matrix-react-sdk
Version:
SDK for matrix.org using React
238 lines (235 loc) • 47 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireWildcard(require("react"));
var _call = require("matrix-js-sdk/src/webrtc/call");
var _classnames = _interopRequireDefault(require("classnames"));
var _languageHandler = require("../../../languageHandler");
var _MemberAvatar = _interopRequireDefault(require("../avatars/MemberAvatar"));
var _LegacyCallEventGrouper = require("../../structures/LegacyCallEventGrouper");
var _AccessibleButton = _interopRequireDefault(require("../elements/AccessibleButton"));
var _InfoTooltip = _interopRequireWildcard(require("../elements/InfoTooltip"));
var _DateUtils = require("../../../DateUtils");
var _Clock = _interopRequireDefault(require("../audio_messages/Clock"));
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 2021 Šimon Brandner <simon.bra.ag@gmail.com>
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
const MAX_NON_NARROW_WIDTH = 450 / 70 * 100;
class LegacyCallEvent extends _react.default.PureComponent {
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "wrapperElement", /*#__PURE__*/(0, _react.createRef)());
(0, _defineProperty2.default)(this, "resizeObserver", void 0);
(0, _defineProperty2.default)(this, "onLengthChanged", length => {
this.setState({
length
});
});
(0, _defineProperty2.default)(this, "resizeObserverCallback", entries => {
const wrapperElementEntry = entries.find(entry => entry.target === this.wrapperElement.current);
if (!wrapperElementEntry) return;
this.setState({
narrow: wrapperElementEntry.contentRect.width < MAX_NON_NARROW_WIDTH
});
});
(0, _defineProperty2.default)(this, "onSilencedChanged", newState => {
this.setState({
silenced: newState
});
});
(0, _defineProperty2.default)(this, "onStateChanged", newState => {
this.setState({
callState: newState
});
});
this.state = {
callState: this.props.callEventGrouper.state,
silenced: false,
narrow: false,
length: 0
};
}
componentDidMount() {
this.props.callEventGrouper.addListener(_LegacyCallEventGrouper.LegacyCallEventGrouperEvent.StateChanged, this.onStateChanged);
this.props.callEventGrouper.addListener(_LegacyCallEventGrouper.LegacyCallEventGrouperEvent.SilencedChanged, this.onSilencedChanged);
this.props.callEventGrouper.addListener(_LegacyCallEventGrouper.LegacyCallEventGrouperEvent.LengthChanged, this.onLengthChanged);
this.resizeObserver = new ResizeObserver(this.resizeObserverCallback);
this.wrapperElement.current && this.resizeObserver.observe(this.wrapperElement.current);
}
componentWillUnmount() {
this.props.callEventGrouper.removeListener(_LegacyCallEventGrouper.LegacyCallEventGrouperEvent.StateChanged, this.onStateChanged);
this.props.callEventGrouper.removeListener(_LegacyCallEventGrouper.LegacyCallEventGrouperEvent.SilencedChanged, this.onSilencedChanged);
this.props.callEventGrouper.removeListener(_LegacyCallEventGrouper.LegacyCallEventGrouperEvent.LengthChanged, this.onLengthChanged);
this.resizeObserver?.disconnect();
}
renderCallBackButton(text) {
return /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
className: "mx_LegacyCallEvent_content_button mx_LegacyCallEvent_content_button_callBack",
onClick: this.props.callEventGrouper.callBack,
kind: "primary"
}, /*#__PURE__*/_react.default.createElement("span", null, " ", text, " "));
}
renderSilenceIcon() {
const silenceClass = (0, _classnames.default)({
mx_LegacyCallEvent_iconButton: true,
mx_LegacyCallEvent_unSilence: this.state.silenced,
mx_LegacyCallEvent_silence: !this.state.silenced
});
return /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
className: silenceClass,
onClick: this.props.callEventGrouper.toggleSilenced,
title: this.state.silenced ? (0, _languageHandler._t)("voip|unsilence") : (0, _languageHandler._t)("voip|silence")
});
}
renderContent() {
if (this.state.callState === _call.CallState.Ringing) {
let silenceIcon;
if (!this.state.narrow) {
silenceIcon = this.renderSilenceIcon();
}
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_content"
}, silenceIcon, /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
className: "mx_LegacyCallEvent_content_button mx_LegacyCallEvent_content_button_reject",
onClick: this.props.callEventGrouper.rejectCall,
kind: "danger"
}, /*#__PURE__*/_react.default.createElement("span", null, " ", (0, _languageHandler._t)("action|decline"), " ")), /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
className: "mx_LegacyCallEvent_content_button mx_LegacyCallEvent_content_button_answer",
onClick: this.props.callEventGrouper.answerCall,
kind: "primary"
}, /*#__PURE__*/_react.default.createElement("span", null, " ", (0, _languageHandler._t)("action|accept"), " ")), this.props.timestamp);
}
if (this.state.callState === _call.CallState.Ended) {
const hangupReason = this.props.callEventGrouper.hangupReason;
const gotRejected = this.props.callEventGrouper.gotRejected;
if (gotRejected) {
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_content"
}, (0, _languageHandler._t)("timeline|m.call.invite|declined"), this.renderCallBackButton((0, _languageHandler._t)("timeline|m.call.invite|call_back_prompt")), this.props.timestamp);
} else if (hangupReason === _call.CallErrorCode.AnsweredElsewhere) {
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_content"
}, (0, _languageHandler._t)("timeline|m.call.invite|answered_elsewhere"), this.props.timestamp);
} else if (this.props.callEventGrouper.callWasMissed) {
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_content"
}, (0, _languageHandler._t)("timeline|m.call.invite|missed_call"), this.renderCallBackButton((0, _languageHandler._t)("timeline|m.call.invite|call_back_prompt")), this.props.timestamp);
} else if (!hangupReason || [_call.CallErrorCode.UserHangup, "user hangup"].includes(hangupReason)) {
// workaround for https://github.com/vector-im/element-web/issues/5178
// it seems Android randomly sets a reason of "user hangup" which is
// interpreted as an error code :(
// https://github.com/vector-im/riot-android/issues/2623
// Also the correct hangup code as of VoIP v1 (with underscore)
// Also, if we don't have a reason
const duration = this.props.callEventGrouper.duration;
let text = (0, _languageHandler._t)("timeline|m.call.hangup|dm");
if (duration) {
text += " • " + (0, _DateUtils.formatPreciseDuration)(duration);
}
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_content"
}, text, this.props.timestamp);
} else if (hangupReason === _call.CallErrorCode.InviteTimeout) {
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_content"
}, (0, _languageHandler._t)("timeline|m.call.invite|no_answer"), this.renderCallBackButton((0, _languageHandler._t)("timeline|m.call.invite|call_back_prompt")), this.props.timestamp);
}
let reason;
if (hangupReason === _call.CallErrorCode.IceFailed) {
// We couldn't establish a connection at all
reason = (0, _languageHandler._t)("timeline|m.call.invite|failed_connect_media");
} else if (hangupReason === "ice_timeout") {
// We established a connection but it died
reason = (0, _languageHandler._t)("timeline|m.call.invite|failed_connection");
} else if (hangupReason === _call.CallErrorCode.NoUserMedia) {
// The other side couldn't open capture devices
reason = (0, _languageHandler._t)("timeline|m.call.invite|failed_opponent_media");
} else if (hangupReason === "unknown_error") {
// An error code the other side doesn't have a way to express
// (as opposed to an error code they gave but we don't know about,
// in which case we show the error code)
reason = (0, _languageHandler._t)("timeline|m.call.invite|unknown_error");
} else if (hangupReason === _call.CallErrorCode.UserBusy) {
reason = (0, _languageHandler._t)("voip|user_busy_description");
} else {
reason = (0, _languageHandler._t)("timeline|m.call.invite|unknown_failure", {
reason: hangupReason
});
}
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_content"
}, /*#__PURE__*/_react.default.createElement(_InfoTooltip.default, {
tooltip: reason,
className: "mx_LegacyCallEvent_content_tooltip",
kind: _InfoTooltip.InfoTooltipKind.Warning
}), (0, _languageHandler._t)("timeline|m.call.invite|failed_connection"), this.renderCallBackButton((0, _languageHandler._t)("action|retry")), this.props.timestamp);
}
if (this.state.callState === _call.CallState.Connected) {
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_content"
}, /*#__PURE__*/_react.default.createElement(_Clock.default, {
seconds: this.state.length,
"aria-live": "off"
}), this.props.timestamp);
}
if (this.state.callState === _call.CallState.Connecting) {
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_content"
}, (0, _languageHandler._t)("voip|connecting"), this.props.timestamp);
}
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_content"
}, (0, _languageHandler._t)("timeline|m.call.invite|unknown_state"), this.props.timestamp);
}
render() {
const event = this.props.mxEvent;
const sender = event.sender ? event.sender.name : event.getSender();
const isVoice = this.props.callEventGrouper.isVoice;
const callType = isVoice ? (0, _languageHandler._t)("voip|voice_call") : (0, _languageHandler._t)("voip|video_call");
const callState = this.state.callState;
const hangupReason = this.props.callEventGrouper.hangupReason;
const content = this.renderContent();
const className = (0, _classnames.default)("mx_LegacyCallEvent", {
mx_LegacyCallEvent_voice: isVoice,
mx_LegacyCallEvent_video: !isVoice,
mx_LegacyCallEvent_narrow: this.state.narrow,
mx_LegacyCallEvent_missed: this.props.callEventGrouper.callWasMissed,
mx_LegacyCallEvent_noAnswer: callState === _call.CallState.Ended && hangupReason === _call.CallErrorCode.InviteTimeout,
mx_LegacyCallEvent_rejected: callState === _call.CallState.Ended && this.props.callEventGrouper.gotRejected
});
let silenceIcon;
if (this.state.narrow && this.state.callState === _call.CallState.Ringing) {
silenceIcon = this.renderSilenceIcon();
}
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_wrapper",
ref: this.wrapperElement
}, /*#__PURE__*/_react.default.createElement("div", {
className: className
}, silenceIcon, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_info"
}, /*#__PURE__*/_react.default.createElement(_MemberAvatar.default, {
member: event.sender,
size: "32px"
}), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_info_basic"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_sender"
}, sender), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_type"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_LegacyCallEvent_type_icon"
}), callType))), content));
}
}
exports.default = LegacyCallEvent;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfY2FsbCIsIl9jbGFzc25hbWVzIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9sYW5ndWFnZUhhbmRsZXIiLCJfTWVtYmVyQXZhdGFyIiwiX0xlZ2FjeUNhbGxFdmVudEdyb3VwZXIiLCJfQWNjZXNzaWJsZUJ1dHRvbiIsIl9JbmZvVG9vbHRpcCIsIl9EYXRlVXRpbHMiLCJfQ2xvY2siLCJfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUiLCJlIiwiV2Vha01hcCIsInIiLCJ0IiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJoYXMiLCJnZXQiLCJuIiwiX19wcm90b19fIiwiYSIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwidSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImkiLCJzZXQiLCJNQVhfTk9OX05BUlJPV19XSURUSCIsIkxlZ2FjeUNhbGxFdmVudCIsIlJlYWN0IiwiUHVyZUNvbXBvbmVudCIsImNvbnN0cnVjdG9yIiwicHJvcHMiLCJfZGVmaW5lUHJvcGVydHkyIiwiY3JlYXRlUmVmIiwibGVuZ3RoIiwic2V0U3RhdGUiLCJlbnRyaWVzIiwid3JhcHBlckVsZW1lbnRFbnRyeSIsImZpbmQiLCJlbnRyeSIsInRhcmdldCIsIndyYXBwZXJFbGVtZW50IiwiY3VycmVudCIsIm5hcnJvdyIsImNvbnRlbnRSZWN0Iiwid2lkdGgiLCJuZXdTdGF0ZSIsInNpbGVuY2VkIiwiY2FsbFN0YXRlIiwic3RhdGUiLCJjYWxsRXZlbnRHcm91cGVyIiwiY29tcG9uZW50RGlkTW91bnQiLCJhZGRMaXN0ZW5lciIsIkxlZ2FjeUNhbGxFdmVudEdyb3VwZXJFdmVudCIsIlN0YXRlQ2hhbmdlZCIsIm9uU3RhdGVDaGFuZ2VkIiwiU2lsZW5jZWRDaGFuZ2VkIiwib25TaWxlbmNlZENoYW5nZWQiLCJMZW5ndGhDaGFuZ2VkIiwib25MZW5ndGhDaGFuZ2VkIiwicmVzaXplT2JzZXJ2ZXIiLCJSZXNpemVPYnNlcnZlciIsInJlc2l6ZU9ic2VydmVyQ2FsbGJhY2siLCJvYnNlcnZlIiwiY29tcG9uZW50V2lsbFVubW91bnQiLCJyZW1vdmVMaXN0ZW5lciIsImRpc2Nvbm5lY3QiLCJyZW5kZXJDYWxsQmFja0J1dHRvbiIsInRleHQiLCJjcmVhdGVFbGVtZW50IiwiY2xhc3NOYW1lIiwib25DbGljayIsImNhbGxCYWNrIiwia2luZCIsInJlbmRlclNpbGVuY2VJY29uIiwic2lsZW5jZUNsYXNzIiwiY2xhc3NOYW1lcyIsIm14X0xlZ2FjeUNhbGxFdmVudF9pY29uQnV0dG9uIiwibXhfTGVnYWN5Q2FsbEV2ZW50X3VuU2lsZW5jZSIsIm14X0xlZ2FjeUNhbGxFdmVudF9zaWxlbmNlIiwidG9nZ2xlU2lsZW5jZWQiLCJ0aXRsZSIsIl90IiwicmVuZGVyQ29udGVudCIsIkNhbGxTdGF0ZSIsIlJpbmdpbmciLCJzaWxlbmNlSWNvbiIsInJlamVjdENhbGwiLCJhbnN3ZXJDYWxsIiwidGltZXN0YW1wIiwiRW5kZWQiLCJoYW5ndXBSZWFzb24iLCJnb3RSZWplY3RlZCIsIkNhbGxFcnJvckNvZGUiLCJBbnN3ZXJlZEVsc2V3aGVyZSIsImNhbGxXYXNNaXNzZWQiLCJVc2VySGFuZ3VwIiwiaW5jbHVkZXMiLCJkdXJhdGlvbiIsImZvcm1hdFByZWNpc2VEdXJhdGlvbiIsIkludml0ZVRpbWVvdXQiLCJyZWFzb24iLCJJY2VGYWlsZWQiLCJOb1VzZXJNZWRpYSIsIlVzZXJCdXN5IiwidG9vbHRpcCIsIkluZm9Ub29sdGlwS2luZCIsIldhcm5pbmciLCJDb25uZWN0ZWQiLCJzZWNvbmRzIiwiQ29ubmVjdGluZyIsInJlbmRlciIsImV2ZW50IiwibXhFdmVudCIsInNlbmRlciIsIm5hbWUiLCJnZXRTZW5kZXIiLCJpc1ZvaWNlIiwiY2FsbFR5cGUiLCJjb250ZW50IiwibXhfTGVnYWN5Q2FsbEV2ZW50X3ZvaWNlIiwibXhfTGVnYWN5Q2FsbEV2ZW50X3ZpZGVvIiwibXhfTGVnYWN5Q2FsbEV2ZW50X25hcnJvdyIsIm14X0xlZ2FjeUNhbGxFdmVudF9taXNzZWQiLCJteF9MZWdhY3lDYWxsRXZlbnRfbm9BbnN3ZXIiLCJteF9MZWdhY3lDYWxsRXZlbnRfcmVqZWN0ZWQiLCJyZWYiLCJtZW1iZXIiLCJzaXplIiwiZXhwb3J0cyJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL21lc3NhZ2VzL0xlZ2FjeUNhbGxFdmVudC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjEgxaBpbW9uIEJyYW5kbmVyIDxzaW1vbi5icmEuYWdAZ21haWwuY29tPlxuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgUmVhY3QsIHsgY3JlYXRlUmVmIH0gZnJvbSBcInJlYWN0XCI7XG5pbXBvcnQgeyBNYXRyaXhFdmVudCB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9tYXRyaXhcIjtcbmltcG9ydCB7IENhbGxFcnJvckNvZGUsIENhbGxTdGF0ZSB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy93ZWJydGMvY2FsbFwiO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSBcImNsYXNzbmFtZXNcIjtcblxuaW1wb3J0IHsgX3QgfSBmcm9tIFwiLi4vLi4vLi4vbGFuZ3VhZ2VIYW5kbGVyXCI7XG5pbXBvcnQgTWVtYmVyQXZhdGFyIGZyb20gXCIuLi9hdmF0YXJzL01lbWJlckF2YXRhclwiO1xuaW1wb3J0IExlZ2FjeUNhbGxFdmVudEdyb3VwZXIsIHsgTGVnYWN5Q2FsbEV2ZW50R3JvdXBlckV2ZW50IH0gZnJvbSBcIi4uLy4uL3N0cnVjdHVyZXMvTGVnYWN5Q2FsbEV2ZW50R3JvdXBlclwiO1xuaW1wb3J0IEFjY2Vzc2libGVCdXR0b24gZnJvbSBcIi4uL2VsZW1lbnRzL0FjY2Vzc2libGVCdXR0b25cIjtcbmltcG9ydCBJbmZvVG9vbHRpcCwgeyBJbmZvVG9vbHRpcEtpbmQgfSBmcm9tIFwiLi4vZWxlbWVudHMvSW5mb1Rvb2x0aXBcIjtcbmltcG9ydCB7IGZvcm1hdFByZWNpc2VEdXJhdGlvbiB9IGZyb20gXCIuLi8uLi8uLi9EYXRlVXRpbHNcIjtcbmltcG9ydCBDbG9jayBmcm9tIFwiLi4vYXVkaW9fbWVzc2FnZXMvQ2xvY2tcIjtcblxuY29uc3QgTUFYX05PTl9OQVJST1dfV0lEVEggPSAoNDUwIC8gNzApICogMTAwO1xuXG5pbnRlcmZhY2UgSVByb3BzIHtcbiAgICBteEV2ZW50OiBNYXRyaXhFdmVudDtcbiAgICBjYWxsRXZlbnRHcm91cGVyOiBMZWdhY3lDYWxsRXZlbnRHcm91cGVyO1xuICAgIHRpbWVzdGFtcD86IEpTWC5FbGVtZW50O1xufVxuXG5pbnRlcmZhY2UgSVN0YXRlIHtcbiAgICBjYWxsU3RhdGU/OiBDYWxsU3RhdGU7XG4gICAgc2lsZW5jZWQ6IGJvb2xlYW47XG4gICAgbmFycm93OiBib29sZWFuO1xuICAgIGxlbmd0aDogbnVtYmVyO1xufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBMZWdhY3lDYWxsRXZlbnQgZXh0ZW5kcyBSZWFjdC5QdXJlQ29tcG9uZW50PElQcm9wcywgSVN0YXRlPiB7XG4gICAgcHJpdmF0ZSB3cmFwcGVyRWxlbWVudCA9IGNyZWF0ZVJlZjxIVE1MRGl2RWxlbWVudD4oKTtcbiAgICBwcml2YXRlIHJlc2l6ZU9ic2VydmVyPzogUmVzaXplT2JzZXJ2ZXI7XG5cbiAgICBwdWJsaWMgY29uc3RydWN0b3IocHJvcHM6IElQcm9wcykge1xuICAgICAgICBzdXBlcihwcm9wcyk7XG5cbiAgICAgICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgICAgICAgIGNhbGxTdGF0ZTogdGhpcy5wcm9wcy5jYWxsRXZlbnRHcm91cGVyLnN0YXRlLFxuICAgICAgICAgICAgc2lsZW5jZWQ6IGZhbHNlLFxuICAgICAgICAgICAgbmFycm93OiBmYWxzZSxcbiAgICAgICAgICAgIGxlbmd0aDogMCxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50RGlkTW91bnQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci5hZGRMaXN0ZW5lcihMZWdhY3lDYWxsRXZlbnRHcm91cGVyRXZlbnQuU3RhdGVDaGFuZ2VkLCB0aGlzLm9uU3RhdGVDaGFuZ2VkKTtcbiAgICAgICAgdGhpcy5wcm9wcy5jYWxsRXZlbnRHcm91cGVyLmFkZExpc3RlbmVyKExlZ2FjeUNhbGxFdmVudEdyb3VwZXJFdmVudC5TaWxlbmNlZENoYW5nZWQsIHRoaXMub25TaWxlbmNlZENoYW5nZWQpO1xuICAgICAgICB0aGlzLnByb3BzLmNhbGxFdmVudEdyb3VwZXIuYWRkTGlzdGVuZXIoTGVnYWN5Q2FsbEV2ZW50R3JvdXBlckV2ZW50Lkxlbmd0aENoYW5nZWQsIHRoaXMub25MZW5ndGhDaGFuZ2VkKTtcblxuICAgICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKHRoaXMucmVzaXplT2JzZXJ2ZXJDYWxsYmFjayk7XG4gICAgICAgIHRoaXMud3JhcHBlckVsZW1lbnQuY3VycmVudCAmJiB0aGlzLnJlc2l6ZU9ic2VydmVyLm9ic2VydmUodGhpcy53cmFwcGVyRWxlbWVudC5jdXJyZW50KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY29tcG9uZW50V2lsbFVubW91bnQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci5yZW1vdmVMaXN0ZW5lcihMZWdhY3lDYWxsRXZlbnRHcm91cGVyRXZlbnQuU3RhdGVDaGFuZ2VkLCB0aGlzLm9uU3RhdGVDaGFuZ2VkKTtcbiAgICAgICAgdGhpcy5wcm9wcy5jYWxsRXZlbnRHcm91cGVyLnJlbW92ZUxpc3RlbmVyKExlZ2FjeUNhbGxFdmVudEdyb3VwZXJFdmVudC5TaWxlbmNlZENoYW5nZWQsIHRoaXMub25TaWxlbmNlZENoYW5nZWQpO1xuICAgICAgICB0aGlzLnByb3BzLmNhbGxFdmVudEdyb3VwZXIucmVtb3ZlTGlzdGVuZXIoTGVnYWN5Q2FsbEV2ZW50R3JvdXBlckV2ZW50Lkxlbmd0aENoYW5nZWQsIHRoaXMub25MZW5ndGhDaGFuZ2VkKTtcblxuICAgICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvbkxlbmd0aENoYW5nZWQgPSAobGVuZ3RoOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGxlbmd0aCB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSByZXNpemVPYnNlcnZlckNhbGxiYWNrID0gKGVudHJpZXM6IFJlc2l6ZU9ic2VydmVyRW50cnlbXSk6IHZvaWQgPT4ge1xuICAgICAgICBjb25zdCB3cmFwcGVyRWxlbWVudEVudHJ5ID0gZW50cmllcy5maW5kKChlbnRyeSkgPT4gZW50cnkudGFyZ2V0ID09PSB0aGlzLndyYXBwZXJFbGVtZW50LmN1cnJlbnQpO1xuICAgICAgICBpZiAoIXdyYXBwZXJFbGVtZW50RW50cnkpIHJldHVybjtcblxuICAgICAgICB0aGlzLnNldFN0YXRlKHsgbmFycm93OiB3cmFwcGVyRWxlbWVudEVudHJ5LmNvbnRlbnRSZWN0LndpZHRoIDwgTUFYX05PTl9OQVJST1dfV0lEVEggfSk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgb25TaWxlbmNlZENoYW5nZWQgPSAobmV3U3RhdGU6IGJvb2xlYW4pOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IHNpbGVuY2VkOiBuZXdTdGF0ZSB9KTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblN0YXRlQ2hhbmdlZCA9IChuZXdTdGF0ZTogQ2FsbFN0YXRlKTogdm9pZCA9PiB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoeyBjYWxsU3RhdGU6IG5ld1N0YXRlIH0pO1xuICAgIH07XG5cbiAgICBwcml2YXRlIHJlbmRlckNhbGxCYWNrQnV0dG9uKHRleHQ6IHN0cmluZyk6IEpTWC5FbGVtZW50IHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxBY2Nlc3NpYmxlQnV0dG9uXG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X2NvbnRlbnRfYnV0dG9uIG14X0xlZ2FjeUNhbGxFdmVudF9jb250ZW50X2J1dHRvbl9jYWxsQmFja1wiXG4gICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5wcm9wcy5jYWxsRXZlbnRHcm91cGVyLmNhbGxCYWNrfVxuICAgICAgICAgICAgICAgIGtpbmQ9XCJwcmltYXJ5XCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8c3Bhbj4ge3RleHR9IDwvc3Bhbj5cbiAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj5cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHJlbmRlclNpbGVuY2VJY29uKCk6IEpTWC5FbGVtZW50IHtcbiAgICAgICAgY29uc3Qgc2lsZW5jZUNsYXNzID0gY2xhc3NOYW1lcyh7XG4gICAgICAgICAgICBteF9MZWdhY3lDYWxsRXZlbnRfaWNvbkJ1dHRvbjogdHJ1ZSxcbiAgICAgICAgICAgIG14X0xlZ2FjeUNhbGxFdmVudF91blNpbGVuY2U6IHRoaXMuc3RhdGUuc2lsZW5jZWQsXG4gICAgICAgICAgICBteF9MZWdhY3lDYWxsRXZlbnRfc2lsZW5jZTogIXRoaXMuc3RhdGUuc2lsZW5jZWQsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17c2lsZW5jZUNsYXNzfVxuICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci50b2dnbGVTaWxlbmNlZH1cbiAgICAgICAgICAgICAgICB0aXRsZT17dGhpcy5zdGF0ZS5zaWxlbmNlZCA/IF90KFwidm9pcHx1bnNpbGVuY2VcIikgOiBfdChcInZvaXB8c2lsZW5jZVwiKX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZW5kZXJDb250ZW50KCk6IEpTWC5FbGVtZW50IHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuY2FsbFN0YXRlID09PSBDYWxsU3RhdGUuUmluZ2luZykge1xuICAgICAgICAgICAgbGV0IHNpbGVuY2VJY29uO1xuICAgICAgICAgICAgaWYgKCF0aGlzLnN0YXRlLm5hcnJvdykge1xuICAgICAgICAgICAgICAgIHNpbGVuY2VJY29uID0gdGhpcy5yZW5kZXJTaWxlbmNlSWNvbigpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X2NvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAge3NpbGVuY2VJY29ufVxuICAgICAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X2NvbnRlbnRfYnV0dG9uIG14X0xlZ2FjeUNhbGxFdmVudF9jb250ZW50X2J1dHRvbl9yZWplY3RcIlxuICAgICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17dGhpcy5wcm9wcy5jYWxsRXZlbnRHcm91cGVyLnJlamVjdENhbGx9XG4gICAgICAgICAgICAgICAgICAgICAgICBraW5kPVwiZGFuZ2VyXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+IHtfdChcImFjdGlvbnxkZWNsaW5lXCIpfSA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvQWNjZXNzaWJsZUJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgICAgPEFjY2Vzc2libGVCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm14X0xlZ2FjeUNhbGxFdmVudF9jb250ZW50X2J1dHRvbiBteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudF9idXR0b25fYW5zd2VyXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci5hbnN3ZXJDYWxsfVxuICAgICAgICAgICAgICAgICAgICAgICAga2luZD1cInByaW1hcnlcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj4ge190KFwiYWN0aW9ufGFjY2VwdFwiKX0gPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8L0FjY2Vzc2libGVCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLnRpbWVzdGFtcH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuY2FsbFN0YXRlID09PSBDYWxsU3RhdGUuRW5kZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGhhbmd1cFJlYXNvbiA9IHRoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci5oYW5ndXBSZWFzb247XG4gICAgICAgICAgICBjb25zdCBnb3RSZWplY3RlZCA9IHRoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci5nb3RSZWplY3RlZDtcblxuICAgICAgICAgICAgaWYgKGdvdFJlamVjdGVkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge190KFwidGltZWxpbmV8bS5jYWxsLmludml0ZXxkZWNsaW5lZFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHt0aGlzLnJlbmRlckNhbGxCYWNrQnV0dG9uKF90KFwidGltZWxpbmV8bS5jYWxsLmludml0ZXxjYWxsX2JhY2tfcHJvbXB0XCIpKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLnRpbWVzdGFtcH1cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaGFuZ3VwUmVhc29uID09PSBDYWxsRXJyb3JDb2RlLkFuc3dlcmVkRWxzZXdoZXJlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge190KFwidGltZWxpbmV8bS5jYWxsLmludml0ZXxhbnN3ZXJlZF9lbHNld2hlcmVcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICB7dGhpcy5wcm9wcy50aW1lc3RhbXB9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci5jYWxsV2FzTWlzc2VkKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge190KFwidGltZWxpbmV8bS5jYWxsLmludml0ZXxtaXNzZWRfY2FsbFwiKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHt0aGlzLnJlbmRlckNhbGxCYWNrQnV0dG9uKF90KFwidGltZWxpbmV8bS5jYWxsLmludml0ZXxjYWxsX2JhY2tfcHJvbXB0XCIpKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLnRpbWVzdGFtcH1cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIWhhbmd1cFJlYXNvbiB8fCBbQ2FsbEVycm9yQ29kZS5Vc2VySGFuZ3VwLCBcInVzZXIgaGFuZ3VwXCJdLmluY2x1ZGVzKGhhbmd1cFJlYXNvbikpIHtcbiAgICAgICAgICAgICAgICAvLyB3b3JrYXJvdW5kIGZvciBodHRwczovL2dpdGh1Yi5jb20vdmVjdG9yLWltL2VsZW1lbnQtd2ViL2lzc3Vlcy81MTc4XG4gICAgICAgICAgICAgICAgLy8gaXQgc2VlbXMgQW5kcm9pZCByYW5kb21seSBzZXRzIGEgcmVhc29uIG9mIFwidXNlciBoYW5ndXBcIiB3aGljaCBpc1xuICAgICAgICAgICAgICAgIC8vIGludGVycHJldGVkIGFzIGFuIGVycm9yIGNvZGUgOihcbiAgICAgICAgICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vdmVjdG9yLWltL3Jpb3QtYW5kcm9pZC9pc3N1ZXMvMjYyM1xuICAgICAgICAgICAgICAgIC8vIEFsc28gdGhlIGNvcnJlY3QgaGFuZ3VwIGNvZGUgYXMgb2YgVm9JUCB2MSAod2l0aCB1bmRlcnNjb3JlKVxuICAgICAgICAgICAgICAgIC8vIEFsc28sIGlmIHdlIGRvbid0IGhhdmUgYSByZWFzb25cbiAgICAgICAgICAgICAgICBjb25zdCBkdXJhdGlvbiA9IHRoaXMucHJvcHMuY2FsbEV2ZW50R3JvdXBlci5kdXJhdGlvbiE7XG4gICAgICAgICAgICAgICAgbGV0IHRleHQgPSBfdChcInRpbWVsaW5lfG0uY2FsbC5oYW5ndXB8ZG1cIik7XG4gICAgICAgICAgICAgICAgaWYgKGR1cmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIHRleHQgKz0gXCIg4oCiIFwiICsgZm9ybWF0UHJlY2lzZUR1cmF0aW9uKGR1cmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3RleHR9XG4gICAgICAgICAgICAgICAgICAgICAgICB7dGhpcy5wcm9wcy50aW1lc3RhbXB9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGhhbmd1cFJlYXNvbiA9PT0gQ2FsbEVycm9yQ29kZS5JbnZpdGVUaW1lb3V0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge190KFwidGltZWxpbmV8bS5jYWxsLmludml0ZXxub19hbnN3ZXJcIil9XG4gICAgICAgICAgICAgICAgICAgICAgICB7dGhpcy5yZW5kZXJDYWxsQmFja0J1dHRvbihfdChcInRpbWVsaW5lfG0uY2FsbC5pbnZpdGV8Y2FsbF9iYWNrX3Byb21wdFwiKSl9XG4gICAgICAgICAgICAgICAgICAgICAgICB7dGhpcy5wcm9wcy50aW1lc3RhbXB9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCByZWFzb247XG4gICAgICAgICAgICBpZiAoaGFuZ3VwUmVhc29uID09PSBDYWxsRXJyb3JDb2RlLkljZUZhaWxlZCkge1xuICAgICAgICAgICAgICAgIC8vIFdlIGNvdWxkbid0IGVzdGFibGlzaCBhIGNvbm5lY3Rpb24gYXQgYWxsXG4gICAgICAgICAgICAgICAgcmVhc29uID0gX3QoXCJ0aW1lbGluZXxtLmNhbGwuaW52aXRlfGZhaWxlZF9jb25uZWN0X21lZGlhXCIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChoYW5ndXBSZWFzb24gPT09IFwiaWNlX3RpbWVvdXRcIikge1xuICAgICAgICAgICAgICAgIC8vIFdlIGVzdGFibGlzaGVkIGEgY29ubmVjdGlvbiBidXQgaXQgZGllZFxuICAgICAgICAgICAgICAgIHJlYXNvbiA9IF90KFwidGltZWxpbmV8bS5jYWxsLmludml0ZXxmYWlsZWRfY29ubmVjdGlvblwiKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaGFuZ3VwUmVhc29uID09PSBDYWxsRXJyb3JDb2RlLk5vVXNlck1lZGlhKSB7XG4gICAgICAgICAgICAgICAgLy8gVGhlIG90aGVyIHNpZGUgY291bGRuJ3Qgb3BlbiBjYXB0dXJlIGRldmljZXNcbiAgICAgICAgICAgICAgICByZWFzb24gPSBfdChcInRpbWVsaW5lfG0uY2FsbC5pbnZpdGV8ZmFpbGVkX29wcG9uZW50X21lZGlhXCIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChoYW5ndXBSZWFzb24gPT09IFwidW5rbm93bl9lcnJvclwiKSB7XG4gICAgICAgICAgICAgICAgLy8gQW4gZXJyb3IgY29kZSB0aGUgb3RoZXIgc2lkZSBkb2Vzbid0IGhhdmUgYSB3YXkgdG8gZXhwcmVzc1xuICAgICAgICAgICAgICAgIC8vIChhcyBvcHBvc2VkIHRvIGFuIGVycm9yIGNvZGUgdGhleSBnYXZlIGJ1dCB3ZSBkb24ndCBrbm93IGFib3V0LFxuICAgICAgICAgICAgICAgIC8vIGluIHdoaWNoIGNhc2Ugd2Ugc2hvdyB0aGUgZXJyb3IgY29kZSlcbiAgICAgICAgICAgICAgICByZWFzb24gPSBfdChcInRpbWVsaW5lfG0uY2FsbC5pbnZpdGV8dW5rbm93bl9lcnJvclwiKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoaGFuZ3VwUmVhc29uID09PSBDYWxsRXJyb3JDb2RlLlVzZXJCdXN5KSB7XG4gICAgICAgICAgICAgICAgcmVhc29uID0gX3QoXCJ2b2lwfHVzZXJfYnVzeV9kZXNjcmlwdGlvblwiKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVhc29uID0gX3QoXCJ0aW1lbGluZXxtLmNhbGwuaW52aXRlfHVua25vd25fZmFpbHVyZVwiLCB7IHJlYXNvbjogaGFuZ3VwUmVhc29uIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X2NvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPEluZm9Ub29sdGlwXG4gICAgICAgICAgICAgICAgICAgICAgICB0b29sdGlwPXtyZWFzb259XG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudF90b29sdGlwXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGtpbmQ9e0luZm9Ub29sdGlwS2luZC5XYXJuaW5nfVxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICB7X3QoXCJ0aW1lbGluZXxtLmNhbGwuaW52aXRlfGZhaWxlZF9jb25uZWN0aW9uXCIpfVxuICAgICAgICAgICAgICAgICAgICB7dGhpcy5yZW5kZXJDYWxsQmFja0J1dHRvbihfdChcImFjdGlvbnxyZXRyeVwiKSl9XG4gICAgICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLnRpbWVzdGFtcH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuc3RhdGUuY2FsbFN0YXRlID09PSBDYWxsU3RhdGUuQ29ubmVjdGVkKSB7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X2NvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPENsb2NrIHNlY29uZHM9e3RoaXMuc3RhdGUubGVuZ3RofSBhcmlhLWxpdmU9XCJvZmZcIiAvPlxuICAgICAgICAgICAgICAgICAgICB7dGhpcy5wcm9wcy50aW1lc3RhbXB9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLmNhbGxTdGF0ZSA9PT0gQ2FsbFN0YXRlLkNvbm5lY3RpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICB7X3QoXCJ2b2lwfGNvbm5lY3RpbmdcIil9XG4gICAgICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLnRpbWVzdGFtcH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfY29udGVudFwiPlxuICAgICAgICAgICAgICAgIHtfdChcInRpbWVsaW5lfG0uY2FsbC5pbnZpdGV8dW5rbm93bl9zdGF0ZVwiKX1cbiAgICAgICAgICAgICAgICB7dGhpcy5wcm9wcy50aW1lc3RhbXB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgcmVuZGVyKCk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5wcm9wcy5teEV2ZW50O1xuICAgICAgICBjb25zdCBzZW5kZXIgPSBldmVudC5zZW5kZXIgPyBldmVudC5zZW5kZXIubmFtZSA6IGV2ZW50LmdldFNlbmRlcigpO1xuICAgICAgICBjb25zdCBpc1ZvaWNlID0gdGhpcy5wcm9wcy5jYWxsRXZlbnRHcm91cGVyLmlzVm9pY2U7XG4gICAgICAgIGNvbnN0IGNhbGxUeXBlID0gaXNWb2ljZSA/IF90KFwidm9pcHx2b2ljZV9jYWxsXCIpIDogX3QoXCJ2b2lwfHZpZGVvX2NhbGxcIik7XG4gICAgICAgIGNvbnN0IGNhbGxTdGF0ZSA9IHRoaXMuc3RhdGUuY2FsbFN0YXRlO1xuICAgICAgICBjb25zdCBoYW5ndXBSZWFzb24gPSB0aGlzLnByb3BzLmNhbGxFdmVudEdyb3VwZXIuaGFuZ3VwUmVhc29uO1xuICAgICAgICBjb25zdCBjb250ZW50ID0gdGhpcy5yZW5kZXJDb250ZW50KCk7XG4gICAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IGNsYXNzTmFtZXMoXCJteF9MZWdhY3lDYWxsRXZlbnRcIiwge1xuICAgICAgICAgICAgbXhfTGVnYWN5Q2FsbEV2ZW50X3ZvaWNlOiBpc1ZvaWNlLFxuICAgICAgICAgICAgbXhfTGVnYWN5Q2FsbEV2ZW50X3ZpZGVvOiAhaXNWb2ljZSxcbiAgICAgICAgICAgIG14X0xlZ2FjeUNhbGxFdmVudF9uYXJyb3c6IHRoaXMuc3RhdGUubmFycm93LFxuICAgICAgICAgICAgbXhfTGVnYWN5Q2FsbEV2ZW50X21pc3NlZDogdGhpcy5wcm9wcy5jYWxsRXZlbnRHcm91cGVyLmNhbGxXYXNNaXNzZWQsXG4gICAgICAgICAgICBteF9MZWdhY3lDYWxsRXZlbnRfbm9BbnN3ZXI6IGNhbGxTdGF0ZSA9PT0gQ2FsbFN0YXRlLkVuZGVkICYmIGhhbmd1cFJlYXNvbiA9PT0gQ2FsbEVycm9yQ29kZS5JbnZpdGVUaW1lb3V0LFxuICAgICAgICAgICAgbXhfTGVnYWN5Q2FsbEV2ZW50X3JlamVjdGVkOiBjYWxsU3RhdGUgPT09IENhbGxTdGF0ZS5FbmRlZCAmJiB0aGlzLnByb3BzLmNhbGxFdmVudEdyb3VwZXIuZ290UmVqZWN0ZWQsXG4gICAgICAgIH0pO1xuICAgICAgICBsZXQgc2lsZW5jZUljb247XG4gICAgICAgIGlmICh0aGlzLnN0YXRlLm5hcnJvdyAmJiB0aGlzLnN0YXRlLmNhbGxTdGF0ZSA9PT0gQ2FsbFN0YXRlLlJpbmdpbmcpIHtcbiAgICAgICAgICAgIHNpbGVuY2VJY29uID0gdGhpcy5yZW5kZXJTaWxlbmNlSWNvbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X3dyYXBwZXJcIiByZWY9e3RoaXMud3JhcHBlckVsZW1lbnR9PlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPXtjbGFzc05hbWV9PlxuICAgICAgICAgICAgICAgICAgICB7c2lsZW5jZUljb259XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X2luZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxNZW1iZXJBdmF0YXIgbWVtYmVyPXtldmVudC5zZW5kZXJ9IHNpemU9XCIzMnB4XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X2luZm9fYmFzaWNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X0xlZ2FjeUNhbGxFdmVudF9zZW5kZXJcIj57c2VuZGVyfTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfTGVnYWN5Q2FsbEV2ZW50X3R5cGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJteF9MZWdhY3lDYWxsRXZlbnRfdHlwZV9pY29uXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge2NhbGxUeXBlfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB7Y29udGVudH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICApO1xuICAgIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFRQSxJ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