matrix-react-sdk
Version:
SDK for matrix.org using React
308 lines (305 loc) • 64.2 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = RoomHeader;
var _react = _interopRequireWildcard(require("react"));
var _compoundWeb = require("@vector-im/compound-web");
var _videoCallSolid = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/video-call-solid"));
var _voiceCall = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/voice-call"));
var _close = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/close"));
var _threadsSolid = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/threads-solid"));
var _infoSolid = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/info-solid"));
var _notificationsSolid = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/notifications-solid"));
var _verified = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/verified"));
var _error = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/error"));
var _public = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/public"));
var _matrix = require("matrix-js-sdk/src/matrix");
var _useRoomName = require("../../../hooks/useRoomName");
var _RightPanelStorePhases = require("../../../stores/right-panel/RightPanelStorePhases");
var _MatrixClientContext = require("../../../contexts/MatrixClientContext");
var _useRoomMembers = require("../../../hooks/useRoomMembers");
var _languageHandler = require("../../../languageHandler");
var _Flex = require("../../utils/Flex");
var _Box = require("../../utils/Box");
var _useRoomCall = require("../../../hooks/room/useRoomCall");
var _useRoomThreadNotifications = require("../../../hooks/room/useRoomThreadNotifications");
var _useGlobalNotificationState = require("../../../hooks/useGlobalNotificationState");
var _SdkConfig = _interopRequireDefault(require("../../../SdkConfig"));
var _useSettings = require("../../../hooks/useSettings");
var _useEncryptionStatus = require("../../../hooks/useEncryptionStatus");
var _ShieldUtils = require("../../../utils/ShieldUtils");
var _FacePile = _interopRequireDefault(require("../elements/FacePile"));
var _useRoomState = require("../../../hooks/useRoomState");
var _RoomAvatar = _interopRequireDefault(require("../avatars/RoomAvatar"));
var _FormattingUtils = require("../../../utils/FormattingUtils");
var _RightPanelStore = _interopRequireDefault(require("../../../stores/right-panel/RightPanelStore"));
var _PosthogTrackers = _interopRequireDefault(require("../../../PosthogTrackers"));
var _VideoRoomChatButton = require("./RoomHeader/VideoRoomChatButton");
var _RoomKnocksBar = require("./RoomKnocksBar");
var _videoRooms = require("../../../utils/video-rooms");
var _notifications = require("../../../utils/notifications");
var _CallGuestLinkButton = require("./RoomHeader/CallGuestLinkButton");
var _WithPresenceIndicator = _interopRequireWildcard(require("../avatars/WithPresenceIndicator"));
var _RoomContext = _interopRequireDefault(require("../../../contexts/RoomContext"));
var _RoomView = require("../../structures/RoomView");
var _dispatcher = _interopRequireDefault(require("../../../dispatcher/dispatcher.ts"));
var _RoomSettingsDialog = require("../dialogs/RoomSettingsDialog.tsx");
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 2023 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.
*/
function RoomHeader({
room,
additionalButtons,
oobData
}) {
const client = (0, _MatrixClientContext.useMatrixClientContext)();
const roomName = (0, _useRoomName.useRoomName)(room);
const joinRule = (0, _useRoomState.useRoomState)(room, state => state.getJoinRule());
const members = (0, _useRoomMembers.useRoomMembers)(room, 2500);
const memberCount = (0, _useRoomMembers.useRoomMemberCount)(room, {
throttleWait: 2500
});
const {
voiceCallDisabledReason,
voiceCallClick,
videoCallDisabledReason,
videoCallClick,
toggleCallMaximized: toggleCall,
isViewingCall,
isConnectedToCall,
hasActiveCallSession,
callOptions,
showVoiceCallButton,
showVideoCallButton
} = (0, _useRoomCall.useRoomCall)(room);
const groupCallsEnabled = (0, _useSettings.useFeatureEnabled)("feature_group_calls");
/**
* A special mode where only Element Call is used. In this case we want to
* hide the voice call button
*/
const useElementCallExclusively = (0, _react.useMemo)(() => {
return _SdkConfig.default.get("element_call").use_exclusively && groupCallsEnabled;
}, [groupCallsEnabled]);
const threadNotifications = (0, _useRoomThreadNotifications.useRoomThreadNotifications)(room);
const globalNotificationState = (0, _useGlobalNotificationState.useGlobalNotificationState)();
const dmMember = (0, _WithPresenceIndicator.useDmMember)(room);
const isDirectMessage = !!dmMember;
const e2eStatus = (0, _useEncryptionStatus.useEncryptionStatus)(client, room);
const notificationsEnabled = (0, _useSettings.useFeatureEnabled)("feature_notifications");
const askToJoinEnabled = (0, _useSettings.useFeatureEnabled)("feature_ask_to_join");
const videoClick = (0, _react.useCallback)(ev => videoCallClick(ev, callOptions[0]), [callOptions, videoCallClick]);
const toggleCallButton = /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, {
label: isViewingCall ? (0, _languageHandler._t)("voip|minimise_call") : (0, _languageHandler._t)("voip|maximise_call")
}, /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, {
onClick: toggleCall
}, /*#__PURE__*/_react.default.createElement(_videoCallSolid.default, null)));
const joinCallButton = /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, {
label: videoCallDisabledReason ?? (0, _languageHandler._t)("voip|video_call")
}, /*#__PURE__*/_react.default.createElement(_compoundWeb.Button, {
size: "sm",
onClick: videoClick,
Icon: _videoCallSolid.default,
className: "mx_RoomHeader_join_button",
disabled: !!videoCallDisabledReason,
color: "primary",
"aria-label": videoCallDisabledReason ?? (0, _languageHandler._t)("action|join")
}, (0, _languageHandler._t)("action|join")));
const callIconWithTooltip = /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, {
label: videoCallDisabledReason ?? (0, _languageHandler._t)("voip|video_call")
}, /*#__PURE__*/_react.default.createElement(_videoCallSolid.default, null));
const [menuOpen, setMenuOpen] = (0, _react.useState)(false);
const onOpenChange = (0, _react.useCallback)(newOpen => {
if (!videoCallDisabledReason) setMenuOpen(newOpen);
}, [videoCallDisabledReason]);
const startVideoCallButton = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, callOptions.length > 1 ? /*#__PURE__*/_react.default.createElement(_compoundWeb.Menu, {
open: menuOpen,
onOpenChange: onOpenChange,
title: (0, _languageHandler._t)("voip|video_call_using"),
trigger: /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, {
disabled: !!videoCallDisabledReason,
"aria-label": videoCallDisabledReason ?? (0, _languageHandler._t)("voip|video_call")
}, callIconWithTooltip),
side: "left",
align: "start"
}, callOptions.map(option => /*#__PURE__*/_react.default.createElement(_compoundWeb.MenuItem, {
key: option,
label: (0, _useRoomCall.getPlatformCallTypeLabel)(option),
"aria-label": (0, _useRoomCall.getPlatformCallTypeLabel)(option),
onClick: ev => videoCallClick(ev, option),
Icon: _videoCallSolid.default,
onSelect: () => {} /* Dummy handler since we want the click event.*/
}))) : /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, {
disabled: !!videoCallDisabledReason,
"aria-label": videoCallDisabledReason ?? (0, _languageHandler._t)("voip|video_call"),
onClick: videoClick
}, callIconWithTooltip));
let voiceCallButton = /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, {
label: voiceCallDisabledReason ?? (0, _languageHandler._t)("voip|voice_call")
}, /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton
// We need both: isViewingCall and isConnectedToCall
// - in the Lobby we are viewing a call but are not connected to it.
// - in pip view we are connected to the call but not viewing it.
, {
disabled: !!voiceCallDisabledReason || isViewingCall || isConnectedToCall,
"aria-label": voiceCallDisabledReason ?? (0, _languageHandler._t)("voip|voice_call"),
onClick: ev => voiceCallClick(ev, callOptions[0])
}, /*#__PURE__*/_react.default.createElement(_voiceCall.default, null)));
const closeLobbyButton = /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, {
label: (0, _languageHandler._t)("voip|close_lobby")
}, /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, {
onClick: toggleCall
}, /*#__PURE__*/_react.default.createElement(_close.default, null)));
let videoCallButton = startVideoCallButton;
if (isConnectedToCall) {
videoCallButton = toggleCallButton;
} else if (isViewingCall) {
videoCallButton = closeLobbyButton;
}
if (!showVideoCallButton) {
videoCallButton = undefined;
}
if (!showVoiceCallButton) {
voiceCallButton = undefined;
}
const roomContext = (0, _react.useContext)(_RoomContext.default);
const isVideoRoom = (0, _videoRooms.isVideoRoom)(room);
const showChatButton = isVideoRoom || roomContext.mainSplitContentType === _RoomView.MainSplitContentType.MaximisedWidget || roomContext.mainSplitContentType === _RoomView.MainSplitContentType.Call;
const onAvatarClick = () => {
_dispatcher.default.dispatch({
action: "open_room_settings",
initial_tab_id: _RoomSettingsDialog.RoomSettingsTab.General
});
};
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_Flex.Flex, {
as: "header",
align: "center",
gap: "var(--cpd-space-3x)",
className: "mx_RoomHeader light-panel"
}, /*#__PURE__*/_react.default.createElement(_WithPresenceIndicator.default, {
room: room,
size: "8px"
}, /*#__PURE__*/_react.default.createElement(_RoomAvatar.default, {
room: room,
size: "40px",
oobData: oobData,
onClick: onAvatarClick,
tabIndex: -1,
"aria-label": (0, _languageHandler._t)("room|header_avatar_open_settings_label")
})), /*#__PURE__*/_react.default.createElement("button", {
"aria-label": (0, _languageHandler._t)("right_panel|room_summary_card|title"),
tabIndex: 0,
onClick: () => _RightPanelStore.default.instance.showOrHidePhase(_RightPanelStorePhases.RightPanelPhases.RoomSummary),
className: "mx_RoomHeader_infoWrapper"
}, /*#__PURE__*/_react.default.createElement(_Box.Box, {
flex: "1",
className: "mx_RoomHeader_info"
}, /*#__PURE__*/_react.default.createElement(_compoundWeb.Body, {
as: "div",
size: "lg",
weight: "semibold",
dir: "auto",
role: "heading",
"aria-level": 1,
className: "mx_RoomHeader_heading"
}, /*#__PURE__*/_react.default.createElement("span", {
className: "mx_RoomHeader_truncated mx_lineClamp"
}, roomName), !isDirectMessage && joinRule === _matrix.JoinRule.Public && /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, {
label: (0, _languageHandler._t)("common|public_room"),
placement: "right"
}, /*#__PURE__*/_react.default.createElement(_public.default, {
width: "16px",
height: "16px",
className: "mx_RoomHeader_icon text-secondary",
"aria-label": (0, _languageHandler._t)("common|public_room")
})), isDirectMessage && e2eStatus === _ShieldUtils.E2EStatus.Verified && /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, {
label: (0, _languageHandler._t)("common|verified"),
placement: "right"
}, /*#__PURE__*/_react.default.createElement(_verified.default, {
width: "16px",
height: "16px",
className: "mx_RoomHeader_icon mx_Verified",
"aria-label": (0, _languageHandler._t)("common|verified")
})), isDirectMessage && e2eStatus === _ShieldUtils.E2EStatus.Warning && /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, {
label: (0, _languageHandler._t)("room|header_untrusted_label"),
placement: "right"
}, /*#__PURE__*/_react.default.createElement(_error.default, {
width: "16px",
height: "16px",
className: "mx_RoomHeader_icon mx_Untrusted",
"aria-label": (0, _languageHandler._t)("room|header_untrusted_label")
}))))), /*#__PURE__*/_react.default.createElement(_Flex.Flex, {
align: "center",
gap: "var(--cpd-space-2x)"
}, additionalButtons?.map(props => {
const label = props.label();
return /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, {
label: label,
key: props.id
}, /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, {
"aria-label": label,
onClick: event => {
event.stopPropagation();
props.onClick();
}
}, typeof props.icon === "function" ? props.icon() : props.icon));
}), isViewingCall && /*#__PURE__*/_react.default.createElement(_CallGuestLinkButton.CallGuestLinkButton, {
room: room
}), hasActiveCallSession && !isConnectedToCall && !isViewingCall ? joinCallButton : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, !isVideoRoom && videoCallButton, !useElementCallExclusively && !isVideoRoom && voiceCallButton), /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, {
label: (0, _languageHandler._t)("right_panel|room_summary_card|title")
}, /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, {
onClick: evt => {
evt.stopPropagation();
_RightPanelStore.default.instance.showOrHidePhase(_RightPanelStorePhases.RightPanelPhases.RoomSummary);
},
"aria-label": (0, _languageHandler._t)("right_panel|room_summary_card|title")
}, /*#__PURE__*/_react.default.createElement(_infoSolid.default, null))), showChatButton && /*#__PURE__*/_react.default.createElement(_VideoRoomChatButton.VideoRoomChatButton, {
room: room
}), /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, {
label: (0, _languageHandler._t)("common|threads")
}, /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, {
indicator: (0, _notifications.notificationLevelToIndicator)(threadNotifications),
onClick: evt => {
evt.stopPropagation();
_RightPanelStore.default.instance.showOrHidePhase(_RightPanelStorePhases.RightPanelPhases.ThreadPanel);
_PosthogTrackers.default.trackInteraction("WebRoomHeaderButtonsThreadsButton", evt);
},
"aria-label": (0, _languageHandler._t)("common|threads")
}, /*#__PURE__*/_react.default.createElement(_threadsSolid.default, null))), notificationsEnabled && /*#__PURE__*/_react.default.createElement(_compoundWeb.Tooltip, {
label: (0, _languageHandler._t)("notifications|enable_prompt_toast_title")
}, /*#__PURE__*/_react.default.createElement(_compoundWeb.IconButton, {
indicator: (0, _notifications.notificationLevelToIndicator)(globalNotificationState.level),
onClick: evt => {
evt.stopPropagation();
_RightPanelStore.default.instance.showOrHidePhase(_RightPanelStorePhases.RightPanelPhases.NotificationPanel);
},
"aria-label": (0, _languageHandler._t)("notifications|enable_prompt_toast_title")
}, /*#__PURE__*/_react.default.createElement(_notificationsSolid.default, null)))), !isDirectMessage && /*#__PURE__*/_react.default.createElement(_compoundWeb.Body, {
as: "div",
size: "sm",
weight: "medium"
}, /*#__PURE__*/_react.default.createElement(_FacePile.default, {
className: "mx_RoomHeader_members",
members: members.slice(0, 3),
size: "20px",
overflow: false,
viewUserOnClick: false,
tooltipLabel: (0, _languageHandler._t)("room|header_face_pile_tooltip"),
onClick: e => {
_RightPanelStore.default.instance.showOrHidePhase(_RightPanelStorePhases.RightPanelPhases.RoomMemberList);
e.stopPropagation();
},
"aria-label": (0, _languageHandler._t)("common|n_members", {
count: memberCount
})
}, (0, _FormattingUtils.formatCount)(memberCount)))), askToJoinEnabled && /*#__PURE__*/_react.default.createElement(_RoomKnocksBar.RoomKnocksBar, {
room: room
}));
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfY29tcG91bmRXZWIiLCJfdmlkZW9DYWxsU29saWQiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX3ZvaWNlQ2FsbCIsIl9jbG9zZSIsIl90aHJlYWRzU29saWQiLCJfaW5mb1NvbGlkIiwiX25vdGlmaWNhdGlvbnNTb2xpZCIsIl92ZXJpZmllZCIsIl9lcnJvciIsIl9wdWJsaWMiLCJfbWF0cml4IiwiX3VzZVJvb21OYW1lIiwiX1JpZ2h0UGFuZWxTdG9yZVBoYXNlcyIsIl9NYXRyaXhDbGllbnRDb250ZXh0IiwiX3VzZVJvb21NZW1iZXJzIiwiX2xhbmd1YWdlSGFuZGxlciIsIl9GbGV4IiwiX0JveCIsIl91c2VSb29tQ2FsbCIsIl91c2VSb29tVGhyZWFkTm90aWZpY2F0aW9ucyIsIl91c2VHbG9iYWxOb3RpZmljYXRpb25TdGF0ZSIsIl9TZGtDb25maWciLCJfdXNlU2V0dGluZ3MiLCJfdXNlRW5jcnlwdGlvblN0YXR1cyIsIl9TaGllbGRVdGlscyIsIl9GYWNlUGlsZSIsIl91c2VSb29tU3RhdGUiLCJfUm9vbUF2YXRhciIsIl9Gb3JtYXR0aW5nVXRpbHMiLCJfUmlnaHRQYW5lbFN0b3JlIiwiX1Bvc3Rob2dUcmFja2VycyIsIl9WaWRlb1Jvb21DaGF0QnV0dG9uIiwiX1Jvb21Lbm9ja3NCYXIiLCJfdmlkZW9Sb29tcyIsIl9ub3RpZmljYXRpb25zIiwiX0NhbGxHdWVzdExpbmtCdXR0b24iLCJfV2l0aFByZXNlbmNlSW5kaWNhdG9yIiwiX1Jvb21Db250ZXh0IiwiX1Jvb21WaWV3IiwiX2Rpc3BhdGNoZXIiLCJfUm9vbVNldHRpbmdzRGlhbG9nIiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiaGFzIiwiZ2V0IiwibiIsIl9fcHJvdG9fXyIsImEiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpIiwic2V0IiwiUm9vbUhlYWRlciIsInJvb20iLCJhZGRpdGlvbmFsQnV0dG9ucyIsIm9vYkRhdGEiLCJjbGllbnQiLCJ1c2VNYXRyaXhDbGllbnRDb250ZXh0Iiwicm9vbU5hbWUiLCJ1c2VSb29tTmFtZSIsImpvaW5SdWxlIiwidXNlUm9vbVN0YXRlIiwic3RhdGUiLCJnZXRKb2luUnVsZSIsIm1lbWJlcnMiLCJ1c2VSb29tTWVtYmVycyIsIm1lbWJlckNvdW50IiwidXNlUm9vbU1lbWJlckNvdW50IiwidGhyb3R0bGVXYWl0Iiwidm9pY2VDYWxsRGlzYWJsZWRSZWFzb24iLCJ2b2ljZUNhbGxDbGljayIsInZpZGVvQ2FsbERpc2FibGVkUmVhc29uIiwidmlkZW9DYWxsQ2xpY2siLCJ0b2dnbGVDYWxsTWF4aW1pemVkIiwidG9nZ2xlQ2FsbCIsImlzVmlld2luZ0NhbGwiLCJpc0Nvbm5lY3RlZFRvQ2FsbCIsImhhc0FjdGl2ZUNhbGxTZXNzaW9uIiwiY2FsbE9wdGlvbnMiLCJzaG93Vm9pY2VDYWxsQnV0dG9uIiwic2hvd1ZpZGVvQ2FsbEJ1dHRvbiIsInVzZVJvb21DYWxsIiwiZ3JvdXBDYWxsc0VuYWJsZWQiLCJ1c2VGZWF0dXJlRW5hYmxlZCIsInVzZUVsZW1lbnRDYWxsRXhjbHVzaXZlbHkiLCJ1c2VNZW1vIiwiU2RrQ29uZmlnIiwidXNlX2V4Y2x1c2l2ZWx5IiwidGhyZWFkTm90aWZpY2F0aW9ucyIsInVzZVJvb21UaHJlYWROb3RpZmljYXRpb25zIiwiZ2xvYmFsTm90aWZpY2F0aW9uU3RhdGUiLCJ1c2VHbG9iYWxOb3RpZmljYXRpb25TdGF0ZSIsImRtTWVtYmVyIiwidXNlRG1NZW1iZXIiLCJpc0RpcmVjdE1lc3NhZ2UiLCJlMmVTdGF0dXMiLCJ1c2VFbmNyeXB0aW9uU3RhdHVzIiwibm90aWZpY2F0aW9uc0VuYWJsZWQiLCJhc2tUb0pvaW5FbmFibGVkIiwidmlkZW9DbGljayIsInVzZUNhbGxiYWNrIiwiZXYiLCJ0b2dnbGVDYWxsQnV0dG9uIiwiY3JlYXRlRWxlbWVudCIsIlRvb2x0aXAiLCJsYWJlbCIsIl90IiwiSWNvbkJ1dHRvbiIsIm9uQ2xpY2siLCJqb2luQ2FsbEJ1dHRvbiIsIkJ1dHRvbiIsInNpemUiLCJJY29uIiwiVmlkZW9DYWxsSWNvbiIsImNsYXNzTmFtZSIsImRpc2FibGVkIiwiY29sb3IiLCJjYWxsSWNvbldpdGhUb29sdGlwIiwibWVudU9wZW4iLCJzZXRNZW51T3BlbiIsInVzZVN0YXRlIiwib25PcGVuQ2hhbmdlIiwibmV3T3BlbiIsInN0YXJ0VmlkZW9DYWxsQnV0dG9uIiwiRnJhZ21lbnQiLCJsZW5ndGgiLCJNZW51Iiwib3BlbiIsInRpdGxlIiwidHJpZ2dlciIsInNpZGUiLCJhbGlnbiIsIm1hcCIsIm9wdGlvbiIsIk1lbnVJdGVtIiwia2V5IiwiZ2V0UGxhdGZvcm1DYWxsVHlwZUxhYmVsIiwib25TZWxlY3QiLCJ2b2ljZUNhbGxCdXR0b24iLCJjbG9zZUxvYmJ5QnV0dG9uIiwidmlkZW9DYWxsQnV0dG9uIiwidW5kZWZpbmVkIiwicm9vbUNvbnRleHQiLCJ1c2VDb250ZXh0IiwiUm9vbUNvbnRleHQiLCJpc1ZpZGVvUm9vbSIsImNhbGNJc1ZpZGVvUm9vbSIsInNob3dDaGF0QnV0dG9uIiwibWFpblNwbGl0Q29udGVudFR5cGUiLCJNYWluU3BsaXRDb250ZW50VHlwZSIsIk1heGltaXNlZFdpZGdldCIsIkNhbGwiLCJvbkF2YXRhckNsaWNrIiwiZGVmYXVsdERpc3BhdGNoZXIiLCJkaXNwYXRjaCIsImFjdGlvbiIsImluaXRpYWxfdGFiX2lkIiwiUm9vbVNldHRpbmdzVGFiIiwiR2VuZXJhbCIsIkZsZXgiLCJhcyIsImdhcCIsInRhYkluZGV4IiwiUmlnaHRQYW5lbFN0b3JlIiwiaW5zdGFuY2UiLCJzaG93T3JIaWRlUGhhc2UiLCJSaWdodFBhbmVsUGhhc2VzIiwiUm9vbVN1bW1hcnkiLCJCb3giLCJmbGV4IiwiQm9keSIsIndlaWdodCIsImRpciIsInJvbGUiLCJKb2luUnVsZSIsIlB1YmxpYyIsInBsYWNlbWVudCIsIndpZHRoIiwiaGVpZ2h0IiwiRTJFU3RhdHVzIiwiVmVyaWZpZWQiLCJXYXJuaW5nIiwicHJvcHMiLCJpZCIsImV2ZW50Iiwic3RvcFByb3BhZ2F0aW9uIiwiaWNvbiIsIkNhbGxHdWVzdExpbmtCdXR0b24iLCJldnQiLCJWaWRlb1Jvb21DaGF0QnV0dG9uIiwiaW5kaWNhdG9yIiwibm90aWZpY2F0aW9uTGV2ZWxUb0luZGljYXRvciIsIlRocmVhZFBhbmVsIiwiUG9zdGhvZ1RyYWNrZXJzIiwidHJhY2tJbnRlcmFjdGlvbiIsImxldmVsIiwiTm90aWZpY2F0aW9uUGFuZWwiLCJzbGljZSIsIm92ZXJmbG93Iiwidmlld1VzZXJPbkNsaWNrIiwidG9vbHRpcExhYmVsIiwiUm9vbU1lbWJlckxpc3QiLCJjb3VudCIsImZvcm1hdENvdW50IiwiUm9vbUtub2Nrc0JhciJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL3Jvb21zL1Jvb21IZWFkZXIudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDIzIFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCBSZWFjdCwgeyB1c2VDYWxsYmFjaywgdXNlQ29udGV4dCwgdXNlTWVtbywgdXNlU3RhdGUgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IEJvZHkgYXMgQm9keVRleHQsIEJ1dHRvbiwgSWNvbkJ1dHRvbiwgTWVudSwgTWVudUl0ZW0sIFRvb2x0aXAgfSBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC13ZWJcIjtcbmltcG9ydCBWaWRlb0NhbGxJY29uIGZyb20gXCJAdmVjdG9yLWltL2NvbXBvdW5kLWRlc2lnbi10b2tlbnMvYXNzZXRzL3dlYi9pY29ucy92aWRlby1jYWxsLXNvbGlkXCI7XG5pbXBvcnQgVm9pY2VDYWxsSWNvbiBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC1kZXNpZ24tdG9rZW5zL2Fzc2V0cy93ZWIvaWNvbnMvdm9pY2UtY2FsbFwiO1xuaW1wb3J0IENsb3NlQ2FsbEljb24gZnJvbSBcIkB2ZWN0b3ItaW0vY29tcG91bmQtZGVzaWduLXRva2Vucy9hc3NldHMvd2ViL2ljb25zL2Nsb3NlXCI7XG5pbXBvcnQgVGhyZWFkc0ljb24gZnJvbSBcIkB2ZWN0b3ItaW0vY29tcG91bmQtZGVzaWduLXRva2Vucy9hc3NldHMvd2ViL2ljb25zL3RocmVhZHMtc29saWRcIjtcbmltcG9ydCBSb29tSW5mb0ljb24gZnJvbSBcIkB2ZWN0b3ItaW0vY29tcG91bmQtZGVzaWduLXRva2Vucy9hc3NldHMvd2ViL2ljb25zL2luZm8tc29saWRcIjtcbmltcG9ydCBOb3RpZmljYXRpb25zSWNvbiBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC1kZXNpZ24tdG9rZW5zL2Fzc2V0cy93ZWIvaWNvbnMvbm90aWZpY2F0aW9ucy1zb2xpZFwiO1xuaW1wb3J0IFZlcmlmaWVkSWNvbiBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC1kZXNpZ24tdG9rZW5zL2Fzc2V0cy93ZWIvaWNvbnMvdmVyaWZpZWRcIjtcbmltcG9ydCBFcnJvckljb24gZnJvbSBcIkB2ZWN0b3ItaW0vY29tcG91bmQtZGVzaWduLXRva2Vucy9hc3NldHMvd2ViL2ljb25zL2Vycm9yXCI7XG5pbXBvcnQgUHVibGljSWNvbiBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC1kZXNpZ24tdG9rZW5zL2Fzc2V0cy93ZWIvaWNvbnMvcHVibGljXCI7XG5pbXBvcnQgeyBKb2luUnVsZSwgdHlwZSBSb29tIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL21hdHJpeFwiO1xuaW1wb3J0IHsgVmlld1Jvb21PcHRzIH0gZnJvbSBcIkBtYXRyaXgtb3JnL3JlYWN0LXNkay1tb2R1bGUtYXBpL2xpYi9saWZlY3ljbGVzL1Jvb21WaWV3TGlmZWN5Y2xlXCI7XG5cbmltcG9ydCB7IHVzZVJvb21OYW1lIH0gZnJvbSBcIi4uLy4uLy4uL2hvb2tzL3VzZVJvb21OYW1lXCI7XG5pbXBvcnQgeyBSaWdodFBhbmVsUGhhc2VzIH0gZnJvbSBcIi4uLy4uLy4uL3N0b3Jlcy9yaWdodC1wYW5lbC9SaWdodFBhbmVsU3RvcmVQaGFzZXNcIjtcbmltcG9ydCB7IHVzZU1hdHJpeENsaWVudENvbnRleHQgfSBmcm9tIFwiLi4vLi4vLi4vY29udGV4dHMvTWF0cml4Q2xpZW50Q29udGV4dFwiO1xuaW1wb3J0IHsgdXNlUm9vbU1lbWJlckNvdW50LCB1c2VSb29tTWVtYmVycyB9IGZyb20gXCIuLi8uLi8uLi9ob29rcy91c2VSb29tTWVtYmVyc1wiO1xuaW1wb3J0IHsgX3QgfSBmcm9tIFwiLi4vLi4vLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgeyBGbGV4IH0gZnJvbSBcIi4uLy4uL3V0aWxzL0ZsZXhcIjtcbmltcG9ydCB7IEJveCB9IGZyb20gXCIuLi8uLi91dGlscy9Cb3hcIjtcbmltcG9ydCB7IGdldFBsYXRmb3JtQ2FsbFR5cGVMYWJlbCwgdXNlUm9vbUNhbGwgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3Mvcm9vbS91c2VSb29tQ2FsbFwiO1xuaW1wb3J0IHsgdXNlUm9vbVRocmVhZE5vdGlmaWNhdGlvbnMgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3Mvcm9vbS91c2VSb29tVGhyZWFkTm90aWZpY2F0aW9uc1wiO1xuaW1wb3J0IHsgdXNlR2xvYmFsTm90aWZpY2F0aW9uU3RhdGUgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3MvdXNlR2xvYmFsTm90aWZpY2F0aW9uU3RhdGVcIjtcbmltcG9ydCBTZGtDb25maWcgZnJvbSBcIi4uLy4uLy4uL1Nka0NvbmZpZ1wiO1xuaW1wb3J0IHsgdXNlRmVhdHVyZUVuYWJsZWQgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3MvdXNlU2V0dGluZ3NcIjtcbmltcG9ydCB7IHVzZUVuY3J5cHRpb25TdGF0dXMgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3MvdXNlRW5jcnlwdGlvblN0YXR1c1wiO1xuaW1wb3J0IHsgRTJFU3RhdHVzIH0gZnJvbSBcIi4uLy4uLy4uL3V0aWxzL1NoaWVsZFV0aWxzXCI7XG5pbXBvcnQgRmFjZVBpbGUgZnJvbSBcIi4uL2VsZW1lbnRzL0ZhY2VQaWxlXCI7XG5pbXBvcnQgeyB1c2VSb29tU3RhdGUgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3MvdXNlUm9vbVN0YXRlXCI7XG5pbXBvcnQgUm9vbUF2YXRhciBmcm9tIFwiLi4vYXZhdGFycy9Sb29tQXZhdGFyXCI7XG5pbXBvcnQgeyBmb3JtYXRDb3VudCB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9Gb3JtYXR0aW5nVXRpbHNcIjtcbmltcG9ydCBSaWdodFBhbmVsU3RvcmUgZnJvbSBcIi4uLy4uLy4uL3N0b3Jlcy9yaWdodC1wYW5lbC9SaWdodFBhbmVsU3RvcmVcIjtcbmltcG9ydCBQb3N0aG9nVHJhY2tlcnMgZnJvbSBcIi4uLy4uLy4uL1Bvc3Rob2dUcmFja2Vyc1wiO1xuaW1wb3J0IHsgVmlkZW9Sb29tQ2hhdEJ1dHRvbiB9IGZyb20gXCIuL1Jvb21IZWFkZXIvVmlkZW9Sb29tQ2hhdEJ1dHRvblwiO1xuaW1wb3J0IHsgUm9vbUtub2Nrc0JhciB9IGZyb20gXCIuL1Jvb21Lbm9ja3NCYXJcIjtcbmltcG9ydCB7IGlzVmlkZW9Sb29tIGFzIGNhbGNJc1ZpZGVvUm9vbSB9IGZyb20gXCIuLi8uLi8uLi91dGlscy92aWRlby1yb29tc1wiO1xuaW1wb3J0IHsgbm90aWZpY2F0aW9uTGV2ZWxUb0luZGljYXRvciB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9ub3RpZmljYXRpb25zXCI7XG5pbXBvcnQgeyBDYWxsR3Vlc3RMaW5rQnV0dG9uIH0gZnJvbSBcIi4vUm9vbUhlYWRlci9DYWxsR3Vlc3RMaW5rQnV0dG9uXCI7XG5pbXBvcnQgeyBCdXR0b25FdmVudCB9IGZyb20gXCIuLi9lbGVtZW50cy9BY2Nlc3NpYmxlQnV0dG9uXCI7XG5pbXBvcnQgV2l0aFByZXNlbmNlSW5kaWNhdG9yLCB7IHVzZURtTWVtYmVyIH0gZnJvbSBcIi4uL2F2YXRhcnMvV2l0aFByZXNlbmNlSW5kaWNhdG9yXCI7XG5pbXBvcnQgeyBJT09CRGF0YSB9IGZyb20gXCIuLi8uLi8uLi9zdG9yZXMvVGhyZWVwaWRJbnZpdGVTdG9yZVwiO1xuaW1wb3J0IFJvb21Db250ZXh0IGZyb20gXCIuLi8uLi8uLi9jb250ZXh0cy9Sb29tQ29udGV4dFwiO1xuaW1wb3J0IHsgTWFpblNwbGl0Q29udGVudFR5cGUgfSBmcm9tIFwiLi4vLi4vc3RydWN0dXJlcy9Sb29tVmlld1wiO1xuaW1wb3J0IGRlZmF1bHREaXNwYXRjaGVyIGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL2Rpc3BhdGNoZXIudHNcIjtcbmltcG9ydCB7IFJvb21TZXR0aW5nc1RhYiB9IGZyb20gXCIuLi9kaWFsb2dzL1Jvb21TZXR0aW5nc0RpYWxvZy50c3hcIjtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUm9vbUhlYWRlcih7XG4gICAgcm9vbSxcbiAgICBhZGRpdGlvbmFsQnV0dG9ucyxcbiAgICBvb2JEYXRhLFxufToge1xuICAgIHJvb206IFJvb207XG4gICAgYWRkaXRpb25hbEJ1dHRvbnM/OiBWaWV3Um9vbU9wdHNbXCJidXR0b25zXCJdO1xuICAgIG9vYkRhdGE/OiBJT09CRGF0YTtcbn0pOiBKU1guRWxlbWVudCB7XG4gICAgY29uc3QgY2xpZW50ID0gdXNlTWF0cml4Q2xpZW50Q29udGV4dCgpO1xuXG4gICAgY29uc3Qgcm9vbU5hbWUgPSB1c2VSb29tTmFtZShyb29tKTtcbiAgICBjb25zdCBqb2luUnVsZSA9IHVzZVJvb21TdGF0ZShyb29tLCAoc3RhdGUpID0+IHN0YXRlLmdldEpvaW5SdWxlKCkpO1xuXG4gICAgY29uc3QgbWVtYmVycyA9IHVzZVJvb21NZW1iZXJzKHJvb20sIDI1MDApO1xuICAgIGNvbnN0IG1lbWJlckNvdW50ID0gdXNlUm9vbU1lbWJlckNvdW50KHJvb20sIHsgdGhyb3R0bGVXYWl0OiAyNTAwIH0pO1xuXG4gICAgY29uc3Qge1xuICAgICAgICB2b2ljZUNhbGxEaXNhYmxlZFJlYXNvbixcbiAgICAgICAgdm9pY2VDYWxsQ2xpY2ssXG4gICAgICAgIHZpZGVvQ2FsbERpc2FibGVkUmVhc29uLFxuICAgICAgICB2aWRlb0NhbGxDbGljayxcbiAgICAgICAgdG9nZ2xlQ2FsbE1heGltaXplZDogdG9nZ2xlQ2FsbCxcbiAgICAgICAgaXNWaWV3aW5nQ2FsbCxcbiAgICAgICAgaXNDb25uZWN0ZWRUb0NhbGwsXG4gICAgICAgIGhhc0FjdGl2ZUNhbGxTZXNzaW9uLFxuICAgICAgICBjYWxsT3B0aW9ucyxcbiAgICAgICAgc2hvd1ZvaWNlQ2FsbEJ1dHRvbixcbiAgICAgICAgc2hvd1ZpZGVvQ2FsbEJ1dHRvbixcbiAgICB9ID0gdXNlUm9vbUNhbGwocm9vbSk7XG5cbiAgICBjb25zdCBncm91cENhbGxzRW5hYmxlZCA9IHVzZUZlYXR1cmVFbmFibGVkKFwiZmVhdHVyZV9ncm91cF9jYWxsc1wiKTtcbiAgICAvKipcbiAgICAgKiBBIHNwZWNpYWwgbW9kZSB3aGVyZSBvbmx5IEVsZW1lbnQgQ2FsbCBpcyB1c2VkLiBJbiB0aGlzIGNhc2Ugd2Ugd2FudCB0b1xuICAgICAqIGhpZGUgdGhlIHZvaWNlIGNhbGwgYnV0dG9uXG4gICAgICovXG4gICAgY29uc3QgdXNlRWxlbWVudENhbGxFeGNsdXNpdmVseSA9IHVzZU1lbW8oKCkgPT4ge1xuICAgICAgICByZXR1cm4gU2RrQ29uZmlnLmdldChcImVsZW1lbnRfY2FsbFwiKS51c2VfZXhjbHVzaXZlbHkgJiYgZ3JvdXBDYWxsc0VuYWJsZWQ7XG4gICAgfSwgW2dyb3VwQ2FsbHNFbmFibGVkXSk7XG5cbiAgICBjb25zdCB0aHJlYWROb3RpZmljYXRpb25zID0gdXNlUm9vbVRocmVhZE5vdGlmaWNhdGlvbnMocm9vbSk7XG4gICAgY29uc3QgZ2xvYmFsTm90aWZpY2F0aW9uU3RhdGUgPSB1c2VHbG9iYWxOb3RpZmljYXRpb25TdGF0ZSgpO1xuXG4gICAgY29uc3QgZG1NZW1iZXIgPSB1c2VEbU1lbWJlcihyb29tKTtcbiAgICBjb25zdCBpc0RpcmVjdE1lc3NhZ2UgPSAhIWRtTWVtYmVyO1xuICAgIGNvbnN0IGUyZVN0YXR1cyA9IHVzZUVuY3J5cHRpb25TdGF0dXMoY2xpZW50LCByb29tKTtcblxuICAgIGNvbnN0IG5vdGlmaWNhdGlvbnNFbmFibGVkID0gdXNlRmVhdHVyZUVuYWJsZWQoXCJmZWF0dXJlX25vdGlmaWNhdGlvbnNcIik7XG5cbiAgICBjb25zdCBhc2tUb0pvaW5FbmFibGVkID0gdXNlRmVhdHVyZUVuYWJsZWQoXCJmZWF0dXJlX2Fza190b19qb2luXCIpO1xuXG4gICAgY29uc3QgdmlkZW9DbGljayA9IHVzZUNhbGxiYWNrKFxuICAgICAgICAoZXY6IFJlYWN0Lk1vdXNlRXZlbnQpID0+IHZpZGVvQ2FsbENsaWNrKGV2LCBjYWxsT3B0aW9uc1swXSksXG4gICAgICAgIFtjYWxsT3B0aW9ucywgdmlkZW9DYWxsQ2xpY2tdLFxuICAgICk7XG5cbiAgICBjb25zdCB0b2dnbGVDYWxsQnV0dG9uID0gKFxuICAgICAgICA8VG9vbHRpcCBsYWJlbD17aXNWaWV3aW5nQ2FsbCA/IF90KFwidm9pcHxtaW5pbWlzZV9jYWxsXCIpIDogX3QoXCJ2b2lwfG1heGltaXNlX2NhbGxcIil9PlxuICAgICAgICAgICAgPEljb25CdXR0b24gb25DbGljaz17dG9nZ2xlQ2FsbH0+XG4gICAgICAgICAgICAgICAgPFZpZGVvQ2FsbEljb24gLz5cbiAgICAgICAgICAgIDwvSWNvbkJ1dHRvbj5cbiAgICAgICAgPC9Ub29sdGlwPlxuICAgICk7XG5cbiAgICBjb25zdCBqb2luQ2FsbEJ1dHRvbiA9IChcbiAgICAgICAgPFRvb2x0aXAgbGFiZWw9e3ZpZGVvQ2FsbERpc2FibGVkUmVhc29uID8/IF90KFwidm9pcHx2aWRlb19jYWxsXCIpfT5cbiAgICAgICAgICAgIDxCdXR0b25cbiAgICAgICAgICAgICAgICBzaXplPVwic21cIlxuICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3ZpZGVvQ2xpY2t9XG4gICAgICAgICAgICAgICAgSWNvbj17VmlkZW9DYWxsSWNvbn1cbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX2pvaW5fYnV0dG9uXCJcbiAgICAgICAgICAgICAgICBkaXNhYmxlZD17ISF2aWRlb0NhbGxEaXNhYmxlZFJlYXNvbn1cbiAgICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIlxuICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9e3ZpZGVvQ2FsbERpc2FibGVkUmVhc29uID8/IF90KFwiYWN0aW9ufGpvaW5cIil9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAge190KFwiYWN0aW9ufGpvaW5cIil9XG4gICAgICAgICAgICA8L0J1dHRvbj5cbiAgICAgICAgPC9Ub29sdGlwPlxuICAgICk7XG5cbiAgICBjb25zdCBjYWxsSWNvbldpdGhUb29sdGlwID0gKFxuICAgICAgICA8VG9vbHRpcCBsYWJlbD17dmlkZW9DYWxsRGlzYWJsZWRSZWFzb24gPz8gX3QoXCJ2b2lwfHZpZGVvX2NhbGxcIil9PlxuICAgICAgICAgICAgPFZpZGVvQ2FsbEljb24gLz5cbiAgICAgICAgPC9Ub29sdGlwPlxuICAgICk7XG5cbiAgICBjb25zdCBbbWVudU9wZW4sIHNldE1lbnVPcGVuXSA9IHVzZVN0YXRlKGZhbHNlKTtcblxuICAgIGNvbnN0IG9uT3BlbkNoYW5nZSA9IHVzZUNhbGxiYWNrKFxuICAgICAgICAobmV3T3BlbjogYm9vbGVhbikgPT4ge1xuICAgICAgICAgICAgaWYgKCF2aWRlb0NhbGxEaXNhYmxlZFJlYXNvbikgc2V0TWVudU9wZW4obmV3T3Blbik7XG4gICAgICAgIH0sXG4gICAgICAgIFt2aWRlb0NhbGxEaXNhYmxlZFJlYXNvbl0sXG4gICAgKTtcblxuICAgIGNvbnN0IHN0YXJ0VmlkZW9DYWxsQnV0dG9uID0gKFxuICAgICAgICA8PlxuICAgICAgICAgICAgey8qIENhbiBiZSBlaXRoZXIgYSBtZW51IG9yIGp1c3QgYSBidXR0b24gZGVwZW5kaW5nIG9uIHRoZSBudW1iZXIgb2YgY2FsbCBvcHRpb25zLiovfVxuICAgICAgICAgICAge2NhbGxPcHRpb25zLmxlbmd0aCA+IDEgPyAoXG4gICAgICAgICAgICAgICAgPE1lbnVcbiAgICAgICAgICAgICAgICAgICAgb3Blbj17bWVudU9wZW59XG4gICAgICAgICAgICAgICAgICAgIG9uT3BlbkNoYW5nZT17b25PcGVuQ2hhbmdlfVxuICAgICAgICAgICAgICAgICAgICB0aXRsZT17X3QoXCJ2b2lwfHZpZGVvX2NhbGxfdXNpbmdcIil9XG4gICAgICAgICAgICAgICAgICAgIHRyaWdnZXI9e1xuICAgICAgICAgICAgICAgICAgICAgICAgPEljb25CdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZD17ISF2aWRlb0NhbGxEaXNhYmxlZFJlYXNvbn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPXt2aWRlb0NhbGxEaXNhYmxlZFJlYXNvbiA/PyBfdChcInZvaXB8dmlkZW9fY2FsbFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Y2FsbEljb25XaXRoVG9vbHRpcH1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvSWNvbkJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBzaWRlPVwibGVmdFwiXG4gICAgICAgICAgICAgICAgICAgIGFsaWduPVwic3RhcnRcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAge2NhbGxPcHRpb25zLm1hcCgob3B0aW9uKSA9PiAoXG4gICAgICAgICAgICAgICAgICAgICAgICA8TWVudUl0ZW1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk9e29wdGlvbn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD17Z2V0UGxhdGZvcm1DYWxsVHlwZUxhYmVsKG9wdGlvbil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD17Z2V0UGxhdGZvcm1DYWxsVHlwZUxhYmVsKG9wdGlvbil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KGV2KSA9PiB2aWRlb0NhbGxDbGljayhldiwgb3B0aW9uKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJY29uPXtWaWRlb0NhbGxJY29ufVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uU2VsZWN0PXsoKSA9PiB7fSAvKiBEdW1teSBoYW5kbGVyIHNpbmNlIHdlIHdhbnQgdGhlIGNsaWNrIGV2ZW50LiovfVxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgKSl9XG4gICAgICAgICAgICAgICAgPC9NZW51PlxuICAgICAgICAgICAgKSA6IChcbiAgICAgICAgICAgICAgICA8SWNvbkJ1dHRvblxuICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZD17ISF2aWRlb0NhbGxEaXNhYmxlZFJlYXNvbn1cbiAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD17dmlkZW9DYWxsRGlzYWJsZWRSZWFzb24gPz8gX3QoXCJ2b2lwfHZpZGVvX2NhbGxcIil9XG4gICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3ZpZGVvQ2xpY2t9XG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICB7Y2FsbEljb25XaXRoVG9vbHRpcH1cbiAgICAgICAgICAgICAgICA8L0ljb25CdXR0b24+XG4gICAgICAgICAgICApfVxuICAgICAgICA8Lz5cbiAgICApO1xuICAgIGxldCB2b2ljZUNhbGxCdXR0b246IEpTWC5FbGVtZW50IHwgdW5kZWZpbmVkID0gKFxuICAgICAgICA8VG9vbHRpcCBsYWJlbD17dm9pY2VDYWxsRGlzYWJsZWRSZWFzb24gPz8gX3QoXCJ2b2lwfHZvaWNlX2NhbGxcIil9PlxuICAgICAgICAgICAgPEljb25CdXR0b25cbiAgICAgICAgICAgICAgICAvLyBXZSBuZWVkIGJvdGg6IGlzVmlld2luZ0NhbGwgYW5kIGlzQ29ubmVjdGVkVG9DYWxsXG4gICAgICAgICAgICAgICAgLy8gIC0gaW4gdGhlIExvYmJ5IHdlIGFyZSB2aWV3aW5nIGEgY2FsbCBidXQgYXJlIG5vdCBjb25uZWN0ZWQgdG8gaXQuXG4gICAgICAgICAgICAgICAgLy8gIC0gaW4gcGlwIHZpZXcgd2UgYXJlIGNvbm5lY3RlZCB0byB0aGUgY2FsbCBidXQgbm90IHZpZXdpbmcgaXQuXG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ9eyEhdm9pY2VDYWxsRGlzYWJsZWRSZWFzb24gfHwgaXNWaWV3aW5nQ2FsbCB8fCBpc0Nvbm5lY3RlZFRvQ2FsbH1cbiAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPXt2b2ljZUNhbGxEaXNhYmxlZFJlYXNvbiA/PyBfdChcInZvaXB8dm9pY2VfY2FsbFwiKX1cbiAgICAgICAgICAgICAgICBvbkNsaWNrPXsoZXYpID0+IHZvaWNlQ2FsbENsaWNrKGV2LCBjYWxsT3B0aW9uc1swXSl9XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPFZvaWNlQ2FsbEljb24gLz5cbiAgICAgICAgICAgIDwvSWNvbkJ1dHRvbj5cbiAgICAgICAgPC9Ub29sdGlwPlxuICAgICk7XG4gICAgY29uc3QgY2xvc2VMb2JieUJ1dHRvbiA9IChcbiAgICAgICAgPFRvb2x0aXAgbGFiZWw9e190KFwidm9pcHxjbG9zZV9sb2JieVwiKX0+XG4gICAgICAgICAgICA8SWNvbkJ1dHRvbiBvbkNsaWNrPXt0b2dnbGVDYWxsfT5cbiAgICAgICAgICAgICAgICA8Q2xvc2VDYWxsSWNvbiAvPlxuICAgICAgICAgICAgPC9JY29uQnV0dG9uPlxuICAgICAgICA8L1Rvb2x0aXA+XG4gICAgKTtcbiAgICBsZXQgdmlkZW9DYWxsQnV0dG9uOiBKU1guRWxlbWVudCB8IHVuZGVmaW5lZCA9IHN0YXJ0VmlkZW9DYWxsQnV0dG9uO1xuICAgIGlmIChpc0Nvbm5lY3RlZFRvQ2FsbCkge1xuICAgICAgICB2aWRlb0NhbGxCdXR0b24gPSB0b2dnbGVDYWxsQnV0dG9uO1xuICAgIH0gZWxzZSBpZiAoaXNWaWV3aW5nQ2FsbCkge1xuICAgICAgICB2aWRlb0NhbGxCdXR0b24gPSBjbG9zZUxvYmJ5QnV0dG9uO1xuICAgIH1cblxuICAgIGlmICghc2hvd1ZpZGVvQ2FsbEJ1dHRvbikge1xuICAgICAgICB2aWRlb0NhbGxCdXR0b24gPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGlmICghc2hvd1ZvaWNlQ2FsbEJ1dHRvbikge1xuICAgICAgICB2b2ljZUNhbGxCdXR0b24gPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3Qgcm9vbUNvbnRleHQgPSB1c2VDb250ZXh0KFJvb21Db250ZXh0KTtcbiAgICBjb25zdCBpc1ZpZGVvUm9vbSA9IGNhbGNJc1ZpZGVvUm9vbShyb29tKTtcbiAgICBjb25zdCBzaG93Q2hhdEJ1dHRvbiA9XG4gICAgICAgIGlzVmlkZW9Sb29tIHx8XG4gICAgICAgIHJvb21Db250ZXh0Lm1haW5TcGxpdENvbnRlbnRUeXBlID09PSBNYWluU3BsaXRDb250ZW50VHlwZS5NYXhpbWlzZWRXaWRnZXQgfHxcbiAgICAgICAgcm9vbUNvbnRleHQubWFpblNwbGl0Q29udGVudFR5cGUgPT09IE1haW5TcGxpdENvbnRlbnRUeXBlLkNhbGw7XG5cbiAgICBjb25zdCBvbkF2YXRhckNsaWNrID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICBkZWZhdWx0RGlzcGF0Y2hlci5kaXNwYXRjaCh7XG4gICAgICAgICAgICBhY3Rpb246IFwib3Blbl9yb29tX3NldHRpbmdzXCIsXG4gICAgICAgICAgICBpbml0aWFsX3RhYl9pZDogUm9vbVNldHRpbmdzVGFiLkdlbmVyYWwsXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8PlxuICAgICAgICAgICAgPEZsZXggYXM9XCJoZWFkZXJcIiBhbGlnbj1cImNlbnRlclwiIGdhcD1cInZhcigtLWNwZC1zcGFjZS0zeClcIiBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyIGxpZ2h0LXBhbmVsXCI+XG4gICAgICAgICAgICAgICAgPFdpdGhQcmVzZW5jZUluZGljYXRvciByb29tPXtyb29tfSBzaXplPVwiOHB4XCI+XG4gICAgICAgICAgICAgICAgICAgIHsvKiBXZSBoaWRlIHRoaXMgZnJvbSB0aGUgdGFiSW5kZXggbGlzdCBhcyBpdCBpcyBhIHBvaW50ZXIgc2hvcnRjdXQgYW5kIHN1cGVyZmx1b3VzIGZvciBhMTF5ICovfVxuICAgICAgICAgICAgICAgICAgICA8Um9vbUF2YXRhclxuICAgICAgICAgICAgICAgICAgICAgICAgcm9vbT17cm9vbX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHNpemU9XCI0MHB4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9vYkRhdGE9e29vYkRhdGF9XG4gICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXtvbkF2YXRhckNsaWNrfVxuICAgICAgICAgICAgICAgICAgICAgICAgdGFiSW5kZXg9ey0xfVxuICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD17X3QoXCJyb29tfGhlYWRlcl9hdmF0YXJfb3Blbl9zZXR0aW5nc19sYWJlbFwiKX1cbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICA8L1dpdGhQcmVzZW5jZUluZGljYXRvcj5cbiAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9e190KFwicmlnaHRfcGFuZWx8cm9vbV9zdW1tYXJ5X2NhcmR8dGl0bGVcIil9XG4gICAgICAgICAgICAgICAgICAgIHRhYkluZGV4PXswfVxuICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBSaWdodFBhbmVsU3RvcmUuaW5zdGFuY2Uuc2hvd09ySGlkZVBoYXNlKFJpZ2h0UGFuZWxQaGFzZXMuUm9vbVN1bW1hcnkpfVxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX2luZm9XcmFwcGVyXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxCb3ggZmxleD1cIjFcIiBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX2luZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxCb2R5VGV4dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzPVwiZGl2XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplPVwibGdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlaWdodD1cInNlbWlib2xkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXI9XCJhdXRvXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2xlPVwiaGVhZGluZ1wiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sZXZlbD17MX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX2hlYWRpbmdcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cIm14X1Jvb21IZWFkZXJfdHJ1bmNhdGVkIG14X2xpbmVDbGFtcFwiPntyb29tTmFtZX08L3NwYW4+XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IWlzRGlyZWN0TWVzc2FnZSAmJiBqb2luUnVsZSA9PT0gSm9pblJ1bGUuUHVibGljICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPFRvb2x0aXAgbGFiZWw9e190KFwiY29tbW9ufHB1YmxpY19yb29tXCIpfSBwbGFjZW1lbnQ9XCJyaWdodFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPFB1YmxpY0ljb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aD1cIjE2cHhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodD1cIjE2cHhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X1Jvb21IZWFkZXJfaWNvbiB0ZXh0LXNlY29uZGFyeVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD17X3QoXCJjb21tb258cHVibGljX3Jvb21cIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L1Rvb2x0aXA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKX1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtpc0RpcmVjdE1lc3NhZ2UgJiYgZTJlU3RhdHVzID09PSBFMkVTdGF0dXMuVmVyaWZpZWQgJiYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8VG9vbHRpcCBsYWJlbD17X3QoXCJjb21tb258dmVyaWZpZWRcIil9IHBsYWNlbWVudD1cInJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8VmVyaWZpZWRJY29uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg9XCIxNnB4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ9XCIxNnB4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX2ljb24gbXhfVmVyaWZpZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9e190KFwiY29tbW9ufHZlcmlmaWVkXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9Ub29sdGlwPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICl9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7aXNEaXJlY3RNZXNzYWdlICYmIGUyZVN0YXR1cyA9PT0gRTJFU3RhdHVzLldhcm5pbmcgJiYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8VG9vbHRpcCBsYWJlbD17X3QoXCJyb29tfGhlYWRlcl91bnRydXN0ZWRfbGFiZWxcIil9IHBsYWNlbWVudD1cInJpZ2h0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8RXJyb3JJY29uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg9XCIxNnB4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ9XCIxNnB4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX2ljb24gbXhfVW50cnVzdGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPXtfdChcInJvb218aGVhZGVyX3VudHJ1c3RlZF9sYWJlbFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvVG9vbHRpcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9Cb2R5VGV4dD5cbiAgICAgICAgICAgICAgICAgICAgPC9Cb3g+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPEZsZXggYWxpZ249XCJjZW50ZXJcIiBnYXA9XCJ2YXIoLS1jcGQtc3BhY2UtMngpXCI+XG4gICAgICAgICAgICAgICAgICAgIHthZGRpdGlvbmFsQnV0dG9ucz8ubWFwKChwcm9wcykgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbGFiZWwgPSBwcm9wcy5sYWJlbCgpO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxUb29sdGlwIGxhYmVsPXtsYWJlbH0ga2V5PXtwcm9wcy5pZH0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxJY29uQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPXtsYWJlbH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9eyhldmVudCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb3BzLm9uQ2xpY2soKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt0eXBlb2YgcHJvcHMuaWNvbiA9PT0gXCJmdW5jdGlvblwiID8gcHJvcHMuaWNvbigpIDogcHJvcHMuaWNvbn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9JY29uQnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvVG9vbHRpcD5cbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH0pfVxuXG4gICAgICAgICAgICAgICAgICAgIHtpc1ZpZXdpbmdDYWxsICYmIDxDYWxsR3Vlc3RMaW5rQnV0dG9uIHJvb209e3Jvb219IC8+fVxuXG4gICAgICAgICAgICAgICAgICAgIHtoYXNBY3RpdmVDYWxsU2Vzc2lvbiAmJiAhaXNDb25uZWN0ZWRUb0NhbGwgJiYgIWlzVmlld2luZ0NhbGwgPyAoXG4gICAgICAgICAgICAgICAgICAgICAgICBqb2luQ2FsbEJ1dHRvblxuICAgICAgICAgICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICAgICAgICAgICAgPD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IWlzVmlkZW9Sb29tICYmIHZpZGVvQ2FsbEJ1dHRvbn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IXVzZUVsZW1lbnRDYWxsRXhjbHVzaXZlbHkgJiYgIWlzVmlkZW9Sb29tICYmIHZvaWNlQ2FsbEJ1dHRvbn1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvPlxuICAgICAgICAgICAgICAgICAgICApfVxuXG4gICAgICAgICAgICAgICAgICAgIDxUb29sdGlwIGxhYmVsPXtfdChcInJpZ2h0X3BhbmVsfHJvb21fc3VtbWFyeV9jYXJkfHRpdGxlXCIpfT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxJY29uQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KGV2dCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJpZ2h0UGFuZWxTdG9yZS5pbnN0YW5jZS5zaG93T3JIaWRlUGhhc2UoUmlnaHRQYW5lbFBoYXNlcy5Sb29tU3VtbWFyeSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPXtfdChcInJpZ2h0X3BhbmVsfHJvb21fc3VtbWFyeV9jYXJkfHRpdGxlXCIpfVxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxSb29tSW5mb0ljb24gLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvSWNvbkJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPC9Ub29sdGlwPlxuXG4gICAgICAgICAgICAgICAgICAgIHtzaG93Q2hhdEJ1dHRvbiAmJiA8VmlkZW9Sb29tQ2hhdEJ1dHRvbiByb29tPXtyb29tfSAvPn1cblxuICAgICAgICAgICAgICAgICAgICA8VG9vbHRpcCBsYWJlbD17X3QoXCJjb21tb258dGhyZWFkc1wiKX0+XG4gICAgICAgICAgICAgICAgICAgICAgICA8SWNvbkJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGljYXRvcj17bm90aWZpY2F0aW9uTGV2ZWxUb0luZGljYXRvcih0aHJlYWROb3RpZmljYXRpb25zKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoZXZ0KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV2dC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmlnaHRQYW5lbFN0b3JlLmluc3RhbmNlLnNob3dPckhpZGVQaGFzZShSaWdodFBhbmVsUGhhc2VzLlRocmVhZFBhbmVsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUG9zdGhvZ1RyYWNrZXJzLnRyYWNrSW50ZXJhY3Rpb24oXCJXZWJSb29tSGVhZGVyQnV0dG9uc1RocmVhZHNCdXR0b25cIiwgZXZ0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9e190KFwiY29tbW9ufHRocmVhZHNcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPFRocmVhZHNJY29uIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L0ljb25CdXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvVG9vbHRpcD5cbiAgICAgICAgICAgICAgICAgICAge25vdGlmaWNhdGlvbnNFbmFibGVkICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgIDxUb29sdGlwIGxhYmVsPXtfdChcIm5vdGlmaWNhdGlvbnN8ZW5hYmxlX3Byb21wdF90b2FzdF90aXRsZVwiKX0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPEljb25CdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kaWNhdG9yPXtub3RpZmljYXRpb25MZXZlbFRvSW5kaWNhdG9yKGdsb2JhbE5vdGlmaWNhdGlvblN0YXRlLmxldmVsKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KGV2dCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXZ0LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmlnaHRQYW5lbFN0b3JlLmluc3RhbmNlLnNob3dPckhpZGVQaGFzZShSaWdodFBhbmVsUGhhc2VzLk5vdGlmaWNhdGlvblBhbmVsKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD17X3QoXCJub3RpZmljYXRpb25zfGVuYWJsZV9wcm9tcHRfdG9hc3RfdGl0bGVcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Tm90aWZpY2F0aW9uc0ljb24gLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L0ljb25CdXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L1Rvb2x0aXA+XG4gICAgICAgICAgICAgICAgICAgICl9XG4gICAgICAgICAgICAgICAgPC9GbGV4PlxuICAgICAgICAgICAgICAgIHshaXNEaXJlY3RNZXNzYWdlICYmIChcbiAgICAgICAgICAgICAgICAgICAgPEJvZHlUZXh0IGFzPVwiZGl2XCIgc2l6ZT1cInNtXCIgd2VpZ2h0PVwibWVkaXVtXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8RmFjZVBpbGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9Sb29tSGVhZGVyX21lbWJlcnNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbWJlcnM9e21lbWJlcnMuc2xpY2UoMCwgMyl9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZT1cIjIwcHhcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJmbG93PXtmYWxzZX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2aWV3VXNlck9uQ2xpY2s9e2ZhbHNlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2x0aXBMYWJlbD17X3QoXCJyb29tfGhlYWRlcl9mYWNlX3BpbGVfdG9vbHRpcFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoZTogQnV0dG9uRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmlnaHRQYW5lbFN0b3JlLmluc3RhbmNlLnNob3dPckhpZGVQaGFzZShSaWdodFBhbmVsUGhhc2VzLlJvb21NZW1iZXJMaXN0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9e190KFwiY29tbW9ufG5fbWVtYmVyc1wiLCB7IGNvdW50OiBtZW1iZXJDb3VudCB9KX1cbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7Zm9ybWF0Q291bnQobWVtYmVyQ291bnQpfVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9GYWNlUGlsZT5cbiAgICAgICAgICAgICAgICAgICAgPC9Cb2R5VGV4dD5cbiAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgPC9GbGV4PlxuICAgICAgICAgICAge2Fza1RvSm9pbkVuYWJsZWQgJiYgPFJvb21Lbm9ja3NCYXIgcm9vbT17cm9vbX0gLz59XG4gICAgICAgIDwvPlxuICAgICk7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFRQSxJQUFBQSxNQUFBLEdBQUFDLHVCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxZQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxlQUFBLEdBQUFDLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBSSxVQUFBLEdBQUFELHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBSyxNQUFBLEdBQUFGLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBTSxhQUFBLEdBQUFILHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBTyxVQUFBLEdBQUFKLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBUSxtQkFBQSxHQUFBTCxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQVMsU0FBQSxHQUFBTixzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQVUsTUFBQSxHQUFBUCxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQVcsT0FBQSxHQUFBUixzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQVksT0FBQSxHQUFBWixPQUFBO0FBR0EsSUFBQWEsWUFBQSxHQUFBYixPQUFBO0FBQ0EsSUFBQWMsc0JBQUEsR0FBQWQsT0FBQTtBQUNBLElBQUFlLG9CQUFBLEdBQUFmLE9BQUE7QUFDQSxJQUFBZ0IsZUFBQSxHQUFBaEIsT0FB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