matrix-react-sdk
Version:
SDK for matrix.org using React
181 lines (167 loc) • 23.6 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useFetchedPinnedEvents = useFetchedPinnedEvents;
exports.useReadPinnedEvents = exports.usePinnedEvents = void 0;
exports.useSortedFetchedPinnedEvents = useSortedFetchedPinnedEvents;
var _react = require("react");
var _matrix = require("matrix-js-sdk/src/matrix");
var _logger = require("matrix-js-sdk/src/logger");
var _useEventEmitter = require("./useEventEmitter");
var _types = require("../components/views/right_panel/types");
var _MatrixClientContext = require("../contexts/MatrixClientContext");
var _useAsyncMemo = require("./useAsyncMemo");
var _PinningUtils = _interopRequireDefault(require("../utils/PinningUtils"));
var _promise = require("../utils/promise.ts");
/*
* 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.
*/
/**
* Get the pinned event IDs from a room.
* The number of pinned events is limited to 100.
* @param room
*/
function getPinnedEventIds(room) {
const eventIds = room?.getLiveTimeline().getState(_matrix.EventTimeline.FORWARDS)?.getStateEvents(_matrix.EventType.RoomPinnedEvents, "")?.getContent()?.pinned ?? [];
// Limit the number of pinned events to 100
return eventIds.slice(0, 100);
}
/**
* Get the pinned event IDs from a room.
* @param room
*/
const usePinnedEvents = room => {
const [pinnedEvents, setPinnedEvents] = (0, _react.useState)(getPinnedEventIds(room));
// Update the pinned events when the room state changes
// Filter out events that are not pinned events
const update = (0, _react.useCallback)(ev => {
if (ev && ev.getType() !== _matrix.EventType.RoomPinnedEvents) return;
setPinnedEvents(getPinnedEventIds(room));
}, [room]);
(0, _useEventEmitter.useTypedEventEmitter)(room?.getLiveTimeline().getState(_matrix.EventTimeline.FORWARDS), _matrix.RoomStateEvent.Events, update);
(0, _react.useEffect)(() => {
setPinnedEvents(getPinnedEventIds(room));
return () => {
setPinnedEvents([]);
};
}, [room]);
return pinnedEvents;
};
/**
* Get the read pinned event IDs from a room.
* @param room
*/
exports.usePinnedEvents = usePinnedEvents;
function getReadPinnedEventIds(room) {
return new Set(room?.getAccountData(_types.ReadPinsEventId)?.getContent()?.event_ids ?? []);
}
/**
* Get the read pinned event IDs from a room.
* @param room
*/
const useReadPinnedEvents = room => {
const [readPinnedEvents, setReadPinnedEvents] = (0, _react.useState)(new Set());
// Update the read pinned events when the room state changes
// Filter out events that are not read pinned events
const update = (0, _react.useCallback)(ev => {
if (ev && ev.getType() !== _types.ReadPinsEventId) return;
setReadPinnedEvents(getReadPinnedEventIds(room));
}, [room]);
(0, _useEventEmitter.useTypedEventEmitter)(room, _matrix.RoomEvent.AccountData, update);
(0, _react.useEffect)(() => {
setReadPinnedEvents(getReadPinnedEventIds(room));
return () => {
setReadPinnedEvents(new Set());
};
}, [room]);
return readPinnedEvents;
};
/**
* Fetch the pinned event
* @param room
* @param pinnedEventId
* @param cli
*/
exports.useReadPinnedEvents = useReadPinnedEvents;
async function fetchPinnedEvent(room, pinnedEventId, cli) {
const timelineSet = room.getUnfilteredTimelineSet();
// Get the event from the local timeline
const localEvent = timelineSet?.getTimelineForEvent(pinnedEventId)?.getEvents().find(e => e.getId() === pinnedEventId);
// Decrypt the event if it's encrypted
// Can happen when the tab is refreshed and the pinned events card is opened directly
if (localEvent?.isEncrypted()) {
await cli.decryptEventIfNeeded(localEvent, {
emit: false
});
}
// If the event is available locally, return it if it's pinnable
// or if it's redacted (to show the redacted event and to be able to unpin it)
// Otherwise, return null
if (localEvent) return _PinningUtils.default.isUnpinnable(localEvent) ? localEvent : null;
try {
// The event is not available locally, so we fetch the event and latest edit in parallel
const [evJson, {
events: [edit]
}] = await Promise.all([cli.fetchRoomEvent(room.roomId, pinnedEventId), cli.relations(room.roomId, pinnedEventId, _matrix.RelationType.Replace, null, {
limit: 1
})]);
const event = new _matrix.MatrixEvent(evJson);
// Decrypt the event if it's encrypted
if (event.isEncrypted()) {
await cli.decryptEventIfNeeded(event, {
emit: false
});
}
// Handle poll events
await room.processPollEvents([event]);
const senderUserId = event.getSender();
if (senderUserId && _PinningUtils.default.isUnpinnable(event)) {
// Inject sender information
event.sender = room.getMember(senderUserId);
// Also inject any edits we've found
if (edit) event.makeReplaced(edit);
return event;
}
} catch (err) {
_logger.logger.error(`Error looking up pinned event ${pinnedEventId} in room ${room.roomId}`);
_logger.logger.error(err);
}
return null;
}
/**
* Fetch the pinned events
* @param room
* @param pinnedEventIds
*/
function useFetchedPinnedEvents(room, pinnedEventIds) {
const cli = (0, _MatrixClientContext.useMatrixClientContext)();
return (0, _useAsyncMemo.useAsyncMemo)(() => {
const fetchPromises = pinnedEventIds.map(eventId => () => fetchPinnedEvent(room, eventId, cli));
// Fetch the pinned events in batches of 10
return (0, _promise.batch)(fetchPromises, 10);
}, [cli, room, pinnedEventIds], null);
}
/**
* Fetch the pinned events and sort them by from the oldest to the newest
* The order is determined by the event timestamp
* @param room
* @param pinnedEventIds
*/
function useSortedFetchedPinnedEvents(room, pinnedEventIds) {
const pinnedEvents = useFetchedPinnedEvents(room, pinnedEventIds);
return (0, _react.useMemo)(() => {
if (!pinnedEvents) return [];
return pinnedEvents.sort((a, b) => {
if (!a) return -1;
if (!b) return 1;
return a.getTs() - b.getTs();
});
}, [pinnedEvents]);
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJyZXF1aXJlIiwiX21hdHJpeCIsIl9sb2dnZXIiLCJfdXNlRXZlbnRFbWl0dGVyIiwiX3R5cGVzIiwiX01hdHJpeENsaWVudENvbnRleHQiLCJfdXNlQXN5bmNNZW1vIiwiX1Bpbm5pbmdVdGlscyIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfcHJvbWlzZSIsImdldFBpbm5lZEV2ZW50SWRzIiwicm9vbSIsImV2ZW50SWRzIiwiZ2V0TGl2ZVRpbWVsaW5lIiwiZ2V0U3RhdGUiLCJFdmVudFRpbWVsaW5lIiwiRk9SV0FSRFMiLCJnZXRTdGF0ZUV2ZW50cyIsIkV2ZW50VHlwZSIsIlJvb21QaW5uZWRFdmVudHMiLCJnZXRDb250ZW50IiwicGlubmVkIiwic2xpY2UiLCJ1c2VQaW5uZWRFdmVudHMiLCJwaW5uZWRFdmVudHMiLCJzZXRQaW5uZWRFdmVudHMiLCJ1c2VTdGF0ZSIsInVwZGF0ZSIsInVzZUNhbGxiYWNrIiwiZXYiLCJnZXRUeXBlIiwidXNlVHlwZWRFdmVudEVtaXR0ZXIiLCJSb29tU3RhdGVFdmVudCIsIkV2ZW50cyIsInVzZUVmZmVjdCIsImV4cG9ydHMiLCJnZXRSZWFkUGlubmVkRXZlbnRJZHMiLCJTZXQiLCJnZXRBY2NvdW50RGF0YSIsIlJlYWRQaW5zRXZlbnRJZCIsImV2ZW50X2lkcyIsInVzZVJlYWRQaW5uZWRFdmVudHMiLCJyZWFkUGlubmVkRXZlbnRzIiwic2V0UmVhZFBpbm5lZEV2ZW50cyIsIlJvb21FdmVudCIsIkFjY291bnREYXRhIiwiZmV0Y2hQaW5uZWRFdmVudCIsInBpbm5lZEV2ZW50SWQiLCJjbGkiLCJ0aW1lbGluZVNldCIsImdldFVuZmlsdGVyZWRUaW1lbGluZVNldCIsImxvY2FsRXZlbnQiLCJnZXRUaW1lbGluZUZvckV2ZW50IiwiZ2V0RXZlbnRzIiwiZmluZCIsImUiLCJnZXRJZCIsImlzRW5jcnlwdGVkIiwiZGVjcnlwdEV2ZW50SWZOZWVkZWQiLCJlbWl0IiwiUGlubmluZ1V0aWxzIiwiaXNVbnBpbm5hYmxlIiwiZXZKc29uIiwiZXZlbnRzIiwiZWRpdCIsIlByb21pc2UiLCJhbGwiLCJmZXRjaFJvb21FdmVudCIsInJvb21JZCIsInJlbGF0aW9ucyIsIlJlbGF0aW9uVHlwZSIsIlJlcGxhY2UiLCJsaW1pdCIsImV2ZW50IiwiTWF0cml4RXZlbnQiLCJwcm9jZXNzUG9sbEV2ZW50cyIsInNlbmRlclVzZXJJZCIsImdldFNlbmRlciIsInNlbmRlciIsImdldE1lbWJlciIsIm1ha2VSZXBsYWNlZCIsImVyciIsImxvZ2dlciIsImVycm9yIiwidXNlRmV0Y2hlZFBpbm5lZEV2ZW50cyIsInBpbm5lZEV2ZW50SWRzIiwidXNlTWF0cml4Q2xpZW50Q29udGV4dCIsInVzZUFzeW5jTWVtbyIsImZldGNoUHJvbWlzZXMiLCJtYXAiLCJldmVudElkIiwiYmF0Y2giLCJ1c2VTb3J0ZWRGZXRjaGVkUGlubmVkRXZlbnRzIiwidXNlTWVtbyIsInNvcnQiLCJhIiwiYiIsImdldFRzIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hvb2tzL3VzZVBpbm5lZEV2ZW50cy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IDIwMjQgTmV3IFZlY3RvciBMdGQuXG4gKiBDb3B5cmlnaHQgMjAyNCBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuICpcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuICogUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiAqL1xuXG5pbXBvcnQgeyB1c2VDYWxsYmFjaywgdXNlRWZmZWN0LCB1c2VNZW1vLCB1c2VTdGF0ZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHtcbiAgICBSb29tLFxuICAgIFJvb21FdmVudCxcbiAgICBSb29tU3RhdGVFdmVudCxcbiAgICBNYXRyaXhFdmVudCxcbiAgICBFdmVudFR5cGUsXG4gICAgUmVsYXRpb25UeXBlLFxuICAgIEV2ZW50VGltZWxpbmUsXG4gICAgTWF0cml4Q2xpZW50LFxufSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5pbXBvcnQgeyBsb2dnZXIgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbG9nZ2VyXCI7XG5cbmltcG9ydCB7IHVzZVR5cGVkRXZlbnRFbWl0dGVyIH0gZnJvbSBcIi4vdXNlRXZlbnRFbWl0dGVyXCI7XG5pbXBvcnQgeyBSZWFkUGluc0V2ZW50SWQgfSBmcm9tIFwiLi4vY29tcG9uZW50cy92aWV3cy9yaWdodF9wYW5lbC90eXBlc1wiO1xuaW1wb3J0IHsgdXNlTWF0cml4Q2xpZW50Q29udGV4dCB9IGZyb20gXCIuLi9jb250ZXh0cy9NYXRyaXhDbGllbnRDb250ZXh0XCI7XG5pbXBvcnQgeyB1c2VBc3luY01lbW8gfSBmcm9tIFwiLi91c2VBc3luY01lbW9cIjtcbmltcG9ydCBQaW5uaW5nVXRpbHMgZnJvbSBcIi4uL3V0aWxzL1Bpbm5pbmdVdGlsc1wiO1xuaW1wb3J0IHsgYmF0Y2ggfSBmcm9tIFwiLi4vdXRpbHMvcHJvbWlzZS50c1wiO1xuXG4vKipcbiAqIEdldCB0aGUgcGlubmVkIGV2ZW50IElEcyBmcm9tIGEgcm9vbS5cbiAqIFRoZSBudW1iZXIgb2YgcGlubmVkIGV2ZW50cyBpcyBsaW1pdGVkIHRvIDEwMC5cbiAqIEBwYXJhbSByb29tXG4gKi9cbmZ1bmN0aW9uIGdldFBpbm5lZEV2ZW50SWRzKHJvb20/OiBSb29tKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGV2ZW50SWRzOiBzdHJpbmdbXSA9XG4gICAgICAgIHJvb21cbiAgICAgICAgICAgID8uZ2V0TGl2ZVRpbWVsaW5lKClcbiAgICAgICAgICAgIC5nZXRTdGF0ZShFdmVudFRpbWVsaW5lLkZPUldBUkRTKVxuICAgICAgICAgICAgPy5nZXRTdGF0ZUV2ZW50cyhFdmVudFR5cGUuUm9vbVBpbm5lZEV2ZW50cywgXCJcIilcbiAgICAgICAgICAgID8uZ2V0Q29udGVudCgpPy5waW5uZWQgPz8gW107XG4gICAgLy8gTGltaXQgdGhlIG51bWJlciBvZiBwaW5uZWQgZXZlbnRzIHRvIDEwMFxuICAgIHJldHVybiBldmVudElkcy5zbGljZSgwLCAxMDApO1xufVxuXG4vKipcbiAqIEdldCB0aGUgcGlubmVkIGV2ZW50IElEcyBmcm9tIGEgcm9vbS5cbiAqIEBwYXJhbSByb29tXG4gKi9cbmV4cG9ydCBjb25zdCB1c2VQaW5uZWRFdmVudHMgPSAocm9vbT86IFJvb20pOiBzdHJpbmdbXSA9PiB7XG4gICAgY29uc3QgW3Bpbm5lZEV2ZW50cywgc2V0UGlubmVkRXZlbnRzXSA9IHVzZVN0YXRlPHN0cmluZ1tdPihnZXRQaW5uZWRFdmVudElkcyhyb29tKSk7XG5cbiAgICAvLyBVcGRhdGUgdGhlIHBpbm5lZCBldmVudHMgd2hlbiB0aGUgcm9vbSBzdGF0ZSBjaGFuZ2VzXG4gICAgLy8gRmlsdGVyIG91dCBldmVudHMgdGhhdCBhcmUgbm90IHBpbm5lZCBldmVudHNcbiAgICBjb25zdCB1cGRhdGUgPSB1c2VDYWxsYmFjayhcbiAgICAgICAgKGV2PzogTWF0cml4RXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChldiAmJiBldi5nZXRUeXBlKCkgIT09IEV2ZW50VHlwZS5Sb29tUGlubmVkRXZlbnRzKSByZXR1cm47XG4gICAgICAgICAgICBzZXRQaW5uZWRFdmVudHMoZ2V0UGlubmVkRXZlbnRJZHMocm9vbSkpO1xuICAgICAgICB9LFxuICAgICAgICBbcm9vbV0sXG4gICAgKTtcblxuICAgIHVzZVR5cGVkRXZlbnRFbWl0dGVyKHJvb20/LmdldExpdmVUaW1lbGluZSgpLmdldFN0YXRlKEV2ZW50VGltZWxpbmUuRk9SV0FSRFMpLCBSb29tU3RhdGVFdmVudC5FdmVudHMsIHVwZGF0ZSk7XG4gICAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgc2V0UGlubmVkRXZlbnRzKGdldFBpbm5lZEV2ZW50SWRzKHJvb20pKTtcbiAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgIHNldFBpbm5lZEV2ZW50cyhbXSk7XG4gICAgICAgIH07XG4gICAgfSwgW3Jvb21dKTtcbiAgICByZXR1cm4gcGlubmVkRXZlbnRzO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIHJlYWQgcGlubmVkIGV2ZW50IElEcyBmcm9tIGEgcm9vbS5cbiAqIEBwYXJhbSByb29tXG4gKi9cbmZ1bmN0aW9uIGdldFJlYWRQaW5uZWRFdmVudElkcyhyb29tPzogUm9vbSk6IFNldDxzdHJpbmc+IHtcbiAgICByZXR1cm4gbmV3IFNldChyb29tPy5nZXRBY2NvdW50RGF0YShSZWFkUGluc0V2ZW50SWQpPy5nZXRDb250ZW50KCk/LmV2ZW50X2lkcyA/PyBbXSk7XG59XG5cbi8qKlxuICogR2V0IHRoZSByZWFkIHBpbm5lZCBldmVudCBJRHMgZnJvbSBhIHJvb20uXG4gKiBAcGFyYW0gcm9vbVxuICovXG5leHBvcnQgY29uc3QgdXNlUmVhZFBpbm5lZEV2ZW50cyA9IChyb29tPzogUm9vbSk6IFNldDxzdHJpbmc+ID0+IHtcbiAgICBjb25zdCBbcmVhZFBpbm5lZEV2ZW50cywgc2V0UmVhZFBpbm5lZEV2ZW50c10gPSB1c2VTdGF0ZTxTZXQ8c3RyaW5nPj4obmV3IFNldCgpKTtcblxuICAgIC8vIFVwZGF0ZSB0aGUgcmVhZCBwaW5uZWQgZXZlbnRzIHdoZW4gdGhlIHJvb20gc3RhdGUgY2hhbmdlc1xuICAgIC8vIEZpbHRlciBvdXQgZXZlbnRzIHRoYXQgYXJlIG5vdCByZWFkIHBpbm5lZCBldmVudHNcbiAgICBjb25zdCB1cGRhdGUgPSB1c2VDYWxsYmFjayhcbiAgICAgICAgKGV2PzogTWF0cml4RXZlbnQpID0+IHtcbiAgICAgICAgICAgIGlmIChldiAmJiBldi5nZXRUeXBlKCkgIT09IFJlYWRQaW5zRXZlbnRJZCkgcmV0dXJuO1xuICAgICAgICAgICAgc2V0UmVhZFBpbm5lZEV2ZW50cyhnZXRSZWFkUGlubmVkRXZlbnRJZHMocm9vbSkpO1xuICAgICAgICB9LFxuICAgICAgICBbcm9vbV0sXG4gICAgKTtcblxuICAgIHVzZVR5cGVkRXZlbnRFbWl0dGVyKHJvb20sIFJvb21FdmVudC5BY2NvdW50RGF0YSwgdXBkYXRlKTtcbiAgICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgICAgICBzZXRSZWFkUGlubmVkRXZlbnRzKGdldFJlYWRQaW5uZWRFdmVudElkcyhyb29tKSk7XG4gICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICBzZXRSZWFkUGlubmVkRXZlbnRzKG5ldyBTZXQoKSk7XG4gICAgICAgIH07XG4gICAgfSwgW3Jvb21dKTtcbiAgICByZXR1cm4gcmVhZFBpbm5lZEV2ZW50cztcbn07XG5cbi8qKlxuICogRmV0Y2ggdGhlIHBpbm5lZCBldmVudFxuICogQHBhcmFtIHJvb21cbiAqIEBwYXJhbSBwaW5uZWRFdmVudElkXG4gKiBAcGFyYW0gY2xpXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGZldGNoUGlubmVkRXZlbnQocm9vbTogUm9vbSwgcGlubmVkRXZlbnRJZDogc3RyaW5nLCBjbGk6IE1hdHJpeENsaWVudCk6IFByb21pc2U8TWF0cml4RXZlbnQgfCBudWxsPiB7XG4gICAgY29uc3QgdGltZWxpbmVTZXQgPSByb29tLmdldFVuZmlsdGVyZWRUaW1lbGluZVNldCgpO1xuICAgIC8vIEdldCB0aGUgZXZlbnQgZnJvbSB0aGUgbG9jYWwgdGltZWxpbmVcbiAgICBjb25zdCBsb2NhbEV2ZW50ID0gdGltZWxpbmVTZXRcbiAgICAgICAgPy5nZXRUaW1lbGluZUZvckV2ZW50KHBpbm5lZEV2ZW50SWQpXG4gICAgICAgID8uZ2V0RXZlbnRzKClcbiAgICAgICAgLmZpbmQoKGUpID0+IGUuZ2V0SWQoKSA9PT0gcGlubmVkRXZlbnRJZCk7XG5cbiAgICAvLyBEZWNyeXB0IHRoZSBldmVudCBpZiBpdCdzIGVuY3J5cHRlZFxuICAgIC8vIENhbiBoYXBwZW4gd2hlbiB0aGUgdGFiIGlzIHJlZnJlc2hlZCBhbmQgdGhlIHBpbm5lZCBldmVudHMgY2FyZCBpcyBvcGVuZWQgZGlyZWN0bHlcbiAgICBpZiAobG9jYWxFdmVudD8uaXNFbmNyeXB0ZWQoKSkge1xuICAgICAgICBhd2FpdCBjbGkuZGVjcnlwdEV2ZW50SWZOZWVkZWQobG9jYWxFdmVudCwgeyBlbWl0OiBmYWxzZSB9KTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgZXZlbnQgaXMgYXZhaWxhYmxlIGxvY2FsbHksIHJldHVybiBpdCBpZiBpdCdzIHBpbm5hYmxlXG4gICAgLy8gb3IgaWYgaXQncyByZWRhY3RlZCAodG8gc2hvdyB0aGUgcmVkYWN0ZWQgZXZlbnQgYW5kIHRvIGJlIGFibGUgdG8gdW5waW4gaXQpXG4gICAgLy8gT3RoZXJ3aXNlLCByZXR1cm4gbnVsbFxuICAgIGlmIChsb2NhbEV2ZW50KSByZXR1cm4gUGlubmluZ1V0aWxzLmlzVW5waW5uYWJsZShsb2NhbEV2ZW50KSA/IGxvY2FsRXZlbnQgOiBudWxsO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgLy8gVGhlIGV2ZW50IGlzIG5vdCBhdmFpbGFibGUgbG9jYWxseSwgc28gd2UgZmV0Y2ggdGhlIGV2ZW50IGFuZCBsYXRlc3QgZWRpdCBpbiBwYXJhbGxlbFxuICAgICAgICBjb25zdCBbXG4gICAgICAgICAgICBldkpzb24sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgZXZlbnRzOiBbZWRpdF0sXG4gICAgICAgICAgICB9LFxuICAgICAgICBdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICAgICAgY2xpLmZldGNoUm9vbUV2ZW50KHJvb20ucm9vbUlkLCBwaW5uZWRFdmVudElkKSxcbiAgICAgICAgICAgIGNsaS5yZWxhdGlvbnMocm9vbS5yb29tSWQsIHBpbm5lZEV2ZW50SWQsIFJlbGF0aW9uVHlwZS5SZXBsYWNlLCBudWxsLCB7IGxpbWl0OiAxIH0pLFxuICAgICAgICBdKTtcblxuICAgICAgICBjb25zdCBldmVudCA9IG5ldyBNYXRyaXhFdmVudChldkpzb24pO1xuXG4gICAgICAgIC8vIERlY3J5cHQgdGhlIGV2ZW50IGlmIGl0J3MgZW5jcnlwdGVkXG4gICAgICAgIGlmIChldmVudC5pc0VuY3J5cHRlZCgpKSB7XG4gICAgICAgICAgICBhd2FpdCBjbGkuZGVjcnlwdEV2ZW50SWZOZWVkZWQoZXZlbnQsIHsgZW1pdDogZmFsc2UgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIYW5kbGUgcG9sbCBldmVudHNcbiAgICAgICAgYXdhaXQgcm9vbS5wcm9jZXNzUG9sbEV2ZW50cyhbZXZlbnRdKTtcblxuICAgICAgICBjb25zdCBzZW5kZXJVc2VySWQgPSBldmVudC5nZXRTZW5kZXIoKTtcbiAgICAgICAgaWYgKHNlbmRlclVzZXJJZCAmJiBQaW5uaW5nVXRpbHMuaXNVbnBpbm5hYmxlKGV2ZW50KSkge1xuICAgICAgICAgICAgLy8gSW5qZWN0IHNlbmRlciBpbmZvcm1hdGlvblxuICAgICAgICAgICAgZXZlbnQuc2VuZGVyID0gcm9vbS5nZXRNZW1iZXIoc2VuZGVyVXNlcklkKTtcbiAgICAgICAgICAgIC8vIEFsc28gaW5qZWN0IGFueSBlZGl0cyB3ZSd2ZSBmb3VuZFxuICAgICAgICAgICAgaWYgKGVkaXQpIGV2ZW50Lm1ha2VSZXBsYWNlZChlZGl0KTtcblxuICAgICAgICAgICAgcmV0dXJuIGV2ZW50O1xuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihgRXJyb3IgbG9va2luZyB1cCBwaW5uZWQgZXZlbnQgJHtwaW5uZWRFdmVudElkfSBpbiByb29tICR7cm9vbS5yb29tSWR9YCk7XG4gICAgICAgIGxvZ2dlci5lcnJvcihlcnIpO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBGZXRjaCB0aGUgcGlubmVkIGV2ZW50c1xuICogQHBhcmFtIHJvb21cbiAqIEBwYXJhbSBwaW5uZWRFdmVudElkc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlRmV0Y2hlZFBpbm5lZEV2ZW50cyhyb29tOiBSb29tLCBwaW5uZWRFdmVudElkczogc3RyaW5nW10pOiBBcnJheTxNYXRyaXhFdmVudCB8IG51bGw+IHwgbnVsbCB7XG4gICAgY29uc3QgY2xpID0gdXNlTWF0cml4Q2xpZW50Q29udGV4dCgpO1xuXG4gICAgcmV0dXJuIHVzZUFzeW5jTWVtbyhcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZmV0Y2hQcm9taXNlcyA9IHBpbm5lZEV2ZW50SWRzLm1hcCgoZXZlbnRJZCkgPT4gKCkgPT4gZmV0Y2hQaW5uZWRFdmVudChyb29tLCBldmVudElkLCBjbGkpKTtcbiAgICAgICAgICAgIC8vIEZldGNoIHRoZSBwaW5uZWQgZXZlbnRzIGluIGJhdGNoZXMgb2YgMTBcbiAgICAgICAgICAgIHJldHVybiBiYXRjaChmZXRjaFByb21pc2VzLCAxMCk7XG4gICAgICAgIH0sXG4gICAgICAgIFtjbGksIHJvb20sIHBpbm5lZEV2ZW50SWRzXSxcbiAgICAgICAgbnVsbCxcbiAgICApO1xufVxuXG4vKipcbiAqIEZldGNoIHRoZSBwaW5uZWQgZXZlbnRzIGFuZCBzb3J0IHRoZW0gYnkgZnJvbSB0aGUgb2xkZXN0IHRvIHRoZSBuZXdlc3RcbiAqIFRoZSBvcmRlciBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBldmVudCB0aW1lc3RhbXBcbiAqIEBwYXJhbSByb29tXG4gKiBAcGFyYW0gcGlubmVkRXZlbnRJZHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZVNvcnRlZEZldGNoZWRQaW5uZWRFdmVudHMocm9vbTogUm9vbSwgcGlubmVkRXZlbnRJZHM6IHN0cmluZ1tdKTogQXJyYXk8TWF0cml4RXZlbnQgfCBudWxsPiB7XG4gICAgY29uc3QgcGlubmVkRXZlbnRzID0gdXNlRmV0Y2hlZFBpbm5lZEV2ZW50cyhyb29tLCBwaW5uZWRFdmVudElkcyk7XG4gICAgcmV0dXJuIHVzZU1lbW8oKCkgPT4ge1xuICAgICAgICBpZiAoIXBpbm5lZEV2ZW50cykgcmV0dXJuIFtdO1xuXG4gICAgICAgIHJldHVybiBwaW5uZWRFdmVudHMuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgICAgaWYgKCFhKSByZXR1cm4gLTE7XG4gICAgICAgICAgICBpZiAoIWIpIHJldHVybiAxO1xuICAgICAgICAgICAgcmV0dXJuIGEuZ2V0VHMoKSAtIGIuZ2V0VHMoKTtcbiAgICAgICAgfSk7XG4gICAgfSwgW3Bpbm5lZEV2ZW50c10pO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFRQSxJQUFBQSxNQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFELE9BQUE7QUFVQSxJQUFBRSxPQUFBLEdBQUFGLE9BQUE7QUFFQSxJQUFBRyxnQkFBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksTUFBQSxHQUFBSixPQUFBO0FBQ0EsSUFBQUssb0JBQUEsR0FBQUwsT0FBQTtBQUNBLElBQUFNLGFBQUEsR0FBQU4sT0FBQTtBQUNBLElBQUFPLGFBQUEsR0FBQUMsc0JBQUEsQ0FBQVIsT0FBQTtBQUNBLElBQUFTLFFBQUEsR0FBQVQsT0FBQTtBQTFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVNVLGlCQUFpQkEsQ0FBQ0MsSUFBVyxFQUFZO0VBQzlDLE1BQU1DLFFBQWtCLEdBQ3BCRCxJQUFJLEVBQ0VFLGVBQWUsQ0FBQyxDQUFDLENBQ2xCQyxRQUFRLENBQUNDLHFCQUFhLENBQUNDLFFBQVEsQ0FBQyxFQUMvQkMsY0FBYyxDQUFDQyxpQkFBUyxDQUFDQyxnQkFBZ0IsRUFBRSxFQUFFLENBQUMsRUFDOUNDLFVBQVUsQ0FBQyxDQUFDLEVBQUVDLE1BQU0sSUFBSSxFQUFFO0VBQ3BDO0VBQ0EsT0FBT1QsUUFBUSxDQUFDVSxLQUFLLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQztBQUNqQzs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU1DLGVBQWUsR0FBSVosSUFBVyxJQUFlO0VBQ3RELE1BQU0sQ0FBQ2EsWUFBWSxFQUFFQyxlQUFlLENBQUMsR0FBRyxJQUFBQyxlQUFRLEVBQVdoQixpQkFBaUIsQ0FBQ0MsSUFBSSxDQUFDLENB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