matrix-react-sdk
Version:
SDK for matrix.org using React
266 lines (249 loc) • 40.2 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.PinnedMessageBanner = PinnedMessageBanner;
var _react = _interopRequireWildcard(require("react"));
var _pinSolid = _interopRequireDefault(require("@vector-im/compound-design-tokens/assets/web/icons/pin-solid"));
var _compoundWeb = require("@vector-im/compound-web");
var _matrix = require("matrix-js-sdk/src/matrix");
var _classnames = _interopRequireDefault(require("classnames"));
var _usePinnedEvents = require("../../../hooks/usePinnedEvents");
var _languageHandler = require("../../../languageHandler");
var _RightPanelStore = _interopRequireDefault(require("../../../stores/right-panel/RightPanelStore"));
var _RightPanelStorePhases = require("../../../stores/right-panel/RightPanelStorePhases");
var _useEventEmitter = require("../../../hooks/useEventEmitter");
var _AsyncStore = require("../../../stores/AsyncStore");
var _MessagePreviewStore = require("../../../stores/room-list/MessagePreviewStore");
var _dispatcher = _interopRequireDefault(require("../../../dispatcher/dispatcher"));
var _actions = require("../../../dispatcher/actions");
var _MessageEvent = _interopRequireDefault(require("../messages/MessageEvent"));
var _PosthogTrackers = _interopRequireDefault(require("../../../PosthogTrackers.ts"));
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
/*
* Copyright 2024 New Vector Ltd.
* Copyright 2024 The Matrix.org Foundation C.I.C.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
* Please see LICENSE files in the repository root for full details.
*/
/**
* The props for the {@link PinnedMessageBanner} component.
*/
/**
* A banner that displays the pinned messages in a room.
*/
function PinnedMessageBanner({
room,
permalinkCreator
}) {
const pinnedEventIds = (0, _usePinnedEvents.usePinnedEvents)(room);
const pinnedEvents = (0, _usePinnedEvents.useSortedFetchedPinnedEvents)(room, pinnedEventIds);
const eventCount = pinnedEvents.length;
const isSinglePinnedEvent = eventCount === 1;
const [currentEventIndex, setCurrentEventIndex] = (0, _react.useState)(eventCount - 1);
// When the number of pinned messages changes, we want to display the last message
(0, _react.useEffect)(() => {
setCurrentEventIndex(() => eventCount - 1);
}, [eventCount]);
const pinnedEvent = pinnedEvents[currentEventIndex];
if (!pinnedEvent) return null;
const shouldUseMessageEvent = pinnedEvent.isRedacted() || pinnedEvent.isDecryptionFailure();
const onBannerClick = () => {
_PosthogTrackers.default.trackInteraction("PinnedMessageBannerClick");
// Scroll to the pinned message
_dispatcher.default.dispatch({
action: _actions.Action.ViewRoom,
event_id: pinnedEvent.getId(),
highlighted: true,
room_id: room.roomId,
metricsTrigger: undefined // room doesn't change
});
// Cycle through the pinned messages
// When we reach the first message, we go back to the last message
setCurrentEventIndex(currentEventIndex => --currentEventIndex === -1 ? eventCount - 1 : currentEventIndex);
};
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_PinnedMessageBanner",
"data-single-message": isSinglePinnedEvent,
"aria-label": (0, _languageHandler._t)("room|pinned_message_banner|description"),
"data-testid": "pinned-message-banner"
}, /*#__PURE__*/_react.default.createElement("button", {
"aria-label": (0, _languageHandler._t)("room|pinned_message_banner|go_to_message"),
type: "button",
className: "mx_PinnedMessageBanner_main",
onClick: onBannerClick
}, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_PinnedMessageBanner_content"
}, /*#__PURE__*/_react.default.createElement(Indicators, {
count: eventCount,
currentIndex: currentEventIndex
}), /*#__PURE__*/_react.default.createElement(_pinSolid.default, {
width: "20px",
height: "20px",
className: "mx_PinnedMessageBanner_PinIcon"
}), !isSinglePinnedEvent && /*#__PURE__*/_react.default.createElement("div", {
className: "mx_PinnedMessageBanner_title",
"data-testid": "banner-counter"
}, (0, _languageHandler._t)("room|pinned_message_banner|title", {
index: currentEventIndex + 1,
length: eventCount
}, {
bold: sub => /*#__PURE__*/_react.default.createElement("span", {
className: "mx_PinnedMessageBanner_title_counter"
}, sub)
})), /*#__PURE__*/_react.default.createElement(EventPreview, {
pinnedEvent: pinnedEvent
}), shouldUseMessageEvent && /*#__PURE__*/_react.default.createElement("div", {
className: "mx_PinnedMessageBanner_redactedMessage"
}, /*#__PURE__*/_react.default.createElement(_MessageEvent.default, {
mxEvent: pinnedEvent,
maxImageHeight: 20,
permalinkCreator: permalinkCreator,
replacingEventId: pinnedEvent.replacingEventId()
})))), !isSinglePinnedEvent && /*#__PURE__*/_react.default.createElement(BannerButton, {
room: room
}));
}
/**
* The props for the {@link EventPreview} component.
*/
/**
* A component that displays a preview for the pinned event.
*/
function EventPreview({
pinnedEvent
}) {
const preview = useEventPreview(pinnedEvent);
if (!preview) return null;
const prefix = getPreviewPrefix(pinnedEvent.getType(), pinnedEvent.getContent().msgtype);
if (!prefix) return /*#__PURE__*/_react.default.createElement("span", {
className: "mx_PinnedMessageBanner_message",
"data-testid": "banner-message"
}, preview);
return /*#__PURE__*/_react.default.createElement("span", {
className: "mx_PinnedMessageBanner_message",
"data-testid": "banner-message"
}, (0, _languageHandler._t)("room|pinned_message_banner|preview", {
prefix,
preview
}, {
bold: sub => /*#__PURE__*/_react.default.createElement("span", {
className: "mx_PinnedMessageBanner_prefix"
}, sub)
}));
}
/**
* Hooks to generate a preview for the pinned event.
* @param pinnedEvent
*/
function useEventPreview(pinnedEvent) {
return (0, _react.useMemo)(() => {
if (!pinnedEvent || pinnedEvent.isRedacted() || pinnedEvent.isDecryptionFailure()) return null;
return _MessagePreviewStore.MessagePreviewStore.instance.generatePreviewForEvent(pinnedEvent);
}, [pinnedEvent]);
}
/**
* Get the prefix for the preview based on the type and the message type.
* @param type
* @param msgType
*/
function getPreviewPrefix(type, msgType) {
switch (type) {
case _matrix.M_POLL_START.name:
return (0, _languageHandler._t)("room|pinned_message_banner|prefix|poll");
default:
}
switch (msgType) {
case _matrix.MsgType.Audio:
return (0, _languageHandler._t)("room|pinned_message_banner|prefix|audio");
case _matrix.MsgType.Image:
return (0, _languageHandler._t)("room|pinned_message_banner|prefix|image");
case _matrix.MsgType.Video:
return (0, _languageHandler._t)("room|pinned_message_banner|prefix|video");
case _matrix.MsgType.File:
return (0, _languageHandler._t)("room|pinned_message_banner|prefix|file");
default:
return null;
}
}
const MAX_INDICATORS = 3;
/**
* The props for the {@link IndicatorsProps} component.
*/
/**
* A component that displays vertical indicators for the pinned messages.
*/
function Indicators({
count,
currentIndex
}) {
// We only display a maximum of 3 indicators at one time.
// When there is more than 3 messages pinned, we will cycle through the indicators
// If there is only 2 messages pinned, we will display 2 indicators
// In case of 1 message pinned, the indicators are not displayed, see {@link PinnedMessageBanner} logic.
const numberOfIndicators = Math.min(count, MAX_INDICATORS);
// The index of the active indicator
const index = currentIndex % numberOfIndicators;
// We hide the indicators when we are on the last cycle and there are less than 3 remaining messages pinned
const numberOfCycles = Math.ceil(count / numberOfIndicators);
// If the current index is greater than the last cycle index, we are on the last cycle
const isLastCycle = currentIndex >= (numberOfCycles - 1) * MAX_INDICATORS;
// The index of the last message in the last cycle
const lastCycleIndex = numberOfIndicators - (numberOfCycles * numberOfIndicators - count);
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_PinnedMessageBanner_Indicators"
}, Array.from({
length: numberOfIndicators
}).map((_, i) => /*#__PURE__*/_react.default.createElement(Indicator, {
key: i,
active: i === index,
hidden: isLastCycle && lastCycleIndex <= i
})));
}
/**
* The props for the {@link Indicator} component.
*/
/**
* A component that displays a vertical indicator for a pinned message.
*/
function Indicator({
active,
hidden
}) {
return /*#__PURE__*/_react.default.createElement("div", {
"data-testid": "banner-indicator",
className: (0, _classnames.default)("mx_PinnedMessageBanner_Indicator", {
"mx_PinnedMessageBanner_Indicator--active": active,
"mx_PinnedMessageBanner_Indicator--hidden": hidden
})
});
}
function getRightPanelPhase(roomId) {
if (!_RightPanelStore.default.instance.isOpenForRoom(roomId)) return null;
return _RightPanelStore.default.instance.currentCard.phase;
}
/**
* The props for the {@link BannerButton} component.
*/
/**
* A button that allows the user to view or close the list of pinned messages.
*/
function BannerButton({
room
}) {
const [currentPhase, setCurrentPhase] = (0, _react.useState)(getRightPanelPhase(room.roomId));
(0, _useEventEmitter.useEventEmitter)(_RightPanelStore.default.instance, _AsyncStore.UPDATE_EVENT, () => setCurrentPhase(getRightPanelPhase(room.roomId)));
const isPinnedMessagesPhase = currentPhase === _RightPanelStorePhases.RightPanelPhases.PinnedMessages;
return /*#__PURE__*/_react.default.createElement(_compoundWeb.Button, {
className: "mx_PinnedMessageBanner_actions",
kind: "tertiary",
onClick: () => {
if (isPinnedMessagesPhase) _PosthogTrackers.default.trackInteraction("PinnedMessageBannerCloseListButton");else _PosthogTrackers.default.trackInteraction("PinnedMessageBannerViewAllButton");
_RightPanelStore.default.instance.showOrHidePhase(_RightPanelStorePhases.RightPanelPhases.PinnedMessages);
}
}, isPinnedMessagesPhase ? (0, _languageHandler._t)("room|pinned_message_banner|button_close_list") : (0, _languageHandler._t)("room|pinned_message_banner|button_view_all"));
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfcGluU29saWQiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX2NvbXBvdW5kV2ViIiwiX21hdHJpeCIsIl9jbGFzc25hbWVzIiwiX3VzZVBpbm5lZEV2ZW50cyIsIl9sYW5ndWFnZUhhbmRsZXIiLCJfUmlnaHRQYW5lbFN0b3JlIiwiX1JpZ2h0UGFuZWxTdG9yZVBoYXNlcyIsIl91c2VFdmVudEVtaXR0ZXIiLCJfQXN5bmNTdG9yZSIsIl9NZXNzYWdlUHJldmlld1N0b3JlIiwiX2Rpc3BhdGNoZXIiLCJfYWN0aW9ucyIsIl9NZXNzYWdlRXZlbnQiLCJfUG9zdGhvZ1RyYWNrZXJzIiwiX2dldFJlcXVpcmVXaWxkY2FyZENhY2hlIiwiZSIsIldlYWtNYXAiLCJyIiwidCIsIl9fZXNNb2R1bGUiLCJkZWZhdWx0IiwiaGFzIiwiZ2V0IiwibiIsIl9fcHJvdG9fXyIsImEiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpIiwic2V0IiwiUGlubmVkTWVzc2FnZUJhbm5lciIsInJvb20iLCJwZXJtYWxpbmtDcmVhdG9yIiwicGlubmVkRXZlbnRJZHMiLCJ1c2VQaW5uZWRFdmVudHMiLCJwaW5uZWRFdmVudHMiLCJ1c2VTb3J0ZWRGZXRjaGVkUGlubmVkRXZlbnRzIiwiZXZlbnRDb3VudCIsImxlbmd0aCIsImlzU2luZ2xlUGlubmVkRXZlbnQiLCJjdXJyZW50RXZlbnRJbmRleCIsInNldEN1cnJlbnRFdmVudEluZGV4IiwidXNlU3RhdGUiLCJ1c2VFZmZlY3QiLCJwaW5uZWRFdmVudCIsInNob3VsZFVzZU1lc3NhZ2VFdmVudCIsImlzUmVkYWN0ZWQiLCJpc0RlY3J5cHRpb25GYWlsdXJlIiwib25CYW5uZXJDbGljayIsIlBvc3Rob2dUcmFja2VycyIsInRyYWNrSW50ZXJhY3Rpb24iLCJkaXMiLCJkaXNwYXRjaCIsImFjdGlvbiIsIkFjdGlvbiIsIlZpZXdSb29tIiwiZXZlbnRfaWQiLCJnZXRJZCIsImhpZ2hsaWdodGVkIiwicm9vbV9pZCIsInJvb21JZCIsIm1ldHJpY3NUcmlnZ2VyIiwidW5kZWZpbmVkIiwiY3JlYXRlRWxlbWVudCIsImNsYXNzTmFtZSIsIl90IiwidHlwZSIsIm9uQ2xpY2siLCJJbmRpY2F0b3JzIiwiY291bnQiLCJjdXJyZW50SW5kZXgiLCJ3aWR0aCIsImhlaWdodCIsImluZGV4IiwiYm9sZCIsInN1YiIsIkV2ZW50UHJldmlldyIsIm14RXZlbnQiLCJtYXhJbWFnZUhlaWdodCIsInJlcGxhY2luZ0V2ZW50SWQiLCJCYW5uZXJCdXR0b24iLCJwcmV2aWV3IiwidXNlRXZlbnRQcmV2aWV3IiwicHJlZml4IiwiZ2V0UHJldmlld1ByZWZpeCIsImdldFR5cGUiLCJnZXRDb250ZW50IiwibXNndHlwZSIsInVzZU1lbW8iLCJNZXNzYWdlUHJldmlld1N0b3JlIiwiaW5zdGFuY2UiLCJnZW5lcmF0ZVByZXZpZXdGb3JFdmVudCIsIm1zZ1R5cGUiLCJNX1BPTExfU1RBUlQiLCJuYW1lIiwiTXNnVHlwZSIsIkF1ZGlvIiwiSW1hZ2UiLCJWaWRlbyIsIkZpbGUiLCJNQVhfSU5ESUNBVE9SUyIsIm51bWJlck9mSW5kaWNhdG9ycyIsIk1hdGgiLCJtaW4iLCJudW1iZXJPZkN5Y2xlcyIsImNlaWwiLCJpc0xhc3RDeWNsZSIsImxhc3RDeWNsZUluZGV4IiwiQXJyYXkiLCJmcm9tIiwibWFwIiwiXyIsIkluZGljYXRvciIsImtleSIsImFjdGl2ZSIsImhpZGRlbiIsImNsYXNzTmFtZXMiLCJnZXRSaWdodFBhbmVsUGhhc2UiLCJSaWdodFBhbmVsU3RvcmUiLCJpc09wZW5Gb3JSb29tIiwiY3VycmVudENhcmQiLCJwaGFzZSIsImN1cnJlbnRQaGFzZSIsInNldEN1cnJlbnRQaGFzZSIsInVzZUV2ZW50RW1pdHRlciIsIlVQREFURV9FVkVOVCIsImlzUGlubmVkTWVzc2FnZXNQaGFzZSIsIlJpZ2h0UGFuZWxQaGFzZXMiLCJQaW5uZWRNZXNzYWdlcyIsIkJ1dHRvbiIsImtpbmQiLCJzaG93T3JIaWRlUGhhc2UiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy92aWV3cy9yb29tcy9QaW5uZWRNZXNzYWdlQmFubmVyLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IDIwMjQgTmV3IFZlY3RvciBMdGQuXG4gKiBDb3B5cmlnaHQgMjAyNCBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuICpcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuICogUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiAqL1xuXG5pbXBvcnQgUmVhY3QsIHsgSlNYLCB1c2VFZmZlY3QsIHVzZU1lbW8sIHVzZVN0YXRlIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgUGluSWNvbiBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC1kZXNpZ24tdG9rZW5zL2Fzc2V0cy93ZWIvaWNvbnMvcGluLXNvbGlkXCI7XG5pbXBvcnQgeyBCdXR0b24gfSBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC13ZWJcIjtcbmltcG9ydCB7IE1fUE9MTF9TVEFSVCwgTWF0cml4RXZlbnQsIE1zZ1R5cGUsIFJvb20gfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5pbXBvcnQgY2xhc3NOYW1lcyBmcm9tIFwiY2xhc3NuYW1lc1wiO1xuXG5pbXBvcnQgeyB1c2VQaW5uZWRFdmVudHMsIHVzZVNvcnRlZEZldGNoZWRQaW5uZWRFdmVudHMgfSBmcm9tIFwiLi4vLi4vLi4vaG9va3MvdXNlUGlubmVkRXZlbnRzXCI7XG5pbXBvcnQgeyBfdCB9IGZyb20gXCIuLi8uLi8uLi9sYW5ndWFnZUhhbmRsZXJcIjtcbmltcG9ydCBSaWdodFBhbmVsU3RvcmUgZnJvbSBcIi4uLy4uLy4uL3N0b3Jlcy9yaWdodC1wYW5lbC9SaWdodFBhbmVsU3RvcmVcIjtcbmltcG9ydCB7IFJpZ2h0UGFuZWxQaGFzZXMgfSBmcm9tIFwiLi4vLi4vLi4vc3RvcmVzL3JpZ2h0LXBhbmVsL1JpZ2h0UGFuZWxTdG9yZVBoYXNlc1wiO1xuaW1wb3J0IHsgdXNlRXZlbnRFbWl0dGVyIH0gZnJvbSBcIi4uLy4uLy4uL2hvb2tzL3VzZUV2ZW50RW1pdHRlclwiO1xuaW1wb3J0IHsgVVBEQVRFX0VWRU5UIH0gZnJvbSBcIi4uLy4uLy4uL3N0b3Jlcy9Bc3luY1N0b3JlXCI7XG5pbXBvcnQgeyBSb29tUGVybWFsaW5rQ3JlYXRvciB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9wZXJtYWxpbmtzL1Blcm1hbGlua3NcIjtcbmltcG9ydCB7IE1lc3NhZ2VQcmV2aWV3U3RvcmUgfSBmcm9tIFwiLi4vLi4vLi4vc3RvcmVzL3Jvb20tbGlzdC9NZXNzYWdlUHJldmlld1N0b3JlXCI7XG5pbXBvcnQgZGlzIGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL2Rpc3BhdGNoZXJcIjtcbmltcG9ydCB7IFZpZXdSb29tUGF5bG9hZCB9IGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL3BheWxvYWRzL1ZpZXdSb29tUGF5bG9hZFwiO1xuaW1wb3J0IHsgQWN0aW9uIH0gZnJvbSBcIi4uLy4uLy4uL2Rpc3BhdGNoZXIvYWN0aW9uc1wiO1xuaW1wb3J0IE1lc3NhZ2VFdmVudCBmcm9tIFwiLi4vbWVzc2FnZXMvTWVzc2FnZUV2ZW50XCI7XG5pbXBvcnQgUG9zdGhvZ1RyYWNrZXJzIGZyb20gXCIuLi8uLi8uLi9Qb3N0aG9nVHJhY2tlcnMudHNcIjtcblxuLyoqXG4gKiBUaGUgcHJvcHMgZm9yIHRoZSB7QGxpbmsgUGlubmVkTWVzc2FnZUJhbm5lcn0gY29tcG9uZW50LlxuICovXG5pbnRlcmZhY2UgUGlubmVkTWVzc2FnZUJhbm5lclByb3BzIHtcbiAgICAvKipcbiAgICAgKiBUaGUgcGVybWFsaW5rIGNyZWF0b3IgdG8gdXNlLlxuICAgICAqL1xuICAgIHBlcm1hbGlua0NyZWF0b3I6IFJvb21QZXJtYWxpbmtDcmVhdG9yO1xuICAgIC8qKlxuICAgICAqIFRoZSByb29tIHdoZXJlIHRoZSBiYW5uZXIgaXMgZGlzcGxheWVkXG4gICAgICovXG4gICAgcm9vbTogUm9vbTtcbn1cblxuLyoqXG4gKiBBIGJhbm5lciB0aGF0IGRpc3BsYXlzIHRoZSBwaW5uZWQgbWVzc2FnZXMgaW4gYSByb29tLlxuICovXG5leHBvcnQgZnVuY3Rpb24gUGlubmVkTWVzc2FnZUJhbm5lcih7IHJvb20sIHBlcm1hbGlua0NyZWF0b3IgfTogUGlubmVkTWVzc2FnZUJhbm5lclByb3BzKTogSlNYLkVsZW1lbnQgfCBudWxsIHtcbiAgICBjb25zdCBwaW5uZWRFdmVudElkcyA9IHVzZVBpbm5lZEV2ZW50cyhyb29tKTtcbiAgICBjb25zdCBwaW5uZWRFdmVudHMgPSB1c2VTb3J0ZWRGZXRjaGVkUGlubmVkRXZlbnRzKHJvb20sIHBpbm5lZEV2ZW50SWRzKTtcbiAgICBjb25zdCBldmVudENvdW50ID0gcGlubmVkRXZlbnRzLmxlbmd0aDtcbiAgICBjb25zdCBpc1NpbmdsZVBpbm5lZEV2ZW50ID0gZXZlbnRDb3VudCA9PT0gMTtcblxuICAgIGNvbnN0IFtjdXJyZW50RXZlbnRJbmRleCwgc2V0Q3VycmVudEV2ZW50SW5kZXhdID0gdXNlU3RhdGUoZXZlbnRDb3VudCAtIDEpO1xuICAgIC8vIFdoZW4gdGhlIG51bWJlciBvZiBwaW5uZWQgbWVzc2FnZXMgY2hhbmdlcywgd2Ugd2FudCB0byBkaXNwbGF5IHRoZSBsYXN0IG1lc3NhZ2VcbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICBzZXRDdXJyZW50RXZlbnRJbmRleCgoKSA9PiBldmVudENvdW50IC0gMSk7XG4gICAgfSwgW2V2ZW50Q291bnRdKTtcblxuICAgIGNvbnN0IHBpbm5lZEV2ZW50ID0gcGlubmVkRXZlbnRzW2N1cnJlbnRFdmVudEluZGV4XTtcbiAgICBpZiAoIXBpbm5lZEV2ZW50KSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IHNob3VsZFVzZU1lc3NhZ2VFdmVudCA9IHBpbm5lZEV2ZW50LmlzUmVkYWN0ZWQoKSB8fCBwaW5uZWRFdmVudC5pc0RlY3J5cHRpb25GYWlsdXJlKCk7XG5cbiAgICBjb25zdCBvbkJhbm5lckNsaWNrID0gKCk6IHZvaWQgPT4ge1xuICAgICAgICBQb3N0aG9nVHJhY2tlcnMudHJhY2tJbnRlcmFjdGlvbihcIlBpbm5lZE1lc3NhZ2VCYW5uZXJDbGlja1wiKTtcblxuICAgICAgICAvLyBTY3JvbGwgdG8gdGhlIHBpbm5lZCBtZXNzYWdlXG4gICAgICAgIGRpcy5kaXNwYXRjaDxWaWV3Um9vbVBheWxvYWQ+KHtcbiAgICAgICAgICAgIGFjdGlvbjogQWN0aW9uLlZpZXdSb29tLFxuICAgICAgICAgICAgZXZlbnRfaWQ6IHBpbm5lZEV2ZW50LmdldElkKCksXG4gICAgICAgICAgICBoaWdobGlnaHRlZDogdHJ1ZSxcbiAgICAgICAgICAgIHJvb21faWQ6IHJvb20ucm9vbUlkLFxuICAgICAgICAgICAgbWV0cmljc1RyaWdnZXI6IHVuZGVmaW5lZCwgLy8gcm9vbSBkb2Vzbid0IGNoYW5nZVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBDeWNsZSB0aHJvdWdoIHRoZSBwaW5uZWQgbWVzc2FnZXNcbiAgICAgICAgLy8gV2hlbiB3ZSByZWFjaCB0aGUgZmlyc3QgbWVzc2FnZSwgd2UgZ28gYmFjayB0byB0aGUgbGFzdCBtZXNzYWdlXG4gICAgICAgIHNldEN1cnJlbnRFdmVudEluZGV4KChjdXJyZW50RXZlbnRJbmRleCkgPT4gKC0tY3VycmVudEV2ZW50SW5kZXggPT09IC0xID8gZXZlbnRDb3VudCAtIDEgOiBjdXJyZW50RXZlbnRJbmRleCkpO1xuICAgIH07XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjbGFzc05hbWU9XCJteF9QaW5uZWRNZXNzYWdlQmFubmVyXCJcbiAgICAgICAgICAgIGRhdGEtc2luZ2xlLW1lc3NhZ2U9e2lzU2luZ2xlUGlubmVkRXZlbnR9XG4gICAgICAgICAgICBhcmlhLWxhYmVsPXtfdChcInJvb218cGlubmVkX21lc3NhZ2VfYmFubmVyfGRlc2NyaXB0aW9uXCIpfVxuICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJwaW5uZWQtbWVzc2FnZS1iYW5uZXJcIlxuICAgICAgICA+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgYXJpYS1sYWJlbD17X3QoXCJyb29tfHBpbm5lZF9tZXNzYWdlX2Jhbm5lcnxnb190b19tZXNzYWdlXCIpfVxuICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X1Bpbm5lZE1lc3NhZ2VCYW5uZXJfbWFpblwiXG4gICAgICAgICAgICAgICAgb25DbGljaz17b25CYW5uZXJDbGlja31cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1Bpbm5lZE1lc3NhZ2VCYW5uZXJfY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICA8SW5kaWNhdG9ycyBjb3VudD17ZXZlbnRDb3VudH0gY3VycmVudEluZGV4PXtjdXJyZW50RXZlbnRJbmRleH0gLz5cbiAgICAgICAgICAgICAgICAgICAgPFBpbkljb24gd2lkdGg9XCIyMHB4XCIgaGVpZ2h0PVwiMjBweFwiIGNsYXNzTmFtZT1cIm14X1Bpbm5lZE1lc3NhZ2VCYW5uZXJfUGluSWNvblwiIC8+XG4gICAgICAgICAgICAgICAgICAgIHshaXNTaW5nbGVQaW5uZWRFdmVudCAmJiAoXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1Bpbm5lZE1lc3NhZ2VCYW5uZXJfdGl0bGVcIiBkYXRhLXRlc3RpZD1cImJhbm5lci1jb3VudGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge190KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcInJvb218cGlubmVkX21lc3NhZ2VfYmFubmVyfHRpdGxlXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4OiBjdXJyZW50RXZlbnRJbmRleCArIDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGg6IGV2ZW50Q291bnQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgYm9sZDogKHN1YikgPT4gPHNwYW4gY2xhc3NOYW1lPVwibXhfUGlubmVkTWVzc2FnZUJhbm5lcl90aXRsZV9jb3VudGVyXCI+e3N1Yn08L3NwYW4+IH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgICAgICA8RXZlbnRQcmV2aWV3IHBpbm5lZEV2ZW50PXtwaW5uZWRFdmVudH0gLz5cbiAgICAgICAgICAgICAgICAgICAgey8qIEluIGNhc2Ugb2YgcmVkYWN0ZWQgZXZlbnQsIHdlIHdhbnQgdG8gZGlzcGxheSB0aGUgbmljZSBzZW50ZW5jZSBvZiB0aGUgbWVzc2FnZSBldmVudCBsaWtlIGluIHRoZSB0aW1lbGluZSBvciBpbiB0aGUgcGlubmVkIG1lc3NhZ2UgbGlzdCAqL31cbiAgICAgICAgICAgICAgICAgICAge3Nob3VsZFVzZU1lc3NhZ2VFdmVudCAmJiAoXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1Bpbm5lZE1lc3NhZ2VCYW5uZXJfcmVkYWN0ZWRNZXNzYWdlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPE1lc3NhZ2VFdmVudFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBteEV2ZW50PXtwaW5uZWRFdmVudH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4SW1hZ2VIZWlnaHQ9ezIwfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZXJtYWxpbmtDcmVhdG9yPXtwZXJtYWxpbmtDcmVhdG9yfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXBsYWNpbmdFdmVudElkPXtwaW5uZWRFdmVudC5yZXBsYWNpbmdFdmVudElkKCl9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICB7IWlzU2luZ2xlUGlubmVkRXZlbnQgJiYgPEJhbm5lckJ1dHRvbiByb29tPXtyb29tfSAvPn1cbiAgICAgICAgPC9kaXY+XG4gICAgKTtcbn1cblxuLyoqXG4gKiBUaGUgcHJvcHMgZm9yIHRoZSB7QGxpbmsgRXZlbnRQcmV2aWV3fSBjb21wb25lbnQuXG4gKi9cbmludGVyZmFjZSBFdmVudFByZXZpZXdQcm9wcyB7XG4gICAgLyoqXG4gICAgICogVGhlIHBpbm5lZCBldmVudCB0byBkaXNwbGF5IHRoZSBwcmV2aWV3IGZvclxuICAgICAqL1xuICAgIHBpbm5lZEV2ZW50OiBNYXRyaXhFdmVudDtcbn1cblxuLyoqXG4gKiBBIGNvbXBvbmVudCB0aGF0IGRpc3BsYXlzIGEgcHJldmlldyBmb3IgdGhlIHBpbm5lZCBldmVudC5cbiAqL1xuZnVuY3Rpb24gRXZlbnRQcmV2aWV3KHsgcGlubmVkRXZlbnQgfTogRXZlbnRQcmV2aWV3UHJvcHMpOiBKU1guRWxlbWVudCB8IG51bGwge1xuICAgIGNvbnN0IHByZXZpZXcgPSB1c2VFdmVudFByZXZpZXcocGlubmVkRXZlbnQpO1xuICAgIGlmICghcHJldmlldykgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBwcmVmaXggPSBnZXRQcmV2aWV3UHJlZml4KHBpbm5lZEV2ZW50LmdldFR5cGUoKSwgcGlubmVkRXZlbnQuZ2V0Q29udGVudCgpLm1zZ3R5cGUgYXMgTXNnVHlwZSk7XG4gICAgaWYgKCFwcmVmaXgpXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJteF9QaW5uZWRNZXNzYWdlQmFubmVyX21lc3NhZ2VcIiBkYXRhLXRlc3RpZD1cImJhbm5lci1tZXNzYWdlXCI+XG4gICAgICAgICAgICAgICAge3ByZXZpZXd9XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICk7XG5cbiAgICByZXR1cm4gKFxuICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJteF9QaW5uZWRNZXNzYWdlQmFubmVyX21lc3NhZ2VcIiBkYXRhLXRlc3RpZD1cImJhbm5lci1tZXNzYWdlXCI+XG4gICAgICAgICAgICB7X3QoXG4gICAgICAgICAgICAgICAgXCJyb29tfHBpbm5lZF9tZXNzYWdlX2Jhbm5lcnxwcmV2aWV3XCIsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBwcmVmaXgsXG4gICAgICAgICAgICAgICAgICAgIHByZXZpZXcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGJvbGQ6IChzdWIpID0+IDxzcGFuIGNsYXNzTmFtZT1cIm14X1Bpbm5lZE1lc3NhZ2VCYW5uZXJfcHJlZml4XCI+e3N1Yn08L3NwYW4+LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICApfVxuICAgICAgICA8L3NwYW4+XG4gICAgKTtcbn1cblxuLyoqXG4gKiBIb29rcyB0byBnZW5lcmF0ZSBhIHByZXZpZXcgZm9yIHRoZSBwaW5uZWQgZXZlbnQuXG4gKiBAcGFyYW0gcGlubmVkRXZlbnRcbiAqL1xuZnVuY3Rpb24gdXNlRXZlbnRQcmV2aWV3KHBpbm5lZEV2ZW50OiBNYXRyaXhFdmVudCB8IG51bGwpOiBzdHJpbmcgfCBudWxsIHtcbiAgICByZXR1cm4gdXNlTWVtbygoKSA9PiB7XG4gICAgICAgIGlmICghcGlubmVkRXZlbnQgfHwgcGlubmVkRXZlbnQuaXNSZWRhY3RlZCgpIHx8IHBpbm5lZEV2ZW50LmlzRGVjcnlwdGlvbkZhaWx1cmUoKSkgcmV0dXJuIG51bGw7XG4gICAgICAgIHJldHVybiBNZXNzYWdlUHJldmlld1N0b3JlLmluc3RhbmNlLmdlbmVyYXRlUHJldmlld0ZvckV2ZW50KHBpbm5lZEV2ZW50KTtcbiAgICB9LCBbcGlubmVkRXZlbnRdKTtcbn1cblxuLyoqXG4gKiBHZXQgdGhlIHByZWZpeCBmb3IgdGhlIHByZXZpZXcgYmFzZWQgb24gdGhlIHR5cGUgYW5kIHRoZSBtZXNzYWdlIHR5cGUuXG4gKiBAcGFyYW0gdHlwZVxuICogQHBhcmFtIG1zZ1R5cGVcbiAqL1xuZnVuY3Rpb24gZ2V0UHJldmlld1ByZWZpeCh0eXBlOiBzdHJpbmcsIG1zZ1R5cGU6IE1zZ1R5cGUpOiBzdHJpbmcgfCBudWxsIHtcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgICAgY2FzZSBNX1BPTExfU1RBUlQubmFtZTpcbiAgICAgICAgICAgIHJldHVybiBfdChcInJvb218cGlubmVkX21lc3NhZ2VfYmFubmVyfHByZWZpeHxwb2xsXCIpO1xuICAgICAgICBkZWZhdWx0OlxuICAgIH1cblxuICAgIHN3aXRjaCAobXNnVHlwZSkge1xuICAgICAgICBjYXNlIE1zZ1R5cGUuQXVkaW86XG4gICAgICAgICAgICByZXR1cm4gX3QoXCJyb29tfHBpbm5lZF9tZXNzYWdlX2Jhbm5lcnxwcmVmaXh8YXVkaW9cIik7XG4gICAgICAgIGNhc2UgTXNnVHlwZS5JbWFnZTpcbiAgICAgICAgICAgIHJldHVybiBfdChcInJvb218cGlubmVkX21lc3NhZ2VfYmFubmVyfHByZWZpeHxpbWFnZVwiKTtcbiAgICAgICAgY2FzZSBNc2dUeXBlLlZpZGVvOlxuICAgICAgICAgICAgcmV0dXJuIF90KFwicm9vbXxwaW5uZWRfbWVzc2FnZV9iYW5uZXJ8cHJlZml4fHZpZGVvXCIpO1xuICAgICAgICBjYXNlIE1zZ1R5cGUuRmlsZTpcbiAgICAgICAgICAgIHJldHVybiBfdChcInJvb218cGlubmVkX21lc3NhZ2VfYmFubmVyfHByZWZpeHxmaWxlXCIpO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxufVxuXG5jb25zdCBNQVhfSU5ESUNBVE9SUyA9IDM7XG5cbi8qKlxuICogVGhlIHByb3BzIGZvciB0aGUge0BsaW5rIEluZGljYXRvcnNQcm9wc30gY29tcG9uZW50LlxuICovXG5pbnRlcmZhY2UgSW5kaWNhdG9yc1Byb3BzIHtcbiAgICAvKipcbiAgICAgKiBUaGUgbnVtYmVyIG9mIG1lc3NhZ2VzIHBpbm5lZFxuICAgICAqL1xuICAgIGNvdW50OiBudW1iZXI7XG4gICAgLyoqXG4gICAgICogVGhlIGN1cnJlbnQgaW5kZXggb2YgdGhlIHBpbm5lZCBtZXNzYWdlXG4gICAgICovXG4gICAgY3VycmVudEluZGV4OiBudW1iZXI7XG59XG5cbi8qKlxuICogQSBjb21wb25lbnQgdGhhdCBkaXNwbGF5cyB2ZXJ0aWNhbCBpbmRpY2F0b3JzIGZvciB0aGUgcGlubmVkIG1lc3NhZ2VzLlxuICovXG5mdW5jdGlvbiBJbmRpY2F0b3JzKHsgY291bnQsIGN1cnJlbnRJbmRleCB9OiBJbmRpY2F0b3JzUHJvcHMpOiBKU1guRWxlbWVudCB7XG4gICAgLy8gV2Ugb25seSBkaXNwbGF5IGEgbWF4aW11bSBvZiAzIGluZGljYXRvcnMgYXQgb25lIHRpbWUuXG4gICAgLy8gV2hlbiB0aGVyZSBpcyBtb3JlIHRoYW4gMyBtZXNzYWdlcyBwaW5uZWQsIHdlIHdpbGwgY3ljbGUgdGhyb3VnaCB0aGUgaW5kaWNhdG9yc1xuXG4gICAgLy8gSWYgdGhlcmUgaXMgb25seSAyIG1lc3NhZ2VzIHBpbm5lZCwgd2Ugd2lsbCBkaXNwbGF5IDIgaW5kaWNhdG9yc1xuICAgIC8vIEluIGNhc2Ugb2YgMSBtZXNzYWdlIHBpbm5lZCwgdGhlIGluZGljYXRvcnMgYXJlIG5vdCBkaXNwbGF5ZWQsIHNlZSB7QGxpbmsgUGlubmVkTWVzc2FnZUJhbm5lcn0gbG9naWMuXG4gICAgY29uc3QgbnVtYmVyT2ZJbmRpY2F0b3JzID0gTWF0aC5taW4oY291bnQsIE1BWF9JTkRJQ0FUT1JTKTtcbiAgICAvLyBUaGUgaW5kZXggb2YgdGhlIGFjdGl2ZSBpbmRpY2F0b3JcbiAgICBjb25zdCBpbmRleCA9IGN1cnJlbnRJbmRleCAlIG51bWJlck9mSW5kaWNhdG9ycztcblxuICAgIC8vIFdlIGhpZGUgdGhlIGluZGljYXRvcnMgd2hlbiB3ZSBhcmUgb24gdGhlIGxhc3QgY3ljbGUgYW5kIHRoZXJlIGFyZSBsZXNzIHRoYW4gMyByZW1haW5pbmcgbWVzc2FnZXMgcGlubmVkXG4gICAgY29uc3QgbnVtYmVyT2ZDeWNsZXMgPSBNYXRoLmNlaWwoY291bnQgLyBudW1iZXJPZkluZGljYXRvcnMpO1xuICAgIC8vIElmIHRoZSBjdXJyZW50IGluZGV4IGlzIGdyZWF0ZXIgdGhhbiB0aGUgbGFzdCBjeWNsZSBpbmRleCwgd2UgYXJlIG9uIHRoZSBsYXN0IGN5Y2xlXG4gICAgY29uc3QgaXNMYXN0Q3ljbGUgPSBjdXJyZW50SW5kZXggPj0gKG51bWJlck9mQ3ljbGVzIC0gMSkgKiBNQVhfSU5ESUNBVE9SUztcbiAgICAvLyBUaGUgaW5kZXggb2YgdGhlIGxhc3QgbWVzc2FnZSBpbiB0aGUgbGFzdCBjeWNsZVxuICAgIGNvbnN0IGxhc3RDeWNsZUluZGV4ID0gbnVtYmVyT2ZJbmRpY2F0b3JzIC0gKG51bWJlck9mQ3ljbGVzICogbnVtYmVyT2ZJbmRpY2F0b3JzIC0gY291bnQpO1xuXG4gICAgcmV0dXJuIChcbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9QaW5uZWRNZXNzYWdlQmFubmVyX0luZGljYXRvcnNcIj5cbiAgICAgICAgICAgIHtBcnJheS5mcm9tKHsgbGVuZ3RoOiBudW1iZXJPZkluZGljYXRvcnMgfSkubWFwKChfLCBpKSA9PiAoXG4gICAgICAgICAgICAgICAgPEluZGljYXRvciBrZXk9e2l9IGFjdGl2ZT17aSA9PT0gaW5kZXh9IGhpZGRlbj17aXNMYXN0Q3ljbGUgJiYgbGFzdEN5Y2xlSW5kZXggPD0gaX0gLz5cbiAgICAgICAgICAgICkpfVxuICAgICAgICA8L2Rpdj5cbiAgICApO1xufVxuXG4vKipcbiAqIFRoZSBwcm9wcyBmb3IgdGhlIHtAbGluayBJbmRpY2F0b3J9IGNvbXBvbmVudC5cbiAqL1xuaW50ZXJmYWNlIEluZGljYXRvclByb3BzIHtcbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHRoZSBpbmRpY2F0b3IgaXMgYWN0aXZlXG4gICAgICovXG4gICAgYWN0aXZlOiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhlIGluZGljYXRvciBpcyBoaWRkZW5cbiAgICAgKi9cbiAgICBoaWRkZW46IGJvb2xlYW47XG59XG5cbi8qKlxuICogQSBjb21wb25lbnQgdGhhdCBkaXNwbGF5cyBhIHZlcnRpY2FsIGluZGljYXRvciBmb3IgYSBwaW5uZWQgbWVzc2FnZS5cbiAqL1xuZnVuY3Rpb24gSW5kaWNhdG9yKHsgYWN0aXZlLCBoaWRkZW4gfTogSW5kaWNhdG9yUHJvcHMpOiBKU1guRWxlbWVudCB7XG4gICAgcmV0dXJuIChcbiAgICAgICAgPGRpdlxuICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJiYW5uZXItaW5kaWNhdG9yXCJcbiAgICAgICAgICAgIGNsYXNzTmFtZT17Y2xhc3NOYW1lcyhcIm14X1Bpbm5lZE1lc3NhZ2VCYW5uZXJfSW5kaWNhdG9yXCIsIHtcbiAgICAgICAgICAgICAgICBcIm14X1Bpbm5lZE1lc3NhZ2VCYW5uZXJfSW5kaWNhdG9yLS1hY3RpdmVcIjogYWN0aXZlLFxuICAgICAgICAgICAgICAgIFwibXhfUGlubmVkTWVzc2FnZUJhbm5lcl9JbmRpY2F0b3ItLWhpZGRlblwiOiBoaWRkZW4sXG4gICAgICAgICAgICB9KX1cbiAgICAgICAgLz5cbiAgICApO1xufVxuXG5mdW5jdGlvbiBnZXRSaWdodFBhbmVsUGhhc2Uocm9vbUlkOiBzdHJpbmcpOiBSaWdodFBhbmVsUGhhc2VzIHwgbnVsbCB7XG4gICAgaWYgKCFSaWdodFBhbmVsU3RvcmUuaW5zdGFuY2UuaXNPcGVuRm9yUm9vbShyb29tSWQpKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gUmlnaHRQYW5lbFN0b3JlLmluc3RhbmNlLmN1cnJlbnRDYXJkLnBoYXNlO1xufVxuXG4vKipcbiAqIFRoZSBwcm9wcyBmb3IgdGhlIHtAbGluayBCYW5uZXJCdXR0b259IGNvbXBvbmVudC5cbiAqL1xuaW50ZXJmYWNlIEJhbm5lckJ1dHRvblByb3BzIHtcbiAgICAvKipcbiAgICAgKiBUaGUgcm9vbSB3aGVyZSB0aGUgYmFubmVyIGlzIGRpc3BsYXllZFxuICAgICAqL1xuICAgIHJvb206IFJvb207XG59XG5cbi8qKlxuICogQSBidXR0b24gdGhhdCBhbGxvd3MgdGhlIHVzZXIgdG8gdmlldyBvciBjbG9zZSB0aGUgbGlzdCBvZiBwaW5uZWQgbWVzc2FnZXMuXG4gKi9cbmZ1bmN0aW9uIEJhbm5lckJ1dHRvbih7IHJvb20gfTogQmFubmVyQnV0dG9uUHJvcHMpOiBKU1guRWxlbWVudCB7XG4gICAgY29uc3QgW2N1cnJlbnRQaGFzZSwgc2V0Q3VycmVudFBoYXNlXSA9IHVzZVN0YXRlPFJpZ2h0UGFuZWxQaGFzZXMgfCBudWxsPihnZXRSaWdodFBhbmVsUGhhc2Uocm9vbS5yb29tSWQpKTtcbiAgICB1c2VFdmVudEVtaXR0ZXIoUmlnaHRQYW5lbFN0b3JlLmluc3RhbmNlLCBVUERBVEVfRVZFTlQsICgpID0+IHNldEN1cnJlbnRQaGFzZShnZXRSaWdodFBhbmVsUGhhc2Uocm9vbS5yb29tSWQpKSk7XG4gICAgY29uc3QgaXNQaW5uZWRNZXNzYWdlc1BoYXNlID0gY3VycmVudFBoYXNlID09PSBSaWdodFBhbmVsUGhhc2VzLlBpbm5lZE1lc3NhZ2VzO1xuXG4gICAgcmV0dXJuIChcbiAgICAgICAgPEJ1dHRvblxuICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfUGlubmVkTWVzc2FnZUJhbm5lcl9hY3Rpb25zXCJcbiAgICAgICAgICAgIGtpbmQ9XCJ0ZXJ0aWFyeVwiXG4gICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGlzUGlubmVkTWVzc2FnZXNQaGFzZSkgUG9zdGhvZ1RyYWNrZXJzLnRyYWNrSW50ZXJhY3Rpb24oXCJQaW5uZWRNZXNzYWdlQmFubmVyQ2xvc2VMaXN0QnV0dG9uXCIpO1xuICAgICAgICAgICAgICAgIGVsc2UgUG9zdGhvZ1RyYWNrZXJzLnRyYWNrSW50ZXJhY3Rpb24oXCJQaW5uZWRNZXNzYWdlQmFubmVyVmlld0FsbEJ1dHRvblwiKTtcblxuICAgICAgICAgICAgICAgIFJpZ2h0UGFuZWxTdG9yZS5pbnN0YW5jZS5zaG93T3JIaWRlUGhhc2UoUmlnaHRQYW5lbFBoYXNlcy5QaW5uZWRNZXNzYWdlcyk7XG4gICAgICAgICAgICB9fVxuICAgICAgICA+XG4gICAgICAgICAgICB7aXNQaW5uZWRNZXNzYWdlc1BoYXNlXG4gICAgICAgICAgICAgICAgPyBfdChcInJvb218cGlubmVkX21lc3NhZ2VfYmFubmVyfGJ1dHRvbl9jbG9zZV9saXN0XCIpXG4gICAgICAgICAgICAgICAgOiBfdChcInJvb218cGlubmVkX21lc3NhZ2VfYmFubmVyfGJ1dHRvbl92aWV3X2FsbFwiKX1cbiAgICAgICAgPC9CdXR0b24+XG4gICAgKTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7OztBQVFBLElBQUFBLE1BQUEsR0FBQUMsdUJBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLFNBQUEsR0FBQUMsc0JBQUEsQ0FBQUYsT0FBQTtBQUNBLElBQUFHLFlBQUEsR0FBQUgsT0FBQTtBQUNBLElBQUFJLE9BQUEsR0FBQUosT0FBQTtBQUNBLElBQUFLLFdBQUEsR0FBQUgsc0JBQUEsQ0FBQUYsT0FBQTtBQUVBLElBQUFNLGdCQUFBLEdBQUFOLE9BQUE7QUFDQSxJQUFBTyxnQkFBQSxHQUFBUCxPQUFBO0FB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