UNPKG

matrix-react-sdk

Version:
663 lines (659 loc) 98.2 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 = _interopRequireDefault(require("react")); var _matrix = require("matrix-js-sdk/src/matrix"); var _types = require("matrix-js-sdk/src/types"); var _classnames = _interopRequireDefault(require("classnames")); var _RoomViewLifecycle = require("@matrix-org/react-sdk-module-api/lib/lifecycles/RoomViewLifecycle"); var _MatrixClientPeg = require("../../../MatrixClientPeg"); var _dispatcher = _interopRequireDefault(require("../../../dispatcher/dispatcher")); var _languageHandler = require("../../../languageHandler"); var _SdkConfig = _interopRequireDefault(require("../../../SdkConfig")); var _IdentityAuthClient = _interopRequireDefault(require("../../../IdentityAuthClient")); var _InviteReason = _interopRequireDefault(require("../elements/InviteReason")); var _Spinner = _interopRequireDefault(require("../elements/Spinner")); var _AccessibleButton = _interopRequireDefault(require("../elements/AccessibleButton")); var _RoomAvatar = _interopRequireDefault(require("../avatars/RoomAvatar")); var _SettingsStore = _interopRequireDefault(require("../../../settings/SettingsStore")); var _UIFeature = require("../../../settings/UIFeature"); var _ModuleRunner = require("../../../modules/ModuleRunner"); var _askToJoin = require("../../../../res/img/element-icons/ask-to-join.svg"); var _Field = _interopRequireDefault(require("../elements/Field")); /* Copyright 2024 New Vector Ltd. Copyright 2015-2021 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. */ const MemberEventHtmlReasonField = "io.element.html_reason"; var MessageCase = /*#__PURE__*/function (MessageCase) { MessageCase["NotLoggedIn"] = "NotLoggedIn"; MessageCase["Joining"] = "Joining"; MessageCase["Loading"] = "Loading"; MessageCase["Rejecting"] = "Rejecting"; MessageCase["Kicked"] = "Kicked"; MessageCase["Banned"] = "Banned"; MessageCase["OtherThreePIDError"] = "OtherThreePIDError"; MessageCase["InvitedEmailNotFoundInAccount"] = "InvitedEmailNotFoundInAccount"; MessageCase["InvitedEmailNoIdentityServer"] = "InvitedEmailNoIdentityServer"; MessageCase["InvitedEmailMismatch"] = "InvitedEmailMismatch"; MessageCase["Invite"] = "Invite"; MessageCase["ViewingRoom"] = "ViewingRoom"; MessageCase["RoomNotFound"] = "RoomNotFound"; MessageCase["OtherError"] = "OtherError"; MessageCase["PromptAskToJoin"] = "PromptAskToJoin"; MessageCase["Knocked"] = "Knocked"; MessageCase["RequestDenied"] = "requestDenied"; return MessageCase; }(MessageCase || {}); class RoomPreviewBar extends _react.default.Component { constructor(props) { super(props); (0, _defineProperty2.default)(this, "onLoginClick", () => { _dispatcher.default.dispatch({ action: "start_login", screenAfterLogin: this.makeScreenAfterLogin() }); }); (0, _defineProperty2.default)(this, "onRegisterClick", () => { _dispatcher.default.dispatch({ action: "start_registration", screenAfterLogin: this.makeScreenAfterLogin() }); }); (0, _defineProperty2.default)(this, "onChangeReason", event => { this.setState({ reason: event.target.value }); }); this.state = { busy: false }; } componentDidMount() { this.checkInvitedEmail(); } componentDidUpdate(prevProps, prevState) { if (this.props.invitedEmail !== prevProps.invitedEmail || this.props.inviterName !== prevProps.inviterName) { this.checkInvitedEmail(); } } async checkInvitedEmail() { // If this is an invite and we've been told what email address was // invited, fetch the user's account emails and discovery bindings so we // can check them against the email that was invited. if (this.props.inviterName && this.props.invitedEmail) { this.setState({ busy: true }); try { // Gather the account 3PIDs const account3pids = await _MatrixClientPeg.MatrixClientPeg.safeGet().getThreePids(); this.setState({ accountEmails: account3pids.threepids.filter(b => b.medium === "email").map(b => b.address) }); // If we have an IS connected, use that to lookup the email and // check the bound MXID. if (!_MatrixClientPeg.MatrixClientPeg.safeGet().getIdentityServerUrl()) { this.setState({ busy: false }); return; } const authClient = new _IdentityAuthClient.default(); const identityAccessToken = await authClient.getAccessToken(); const result = await _MatrixClientPeg.MatrixClientPeg.safeGet().lookupThreePid("email", this.props.invitedEmail, identityAccessToken); if (!("mxid" in result)) { throw new _languageHandler.UserFriendlyError("room|error_3pid_invite_email_lookup"); } this.setState({ invitedEmailMxid: result.mxid }); } catch (err) { this.setState({ threePidFetchError: err }); } this.setState({ busy: false }); } } getMessageCase() { const isGuest = _MatrixClientPeg.MatrixClientPeg.safeGet().isGuest(); if (isGuest) { return MessageCase.NotLoggedIn; } const myMember = this.getMyMember(); if (myMember) { const previousMembership = myMember.events.member?.getPrevContent().membership; if (myMember.isKicked()) { if (previousMembership === _types.KnownMembership.Knock) { return MessageCase.RequestDenied; } else if (this.props.promptAskToJoin) { return MessageCase.PromptAskToJoin; } return MessageCase.Kicked; } else if (myMember.membership === _types.KnownMembership.Ban) { return MessageCase.Banned; } } if (this.props.joining) { return MessageCase.Joining; } else if (this.props.rejecting) { return MessageCase.Rejecting; } else if (this.props.loading || this.state.busy) { return MessageCase.Loading; } else if (this.props.knocked) { return MessageCase.Knocked; } else if (this.props.canAskToJoinAndMembershipIsLeave || this.props.promptAskToJoin) { return MessageCase.PromptAskToJoin; } if (this.props.inviterName) { if (this.props.invitedEmail) { if (this.state.threePidFetchError) { return MessageCase.OtherThreePIDError; } else if (this.state.accountEmails && !this.state.accountEmails.includes(this.props.invitedEmail)) { return MessageCase.InvitedEmailNotFoundInAccount; } else if (!_MatrixClientPeg.MatrixClientPeg.safeGet().getIdentityServerUrl()) { return MessageCase.InvitedEmailNoIdentityServer; } else if (this.state.invitedEmailMxid != _MatrixClientPeg.MatrixClientPeg.safeGet().getUserId()) { return MessageCase.InvitedEmailMismatch; } } return MessageCase.Invite; } else if (this.props.error) { if (this.props.error.errcode == "M_NOT_FOUND") { return MessageCase.RoomNotFound; } else { return MessageCase.OtherError; } } else { return MessageCase.ViewingRoom; } } getKickOrBanInfo() { const myMember = this.getMyMember(); if (!myMember) { return {}; } const kickerUserId = myMember.events.member?.getSender(); const kickerMember = kickerUserId ? this.props.room?.currentState.getMember(kickerUserId) : undefined; const memberName = kickerMember?.name ?? kickerUserId; const reason = myMember.events.member?.getContent().reason; return { memberName, reason }; } joinRule() { return this.props.room?.currentState.getStateEvents(_matrix.EventType.RoomJoinRules, "")?.getContent().join_rule ?? null; } getMyMember() { return this.props.room?.getMember(_MatrixClientPeg.MatrixClientPeg.safeGet().getSafeUserId()) ?? null; } getInviteMember() { const { room } = this.props; if (!room) { return null; } const myUserId = _MatrixClientPeg.MatrixClientPeg.safeGet().getSafeUserId(); const inviteEvent = room.currentState.getMember(myUserId); if (!inviteEvent) { return null; } const inviterUserId = inviteEvent.events.member?.getSender(); return inviterUserId ? room.currentState.getMember(inviterUserId) : null; } isDMInvite() { const myMember = this.getMyMember(); if (!myMember) { return false; } const memberContent = myMember.events.member?.getContent(); return memberContent?.membership === _types.KnownMembership.Invite && memberContent.is_direct; } makeScreenAfterLogin() { return { screen: "room", params: { email: this.props.invitedEmail, signurl: this.props.signUrl, room_name: this.props.oobData?.name ?? null, room_avatar_url: this.props.oobData?.avatarUrl ?? null, inviter_name: this.props.oobData?.inviterName ?? null } }; } render() { const brand = _SdkConfig.default.get().brand; const roomName = this.props.room?.name ?? this.props.roomAlias ?? ""; const isSpace = this.props.room?.isSpaceRoom() ?? this.props.oobData?.roomType === _matrix.RoomType.Space; let showSpinner = false; let title; let subTitle; let reasonElement; let primaryActionHandler; let primaryActionLabel; let secondaryActionHandler; let secondaryActionLabel; let footer; const extraComponents = []; const messageCase = this.getMessageCase(); switch (messageCase) { case MessageCase.Joining: { if (this.props.oobData?.roomType || isSpace) { title = isSpace ? (0, _languageHandler._t)("room|joining_space") : (0, _languageHandler._t)("room|joining_room"); } else { title = (0, _languageHandler._t)("room|joining"); } showSpinner = true; break; } case MessageCase.Loading: { title = (0, _languageHandler._t)("common|loading"); showSpinner = true; break; } case MessageCase.Rejecting: { title = (0, _languageHandler._t)("room|rejecting"); showSpinner = true; break; } case MessageCase.NotLoggedIn: { const opts = { canJoin: false }; if (this.props.roomId) { _ModuleRunner.ModuleRunner.instance.invoke(_RoomViewLifecycle.RoomViewLifecycle.PreviewRoomNotLoggedIn, opts, this.props.roomId); } if (opts.canJoin) { title = (0, _languageHandler._t)("room|join_title"); primaryActionLabel = (0, _languageHandler._t)("action|join"); primaryActionHandler = () => { _ModuleRunner.ModuleRunner.instance.invoke(_RoomViewLifecycle.RoomViewLifecycle.JoinFromRoomPreview, this.props.roomId); }; } else { title = (0, _languageHandler._t)("room|join_title_account"); if (_SettingsStore.default.getValue(_UIFeature.UIFeature.Registration)) { primaryActionLabel = (0, _languageHandler._t)("room|join_button_account"); primaryActionHandler = this.onRegisterClick; } secondaryActionLabel = (0, _languageHandler._t)("action|sign_in"); secondaryActionHandler = this.onLoginClick; } if (this.props.previewLoading) { footer = /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(_Spinner.default, { w: 20, h: 20 }), (0, _languageHandler._t)("room|loading_preview")); } break; } case MessageCase.Kicked: { const { memberName, reason } = this.getKickOrBanInfo(); if (roomName) { title = (0, _languageHandler._t)("room|kicked_from_room_by", { memberName, roomName }); } else { title = (0, _languageHandler._t)("room|kicked_by", { memberName }); } subTitle = reason ? (0, _languageHandler._t)("room|kick_reason", { reason }) : undefined; if (isSpace) { primaryActionLabel = (0, _languageHandler._t)("room|forget_space"); } else { primaryActionLabel = (0, _languageHandler._t)("room|forget_room"); } primaryActionHandler = this.props.onForgetClick; if (this.joinRule() !== _matrix.JoinRule.Invite) { secondaryActionLabel = primaryActionLabel; secondaryActionHandler = primaryActionHandler; primaryActionLabel = (0, _languageHandler._t)("room|rejoin_button"); primaryActionHandler = this.props.onJoinClick; } break; } case MessageCase.RequestDenied: { title = (0, _languageHandler._t)("room|knock_denied_title"); subTitle = (0, _languageHandler._t)("room|knock_denied_subtitle"); if (isSpace) { primaryActionLabel = (0, _languageHandler._t)("room|forget_space"); } else { primaryActionLabel = (0, _languageHandler._t)("room|forget_room"); } primaryActionHandler = this.props.onForgetClick; break; } case MessageCase.Banned: { const { memberName, reason } = this.getKickOrBanInfo(); if (roomName) { title = (0, _languageHandler._t)("room|banned_from_room_by", { memberName, roomName }); } else { title = (0, _languageHandler._t)("room|banned_by", { memberName }); } subTitle = reason ? (0, _languageHandler._t)("room|kick_reason", { reason }) : undefined; if (isSpace) { primaryActionLabel = (0, _languageHandler._t)("room|forget_space"); } else { primaryActionLabel = (0, _languageHandler._t)("room|forget_room"); } primaryActionHandler = this.props.onForgetClick; break; } case MessageCase.OtherThreePIDError: { if (roomName) { title = (0, _languageHandler._t)("room|3pid_invite_error_title_room", { roomName }); } else { title = (0, _languageHandler._t)("room|3pid_invite_error_title"); } const joinRule = this.joinRule(); const errCodeMessage = (0, _languageHandler._t)("room|3pid_invite_error_description", { errcode: this.state.threePidFetchError?.errcode || (0, _languageHandler._t)("error|unknown_error_code") }); switch (joinRule) { case "invite": subTitle = [(0, _languageHandler._t)("room|3pid_invite_error_invite_subtitle"), errCodeMessage]; primaryActionLabel = (0, _languageHandler._t)("room|3pid_invite_error_invite_action"); primaryActionHandler = this.props.onJoinClick; break; case "public": subTitle = (0, _languageHandler._t)("room|3pid_invite_error_public_subtitle"); primaryActionLabel = (0, _languageHandler._t)("room|join_the_discussion"); primaryActionHandler = this.props.onJoinClick; break; default: subTitle = errCodeMessage; primaryActionLabel = (0, _languageHandler._t)("room|3pid_invite_error_invite_action"); primaryActionHandler = this.props.onJoinClick; break; } break; } case MessageCase.InvitedEmailNotFoundInAccount: { if (roomName) { title = (0, _languageHandler._t)("room|3pid_invite_email_not_found_account_room", { roomName, email: this.props.invitedEmail }); } else { title = (0, _languageHandler._t)("room|3pid_invite_email_not_found_account", { email: this.props.invitedEmail }); } subTitle = (0, _languageHandler._t)("room|link_email_to_receive_3pid_invite", { brand }); primaryActionLabel = (0, _languageHandler._t)("room|join_the_discussion"); primaryActionHandler = this.props.onJoinClick; break; } case MessageCase.InvitedEmailNoIdentityServer: { if (roomName) { title = (0, _languageHandler._t)("room|invite_sent_to_email_room", { roomName, email: this.props.invitedEmail }); } else { title = (0, _languageHandler._t)("room|invite_sent_to_email", { email: this.props.invitedEmail }); } subTitle = (0, _languageHandler._t)("room|3pid_invite_no_is_subtitle", { brand }); primaryActionLabel = (0, _languageHandler._t)("room|join_the_discussion"); primaryActionHandler = this.props.onJoinClick; break; } case MessageCase.InvitedEmailMismatch: { if (roomName) { title = (0, _languageHandler._t)("room|invite_sent_to_email_room", { roomName, email: this.props.invitedEmail }); } else { title = (0, _languageHandler._t)("room|invite_sent_to_email", { email: this.props.invitedEmail }); } subTitle = (0, _languageHandler._t)("room|invite_email_mismatch_suggestion", { brand }); primaryActionLabel = (0, _languageHandler._t)("room|join_the_discussion"); primaryActionHandler = this.props.onJoinClick; break; } case MessageCase.Invite: { const isDM = this.isDMInvite(); const avatar = /*#__PURE__*/_react.default.createElement(_RoomAvatar.default, { room: this.props.room, oobData: this.props.oobData }); const inviteMember = this.getInviteMember(); const userName = /*#__PURE__*/_react.default.createElement("span", { className: "mx_RoomPreviewBar_inviter" }, inviteMember?.rawDisplayName ?? this.props.inviterName); const inviterElement = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, isDM ? (0, _languageHandler._t)("room|dm_invite_subtitle", {}, { userName }) : (0, _languageHandler._t)("room|invite_subtitle", {}, { userName }), inviteMember && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("span", { className: "mx_RoomPreviewBar_inviter_mxid" }, inviteMember.userId))); if (isDM) { title = (0, _languageHandler._t)("room|dm_invite_title", { user: inviteMember?.name ?? this.props.inviterName }); primaryActionLabel = (0, _languageHandler._t)("room|dm_invite_action"); } else { title = (0, _languageHandler._t)("room|invite_title", { roomName }); primaryActionLabel = (0, _languageHandler._t)("action|accept"); } subTitle = [avatar, inviterElement]; const myUserId = _MatrixClientPeg.MatrixClientPeg.safeGet().getSafeUserId(); const member = this.props.room?.currentState.getMember(myUserId); const memberEventContent = member?.events.member?.getContent(); if (memberEventContent?.reason) { reasonElement = /*#__PURE__*/_react.default.createElement(_InviteReason.default, { reason: memberEventContent.reason, htmlReason: memberEventContent[MemberEventHtmlReasonField] }); } primaryActionHandler = this.props.onJoinClick; secondaryActionLabel = (0, _languageHandler._t)("action|reject"); secondaryActionHandler = this.props.onRejectClick; if (this.props.onRejectAndIgnoreClick) { extraComponents.push( /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { kind: "secondary", onClick: this.props.onRejectAndIgnoreClick, key: "ignore" }, (0, _languageHandler._t)("room|invite_reject_ignore"))); } break; } case MessageCase.ViewingRoom: { if (this.props.canPreview) { title = (0, _languageHandler._t)("room|peek_join_prompt", { roomName }); } else if (roomName) { title = (0, _languageHandler._t)("room|no_peek_join_prompt", { roomName }); } else { title = (0, _languageHandler._t)("room|no_peek_no_name_join_prompt"); } primaryActionLabel = (0, _languageHandler._t)("room|join_the_discussion"); primaryActionHandler = this.props.onJoinClick; break; } case MessageCase.RoomNotFound: { if (roomName) { title = (0, _languageHandler._t)("room|not_found_title_name", { roomName }); } else { title = (0, _languageHandler._t)("room|not_found_title"); } subTitle = (0, _languageHandler._t)("room|not_found_subtitle"); break; } case MessageCase.OtherError: { if (roomName) { title = (0, _languageHandler._t)("room|inaccessible_name", { roomName }); } else { title = (0, _languageHandler._t)("room|inaccessible"); } subTitle = [(0, _languageHandler._t)("room|inaccessible_subtitle_1"), (0, _languageHandler._t)("room|inaccessible_subtitle_2", { errcode: String(this.props.error?.errcode) }, { issueLink: label => /*#__PURE__*/_react.default.createElement("a", { href: _SdkConfig.default.get().feedback.new_issue_url, target: "_blank", rel: "noreferrer noopener" }, label) })]; break; } case MessageCase.PromptAskToJoin: { if (roomName) { title = (0, _languageHandler._t)("room|knock_prompt_name", { roomName }); } else { title = (0, _languageHandler._t)("room|knock_prompt"); } const avatar = /*#__PURE__*/_react.default.createElement(_RoomAvatar.default, { room: this.props.room, oobData: this.props.oobData }); subTitle = [avatar, (0, _languageHandler._t)("room|knock_subtitle")]; reasonElement = /*#__PURE__*/_react.default.createElement(_Field.default, { autoFocus: true, className: "mx_RoomPreviewBar_fullWidth", element: "textarea", onChange: this.onChangeReason, placeholder: (0, _languageHandler._t)("room|knock_message_field_placeholder"), type: "text", value: this.state.reason ?? "" }); primaryActionHandler = () => this.props.onSubmitAskToJoin && this.props.onSubmitAskToJoin(this.state.reason); primaryActionLabel = (0, _languageHandler._t)("room|knock_send_action"); break; } case MessageCase.Knocked: { title = (0, _languageHandler._t)("room|knock_sent"); subTitle = [/*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_askToJoin.Icon, { className: "mx_Icon mx_Icon_16 mx_RoomPreviewBar_icon" }), (0, _languageHandler._t)("room|knock_sent_subtitle"))]; secondaryActionHandler = this.props.onCancelAskToJoin; secondaryActionLabel = (0, _languageHandler._t)("room|knock_cancel_action"); break; } } let subTitleElements; if (subTitle) { if (!Array.isArray(subTitle)) { subTitle = [subTitle]; } subTitleElements = subTitle.map((t, i) => /*#__PURE__*/_react.default.createElement("p", { key: `subTitle${i}` }, t)); } let titleElement; if (showSpinner) { titleElement = /*#__PURE__*/_react.default.createElement("h3", { className: "mx_RoomPreviewBar_spinnerTitle" }, /*#__PURE__*/_react.default.createElement(_Spinner.default, null), title); } else { titleElement = /*#__PURE__*/_react.default.createElement("h3", null, title); } let primaryButton; if (primaryActionHandler) { primaryButton = /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { kind: "primary", onClick: primaryActionHandler }, primaryActionLabel); } let secondaryButton; if (secondaryActionHandler) { secondaryButton = /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, { kind: "secondary", onClick: secondaryActionHandler }, secondaryActionLabel); } const isPanel = this.props.canPreview; const classes = (0, _classnames.default)("mx_RoomPreviewBar", `mx_RoomPreviewBar_${messageCase}`, { mx_RoomPreviewBar_panel: isPanel, mx_RoomPreviewBar_dialog: !isPanel }); // ensure correct tab order for both views const actions = isPanel ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, secondaryButton, extraComponents, primaryButton) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, primaryButton, extraComponents, secondaryButton); return /*#__PURE__*/_react.default.createElement("div", { role: "complementary", className: classes }, /*#__PURE__*/_react.default.createElement("div", { className: "mx_RoomPreviewBar_message" }, titleElement, subTitleElements), reasonElement, /*#__PURE__*/_react.default.createElement("div", { className: (0, _classnames.default)("mx_RoomPreviewBar_actions", { mx_RoomPreviewBar_fullWidth: messageCase === MessageCase.PromptAskToJoin }) }, actions), /*#__PURE__*/_react.default.createElement("div", { className: "mx_RoomPreviewBar_footer" }, footer)); } } exports.default = RoomPreviewBar; (0, _defineProperty2.default)(RoomPreviewBar, "defaultProps", { onJoinClick() {} }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9tYXRyaXgiLCJfdHlwZXMiLCJfY2xhc3NuYW1lcyIsIl9Sb29tVmlld0xpZmVjeWNsZSIsIl9NYXRyaXhDbGllbnRQZWciLCJfZGlzcGF0Y2hlciIsIl9sYW5ndWFnZUhhbmRsZXIiLCJfU2RrQ29uZmlnIiwiX0lkZW50aXR5QXV0aENsaWVudCIsIl9JbnZpdGVSZWFzb24iLCJfU3Bpbm5lciIsIl9BY2Nlc3NpYmxlQnV0dG9uIiwiX1Jvb21BdmF0YXIiLCJfU2V0dGluZ3NTdG9yZSIsIl9VSUZlYXR1cmUiLCJfTW9kdWxlUnVubmVyIiwiX2Fza1RvSm9pbiIsIl9GaWVsZCIsIk1lbWJlckV2ZW50SHRtbFJlYXNvbkZpZWxkIiwiTWVzc2FnZUNhc2UiLCJSb29tUHJldmlld0JhciIsIlJlYWN0IiwiQ29tcG9uZW50IiwiY29uc3RydWN0b3IiLCJwcm9wcyIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJkZWZhdWx0IiwiZGlzIiwiZGlzcGF0Y2giLCJhY3Rpb24iLCJzY3JlZW5BZnRlckxvZ2luIiwibWFrZVNjcmVlbkFmdGVyTG9naW4iLCJldmVudCIsInNldFN0YXRlIiwicmVhc29uIiwidGFyZ2V0IiwidmFsdWUiLCJzdGF0ZSIsImJ1c3kiLCJjb21wb25lbnREaWRNb3VudCIsImNoZWNrSW52aXRlZEVtYWlsIiwiY29tcG9uZW50RGlkVXBkYXRlIiwicHJldlByb3BzIiwicHJldlN0YXRlIiwiaW52aXRlZEVtYWlsIiwiaW52aXRlck5hbWUiLCJhY2NvdW50M3BpZHMiLCJNYXRyaXhDbGllbnRQZWciLCJzYWZlR2V0IiwiZ2V0VGhyZWVQaWRzIiwiYWNjb3VudEVtYWlscyIsInRocmVlcGlkcyIsImZpbHRlciIsImIiLCJtZWRpdW0iLCJtYXAiLCJhZGRyZXNzIiwiZ2V0SWRlbnRpdHlTZXJ2ZXJVcmwiLCJhdXRoQ2xpZW50IiwiSWRlbnRpdHlBdXRoQ2xpZW50IiwiaWRlbnRpdHlBY2Nlc3NUb2tlbiIsImdldEFjY2Vzc1Rva2VuIiwicmVzdWx0IiwibG9va3VwVGhyZWVQaWQiLCJVc2VyRnJpZW5kbHlFcnJvciIsImludml0ZWRFbWFpbE14aWQiLCJteGlkIiwiZXJyIiwidGhyZWVQaWRGZXRjaEVycm9yIiwiZ2V0TWVzc2FnZUNhc2UiLCJpc0d1ZXN0IiwiTm90TG9nZ2VkSW4iLCJteU1lbWJlciIsImdldE15TWVtYmVyIiwicHJldmlvdXNNZW1iZXJzaGlwIiwiZXZlbnRzIiwibWVtYmVyIiwiZ2V0UHJldkNvbnRlbnQiLCJtZW1iZXJzaGlwIiwiaXNLaWNrZWQiLCJLbm93bk1lbWJlcnNoaXAiLCJLbm9jayIsIlJlcXVlc3REZW5pZWQiLCJwcm9tcHRBc2tUb0pvaW4iLCJQcm9tcHRBc2tUb0pvaW4iLCJLaWNrZWQiLCJCYW4iLCJCYW5uZWQiLCJqb2luaW5nIiwiSm9pbmluZyIsInJlamVjdGluZyIsIlJlamVjdGluZyIsImxvYWRpbmciLCJMb2FkaW5nIiwia25vY2tlZCIsIktub2NrZWQiLCJjYW5Bc2tUb0pvaW5BbmRNZW1iZXJzaGlwSXNMZWF2ZSIsIk90aGVyVGhyZWVQSURFcnJvciIsImluY2x1ZGVzIiwiSW52aXRlZEVtYWlsTm90Rm91bmRJbkFjY291bnQiLCJJbnZpdGVkRW1haWxOb0lkZW50aXR5U2VydmVyIiwiZ2V0VXNlcklkIiwiSW52aXRlZEVtYWlsTWlzbWF0Y2giLCJJbnZpdGUiLCJlcnJvciIsImVycmNvZGUiLCJSb29tTm90Rm91bmQiLCJPdGhlckVycm9yIiwiVmlld2luZ1Jvb20iLCJnZXRLaWNrT3JCYW5JbmZvIiwia2lja2VyVXNlcklkIiwiZ2V0U2VuZGVyIiwia2lja2VyTWVtYmVyIiwicm9vbSIsImN1cnJlbnRTdGF0ZSIsImdldE1lbWJlciIsInVuZGVmaW5lZCIsIm1lbWJlck5hbWUiLCJuYW1lIiwiZ2V0Q29udGVudCIsImpvaW5SdWxlIiwiZ2V0U3RhdGVFdmVudHMiLCJFdmVudFR5cGUiLCJSb29tSm9pblJ1bGVzIiwiam9pbl9ydWxlIiwiZ2V0U2FmZVVzZXJJZCIsImdldEludml0ZU1lbWJlciIsIm15VXNlcklkIiwiaW52aXRlRXZlbnQiLCJpbnZpdGVyVXNlcklkIiwiaXNETUludml0ZSIsIm1lbWJlckNvbnRlbnQiLCJpc19kaXJlY3QiLCJzY3JlZW4iLCJwYXJhbXMiLCJlbWFpbCIsInNpZ251cmwiLCJzaWduVXJsIiwicm9vbV9uYW1lIiwib29iRGF0YSIsInJvb21fYXZhdGFyX3VybCIsImF2YXRhclVybCIsImludml0ZXJfbmFtZSIsInJlbmRlciIsImJyYW5kIiwiU2RrQ29uZmlnIiwiZ2V0Iiwicm9vbU5hbWUiLCJyb29tQWxpYXMiLCJpc1NwYWNlIiwiaXNTcGFjZVJvb20iLCJyb29tVHlwZSIsIlJvb21UeXBlIiwiU3BhY2UiLCJzaG93U3Bpbm5lciIsInRpdGxlIiwic3ViVGl0bGUiLCJyZWFzb25FbGVtZW50IiwicHJpbWFyeUFjdGlvbkhhbmRsZXIiLCJwcmltYXJ5QWN0aW9uTGFiZWwiLCJzZWNvbmRhcnlBY3Rpb25IYW5kbGVyIiwic2Vjb25kYXJ5QWN0aW9uTGFiZWwiLCJmb290ZXIiLCJleHRyYUNvbXBvbmVudHMiLCJtZXNzYWdlQ2FzZSIsIl90Iiwib3B0cyIsImNhbkpvaW4iLCJyb29tSWQiLCJNb2R1bGVSdW5uZXIiLCJpbnN0YW5jZSIsImludm9rZSIsIlJvb21WaWV3TGlmZWN5Y2xlIiwiUHJldmlld1Jvb21Ob3RMb2dnZWRJbiIsIkpvaW5Gcm9tUm9vbVByZXZpZXciLCJTZXR0aW5nc1N0b3JlIiwiZ2V0VmFsdWUiLCJVSUZlYXR1cmUiLCJSZWdpc3RyYXRpb24iLCJvblJlZ2lzdGVyQ2xpY2siLCJvbkxvZ2luQ2xpY2siLCJwcmV2aWV3TG9hZGluZyIsImNyZWF0ZUVsZW1lbnQiLCJ3IiwiaCIsIm9uRm9yZ2V0Q2xpY2siLCJKb2luUnVsZSIsIm9uSm9pbkNsaWNrIiwiZXJyQ29kZU1lc3NhZ2UiLCJpc0RNIiwiYXZhdGFyIiwiaW52aXRlTWVtYmVyIiwidXNlck5hbWUiLCJjbGFzc05hbWUiLCJyYXdEaXNwbGF5TmFtZSIsImludml0ZXJFbGVtZW50IiwiRnJhZ21lbnQiLCJ1c2VySWQiLCJ1c2VyIiwibWVtYmVyRXZlbnRDb250ZW50IiwiaHRtbFJlYXNvbiIsIm9uUmVqZWN0Q2xpY2siLCJvblJlamVjdEFuZElnbm9yZUNsaWNrIiwicHVzaCIsImtpbmQiLCJvbkNsaWNrIiwia2V5IiwiY2FuUHJldmlldyIsIlN0cmluZyIsImlzc3VlTGluayIsImxhYmVsIiwiaHJlZiIsImZlZWRiYWNrIiwibmV3X2lzc3VlX3VybCIsInJlbCIsImF1dG9Gb2N1cyIsImVsZW1lbnQiLCJvbkNoYW5nZSIsIm9uQ2hhbmdlUmVhc29uIiwicGxhY2Vob2xkZXIiLCJ0eXBlIiwib25TdWJtaXRBc2tUb0pvaW4iLCJJY29uIiwib25DYW5jZWxBc2tUb0pvaW4iLCJzdWJUaXRsZUVsZW1lbnRzIiwiQXJyYXkiLCJpc0FycmF5IiwidCIsImkiLCJ0aXRsZUVsZW1lbnQiLCJwcmltYXJ5QnV0dG9uIiwic2Vjb25kYXJ5QnV0dG9uIiwiaXNQYW5lbCIsImNsYXNzZXMiLCJjbGFzc05hbWVzIiwibXhfUm9vbVByZXZpZXdCYXJfcGFuZWwiLCJteF9Sb29tUHJldmlld0Jhcl9kaWFsb2ciLCJhY3Rpb25zIiwicm9sZSIsIm14X1Jvb21QcmV2aWV3QmFyX2Z1bGxXaWR0aCIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy92aWV3cy9yb29tcy9Sb29tUHJldmlld0Jhci50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMTUtMjAyMSBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgUmVhY3QsIHsgQ2hhbmdlRXZlbnQsIFJlYWN0Tm9kZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgUm9vbSwgUm9vbU1lbWJlciwgRXZlbnRUeXBlLCBSb29tVHlwZSwgSm9pblJ1bGUsIE1hdHJpeEVycm9yIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL21hdHJpeFwiO1xuaW1wb3J0IHsgS25vd25NZW1iZXJzaGlwLCBSb29tSm9pblJ1bGVzRXZlbnRDb250ZW50IH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL3R5cGVzXCI7XG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tIFwiY2xhc3NuYW1lc1wiO1xuaW1wb3J0IHsgUm9vbVByZXZpZXdPcHRzLCBSb29tVmlld0xpZmVjeWNsZSB9IGZyb20gXCJAbWF0cml4LW9yZy9yZWFjdC1zZGstbW9kdWxlLWFwaS9saWIvbGlmZWN5Y2xlcy9Sb29tVmlld0xpZmVjeWNsZVwiO1xuXG5pbXBvcnQgeyBNYXRyaXhDbGllbnRQZWcgfSBmcm9tIFwiLi4vLi4vLi4vTWF0cml4Q2xpZW50UGVnXCI7XG5pbXBvcnQgZGlzIGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL2Rpc3BhdGNoZXJcIjtcbmltcG9ydCB7IF90LCBVc2VyRnJpZW5kbHlFcnJvciB9IGZyb20gXCIuLi8uLi8uLi9sYW5ndWFnZUhhbmRsZXJcIjtcbmltcG9ydCBTZGtDb25maWcgZnJvbSBcIi4uLy4uLy4uL1Nka0NvbmZpZ1wiO1xuaW1wb3J0IElkZW50aXR5QXV0aENsaWVudCBmcm9tIFwiLi4vLi4vLi4vSWRlbnRpdHlBdXRoQ2xpZW50XCI7XG5pbXBvcnQgSW52aXRlUmVhc29uIGZyb20gXCIuLi9lbGVtZW50cy9JbnZpdGVSZWFzb25cIjtcbmltcG9ydCB7IElPT0JEYXRhIH0gZnJvbSBcIi4uLy4uLy4uL3N0b3Jlcy9UaHJlZXBpZEludml0ZVN0b3JlXCI7XG5pbXBvcnQgU3Bpbm5lciBmcm9tIFwiLi4vZWxlbWVudHMvU3Bpbm5lclwiO1xuaW1wb3J0IEFjY2Vzc2libGVCdXR0b24gZnJvbSBcIi4uL2VsZW1lbnRzL0FjY2Vzc2libGVCdXR0b25cIjtcbmltcG9ydCBSb29tQXZhdGFyIGZyb20gXCIuLi9hdmF0YXJzL1Jvb21BdmF0YXJcIjtcbmltcG9ydCBTZXR0aW5nc1N0b3JlIGZyb20gXCIuLi8uLi8uLi9zZXR0aW5ncy9TZXR0aW5nc1N0b3JlXCI7XG5pbXBvcnQgeyBVSUZlYXR1cmUgfSBmcm9tIFwiLi4vLi4vLi4vc2V0dGluZ3MvVUlGZWF0dXJlXCI7XG5pbXBvcnQgeyBNb2R1bGVSdW5uZXIgfSBmcm9tIFwiLi4vLi4vLi4vbW9kdWxlcy9Nb2R1bGVSdW5uZXJcIjtcbmltcG9ydCB7IEljb24gYXMgQXNrVG9Kb2luSWNvbiB9IGZyb20gXCIuLi8uLi8uLi8uLi9yZXMvaW1nL2VsZW1lbnQtaWNvbnMvYXNrLXRvLWpvaW4uc3ZnXCI7XG5pbXBvcnQgRmllbGQgZnJvbSBcIi4uL2VsZW1lbnRzL0ZpZWxkXCI7XG5cbmNvbnN0IE1lbWJlckV2ZW50SHRtbFJlYXNvbkZpZWxkID0gXCJpby5lbGVtZW50Lmh0bWxfcmVhc29uXCI7XG5cbmVudW0gTWVzc2FnZUNhc2Uge1xuICAgIE5vdExvZ2dlZEluID0gXCJOb3RMb2dnZWRJblwiLFxuICAgIEpvaW5pbmcgPSBcIkpvaW5pbmdcIixcbiAgICBMb2FkaW5nID0gXCJMb2FkaW5nXCIsXG4gICAgUmVqZWN0aW5nID0gXCJSZWplY3RpbmdcIixcbiAgICBLaWNrZWQgPSBcIktpY2tlZFwiLFxuICAgIEJhbm5lZCA9IFwiQmFubmVkXCIsXG4gICAgT3RoZXJUaHJlZVBJREVycm9yID0gXCJPdGhlclRocmVlUElERXJyb3JcIixcbiAgICBJbnZpdGVkRW1haWxOb3RGb3VuZEluQWNjb3VudCA9IFwiSW52aXRlZEVtYWlsTm90Rm91bmRJbkFjY291bnRcIixcbiAgICBJbnZpdGVkRW1haWxOb0lkZW50aXR5U2VydmVyID0gXCJJbnZpdGVkRW1haWxOb0lkZW50aXR5U2VydmVyXCIsXG4gICAgSW52aXRlZEVtYWlsTWlzbWF0Y2ggPSBcIkludml0ZWRFbWFpbE1pc21hdGNoXCIsXG4gICAgSW52aXRlID0gXCJJbnZpdGVcIixcbiAgICBWaWV3aW5nUm9vbSA9IFwiVmlld2luZ1Jvb21cIixcbiAgICBSb29tTm90Rm91bmQgPSBcIlJvb21Ob3RGb3VuZFwiLFxuICAgIE90aGVyRXJyb3IgPSBcIk90aGVyRXJyb3JcIixcbiAgICBQcm9tcHRBc2tUb0pvaW4gPSBcIlByb21wdEFza1RvSm9pblwiLFxuICAgIEtub2NrZWQgPSBcIktub2NrZWRcIixcbiAgICBSZXF1ZXN0RGVuaWVkID0gXCJyZXF1ZXN0RGVuaWVkXCIsXG59XG5cbmludGVyZmFjZSBJUHJvcHMge1xuICAgIC8vIGlmIGludml0ZXJOYW1lIGlzIHNwZWNpZmllZCwgdGhlIHByZXZpZXcgYmFyIHdpbGwgc2hvd24gYW4gaW52aXRlIHRvIHRoZSByb29tLlxuICAgIC8vIFlvdSBzaG91bGQgYWxzbyBzcGVjaWZ5IG9uUmVqZWN0Q2xpY2sgaWYgc3BlY2lmeWluZyBpbnZpdGVyTmFtZVxuICAgIGludml0ZXJOYW1lPzogc3RyaW5nO1xuXG4gICAgLy8gSWYgaW52aXRlZCBieSAzcmQgcGFydHkgaW52aXRlLCB0aGUgZW1haWwgYWRkcmVzcyB0aGUgaW52aXRlIHdhcyBzZW50IHRvXG4gICAgaW52aXRlZEVtYWlsPzogc3RyaW5nO1xuXG4gICAgLy8gRm9yIHRoaXJkIHBhcnR5IGludml0ZXMsIGluZm9ybWF0aW9uIHBhc3NlZCBhYm91dCB0aGUgcm9vbSBvdXQtb2YtYmFuZFxuICAgIG9vYkRhdGE/OiBJT09CRGF0YTtcblxuICAgIC8vIEZvciB0aGlyZCBwYXJ0eSBpbnZpdGVzLCBhIFVSTCBmb3IgYSAzcGlkIGludml0ZSBzaWduaW5nIHNlcnZpY2VcbiAgICBzaWduVXJsPzogc3RyaW5nO1xuXG4gICAgLy8gQSBzdGFuZGFyZCBjbGllbnQvc2VydmVyIEFQSSBlcnJvciBvYmplY3QuIElmIHN1cHBsaWVkLCBpbmRpY2F0ZXMgdGhhdCB0aGVcbiAgICAvLyBjYWxsZXIgd2FzIHVuYWJsZSB0byBmZXRjaCBkZXRhaWxzIGFib3V0IHRoZSByb29tIGZvciB0aGUgZ2l2ZW4gcmVhc29uLlxuICAgIGVycm9yPzogTWF0cml4RXJyb3I7XG5cbiAgICBjYW5QcmV2aWV3PzogYm9vbGVhbjtcbiAgICBwcmV2aWV3TG9hZGluZz86IGJvb2xlYW47XG5cbiAgICAvLyBUaGUgaWQgb2YgdGhlIHJvb20gdG8gYmUgcHJldmlld2VkLCBpZiBpdCBpcyBrbm93bi5cbiAgICAvLyAoSXQgbWF5IGJlIHVua25vd24gaWYgd2UgYXJlIHdhaXRpbmcgZm9yIGFuIGFsaWFzIHRvIGJlIHJlc29sdmVkLilcbiAgICByb29tSWQ/OiBzdHJpbmc7XG5cbiAgICAvLyBBIGBSb29tYCBvYmplY3QgZm9yIHRoZSByb29tIHRvIGJlIHByZXZpZXdlZCwgaWYgd2UgaGF2ZSBvbmUuXG4gICAgcm9vbT86IFJvb207XG5cbiAgICBsb2FkaW5nPzogYm9vbGVhbjtcbiAgICBqb2luaW5nPzogYm9vbGVhbjtcbiAgICByZWplY3Rpbmc/OiBib29sZWFuO1xuICAgIC8vIFRoZSBhbGlhcyB0aGF0IHdhcyB1c2VkIHRvIGFjY2VzcyB0aGlzIHJvb20sIGlmIGFwcHJvcHJpYXRlXG4gICAgLy8gSWYgZ2l2ZW4sIHRoaXMgd2lsbCBiZSBob3cgdGhlIHJvb20gaXMgcmVmZXJyZWQgdG8gKGVnLlxuICAgIC8vIGluIGVycm9yIG1lc3NhZ2VzKS5cbiAgICByb29tQWxpYXM/OiBzdHJpbmc7XG5cbiAgICBvbkpvaW5DbGljaz8oKTogdm9pZDtcbiAgICBvblJlamVjdENsaWNrPygpOiB2b2lkO1xuICAgIG9uUmVqZWN0QW5kSWdub3JlQ2xpY2s/KCk6IHZvaWQ7XG4gICAgb25Gb3JnZXRDbGljaz8oKTogdm9pZDtcblxuICAgIGNhbkFza1RvSm9pbkFuZE1lbWJlcnNoaXBJc0xlYXZlPzogYm9vbGVhbjtcbiAgICBwcm9tcHRBc2tUb0pvaW4/OiBib29sZWFuO1xuICAgIGtub2NrZWQ/OiBib29sZWFuO1xuICAgIG9uU3VibWl0QXNrVG9Kb2luPyhyZWFzb24/OiBzdHJpbmcpOiB2b2lkO1xuICAgIG9uQ2FuY2VsQXNrVG9Kb2luPygpOiB2b2lkO1xufVxuXG5pbnRlcmZhY2UgSVN0YXRlIHtcbiAgICBidXN5OiBib29sZWFuO1xuICAgIGFjY291bnRFbWFpbHM/OiBzdHJpbmdbXTtcbiAgICBpbnZpdGVkRW1haWxNeGlkPzogc3RyaW5nO1xuICAgIHRocmVlUGlkRmV0Y2hFcnJvcj86IE1hdHJpeEVycm9yO1xuICAgIHJlYXNvbj86IHN0cmluZztcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUm9vbVByZXZpZXdCYXIgZXh0ZW5kcyBSZWFjdC5Db21wb25lbnQ8SVByb3BzLCBJU3RhdGU+IHtcbiAgICBwdWJsaWMgc3RhdGljIGRlZmF1bHRQcm9wcyA9IHtcbiAgICAgICAgb25Kb2luQ2xpY2soKSB7fSxcbiAgICB9O1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByb3BzOiBJUHJvcHMpIHtcbiAgICAgICAgc3VwZXIocHJvcHMpO1xuXG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICBidXN5OiBmYWxzZSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50RGlkTW91bnQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2hlY2tJbnZpdGVkRW1haWwoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wczogSVByb3BzLCBwcmV2U3RhdGU6IElTdGF0ZSk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5pbnZpdGVkRW1haWwgIT09IHByZXZQcm9wcy5pbnZpdGVkRW1haWwgfHwgdGhpcy5wcm9wcy5pbnZpdGVyTmFtZSAhPT0gcHJldlByb3BzLmludml0ZXJOYW1lKSB7XG4gICAgICAgICAgICB0aGlzLmNoZWNrSW52aXRlZEVtYWlsKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGNoZWNrSW52aXRlZEVtYWlsKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICAvLyBJZiB0aGlzIGlzIGFuIGludml0ZSBhbmQgd2UndmUgYmVlbiB0b2xkIHdoYXQgZW1haWwgYWRkcmVzcyB3YXNcbiAgICAgICAgLy8gaW52aXRlZCwgZmV0Y2ggdGhlIHVzZXIncyBhY2NvdW50IGVtYWlscyBhbmQgZGlzY292ZXJ5IGJpbmRpbmdzIHNvIHdlXG4gICAgICAgIC8vIGNhbiBjaGVjayB0aGVtIGFnYWluc3QgdGhlIGVtYWlsIHRoYXQgd2FzIGludml0ZWQuXG4gICAgICAgIGlmICh0aGlzLnByb3BzLmludml0ZXJOYW1lICYmIHRoaXMucHJvcHMuaW52aXRlZEVtYWlsKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgYnVzeTogdHJ1ZSB9KTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gR2F0aGVyIHRoZSBhY2NvdW50IDNQSURzXG4gICAgICAgICAgICAgICAgY29uc3QgYWNjb3VudDNwaWRzID0gYXdhaXQgTWF0cml4Q2xpZW50UGVnLnNhZmVHZXQoKS5nZXRUaHJlZVBpZHMoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgICAgYWNjb3VudEVtYWlsczogYWNjb3VudDNwaWRzLnRocmVlcGlkcy5maWx0ZXIoKGIpID0+IGIubWVkaXVtID09PSBcImVtYWlsXCIpLm1hcCgoYikgPT4gYi5hZGRyZXNzKSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAvLyBJZiB3ZSBoYXZlIGFuIElTIGNvbm5lY3RlZCwgdXNlIHRoYXQgdG8gbG9va3VwIHRoZSBlbWFpbCBhbmRcbiAgICAgICAgICAgICAgICAvLyBjaGVjayB0aGUgYm91bmQgTVhJRC5cbiAgICAgICAgICAgICAgICBpZiAoIU1hdHJpeENsaWVudFBlZy5zYWZlR2V0KCkuZ2V0SWRlbnRpdHlTZXJ2ZXJVcmwoKSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldFN0YXRlKHsgYnVzeTogZmFsc2UgfSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY29uc3QgYXV0aENsaWVudCA9IG5ldyBJZGVudGl0eUF1dGhDbGllbnQoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBpZGVudGl0eUFjY2Vzc1Rva2VuID0gYXdhaXQgYXV0aENsaWVudC5nZXRBY2Nlc3NUb2tlbigpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IE1hdHJpeENsaWVudFBlZy5zYWZlR2V0KCkubG9va3VwVGhyZWVQaWQoXG4gICAgICAgICAgICAgICAgICAgIFwiZW1haWxcIixcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5pbnZpdGVkRW1haWwsXG4gICAgICAgICAgICAgICAgICAgIGlkZW50aXR5QWNjZXNzVG9rZW4hLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgaWYgKCEoXCJteGlkXCIgaW4gcmVzdWx0KSkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVXNlckZyaWVuZGx5RXJyb3IoXCJyb29tfGVycm9yXzNwaWRfaW52aXRlX2VtYWlsX2xvb2t1cFwiKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGludml0ZWRFbWFpbE14aWQ6IHJlc3VsdC5teGlkIH0pO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHRocmVlUGlkRmV0Y2hFcnJvcjogZXJyIGFzIE1hdHJpeEVycm9yIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGJ1c3k6IGZhbHNlIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRNZXNzYWdlQ2FzZSgpOiBNZXNzYWdlQ2FzZSB7XG4gICAgICAgIGNvbnN0IGlzR3Vlc3QgPSBNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpLmlzR3Vlc3QoKTtcblxuICAgICAgICBpZiAoaXNHdWVzdCkge1xuICAgICAgICAgICAgcmV0dXJuIE1lc3NhZ2VDYXNlLk5vdExvZ2dlZEluO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbXlNZW1iZXIgPSB0aGlzLmdldE15TWVtYmVyKCk7XG5cbiAgICAgICAgaWYgKG15TWVtYmVyKSB7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91c01lbWJlcnNoaXAgPSBteU1lbWJlci5ldmVudHMubWVtYmVyPy5nZXRQcmV2Q29udGVudCgpLm1lbWJlcnNoaXA7XG4gICAgICAgICAgICBpZiAobXlNZW1iZXIuaXNLaWNrZWQoKSkge1xuICAgICAgICAgICAgICAgIGlmIChwcmV2aW91c01lbWJlcnNoaXAgPT09IEtub3duTWVtYmVyc2hpcC5Lbm9jaykge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTWVzc2FnZUNhc2UuUmVxdWVzdERlbmllZDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJvcHMucHJvbXB0QXNrVG9Kb2luKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBNZXNzYWdlQ2FzZS5Qcm9tcHRBc2tUb0pvaW47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBNZXNzYWdlQ2FzZS5LaWNrZWQ7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKG15TWVtYmVyLm1lbWJlcnNoaXAgPT09IEtub3duTWVtYmVyc2hpcC5CYW4pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gTWVzc2FnZUNhc2UuQmFubmVkO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucHJvcHMuam9pbmluZykge1xuICAgICAgICAgICAgcmV0dXJuIE1lc3NhZ2VDYXNlLkpvaW5pbmc7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy5yZWplY3RpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiBNZXNzYWdlQ2FzZS5SZWplY3Rpbmc7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy5sb2FkaW5nIHx8IHRoaXMuc3RhdGUuYnVzeSkge1xuICAgICAgICAgICAgcmV0dXJuIE1lc3NhZ2VDYXNlLkxvYWRpbmc7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5wcm9wcy5rbm9ja2VkKSB7XG4gICAgICAgICAgICByZXR1cm4gTWVzc2FnZUNhc2UuS25vY2tlZDtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByb3BzLmNhbkFza1RvSm9pbkFuZE1lbWJlcnNoaXBJc0xlYXZlIHx8IHRoaXMucHJvcHMucHJvbXB0QXNrVG9Kb2luKSB7XG4gICAgICAgICAgICByZXR1cm4gTWVzc2FnZUNhc2UuUHJvbXB0QXNrVG9Kb2luO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucHJvcHMuaW52aXRlck5hbWUpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLmludml0ZWRFbWFpbCkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnN0YXRlLnRocmVlUGlkRmV0Y2hFcnJvcikge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTWVzc2FnZUNhc2UuT3RoZXJUaHJlZVBJREVycm9yO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5zdGF0ZS5hY2NvdW50RW1haWxzICYmICF0aGlzLnN0YXRlLmFjY291bnRFbWFpbHMuaW5jbHVkZXModGhpcy5wcm9wcy5pbnZpdGVkRW1haWwpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBNZXNzYWdlQ2FzZS5JbnZpdGVkRW1haWxOb3RGb3VuZEluQWNjb3VudDtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpLmdldElkZW50aXR5U2VydmVyVXJsKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE1lc3NhZ2VDYXNlLkludml0ZWRFbWFpbE5vSWRlbnRpdHlTZXJ2ZXI7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmICh0aGlzLnN0YXRlLmludml0ZWRFbWFpbE14aWQgIT0gTWF0cml4Q2xpZW50UGVnLnNhZmVHZXQoKS5nZXRVc2VySWQoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gTWVzc2FnZUNhc2UuSW52aXRlZEVtYWlsTWlzbWF0Y2g7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIE1lc3NhZ2VDYXNlLkludml0ZTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByb3BzLmVycm9yKSB7XG4gICAgICAgICAgICBpZiAoKHRoaXMucHJvcHMuZXJyb3IgYXMgTWF0cml4RXJyb3IpLmVycmNvZGUgPT0gXCJNX05PVF9GT1VORFwiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIE1lc3NhZ2VDYXNlLlJvb21Ob3RGb3VuZDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIE1lc3NhZ2VDYXNlLk90aGVyRXJyb3I7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gTWVzc2FnZUNhc2UuVmlld2luZ1Jvb207XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGdldEtpY2tPckJhbkluZm8oKTogeyBtZW1iZXJOYW1lPzogc3RyaW5nOyByZWFzb24/OiBzdHJpbmcgfSB7XG4gICAgICAgIGNvbnN0IG15TWVtYmVyID0gdGhpcy5nZXRNeU1lbWJlcigpO1xuICAgICAgICBpZiAoIW15TWVtYmVyKSB7XG4gICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBraWNrZXJVc2VySWQgPSBteU1lbWJlci5ldmVudHMubWVtYmVyPy5nZXRTZW5kZXIoKTtcbiAgICAgICAgY29uc3Qga2lja2VyTWVtYmVyID0ga2lja2VyVXNlcklkID8gdGhpcy5wcm9wcy5yb29tPy5jdXJyZW50U3RhdGUuZ2V0TWVtYmVyKGtpY2tlclVzZXJJZCkgOiB1bmRlZmluZWQ7XG4gICAgICAgIGNvbnN0IG1lbWJlck5hbWUgPSBraWNrZXJNZW1iZXI/Lm5hbWUgPz8ga2lja2VyVXNlcklkO1xuICAgICAgICBjb25zdCByZWFzb24gPSBteU1lbWJlci5ldmVudHMubWVtYmVyPy5nZXRDb250ZW50KCkucmVhc29uO1xuICAgICAgICByZXR1cm4geyBtZW1iZXJOYW1lLCByZWFzb24gfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGpvaW5SdWxlKCk6IEpvaW5SdWxlIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICB0aGlzLnByb3BzLnJvb20/LmN1cnJlbnRTdGF0ZVxuICAgICAgICAgICAgICAgIC5nZXRTdGF0ZUV2ZW50cyhFdmVudFR5cGUuUm9vbUpvaW5SdWxlcywgXCJcIilcbiAgICAgICAgICAgICAgICA/LmdldENvbnRlbnQ8Um9vbUpvaW5SdWxlc0V2ZW50Q29udGVudD4oKS5qb2luX3J1bGUgPz8gbnVsbFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0TXlNZW1iZXIoKTogUm9vbU1lbWJlciB8IG51bGwge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wcy5yb29tPy5nZXRNZW1iZXIoTWF0cml4Q2xpZW50UGVnLnNhZmVHZXQoKS5nZXRTYWZlVXNlcklkKCkpID8/IG51bGw7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRJbnZpdGVNZW1iZXIoKTogUm9vbU1lbWJlciB8IG51bGwge1xuICAgICAgICBjb25zdCB7IHJvb20gfSA9IHRoaXMucHJvcHM7XG4gICAgICAgIGlmICghcm9vbSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbXlVc2VySWQgPSBNYXRyaXhDbGllbnRQZWcuc2FmZUdldCgpLmdldFNhZmVVc2VySWQoKTtcbiAgICAgICAgY29uc3QgaW52aXRlRXZlbnQgPSByb29tLmN1cnJlbnRTdGF0ZS5nZXRNZW1iZXIobXlVc2VySWQpO1xuICAgICAgICBpZiAoIWludml0ZUV2ZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbnZpdGVyVXNlcklkID0gaW52aXRlRXZlbnQuZXZlbnRzLm1lbWJlcj8uZ2V0U2VuZGVyKCk7XG4gICAgICAgIHJldHVybiBpbnZpdGVyVXNlcklkID8gcm9vbS5jdXJyZW50U3RhdGUuZ2V0TWVtYmVyKGludml0ZXJVc2VySWQpIDogbnVsbDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzRE1JbnZpdGUoKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IG15TWVtYmVyID0gdGhpcy5nZXRNeU1lbWJlcigpO1xuICAgICAgICBpZiAoIW15TWVtYmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbWVtYmVyQ29udGVudCA9IG15TWVtYmVyLmV2ZW50cy5tZW1iZXI/LmdldENvbnRlbnQoKTtcbiAgICAgICAgcmV0dXJuIG1lbWJlckNvbnRlbnQ/Lm1lbWJlcnNoaXAgPT09IEtub3duTWVtYmVyc2hpcC5JbnZpdGUgJiYgbWVtYmVyQ29udGVudC5pc19kaXJlY3Q7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBtYWtlU2NyZWVuQWZ0ZXJMb2dpbigpOiB7IHNjcmVlbjogc3RyaW5nOyBwYXJhbXM6IFJlY29yZDxzdHJpbmcsIGFueT4gfSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzY3JlZW46IFwicm9vbVwiLFxuICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgICAgZW1haWw6IHRoaXMucHJvcHMuaW52aXRlZEVtYWlsLFxuICAgICAgICAgICAgICAgIHNpZ251cmw6IHRoaXMucHJvcHMuc2lnblVybCxcbiAgICAgICAgICAgICAgICByb29tX25hbWU6IHRoaXMucHJvcHMub29iRGF0YT8ubmFtZSA/PyBudWxsLFxuICAgICAgICAgICAgICAgIHJvb21fYXZhdGFyX3VybDogdGhpcy5wcm9wcy5vb2JEYXRhPy5hdmF0YXJVcmwgPz8gbnVsbCxcbiAgICAgICAgICAgICAgICBpbnZpdGVyX25hbWU6IHRoaXMucHJvcHMub29iRGF0YT8uaW52aXRlck5hbWUgPz8gbnVsbCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkxvZ2luQ2xpY2sgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgIGRpcy5kaXNwYXRjaCh7IGFjdGlvbjogXCJzdGFydF9sb2dpblwiLCBzY3JlZW5BZnRlckxvZ2luOiB0aGlzLm1ha2VTY3JlZW5BZnRlckxvZ2luKCkgfSk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25SZWdpc3RlckNsaWNrID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICBkaXMuZGlzcGF0Y2goeyBhY3Rpb246IFwic3RhcnRfcmVnaXN0cmF0aW9uXCIsIHNjcmVlbkFmdGVyTG9naW46IHRoaXMubWFrZVNjcmVlbkFmdGVyTG9naW4oKSB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvbkNoYW5nZVJlYXNvbiA9IChldmVudDogQ2hhbmdlRXZlbnQ8SFRNTFRleHRBcmVhRWxlbWVudD4pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHJlYXNvbjogZXZlbnQudGFyZ2V0LnZhbHVlIH0pO1xuICAgIH07XG5cbiAgICBwdWJsaWMgcmVuZGVyKCk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gICAgICAgIGNvbnN0IGJyYW5kID0gU2RrQ29uZmlnLmdldCgpLmJyYW5kO1xuICAgICAgICBjb25zdCByb29tTmFtZSA9IHRoaXMucHJvcHMucm9vbT8ubmFtZSA/PyB0aGlzLnByb3BzLnJvb21BbGlhcyA/PyBcIlwiO1xuICAgICAgICBjb25zdCBpc1NwYWNlID0gdGhpcy5wcm9wcy5yb29tPy5pc1NwYWNlUm9vbSgpID8/IHRoaXMucHJvcHMub29iRGF0YT8ucm9vbVR5cGUgPT09IFJvb21UeXBlLlNwYWNlO1xuXG4gICAgICAgIGxldCBzaG93U3Bpbm5lciA9IGZhbHNlO1xuICAgICAgICBsZXQgdGl0bGU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IHN1YlRpdGxlOiBzdHJpbmcgfCBSZWFjdE5vZGVbXSB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IHJlYXNvbkVsZW1lbnQ6IEpTWC5FbGVtZW50IHwgdW5kZWZpbmVkO1xuICAgICAgICBsZXQgcHJpbWFyeUFjdGlvbkhhbmRsZXI6ICgoKSA9PiB2b2lkKSB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IHByaW1hcnlBY3Rpb25MYWJlbDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgICBsZXQgc2Vjb25kYXJ5QWN0aW9uSGFuZGxlcjogKCgpID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xuICAgICAgICBsZXQgc2Vjb25kYXJ5QWN0aW9uTGFiZWw6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGZvb3RlcjogSlNYLkVsZW1lbnQgfCB1bmRlZmluZWQ7XG4gICAgICAgIGNvbnN0IGV4dHJhQ29tcG9uZW50czogSlNYLkVsZW1lbnRbXSA9IFtdO1xuXG4gICAgICAgIGNvbnN0IG1lc3NhZ2VDYXNlID0gdGhpcy5nZXRNZXNzYWdlQ2FzZSgpO1xuICAgICAgICBzd2l0Y2ggKG1lc3NhZ2VDYXNlKSB7XG4gICAgICAgICAgICBjYXNlIE1lc3NhZ2VDYXNlLkpvaW5pbmc6IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5wcm9wcy5vb2JEYXRhPy5yb29tVHlwZSB8fCBpc1NwYWNlKSB7XG4gICAgICAgICAgICAgICAgICAgIHRpdGxlID0gaXNTcGFjZSA/IF90KFwicm9vbXxqb2luaW5nX3NwYWNlXCIpIDogX3QoXCJyb29tfGpvaW5pbmdfcm9vbVwiKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aXRsZSA9IF90KFwicm9vbXxqb2luaW5nXCIpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHNob3dTcGlubmVyID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNhc2UgTWVzc2FnZUNhc2UuTG9hZGluZzoge1xuICAgICAgICAgICAgICAgIHRpdGxlID0gX3QoXCJjb21tb258bG9hZGluZ1wiKTtcbiAgICAgICAgICAgICAgICBzaG93U3Bpbm5lciA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIE1lc3NhZ2VDYXNlLlJlamVjdGluZzoge1xuICAgICAgICAgICAgICAgIHRpdGxlID0gX3QoXCJyb29tfHJlamVjdGluZ1wiKTtcbiAgICAgICAgICAgICAgICBzaG93U3Bpbm5lciA9IHRydWU7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIE1lc3NhZ2VDYXNlLk5vdExvZ2dlZEluOiB7XG4gICAgICAgICAgICAgICAgY29uc3Qgb3B0czogUm9vbVByZXZpZXdPcHRzID0geyBjYW5Kb2luOiBmYWxzZSB9O1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByb3BzLnJvb21JZCkge1xuICAgICAgICAgICAgICAgICAgICBNb2R1bGVSdW5uZXIuaW5zdGFuY2UuaW52b2tlKFJvb21WaWV3TGlmZWN5Y2xlLlByZXZpZXdSb29tTm90TG9nZ2VkSW4sIG9wdHMsIHRoaXMucHJvcHMucm9vbUlkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG9wdHMuY2FuSm9pbikge1xuICAgICAgICAgICAgICAgICAgICB0aXRsZSA9IF90KFwicm9vbXxqb2luX3RpdGxlXCIpO1xuICAgICAgICAgICAgICAgICAgICBwcmltYXJ5QWN0aW9uTGFiZWwgPSBfdChcImFjdGlvbnxqb2luXCIpO1xuICAgICAgICAgICAgICAgICAgICBwcmltYXJ5QWN0aW9uSGFuZGxlciA9ICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIE1v