UNPKG

matrix-react-sdk

Version:
266 lines (261 loc) 58 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _rendezvous = require("matrix-js-sdk/src/rendezvous"); var _chevronLeft = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/chevron-left")); var _checkCircleSolid = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/check-circle-solid")); var _error = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/error")); var _compoundWeb = require("@vector-im/compound-web"); var _classnames = _interopRequireDefault(require("classnames")); var _icons = require("@vector-im/compound-design-tokens/assets/web/icons"); var _languageHandler = require("../../../languageHandler"); var _AccessibleButton = _interopRequireDefault(require("../elements/AccessibleButton")); var _QRCode = _interopRequireDefault(require("../elements/QRCode")); var _Spinner = _interopRequireDefault(require("../elements/Spinner")); var _i = require("../../../../res/img/element-icons/i.svg"); var _LoginWithQRTypes = require("./LoginWithQR-types"); var _SdkConfig = _interopRequireDefault(require("../../../SdkConfig")); var _LoginWithQR = require("./LoginWithQR"); var _ErrorMessage = require("../../structures/ErrorMessage"); 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 2022-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. */ /** * @deprecated the MSC3906 implementation is deprecated in favour of MSC4108. */ // n.b MSC3886/MSC3903/MSC3906 that this is based on are now closed. // However, we want to keep this implementation around for some time. // TODO: define an end-of-life date for this implementation. /** * A component that implements the UI for sign in and E2EE set up with a QR code. * * This supports the unstable features of MSC3906 and MSC4108 */ class LoginWithQRFlow extends _react.default.Component { constructor(props) { super(props); (0, _defineProperty2.default)(this, "checkCodeInput", /*#__PURE__*/(0, _react.createRef)()); (0, _defineProperty2.default)(this, "handleClick", type => { return async e => { e.preventDefault(); await this.props.onClick(type, type === _LoginWithQRTypes.Click.Approve ? this.checkCodeInput.current?.value : undefined); }; }); (0, _defineProperty2.default)(this, "cancelButton", () => /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { "data-testid": "cancel-button", kind: "primary_outline", onClick: this.handleClick(_LoginWithQRTypes.Click.Cancel) }, (0, _languageHandler._t)("action|cancel"))); (0, _defineProperty2.default)(this, "simpleSpinner", description => { return /*#__PURE__*/_react.default.createElement("div", { className: "mx_LoginWithQR_spinner" }, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_Spinner.default, null), description && /*#__PURE__*/_react.default.createElement("p", null, description))); }); } render() { let main; let buttons; let backButton = true; let className = ""; switch (this.props.phase) { case _LoginWithQRTypes.Phase.Error: { backButton = false; let Icon = _error.default; let success = false; let title; let message; switch (this.props.failureReason) { case _rendezvous.MSC4108FailureReason.UnsupportedProtocol: case _rendezvous.LegacyRendezvousFailureReason.UnsupportedProtocol: title = (0, _languageHandler._t)("auth|qr_code_login|error_unsupported_protocol_title"); message = (0, _languageHandler._t)("auth|qr_code_login|error_unsupported_protocol"); break; case _rendezvous.MSC4108FailureReason.UserCancelled: case _rendezvous.LegacyRendezvousFailureReason.UserCancelled: title = (0, _languageHandler._t)("auth|qr_code_login|error_user_cancelled_title"); message = (0, _languageHandler._t)("auth|qr_code_login|error_user_cancelled"); break; case _rendezvous.MSC4108FailureReason.AuthorizationExpired: case _rendezvous.ClientRendezvousFailureReason.Expired: case _rendezvous.LegacyRendezvousFailureReason.Expired: title = (0, _languageHandler._t)("auth|qr_code_login|error_expired_title"); message = (0, _languageHandler._t)("auth|qr_code_login|error_expired"); break; case _rendezvous.ClientRendezvousFailureReason.InsecureChannelDetected: title = (0, _languageHandler._t)("auth|qr_code_login|error_insecure_channel_detected_title"); message = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, (0, _languageHandler._t)("auth|qr_code_login|error_insecure_channel_detected"), /*#__PURE__*/_react.default.createElement(_compoundWeb.Text, { as: "h2", size: "lg", weight: "semibold", "data-testid": "cancellation-message" }, (0, _languageHandler._t)("auth|qr_code_login|error_insecure_channel_detected_instructions")), /*#__PURE__*/_react.default.createElement("ol", null, /*#__PURE__*/_react.default.createElement("li", null, (0, _languageHandler._t)("auth|qr_code_login|error_insecure_channel_detected_instructions_1")), /*#__PURE__*/_react.default.createElement("li", null, (0, _languageHandler._t)("auth|qr_code_login|error_insecure_channel_detected_instructions_2")), /*#__PURE__*/_react.default.createElement("li", null, (0, _languageHandler._t)("auth|qr_code_login|error_insecure_channel_detected_instructions_3")))); break; case _rendezvous.ClientRendezvousFailureReason.OtherDeviceAlreadySignedIn: success = true; Icon = _checkCircleSolid.default; title = (0, _languageHandler._t)("auth|qr_code_login|error_other_device_already_signed_in_title"); message = (0, _languageHandler._t)("auth|qr_code_login|error_other_device_already_signed_in"); break; case _rendezvous.ClientRendezvousFailureReason.UserDeclined: title = (0, _languageHandler._t)("auth|qr_code_login|error_user_declined_title"); message = (0, _languageHandler._t)("auth|qr_code_login|error_user_declined"); break; case _LoginWithQR.LoginWithQRFailureReason.RateLimited: title = (0, _languageHandler._t)("error|something_went_wrong"); message = (0, _languageHandler._t)("auth|qr_code_login|error_rate_limited"); break; case _rendezvous.ClientRendezvousFailureReason.ETagMissing: title = (0, _languageHandler._t)("error|something_went_wrong"); message = (0, _languageHandler._t)("auth|qr_code_login|error_etag_missing"); break; case _rendezvous.LegacyRendezvousFailureReason.HomeserverLacksSupport: case _rendezvous.ClientRendezvousFailureReason.HomeserverLacksSupport: success = null; Icon = _icons.QrCodeIcon; backButton = true; title = (0, _languageHandler._t)("auth|qr_code_login|unsupported_heading"); message = (0, _languageHandler._t)("auth|qr_code_login|unsupported_explainer"); break; case _rendezvous.MSC4108FailureReason.DeviceAlreadyExists: case _rendezvous.MSC4108FailureReason.DeviceNotFound: case _rendezvous.MSC4108FailureReason.UnexpectedMessageReceived: case _rendezvous.ClientRendezvousFailureReason.OtherDeviceNotSignedIn: case _rendezvous.ClientRendezvousFailureReason.Unknown: default: title = (0, _languageHandler._t)("error|something_went_wrong"); message = (0, _languageHandler._t)("auth|qr_code_login|error_unexpected"); break; } className = "mx_LoginWithQR_error"; main = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", { className: (0, _classnames.default)("mx_LoginWithQR_icon", { "mx_LoginWithQR_icon--critical": success === false, "mx_LoginWithQR_icon--success": success === true }) }, /*#__PURE__*/_react.default.createElement(Icon, { width: "32px", height: "32px" })), /*#__PURE__*/_react.default.createElement(_compoundWeb.Heading, { as: "h1", size: "sm", weight: "semibold" }, title), typeof message === "object" ? message : /*#__PURE__*/_react.default.createElement("p", { "data-testid": "cancellation-message" }, message)); break; } case _LoginWithQRTypes.Phase.LegacyConnected: backButton = false; main = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("auth|qr_code_login|confirm_code_match")), /*#__PURE__*/_react.default.createElement("div", { className: "mx_LoginWithQR_confirmationDigits" }, this.props.confirmationDigits), /*#__PURE__*/_react.default.createElement("div", { className: "mx_LoginWithQR_confirmationAlert" }, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_i.Icon, null)), /*#__PURE__*/_react.default.createElement("div", null, (0, _languageHandler._t)("auth|qr_code_login|approve_access_warning")))); buttons = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { "data-testid": "approve-login-button", kind: "primary", onClick: this.handleClick(_LoginWithQRTypes.Click.Approve) }, (0, _languageHandler._t)("action|approve")), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { "data-testid": "decline-login-button", kind: "primary_outline", onClick: this.handleClick(_LoginWithQRTypes.Click.Decline) }, (0, _languageHandler._t)("action|cancel"))); break; case _LoginWithQRTypes.Phase.OutOfBandConfirmation: backButton = false; main = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_compoundWeb.Heading, { as: "h1", size: "sm", weight: "semibold" }, (0, _languageHandler._t)("auth|qr_code_login|check_code_heading")), /*#__PURE__*/_react.default.createElement(_compoundWeb.Text, { size: "md" }, (0, _languageHandler._t)("auth|qr_code_login|check_code_explainer")), /*#__PURE__*/_react.default.createElement("label", { htmlFor: "mx_LoginWithQR_checkCode" }, (0, _languageHandler._t)("auth|qr_code_login|check_code_input_label")), /*#__PURE__*/_react.default.createElement(_compoundWeb.MFAInput, { className: "mx_LoginWithQR_checkCode_input mx_no_textinput", ref: this.checkCodeInput, length: 2, autoFocus: true, id: "mx_LoginWithQR_checkCode", "data-invalid": this.props.failureReason === _LoginWithQR.LoginWithQRFailureReason.CheckCodeMismatch ? true : undefined }), /*#__PURE__*/_react.default.createElement(_ErrorMessage.ErrorMessage, { message: this.props.failureReason === _LoginWithQR.LoginWithQRFailureReason.CheckCodeMismatch ? (0, _languageHandler._t)("auth|qr_code_login|check_code_mismatch") : null })); buttons = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { "data-testid": "approve-login-button", kind: "primary", onClick: this.handleClick(_LoginWithQRTypes.Click.Approve) }, (0, _languageHandler._t)("action|continue")), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { "data-testid": "decline-login-button", kind: "primary_outline", onClick: this.handleClick(_LoginWithQRTypes.Click.Decline) }, (0, _languageHandler._t)("action|cancel"))); break; case _LoginWithQRTypes.Phase.ShowingQR: if (this.props.code) { const data = typeof this.props.code !== "string" ? this.props.code : Buffer.from(this.props.code ?? ""); main = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_compoundWeb.Heading, { as: "h1", size: "sm", weight: "semibold" }, (0, _languageHandler._t)("auth|qr_code_login|scan_code_instruction")), /*#__PURE__*/_react.default.createElement("div", { className: "mx_LoginWithQR_qrWrapper" }, /*#__PURE__*/_react.default.createElement(_QRCode.default, { data: [{ data, mode: "byte" }], className: "mx_QRCode" })), /*#__PURE__*/_react.default.createElement("ol", null, /*#__PURE__*/_react.default.createElement("li", null, (0, _languageHandler._t)("auth|qr_code_login|open_element_other_device", { brand: _SdkConfig.default.get().brand })), /*#__PURE__*/_react.default.createElement("li", null, (0, _languageHandler._t)("auth|qr_code_login|select_qr_code", { scanQRCode: /*#__PURE__*/_react.default.createElement("strong", null, (0, _languageHandler._t)("auth|qr_code_login|scan_qr_code")) })), /*#__PURE__*/_react.default.createElement("li", null, (0, _languageHandler._t)("auth|qr_code_login|point_the_camera")), /*#__PURE__*/_react.default.createElement("li", null, (0, _languageHandler._t)("auth|qr_code_login|follow_remaining_instructions")))); } else { main = this.simpleSpinner(); buttons = this.cancelButton(); } break; case _LoginWithQRTypes.Phase.Loading: main = this.simpleSpinner(); break; case _LoginWithQRTypes.Phase.WaitingForDevice: main = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, this.simpleSpinner((0, _languageHandler._t)("auth|qr_code_login|waiting_for_device")), this.props.userCode ? /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("auth|qr_code_login|security_code")), /*#__PURE__*/_react.default.createElement("p", null, (0, _languageHandler._t)("auth|qr_code_login|security_code_prompt")), /*#__PURE__*/_react.default.createElement("p", null, this.props.userCode)) : null); buttons = this.cancelButton(); break; case _LoginWithQRTypes.Phase.Verifying: main = this.simpleSpinner((0, _languageHandler._t)("auth|qr_code_login|completing_setup")); break; } return /*#__PURE__*/_react.default.createElement("div", { "data-testid": "login-with-qr", className: (0, _classnames.default)("mx_LoginWithQR", className) }, backButton ? /*#__PURE__*/_react.default.createElement("div", { className: "mx_LoginWithQR_heading" }, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { "data-testid": "back-button", className: "mx_LoginWithQR_BackButton", onClick: this.handleClick(_LoginWithQRTypes.Click.Back), title: "Back" }, /*#__PURE__*/_react.default.createElement(_chevronLeft.default, null)), /*#__PURE__*/_react.default.createElement("div", { className: "mx_LoginWithQR_breadcrumbs" }, (0, _languageHandler._t)("settings|sessions|title"), " / ", (0, _languageHandler._t)("settings|sessions|sign_in_with_qr"))) : null, /*#__PURE__*/_react.default.createElement("div", { className: "mx_LoginWithQR_main" }, main), /*#__PURE__*/_react.default.createElement("div", { className: "mx_LoginWithQR_buttons" }, buttons)); } } exports.default = LoginWithQRFlow; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfcmVuZGV6dm91cyIsIl9jaGV2cm9uTGVmdCIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfY2hlY2tDaXJjbGVTb2xpZCIsIl9lcnJvciIsIl9jb21wb3VuZFdlYiIsIl9jbGFzc25hbWVzIiwiX2ljb25zIiwiX2xhbmd1YWdlSGFuZGxlciIsIl9BY2Nlc3NpYmxlQnV0dG9uIiwiX1FSQ29kZSIsIl9TcGlubmVyIiwiX2kiLCJfTG9naW5XaXRoUVJUeXBlcyIsIl9TZGtDb25maWciLCJfTG9naW5XaXRoUVIiLCJfRXJyb3JNZXNzYWdlIiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiaGFzIiwiZ2V0IiwibiIsIl9fcHJvdG9fXyIsImEiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpIiwic2V0IiwiTG9naW5XaXRoUVJGbG93IiwiUmVhY3QiLCJDb21wb25lbnQiLCJjb25zdHJ1Y3RvciIsInByb3BzIiwiX2RlZmluZVByb3BlcnR5MiIsImNyZWF0ZVJlZiIsInR5cGUiLCJwcmV2ZW50RGVmYXVsdCIsIm9uQ2xpY2siLCJDbGljayIsIkFwcHJvdmUiLCJjaGVja0NvZGVJbnB1dCIsImN1cnJlbnQiLCJ2YWx1ZSIsInVuZGVmaW5lZCIsImNyZWF0ZUVsZW1lbnQiLCJraW5kIiwiaGFuZGxlQ2xpY2siLCJDYW5jZWwiLCJfdCIsImRlc2NyaXB0aW9uIiwiY2xhc3NOYW1lIiwicmVuZGVyIiwibWFpbiIsImJ1dHRvbnMiLCJiYWNrQnV0dG9uIiwicGhhc2UiLCJQaGFzZSIsIkVycm9yIiwiSWNvbiIsIkVycm9ySWNvbiIsInN1Y2Nlc3MiLCJ0aXRsZSIsIm1lc3NhZ2UiLCJmYWlsdXJlUmVhc29uIiwiTVNDNDEwOEZhaWx1cmVSZWFzb24iLCJVbnN1cHBvcnRlZFByb3RvY29sIiwiTGVnYWN5UmVuZGV6dm91c0ZhaWx1cmVSZWFzb24iLCJVc2VyQ2FuY2VsbGVkIiwiQXV0aG9yaXphdGlvbkV4cGlyZWQiLCJDbGllbnRSZW5kZXp2b3VzRmFpbHVyZVJlYXNvbiIsIkV4cGlyZWQiLCJJbnNlY3VyZUNoYW5uZWxEZXRlY3RlZCIsIkZyYWdtZW50IiwiVGV4dCIsImFzIiwic2l6ZSIsIndlaWdodCIsIk90aGVyRGV2aWNlQWxyZWFkeVNpZ25lZEluIiwiQ2hlY2tDaXJjbGVTb2xpZEljb24iLCJVc2VyRGVjbGluZWQiLCJMb2dpbldpdGhRUkZhaWx1cmVSZWFzb24iLCJSYXRlTGltaXRlZCIsIkVUYWdNaXNzaW5nIiwiSG9tZXNlcnZlckxhY2tzU3VwcG9ydCIsIlFyQ29kZUljb24iLCJEZXZpY2VBbHJlYWR5RXhpc3RzIiwiRGV2aWNlTm90Rm91bmQiLCJVbmV4cGVjdGVkTWVzc2FnZVJlY2VpdmVkIiwiT3RoZXJEZXZpY2VOb3RTaWduZWRJbiIsIlVua25vd24iLCJjbGFzc05hbWVzIiwid2lkdGgiLCJoZWlnaHQiLCJIZWFkaW5nIiwiTGVnYWN5Q29ubmVjdGVkIiwiY29uZmlybWF0aW9uRGlnaXRzIiwiRGVjbGluZSIsIk91dE9mQmFuZENvbmZpcm1hdGlvbiIsImh0bWxGb3IiLCJNRkFJbnB1dCIsInJlZiIsImxlbmd0aCIsImF1dG9Gb2N1cyIsImlkIiwiQ2hlY2tDb2RlTWlzbWF0Y2giLCJFcnJvck1lc3NhZ2UiLCJTaG93aW5nUVIiLCJjb2RlIiwiZGF0YSIsIkJ1ZmZlciIsImZyb20iLCJtb2RlIiwiYnJhbmQiLCJTZGtDb25maWciLCJzY2FuUVJDb2RlIiwic2ltcGxlU3Bpbm5lciIsImNhbmNlbEJ1dHRvbiIsIkxvYWRpbmciLCJXYWl0aW5nRm9yRGV2aWNlIiwidXNlckNvZGUiLCJWZXJpZnlpbmciLCJCYWNrIiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL2F1dGgvTG9naW5XaXRoUVJGbG93LnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuQ29weXJpZ2h0IDIwMjQgTmV3IFZlY3RvciBMdGQuXG5Db3B5cmlnaHQgMjAyMi0yMDI0IFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCBSZWFjdCwgeyBjcmVhdGVSZWYsIFJlYWN0Tm9kZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHtcbiAgICBDbGllbnRSZW5kZXp2b3VzRmFpbHVyZVJlYXNvbixcbiAgICBMZWdhY3lSZW5kZXp2b3VzRmFpbHVyZVJlYXNvbixcbiAgICBNU0M0MTA4RmFpbHVyZVJlYXNvbixcbn0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL3JlbmRlenZvdXNcIjtcbmltcG9ydCBDaGV2cm9uTGVmdEljb24gZnJvbSBcIkB2ZWN0b3ItaW0vY29tcG91bmQtZGVzaWduLXRva2Vucy9hc3NldHMvd2ViL2ljb25zL2NoZXZyb24tbGVmdFwiO1xuaW1wb3J0IENoZWNrQ2lyY2xlU29saWRJY29uIGZyb20gXCJAdmVjdG9yLWltL2NvbXBvdW5kLWRlc2lnbi10b2tlbnMvYXNzZXRzL3dlYi9pY29ucy9jaGVjay1jaXJjbGUtc29saWRcIjtcbmltcG9ydCBFcnJvckljb24gZnJvbSBcIkB2ZWN0b3ItaW0vY29tcG91bmQtZGVzaWduLXRva2Vucy9hc3NldHMvd2ViL2ljb25zL2Vycm9yXCI7XG5pbXBvcnQgeyBIZWFkaW5nLCBNRkFJbnB1dCwgVGV4dCB9IGZyb20gXCJAdmVjdG9yLWltL2NvbXBvdW5kLXdlYlwiO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSBcImNsYXNzbmFtZXNcIjtcbmltcG9ydCB7IFFyQ29kZUljb24gfSBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC1kZXNpZ24tdG9rZW5zL2Fzc2V0cy93ZWIvaWNvbnNcIjtcblxuaW1wb3J0IHsgX3QgfSBmcm9tIFwiLi4vLi4vLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgQWNjZXNzaWJsZUJ1dHRvbiBmcm9tIFwiLi4vZWxlbWVudHMvQWNjZXNzaWJsZUJ1dHRvblwiO1xuaW1wb3J0IFFSQ29kZSBmcm9tIFwiLi4vZWxlbWVudHMvUVJDb2RlXCI7XG5pbXBvcnQgU3Bpbm5lciBmcm9tIFwiLi4vZWxlbWVudHMvU3Bpbm5lclwiO1xuaW1wb3J0IHsgSWNvbiBhcyBJbmZvSWNvbiB9IGZyb20gXCIuLi8uLi8uLi8uLi9yZXMvaW1nL2VsZW1lbnQtaWNvbnMvaS5zdmdcIjtcbmltcG9ydCB7IENsaWNrLCBQaGFzZSB9IGZyb20gXCIuL0xvZ2luV2l0aFFSLXR5cGVzXCI7XG5pbXBvcnQgU2RrQ29uZmlnIGZyb20gXCIuLi8uLi8uLi9TZGtDb25maWdcIjtcbmltcG9ydCB7IEZhaWx1cmVSZWFzb24sIExvZ2luV2l0aFFSRmFpbHVyZVJlYXNvbiB9IGZyb20gXCIuL0xvZ2luV2l0aFFSXCI7XG5pbXBvcnQgeyBYT1IgfSBmcm9tIFwiLi4vLi4vLi4vQHR5cGVzL2NvbW1vblwiO1xuaW1wb3J0IHsgRXJyb3JNZXNzYWdlIH0gZnJvbSBcIi4uLy4uL3N0cnVjdHVyZXMvRXJyb3JNZXNzYWdlXCI7XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgdGhlIE1TQzM5MDYgaW1wbGVtZW50YXRpb24gaXMgZGVwcmVjYXRlZCBpbiBmYXZvdXIgb2YgTVNDNDEwOC5cbiAqL1xuaW50ZXJmYWNlIE1TQzM5MDZQcm9wcyBleHRlbmRzIFBpY2s8UHJvcHMsIFwicGhhc2VcIiB8IFwib25DbGlja1wiIHwgXCJmYWlsdXJlUmVhc29uXCI+IHtcbiAgICBjb2RlPzogc3RyaW5nO1xuICAgIGNvbmZpcm1hdGlvbkRpZ2l0cz86IHN0cmluZztcbn1cblxuaW50ZXJmYWNlIFByb3BzIHtcbiAgICBwaGFzZTogUGhhc2U7XG4gICAgY29kZT86IFVpbnQ4QXJyYXk7XG4gICAgb25DbGljayh0eXBlOiBDbGljaywgY2hlY2tDb2RlRW50ZXJlZD86IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gICAgZmFpbHVyZVJlYXNvbj86IEZhaWx1cmVSZWFzb247XG4gICAgdXNlckNvZGU/OiBzdHJpbmc7XG4gICAgY2hlY2tDb2RlPzogc3RyaW5nO1xufVxuXG4vLyBuLmIgTVNDMzg4Ni9NU0MzOTAzL01TQzM5MDYgdGhhdCB0aGlzIGlzIGJhc2VkIG9uIGFyZSBub3cgY2xvc2VkLlxuLy8gSG93ZXZlciwgd2Ugd2FudCB0byBrZWVwIHRoaXMgaW1wbGVtZW50YXRpb24gYXJvdW5kIGZvciBzb21lIHRpbWUuXG4vLyBUT0RPOiBkZWZpbmUgYW4gZW5kLW9mLWxpZmUgZGF0ZSBmb3IgdGhpcyBpbXBsZW1lbnRhdGlvbi5cblxuLyoqXG4gKiBBIGNvbXBvbmVudCB0aGF0IGltcGxlbWVudHMgdGhlIFVJIGZvciBzaWduIGluIGFuZCBFMkVFIHNldCB1cCB3aXRoIGEgUVIgY29kZS5cbiAqXG4gKiBUaGlzIHN1cHBvcnRzIHRoZSB1bnN0YWJsZSBmZWF0dXJlcyBvZiBNU0MzOTA2IGFuZCBNU0M0MTA4XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIExvZ2luV2l0aFFSRmxvdyBleHRlbmRzIFJlYWN0LkNvbXBvbmVudDxYT1I8UHJvcHMsIE1TQzM5MDZQcm9wcz4+IHtcbiAgICBwcml2YXRlIGNoZWNrQ29kZUlucHV0ID0gY3JlYXRlUmVmPEhUTUxJbnB1dEVsZW1lbnQ+KCk7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJvcHM6IFhPUjxQcm9wcywgTVNDMzkwNlByb3BzPikge1xuICAgICAgICBzdXBlcihwcm9wcyk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBoYW5kbGVDbGljayA9ICh0eXBlOiBDbGljayk6ICgoZTogUmVhY3QuRm9ybUV2ZW50KSA9PiBQcm9taXNlPHZvaWQ+KSA9PiB7XG4gICAgICAgIHJldHVybiBhc3luYyAoZTogUmVhY3QuRm9ybUV2ZW50KTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnByb3BzLm9uQ2xpY2sodHlwZSwgdHlwZSA9PT0gQ2xpY2suQXBwcm92ZSA/IHRoaXMuY2hlY2tDb2RlSW5wdXQuY3VycmVudD8udmFsdWUgOiB1bmRlZmluZWQpO1xuICAgICAgICB9O1xuICAgIH07XG5cbiAgICBwcml2YXRlIGNhbmNlbEJ1dHRvbiA9ICgpOiBKU1guRWxlbWVudCA9PiAoXG4gICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uIGRhdGEtdGVzdGlkPVwiY2FuY2VsLWJ1dHRvblwiIGtpbmQ9XCJwcmltYXJ5X291dGxpbmVcIiBvbkNsaWNrPXt0aGlzLmhhbmRsZUNsaWNrKENsaWNrLkNhbmNlbCl9PlxuICAgICAgICAgICAge190KFwiYWN0aW9ufGNhbmNlbFwiKX1cbiAgICAgICAgPC9BY2Nlc3NpYmxlQnV0dG9uPlxuICAgICk7XG5cbiAgICBwcml2YXRlIHNpbXBsZVNwaW5uZXIgPSAoZGVzY3JpcHRpb24/OiBzdHJpbmcpOiBKU1guRWxlbWVudCA9PiB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X0xvZ2luV2l0aFFSX3NwaW5uZXJcIj5cbiAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICA8U3Bpbm5lciAvPlxuICAgICAgICAgICAgICAgICAgICB7ZGVzY3JpcHRpb24gJiYgPHA+e2Rlc2NyaXB0aW9ufTwvcD59XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9O1xuXG4gICAgcHVibGljIHJlbmRlcigpOiBSZWFjdC5SZWFjdE5vZGUge1xuICAgICAgICBsZXQgbWFpbjogSlNYLkVsZW1lbnQgfCB1bmRlZmluZWQ7XG4gICAgICAgIGxldCBidXR0b25zOiBKU1guRWxlbWVudCB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGJhY2tCdXR0b24gPSB0cnVlO1xuICAgICAgICBsZXQgY2xhc3NOYW1lID0gXCJcIjtcblxuICAgICAgICBzd2l0Y2ggKHRoaXMucHJvcHMucGhhc2UpIHtcbiAgICAgICAgICAgIGNhc2UgUGhhc2UuRXJyb3I6IHtcbiAgICAgICAgICAgICAgICBiYWNrQnV0dG9uID0gZmFsc2U7XG5cbiAgICAgICAgICAgICAgICBsZXQgSWNvbiA9IEVycm9ySWNvbjtcbiAgICAgICAgICAgICAgICBsZXQgc3VjY2VzczogYm9vbGVhbiB8IG51bGwgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBsZXQgdGl0bGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICBsZXQgbWVzc2FnZTogUmVhY3ROb2RlIHwgdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgc3dpdGNoICh0aGlzLnByb3BzLmZhaWx1cmVSZWFzb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBNU0M0MTA4RmFpbHVyZVJlYXNvbi5VbnN1cHBvcnRlZFByb3RvY29sOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIExlZ2FjeVJlbmRlenZvdXNGYWlsdXJlUmVhc29uLlVuc3VwcG9ydGVkUHJvdG9jb2w6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9IF90KFwiYXV0aHxxcl9jb2RlX2xvZ2lufGVycm9yX3Vuc3VwcG9ydGVkX3Byb3RvY29sX3RpdGxlXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IF90KFwiYXV0aHxxcl9jb2RlX2xvZ2lufGVycm9yX3Vuc3VwcG9ydGVkX3Byb3RvY29sXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBNU0M0MTA4RmFpbHVyZVJlYXNvbi5Vc2VyQ2FuY2VsbGVkOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIExlZ2FjeVJlbmRlenZvdXNGYWlsdXJlUmVhc29uLlVzZXJDYW5jZWxsZWQ6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9IF90KFwiYXV0aHxxcl9jb2RlX2xvZ2lufGVycm9yX3VzZXJfY2FuY2VsbGVkX3RpdGxlXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IF90KFwiYXV0aHxxcl9jb2RlX2xvZ2lufGVycm9yX3VzZXJfY2FuY2VsbGVkXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBNU0M0MTA4RmFpbHVyZVJlYXNvbi5BdXRob3JpemF0aW9uRXhwaXJlZDpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBDbGllbnRSZW5kZXp2b3VzRmFpbHVyZVJlYXNvbi5FeHBpcmVkOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIExlZ2FjeVJlbmRlenZvdXNGYWlsdXJlUmVhc29uLkV4cGlyZWQ6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9IF90KFwiYXV0aHxxcl9jb2RlX2xvZ2lufGVycm9yX2V4cGlyZWRfdGl0bGVcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gX3QoXCJhdXRofHFyX2NvZGVfbG9naW58ZXJyb3JfZXhwaXJlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgQ2xpZW50UmVuZGV6dm91c0ZhaWx1cmVSZWFzb24uSW5zZWN1cmVDaGFubmVsRGV0ZWN0ZWQ6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9IF90KFwiYXV0aHxxcl9jb2RlX2xvZ2lufGVycm9yX2luc2VjdXJlX2NoYW5uZWxfZGV0ZWN0ZWRfdGl0bGVcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtfdChcImF1dGh8cXJfY29kZV9sb2dpbnxlcnJvcl9pbnNlY3VyZV9jaGFubmVsX2RldGVjdGVkXCIpfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxUZXh0IGFzPVwiaDJcIiBzaXplPVwibGdcIiB3ZWlnaHQ9XCJzZW1pYm9sZFwiIGRhdGEtdGVzdGlkPVwiY2FuY2VsbGF0aW9uLW1lc3NhZ2VcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtfdChcImF1dGh8cXJfY29kZV9sb2dpbnxlcnJvcl9pbnNlY3VyZV9jaGFubmVsX2RldGVjdGVkX2luc3RydWN0aW9uc1wiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9UZXh0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8b2w+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGk+e190KFwiYXV0aHxxcl9jb2RlX2xvZ2lufGVycm9yX2luc2VjdXJlX2NoYW5uZWxfZGV0ZWN0ZWRfaW5zdHJ1Y3Rpb25zXzFcIil9PC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaT57X3QoXCJhdXRofHFyX2NvZGVfbG9naW58ZXJyb3JfaW5zZWN1cmVfY2hhbm5lbF9kZXRlY3RlZF9pbnN0cnVjdGlvbnNfMlwiKX08L2xpPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpPntfdChcImF1dGh8cXJfY29kZV9sb2dpbnxlcnJvcl9pbnNlY3VyZV9jaGFubmVsX2RldGVjdGVkX2luc3RydWN0aW9uc18zXCIpfTwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvb2w+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC8+XG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBDbGllbnRSZW5kZXp2b3VzRmFpbHVyZVJlYXNvbi5PdGhlckRldmljZUFscmVhZHlTaWduZWRJbjpcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1Y2Nlc3MgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgSWNvbiA9IENoZWNrQ2lyY2xlU29saWRJY29uO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSBfdChcImF1dGh8cXJfY29kZV9sb2dpbnxlcnJvcl9vdGhlcl9kZXZpY2VfYWxyZWFkeV9zaWduZWRfaW5fdGl0bGVcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gX3QoXCJhdXRofHFyX2NvZGVfbG9naW58ZXJyb3Jfb3RoZXJfZGV2aWNlX2FscmVhZHlfc2lnbmVkX2luXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBDbGllbnRSZW5kZXp2b3VzRmFpbHVyZVJlYXNvbi5Vc2VyRGVjbGluZWQ6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9IF90KFwiYXV0aHxxcl9jb2RlX2xvZ2lufGVycm9yX3VzZXJfZGVjbGluZWRfdGl0bGVcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gX3QoXCJhdXRofHFyX2NvZGVfbG9naW58ZXJyb3JfdXNlcl9kZWNsaW5lZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgTG9naW5XaXRoUVJGYWlsdXJlUmVhc29uLlJhdGVMaW1pdGVkOlxuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSBfdChcImVycm9yfHNvbWV0aGluZ193ZW50X3dyb25nXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IF90KFwiYXV0aHxxcl9jb2RlX2xvZ2lufGVycm9yX3JhdGVfbGltaXRlZFwiKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgQ2xpZW50UmVuZGV6dm91c0ZhaWx1cmVSZWFzb24uRVRhZ01pc3Npbmc6XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9IF90KFwiZXJyb3J8c29tZXRoaW5nX3dlbnRfd3JvbmdcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gX3QoXCJhdXRofHFyX2NvZGVfbG9naW58ZXJyb3JfZXRhZ19taXNzaW5nXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBMZWdhY3lSZW5kZXp2b3VzRmFpbHVyZVJlYXNvbi5Ib21lc2VydmVyTGFja3NTdXBwb3J0OlxuICAgICAgICAgICAgICAgICAgICBjYXNlIENsaWVudFJlbmRlenZvdXNGYWlsdXJlUmVhc29uLkhvbWVzZXJ2ZXJMYWNrc1N1cHBvcnQ6XG4gICAgICAgICAgICAgICAgICAgICAgICBzdWNjZXNzID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIEljb24gPSBRckNvZGVJY29uO1xuICAgICAgICAgICAgICAgICAgICAgICAgYmFja0J1dHRvbiA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZSA9IF90KFwiYXV0aHxxcl9jb2RlX2xvZ2lufHVuc3VwcG9ydGVkX2hlYWRpbmdcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gX3QoXCJhdXRofHFyX2NvZGVfbG9naW58dW5zdXBwb3J0ZWRfZXhwbGFpbmVyXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgICAgICAgICAgY2FzZSBNU0M0MTA4RmFpbHVyZVJlYXNvbi5EZXZpY2VBbHJlYWR5RXhpc3RzOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIE1TQzQxMDhGYWlsdXJlUmVhc29uLkRldmljZU5vdEZvdW5kOlxuICAgICAgICAgICAgICAgICAgICBjYXNlIE1TQzQxMDhGYWlsdXJlUmVhc29uLlVuZXhwZWN0ZWRNZXNzYWdlUmVjZWl2ZWQ6XG4gICAgICAgICAgICAgICAgICAgIGNhc2UgQ2xpZW50UmVuZGV6dm91c0ZhaWx1cmVSZWFzb24uT3RoZXJEZXZpY2VOb3RTaWduZWRJbjpcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBDbGllbnRSZW5kZXp2b3VzRmFpbHVyZVJlYXNvbi5Vbmtub3duOlxuICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSBfdChcImVycm9yfHNvbWV0aGluZ193ZW50X3dyb25nXCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IF90KFwiYXV0aHxxcl9jb2RlX2xvZ2lufGVycm9yX3VuZXhwZWN0ZWRcIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lID0gXCJteF9Mb2dpbldpdGhRUl9lcnJvclwiO1xuICAgICAgICAgICAgICAgIG1haW4gPSAoXG4gICAgICAgICAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtjbGFzc05hbWVzKFwibXhfTG9naW5XaXRoUVJfaWNvblwiLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwibXhfTG9naW5XaXRoUVJfaWNvbi0tY3JpdGljYWxcIjogc3VjY2VzcyA9PT0gZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwibXhfTG9naW5XaXRoUVJfaWNvbi0tc3VjY2Vzc1wiOiBzdWNjZXNzID09PSB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pfVxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxJY29uIHdpZHRoPVwiMzJweFwiIGhlaWdodD1cIjMycHhcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8SGVhZGluZyBhcz1cImgxXCIgc2l6ZT1cInNtXCIgd2VpZ2h0PVwic2VtaWJvbGRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dGl0bGV9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L0hlYWRpbmc+XG4gICAgICAgICAgICAgICAgICAgICAgICB7dHlwZW9mIG1lc3NhZ2UgPT09IFwib2JqZWN0XCIgPyBtZXNzYWdlIDogPHAgZGF0YS10ZXN0aWQ9XCJjYW5jZWxsYXRpb24tbWVzc2FnZVwiPnttZXNzYWdlfTwvcD59XG4gICAgICAgICAgICAgICAgICAgIDwvPlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFBoYXNlLkxlZ2FjeUNvbm5lY3RlZDpcbiAgICAgICAgICAgICAgICBiYWNrQnV0dG9uID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgbWFpbiA9IChcbiAgICAgICAgICAgICAgICAgICAgPD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxwPntfdChcImF1dGh8cXJfY29kZV9sb2dpbnxjb25maXJtX2NvZGVfbWF0Y2hcIil9PC9wPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9Mb2dpbldpdGhRUl9jb25maXJtYXRpb25EaWdpdHNcIj57dGhpcy5wcm9wcy5jb25maXJtYXRpb25EaWdpdHN9PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X0xvZ2luV2l0aFFSX2NvbmZpcm1hdGlvbkFsZXJ0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPEluZm9JY29uIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdj57X3QoXCJhdXRofHFyX2NvZGVfbG9naW58YXBwcm92ZV9hY2Nlc3Nfd2FybmluZ1wiKX08L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8Lz5cbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgYnV0dG9ucyA9IChcbiAgICAgICAgICAgICAgICAgICAgPD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJhcHByb3ZlLWxvZ2luLWJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAga2luZD1cInByaW1hcnlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMuaGFuZGxlQ2xpY2soQ2xpY2suQXBwcm92ZSl9XG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge190KFwiYWN0aW9ufGFwcHJvdmVcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwiZGVjbGluZS1sb2dpbi1idXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpbmQ9XCJwcmltYXJ5X291dGxpbmVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMuaGFuZGxlQ2xpY2soQ2xpY2suRGVjbGluZSl9XG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge190KFwiYWN0aW9ufGNhbmNlbFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC8+XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgUGhhc2UuT3V0T2ZCYW5kQ29uZmlybWF0aW9uOlxuICAgICAgICAgICAgICAgIGJhY2tCdXR0b24gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICBtYWluID0gKFxuICAgICAgICAgICAgICAgICAgICA8PlxuICAgICAgICAgICAgICAgICAgICAgICAgPEhlYWRpbmcgYXM9XCJoMVwiIHNpemU9XCJzbVwiIHdlaWdodD1cInNlbWlib2xkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge190KFwiYXV0aHxxcl9jb2RlX2xvZ2lufGNoZWNrX2NvZGVfaGVhZGluZ1wiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvSGVhZGluZz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxUZXh0IHNpemU9XCJtZFwiPntfdChcImF1dGh8cXJfY29kZV9sb2dpbnxjaGVja19jb2RlX2V4cGxhaW5lclwiKX08L1RleHQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgaHRtbEZvcj1cIm14X0xvZ2luV2l0aFFSX2NoZWNrQ29kZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtfdChcImF1dGh8cXJfY29kZV9sb2dpbnxjaGVja19jb2RlX2lucHV0X2xhYmVsXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxNRkFJbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X0xvZ2luV2l0aFFSX2NoZWNrQ29kZV9pbnB1dCBteF9ub190ZXh0aW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZj17dGhpcy5jaGVja0NvZGVJbnB1dH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGg9ezJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0b0ZvY3VzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWQ9XCJteF9Mb2dpbldpdGhRUl9jaGVja0NvZGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEtaW52YWxpZD17XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucHJvcHMuZmFpbHVyZVJlYXNvbiA9PT0gTG9naW5XaXRoUVJGYWlsdXJlUmVhc29uLkNoZWNrQ29kZU1pc21hdGNoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IHRydWVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxFcnJvck1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlPXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5mYWlsdXJlUmVhc29uID09PSBMb2dpbldpdGhRUkZhaWx1cmVSZWFzb24uQ2hlY2tDb2RlTWlzbWF0Y2hcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gX3QoXCJhdXRofHFyX2NvZGVfbG9naW58Y2hlY2tfY29kZV9taXNtYXRjaFwiKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBudWxsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPC8+XG4gICAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICAgIGJ1dHRvbnMgPSAoXG4gICAgICAgICAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwiYXBwcm92ZS1sb2dpbi1idXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpbmQ9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXt0aGlzLmhhbmRsZUNsaWNrKENsaWNrLkFwcHJvdmUpfVxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtfdChcImFjdGlvbnxjb250aW51ZVwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJkZWNsaW5lLWxvZ2luLWJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAga2luZD1cInByaW1hcnlfb3V0bGluZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5oYW5kbGVDbGljayhDbGljay5EZWNsaW5lKX1cbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJhY3Rpb258Y2FuY2VsXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9BY2Nlc3NpYmxlQnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8Lz5cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBQaGFzZS5TaG93aW5nUVI6XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMuY29kZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkYXRhID1cbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGVvZiB0aGlzLnByb3BzLmNvZGUgIT09IFwic3RyaW5nXCIgPyB0aGlzLnByb3BzLmNvZGUgOiBCdWZmZXIuZnJvbSh0aGlzLnByb3BzLmNvZGUgPz8gXCJcIik7XG5cbiAgICAgICAgICAgICAgICAgICAgbWFpbiA9IChcbiAgICAgICAgICAgICAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPEhlYWRpbmcgYXM9XCJoMVwiIHNpemU9XCJzbVwiIHdlaWdodD1cInNlbWlib2xkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtfdChcImF1dGh8cXJfY29kZV9sb2dpbnxzY2FuX2NvZGVfaW5zdHJ1Y3Rpb25cIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9IZWFkaW5nPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTG9naW5XaXRoUVJfcXJXcmFwcGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxRUkNvZGUgZGF0YT17W3sgZGF0YSwgbW9kZTogXCJieXRlXCIgfV19IGNsYXNzTmFtZT1cIm14X1FSQ29kZVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG9sPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJhdXRofHFyX2NvZGVfbG9naW58b3Blbl9lbGVtZW50X290aGVyX2RldmljZVwiLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJhbmQ6IFNka0NvbmZpZy5nZXQoKS5icmFuZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJhdXRofHFyX2NvZGVfbG9naW58c2VsZWN0X3FyX2NvZGVcIiwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjYW5RUkNvZGU6IDxzdHJvbmc+e190KFwiYXV0aHxxcl9jb2RlX2xvZ2lufHNjYW5fcXJfY29kZVwiKX08L3N0cm9uZz4sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGxpPntfdChcImF1dGh8cXJfY29kZV9sb2dpbnxwb2ludF90aGVfY2FtZXJhXCIpfTwvbGk+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxsaT57X3QoXCJhdXRofHFyX2NvZGVfbG9naW58Zm9sbG93X3JlbWFpbmluZ19pbnN0cnVjdGlvbnNcIil9PC9saT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L29sPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC8+XG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbWFpbiA9IHRoaXMuc2ltcGxlU3Bpbm5lcigpO1xuICAgICAgICAgICAgICAgICAgICBidXR0b25zID0gdGhpcy5jYW5jZWxCdXR0b24oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIFBoYXNlLkxvYWRpbmc6XG4gICAgICAgICAgICAgICAgbWFpbiA9IHRoaXMuc2ltcGxlU3Bpbm5lcigpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBQaGFzZS5XYWl0aW5nRm9yRGV2aWNlOlxuICAgICAgICAgICAgICAgIG1haW4gPSAoXG4gICAgICAgICAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgICAgICAgICAgICB7dGhpcy5zaW1wbGVTcGlubmVyKF90KFwiYXV0aHxxcl9jb2RlX2xvZ2lufHdhaXRpbmdfZm9yX2RldmljZVwiKSl9XG4gICAgICAgICAgICAgICAgICAgICAgICB7dGhpcy5wcm9wcy51c2VyQ29kZSA/IChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cD57X3QoXCJhdXRofHFyX2NvZGVfbG9naW58c2VjdXJpdHlfY29kZVwiKX08L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwPntfdChcImF1dGh8cXJfY29kZV9sb2dpbnxzZWN1cml0eV9jb2RlX3Byb21wdFwiKX08L3A+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxwPnt0aGlzLnByb3BzLnVzZXJDb2RlfTwvcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICkgOiBudWxsfVxuICAgICAgICAgICAgICAgICAgICA8Lz5cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIGJ1dHRvbnMgPSB0aGlzLmNhbmNlbEJ1dHRvbigpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSBQaGFzZS5WZXJpZnlpbmc6XG4gICAgICAgICAgICAgICAgbWFpbiA9IHRoaXMuc2ltcGxlU3Bpbm5lcihfdChcImF1dGh8cXJfY29kZV9sb2dpbnxjb21wbGV0aW5nX3NldHVwXCIpKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2IGRhdGEtdGVzdGlkPVwibG9naW4td2l0aC1xclwiIGNsYXNzTmFtZT17Y2xhc3NOYW1lcyhcIm14X0xvZ2luV2l0aFFSXCIsIGNsYXNzTmFtZSl9PlxuICAgICAgICAgICAgICAgIHtiYWNrQnV0dG9uID8gKFxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X0xvZ2luV2l0aFFSX2hlYWRpbmdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJiYWNrLWJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfTG9naW5XaXRoUVJfQmFja0J1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5oYW5kbGVDbGljayhDbGljay5CYWNrKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkJhY2tcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxDaGV2cm9uTGVmdEljb24gLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTG9naW5XaXRoUVJfYnJlYWRjcnVtYnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7X3QoXCJzZXR0aW5nc3xzZXNzaW9uc3x0aXRsZVwiKX0gLyB7X3QoXCJzZXR0aW5nc3xzZXNzaW9uc3xzaWduX2luX3dpdGhfcXJcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgKSA6IG51bGx9XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9Mb2dpbldpdGhRUl9tYWluXCI+e21haW59PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9Mb2dpbldpdGhRUl9idXR0b25zXCI+e2J1dHRvbnN9PC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBUUEsSUFBQUEsTUFBQSxHQUFBQyx1QkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsV0FBQSxHQUFBRCxPQUFBO0FBS0EsSUFBQUUsWUFBQSxHQUFBQyxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQUksaUJBQUEsR0FBQUQsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFLLE1BQUEsR0FBQUYsc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFNLFlBQUEsR0FBQU4sT0FBQTtBQUNBLElBQUFPLFdBQUEsR0FBQUosc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFRLE1BQUEsR0FBQVIsT0FBQTtBQUVBLElBQUFTLGdCQUFBLEdBQUFULE9BQUE7QUFDQSxJQUFBVSxpQkFBQSxHQUFBUCxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQVcsT0FBQSxHQUFBUixzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQVksUUFBQSxHQUFBVCxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQWEsRUFBQSxHQUFBYixPQUFBO0FBQ0EsSUFBQWMsaUJBQUEsR0FBQWQsT0FBQTtBQUNBLElBQUFlLFVBQUEsR0FBQVosc0JBQUEsQ0FBQUgsT0FBQTtBQUNBLElBQUFnQixZQUFBLEdBQUFoQixPQUFBO0FBRUEsSUFBQWlCLGFBQUEsR0FBQWpCLE9BQUE7QUFBNkQsU0FBQWtCLHlCQUFBQyxDQUFBLDZCQUFBQyxPQUFBLG1CQUFBQyxDQUFBLE9BQUFELE9BQUEsSUFBQUUsQ0FBQSxPQUFBRixPQUFBLFlBQUFGLHdC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