matrix-react-sdk
Version:
SDK for matrix.org using React
124 lines (119 loc) • 18.9 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.ActiveWidgetStoreEvent = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _events = _interopRequireDefault(require("events"));
var _matrix = require("matrix-js-sdk/src/matrix");
var _MatrixClientPeg = require("../MatrixClientPeg");
var _WidgetUtils = _interopRequireDefault(require("../utils/WidgetUtils"));
var _WidgetMessagingStore = require("./widgets/WidgetMessagingStore");
/*
Copyright 2018-2024 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
let ActiveWidgetStoreEvent = exports.ActiveWidgetStoreEvent = /*#__PURE__*/function (ActiveWidgetStoreEvent) {
ActiveWidgetStoreEvent["Persistence"] = "persistence";
ActiveWidgetStoreEvent["Dock"] = "dock";
ActiveWidgetStoreEvent["Undock"] = "undock";
return ActiveWidgetStoreEvent;
}({});
/**
* Stores information about the widgets active in the app right now:
* * What widget is set to remain always-on-screen, if any
* Only one widget may be 'always on screen' at any one time.
* * Reference counts to keep track of whether a widget is kept docked or alive
* by any components
*/
class ActiveWidgetStore extends _events.default {
constructor(...args) {
super(...args);
(0, _defineProperty2.default)(this, "persistentWidgetId", null);
(0, _defineProperty2.default)(this, "persistentRoomId", null);
(0, _defineProperty2.default)(this, "dockedWidgetsByUid", new Map());
(0, _defineProperty2.default)(this, "onRoomStateEvents", (ev, {
roomId
}) => {
// XXX: This listens for state events in order to remove the active widget.
// Everything else relies on views listening for events and calling setters
// on this class which is terrible. This store should just listen for events
// and keep itself up to date.
// TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
if (ev.getType() === "im.vector.modular.widgets") {
this.destroyPersistentWidget(ev.getStateKey(), roomId);
}
});
}
static get instance() {
if (!ActiveWidgetStore.internalInstance) {
ActiveWidgetStore.internalInstance = new ActiveWidgetStore();
}
return ActiveWidgetStore.internalInstance;
}
start() {
_MatrixClientPeg.MatrixClientPeg.safeGet().on(_matrix.RoomStateEvent.Events, this.onRoomStateEvents);
}
stop() {
_MatrixClientPeg.MatrixClientPeg.get()?.removeListener(_matrix.RoomStateEvent.Events, this.onRoomStateEvents);
}
destroyPersistentWidget(widgetId, roomId) {
if (!this.getWidgetPersistence(widgetId, roomId)) return;
// We first need to set the widget persistence to false
this.setWidgetPersistence(widgetId, roomId, false);
// Then we can stop the messaging. Stopping the messaging emits - we might move the widget out of sight.
// If we would do this before setting the persistence to false, it would stay in the DOM (hidden) because
// its still persistent. We need to avoid this.
_WidgetMessagingStore.WidgetMessagingStore.instance.stopMessagingByUid(_WidgetUtils.default.calcWidgetUid(widgetId, roomId ?? undefined));
}
setWidgetPersistence(widgetId, roomId, val) {
const isPersisted = this.getWidgetPersistence(widgetId, roomId);
if (isPersisted && !val) {
this.persistentWidgetId = null;
this.persistentRoomId = null;
} else if (!isPersisted && val) {
this.persistentWidgetId = widgetId;
this.persistentRoomId = roomId;
}
this.emit(ActiveWidgetStoreEvent.Persistence);
}
getWidgetPersistence(widgetId, roomId) {
return this.persistentWidgetId === widgetId && this.persistentRoomId === roomId;
}
getPersistentWidgetId() {
return this.persistentWidgetId;
}
getPersistentRoomId() {
return this.persistentRoomId;
}
// Registers the given widget as being docked somewhere in the UI (not a PiP),
// to allow its lifecycle to be tracked.
dockWidget(widgetId, roomId) {
const uid = _WidgetUtils.default.calcWidgetUid(widgetId, roomId ?? undefined);
const refs = this.dockedWidgetsByUid.get(uid) ?? 0;
this.dockedWidgetsByUid.set(uid, refs + 1);
if (refs === 0) this.emit(ActiveWidgetStoreEvent.Dock);
}
undockWidget(widgetId, roomId) {
const uid = _WidgetUtils.default.calcWidgetUid(widgetId, roomId ?? undefined);
const refs = this.dockedWidgetsByUid.get(uid);
if (refs) this.dockedWidgetsByUid.set(uid, refs - 1);
if (refs === 1) this.emit(ActiveWidgetStoreEvent.Undock);
}
// Determines whether the given widget is docked anywhere in the UI (not a PiP)
isDocked(widgetId, roomId) {
const uid = _WidgetUtils.default.calcWidgetUid(widgetId, roomId ?? undefined);
const refs = this.dockedWidgetsByUid.get(uid) ?? 0;
return refs > 0;
}
// Determines whether the given widget is being kept alive in the UI, including PiPs
isLive(widgetId, roomId) {
return this.isDocked(widgetId, roomId) || this.getWidgetPersistence(widgetId, roomId);
}
}
exports.default = ActiveWidgetStore;
(0, _defineProperty2.default)(ActiveWidgetStore, "internalInstance", void 0);
window.mxActiveWidgetStore = ActiveWidgetStore.instance;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfZXZlbnRzIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsInJlcXVpcmUiLCJfbWF0cml4IiwiX01hdHJpeENsaWVudFBlZyIsIl9XaWRnZXRVdGlscyIsIl9XaWRnZXRNZXNzYWdpbmdTdG9yZSIsIkFjdGl2ZVdpZGdldFN0b3JlRXZlbnQiLCJleHBvcnRzIiwiQWN0aXZlV2lkZ2V0U3RvcmUiLCJFdmVudEVtaXR0ZXIiLCJjb25zdHJ1Y3RvciIsImFyZ3MiLCJfZGVmaW5lUHJvcGVydHkyIiwiZGVmYXVsdCIsIk1hcCIsImV2Iiwicm9vbUlkIiwiZ2V0VHlwZSIsImRlc3Ryb3lQZXJzaXN0ZW50V2lkZ2V0IiwiZ2V0U3RhdGVLZXkiLCJpbnN0YW5jZSIsImludGVybmFsSW5zdGFuY2UiLCJzdGFydCIsIk1hdHJpeENsaWVudFBlZyIsInNhZmVHZXQiLCJvbiIsIlJvb21TdGF0ZUV2ZW50IiwiRXZlbnRzIiwib25Sb29tU3RhdGVFdmVudHMiLCJzdG9wIiwiZ2V0IiwicmVtb3ZlTGlzdGVuZXIiLCJ3aWRnZXRJZCIsImdldFdpZGdldFBlcnNpc3RlbmNlIiwic2V0V2lkZ2V0UGVyc2lzdGVuY2UiLCJXaWRnZXRNZXNzYWdpbmdTdG9yZSIsInN0b3BNZXNzYWdpbmdCeVVpZCIsIldpZGdldFV0aWxzIiwiY2FsY1dpZGdldFVpZCIsInVuZGVmaW5lZCIsInZhbCIsImlzUGVyc2lzdGVkIiwicGVyc2lzdGVudFdpZGdldElkIiwicGVyc2lzdGVudFJvb21JZCIsImVtaXQiLCJQZXJzaXN0ZW5jZSIsImdldFBlcnNpc3RlbnRXaWRnZXRJZCIsImdldFBlcnNpc3RlbnRSb29tSWQiLCJkb2NrV2lkZ2V0IiwidWlkIiwicmVmcyIsImRvY2tlZFdpZGdldHNCeVVpZCIsInNldCIsIkRvY2siLCJ1bmRvY2tXaWRnZXQiLCJVbmRvY2siLCJpc0RvY2tlZCIsImlzTGl2ZSIsIndpbmRvdyIsIm14QWN0aXZlV2lkZ2V0U3RvcmUiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RvcmVzL0FjdGl2ZVdpZGdldFN0b3JlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qXG5Db3B5cmlnaHQgMjAxOC0yMDI0IE5ldyBWZWN0b3IgTHRkLlxuXG5TUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQUdQTC0zLjAtb25seSBPUiBHUEwtMy4wLW9ubHlcblBsZWFzZSBzZWUgTElDRU5TRSBmaWxlcyBpbiB0aGUgcmVwb3NpdG9yeSByb290IGZvciBmdWxsIGRldGFpbHMuXG4qL1xuXG5pbXBvcnQgRXZlbnRFbWl0dGVyIGZyb20gXCJldmVudHNcIjtcbmltcG9ydCB7IE1hdHJpeEV2ZW50LCBSb29tU3RhdGVFdmVudCwgUm9vbVN0YXRlIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL21hdHJpeFwiO1xuXG5pbXBvcnQgeyBNYXRyaXhDbGllbnRQZWcgfSBmcm9tIFwiLi4vTWF0cml4Q2xpZW50UGVnXCI7XG5pbXBvcnQgV2lkZ2V0VXRpbHMgZnJvbSBcIi4uL3V0aWxzL1dpZGdldFV0aWxzXCI7XG5pbXBvcnQgeyBXaWRnZXRNZXNzYWdpbmdTdG9yZSB9IGZyb20gXCIuL3dpZGdldHMvV2lkZ2V0TWVzc2FnaW5nU3RvcmVcIjtcblxuZXhwb3J0IGVudW0gQWN0aXZlV2lkZ2V0U3RvcmVFdmVudCB7XG4gICAgLy8gSW5kaWNhdGVzIGEgY2hhbmdlIGluIHRoZSBjdXJyZW50bHkgcGVyc2lzdGVudCB3aWRnZXRcbiAgICBQZXJzaXN0ZW5jZSA9IFwicGVyc2lzdGVuY2VcIixcbiAgICAvLyBJbmRpY2F0ZSBjaGFuZ2VzIGluIHRoZSBjdXJyZW50bHkgZG9ja2VkIHdpZGdldHNcbiAgICBEb2NrID0gXCJkb2NrXCIsXG4gICAgVW5kb2NrID0gXCJ1bmRvY2tcIixcbn1cblxuLyoqXG4gKiBTdG9yZXMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHdpZGdldHMgYWN0aXZlIGluIHRoZSBhcHAgcmlnaHQgbm93OlxuICogICogV2hhdCB3aWRnZXQgaXMgc2V0IHRvIHJlbWFpbiBhbHdheXMtb24tc2NyZWVuLCBpZiBhbnlcbiAqICAgIE9ubHkgb25lIHdpZGdldCBtYXkgYmUgJ2Fsd2F5cyBvbiBzY3JlZW4nIGF0IGFueSBvbmUgdGltZS5cbiAqICAqIFJlZmVyZW5jZSBjb3VudHMgdG8ga2VlcCB0cmFjayBvZiB3aGV0aGVyIGEgd2lkZ2V0IGlzIGtlcHQgZG9ja2VkIG9yIGFsaXZlXG4gKiAgICBieSBhbnkgY29tcG9uZW50c1xuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBY3RpdmVXaWRnZXRTdG9yZSBleHRlbmRzIEV2ZW50RW1pdHRlciB7XG4gICAgcHJpdmF0ZSBzdGF0aWMgaW50ZXJuYWxJbnN0YW5jZTogQWN0aXZlV2lkZ2V0U3RvcmU7XG4gICAgcHJpdmF0ZSBwZXJzaXN0ZW50V2lkZ2V0SWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgcGVyc2lzdGVudFJvb21JZDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSBkb2NrZWRXaWRnZXRzQnlVaWQgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuXG4gICAgcHVibGljIHN0YXRpYyBnZXQgaW5zdGFuY2UoKTogQWN0aXZlV2lkZ2V0U3RvcmUge1xuICAgICAgICBpZiAoIUFjdGl2ZVdpZGdldFN0b3JlLmludGVybmFsSW5zdGFuY2UpIHtcbiAgICAgICAgICAgIEFjdGl2ZVdpZGdldFN0b3JlLmludGVybmFsSW5zdGFuY2UgPSBuZXcgQWN0aXZlV2lkZ2V0U3RvcmUoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gQWN0aXZlV2lkZ2V0U3RvcmUuaW50ZXJuYWxJbnN0YW5jZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhcnQoKTogdm9pZCB7XG4gICAgICAgIE1hdHJpeENsaWVudFBlZy5zYWZlR2V0KCkub24oUm9vbVN0YXRlRXZlbnQuRXZlbnRzLCB0aGlzLm9uUm9vbVN0YXRlRXZlbnRzKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RvcCgpOiB2b2lkIHtcbiAgICAgICAgTWF0cml4Q2xpZW50UGVnLmdldCgpPy5yZW1vdmVMaXN0ZW5lcihSb29tU3RhdGVFdmVudC5FdmVudHMsIHRoaXMub25Sb29tU3RhdGVFdmVudHMpO1xuICAgIH1cblxuICAgIHByaXZhdGUgb25Sb29tU3RhdGVFdmVudHMgPSAoZXY6IE1hdHJpeEV2ZW50LCB7IHJvb21JZCB9OiBSb29tU3RhdGUpOiB2b2lkID0+IHtcbiAgICAgICAgLy8gWFhYOiBUaGlzIGxpc3RlbnMgZm9yIHN0YXRlIGV2ZW50cyBpbiBvcmRlciB0byByZW1vdmUgdGhlIGFjdGl2ZSB3aWRnZXQuXG4gICAgICAgIC8vIEV2ZXJ5dGhpbmcgZWxzZSByZWxpZXMgb24gdmlld3MgbGlzdGVuaW5nIGZvciBldmVudHMgYW5kIGNhbGxpbmcgc2V0dGVyc1xuICAgICAgICAvLyBvbiB0aGlzIGNsYXNzIHdoaWNoIGlzIHRlcnJpYmxlLiBUaGlzIHN0b3JlIHNob3VsZCBqdXN0IGxpc3RlbiBmb3IgZXZlbnRzXG4gICAgICAgIC8vIGFuZCBrZWVwIGl0c2VsZiB1cCB0byBkYXRlLlxuICAgICAgICAvLyBUT0RPOiBFbmFibGUgc3VwcG9ydCBmb3IgbS53aWRnZXQgZXZlbnQgdHlwZSAoaHR0cHM6Ly9naXRodWIuY29tL3ZlY3Rvci1pbS9lbGVtZW50LXdlYi9pc3N1ZXMvMTMxMTEpXG4gICAgICAgIGlmIChldi5nZXRUeXBlKCkgPT09IFwiaW0udmVjdG9yLm1vZHVsYXIud2lkZ2V0c1wiKSB7XG4gICAgICAgICAgICB0aGlzLmRlc3Ryb3lQZXJzaXN0ZW50V2lkZ2V0KGV2LmdldFN0YXRlS2V5KCkhLCByb29tSWQpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHB1YmxpYyBkZXN0cm95UGVyc2lzdGVudFdpZGdldCh3aWRnZXRJZDogc3RyaW5nLCByb29tSWQ6IHN0cmluZyB8IG51bGwpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmdldFdpZGdldFBlcnNpc3RlbmNlKHdpZGdldElkLCByb29tSWQpKSByZXR1cm47XG4gICAgICAgIC8vIFdlIGZpcnN0IG5lZWQgdG8gc2V0IHRoZSB3aWRnZXQgcGVyc2lzdGVuY2UgdG8gZmFsc2VcbiAgICAgICAgdGhpcy5zZXRXaWRnZXRQZXJzaXN0ZW5jZSh3aWRnZXRJZCwgcm9vbUlkLCBmYWxzZSk7XG4gICAgICAgIC8vIFRoZW4gd2UgY2FuIHN0b3AgdGhlIG1lc3NhZ2luZy4gU3RvcHBpbmcgdGhlIG1lc3NhZ2luZyBlbWl0cyAtIHdlIG1pZ2h0IG1vdmUgdGhlIHdpZGdldCBvdXQgb2Ygc2lnaHQuXG4gICAgICAgIC8vIElmIHdlIHdvdWxkIGRvIHRoaXMgYmVmb3JlIHNldHRpbmcgdGhlIHBlcnNpc3RlbmNlIHRvIGZhbHNlLCBpdCB3b3VsZCBzdGF5IGluIHRoZSBET00gKGhpZGRlbikgYmVjYXVzZVxuICAgICAgICAvLyBpdHMgc3RpbGwgcGVyc2lzdGVudC4gV2UgbmVlZCB0byBhdm9pZCB0aGlzLlxuICAgICAgICBXaWRnZXRNZXNzYWdpbmdTdG9yZS5pbnN0YW5jZS5zdG9wTWVzc2FnaW5nQnlVaWQoV2lkZ2V0VXRpbHMuY2FsY1dpZGdldFVpZCh3aWRnZXRJZCwgcm9vbUlkID8/IHVuZGVmaW5lZCkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRXaWRnZXRQZXJzaXN0ZW5jZSh3aWRnZXRJZDogc3RyaW5nLCByb29tSWQ6IHN0cmluZyB8IG51bGwsIHZhbDogYm9vbGVhbik6IHZvaWQge1xuICAgICAgICBjb25zdCBpc1BlcnNpc3RlZCA9IHRoaXMuZ2V0V2lkZ2V0UGVyc2lzdGVuY2Uod2lkZ2V0SWQsIHJvb21JZCk7XG5cbiAgICAgICAgaWYgKGlzUGVyc2lzdGVkICYmICF2YWwpIHtcbiAgICAgICAgICAgIHRoaXMucGVyc2lzdGVudFdpZGdldElkID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMucGVyc2lzdGVudFJvb21JZCA9IG51bGw7XG4gICAgICAgIH0gZWxzZSBpZiAoIWlzUGVyc2lzdGVkICYmIHZhbCkge1xuICAgICAgICAgICAgdGhpcy5wZXJzaXN0ZW50V2lkZ2V0SWQgPSB3aWRnZXRJZDtcbiAgICAgICAgICAgIHRoaXMucGVyc2lzdGVudFJvb21JZCA9IHJvb21JZDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVtaXQoQWN0aXZlV2lkZ2V0U3RvcmVFdmVudC5QZXJzaXN0ZW5jZSk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldFdpZGdldFBlcnNpc3RlbmNlKHdpZGdldElkOiBzdHJpbmcsIHJvb21JZDogc3RyaW5nIHwgbnVsbCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5wZXJzaXN0ZW50V2lkZ2V0SWQgPT09IHdpZGdldElkICYmIHRoaXMucGVyc2lzdGVudFJvb21JZCA9PT0gcm9vbUlkO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRQZXJzaXN0ZW50V2lkZ2V0SWQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgICAgIHJldHVybiB0aGlzLnBlcnNpc3RlbnRXaWRnZXRJZDtcbiAgICB9XG5cbiAgICBwdWJsaWMgZ2V0UGVyc2lzdGVudFJvb21JZCgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucGVyc2lzdGVudFJvb21JZDtcbiAgICB9XG5cbiAgICAvLyBSZWdpc3RlcnMgdGhlIGdpdmVuIHdpZGdldCBhcyBiZWluZyBkb2NrZWQgc29tZXdoZXJlIGluIHRoZSBVSSAobm90IGEgUGlQKSxcbiAgICAvLyB0byBhbGxvdyBpdHMgbGlmZWN5Y2xlIHRvIGJlIHRyYWNrZWQuXG4gICAgcHVibGljIGRvY2tXaWRnZXQod2lkZ2V0SWQ6IHN0cmluZywgcm9vbUlkOiBzdHJpbmcgfCBudWxsKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHVpZCA9IFdpZGdldFV0aWxzLmNhbGNXaWRnZXRVaWQod2lkZ2V0SWQsIHJvb21JZCA/PyB1bmRlZmluZWQpO1xuICAgICAgICBjb25zdCByZWZzID0gdGhpcy5kb2NrZWRXaWRnZXRzQnlVaWQuZ2V0KHVpZCkgPz8gMDtcbiAgICAgICAgdGhpcy5kb2NrZWRXaWRnZXRzQnlVaWQuc2V0KHVpZCwgcmVmcyArIDEpO1xuICAgICAgICBpZiAocmVmcyA9PT0gMCkgdGhpcy5lbWl0KEFjdGl2ZVdpZGdldFN0b3JlRXZlbnQuRG9jayk7XG4gICAgfVxuXG4gICAgcHVibGljIHVuZG9ja1dpZGdldCh3aWRnZXRJZDogc3RyaW5nLCByb29tSWQ6IHN0cmluZyB8IG51bGwpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdWlkID0gV2lkZ2V0VXRpbHMuY2FsY1dpZGdldFVpZCh3aWRnZXRJZCwgcm9vbUlkID8/IHVuZGVmaW5lZCk7XG4gICAgICAgIGNvbnN0IHJlZnMgPSB0aGlzLmRvY2tlZFdpZGdldHNCeVVpZC5nZXQodWlkKTtcbiAgICAgICAgaWYgKHJlZnMpIHRoaXMuZG9ja2VkV2lkZ2V0c0J5VWlkLnNldCh1aWQsIHJlZnMgLSAxKTtcbiAgICAgICAgaWYgKHJlZnMgPT09IDEpIHRoaXMuZW1pdChBY3RpdmVXaWRnZXRTdG9yZUV2ZW50LlVuZG9jayk7XG4gICAgfVxuXG4gICAgLy8gRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBnaXZlbiB3aWRnZXQgaXMgZG9ja2VkIGFueXdoZXJlIGluIHRoZSBVSSAobm90IGEgUGlQKVxuICAgIHB1YmxpYyBpc0RvY2tlZCh3aWRnZXRJZDogc3RyaW5nLCByb29tSWQ6IHN0cmluZyB8IG51bGwpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgdWlkID0gV2lkZ2V0VXRpbHMuY2FsY1dpZGdldFVpZCh3aWRnZXRJZCwgcm9vbUlkID8/IHVuZGVmaW5lZCk7XG4gICAgICAgIGNvbnN0IHJlZnMgPSB0aGlzLmRvY2tlZFdpZGdldHNCeVVpZC5nZXQodWlkKSA/PyAwO1xuICAgICAgICByZXR1cm4gcmVmcyA+IDA7XG4gICAgfVxuXG4gICAgLy8gRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBnaXZlbiB3aWRnZXQgaXMgYmVpbmcga2VwdCBhbGl2ZSBpbiB0aGUgVUksIGluY2x1ZGluZyBQaVBzXG4gICAgcHVibGljIGlzTGl2ZSh3aWRnZXRJZDogc3RyaW5nLCByb29tSWQ6IHN0cmluZyB8IG51bGwpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNEb2NrZWQod2lkZ2V0SWQsIHJvb21JZCkgfHwgdGhpcy5nZXRXaWRnZXRQZXJzaXN0ZW5jZSh3aWRnZXRJZCwgcm9vbUlkKTtcbiAgICB9XG59XG5cbndpbmRvdy5teEFjdGl2ZVdpZGdldFN0b3JlID0gQWN0aXZlV2lkZ2V0U3RvcmUuaW5zdGFuY2U7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBT0EsSUFBQUEsT0FBQSxHQUFBQyxzQkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsT0FBQSxHQUFBRCxPQUFBO0FBRUEsSUFBQUUsZ0JBQUEsR0FBQUYsT0FBQTtBQUNBLElBQUFHLFlBQUEsR0FBQUosc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFJLHFCQUFBLEdBQUFKLE9BQUE7QUFaQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFMQSxJQWNZSyxzQkFBc0IsR0FBQUMsT0FBQSxDQUFBRCxzQkFBQSwwQkFBdEJBLHNCQUFzQjtFQUF0QkEsc0JBQXNCO0VBQXRCQSxzQkFBc0I7RUFBdEJBLHNCQUFzQjtFQUFBLE9BQXRCQSxzQkFBc0I7QUFBQTtBQVFsQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLE1BQU1FLGlCQUFpQixTQUFTQyxlQUFZLENBQUM7RUFBQUMsWUFBQSxHQUFBQyxJQUFBO0lBQUEsU0FBQUEsSUFBQTtJQUFBLElBQUFDLGdCQUFBLENBQUFDLE9BQUEsOEJBRVosSUFBSTtJQUFBLElBQUFELGdCQUFBLENBQUFDLE9BQUEsNEJBQ04sSUFBSTtJQUFBLElBQUFELGdCQUFBLENBQUFDLE9BQUEsOEJBQ2pCLElBQUlDLEdBQUcsQ0FBaUIsQ0FBQztJQUFBLElBQUFGLGdCQUFBLENBQUFDLE9BQUEsNkJBaUIxQixDQUFDRSxFQUFlLEVBQUU7TUFBRUM7SUFBa0IsQ0FBQyxLQUFXO01BQzFFO01BQ0E7TUFDQTtNQUNBO01BQ0E7TUFDQSxJQUFJRCxFQUFFLENBQUNF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