matrix-react-sdk
Version:
SDK for matrix.org using React
211 lines (207 loc) • 34 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.REACTION_SHORTCODE_KEY = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _react = _interopRequireDefault(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _matrix = require("matrix-js-sdk/src/matrix");
var _lodash = require("lodash");
var _NamespacedValue = require("matrix-js-sdk/src/NamespacedValue");
var _languageHandler = require("../../../languageHandler");
var _EventUtils = require("../../../utils/EventUtils");
var _ContextMenuTooltipButton = require("../../../accessibility/context_menu/ContextMenuTooltipButton");
var _ContextMenu = _interopRequireWildcard(require("../../structures/ContextMenu"));
var _ReactionPicker = _interopRequireDefault(require("../emojipicker/ReactionPicker"));
var _ReactionsRowButton = _interopRequireDefault(require("./ReactionsRowButton"));
var _RoomContext = _interopRequireDefault(require("../../../contexts/RoomContext"));
var _AccessibleButton = _interopRequireDefault(require("../elements/AccessibleButton"));
var _SettingsStore = _interopRequireDefault(require("../../../settings/SettingsStore"));
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 2019-2021 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
// The maximum number of reactions to initially show on a message.
const MAX_ITEMS_WHEN_LIMITED = 8;
const REACTION_SHORTCODE_KEY = exports.REACTION_SHORTCODE_KEY = new _NamespacedValue.UnstableValue("shortcode", "com.beeper.reaction.shortcode");
const ReactButton = ({
mxEvent,
reactions
}) => {
const [menuDisplayed, button, openMenu, closeMenu] = (0, _ContextMenu.useContextMenu)();
let contextMenu;
if (menuDisplayed && button.current) {
const buttonRect = button.current.getBoundingClientRect();
contextMenu = /*#__PURE__*/_react.default.createElement(_ContextMenu.default, (0, _extends2.default)({}, (0, _ContextMenu.aboveLeftOf)(buttonRect), {
onFinished: closeMenu,
managed: false
}), /*#__PURE__*/_react.default.createElement(_ReactionPicker.default, {
mxEvent: mxEvent,
reactions: reactions,
onFinished: closeMenu
}));
}
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_ContextMenuTooltipButton.ContextMenuTooltipButton, {
className: (0, _classnames.default)("mx_ReactionsRow_addReactionButton", {
mx_ReactionsRow_addReactionButton_active: menuDisplayed
}),
title: (0, _languageHandler._t)("timeline|reactions|add_reaction_prompt"),
onClick: openMenu,
onContextMenu: e => {
e.preventDefault();
openMenu();
},
isExpanded: menuDisplayed,
ref: button
}), contextMenu);
};
class ReactionsRow extends _react.default.PureComponent {
constructor(props, context) {
super(props, context);
(0, _defineProperty2.default)(this, "onDecrypted", () => {
// Decryption changes whether the event is actionable
this.forceUpdate();
});
(0, _defineProperty2.default)(this, "onReactionsChange", () => {
// TODO: Call `onHeightChanged` as needed
this.setState({
myReactions: this.getMyReactions()
});
// Using `forceUpdate` for the moment, since we know the overall set of reactions
// has changed (this is triggered by events for that purpose only) and
// `PureComponent`s shallow state / props compare would otherwise filter this out.
this.forceUpdate();
});
(0, _defineProperty2.default)(this, "onShowAllClick", () => {
this.setState({
showAll: true
});
});
this.state = {
myReactions: this.getMyReactions(),
showAll: false
};
}
componentDidMount() {
const {
mxEvent,
reactions
} = this.props;
if (mxEvent.isBeingDecrypted() || mxEvent.shouldAttemptDecryption()) {
mxEvent.once(_matrix.MatrixEventEvent.Decrypted, this.onDecrypted);
}
if (reactions) {
reactions.on(_matrix.RelationsEvent.Add, this.onReactionsChange);
reactions.on(_matrix.RelationsEvent.Remove, this.onReactionsChange);
reactions.on(_matrix.RelationsEvent.Redaction, this.onReactionsChange);
}
}
componentWillUnmount() {
const {
mxEvent,
reactions
} = this.props;
mxEvent.off(_matrix.MatrixEventEvent.Decrypted, this.onDecrypted);
if (reactions) {
reactions.off(_matrix.RelationsEvent.Add, this.onReactionsChange);
reactions.off(_matrix.RelationsEvent.Remove, this.onReactionsChange);
reactions.off(_matrix.RelationsEvent.Redaction, this.onReactionsChange);
}
}
componentDidUpdate(prevProps) {
if (this.props.reactions && prevProps.reactions !== this.props.reactions) {
this.props.reactions.on(_matrix.RelationsEvent.Add, this.onReactionsChange);
this.props.reactions.on(_matrix.RelationsEvent.Remove, this.onReactionsChange);
this.props.reactions.on(_matrix.RelationsEvent.Redaction, this.onReactionsChange);
this.onReactionsChange();
}
}
getMyReactions() {
const reactions = this.props.reactions;
if (!reactions) {
return null;
}
const userId = this.context.room?.client.getUserId();
if (!userId) return null;
const myReactions = reactions.getAnnotationsBySender()?.[userId];
if (!myReactions) {
return null;
}
return [...myReactions.values()];
}
render() {
const {
mxEvent,
reactions
} = this.props;
const {
myReactions,
showAll
} = this.state;
if (!reactions || !(0, _EventUtils.isContentActionable)(mxEvent)) {
return null;
}
const customReactionImagesEnabled = _SettingsStore.default.getValue("feature_render_reaction_images");
let items = reactions.getSortedAnnotationsByKey()?.map(([content, events]) => {
const count = events.size;
if (!count) {
return null;
}
// Deduplicate the events as per the spec https://spec.matrix.org/v1.7/client-server-api/#annotations-client-behaviour
// This isn't done by the underlying data model as applications may still need access to the whole list of events
// for moderation purposes.
const deduplicatedEvents = (0, _lodash.uniqBy)([...events], e => e.getSender());
const myReactionEvent = myReactions?.find(mxEvent => {
if (mxEvent.isRedacted()) {
return false;
}
return mxEvent.getRelation()?.key === content;
});
return /*#__PURE__*/_react.default.createElement(_ReactionsRowButton.default, {
key: content,
content: content,
count: deduplicatedEvents.length,
mxEvent: mxEvent,
reactionEvents: deduplicatedEvents,
myReactionEvent: myReactionEvent,
customReactionImagesEnabled: customReactionImagesEnabled,
disabled: !this.context.canReact || myReactionEvent && !myReactionEvent.isRedacted() && !this.context.canSelfRedact
});
}).filter(item => !!item);
if (!items?.length) return null;
// Show the first MAX_ITEMS if there are MAX_ITEMS + 1 or more items.
// The "+ 1" ensure that the "show all" reveals something that takes up
// more space than the button itself.
let showAllButton;
if (items.length > MAX_ITEMS_WHEN_LIMITED + 1 && !showAll) {
items = items.slice(0, MAX_ITEMS_WHEN_LIMITED);
showAllButton = /*#__PURE__*/_react.default.createElement(_AccessibleButton.default, {
kind: "link_inline",
className: "mx_ReactionsRow_showAll",
onClick: this.onShowAllClick
}, (0, _languageHandler._t)("action|show_all"));
}
let addReactionButton;
if (this.context.canReact) {
addReactionButton = /*#__PURE__*/_react.default.createElement(ReactButton, {
mxEvent: mxEvent,
reactions: reactions
});
}
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_ReactionsRow",
role: "toolbar",
"aria-label": (0, _languageHandler._t)("common|reactions")
}, items, showAllButton, addReactionButton);
}
}
exports.default = ReactionsRow;
(0, _defineProperty2.default)(ReactionsRow, "contextType", _RoomContext.default);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9jbGFzc25hbWVzIiwiX21hdHJpeCIsIl9sb2Rhc2giLCJfTmFtZXNwYWNlZFZhbHVlIiwiX2xhbmd1YWdlSGFuZGxlciIsIl9FdmVudFV0aWxzIiwiX0NvbnRleHRNZW51VG9vbHRpcEJ1dHRvbiIsIl9Db250ZXh0TWVudSIsIl9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkIiwiX1JlYWN0aW9uUGlja2VyIiwiX1JlYWN0aW9uc1Jvd0J1dHRvbiIsIl9Sb29tQ29udGV4dCIsIl9BY2Nlc3NpYmxlQnV0dG9uIiwiX1NldHRpbmdzU3RvcmUiLCJfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUiLCJlIiwiV2Vha01hcCIsInIiLCJ0IiwiX19lc01vZHVsZSIsImRlZmF1bHQiLCJoYXMiLCJnZXQiLCJuIiwiX19wcm90b19fIiwiYSIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwidSIsImhhc093blByb3BlcnR5IiwiY2FsbCIsImkiLCJzZXQiLCJNQVhfSVRFTVNfV0hFTl9MSU1JVEVEIiwiUkVBQ1RJT05fU0hPUlRDT0RFX0tFWSIsImV4cG9ydHMiLCJVbnN0YWJsZVZhbHVlIiwiUmVhY3RCdXR0b24iLCJteEV2ZW50IiwicmVhY3Rpb25zIiwibWVudURpc3BsYXllZCIsImJ1dHRvbiIsIm9wZW5NZW51IiwiY2xvc2VNZW51IiwidXNlQ29udGV4dE1lbnUiLCJjb250ZXh0TWVudSIsImN1cnJlbnQiLCJidXR0b25SZWN0IiwiZ2V0Qm91bmRpbmdDbGllbnRSZWN0IiwiY3JlYXRlRWxlbWVudCIsIl9leHRlbmRzMiIsImFib3ZlTGVmdE9mIiwib25GaW5pc2hlZCIsIm1hbmFnZWQiLCJGcmFnbWVudCIsIkNvbnRleHRNZW51VG9vbHRpcEJ1dHRvbiIsImNsYXNzTmFtZSIsImNsYXNzTmFtZXMiLCJteF9SZWFjdGlvbnNSb3dfYWRkUmVhY3Rpb25CdXR0b25fYWN0aXZlIiwidGl0bGUiLCJfdCIsIm9uQ2xpY2siLCJvbkNvbnRleHRNZW51IiwicHJldmVudERlZmF1bHQiLCJpc0V4cGFuZGVkIiwicmVmIiwiUmVhY3Rpb25zUm93IiwiUmVhY3QiLCJQdXJlQ29tcG9uZW50IiwiY29uc3RydWN0b3IiLCJwcm9wcyIsImNvbnRleHQiLCJfZGVmaW5lUHJvcGVydHkyIiwiZm9yY2VVcGRhdGUiLCJzZXRTdGF0ZSIsIm15UmVhY3Rpb25zIiwiZ2V0TXlSZWFjdGlvbnMiLCJzaG93QWxsIiwic3RhdGUiLCJjb21wb25lbnREaWRNb3VudCIsImlzQmVpbmdEZWNyeXB0ZWQiLCJzaG91bGRBdHRlbXB0RGVjcnlwdGlvbiIsIm9uY2UiLCJNYXRyaXhFdmVudEV2ZW50IiwiRGVjcnlwdGVkIiwib25EZWNyeXB0ZWQiLCJvbiIsIlJlbGF0aW9uc0V2ZW50IiwiQWRkIiwib25SZWFjdGlvbnNDaGFuZ2UiLCJSZW1vdmUiLCJSZWRhY3Rpb24iLCJjb21wb25lbnRXaWxsVW5tb3VudCIsIm9mZiIsImNvbXBvbmVudERpZFVwZGF0ZSIsInByZXZQcm9wcyIsInVzZXJJZCIsInJvb20iLCJjbGllbnQiLCJnZXRVc2VySWQiLCJnZXRBbm5vdGF0aW9uc0J5U2VuZGVyIiwidmFsdWVzIiwicmVuZGVyIiwiaXNDb250ZW50QWN0aW9uYWJsZSIsImN1c3RvbVJlYWN0aW9uSW1hZ2VzRW5hYmxlZCIsIlNldHRpbmdzU3RvcmUiLCJnZXRWYWx1ZSIsIml0ZW1zIiwiZ2V0U29ydGVkQW5ub3RhdGlvbnNCeUtleSIsIm1hcCIsImNvbnRlbnQiLCJldmVudHMiLCJjb3VudCIsInNpemUiLCJkZWR1cGxpY2F0ZWRFdmVudHMiLCJ1bmlxQnkiLCJnZXRTZW5kZXIiLCJteVJlYWN0aW9uRXZlbnQiLCJmaW5kIiwiaXNSZWRhY3RlZCIsImdldFJlbGF0aW9uIiwia2V5IiwibGVuZ3RoIiwicmVhY3Rpb25FdmVudHMiLCJkaXNhYmxlZCIsImNhblJlYWN0IiwiY2FuU2VsZlJlZGFjdCIsImZpbHRlciIsIml0ZW0iLCJzaG93QWxsQnV0dG9uIiwic2xpY2UiLCJraW5kIiwib25TaG93QWxsQ2xpY2siLCJhZGRSZWFjdGlvbkJ1dHRvbiIsInJvbGUiLCJSb29tQ29udGV4dCJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL21lc3NhZ2VzL1JlYWN0aW9uc1Jvdy50c3giXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMTktMjAyMSBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgUmVhY3QsIHsgU3ludGhldGljRXZlbnQgfSBmcm9tIFwicmVhY3RcIjtcbmltcG9ydCBjbGFzc05hbWVzIGZyb20gXCJjbGFzc25hbWVzXCI7XG5pbXBvcnQgeyBNYXRyaXhFdmVudCwgTWF0cml4RXZlbnRFdmVudCwgUmVsYXRpb25zLCBSZWxhdGlvbnNFdmVudCB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9tYXRyaXhcIjtcbmltcG9ydCB7IHVuaXFCeSB9IGZyb20gXCJsb2Rhc2hcIjtcbmltcG9ydCB7IFVuc3RhYmxlVmFsdWUgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvTmFtZXNwYWNlZFZhbHVlXCI7XG5cbmltcG9ydCB7IF90IH0gZnJvbSBcIi4uLy4uLy4uL2xhbmd1YWdlSGFuZGxlclwiO1xuaW1wb3J0IHsgaXNDb250ZW50QWN0aW9uYWJsZSB9IGZyb20gXCIuLi8uLi8uLi91dGlscy9FdmVudFV0aWxzXCI7XG5pbXBvcnQgeyBDb250ZXh0TWVudVRvb2x0aXBCdXR0b24gfSBmcm9tIFwiLi4vLi4vLi4vYWNjZXNzaWJpbGl0eS9jb250ZXh0X21lbnUvQ29udGV4dE1lbnVUb29sdGlwQnV0dG9uXCI7XG5pbXBvcnQgQ29udGV4dE1lbnUsIHsgYWJvdmVMZWZ0T2YsIHVzZUNvbnRleHRNZW51IH0gZnJvbSBcIi4uLy4uL3N0cnVjdHVyZXMvQ29udGV4dE1lbnVcIjtcbmltcG9ydCBSZWFjdGlvblBpY2tlciBmcm9tIFwiLi4vZW1vamlwaWNrZXIvUmVhY3Rpb25QaWNrZXJcIjtcbmltcG9ydCBSZWFjdGlvbnNSb3dCdXR0b24gZnJvbSBcIi4vUmVhY3Rpb25zUm93QnV0dG9uXCI7XG5pbXBvcnQgUm9vbUNvbnRleHQgZnJvbSBcIi4uLy4uLy4uL2NvbnRleHRzL1Jvb21Db250ZXh0XCI7XG5pbXBvcnQgQWNjZXNzaWJsZUJ1dHRvbiBmcm9tIFwiLi4vZWxlbWVudHMvQWNjZXNzaWJsZUJ1dHRvblwiO1xuaW1wb3J0IFNldHRpbmdzU3RvcmUgZnJvbSBcIi4uLy4uLy4uL3NldHRpbmdzL1NldHRpbmdzU3RvcmVcIjtcblxuLy8gVGhlIG1heGltdW0gbnVtYmVyIG9mIHJlYWN0aW9ucyB0byBpbml0aWFsbHkgc2hvdyBvbiBhIG1lc3NhZ2UuXG5jb25zdCBNQVhfSVRFTVNfV0hFTl9MSU1JVEVEID0gODtcblxuZXhwb3J0IGNvbnN0IFJFQUNUSU9OX1NIT1JUQ09ERV9LRVkgPSBuZXcgVW5zdGFibGVWYWx1ZShcInNob3J0Y29kZVwiLCBcImNvbS5iZWVwZXIucmVhY3Rpb24uc2hvcnRjb2RlXCIpO1xuXG5jb25zdCBSZWFjdEJ1dHRvbjogUmVhY3QuRkM8SVByb3BzPiA9ICh7IG14RXZlbnQsIHJlYWN0aW9ucyB9KSA9PiB7XG4gICAgY29uc3QgW21lbnVEaXNwbGF5ZWQsIGJ1dHRvbiwgb3Blbk1lbnUsIGNsb3NlTWVudV0gPSB1c2VDb250ZXh0TWVudSgpO1xuXG4gICAgbGV0IGNvbnRleHRNZW51OiBKU1guRWxlbWVudCB8IHVuZGVmaW5lZDtcbiAgICBpZiAobWVudURpc3BsYXllZCAmJiBidXR0b24uY3VycmVudCkge1xuICAgICAgICBjb25zdCBidXR0b25SZWN0ID0gYnV0dG9uLmN1cnJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGNvbnRleHRNZW51ID0gKFxuICAgICAgICAgICAgPENvbnRleHRNZW51IHsuLi5hYm92ZUxlZnRPZihidXR0b25SZWN0KX0gb25GaW5pc2hlZD17Y2xvc2VNZW51fSBtYW5hZ2VkPXtmYWxzZX0+XG4gICAgICAgICAgICAgICAgPFJlYWN0aW9uUGlja2VyIG14RXZlbnQ9e214RXZlbnR9IHJlYWN0aW9ucz17cmVhY3Rpb25zfSBvbkZpbmlzaGVkPXtjbG9zZU1lbnV9IC8+XG4gICAgICAgICAgICA8L0NvbnRleHRNZW51PlxuICAgICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiAoXG4gICAgICAgIDxSZWFjdC5GcmFnbWVudD5cbiAgICAgICAgICAgIDxDb250ZXh0TWVudVRvb2x0aXBCdXR0b25cbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9e2NsYXNzTmFtZXMoXCJteF9SZWFjdGlvbnNSb3dfYWRkUmVhY3Rpb25CdXR0b25cIiwge1xuICAgICAgICAgICAgICAgICAgICBteF9SZWFjdGlvbnNSb3dfYWRkUmVhY3Rpb25CdXR0b25fYWN0aXZlOiBtZW51RGlzcGxheWVkLFxuICAgICAgICAgICAgICAgIH0pfVxuICAgICAgICAgICAgICAgIHRpdGxlPXtfdChcInRpbWVsaW5lfHJlYWN0aW9uc3xhZGRfcmVhY3Rpb25fcHJvbXB0XCIpfVxuICAgICAgICAgICAgICAgIG9uQ2xpY2s9e29wZW5NZW51fVxuICAgICAgICAgICAgICAgIG9uQ29udGV4dE1lbnU9eyhlOiBTeW50aGV0aWNFdmVudCk6IHZvaWQgPT4ge1xuICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIG9wZW5NZW51KCk7XG4gICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICBpc0V4cGFuZGVkPXttZW51RGlzcGxheWVkfVxuICAgICAgICAgICAgICAgIHJlZj17YnV0dG9ufVxuICAgICAgICAgICAgLz5cblxuICAgICAgICAgICAge2NvbnRleHRNZW51fVxuICAgICAgICA8L1JlYWN0LkZyYWdtZW50PlxuICAgICk7XG59O1xuXG5pbnRlcmZhY2UgSVByb3BzIHtcbiAgICAvLyBUaGUgZXZlbnQgd2UncmUgZGlzcGxheWluZyByZWFjdGlvbnMgZm9yXG4gICAgbXhFdmVudDogTWF0cml4RXZlbnQ7XG4gICAgLy8gVGhlIFJlbGF0aW9ucyBtb2RlbCBmcm9tIHRoZSBKUyBTREsgZm9yIHJlYWN0aW9ucyB0byBgbXhFdmVudGBcbiAgICByZWFjdGlvbnM/OiBSZWxhdGlvbnMgfCBudWxsIHwgdW5kZWZpbmVkO1xufVxuXG5pbnRlcmZhY2UgSVN0YXRlIHtcbiAgICBteVJlYWN0aW9uczogTWF0cml4RXZlbnRbXSB8IG51bGw7XG4gICAgc2hvd0FsbDogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmVhY3Rpb25zUm93IGV4dGVuZHMgUmVhY3QuUHVyZUNvbXBvbmVudDxJUHJvcHMsIElTdGF0ZT4ge1xuICAgIHB1YmxpYyBzdGF0aWMgY29udGV4dFR5cGUgPSBSb29tQ29udGV4dDtcbiAgICBwdWJsaWMgZGVjbGFyZSBjb250ZXh0OiBSZWFjdC5Db250ZXh0VHlwZTx0eXBlb2YgUm9vbUNvbnRleHQ+O1xuXG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHByb3BzOiBJUHJvcHMsIGNvbnRleHQ6IFJlYWN0LkNvbnRleHRUeXBlPHR5cGVvZiBSb29tQ29udGV4dD4pIHtcbiAgICAgICAgc3VwZXIocHJvcHMsIGNvbnRleHQpO1xuXG4gICAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgICAgICBteVJlYWN0aW9uczogdGhpcy5nZXRNeVJlYWN0aW9ucygpLFxuICAgICAgICAgICAgc2hvd0FsbDogZmFsc2UsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXBvbmVudERpZE1vdW50KCk6IHZvaWQge1xuICAgICAgICBjb25zdCB7IG14RXZlbnQsIHJlYWN0aW9ucyB9ID0gdGhpcy5wcm9wcztcblxuICAgICAgICBpZiAobXhFdmVudC5pc0JlaW5nRGVjcnlwdGVkKCkgfHwgbXhFdmVudC5zaG91bGRBdHRlbXB0RGVjcnlwdGlvbigpKSB7XG4gICAgICAgICAgICBteEV2ZW50Lm9uY2UoTWF0cml4RXZlbnRFdmVudC5EZWNyeXB0ZWQsIHRoaXMub25EZWNyeXB0ZWQpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJlYWN0aW9ucykge1xuICAgICAgICAgICAgcmVhY3Rpb25zLm9uKFJlbGF0aW9uc0V2ZW50LkFkZCwgdGhpcy5vblJlYWN0aW9uc0NoYW5nZSk7XG4gICAgICAgICAgICByZWFjdGlvbnMub24oUmVsYXRpb25zRXZlbnQuUmVtb3ZlLCB0aGlzLm9uUmVhY3Rpb25zQ2hhbmdlKTtcbiAgICAgICAgICAgIHJlYWN0aW9ucy5vbihSZWxhdGlvbnNFdmVudC5SZWRhY3Rpb24sIHRoaXMub25SZWFjdGlvbnNDaGFuZ2UpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXBvbmVudFdpbGxVbm1vdW50KCk6IHZvaWQge1xuICAgICAgICBjb25zdCB7IG14RXZlbnQsIHJlYWN0aW9ucyB9ID0gdGhpcy5wcm9wcztcblxuICAgICAgICBteEV2ZW50Lm9mZihNYXRyaXhFdmVudEV2ZW50LkRlY3J5cHRlZCwgdGhpcy5vbkRlY3J5cHRlZCk7XG5cbiAgICAgICAgaWYgKHJlYWN0aW9ucykge1xuICAgICAgICAgICAgcmVhY3Rpb25zLm9mZihSZWxhdGlvbnNFdmVudC5BZGQsIHRoaXMub25SZWFjdGlvbnNDaGFuZ2UpO1xuICAgICAgICAgICAgcmVhY3Rpb25zLm9mZihSZWxhdGlvbnNFdmVudC5SZW1vdmUsIHRoaXMub25SZWFjdGlvbnNDaGFuZ2UpO1xuICAgICAgICAgICAgcmVhY3Rpb25zLm9mZihSZWxhdGlvbnNFdmVudC5SZWRhY3Rpb24sIHRoaXMub25SZWFjdGlvbnNDaGFuZ2UpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGNvbXBvbmVudERpZFVwZGF0ZShwcmV2UHJvcHM6IElQcm9wcyk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5yZWFjdGlvbnMgJiYgcHJldlByb3BzLnJlYWN0aW9ucyAhPT0gdGhpcy5wcm9wcy5yZWFjdGlvbnMpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMucmVhY3Rpb25zLm9uKFJlbGF0aW9uc0V2ZW50LkFkZCwgdGhpcy5vblJlYWN0aW9uc0NoYW5nZSk7XG4gICAgICAgICAgICB0aGlzLnByb3BzLnJlYWN0aW9ucy5vbihSZWxhdGlvbnNFdmVudC5SZW1vdmUsIHRoaXMub25SZWFjdGlvbnNDaGFuZ2UpO1xuICAgICAgICAgICAgdGhpcy5wcm9wcy5yZWFjdGlvbnMub24oUmVsYXRpb25zRXZlbnQuUmVkYWN0aW9uLCB0aGlzLm9uUmVhY3Rpb25zQ2hhbmdlKTtcbiAgICAgICAgICAgIHRoaXMub25SZWFjdGlvbnNDaGFuZ2UoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgb25EZWNyeXB0ZWQgPSAoKTogdm9pZCA9PiB7XG4gICAgICAgIC8vIERlY3J5cHRpb24gY2hhbmdlcyB3aGV0aGVyIHRoZSBldmVudCBpcyBhY3Rpb25hYmxlXG4gICAgICAgIHRoaXMuZm9yY2VVcGRhdGUoKTtcbiAgICB9O1xuXG4gICAgcHJpdmF0ZSBvblJlYWN0aW9uc0NoYW5nZSA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgLy8gVE9ETzogQ2FsbCBgb25IZWlnaHRDaGFuZ2VkYCBhcyBuZWVkZWRcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBteVJlYWN0aW9uczogdGhpcy5nZXRNeVJlYWN0aW9ucygpLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gVXNpbmcgYGZvcmNlVXBkYXRlYCBmb3IgdGhlIG1vbWVudCwgc2luY2Ugd2Uga25vdyB0aGUgb3ZlcmFsbCBzZXQgb2YgcmVhY3Rpb25zXG4gICAgICAgIC8vIGhhcyBjaGFuZ2VkICh0aGlzIGlzIHRyaWdnZXJlZCBieSBldmVudHMgZm9yIHRoYXQgcHVycG9zZSBvbmx5KSBhbmRcbiAgICAgICAgLy8gYFB1cmVDb21wb25lbnRgcyBzaGFsbG93IHN0YXRlIC8gcHJvcHMgY29tcGFyZSB3b3VsZCBvdGhlcndpc2UgZmlsdGVyIHRoaXMgb3V0LlxuICAgICAgICB0aGlzLmZvcmNlVXBkYXRlKCk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgZ2V0TXlSZWFjdGlvbnMoKTogTWF0cml4RXZlbnRbXSB8IG51bGwge1xuICAgICAgICBjb25zdCByZWFjdGlvbnMgPSB0aGlzLnByb3BzLnJlYWN0aW9ucztcbiAgICAgICAgaWYgKCFyZWFjdGlvbnMpIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHVzZXJJZCA9IHRoaXMuY29udGV4dC5yb29tPy5jbGllbnQuZ2V0VXNlcklkKCk7XG4gICAgICAgIGlmICghdXNlcklkKSByZXR1cm4gbnVsbDtcbiAgICAgICAgY29uc3QgbXlSZWFjdGlvbnMgPSByZWFjdGlvbnMuZ2V0QW5ub3RhdGlvbnNCeVNlbmRlcigpPy5bdXNlcklkXTtcbiAgICAgICAgaWYgKCFteVJlYWN0aW9ucykge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFsuLi5teVJlYWN0aW9ucy52YWx1ZXMoKV07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvblNob3dBbGxDbGljayA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzaG93QWxsOiB0cnVlLFxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgcHVibGljIHJlbmRlcigpOiBSZWFjdC5SZWFjdE5vZGUge1xuICAgICAgICBjb25zdCB7IG14RXZlbnQsIHJlYWN0aW9ucyB9ID0gdGhpcy5wcm9wcztcbiAgICAgICAgY29uc3QgeyBteVJlYWN0aW9ucywgc2hvd0FsbCB9ID0gdGhpcy5zdGF0ZTtcblxuICAgICAgICBpZiAoIXJlYWN0aW9ucyB8fCAhaXNDb250ZW50QWN0aW9uYWJsZShteEV2ZW50KSkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgY3VzdG9tUmVhY3Rpb25JbWFnZXNFbmFibGVkID0gU2V0dGluZ3NTdG9yZS5nZXRWYWx1ZShcImZlYXR1cmVfcmVuZGVyX3JlYWN0aW9uX2ltYWdlc1wiKTtcblxuICAgICAgICBsZXQgaXRlbXMgPSByZWFjdGlvbnNcbiAgICAgICAgICAgIC5nZXRTb3J0ZWRBbm5vdGF0aW9uc0J5S2V5KClcbiAgICAgICAgICAgID8ubWFwKChbY29udGVudCwgZXZlbnRzXSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gZXZlbnRzLnNpemU7XG4gICAgICAgICAgICAgICAgaWYgKCFjb3VudCkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gRGVkdXBsaWNhdGUgdGhlIGV2ZW50cyBhcyBwZXIgdGhlIHNwZWMgaHR0cHM6Ly9zcGVjLm1hdHJpeC5vcmcvdjEuNy9jbGllbnQtc2VydmVyLWFwaS8jYW5ub3RhdGlvbnMtY2xpZW50LWJlaGF2aW91clxuICAgICAgICAgICAgICAgIC8vIFRoaXMgaXNuJ3QgZG9uZSBieSB0aGUgdW5kZXJseWluZyBkYXRhIG1vZGVsIGFzIGFwcGxpY2F0aW9ucyBtYXkgc3RpbGwgbmVlZCBhY2Nlc3MgdG8gdGhlIHdob2xlIGxpc3Qgb2YgZXZlbnRzXG4gICAgICAgICAgICAgICAgLy8gZm9yIG1vZGVyYXRpb24gcHVycG9zZXMuXG4gICAgICAgICAgICAgICAgY29uc3QgZGVkdXBsaWNhdGVkRXZlbnRzID0gdW5pcUJ5KFsuLi5ldmVudHNdLCAoZSkgPT4gZS5nZXRTZW5kZXIoKSk7XG4gICAgICAgICAgICAgICAgY29uc3QgbXlSZWFjdGlvbkV2ZW50ID0gbXlSZWFjdGlvbnM/LmZpbmQoKG14RXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG14RXZlbnQuaXNSZWRhY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG14RXZlbnQuZ2V0UmVsYXRpb24oKT8ua2V5ID09PSBjb250ZW50O1xuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgIDxSZWFjdGlvbnNSb3dCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgIGtleT17Y29udGVudH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnQ9e2NvbnRlbnR9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb3VudD17ZGVkdXBsaWNhdGVkRXZlbnRzLmxlbmd0aH1cbiAgICAgICAgICAgICAgICAgICAgICAgIG14RXZlbnQ9e214RXZlbnR9XG4gICAgICAgICAgICAgICAgICAgICAgICByZWFjdGlvbkV2ZW50cz17ZGVkdXBsaWNhdGVkRXZlbnRzfVxuICAgICAgICAgICAgICAgICAgICAgICAgbXlSZWFjdGlvbkV2ZW50PXtteVJlYWN0aW9uRXZlbnR9XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXN0b21SZWFjdGlvbkltYWdlc0VuYWJsZWQ9e2N1c3RvbVJlYWN0aW9uSW1hZ2VzRW5hYmxlZH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVkPXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAhdGhpcy5jb250ZXh0LmNhblJlYWN0IHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG15UmVhY3Rpb25FdmVudCAmJiAhbXlSZWFjdGlvbkV2ZW50LmlzUmVkYWN0ZWQoKSAmJiAhdGhpcy5jb250ZXh0LmNhblNlbGZSZWRhY3QpXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuZmlsdGVyKChpdGVtKSA9PiAhIWl0ZW0pO1xuXG4gICAgICAgIGlmICghaXRlbXM/Lmxlbmd0aCkgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgLy8gU2hvdyB0aGUgZmlyc3QgTUFYX0lURU1TIGlmIHRoZXJlIGFyZSBNQVhfSVRFTVMgKyAxIG9yIG1vcmUgaXRlbXMuXG4gICAgICAgIC8vIFRoZSBcIisgMVwiIGVuc3VyZSB0aGF0IHRoZSBcInNob3cgYWxsXCIgcmV2ZWFscyBzb21ldGhpbmcgdGhhdCB0YWtlcyB1cFxuICAgICAgICAvLyBtb3JlIHNwYWNlIHRoYW4gdGhlIGJ1dHRvbiBpdHNlbGYuXG4gICAgICAgIGxldCBzaG93QWxsQnV0dG9uOiBKU1guRWxlbWVudCB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGl0ZW1zLmxlbmd0aCA+IE1BWF9JVEVNU19XSEVOX0xJTUlURUQgKyAxICYmICFzaG93QWxsKSB7XG4gICAgICAgICAgICBpdGVtcyA9IGl0ZW1zLnNsaWNlKDAsIE1BWF9JVEVNU19XSEVOX0xJTUlURUQpO1xuICAgICAgICAgICAgc2hvd0FsbEJ1dHRvbiA9IChcbiAgICAgICAgICAgICAgICA8QWNjZXNzaWJsZUJ1dHRvbiBraW5kPVwibGlua19pbmxpbmVcIiBjbGFzc05hbWU9XCJteF9SZWFjdGlvbnNSb3dfc2hvd0FsbFwiIG9uQ2xpY2s9e3RoaXMub25TaG93QWxsQ2xpY2t9PlxuICAgICAgICAgICAgICAgICAgICB7X3QoXCJhY3Rpb258c2hvd19hbGxcIil9XG4gICAgICAgICAgICAgICAgPC9BY2Nlc3NpYmxlQnV0dG9uPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBhZGRSZWFjdGlvbkJ1dHRvbjogSlNYLkVsZW1lbnQgfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmICh0aGlzLmNvbnRleHQuY2FuUmVhY3QpIHtcbiAgICAgICAgICAgIGFkZFJlYWN0aW9uQnV0dG9uID0gPFJlYWN0QnV0dG9uIG14RXZlbnQ9e214RXZlbnR9IHJlYWN0aW9ucz17cmVhY3Rpb25zfSAvPjtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1JlYWN0aW9uc1Jvd1wiIHJvbGU9XCJ0b29sYmFyXCIgYXJpYS1sYWJlbD17X3QoXCJjb21tb258cmVhY3Rpb25zXCIpfT5cbiAgICAgICAgICAgICAgICB7aXRlbXN9XG4gICAgICAgICAgICAgICAge3Nob3dBbGxCdXR0b259XG4gICAgICAgICAgICAgICAge2FkZFJlYWN0aW9uQnV0dG9ufVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICk7XG4gICAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFRQSxJQUFBQSxNQUFBLEdBQUFDLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxXQUFBLEdBQUFGLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBRSxPQUFBLEdBQUFGLE9BQUE7QUFDQSxJQUFBRyxPQUFBLEdBQUFILE9BQUE7QUFDQSxJQUFBSSxnQkFBQSxHQUFBSixPQUFBO0FBRUEsSUFBQUssZ0JBQUEsR0FBQUwsT0FBQTtBQUNBLElBQUFNLFdBQUEsR0FBQU4sT0FBQTtBQUNBLElBQUFPLHlCQUFBLEdBQUFQLE9BQUE7QUFDQSxJQUFBUSxZQUFBLEdBQUFDLHVCQUFBLENBQUFULE9BQUE7QUFDQSxJQUFBVSxlQUFBLEdBQUFYLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBVyxtQkFBQSxHQUFBWixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQVksWUFBQSxHQUFBYixzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQWEsaUJBQUEsR0FBQWQsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFj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