matrix-react-sdk
Version:
SDK for matrix.org using React
238 lines (231 loc) • 44.3 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useRoomCall = exports.getPlatformCallTypeLabel = exports.PlatformCallType = void 0;
var _react = require("react");
var _call = require("matrix-js-sdk/src/webrtc/call");
var _useSettings = require("../useSettings");
var _SdkConfig = _interopRequireDefault(require("../../SdkConfig"));
var _useEventEmitter = require("../useEventEmitter");
var _LegacyCallHandler = _interopRequireWildcard(require("../../LegacyCallHandler"));
var _WidgetUtils = require("../../utils/WidgetUtils");
var _WidgetType = require("../../widgets/WidgetType");
var _useCall = require("../useCall");
var _useRoomMembers = require("../useRoomMembers");
var _Call = require("../../models/Call");
var _placeCall = require("../../utils/room/placeCall");
var _WidgetLayoutStore = require("../../stores/widgets/WidgetLayoutStore");
var _useRoomState = require("../useRoomState");
var _languageHandler = require("../../languageHandler");
var _ManagedHybrid = require("../../widgets/ManagedHybrid");
var _SDKContext = require("../../contexts/SDKContext");
var _AsyncStore = require("../../stores/AsyncStore");
var _dispatcher = _interopRequireDefault(require("../../dispatcher/dispatcher"));
var _actions = require("../../dispatcher/actions");
var _CallStore = require("../../stores/CallStore");
var _videoRooms = require("../../utils/video-rooms");
var _useGuestAccessInformation = require("./useGuestAccessInformation");
var _SettingsStore = _interopRequireDefault(require("../../settings/SettingsStore"));
var _UIFeature = require("../../settings/UIFeature");
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.
*/
let PlatformCallType = exports.PlatformCallType = /*#__PURE__*/function (PlatformCallType) {
PlatformCallType[PlatformCallType["ElementCall"] = 0] = "ElementCall";
PlatformCallType[PlatformCallType["JitsiCall"] = 1] = "JitsiCall";
PlatformCallType[PlatformCallType["LegacyCall"] = 2] = "LegacyCall";
return PlatformCallType;
}({});
const getPlatformCallTypeLabel = platformCallType => {
switch (platformCallType) {
case PlatformCallType.ElementCall:
return (0, _languageHandler._t)("voip|element_call");
case PlatformCallType.JitsiCall:
return (0, _languageHandler._t)("voip|jitsi_call");
case PlatformCallType.LegacyCall:
return (0, _languageHandler._t)("voip|legacy_call");
}
};
exports.getPlatformCallTypeLabel = getPlatformCallTypeLabel;
var State = /*#__PURE__*/function (State) {
State[State["NoCall"] = 0] = "NoCall";
State[State["NoOneHere"] = 1] = "NoOneHere";
State[State["NoPermission"] = 2] = "NoPermission";
State[State["Unpinned"] = 3] = "Unpinned";
State[State["Ongoing"] = 4] = "Ongoing";
State[State["NotJoined"] = 5] = "NotJoined";
return State;
}(State || {});
/**
* Utility hook for resolving state and click handlers for Voice & Video call buttons in the room header
* @param room the room to track
* @returns the call button attributes for the given room
*/
const useRoomCall = room => {
// settings
const groupCallsEnabled = (0, _useSettings.useFeatureEnabled)("feature_group_calls");
const useElementCallExclusively = (0, _react.useMemo)(() => {
return _SdkConfig.default.get("element_call").use_exclusively;
}, []);
const hasLegacyCall = (0, _useEventEmitter.useEventEmitterState)(_LegacyCallHandler.default.instance, _LegacyCallHandler.LegacyCallHandlerEvent.CallsChanged, () => _LegacyCallHandler.default.instance.getCallForRoom(room.roomId) !== null);
// settings
const widgets = (0, _WidgetUtils.useWidgets)(room);
const jitsiWidget = (0, _react.useMemo)(() => widgets.find(widget => _WidgetType.WidgetType.JITSI.matches(widget.type)), [widgets]);
const hasJitsiWidget = !!jitsiWidget;
const managedHybridWidget = (0, _react.useMemo)(() => widgets.find(_ManagedHybrid.isManagedHybridWidget), [widgets]);
const hasManagedHybridWidget = !!managedHybridWidget;
// group call
const groupCall = (0, _useCall.useCall)(room.roomId);
const isConnectedToCall = (0, _useCall.useConnectionState)(groupCall) === _Call.ConnectionState.Connected;
const hasGroupCall = groupCall !== null;
const hasActiveCallSession = (0, _useCall.useParticipantCount)(groupCall) > 0;
const isViewingCall = (0, _useEventEmitter.useEventEmitterState)(_SDKContext.SdkContextClass.instance.roomViewStore, _AsyncStore.UPDATE_EVENT, () => _SDKContext.SdkContextClass.instance.roomViewStore.isViewingCall() || (0, _videoRooms.isVideoRoom)(room));
// room
const memberCount = (0, _useRoomMembers.useRoomMemberCount)(room);
const [mayEditWidgets, mayCreateElementCalls] = (0, _useRoomState.useRoomState)(room, () => [room.currentState.mayClientSendStateEvent("im.vector.modular.widgets", room.client), room.currentState.mayClientSendStateEvent(_Call.ElementCall.MEMBER_EVENT_TYPE.name, room.client)]);
// The options provided to the RoomHeader.
// If there are multiple options, the user will be prompted to choose.
const callOptions = (0, _react.useMemo)(() => {
const options = [];
if (memberCount <= 2) {
options.push(PlatformCallType.LegacyCall);
} else if (mayEditWidgets || hasJitsiWidget) {
options.push(PlatformCallType.JitsiCall);
}
if (groupCallsEnabled) {
if (hasGroupCall || mayCreateElementCalls) {
options.push(PlatformCallType.ElementCall);
}
if (useElementCallExclusively && !hasJitsiWidget) {
return [PlatformCallType.ElementCall];
}
}
if (hasGroupCall && _WidgetType.WidgetType.CALL.matches(groupCall.widget.type)) {
// only allow joining the ongoing Element call if there is one.
return [PlatformCallType.ElementCall];
}
return options;
}, [memberCount, mayEditWidgets, hasJitsiWidget, groupCallsEnabled, hasGroupCall, mayCreateElementCalls, useElementCallExclusively, groupCall?.widget.type]);
let widget;
if (callOptions.includes(PlatformCallType.JitsiCall) || callOptions.includes(PlatformCallType.LegacyCall)) {
widget = jitsiWidget ?? managedHybridWidget;
}
if (callOptions.includes(PlatformCallType.ElementCall)) {
widget = groupCall?.widget;
} else {
widget = groupCall?.widget ?? jitsiWidget;
}
const updateWidgetState = (0, _react.useCallback)(() => {
setCanPinWidget(_WidgetLayoutStore.WidgetLayoutStore.instance.canAddToContainer(room, _WidgetLayoutStore.Container.Top));
setWidgetPinned(!!widget && _WidgetLayoutStore.WidgetLayoutStore.instance.isInContainer(room, widget, _WidgetLayoutStore.Container.Top));
}, [room, widget]);
(0, _useEventEmitter.useEventEmitter)(_WidgetLayoutStore.WidgetLayoutStore.instance, _WidgetLayoutStore.WidgetLayoutStore.emissionForRoom(room), updateWidgetState);
(0, _react.useEffect)(() => {
updateWidgetState();
}, [room, jitsiWidget, groupCall, updateWidgetState]);
const [canPinWidget, setCanPinWidget] = (0, _react.useState)(false);
const [widgetPinned, setWidgetPinned] = (0, _react.useState)(false);
// We only want to prompt to pin the widget if it's not element call based.
const isECWidget = _WidgetType.WidgetType.CALL.matches(widget?.type ?? "");
const promptPinWidget = !isECWidget && canPinWidget && !widgetPinned;
const connectedCalls = (0, _useEventEmitter.useEventEmitterState)(_CallStore.CallStore.instance, _CallStore.CallStoreEvent.ConnectedCalls, () => Array.from(_CallStore.CallStore.instance.connectedCalls));
const {
canInviteGuests
} = (0, _useGuestAccessInformation.useGuestAccessInformation)(room);
const state = (0, _react.useMemo)(() => {
if (connectedCalls.find(call => call.roomId != room.roomId)) {
return State.Ongoing;
}
if (hasGroupCall && (hasJitsiWidget || hasManagedHybridWidget)) {
return promptPinWidget ? State.Unpinned : State.Ongoing;
}
if (hasLegacyCall) {
return State.Ongoing;
}
if (memberCount <= 1 && !canInviteGuests) {
return State.NoOneHere;
}
if (!mayCreateElementCalls && !mayEditWidgets) {
return State.NoPermission;
}
return State.NoCall;
}, [connectedCalls, canInviteGuests, hasGroupCall, hasJitsiWidget, hasLegacyCall, hasManagedHybridWidget, mayCreateElementCalls, mayEditWidgets, memberCount, promptPinWidget, room.roomId]);
const voiceCallClick = (0, _react.useCallback)((evt, callPlatformType) => {
evt?.stopPropagation();
if (widget && promptPinWidget) {
_WidgetLayoutStore.WidgetLayoutStore.instance.moveToContainer(room, widget, _WidgetLayoutStore.Container.Top);
} else {
(0, _placeCall.placeCall)(room, _call.CallType.Voice, callPlatformType, evt?.shiftKey ?? false);
}
}, [promptPinWidget, room, widget]);
const videoCallClick = (0, _react.useCallback)((evt, callPlatformType) => {
evt?.stopPropagation();
if (widget && promptPinWidget) {
_WidgetLayoutStore.WidgetLayoutStore.instance.moveToContainer(room, widget, _WidgetLayoutStore.Container.Top);
} else {
(0, _placeCall.placeCall)(room, _call.CallType.Video, callPlatformType, evt?.shiftKey ?? false);
}
}, [widget, promptPinWidget, room]);
let voiceCallDisabledReason;
let videoCallDisabledReason;
switch (state) {
case State.NoPermission:
voiceCallDisabledReason = (0, _languageHandler._t)("voip|disabled_no_perms_start_voice_call");
videoCallDisabledReason = (0, _languageHandler._t)("voip|disabled_no_perms_start_video_call");
break;
case State.Ongoing:
voiceCallDisabledReason = (0, _languageHandler._t)("voip|disabled_ongoing_call");
videoCallDisabledReason = (0, _languageHandler._t)("voip|disabled_ongoing_call");
break;
case State.NoOneHere:
voiceCallDisabledReason = (0, _languageHandler._t)("voip|disabled_no_one_here");
videoCallDisabledReason = (0, _languageHandler._t)("voip|disabled_no_one_here");
break;
case State.Unpinned:
case State.NotJoined:
case State.NoCall:
voiceCallDisabledReason = null;
videoCallDisabledReason = null;
}
const toggleCallMaximized = (0, _react.useCallback)(() => {
_dispatcher.default.dispatch({
action: _actions.Action.ViewRoom,
room_id: room.roomId,
metricsTrigger: undefined,
view_call: !isViewingCall
});
}, [isViewingCall, room.roomId]);
// We hide the voice call button if it'd have the same effect as the video call button
let hideVoiceCallButton = (0, _ManagedHybrid.isManagedHybridWidgetEnabled)(room) || !callOptions.includes(PlatformCallType.LegacyCall);
let hideVideoCallButton = false;
// We hide both buttons if they require widgets but widgets are disabled.
if (memberCount > 2 && !_SettingsStore.default.getValue(_UIFeature.UIFeature.Widgets)) {
hideVoiceCallButton = true;
hideVideoCallButton = true;
}
/**
* We've gone through all the steps
*/
return {
voiceCallDisabledReason,
voiceCallClick,
videoCallDisabledReason,
videoCallClick,
toggleCallMaximized: toggleCallMaximized,
isViewingCall: isViewingCall,
isConnectedToCall: isConnectedToCall,
hasActiveCallSession: hasActiveCallSession,
callOptions,
showVoiceCallButton: !hideVoiceCallButton,
showVideoCallButton: !hideVideoCallButton
};
};
exports.useRoomCall = useRoomCall;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJyZXF1aXJlIiwiX2NhbGwiLCJfdXNlU2V0dGluZ3MiLCJfU2RrQ29uZmlnIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl91c2VFdmVudEVtaXR0ZXIiLCJfTGVnYWN5Q2FsbEhhbmRsZXIiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsIl9XaWRnZXRVdGlscyIsIl9XaWRnZXRUeXBlIiwiX3VzZUNhbGwiLCJfdXNlUm9vbU1lbWJlcnMiLCJfQ2FsbCIsIl9wbGFjZUNhbGwiLCJfV2lkZ2V0TGF5b3V0U3RvcmUiLCJfdXNlUm9vbVN0YXRlIiwiX2xhbmd1YWdlSGFuZGxlciIsIl9NYW5hZ2VkSHlicmlkIiwiX1NES0NvbnRleHQiLCJfQXN5bmNTdG9yZSIsIl9kaXNwYXRjaGVyIiwiX2FjdGlvbnMiLCJfQ2FsbFN0b3JlIiwiX3ZpZGVvUm9vbXMiLCJfdXNlR3Vlc3RBY2Nlc3NJbmZvcm1hdGlvbiIsIl9TZXR0aW5nc1N0b3JlIiwiX1VJRmVhdHVyZSIsIl9nZXRSZXF1aXJlV2lsZGNhcmRDYWNoZSIsImUiLCJXZWFrTWFwIiwiciIsInQiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsImhhcyIsImdldCIsIm4iLCJfX3Byb3RvX18iLCJhIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJ1IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiaSIsInNldCIsIlBsYXRmb3JtQ2FsbFR5cGUiLCJleHBvcnRzIiwiZ2V0UGxhdGZvcm1DYWxsVHlwZUxhYmVsIiwicGxhdGZvcm1DYWxsVHlwZSIsIkVsZW1lbnRDYWxsIiwiX3QiLCJKaXRzaUNhbGwiLCJMZWdhY3lDYWxsIiwiU3RhdGUiLCJ1c2VSb29tQ2FsbCIsInJvb20iLCJncm91cENhbGxzRW5hYmxlZCIsInVzZUZlYXR1cmVFbmFibGVkIiwidXNlRWxlbWVudENhbGxFeGNsdXNpdmVseSIsInVzZU1lbW8iLCJTZGtDb25maWciLCJ1c2VfZXhjbHVzaXZlbHkiLCJoYXNMZWdhY3lDYWxsIiwidXNlRXZlbnRFbWl0dGVyU3RhdGUiLCJMZWdhY3lDYWxsSGFuZGxlciIsImluc3RhbmNlIiwiTGVnYWN5Q2FsbEhhbmRsZXJFdmVudCIsIkNhbGxzQ2hhbmdlZCIsImdldENhbGxGb3JSb29tIiwicm9vbUlkIiwid2lkZ2V0cyIsInVzZVdpZGdldHMiLCJqaXRzaVdpZGdldCIsImZpbmQiLCJ3aWRnZXQiLCJXaWRnZXRUeXBlIiwiSklUU0kiLCJtYXRjaGVzIiwidHlwZSIsImhhc0ppdHNpV2lkZ2V0IiwibWFuYWdlZEh5YnJpZFdpZGdldCIsImlzTWFuYWdlZEh5YnJpZFdpZGdldCIsImhhc01hbmFnZWRIeWJyaWRXaWRnZXQiLCJncm91cENhbGwiLCJ1c2VDYWxsIiwiaXNDb25uZWN0ZWRUb0NhbGwiLCJ1c2VDb25uZWN0aW9uU3RhdGUiLCJDb25uZWN0aW9uU3RhdGUiLCJDb25uZWN0ZWQiLCJoYXNHcm91cENhbGwiLCJoYXNBY3RpdmVDYWxsU2Vzc2lvbiIsInVzZVBhcnRpY2lwYW50Q291bnQiLCJpc1ZpZXdpbmdDYWxsIiwiU2RrQ29udGV4dENsYXNzIiwicm9vbVZpZXdTdG9yZSIsIlVQREFURV9FVkVOVCIsImlzVmlkZW9Sb29tIiwibWVtYmVyQ291bnQiLCJ1c2VSb29tTWVtYmVyQ291bnQiLCJtYXlFZGl0V2lkZ2V0cyIsIm1heUNyZWF0ZUVsZW1lbnRDYWxscyIsInVzZVJvb21TdGF0ZSIsImN1cnJlbnRTdGF0ZSIsIm1heUNsaWVudFNlbmRTdGF0ZUV2ZW50IiwiY2xpZW50IiwiTUVNQkVSX0VWRU5UX1RZUEUiLCJuYW1lIiwiY2FsbE9wdGlvbnMiLCJvcHRpb25zIiwicHVzaCIsIkNBTEwiLCJpbmNsdWRlcyIsInVwZGF0ZVdpZGdldFN0YXRlIiwidXNlQ2FsbGJhY2siLCJzZXRDYW5QaW5XaWRnZXQiLCJXaWRnZXRMYXlvdXRTdG9yZSIsImNhbkFkZFRvQ29udGFpbmVyIiwiQ29udGFpbmVyIiwiVG9wIiwic2V0V2lkZ2V0UGlubmVkIiwiaXNJbkNvbnRhaW5lciIsInVzZUV2ZW50RW1pdHRlciIsImVtaXNzaW9uRm9yUm9vbSIsInVzZUVmZmVjdCIsImNhblBpbldpZGdldCIsInVzZVN0YXRlIiwid2lkZ2V0UGlubmVkIiwiaXNFQ1dpZGdldCIsInByb21wdFBpbldpZGdldCIsImNvbm5lY3RlZENhbGxzIiwiQ2FsbFN0b3JlIiwiQ2FsbFN0b3JlRXZlbnQiLCJDb25uZWN0ZWRDYWxscyIsIkFycmF5IiwiZnJvbSIsImNhbkludml0ZUd1ZXN0cyIsInVzZUd1ZXN0QWNjZXNzSW5mb3JtYXRpb24iLCJzdGF0ZSIsIk9uZ29pbmciLCJVbnBpbm5lZCIsIk5vT25lSGVyZSIsIk5vUGVybWlzc2lvbiIsIk5vQ2FsbCIsInZvaWNlQ2FsbENsaWNrIiwiZXZ0IiwiY2FsbFBsYXRmb3JtVHlwZSIsInN0b3BQcm9wYWdhdGlvbiIsIm1vdmVUb0NvbnRhaW5lciIsInBsYWNlQ2FsbCIsIkNhbGxUeXBlIiwiVm9pY2UiLCJzaGlmdEtleSIsInZpZGVvQ2FsbENsaWNrIiwiVmlkZW8iLCJ2b2ljZUNhbGxEaXNhYmxlZFJlYXNvbiIsInZpZGVvQ2FsbERpc2FibGVkUmVhc29uIiwiTm90Sm9pbmVkIiwidG9nZ2xlQ2FsbE1heGltaXplZCIsImRlZmF1bHREaXNwYXRjaGVyIiwiZGlzcGF0Y2giLCJhY3Rpb24iLCJBY3Rpb24iLCJWaWV3Um9vbSIsInJvb21faWQiLCJtZXRyaWNzVHJpZ2dlciIsInVuZGVmaW5lZCIsInZpZXdfY2FsbCIsImhpZGVWb2ljZUNhbGxCdXR0b24iLCJpc01hbmFnZWRIeWJyaWRXaWRnZXRFbmFibGVkIiwiaGlkZVZpZGVvQ2FsbEJ1dHRvbiIsIlNldHRpbmdzU3RvcmUiLCJnZXRWYWx1ZSIsIlVJRmVhdHVyZSIsIldpZGdldHMiLCJzaG93Vm9pY2VDYWxsQnV0dG9uIiwic2hvd1ZpZGVvQ2FsbEJ1dHRvbiJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9ob29rcy9yb29tL3VzZVJvb21DYWxsLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAyNCBOZXcgVmVjdG9yIEx0ZC5cbkNvcHlyaWdodCAyMDIzIFRoZSBNYXRyaXgub3JnIEZvdW5kYXRpb24gQy5JLkMuXG5cblNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiovXG5cbmltcG9ydCB7IFJvb20gfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5pbXBvcnQgUmVhY3QsIHsgdXNlQ2FsbGJhY2ssIHVzZUVmZmVjdCwgdXNlTWVtbywgdXNlU3RhdGUgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCB7IENhbGxUeXBlIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL3dlYnJ0Yy9jYWxsXCI7XG5cbmltcG9ydCB7IHVzZUZlYXR1cmVFbmFibGVkIH0gZnJvbSBcIi4uL3VzZVNldHRpbmdzXCI7XG5pbXBvcnQgU2RrQ29uZmlnIGZyb20gXCIuLi8uLi9TZGtDb25maWdcIjtcbmltcG9ydCB7IHVzZUV2ZW50RW1pdHRlciwgdXNlRXZlbnRFbWl0dGVyU3RhdGUgfSBmcm9tIFwiLi4vdXNlRXZlbnRFbWl0dGVyXCI7XG5pbXBvcnQgTGVnYWN5Q2FsbEhhbmRsZXIsIHsgTGVnYWN5Q2FsbEhhbmRsZXJFdmVudCB9IGZyb20gXCIuLi8uLi9MZWdhY3lDYWxsSGFuZGxlclwiO1xuaW1wb3J0IHsgdXNlV2lkZ2V0cyB9IGZyb20gXCIuLi8uLi91dGlscy9XaWRnZXRVdGlsc1wiO1xuaW1wb3J0IHsgV2lkZ2V0VHlwZSB9IGZyb20gXCIuLi8uLi93aWRnZXRzL1dpZGdldFR5cGVcIjtcbmltcG9ydCB7IHVzZUNhbGwsIHVzZUNvbm5lY3Rpb25TdGF0ZSwgdXNlUGFydGljaXBhbnRDb3VudCB9IGZyb20gXCIuLi91c2VDYWxsXCI7XG5pbXBvcnQgeyB1c2VSb29tTWVtYmVyQ291bnQgfSBmcm9tIFwiLi4vdXNlUm9vbU1lbWJlcnNcIjtcbmltcG9ydCB7IENvbm5lY3Rpb25TdGF0ZSwgRWxlbWVudENhbGwgfSBmcm9tIFwiLi4vLi4vbW9kZWxzL0NhbGxcIjtcbmltcG9ydCB7IHBsYWNlQ2FsbCB9IGZyb20gXCIuLi8uLi91dGlscy9yb29tL3BsYWNlQ2FsbFwiO1xuaW1wb3J0IHsgQ29udGFpbmVyLCBXaWRnZXRMYXlvdXRTdG9yZSB9IGZyb20gXCIuLi8uLi9zdG9yZXMvd2lkZ2V0cy9XaWRnZXRMYXlvdXRTdG9yZVwiO1xuaW1wb3J0IHsgdXNlUm9vbVN0YXRlIH0gZnJvbSBcIi4uL3VzZVJvb21TdGF0ZVwiO1xuaW1wb3J0IHsgX3QgfSBmcm9tIFwiLi4vLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgeyBpc01hbmFnZWRIeWJyaWRXaWRnZXQsIGlzTWFuYWdlZEh5YnJpZFdpZGdldEVuYWJsZWQgfSBmcm9tIFwiLi4vLi4vd2lkZ2V0cy9NYW5hZ2VkSHlicmlkXCI7XG5pbXBvcnQgeyBJQXBwIH0gZnJvbSBcIi4uLy4uL3N0b3Jlcy9XaWRnZXRTdG9yZVwiO1xuaW1wb3J0IHsgU2RrQ29udGV4dENsYXNzIH0gZnJvbSBcIi4uLy4uL2NvbnRleHRzL1NES0NvbnRleHRcIjtcbmltcG9ydCB7IFVQREFURV9FVkVOVCB9IGZyb20gXCIuLi8uLi9zdG9yZXMvQXN5bmNTdG9yZVwiO1xuaW1wb3J0IGRlZmF1bHREaXNwYXRjaGVyIGZyb20gXCIuLi8uLi9kaXNwYXRjaGVyL2Rpc3BhdGNoZXJcIjtcbmltcG9ydCB7IFZpZXdSb29tUGF5bG9hZCB9IGZyb20gXCIuLi8uLi9kaXNwYXRjaGVyL3BheWxvYWRzL1ZpZXdSb29tUGF5bG9hZFwiO1xuaW1wb3J0IHsgQWN0aW9uIH0gZnJvbSBcIi4uLy4uL2Rpc3BhdGNoZXIvYWN0aW9uc1wiO1xuaW1wb3J0IHsgQ2FsbFN0b3JlLCBDYWxsU3RvcmVFdmVudCB9IGZyb20gXCIuLi8uLi9zdG9yZXMvQ2FsbFN0b3JlXCI7XG5pbXBvcnQgeyBpc1ZpZGVvUm9vbSB9IGZyb20gXCIuLi8uLi91dGlscy92aWRlby1yb29tc1wiO1xuaW1wb3J0IHsgdXNlR3Vlc3RBY2Nlc3NJbmZvcm1hdGlvbiB9IGZyb20gXCIuL3VzZUd1ZXN0QWNjZXNzSW5mb3JtYXRpb25cIjtcbmltcG9ydCBTZXR0aW5nc1N0b3JlIGZyb20gXCIuLi8uLi9zZXR0aW5ncy9TZXR0aW5nc1N0b3JlXCI7XG5pbXBvcnQgeyBVSUZlYXR1cmUgfSBmcm9tIFwiLi4vLi4vc2V0dGluZ3MvVUlGZWF0dXJlXCI7XG5cbmV4cG9ydCBlbnVtIFBsYXRmb3JtQ2FsbFR5cGUge1xuICAgIEVsZW1lbnRDYWxsLFxuICAgIEppdHNpQ2FsbCxcbiAgICBMZWdhY3lDYWxsLFxufVxuZXhwb3J0IGNvbnN0IGdldFBsYXRmb3JtQ2FsbFR5cGVMYWJlbCA9IChwbGF0Zm9ybUNhbGxUeXBlOiBQbGF0Zm9ybUNhbGxUeXBlKTogc3RyaW5nID0+IHtcbiAgICBzd2l0Y2ggKHBsYXRmb3JtQ2FsbFR5cGUpIHtcbiAgICAgICAgY2FzZSBQbGF0Zm9ybUNhbGxUeXBlLkVsZW1lbnRDYWxsOlxuICAgICAgICAgICAgcmV0dXJuIF90KFwidm9pcHxlbGVtZW50X2NhbGxcIik7XG4gICAgICAgIGNhc2UgUGxhdGZvcm1DYWxsVHlwZS5KaXRzaUNhbGw6XG4gICAgICAgICAgICByZXR1cm4gX3QoXCJ2b2lwfGppdHNpX2NhbGxcIik7XG4gICAgICAgIGNhc2UgUGxhdGZvcm1DYWxsVHlwZS5MZWdhY3lDYWxsOlxuICAgICAgICAgICAgcmV0dXJuIF90KFwidm9pcHxsZWdhY3lfY2FsbFwiKTtcbiAgICB9XG59O1xuY29uc3QgZW51bSBTdGF0ZSB7XG4gICAgTm9DYWxsLFxuICAgIE5vT25lSGVyZSxcbiAgICBOb1Blcm1pc3Npb24sXG4gICAgVW5waW5uZWQsXG4gICAgT25nb2luZyxcbiAgICBOb3RKb2luZWQsXG59XG5cbi8qKlxuICogVXRpbGl0eSBob29rIGZvciByZXNvbHZpbmcgc3RhdGUgYW5kIGNsaWNrIGhhbmRsZXJzIGZvciBWb2ljZSAmIFZpZGVvIGNhbGwgYnV0dG9ucyBpbiB0aGUgcm9vbSBoZWFkZXJcbiAqIEBwYXJhbSByb29tIHRoZSByb29tIHRvIHRyYWNrXG4gKiBAcmV0dXJucyB0aGUgY2FsbCBidXR0b24gYXR0cmlidXRlcyBmb3IgdGhlIGdpdmVuIHJvb21cbiAqL1xuZXhwb3J0IGNvbnN0IHVzZVJvb21DYWxsID0gKFxuICAgIHJvb206IFJvb20sXG4pOiB7XG4gICAgdm9pY2VDYWxsRGlzYWJsZWRSZWFzb246IHN0cmluZyB8IG51bGw7XG4gICAgdm9pY2VDYWxsQ2xpY2soZXZ0OiBSZWFjdC5Nb3VzZUV2ZW50IHwgdW5kZWZpbmVkLCBzZWxlY3RlZFR5cGU6IFBsYXRmb3JtQ2FsbFR5cGUpOiB2b2lkO1xuICAgIHZpZGVvQ2FsbERpc2FibGVkUmVhc29uOiBzdHJpbmcgfCBudWxsO1xuICAgIHZpZGVvQ2FsbENsaWNrKGV2dDogUmVhY3QuTW91c2VFdmVudCB8IHVuZGVmaW5lZCwgc2VsZWN0ZWRUeXBlOiBQbGF0Zm9ybUNhbGxUeXBlKTogdm9pZDtcbiAgICB0b2dnbGVDYWxsTWF4aW1pemVkOiAoKSA9PiB2b2lkO1xuICAgIGlzVmlld2luZ0NhbGw6IGJvb2xlYW47XG4gICAgaXNDb25uZWN0ZWRUb0NhbGw6IGJvb2xlYW47XG4gICAgaGFzQWN0aXZlQ2FsbFNlc3Npb246IGJvb2xlYW47XG4gICAgY2FsbE9wdGlvbnM6IFBsYXRmb3JtQ2FsbFR5cGVbXTtcbiAgICBzaG93VmlkZW9DYWxsQnV0dG9uOiBib29sZWFuO1xuICAgIHNob3dWb2ljZUNhbGxCdXR0b246IGJvb2xlYW47XG59ID0+IHtcbiAgICAvLyBzZXR0aW5nc1xuICAgIGNvbnN0IGdyb3VwQ2FsbHNFbmFibGVkID0gdXNlRmVhdHVyZUVuYWJsZWQoXCJmZWF0dXJlX2dyb3VwX2NhbGxzXCIpO1xuICAgIGNvbnN0IHVzZUVsZW1lbnRDYWxsRXhjbHVzaXZlbHkgPSB1c2VNZW1vKCgpID0+IHtcbiAgICAgICAgcmV0dXJuIFNka0NvbmZpZy5nZXQoXCJlbGVtZW50X2NhbGxcIikudXNlX2V4Y2x1c2l2ZWx5O1xuICAgIH0sIFtdKTtcblxuICAgIGNvbnN0IGhhc0xlZ2FjeUNhbGwgPSB1c2VFdmVudEVtaXR0ZXJTdGF0ZShcbiAgICAgICAgTGVnYWN5Q2FsbEhhbmRsZXIuaW5zdGFuY2UsXG4gICAgICAgIExlZ2FjeUNhbGxIYW5kbGVyRXZlbnQuQ2FsbHNDaGFuZ2VkLFxuICAgICAgICAoKSA9PiBMZWdhY3lDYWxsSGFuZGxlci5pbnN0YW5jZS5nZXRDYWxsRm9yUm9vbShyb29tLnJvb21JZCkgIT09IG51bGwsXG4gICAgKTtcbiAgICAvLyBzZXR0aW5nc1xuICAgIGNvbnN0IHdpZGdldHMgPSB1c2VXaWRnZXRzKHJvb20pO1xuICAgIGNvbnN0IGppdHNpV2lkZ2V0ID0gdXNlTWVtbygoKSA9PiB3aWRnZXRzLmZpbmQoKHdpZGdldCkgPT4gV2lkZ2V0VHlwZS5KSVRTSS5tYXRjaGVzKHdpZGdldC50eXBlKSksIFt3aWRnZXRzXSk7XG4gICAgY29uc3QgaGFzSml0c2lXaWRnZXQgPSAhIWppdHNpV2lkZ2V0O1xuICAgIGNvbnN0IG1hbmFnZWRIeWJyaWRXaWRnZXQgPSB1c2VNZW1vKCgpID0+IHdpZGdldHMuZmluZChpc01hbmFnZWRIeWJyaWRXaWRnZXQpLCBbd2lkZ2V0c10pO1xuICAgIGNvbnN0IGhhc01hbmFnZWRIeWJyaWRXaWRnZXQgPSAhIW1hbmFnZWRIeWJyaWRXaWRnZXQ7XG5cbiAgICAvLyBncm91cCBjYWxsXG4gICAgY29uc3QgZ3JvdXBDYWxsID0gdXNlQ2FsbChyb29tLnJvb21JZCk7XG4gICAgY29uc3QgaXNDb25uZWN0ZWRUb0NhbGwgPSB1c2VDb25uZWN0aW9uU3RhdGUoZ3JvdXBDYWxsKSA9PT0gQ29ubmVjdGlvblN0YXRlLkNvbm5lY3RlZDtcbiAgICBjb25zdCBoYXNHcm91cENhbGwgPSBncm91cENhbGwgIT09IG51bGw7XG4gICAgY29uc3QgaGFzQWN0aXZlQ2FsbFNlc3Npb24gPSB1c2VQYXJ0aWNpcGFudENvdW50KGdyb3VwQ2FsbCkgPiAwO1xuICAgIGNvbnN0IGlzVmlld2luZ0NhbGwgPSB1c2VFdmVudEVtaXR0ZXJTdGF0ZShcbiAgICAgICAgU2RrQ29udGV4dENsYXNzLmluc3RhbmNlLnJvb21WaWV3U3RvcmUsXG4gICAgICAgIFVQREFURV9FVkVOVCxcbiAgICAgICAgKCkgPT4gU2RrQ29udGV4dENsYXNzLmluc3RhbmNlLnJvb21WaWV3U3RvcmUuaXNWaWV3aW5nQ2FsbCgpIHx8IGlzVmlkZW9Sb29tKHJvb20pLFxuICAgICk7XG5cbiAgICAvLyByb29tXG4gICAgY29uc3QgbWVtYmVyQ291bnQgPSB1c2VSb29tTWVtYmVyQ291bnQocm9vbSk7XG5cbiAgICBjb25zdCBbbWF5RWRpdFdpZGdldHMsIG1heUNyZWF0ZUVsZW1lbnRDYWxsc10gPSB1c2VSb29tU3RhdGUocm9vbSwgKCkgPT4gW1xuICAgICAgICByb29tLmN1cnJlbnRTdGF0ZS5tYXlDbGllbnRTZW5kU3RhdGVFdmVudChcImltLnZlY3Rvci5tb2R1bGFyLndpZGdldHNcIiwgcm9vbS5jbGllbnQpLFxuICAgICAgICByb29tLmN1cnJlbnRTdGF0ZS5tYXlDbGllbnRTZW5kU3RhdGVFdmVudChFbGVtZW50Q2FsbC5NRU1CRVJfRVZFTlRfVFlQRS5uYW1lLCByb29tLmNsaWVudCksXG4gICAgXSk7XG5cbiAgICAvLyBUaGUgb3B0aW9ucyBwcm92aWRlZCB0byB0aGUgUm9vbUhlYWRlci5cbiAgICAvLyBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgb3B0aW9ucywgdGhlIHVzZXIgd2lsbCBiZSBwcm9tcHRlZCB0byBjaG9vc2UuXG4gICAgY29uc3QgY2FsbE9wdGlvbnMgPSB1c2VNZW1vKCgpOiBQbGF0Zm9ybUNhbGxUeXBlW10gPT4ge1xuICAgICAgICBjb25zdCBvcHRpb25zOiBQbGF0Zm9ybUNhbGxUeXBlW10gPSBbXTtcbiAgICAgICAgaWYgKG1lbWJlckNvdW50IDw9IDIpIHtcbiAgICAgICAgICAgIG9wdGlvbnMucHVzaChQbGF0Zm9ybUNhbGxUeXBlLkxlZ2FjeUNhbGwpO1xuICAgICAgICB9IGVsc2UgaWYgKG1heUVkaXRXaWRnZXRzIHx8IGhhc0ppdHNpV2lkZ2V0KSB7XG4gICAgICAgICAgICBvcHRpb25zLnB1c2goUGxhdGZvcm1DYWxsVHlwZS5KaXRzaUNhbGwpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChncm91cENhbGxzRW5hYmxlZCkge1xuICAgICAgICAgICAgaWYgKGhhc0dyb3VwQ2FsbCB8fCBtYXlDcmVhdGVFbGVtZW50Q2FsbHMpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLnB1c2goUGxhdGZvcm1DYWxsVHlwZS5FbGVtZW50Q2FsbCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodXNlRWxlbWVudENhbGxFeGNsdXNpdmVseSAmJiAhaGFzSml0c2lXaWRnZXQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gW1BsYXRmb3JtQ2FsbFR5cGUuRWxlbWVudENhbGxdO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNHcm91cENhbGwgJiYgV2lkZ2V0VHlwZS5DQUxMLm1hdGNoZXMoZ3JvdXBDYWxsLndpZGdldC50eXBlKSkge1xuICAgICAgICAgICAgLy8gb25seSBhbGxvdyBqb2luaW5nIHRoZSBvbmdvaW5nIEVsZW1lbnQgY2FsbCBpZiB0aGVyZSBpcyBvbmUuXG4gICAgICAgICAgICByZXR1cm4gW1BsYXRmb3JtQ2FsbFR5cGUuRWxlbWVudENhbGxdO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvcHRpb25zO1xuICAgIH0sIFtcbiAgICAgICAgbWVtYmVyQ291bnQsXG4gICAgICAgIG1heUVkaXRXaWRnZXRzLFxuICAgICAgICBoYXNKaXRzaVdpZGdldCxcbiAgICAgICAgZ3JvdXBDYWxsc0VuYWJsZWQsXG4gICAgICAgIGhhc0dyb3VwQ2FsbCxcbiAgICAgICAgbWF5Q3JlYXRlRWxlbWVudENhbGxzLFxuICAgICAgICB1c2VFbGVtZW50Q2FsbEV4Y2x1c2l2ZWx5LFxuICAgICAgICBncm91cENhbGw/LndpZGdldC50eXBlLFxuICAgIF0pO1xuXG4gICAgbGV0IHdpZGdldDogSUFwcCB8IHVuZGVmaW5lZDtcbiAgICBpZiAoY2FsbE9wdGlvbnMuaW5jbHVkZXMoUGxhdGZvcm1DYWxsVHlwZS5KaXRzaUNhbGwpIHx8IGNhbGxPcHRpb25zLmluY2x1ZGVzKFBsYXRmb3JtQ2FsbFR5cGUuTGVnYWN5Q2FsbCkpIHtcbiAgICAgICAgd2lkZ2V0ID0gaml0c2lXaWRnZXQgPz8gbWFuYWdlZEh5YnJpZFdpZGdldDtcbiAgICB9XG4gICAgaWYgKGNhbGxPcHRpb25zLmluY2x1ZGVzKFBsYXRmb3JtQ2FsbFR5cGUuRWxlbWVudENhbGwpKSB7XG4gICAgICAgIHdpZGdldCA9IGdyb3VwQ2FsbD8ud2lkZ2V0O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHdpZGdldCA9IGdyb3VwQ2FsbD8ud2lkZ2V0ID8/IGppdHNpV2lkZ2V0O1xuICAgIH1cbiAgICBjb25zdCB1cGRhdGVXaWRnZXRTdGF0ZSA9IHVzZUNhbGxiYWNrKCgpOiB2b2lkID0+IHtcbiAgICAgICAgc2V0Q2FuUGluV2lkZ2V0KFdpZGdldExheW91dFN0b3JlLmluc3RhbmNlLmNhbkFkZFRvQ29udGFpbmVyKHJvb20sIENvbnRhaW5lci5Ub3ApKTtcbiAgICAgICAgc2V0V2lkZ2V0UGlubmVkKCEhd2lkZ2V0ICYmIFdpZGdldExheW91dFN0b3JlLmluc3RhbmNlLmlzSW5Db250YWluZXIocm9vbSwgd2lkZ2V0LCBDb250YWluZXIuVG9wKSk7XG4gICAgfSwgW3Jvb20sIHdpZGdldF0pO1xuICAgIHVzZUV2ZW50RW1pdHRlcihXaWRnZXRMYXlvdXRTdG9yZS5pbnN0YW5jZSwgV2lkZ2V0TGF5b3V0U3RvcmUuZW1pc3Npb25Gb3JSb29tKHJvb20pLCB1cGRhdGVXaWRnZXRTdGF0ZSk7XG4gICAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgdXBkYXRlV2lkZ2V0U3RhdGUoKTtcbiAgICB9LCBbcm9vbSwgaml0c2lXaWRnZXQsIGdyb3VwQ2FsbCwgdXBkYXRlV2lkZ2V0U3RhdGVdKTtcbiAgICBjb25zdCBbY2FuUGluV2lkZ2V0LCBzZXRDYW5QaW5XaWRnZXRdID0gdXNlU3RhdGUoZmFsc2UpO1xuICAgIGNvbnN0IFt3aWRnZXRQaW5uZWQsIHNldFdpZGdldFBpbm5lZF0gPSB1c2VTdGF0ZShmYWxzZSk7XG4gICAgLy8gV2Ugb25seSB3YW50IHRvIHByb21wdCB0byBwaW4gdGhlIHdpZGdldCBpZiBpdCdzIG5vdCBlbGVtZW50IGNhbGwgYmFzZWQuXG4gICAgY29uc3QgaXNFQ1dpZGdldCA9IFdpZGdldFR5cGUuQ0FMTC5tYXRjaGVzKHdpZGdldD8udHlwZSA/PyBcIlwiKTtcbiAgICBjb25zdCBwcm9tcHRQaW5XaWRnZXQgPSAhaXNFQ1dpZGdldCAmJiBjYW5QaW5XaWRnZXQgJiYgIXdpZGdldFBpbm5lZDtcbiAgICBjb25zdCBjb25uZWN0ZWRDYWxscyA9IHVzZUV2ZW50RW1pdHRlclN0YXRlKENhbGxTdG9yZS5pbnN0YW5jZSwgQ2FsbFN0b3JlRXZlbnQuQ29ubmVjdGVkQ2FsbHMsICgpID0+XG4gICAgICAgIEFycmF5LmZyb20oQ2FsbFN0b3JlLmluc3RhbmNlLmNvbm5lY3RlZENhbGxzKSxcbiAgICApO1xuICAgIGNvbnN0IHsgY2FuSW52aXRlR3Vlc3RzIH0gPSB1c2VHdWVzdEFjY2Vzc0luZm9ybWF0aW9uKHJvb20pO1xuXG4gICAgY29uc3Qgc3RhdGUgPSB1c2VNZW1vKCgpOiBTdGF0ZSA9PiB7XG4gICAgICAgIGlmIChjb25uZWN0ZWRDYWxscy5maW5kKChjYWxsKSA9PiBjYWxsLnJvb21JZCAhPSByb29tLnJvb21JZCkpIHtcbiAgICAgICAgICAgIHJldHVybiBTdGF0ZS5PbmdvaW5nO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNHcm91cENhbGwgJiYgKGhhc0ppdHNpV2lkZ2V0IHx8IGhhc01hbmFnZWRIeWJyaWRXaWRnZXQpKSB7XG4gICAgICAgICAgICByZXR1cm4gcHJvbXB0UGluV2lkZ2V0ID8gU3RhdGUuVW5waW5uZWQgOiBTdGF0ZS5PbmdvaW5nO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNMZWdhY3lDYWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gU3RhdGUuT25nb2luZztcbiAgICAgICAgfVxuICAgICAgICBpZiAobWVtYmVyQ291bnQgPD0gMSAmJiAhY2FuSW52aXRlR3Vlc3RzKSB7XG4gICAgICAgICAgICByZXR1cm4gU3RhdGUuTm9PbmVIZXJlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFtYXlDcmVhdGVFbGVtZW50Q2FsbHMgJiYgIW1heUVkaXRXaWRnZXRzKSB7XG4gICAgICAgICAgICByZXR1cm4gU3RhdGUuTm9QZXJtaXNzaW9uO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBTdGF0ZS5Ob0NhbGw7XG4gICAgfSwgW1xuICAgICAgICBjb25uZWN0ZWRDYWxscyxcbiAgICAgICAgY2FuSW52aXRlR3Vlc3RzLFxuICAgICAgICBoYXNHcm91cENhbGwsXG4gICAgICAgIGhhc0ppdHNpV2lkZ2V0LFxuICAgICAgICBoYXNMZWdhY3lDYWxsLFxuICAgICAgICBoYXNNYW5hZ2VkSHlicmlkV2lkZ2V0LFxuICAgICAgICBtYXlDcmVhdGVFbGVtZW50Q2FsbHMsXG4gICAgICAgIG1heUVkaXRXaWRnZXRzLFxuICAgICAgICBtZW1iZXJDb3VudCxcbiAgICAgICAgcHJvbXB0UGluV2lkZ2V0LFxuICAgICAgICByb29tLnJvb21JZCxcbiAgICBdKTtcblxuICAgIGNvbnN0IHZvaWNlQ2FsbENsaWNrID0gdXNlQ2FsbGJhY2soXG4gICAgICAgIChldnQ6IFJlYWN0Lk1vdXNlRXZlbnQgfCB1bmRlZmluZWQsIGNhbGxQbGF0Zm9ybVR5cGU6IFBsYXRmb3JtQ2FsbFR5cGUpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGV2dD8uc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICBpZiAod2lkZ2V0ICYmIHByb21wdFBpbldpZGdldCkge1xuICAgICAgICAgICAgICAgIFdpZGdldExheW91dFN0b3JlLmluc3RhbmNlLm1vdmVUb0NvbnRhaW5lcihyb29tLCB3aWRnZXQsIENvbnRhaW5lci5Ub3ApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwbGFjZUNhbGwocm9vbSwgQ2FsbFR5cGUuVm9pY2UsIGNhbGxQbGF0Zm9ybVR5cGUsIGV2dD8uc2hpZnRLZXkgPz8gZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBbcHJvbXB0UGluV2lkZ2V0LCByb29tLCB3aWRnZXRdLFxuICAgICk7XG4gICAgY29uc3QgdmlkZW9DYWxsQ2xpY2sgPSB1c2VDYWxsYmFjayhcbiAgICAgICAgKGV2dDogUmVhY3QuTW91c2VFdmVudCB8IHVuZGVmaW5lZCwgY2FsbFBsYXRmb3JtVHlwZTogUGxhdGZvcm1DYWxsVHlwZSk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgZXZ0Py5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIGlmICh3aWRnZXQgJiYgcHJvbXB0UGluV2lkZ2V0KSB7XG4gICAgICAgICAgICAgICAgV2lkZ2V0TGF5b3V0U3RvcmUuaW5zdGFuY2UubW92ZVRvQ29udGFpbmVyKHJvb20sIHdpZGdldCwgQ29udGFpbmVyLlRvcCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBsYWNlQ2FsbChyb29tLCBDYWxsVHlwZS5WaWRlbywgY2FsbFBsYXRmb3JtVHlwZSwgZXZ0Py5zaGlmdEtleSA/PyBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sXG4gICAgICAgIFt3aWRnZXQsIHByb21wdFBpbldpZGdldCwgcm9vbV0sXG4gICAgKTtcblxuICAgIGxldCB2b2ljZUNhbGxEaXNhYmxlZFJlYXNvbjogc3RyaW5nIHwgbnVsbDtcbiAgICBsZXQgdmlkZW9DYWxsRGlzYWJsZWRSZWFzb246IHN0cmluZyB8IG51bGw7XG4gICAgc3dpdGNoIChzdGF0ZSkge1xuICAgICAgICBjYXNlIFN0YXRlLk5vUGVybWlzc2lvbjpcbiAgICAgICAgICAgIHZvaWNlQ2FsbERpc2FibGVkUmVhc29uID0gX3QoXCJ2b2lwfGRpc2FibGVkX25vX3Blcm1zX3N0YXJ0X3ZvaWNlX2NhbGxcIik7XG4gICAgICAgICAgICB2aWRlb0NhbGxEaXNhYmxlZFJlYXNvbiA9IF90KFwidm9pcHxkaXNhYmxlZF9ub19wZXJtc19zdGFydF92aWRlb19jYWxsXCIpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgU3RhdGUuT25nb2luZzpcbiAgICAgICAgICAgIHZvaWNlQ2FsbERpc2FibGVkUmVhc29uID0gX3QoXCJ2b2lwfGRpc2FibGVkX29uZ29pbmdfY2FsbFwiKTtcbiAgICAgICAgICAgIHZpZGVvQ2FsbERpc2FibGVkUmVhc29uID0gX3QoXCJ2b2lwfGRpc2FibGVkX29uZ29pbmdfY2FsbFwiKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFN0YXRlLk5vT25lSGVyZTpcbiAgICAgICAgICAgIHZvaWNlQ2FsbERpc2FibGVkUmVhc29uID0gX3QoXCJ2b2lwfGRpc2FibGVkX25vX29uZV9oZXJlXCIpO1xuICAgICAgICAgICAgdmlkZW9DYWxsRGlzYWJsZWRSZWFzb24gPSBfdChcInZvaXB8ZGlzYWJsZWRfbm9fb25lX2hlcmVcIik7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBTdGF0ZS5VbnBpbm5lZDpcbiAgICAgICAgY2FzZSBTdGF0ZS5Ob3RKb2luZWQ6XG4gICAgICAgIGNhc2UgU3RhdGUuTm9DYWxsOlxuICAgICAgICAgICAgdm9pY2VDYWxsRGlzYWJsZWRSZWFzb24gPSBudWxsO1xuICAgICAgICAgICAgdmlkZW9DYWxsRGlzYWJsZWRSZWFzb24gPSBudWxsO1xuICAgIH1cbiAgICBjb25zdCB0b2dnbGVDYWxsTWF4aW1pemVkID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgICAgICBkZWZhdWx0RGlzcGF0Y2hlci5kaXNwYXRjaDxWaWV3Um9vbVBheWxvYWQ+KHtcbiAgICAgICAgICAgIGFjdGlvbjogQWN0aW9uLlZpZXdSb29tLFxuICAgICAgICAgICAgcm9vbV9pZDogcm9vbS5yb29tSWQsXG4gICAgICAgICAgICBtZXRyaWNzVHJpZ2dlcjogdW5kZWZpbmVkLFxuICAgICAgICAgICAgdmlld19jYWxsOiAhaXNWaWV3aW5nQ2FsbCxcbiAgICAgICAgfSk7XG4gICAgfSwgW2lzVmlld2luZ0NhbGwsIHJvb20ucm9vbUlkXSk7XG5cbiAgICAvLyBXZSBoaWRlIHRoZSB2b2ljZSBjYWxsIGJ1dHRvbiBpZiBpdCdkIGhhdmUgdGhlIHNhbWUgZWZmZWN0IGFzIHRoZSB2aWRlbyBjYWxsIGJ1dHRvblxuICAgIGxldCBoaWRlVm9pY2VDYWxsQnV0dG9uID0gaXNNYW5hZ2VkSHlicmlkV2lkZ2V0RW5hYmxlZChyb29tKSB8fCAhY2FsbE9wdGlvbnMuaW5jbHVkZXMoUGxhdGZvcm1DYWxsVHlwZS5MZWdhY3lDYWxsKTtcbiAgICBsZXQgaGlkZVZpZGVvQ2FsbEJ1dHRvbiA9IGZhbHNlO1xuICAgIC8vIFdlIGhpZGUgYm90aCBidXR0b25zIGlmIHRoZXkgcmVxdWlyZSB3aWRnZXRzIGJ1dCB3aWRnZXRzIGFyZSBkaXNhYmxlZC5cbiAgICBpZiAobWVtYmVyQ291bnQgPiAyICYmICFTZXR0aW5nc1N0b3JlLmdldFZhbHVlKFVJRmVhdHVyZS5XaWRnZXRzKSkge1xuICAgICAgICBoaWRlVm9pY2VDYWxsQnV0dG9uID0gdHJ1ZTtcbiAgICAgICAgaGlkZVZpZGVvQ2FsbEJ1dHRvbiA9IHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogV2UndmUgZ29uZSB0aHJvdWdoIGFsbCB0aGUgc3RlcHNcbiAgICAgKi9cbiAgICByZXR1cm4ge1xuICAgICAgICB2b2ljZUNhbGxEaXNhYmxlZFJlYXNvbixcbiAgICAgICAgdm9pY2VDYWxsQ2xpY2ssXG4gICAgICAgIHZpZGVvQ2FsbERpc2FibGVkUmVhc29uLFxuICAgICAgICB2aWRlb0NhbGxDbGljayxcbiAgICAgICAgdG9nZ2xlQ2FsbE1heGltaXplZDogdG9nZ2xlQ2FsbE1heGltaXplZCxcbiAgICAgICAgaXNWaWV3aW5nQ2FsbDogaXNWaWV3aW5nQ2FsbCxcbiAgICAgICAgaXNDb25uZWN0ZWRUb0NhbGw6IGlzQ29ubmVjdGVkVG9DYWxsLFxuICAgICAgICBoYXNBY3RpdmVDYWxsU2Vzc2lvbjogaGFzQWN0aXZlQ2FsbFNlc3Npb24sXG4gICAgICAgIGNhbGxPcHRpb25zLFxuICAgICAgICBzaG93Vm9pY2VDYWxsQnV0dG9uOiAhaGlkZVZvaWNlQ2FsbEJ1dHRvbixcbiAgICAgICAgc2hvd1ZpZGVvQ2FsbEJ1dHRvbjogIWhpZGVWaWRlb0NhbGxCdXR0b24sXG4gICAgfTtcbn07XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFTQSxJQUFBQSxNQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxLQUFBLEdBQUFELE9BQUE7QUFFQSxJQUFBRSxZQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxVQUFBLEdBQUFDLHNCQUFBLENBQUFKLE9BQUE7QUFDQSxJQUFBSyxnQkFBQSxHQUFBTCxPQUFBO0FBQ0EsSUFBQU0sa0JBQUEsR0FBQUMsdUJBQUEsQ0FBQVAsT0FBQTtBQUNBLElBQUFRLFlBQUEsR0FBQVIsT0FBQTtBQUNBLElBQUFTLFdBQUEsR0FBQVQsT0FBQTtBQUNBLElBQUFVLFFBQUEsR0FBQVYsT0FBQTtBQUNBLElBQUFXLGVBQUEsR0FBQVgsT0FBQTtBQUNBLElBQUFZLEtBQUEsR0FBQVosT0FBQTtBQUNBLElBQUFhLFVBQUEsR0FBQWIsT0FBQTtBQUNBLElBQUFjLGtCQUFBLEdBQUFkLE9BQUE7QUFDQSxJQUFBZSxhQUFBLEdBQUFmLE9BQUE7QUFDQSxJQUFBZ0IsZ0JBQUEsR0FBQWhCLE9BQUE7QUFDQSxJQUFBaUIsY0FBQSxHQUFBakIsT0FBQTtBQUVBLElBQUFrQixXQUFBLEdBQUFsQixPQUFBO0FBQ0EsSUFBQW1CLFdBQUEsR0FBQW5CLE9BQUE7QUFDQSxJQUFBb0IsV0FB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