UNPKG

matrix-react-sdk

Version:
390 lines (385 loc) 71 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.AddRemoveThreepids = void 0; var _react = _interopRequireWildcard(require("react")); var _logger = require("matrix-js-sdk/src/logger"); var _matrix = require("matrix-js-sdk/src/matrix"); var _AddThreepid = _interopRequireDefault(require("../../../AddThreepid")); var _languageHandler = require("../../../languageHandler"); var _AccessibleButton = _interopRequireDefault(require("../elements/AccessibleButton")); var _MatrixClientContext = require("../../../contexts/MatrixClientContext"); var _Modal = _interopRequireDefault(require("../../../Modal")); var _ErrorDialog = _interopRequireWildcard(require("../dialogs/ErrorDialog")); var _Field = _interopRequireDefault(require("../elements/Field")); var _email = require("../../../email"); var _CountryDropdown = _interopRequireDefault(require("../auth/CountryDropdown")); var _InlineSpinner = _interopRequireDefault(require("../elements/InlineSpinner")); 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; } /* Copyright 2024 New Vector Ltd. Copyright 2024 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. */ // Whether we're adding 3pids to the user's account on the homeserver or sharing them on an identity server const ExistingThreepid = ({ mode, threepid, onChange, disabled }) => { const [isConfirming, setIsConfirming] = (0, _react.useState)(false); const client = (0, _MatrixClientContext.useMatrixClientContext)(); const bindTask = (0, _react.useRef)(); const [isVerifyingBind, setIsVerifyingBind] = (0, _react.useState)(false); const [continueDisabled, setContinueDisabled] = (0, _react.useState)(false); const [verificationCode, setVerificationCode] = (0, _react.useState)(""); const onRemoveClick = (0, _react.useCallback)(e => { e.stopPropagation(); e.preventDefault(); setIsConfirming(true); }, []); const onCancelClick = (0, _react.useCallback)(e => { e.stopPropagation(); e.preventDefault(); setIsConfirming(false); }, []); const onConfirmRemoveClick = (0, _react.useCallback)(e => { e.stopPropagation(); e.preventDefault(); client.deleteThreePid(threepid.medium, threepid.address).then(() => { return onChange(threepid); }).catch(err => { _logger.logger.error("Unable to remove contact information: " + err); _Modal.default.createDialog(_ErrorDialog.default, { title: (0, _languageHandler._t)("settings|general|error_remove_3pid"), description: err && err.message ? err.message : (0, _languageHandler._t)("invite|failed_generic") }); }); }, [client, threepid, onChange]); const changeBinding = (0, _react.useCallback)(async ({ bind, label, errorTitle }) => { try { if (bind) { bindTask.current = new _AddThreepid.default(client); setContinueDisabled(true); if (threepid.medium === _matrix.ThreepidMedium.Email) { await bindTask.current.bindEmailAddress(threepid.address); } else { // XXX: Sydent will accept a number without country code if you add // a leading plus sign to a number in E.164 format (which the 3PID // address is), but this goes against the spec. // See https://github.com/matrix-org/matrix-doc/issues/2222 await bindTask.current.bindMsisdn(null, `+${threepid.address}`); } setContinueDisabled(false); setIsVerifyingBind(true); } else { await client.unbindThreePid(threepid.medium, threepid.address); onChange(threepid); } } catch (err) { _logger.logger.error(`changeBinding: Unable to ${label} email address ${threepid.address}`, err); setIsVerifyingBind(false); setContinueDisabled(false); bindTask.current = undefined; _Modal.default.createDialog(_ErrorDialog.default, { title: errorTitle, description: (0, _ErrorDialog.extractErrorMessageFromError)(err, (0, _languageHandler._t)("invite|failed_generic")) }); } }, [client, threepid, onChange]); const onRevokeClick = (0, _react.useCallback)(e => { e.stopPropagation(); e.preventDefault(); changeBinding({ bind: false, label: "revoke", errorTitle: threepid.medium === "email" ? (0, _languageHandler._t)("settings|general|error_revoke_email_discovery") : (0, _languageHandler._t)("settings|general|error_revoke_msisdn_discovery") }).then(); }, [changeBinding, threepid.medium]); const onShareClick = (0, _react.useCallback)(e => { e.stopPropagation(); e.preventDefault(); changeBinding({ bind: true, label: "share", errorTitle: threepid.medium === "email" ? (0, _languageHandler._t)("settings|general|error_share_email_discovery") : (0, _languageHandler._t)("settings|general|error_share_msisdn_discovery") }).then(); }, [changeBinding, threepid.medium]); const onContinueClick = (0, _react.useCallback)(async e => { e.stopPropagation(); e.preventDefault(); setContinueDisabled(true); try { if (threepid.medium === _matrix.ThreepidMedium.Email) { await bindTask.current?.checkEmailLinkClicked(); } else { await bindTask.current?.haveMsisdnToken(verificationCode); } setIsVerifyingBind(false); onChange(threepid); bindTask.current = undefined; } catch (err) { _logger.logger.error(`Unable to verify threepid:`, err); let underlyingError = err; if (err instanceof _languageHandler.UserFriendlyError) { underlyingError = err.cause; } if (underlyingError instanceof _matrix.MatrixError && underlyingError.errcode === "M_THREEPID_AUTH_FAILED") { _Modal.default.createDialog(_ErrorDialog.default, { title: threepid.medium === "email" ? (0, _languageHandler._t)("settings|general|email_not_verified") : (0, _languageHandler._t)("settings|general|error_msisdn_verification"), description: threepid.medium === "email" ? (0, _languageHandler._t)("settings|general|email_verification_instructions") : (0, _ErrorDialog.extractErrorMessageFromError)(err, (0, _languageHandler._t)("invite|failed_generic")) }); } else { _logger.logger.error("Unable to verify email address: " + err); _Modal.default.createDialog(_ErrorDialog.default, { title: (0, _languageHandler._t)("settings|general|error_email_verification"), description: (0, _ErrorDialog.extractErrorMessageFromError)(err, (0, _languageHandler._t)("invite|failed_generic")) }); } } finally { setContinueDisabled(false); } }, [verificationCode, onChange, threepid]); const onVerificationCodeChange = (0, _react.useCallback)(e => { setVerificationCode(e.target.value); }, []); if (isConfirming) { return /*#__PURE__*/_react.default.createElement("div", { className: "mx_AddRemoveThreepids_existing" }, /*#__PURE__*/_react.default.createElement("span", { className: "mx_AddRemoveThreepids_existing_promptText" }, threepid.medium === _matrix.ThreepidMedium.Email ? (0, _languageHandler._t)("settings|general|remove_email_prompt", { email: threepid.address }) : (0, _languageHandler._t)("settings|general|remove_msisdn_prompt", { phone: threepid.address })), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { onClick: onConfirmRemoveClick, kind: "danger_sm", className: "mx_AddRemoveThreepids_existing_button" }, (0, _languageHandler._t)("action|remove")), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { onClick: onCancelClick, kind: "link_sm", className: "mx_AddRemoveThreepids_existing_button" }, (0, _languageHandler._t)("action|cancel"))); } if (isVerifyingBind) { if (threepid.medium === _matrix.ThreepidMedium.Email) { return /*#__PURE__*/_react.default.createElement("div", { className: "mx_EmailAddressesPhoneNumbers_verify" }, /*#__PURE__*/_react.default.createElement("span", { className: "mx_EmailAddressesPhoneNumbers_verify_instructions" }, (0, _languageHandler._t)("settings|general|discovery_email_verification_instructions")), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { className: "mx_EmailAddressesPhoneNumbers_existing_button", kind: "primary_sm", onClick: onContinueClick, disabled: continueDisabled }, (0, _languageHandler._t)("action|complete"))); } else { return /*#__PURE__*/_react.default.createElement("div", { className: "mx_EmailAddressesPhoneNumbers_verify" }, /*#__PURE__*/_react.default.createElement("span", { className: "mx_EmailAddressesPhoneNumbers_verify_instructions" }, (0, _languageHandler._t)("settings|general|msisdn_verification_instructions")), /*#__PURE__*/_react.default.createElement("form", { onSubmit: onContinueClick, autoComplete: "off", noValidate: true }, /*#__PURE__*/_react.default.createElement(_Field.default, { type: "text", label: (0, _languageHandler._t)("settings|general|msisdn_verification_field_label"), autoComplete: "off", disabled: continueDisabled, value: verificationCode, onChange: onVerificationCodeChange }))); } } return /*#__PURE__*/_react.default.createElement("div", { className: "mx_AddRemoveThreepids_existing" }, /*#__PURE__*/_react.default.createElement("span", { className: "mx_AddRemoveThreepids_existing_address" }, threepid.address), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { onClick: mode === "hs" ? onRemoveClick : threepid.bound ? onRevokeClick : onShareClick, kind: mode === "hs" || threepid.bound ? "danger_sm" : "primary_sm", disabled: disabled }, mode === "hs" ? (0, _languageHandler._t)("action|remove") : threepid.bound ? (0, _languageHandler._t)("action|revoke") : (0, _languageHandler._t)("action|share"))); }; function isMsisdnResponse(resp) { return resp.msisdn !== undefined; } const AddThreepidSection = ({ medium, disabled, onChange }) => { const addTask = (0, _react.useRef)(); const [newThreepidInput, setNewThreepidInput] = (0, _react.useState)(""); const [phoneCountryInput, setPhoneCountryInput] = (0, _react.useState)(""); const [verificationCodeInput, setVerificationCodeInput] = (0, _react.useState)(""); const [isVerifying, setIsVerifying] = (0, _react.useState)(false); const [continueDisabled, setContinueDisabled] = (0, _react.useState)(false); const [sentToMsisdn, setSentToMsisdn] = (0, _react.useState)(""); const client = (0, _MatrixClientContext.useMatrixClientContext)(); const onPhoneCountryChanged = (0, _react.useCallback)(country => { setPhoneCountryInput(country.iso2); }, []); const onContinueClick = (0, _react.useCallback)(e => { e.stopPropagation(); e.preventDefault(); if (!addTask.current) return; setContinueDisabled(true); const checkPromise = medium === "email" ? addTask.current?.checkEmailLinkClicked() : addTask.current?.haveMsisdnToken(verificationCodeInput); checkPromise.then(([finished]) => { if (finished) { addTask.current = undefined; setIsVerifying(false); setNewThreepidInput(""); onChange(); } setContinueDisabled(false); }).catch(err => { _logger.logger.error("Unable to verify 3pid: ", err); setContinueDisabled(false); let underlyingError = err; if (err instanceof _languageHandler.UserFriendlyError) { underlyingError = err.cause; } if (underlyingError instanceof _matrix.MatrixError && underlyingError.errcode === "M_THREEPID_AUTH_FAILED") { _Modal.default.createDialog(_ErrorDialog.default, { title: medium === "email" ? (0, _languageHandler._t)("settings|general|email_not_verified") : (0, _languageHandler._t)("settings|general|error_msisdn_verification"), description: (0, _languageHandler._t)("settings|general|email_verification_instructions") }); } else { _Modal.default.createDialog(_ErrorDialog.default, { title: medium == "email" ? (0, _languageHandler._t)("settings|general|error_email_verification") : (0, _languageHandler._t)("settings|general|error_msisdn_verification"), description: (0, _ErrorDialog.extractErrorMessageFromError)(err, (0, _languageHandler._t)("invite|failed_generic")) }); } }); }, [onChange, medium, verificationCodeInput]); const onNewThreepidInputChange = (0, _react.useCallback)(e => { setNewThreepidInput(e.target.value); }, []); const onAddClick = (0, _react.useCallback)(e => { e.stopPropagation(); e.preventDefault(); if (!newThreepidInput) return; // TODO: Inline field validation if (medium === "email" && !(0, _email.looksValid)(newThreepidInput)) { _Modal.default.createDialog(_ErrorDialog.default, { title: (0, _languageHandler._t)("settings|general|error_invalid_email"), description: (0, _languageHandler._t)("settings|general|error_invalid_email_detail") }); return; } addTask.current = new _AddThreepid.default(client); setIsVerifying(true); setContinueDisabled(true); const addPromise = medium === "email" ? addTask.current.addEmailAddress(newThreepidInput) : addTask.current.addMsisdn(phoneCountryInput, newThreepidInput); addPromise.then(resp => { setContinueDisabled(false); if (isMsisdnResponse(resp)) { setSentToMsisdn(resp.msisdn); } }).catch(err => { _logger.logger.error(`Unable to add threepid ${newThreepidInput}`, err); setIsVerifying(false); setContinueDisabled(false); addTask.current = undefined; _Modal.default.createDialog(_ErrorDialog.default, { title: medium === "email" ? (0, _languageHandler._t)("settings|general|error_add_email") : (0, _languageHandler._t)("common|error"), description: (0, _ErrorDialog.extractErrorMessageFromError)(err, (0, _languageHandler._t)("invite|failed_generic")) }); }); }, [client, phoneCountryInput, newThreepidInput, medium]); const onVerificationCodeInputChange = (0, _react.useCallback)(e => { setVerificationCodeInput(e.target.value); }, []); if (isVerifying && medium === "email") { return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", null, (0, _languageHandler._t)("settings|general|add_email_instructions")), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { onClick: onContinueClick, kind: "primary", disabled: continueDisabled }, (0, _languageHandler._t)("action|continue"))); } else if (isVerifying) { return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", null, (0, _languageHandler._t)("settings|general|add_msisdn_instructions", { msisdn: sentToMsisdn }), /*#__PURE__*/_react.default.createElement("br", null)), /*#__PURE__*/_react.default.createElement("form", { onSubmit: onContinueClick, autoComplete: "off", noValidate: true }, /*#__PURE__*/_react.default.createElement(_Field.default, { type: "text", label: (0, _languageHandler._t)("settings|general|msisdn_verification_field_label"), autoComplete: "off", disabled: disabled || continueDisabled, value: verificationCodeInput, onChange: onVerificationCodeInputChange }), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { onClick: onContinueClick, kind: "primary", disabled: disabled || continueDisabled || verificationCodeInput.length === 0 }, (0, _languageHandler._t)("action|continue")))); } const phoneCountry = medium === "msisdn" ? /*#__PURE__*/_react.default.createElement(_CountryDropdown.default, { onOptionChange: onPhoneCountryChanged, className: "mx_PhoneNumbers_country", value: phoneCountryInput, disabled: isVerifying, isSmall: true, showPrefix: true }) : undefined; return /*#__PURE__*/_react.default.createElement("form", { onSubmit: onAddClick, autoComplete: "off", noValidate: true }, /*#__PURE__*/_react.default.createElement(_Field.default, { type: "text", label: medium === "email" ? (0, _languageHandler._t)("settings|general|email_address_label") : (0, _languageHandler._t)("settings|general|msisdn_label"), autoComplete: medium === "email" ? "email" : "tel-national", disabled: disabled || isVerifying, value: newThreepidInput, onChange: onNewThreepidInputChange, prefixComponent: phoneCountry }), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { onClick: onAddClick, kind: "primary", disabled: disabled }, (0, _languageHandler._t)("action|add"))); }; const AddRemoveThreepids = ({ mode, medium, threepids, disabled, onChange, isLoading }) => { if (isLoading) { return /*#__PURE__*/_react.default.createElement(_InlineSpinner.default, null); } const existingEmailElements = threepids.map(e => { return /*#__PURE__*/_react.default.createElement(ExistingThreepid, { mode: mode, threepid: e, onChange: onChange, key: e.address, disabled: disabled }); }); return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, existingEmailElements, mode === "hs" && /*#__PURE__*/_react.default.createElement(AddThreepidSection, { medium: medium, disabled: disabled, onChange: onChange })); }; exports.AddRemoveThreepids = AddRemoveThreepids; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfbG9nZ2VyIiwiX21hdHJpeCIsIl9BZGRUaHJlZXBpZCIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfbGFuZ3VhZ2VIYW5kbGVyIiwiX0FjY2Vzc2libGVCdXR0b24iLCJfTWF0cml4Q2xpZW50Q29udGV4dCIsIl9Nb2RhbCIsIl9FcnJvckRpYWxvZyIsIl9GaWVsZCIsIl9lbWFpbCIsIl9Db3VudHJ5RHJvcGRvd24iLCJfSW5saW5lU3Bpbm5lciIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIkV4aXN0aW5nVGhyZWVwaWQiLCJtb2RlIiwidGhyZWVwaWQiLCJvbkNoYW5nZSIsImRpc2FibGVkIiwiaXNDb25maXJtaW5nIiwic2V0SXNDb25maXJtaW5nIiwidXNlU3RhdGUiLCJjbGllbnQiLCJ1c2VNYXRyaXhDbGllbnRDb250ZXh0IiwiYmluZFRhc2siLCJ1c2VSZWYiLCJpc1ZlcmlmeWluZ0JpbmQiLCJzZXRJc1ZlcmlmeWluZ0JpbmQiLCJjb250aW51ZURpc2FibGVkIiwic2V0Q29udGludWVEaXNhYmxlZCIsInZlcmlmaWNhdGlvbkNvZGUiLCJzZXRWZXJpZmljYXRpb25Db2RlIiwib25SZW1vdmVDbGljayIsInVzZUNhbGxiYWNrIiwic3RvcFByb3BhZ2F0aW9uIiwicHJldmVudERlZmF1bHQiLCJvbkNhbmNlbENsaWNrIiwib25Db25maXJtUmVtb3ZlQ2xpY2siLCJkZWxldGVUaHJlZVBpZCIsIm1lZGl1bSIsImFkZHJlc3MiLCJ0aGVuIiwiY2F0Y2giLCJlcnIiLCJsb2dnZXIiLCJlcnJvciIsIk1vZGFsIiwiY3JlYXRlRGlhbG9nIiwiRXJyb3JEaWFsb2ciLCJ0aXRsZSIsIl90IiwiZGVzY3JpcHRpb24iLCJtZXNzYWdlIiwiY2hhbmdlQmluZGluZyIsImJpbmQiLCJsYWJlbCIsImVycm9yVGl0bGUiLCJjdXJyZW50IiwiQWRkVGhyZWVwaWQiLCJUaHJlZXBpZE1lZGl1bSIsIkVtYWlsIiwiYmluZEVtYWlsQWRkcmVzcyIsImJpbmRNc2lzZG4iLCJ1bmJpbmRUaHJlZVBpZCIsInVuZGVmaW5lZCIsImV4dHJhY3RFcnJvck1lc3NhZ2VGcm9tRXJyb3IiLCJvblJldm9rZUNsaWNrIiwib25TaGFyZUNsaWNrIiwib25Db250aW51ZUNsaWNrIiwiY2hlY2tFbWFpbExpbmtDbGlja2VkIiwiaGF2ZU1zaXNkblRva2VuIiwidW5kZXJseWluZ0Vycm9yIiwiVXNlckZyaWVuZGx5RXJyb3IiLCJjYXVzZSIsIk1hdHJpeEVycm9yIiwiZXJyY29kZSIsIm9uVmVyaWZpY2F0aW9uQ29kZUNoYW5nZSIsInRhcmdldCIsInZhbHVlIiwiY3JlYXRlRWxlbWVudCIsImNsYXNzTmFtZSIsImVtYWlsIiwicGhvbmUiLCJvbkNsaWNrIiwia2luZCIsIm9uU3VibWl0IiwiYXV0b0NvbXBsZXRlIiwibm9WYWxpZGF0ZSIsInR5cGUiLCJib3VuZCIsImlzTXNpc2RuUmVzcG9uc2UiLCJyZXNwIiwibXNpc2RuIiwiQWRkVGhyZWVwaWRTZWN0aW9uIiwiYWRkVGFzayIsIm5ld1RocmVlcGlkSW5wdXQiLCJzZXROZXdUaHJlZXBpZElucHV0IiwicGhvbmVDb3VudHJ5SW5wdXQiLCJzZXRQaG9uZUNvdW50cnlJbnB1dCIsInZlcmlmaWNhdGlvbkNvZGVJbnB1dCIsInNldFZlcmlmaWNhdGlvbkNvZGVJbnB1dCIsImlzVmVyaWZ5aW5nIiwic2V0SXNWZXJpZnlpbmciLCJzZW50VG9Nc2lzZG4iLCJzZXRTZW50VG9Nc2lzZG4iLCJvblBob25lQ291bnRyeUNoYW5nZWQiLCJjb3VudHJ5IiwiaXNvMiIsImNoZWNrUHJvbWlzZSIsImZpbmlzaGVkIiwib25OZXdUaHJlZXBpZElucHV0Q2hhbmdlIiwib25BZGRDbGljayIsImVtYWlsTG9va3NWYWxpZCIsImFkZFByb21pc2UiLCJhZGRFbWFpbEFkZHJlc3MiLCJhZGRNc2lzZG4iLCJvblZlcmlmaWNhdGlvbkNvZGVJbnB1dENoYW5nZSIsImxlbmd0aCIsInBob25lQ291bnRyeSIsIm9uT3B0aW9uQ2hhbmdlIiwiaXNTbWFsbCIsInNob3dQcmVmaXgiLCJwcmVmaXhDb21wb25lbnQiLCJBZGRSZW1vdmVUaHJlZXBpZHMiLCJ0aHJlZXBpZHMiLCJpc0xvYWRpbmciLCJleGlzdGluZ0VtYWlsRWxlbWVudHMiLCJtYXAiLCJrZXkiLCJGcmFnbWVudCIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy92aWV3cy9zZXR0aW5ncy9BZGRSZW1vdmVUaHJlZXBpZHMudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDI0IFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCBSZWFjdCwgeyB1c2VDYWxsYmFjaywgdXNlUmVmLCB1c2VTdGF0ZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgbG9nZ2VyIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL2xvZ2dlclwiO1xuaW1wb3J0IHtcbiAgICBJUmVxdWVzdE1zaXNkblRva2VuUmVzcG9uc2UsXG4gICAgSVJlcXVlc3RUb2tlblJlc3BvbnNlLFxuICAgIE1hdHJpeEVycm9yLFxuICAgIFRocmVlcGlkTWVkaXVtLFxufSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5cbmltcG9ydCBBZGRUaHJlZXBpZCwgeyBCaW5kaW5nLCBUaGlyZFBhcnR5SWRlbnRpZmllciB9IGZyb20gXCIuLi8uLi8uLi9BZGRUaHJlZXBpZFwiO1xuaW1wb3J0IHsgX3QsIFVzZXJGcmllbmRseUVycm9yIH0gZnJvbSBcIi4uLy4uLy4uL2xhbmd1YWdlSGFuZGxlclwiO1xuaW1wb3J0IEFjY2Vzc2libGVCdXR0b24sIHsgQnV0dG9uRXZlbnQgfSBmcm9tIFwiLi4vZWxlbWVudHMvQWNjZXNzaWJsZUJ1dHRvblwiO1xuaW1wb3J0IHsgdXNlTWF0cml4Q2xpZW50Q29udGV4dCB9IGZyb20gXCIuLi8uLi8uLi9jb250ZXh0cy9NYXRyaXhDbGllbnRDb250ZXh0XCI7XG5pbXBvcnQgTW9kYWwgZnJvbSBcIi4uLy4uLy4uL01vZGFsXCI7XG5pbXBvcnQgRXJyb3JEaWFsb2csIHsgZXh0cmFjdEVycm9yTWVzc2FnZUZyb21FcnJvciB9IGZyb20gXCIuLi9kaWFsb2dzL0Vycm9yRGlhbG9nXCI7XG5pbXBvcnQgRmllbGQgZnJvbSBcIi4uL2VsZW1lbnRzL0ZpZWxkXCI7XG5pbXBvcnQgeyBsb29rc1ZhbGlkIGFzIGVtYWlsTG9va3NWYWxpZCB9IGZyb20gXCIuLi8uLi8uLi9lbWFpbFwiO1xuaW1wb3J0IENvdW50cnlEcm9wZG93biBmcm9tIFwiLi4vYXV0aC9Db3VudHJ5RHJvcGRvd25cIjtcbmltcG9ydCB7IFBob25lTnVtYmVyQ291bnRyeURlZmluaXRpb24gfSBmcm9tIFwiLi4vLi4vLi4vcGhvbmVudW1iZXJcIjtcbmltcG9ydCBJbmxpbmVTcGlubmVyIGZyb20gXCIuLi9lbGVtZW50cy9JbmxpbmVTcGlubmVyXCI7XG5cbi8vIFdoZXRoZXIgd2UncmUgYWRkaW5nIDNwaWRzIHRvIHRoZSB1c2VyJ3MgYWNjb3VudCBvbiB0aGUgaG9tZXNlcnZlciBvciBzaGFyaW5nIHRoZW0gb24gYW4gaWRlbnRpdHkgc2VydmVyXG50eXBlIFRoZWVwaWRDb250cm9sTW9kZSA9IFwiaHNcIiB8IFwiaXNcIjtcblxuaW50ZXJmYWNlIEV4aXN0aW5nVGhyZWVwaWRQcm9wcyB7XG4gICAgbW9kZTogVGhlZXBpZENvbnRyb2xNb2RlO1xuICAgIHRocmVlcGlkOiBUaGlyZFBhcnR5SWRlbnRpZmllcjtcbiAgICBvbkNoYW5nZTogKHRocmVlcGlkOiBUaGlyZFBhcnR5SWRlbnRpZmllcikgPT4gdm9pZDtcbiAgICBkaXNhYmxlZD86IGJvb2xlYW47XG59XG5cbmNvbnN0IEV4aXN0aW5nVGhyZWVwaWQ6IFJlYWN0LkZDPEV4aXN0aW5nVGhyZWVwaWRQcm9wcz4gPSAoeyBtb2RlLCB0aHJlZXBpZCwgb25DaGFuZ2UsIGRpc2FibGVkIH0pID0+IHtcbiAgICBjb25zdCBbaXNDb25maXJtaW5nLCBzZXRJc0NvbmZpcm1pbmddID0gdXNlU3RhdGUoZmFsc2UpO1xuICAgIGNvbnN0IGNsaWVudCA9IHVzZU1hdHJpeENsaWVudENvbnRleHQoKTtcbiAgICBjb25zdCBiaW5kVGFzayA9IHVzZVJlZjxBZGRUaHJlZXBpZCB8IHVuZGVmaW5lZD4oKTtcblxuICAgIGNvbnN0IFtpc1ZlcmlmeWluZ0JpbmQsIHNldElzVmVyaWZ5aW5nQmluZF0gPSB1c2VTdGF0ZShmYWxzZSk7XG4gICAgY29uc3QgW2NvbnRpbnVlRGlzYWJsZWQsIHNldENvbnRpbnVlRGlzYWJsZWRdID0gdXNlU3RhdGUoZmFsc2UpO1xuICAgIGNvbnN0IFt2ZXJpZmljYXRpb25Db2RlLCBzZXRWZXJpZmljYXRpb25Db2RlXSA9IHVzZVN0YXRlKFwiXCIpO1xuXG4gICAgY29uc3Qgb25SZW1vdmVDbGljayA9IHVzZUNhbGxiYWNrKChlOiBCdXR0b25FdmVudCkgPT4ge1xuICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgc2V0SXNDb25maXJtaW5nKHRydWUpO1xuICAgIH0sIFtdKTtcblxuICAgIGNvbnN0IG9uQ2FuY2VsQ2xpY2sgPSB1c2VDYWxsYmFjaygoZTogQnV0dG9uRXZlbnQpID0+IHtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgIHNldElzQ29uZmlybWluZyhmYWxzZSk7XG4gICAgfSwgW10pO1xuXG4gICAgY29uc3Qgb25Db25maXJtUmVtb3ZlQ2xpY2sgPSB1c2VDYWxsYmFjayhcbiAgICAgICAgKGU6IEJ1dHRvbkV2ZW50KSA9PiB7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgICAgICBjbGllbnRcbiAgICAgICAgICAgICAgICAuZGVsZXRlVGhyZWVQaWQodGhyZWVwaWQubWVkaXVtLCB0aHJlZXBpZC5hZGRyZXNzKVxuICAgICAgICAgICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9uQ2hhbmdlKHRocmVlcGlkKTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihcIlVuYWJsZSB0byByZW1vdmUgY29udGFjdCBpbmZvcm1hdGlvbjogXCIgKyBlcnIpO1xuICAgICAgICAgICAgICAgICAgICBNb2RhbC5jcmVhdGVEaWFsb2coRXJyb3JEaWFsb2csIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiBfdChcInNldHRpbmdzfGdlbmVyYWx8ZXJyb3JfcmVtb3ZlXzNwaWRcIiksXG4gICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogZXJyICYmIGVyci5tZXNzYWdlID8gZXJyLm1lc3NhZ2UgOiBfdChcImludml0ZXxmYWlsZWRfZ2VuZXJpY1wiKSxcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sXG4gICAgICAgIFtjbGllbnQsIHRocmVlcGlkLCBvbkNoYW5nZV0sXG4gICAgKTtcblxuICAgIGNvbnN0IGNoYW5nZUJpbmRpbmcgPSB1c2VDYWxsYmFjayhcbiAgICAgICAgYXN5bmMgKHsgYmluZCwgbGFiZWwsIGVycm9yVGl0bGUgfTogQmluZGluZykgPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAoYmluZCkge1xuICAgICAgICAgICAgICAgICAgICBiaW5kVGFzay5jdXJyZW50ID0gbmV3IEFkZFRocmVlcGlkKGNsaWVudCk7XG4gICAgICAgICAgICAgICAgICAgIHNldENvbnRpbnVlRGlzYWJsZWQodHJ1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICh0aHJlZXBpZC5tZWRpdW0gPT09IFRocmVlcGlkTWVkaXVtLkVtYWlsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBiaW5kVGFzay5jdXJyZW50LmJpbmRFbWFpbEFkZHJlc3ModGhyZWVwaWQuYWRkcmVzcyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBYWFg6IFN5ZGVudCB3aWxsIGFjY2VwdCBhIG51bWJlciB3aXRob3V0IGNvdW50cnkgY29kZSBpZiB5b3UgYWRkXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBhIGxlYWRpbmcgcGx1cyBzaWduIHRvIGEgbnVtYmVyIGluIEUuMTY0IGZvcm1hdCAod2hpY2ggdGhlIDNQSURcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFkZHJlc3MgaXMpLCBidXQgdGhpcyBnb2VzIGFnYWluc3QgdGhlIHNwZWMuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL21hdHJpeC1vcmcvbWF0cml4LWRvYy9pc3N1ZXMvMjIyMlxuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgYmluZFRhc2suY3VycmVudC5iaW5kTXNpc2RuKG51bGwgYXMgdW5rbm93biBhcyBzdHJpbmcsIGArJHt0aHJlZXBpZC5hZGRyZXNzfWApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHNldENvbnRpbnVlRGlzYWJsZWQoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBzZXRJc1ZlcmlmeWluZ0JpbmQodHJ1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgY2xpZW50LnVuYmluZFRocmVlUGlkKHRocmVlcGlkLm1lZGl1bSwgdGhyZWVwaWQuYWRkcmVzcyk7XG4gICAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlKHRocmVlcGlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYGNoYW5nZUJpbmRpbmc6IFVuYWJsZSB0byAke2xhYmVsfSBlbWFpbCBhZGRyZXNzICR7dGhyZWVwaWQuYWRkcmVzc31gLCBlcnIpO1xuICAgICAgICAgICAgICAgIHNldElzVmVyaWZ5aW5nQmluZChmYWxzZSk7XG4gICAgICAgICAgICAgICAgc2V0Q29udGludWVEaXNhYmxlZChmYWxzZSk7XG4gICAgICAgICAgICAgICAgYmluZFRhc2suY3VycmVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBNb2RhbC5jcmVhdGVEaWFsb2coRXJyb3JEaWFsb2csIHtcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU6IGVycm9yVGl0bGUsXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBleHRyYWN0RXJyb3JNZXNzYWdlRnJvbUVycm9yKGVyciwgX3QoXCJpbnZpdGV8ZmFpbGVkX2dlbmVyaWNcIikpLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBbY2xpZW50LCB0aHJlZXBpZCwgb25DaGFuZ2VdLFxuICAgICk7XG5cbiAgICBjb25zdCBvblJldm9rZUNsaWNrID0gdXNlQ2FsbGJhY2soXG4gICAgICAgIChlOiBCdXR0b25FdmVudCk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIGNoYW5nZUJpbmRpbmcoe1xuICAgICAgICAgICAgICAgIGJpbmQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBcInJldm9rZVwiLFxuICAgICAgICAgICAgICAgIGVycm9yVGl0bGU6XG4gICAgICAgICAgICAgICAgICAgIHRocmVlcGlkLm1lZGl1bSA9PT0gXCJlbWFpbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICA/IF90KFwic2V0dGluZ3N8Z2VuZXJhbHxlcnJvcl9yZXZva2VfZW1haWxfZGlzY292ZXJ5XCIpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IF90KFwic2V0dGluZ3N8Z2VuZXJhbHxlcnJvcl9yZXZva2VfbXNpc2RuX2Rpc2NvdmVyeVwiKSxcbiAgICAgICAgICAgIH0pLnRoZW4oKTtcbiAgICAgICAgfSxcbiAgICAgICAgW2NoYW5nZUJpbmRpbmcsIHRocmVlcGlkLm1lZGl1bV0sXG4gICAgKTtcblxuICAgIGNvbnN0IG9uU2hhcmVDbGljayA9IHVzZUNhbGxiYWNrKFxuICAgICAgICAoZTogQnV0dG9uRXZlbnQpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBjaGFuZ2VCaW5kaW5nKHtcbiAgICAgICAgICAgICAgICBiaW5kOiB0cnVlLFxuICAgICAgICAgICAgICAgIGxhYmVsOiBcInNoYXJlXCIsXG4gICAgICAgICAgICAgICAgZXJyb3JUaXRsZTpcbiAgICAgICAgICAgICAgICAgICAgdGhyZWVwaWQubWVkaXVtID09PSBcImVtYWlsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gX3QoXCJzZXR0aW5nc3xnZW5lcmFsfGVycm9yX3NoYXJlX2VtYWlsX2Rpc2NvdmVyeVwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBfdChcInNldHRpbmdzfGdlbmVyYWx8ZXJyb3Jfc2hhcmVfbXNpc2RuX2Rpc2NvdmVyeVwiKSxcbiAgICAgICAgICAgIH0pLnRoZW4oKTtcbiAgICAgICAgfSxcbiAgICAgICAgW2NoYW5nZUJpbmRpbmcsIHRocmVlcGlkLm1lZGl1bV0sXG4gICAgKTtcblxuICAgIGNvbnN0IG9uQ29udGludWVDbGljayA9IHVzZUNhbGxiYWNrKFxuICAgICAgICBhc3luYyAoZTogQnV0dG9uRXZlbnQpID0+IHtcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgICAgICAgIHNldENvbnRpbnVlRGlzYWJsZWQodHJ1ZSk7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aHJlZXBpZC5tZWRpdW0gPT09IFRocmVlcGlkTWVkaXVtLkVtYWlsKSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGJpbmRUYXNrLmN1cnJlbnQ/LmNoZWNrRW1haWxMaW5rQ2xpY2tlZCgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IGJpbmRUYXNrLmN1cnJlbnQ/LmhhdmVNc2lzZG5Ub2tlbih2ZXJpZmljYXRpb25Db2RlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgc2V0SXNWZXJpZnlpbmdCaW5kKGZhbHNlKTtcbiAgICAgICAgICAgICAgICBvbkNoYW5nZSh0aHJlZXBpZCk7XG4gICAgICAgICAgICAgICAgYmluZFRhc2suY3VycmVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgVW5hYmxlIHRvIHZlcmlmeSB0aHJlZXBpZDpgLCBlcnIpO1xuXG4gICAgICAgICAgICAgICAgbGV0IHVuZGVybHlpbmdFcnJvciA9IGVycjtcbiAgICAgICAgICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgVXNlckZyaWVuZGx5RXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgdW5kZXJseWluZ0Vycm9yID0gZXJyLmNhdXNlO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICh1bmRlcmx5aW5nRXJyb3IgaW5zdGFuY2VvZiBNYXRyaXhFcnJvciAmJiB1bmRlcmx5aW5nRXJyb3IuZXJyY29kZSA9PT0gXCJNX1RIUkVFUElEX0FVVEhfRkFJTEVEXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgTW9kYWwuY3JlYXRlRGlhbG9nKEVycm9yRGlhbG9nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJlZXBpZC5tZWRpdW0gPT09IFwiZW1haWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IF90KFwic2V0dGluZ3N8Z2VuZXJhbHxlbWFpbF9ub3RfdmVyaWZpZWRcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBfdChcInNldHRpbmdzfGdlbmVyYWx8ZXJyb3JfbXNpc2RuX3ZlcmlmaWNhdGlvblwiKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocmVlcGlkLm1lZGl1bSA9PT0gXCJlbWFpbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gX3QoXCJzZXR0aW5nc3xnZW5lcmFsfGVtYWlsX3ZlcmlmaWNhdGlvbl9pbnN0cnVjdGlvbnNcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBleHRyYWN0RXJyb3JNZXNzYWdlRnJvbUVycm9yKGVyciwgX3QoXCJpbnZpdGV8ZmFpbGVkX2dlbmVyaWNcIikpLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoXCJVbmFibGUgdG8gdmVyaWZ5IGVtYWlsIGFkZHJlc3M6IFwiICsgZXJyKTtcbiAgICAgICAgICAgICAgICAgICAgTW9kYWwuY3JlYXRlRGlhbG9nKEVycm9yRGlhbG9nLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogX3QoXCJzZXR0aW5nc3xnZW5lcmFsfGVycm9yX2VtYWlsX3ZlcmlmaWNhdGlvblwiKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBleHRyYWN0RXJyb3JNZXNzYWdlRnJvbUVycm9yKGVyciwgX3QoXCJpbnZpdGV8ZmFpbGVkX2dlbmVyaWNcIikpLFxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgICAgIHNldENvbnRpbnVlRGlzYWJsZWQoZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBbdmVyaWZpY2F0aW9uQ29kZSwgb25DaGFuZ2UsIHRocmVlcGlkXSxcbiAgICApO1xuXG4gICAgY29uc3Qgb25WZXJpZmljYXRpb25Db2RlQ2hhbmdlID0gdXNlQ2FsbGJhY2soKGU6IFJlYWN0LkNoYW5nZUV2ZW50PEhUTUxJbnB1dEVsZW1lbnQ+KSA9PiB7XG4gICAgICAgIHNldFZlcmlmaWNhdGlvbkNvZGUoZS50YXJnZXQudmFsdWUpO1xuICAgIH0sIFtdKTtcblxuICAgIGlmIChpc0NvbmZpcm1pbmcpIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfQWRkUmVtb3ZlVGhyZWVwaWRzX2V4aXN0aW5nXCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwibXhfQWRkUmVtb3ZlVGhyZWVwaWRzX2V4aXN0aW5nX3Byb21wdFRleHRcIj5cbiAgICAgICAgICAgICAgICAgICAge3RocmVlcGlkLm1lZGl1bSA9PT0gVGhyZWVwaWRNZWRpdW0uRW1haWxcbiAgICAgICAgICAgICAgICAgICAgICAgID8gX3QoXCJzZXR0aW5nc3xnZW5lcmFsfHJlbW92ZV9lbWFpbF9wcm9tcHRcIiwgeyBlbWFpbDogdGhyZWVwaWQuYWRkcmVzcyB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBfdChcInNldHRpbmdzfGdlbmVyYWx8cmVtb3ZlX21zaXNkbl9wcm9tcHRcIiwgeyBwaG9uZTogdGhyZWVwaWQuYWRkcmVzcyB9KX1cbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPEFjY2Vzc2libGVCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgb25DbGljaz17b25Db25maXJtUmVtb3ZlQ2xpY2t9XG4gICAgICAgICAgICAgICAgICAgIGtpbmQ9XCJkYW5nZXJfc21cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9BZGRSZW1vdmVUaHJlZXBpZHNfZXhpc3RpbmdfYnV0dG9uXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIHtfdChcImFjdGlvbnxyZW1vdmVcIil9XG4gICAgICAgICAgICAgICAgPC9BY2Nlc3NpYmxlQnV0dG9uPlxuICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e29uQ2FuY2VsQ2xpY2t9XG4gICAgICAgICAgICAgICAgICAgIGtpbmQ9XCJsaW5rX3NtXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfQWRkUmVtb3ZlVGhyZWVwaWRzX2V4aXN0aW5nX2J1dHRvblwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICB7X3QoXCJhY3Rpb258Y2FuY2VsXCIpfVxuICAgICAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICApO1xuICAgIH1cblxuICAgIGlmIChpc1ZlcmlmeWluZ0JpbmQpIHtcbiAgICAgICAgaWYgKHRocmVlcGlkLm1lZGl1bSA9PT0gVGhyZWVwaWRNZWRpdW0uRW1haWwpIHtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9FbWFpbEFkZHJlc3Nlc1Bob25lTnVtYmVyc192ZXJpZnlcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwibXhfRW1haWxBZGRyZXNzZXNQaG9uZU51bWJlcnNfdmVyaWZ5X2luc3RydWN0aW9uc1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAge190KFwic2V0dGluZ3N8Z2VuZXJhbHxkaXNjb3ZlcnlfZW1haWxfdmVyaWZpY2F0aW9uX2luc3RydWN0aW9uc1wiKX1cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfRW1haWxBZGRyZXNzZXNQaG9uZU51bWJlcnNfZXhpc3RpbmdfYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtpbmQ9XCJwcmltYXJ5X3NtXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e29uQ29udGludWVDbGlja31cbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVkPXtjb250aW51ZURpc2FibGVkfVxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJhY3Rpb258Y29tcGxldGVcIil9XG4gICAgICAgICAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfRW1haWxBZGRyZXNzZXNQaG9uZU51bWJlcnNfdmVyaWZ5XCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cIm14X0VtYWlsQWRkcmVzc2VzUGhvbmVOdW1iZXJzX3ZlcmlmeV9pbnN0cnVjdGlvbnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHtfdChcInNldHRpbmdzfGdlbmVyYWx8bXNpc2RuX3ZlcmlmaWNhdGlvbl9pbnN0cnVjdGlvbnNcIil9XG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPGZvcm0gb25TdWJtaXQ9e29uQ29udGludWVDbGlja30gYXV0b0NvbXBsZXRlPVwib2ZmXCIgbm9WYWxpZGF0ZT17dHJ1ZX0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8RmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw9e190KFwic2V0dGluZ3N8Z2VuZXJhbHxtc2lzZG5fdmVyaWZpY2F0aW9uX2ZpZWxkX2xhYmVsXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dG9Db21wbGV0ZT1cIm9mZlwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ9e2NvbnRpbnVlRGlzYWJsZWR9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWU9e3ZlcmlmaWNhdGlvbkNvZGV9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9e29uVmVyaWZpY2F0aW9uQ29kZUNoYW5nZX1cbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDwvZm9ybT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X0FkZFJlbW92ZVRocmVlcGlkc19leGlzdGluZ1wiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwibXhfQWRkUmVtb3ZlVGhyZWVwaWRzX2V4aXN0aW5nX2FkZHJlc3NcIj57dGhyZWVwaWQuYWRkcmVzc308L3NwYW4+XG4gICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgIG9uQ2xpY2s9e21vZGUgPT09IFwiaHNcIiA/IG9uUmVtb3ZlQ2xpY2sgOiB0aHJlZXBpZC5ib3VuZCA/IG9uUmV2b2tlQ2xpY2sgOiBvblNoYXJlQ2xpY2t9XG4gICAgICAgICAgICAgICAga2luZD17bW9kZSA9PT0gXCJoc1wiIHx8IHRocmVlcGlkLmJvdW5kID8gXCJkYW5nZXJfc21cIiA6IFwicHJpbWFyeV9zbVwifVxuICAgICAgICAgICAgICAgIGRpc2FibGVkPXtkaXNhYmxlZH1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7bW9kZSA9PT0gXCJoc1wiID8gX3QoXCJhY3Rpb258cmVtb3ZlXCIpIDogdGhyZWVwaWQuYm91bmQgPyBfdChcImFjdGlvbnxyZXZva2VcIikgOiBfdChcImFjdGlvbnxzaGFyZVwiKX1cbiAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgKTtcbn07XG5cbmZ1bmN0aW9uIGlzTXNpc2RuUmVzcG9uc2UoXG4gICAgcmVzcDogSVJlcXVlc3RUb2tlblJlc3BvbnNlIHwgSVJlcXVlc3RNc2lzZG5Ub2tlblJlc3BvbnNlLFxuKTogcmVzcCBpcyBJUmVxdWVzdE1zaXNkblRva2VuUmVzcG9uc2Uge1xuICAgIHJldHVybiAocmVzcCBhcyBJUmVxdWVzdE1zaXNkblRva2VuUmVzcG9uc2UpLm1zaXNkbiAhPT0gdW5kZWZpbmVkO1xufVxuXG5jb25zdCBBZGRUaHJlZXBpZFNlY3Rpb246IFJlYWN0LkZDPHsgbWVkaXVtOiBcImVtYWlsXCIgfCBcIm1zaXNkblwiOyBkaXNhYmxlZD86IGJvb2xlYW47IG9uQ2hhbmdlOiAoKSA9PiB2b2lkIH0+ID0gKHtcbiAgICBtZWRpdW0sXG4gICAgZGlzYWJsZWQsXG4gICAgb25DaGFuZ2UsXG59KSA9PiB7XG4gICAgY29uc3QgYWRkVGFzayA9IHVzZVJlZjxBZGRUaHJlZXBpZCB8IHVuZGVmaW5lZD4oKTtcbiAgICBjb25zdCBbbmV3VGhyZWVwaWRJbnB1dCwgc2V0TmV3VGhyZWVwaWRJbnB1dF0gPSB1c2VTdGF0ZShcIlwiKTtcbiAgICBjb25zdCBbcGhvbmVDb3VudHJ5SW5wdXQsIHNldFBob25lQ291bnRyeUlucHV0XSA9IHVzZVN0YXRlKFwiXCIpO1xuICAgIGNvbnN0IFt2ZXJpZmljYXRpb25Db2RlSW5wdXQsIHNldFZlcmlmaWNhdGlvbkNvZGVJbnB1dF0gPSB1c2VTdGF0ZShcIlwiKTtcbiAgICBjb25zdCBbaXNWZXJpZnlpbmcsIHNldElzVmVyaWZ5aW5nXSA9IHVzZVN0YXRlKGZhbHNlKTtcbiAgICBjb25zdCBbY29udGludWVEaXNhYmxlZCwgc2V0Q29udGludWVEaXNhYmxlZF0gPSB1c2VTdGF0ZShmYWxzZSk7XG4gICAgY29uc3QgW3NlbnRUb01zaXNkbiwgc2V0U2VudFRvTXNpc2RuXSA9IHVzZVN0YXRlKFwiXCIpO1xuXG4gICAgY29uc3QgY2xpZW50ID0gdXNlTWF0cml4Q2xpZW50Q29udGV4dCgpO1xuXG4gICAgY29uc3Qgb25QaG9uZUNvdW50cnlDaGFuZ2VkID0gdXNlQ2FsbGJhY2soKGNvdW50cnk6IFBob25lTnVtYmVyQ291bnRyeURlZmluaXRpb24pID0+IHtcbiAgICAgICAgc2V0UGhvbmVDb3VudHJ5SW5wdXQoY291bnRyeS5pc28yKTtcbiAgICB9LCBbXSk7XG5cbiAgICBjb25zdCBvbkNvbnRpbnVlQ2xpY2sgPSB1c2VDYWxsYmFjayhcbiAgICAgICAgKGU6IEJ1dHRvbkV2ZW50KSA9PiB7XG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgICAgICAgICBpZiAoIWFkZFRhc2suY3VycmVudCkgcmV0dXJuO1xuXG4gICAgICAgICAgICBzZXRDb250aW51ZURpc2FibGVkKHRydWUpO1xuXG4gICAgICAgICAgICBjb25zdCBjaGVja1Byb21pc2UgPVxuICAgICAgICAgICAgICAgIG1lZGl1bSA9PT0gXCJlbWFpbFwiXG4gICAgICAgICAgICAgICAgICAgID8gYWRkVGFzay5jdXJyZW50Py5jaGVja0VtYWlsTGlua0NsaWNrZWQoKVxuICAgICAgICAgICAgICAgICAgICA6IGFkZFRhc2suY3VycmVudD8uaGF2ZU1zaXNkblRva2VuKHZlcmlmaWNhdGlvbkNvZGVJbnB1dCk7XG4gICAgICAgICAgICBjaGVja1Byb21pc2VcbiAgICAgICAgICAgICAgICAudGhlbigoW2ZpbmlzaGVkXSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZmluaXNoZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFkZFRhc2suY3VycmVudCA9IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldElzVmVyaWZ5aW5nKGZhbHNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNldE5ld1RocmVlcGlkSW5wdXQoXCJcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZSgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHNldENvbnRpbnVlRGlzYWJsZWQoZmFsc2UpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKFwiVW5hYmxlIHRvIHZlcmlmeSAzcGlkOiBcIiwgZXJyKTtcblxuICAgICAgICAgICAgICAgICAgICBzZXRDb250aW51ZURpc2FibGVkKGZhbHNlKTtcblxuICAgICAgICAgICAgICAgICAgICBsZXQgdW5kZXJseWluZ0Vycm9yID0gZXJyO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyIGluc3RhbmNlb2YgVXNlckZyaWVuZGx5RXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVuZGVybHlpbmdFcnJvciA9IGVyci5jYXVzZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgIHVuZGVybHlpbmdFcnJvciBpbnN0YW5jZW9mIE1hdHJpeEVycm9yICYmXG4gICAgICAgICAgICAgICAgICAgICAgICB1bmRlcmx5aW5nRXJyb3IuZXJyY29kZSA9PT0gXCJNX1RIUkVFUElEX0FVVEhfRkFJTEVEXCJcbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBNb2RhbC5jcmVhdGVEaWFsb2coRXJyb3JEaWFsb2csIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVkaXVtID09PSBcImVtYWlsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gX3QoXCJzZXR0aW5nc3xnZW5lcmFsfGVtYWlsX25vdF92ZXJpZmllZFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBfdChcInNldHRpbmdzfGdlbmVyYWx8ZXJyb3JfbXNpc2RuX3ZlcmlmaWNhdGlvblwiKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogX3QoXCJzZXR0aW5nc3xnZW5lcmFsfGVtYWlsX3ZlcmlmaWNhdGlvbl9pbnN0cnVjdGlvbnNcIiksXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIE1vZGFsLmNyZWF0ZURpYWxvZyhFcnJvckRpYWxvZywge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRpdW0gPT0gXCJlbWFpbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IF90KFwic2V0dGluZ3N8Z2VuZXJhbHxlcnJvcl9lbWFpbF92ZXJpZmljYXRpb25cIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogX3QoXCJzZXR0aW5nc3xnZW5lcmFsfGVycm9yX21zaXNkbl92ZXJpZmljYXRpb25cIiksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGV4dHJhY3RFcnJvck1lc3NhZ2VGcm9tRXJyb3IoZXJyLCBfdChcImludml0ZXxmYWlsZWRfZ2VuZXJpY1wiKSksXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICBbb25DaGFuZ2UsIG1lZGl1bSwgdmVyaWZpY2F0aW9uQ29kZUlucHV0XSxcbiAgICApO1xuXG4gICAgY29uc3Qgb25OZXdUaHJlZXBpZElucHV0Q2hhbmdlID0gdXNlQ2FsbGJhY2soKGU6IFJlYWN0LkNoYW5nZUV2ZW50PEhUTUxJbnB1dEVsZW1lbnQ+KSA9PiB7XG4gICAgICAgIHNldE5ld1RocmVlcGlkSW5wdXQoZS50YXJnZXQudmFsdWUpO1xuICAgIH0sIFtdKTtcblxuICAgIGNvbnN0IG9uQWRkQ2xpY2sgPSB1c2VDYWxsYmFjayhcbiAgICAgICAgKGU6IFJlYWN0LkZvcm1FdmVudCkgPT4ge1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgICAgICAgaWYgKCFuZXdUaHJlZXBpZElucHV0KSByZXR1cm47XG5cbiAgICAgICAgICAgIC8vIFRPRE86IElubGluZSBmaWVsZCB2YWxpZGF0aW9uXG4gICAgICAgICAgICBpZiAobWVkaXVtID09PSBcImVtYWlsXCIgJiYgIWVtYWlsTG9va3NWYWxpZChuZXdUaHJlZXBpZElucHV0KSkge1xuICAgICAgICAgICAgICAgIE1vZGFsLmNyZWF0ZURpYWxvZyhFcnJvckRpYWxvZywge1xuICAgICAgICAgICAgICAgICAgICB0aXRsZTogX3QoXCJzZXR0aW5nc3xnZW5lcmFsfGVycm9yX2ludmFsaWRfZW1haWxcIiksXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBfdChcInNldHRpbmdzfGdlbmVyYWx8ZXJyb3JfaW52YWxpZF9lbWFpbF9kZXRhaWxcIiksXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBhZGRUYXNrLmN1cnJlbnQgPSBuZXcgQWRkVGhyZWVwaWQoY2xpZW50KTtcbiAgICAgICAgICAgIHNldElzVmVyaWZ5aW5nKHRydWUpO1xuICAgICAgICAgICAgc2V0Q29udGludWVEaXNhYmxlZCh0cnVlKTtcblxuICAgICAgICAgICAgY29uc3QgYWRkUHJvbWlzZSA9XG4gICAgICAgICAgICAgICAgbWVkaXVtID09PSBcImVtYWlsXCJcbiAgICAgICAgICAgICAgICAgICAgPyBhZGRUYXNrLmN1cnJlbnQuYWRkRW1haWxBZGRyZXNzKG5ld1RocmVlcGlkSW5wdXQpXG4gICAgICAgICAgICAgICAgICAgIDogYWRkVGFzay5jdXJyZW50LmFkZE1zaXNkbihwaG9uZUNvdW50cnlJbnB1dCwgbmV3VGhyZWVwaWRJbnB1dCk7XG5cbiAgICAgICAgICAgIGFkZFByb21pc2VcbiAgICAgICAgICAgICAgICAudGhlbigocmVzcDogSVJlcXVlc3RUb2tlblJlc3BvbnNlIHwgSVJlcXVlc3RNc2lzZG5Ub2tlblJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHNldENvbnRpbnVlRGlzYWJsZWQoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaXNNc2lzZG5SZXNwb25zZShyZXNwKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2V0U2VudFRvTXNpc2RuKHJlc3AubXNpc2RuKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBVbmFibGUgdG8gYWRkIHRocmVlcGlkICR7bmV3VGhyZWVwaWRJbnB1dH1gLCBlcnIpO1xuICAgICAgICAgICAgICAgICAgICBzZXRJc1ZlcmlmeWluZyhmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIHNldENvbnRpbnVlRGlzYWJsZWQoZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBhZGRUYXNrLmN1cnJlbnQgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgIE1vZGFsLmNyZWF0ZURpYWxvZyhFcnJvckRpYWxvZywge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6IG1lZGl1bSA9PT0gXCJlbWFpbFwiID8gX3QoXCJzZXR0aW5nc3xnZW5lcmFsfGVycm9yX2FkZF9lbWFpbFwiKSA6IF90KFwiY29tbW9ufGVycm9yXCIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IGV4dHJhY3RFcnJvck1lc3NhZ2VGcm9tRXJyb3IoZXJyLCBfdChcImludml0ZXxmYWlsZWRfZ2VuZXJpY1wiKSksXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICB9LFxuICAgICAgICBbY2xpZW50LCBwaG9uZUNvdW50cnlJbnB1dCwgbmV3VGhyZWVwaWRJbnB1dCwgbWVkaXVtXSxcbiAgICApO1xuXG4gICAgY29uc3Qgb25WZXJpZmljYXRpb25Db2RlSW5wdXRDaGFuZ2UgPSB1c2VDYWxsYmFjaygoZTogUmVhY3QuQ2hhbmdlRXZlbnQ8SFRNTElucHV0RWxlbWVudD4pID0+IHtcbiAgICAgICAgc2V0VmVyaWZpY2F0aW9uQ29kZUlucHV0KGUudGFyZ2V0LnZhbHVlKTtcbiAgICB9LCBbXSk7XG5cbiAgICBpZiAoaXNWZXJpZnlpbmcgJiYgbWVkaXVtID09PSBcImVtYWlsXCIpIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGRpdj57X3QoXCJzZXR0aW5nc3xnZW5lcmFsfGFkZF9lbWFpbF9pbnN0cnVjdGlvbnNcIil9PC9kaXY+XG4gICAgICAgICAgICAgICAgPEFjY2Vzc2libGVCdXR0b24gb25DbGljaz17b25Db250aW51ZUNsaWNrfSBraW5kPVwicHJpbWFyeVwiIGRpc2FibGVkPXtjb250aW51ZURpc2FibGVkfT5cbiAgICAgICAgICAgICAgICAgICAge190KFwiYWN0aW9ufGNvbnRpbnVlXCIpfVxuICAgICAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICApO1xuICAgIH0gZWxzZSBpZiAoaXNWZXJpZnlpbmcpIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAge190KFwic2V0dGluZ3N8Z2VuZXJhbHxhZGRfbXNpc2RuX2luc3RydWN0aW9uc1wiLCB7IG1zaXNkbjogc2VudFRvTXNpc2RuIH0pfVxuICAgICAgICAgICAgICAgICAgICA8YnIgLz5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8Zm9ybSBvblN1Ym1pdD17b25Db250aW51ZUNsaWNrfSBhdXRvQ29tcGxldGU9XCJvZmZcIiBub1ZhbGlkYXRlPXt0cnVlfT5cbiAgICAgICAgICAgICAgICAgICAgPEZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD17X3QoXCJzZXR0aW5nc3xnZW5lcmFsfG1zaXNkbl92ZXJpZmljYXRpb25fZmllbGRfbGFiZWxcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICBhdXRvQ29tcGxldGU9XCJvZmZcIlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ9e2Rpc2FibGVkIHx8IGNvbnRpbnVlRGlzYWJsZWR9XG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT17dmVyaWZpY2F0aW9uQ29kZUlucHV0fVxuICAgICAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9e29uVmVyaWZpY2F0aW9uQ29kZUlucHV0Q2hhbmdlfVxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17b25Db250aW51ZUNsaWNrfVxuICAgICAgICAgICAgICAgICAgICAgICAga2luZD1cInByaW1hcnlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ9e2Rpc2FibGVkIHx8IGNvbnRpbnVlRGlzYWJsZWQgfHwgdmVyaWZpY2F0aW9uQ29kZUlucHV0Lmxlbmd0aCA9PT0gMH1cbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAge190KFwiYWN0aW9ufGNvbnRpbnVlXCIpfVxuICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgcGhvbmVDb3VudHJ5ID1cbiAgICAgICAgbWVkaXVtID09PSBcIm1zaXNkblwiID8gKFxuICAgICAgICAgICAgPENvdW50cnlEcm9wZG93blxuICAgICAgICAgICAgICAgIG9uT3B0aW9uQ2hhbmdlPXtvblBob25lQ291bnRyeUNoYW5nZWR9XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfUGhvbmVOdW1iZXJzX2NvdW50cnlcIlxuICAgICAgICAgICAgICAgIHZhbHVlPXtwaG9uZUNvdW50cnlJbnB1dH1cbiAgICAgICAgICAgICAgICBkaXNhYmxlZD17aXNWZXJpZnlpbmd9XG4gICAgICAgICAgICAgICAgaXNTbWFsbD17dHJ1ZX1cbiAgICAgICAgICAgICAgICBzaG93UHJlZml4PXt0cnVlfVxuICAgICAgICAgICAgLz5cbiAgICAgICAgKSA6IHVuZGVmaW5lZDtcblxuICAgIHJldHVybiAoXG4gICAgICAgIDxmb3JtIG9uU3VibWl0PXtvbkFkZENsaWNrfSBhdXRvQ29tcGxldGU9XCJvZmZcIiBub1ZhbGlkYXRlPXt0cnVlfT5cbiAgICAgICAgICAgIDxGaWVsZFxuICAgICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgICAgICAgICBsYWJlbD17XG4gICAgICAgICAgICAgICAgICAgIG1lZGl1bSA9PT0gXCJlbWFpbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICA/IF90KFwic2V0dGluZ3N8Z2VuZXJhbHxlbWFpbF9hZGRyZXNzX2xhYmVsXCIpXG4gICAgICAgICAgICAgICAgICAgICAgICA6IF90KFwic2V0dGluZ3N8Z2VuZXJhbHxtc2lzZG5fbGFiZWxcIilcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXV0b0NvbXBsZXRlPXttZWRpdW0gPT09IFwiZW1haWxcIiA/IFwiZW1haWxcIiA6IFwidGVsLW5hdGlvbmFsXCJ9XG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ9e2Rpc2FibGVkIHx8IGlzVmVyaWZ5aW5nfVxuICAgICAgICAgICAgICAgIHZhbHVlPXtuZXdUaHJlZXBpZElucHV0fVxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXtvbk5ld1RocmVlcGlkSW5wdXRDaGFuZ2V9XG4gICAgICAgICAgICAgICAgcHJlZml4Q29tcG9uZW50PXtwaG9uZUNvdW50cnl9XG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAgPEFjY2Vzc2libGVCdXR0b24gb25DbGljaz17b25BZGRDbGlja30ga2luZD1cInByaW1hcnlcIiBkaXNhYmxlZD17ZGlzYWJsZWR9PlxuICAgICAgICAgICAgICAgIHtfdChcImFjdGlvbnxhZGRcIil9XG4gICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgIDwvZm9ybT5cbiAgICApO1xufTtcblxuaW50ZXJmYWNlIEFkZFJlbW92ZVRocmVlcGlkc1Byb3BzIHtcbiAgICAvLyBXaGV0aGVyIHRoZSBjb250cm9sIGlzIGZvciBhZGRpbmcgM3BpZHMgdG8gdGhlIHVzZXIncyBob21lc2VydmVyIGFjY291bnQgb3Igc2hhcmluZyB0aGVtIG9uIGFuIElTXG4gICAgbW9kZTogVGhlZXBpZENvbnRyb2xNb2RlO1xuICAgIC8vIFdoZXRoZXIgdGhlIGNvbnRyb2wgaXMgZm9yIGVtYWlscyBvciBwaG9uZSBudW1iZXJzXG4gICAgbWVkaXVtOiBUaHJlZXBpZE1lZGl1bTtcbiAgICAvLyBUaGUgY3VycmVudCBsaXN0IG9mIHRoaXJkIHBhcnR5IGlkZW50aWZpZXJzXG4gICAgdGhyZWVwaWRzOiBUaGlyZFBhcnR5SWRlbnRpZmllcltdO1xuICAgIC8vIElmIHRydWUsIHRoZSBjb21wb25lbnQgaXMgZGlzYWJsZWQgYW5kIG5vIHRoaXJkIHBhcnR5IGlkZW50aWZpZXJzIGNhbiBiZSBhZGRlZCBvciByZW1vdmVkXG4gICAgZGlzYWJsZWQ/OiBib29sZWFuO1xuICAgIC8vIENhbGxlZCB3aGVuIGNoYW5nZXMgYXJlIG1hZGUgdG8gdGhlIGxpc3Qgb2YgdGhpcmQgcGFydHkgaWRlbnRpZmllcnNcbiAgICBvbkNoYW5nZTogKCkgPT4gdm9pZDtcbiAgICAvLyBJZiB0cnVlLCBhIHNwaW5uZXIgaXMgc2hvd24gaW5zdGVhZCBvZiB0aGUgY29tcG9uZW50XG4gICAgaXNMb2FkaW5nOiBib29sZWFuO1xufVxuXG5leHBvcnQgY29uc3QgQWRkUmVtb3ZlVGhyZWVwaWRzOiBSZWFjdC5GQzxBZGRSZW1vdmVUaHJlZXBpZHNQcm9wcz4gPSAoe1xuICAgIG1vZGUsXG4gICAgbWVkaXVtLFxuICAgI