matrix-react-sdk
Version:
SDK for matrix.org using React
122 lines (115 loc) • 19 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 _matrix = require("matrix-js-sdk/src/matrix");
var _utils = require("matrix-js-sdk/src/utils");
var _MatrixClientBackedSettingsHandler = _interopRequireDefault(require("./MatrixClientBackedSettingsHandler"));
var _objects = require("../../utils/objects");
var _SettingLevel = require("../SettingLevel");
/*
Copyright 2024 New Vector Ltd.
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
Copyright 2017 Travis Ralston
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
const DEFAULT_SETTINGS_EVENT_TYPE = "im.vector.web.settings";
const PREVIEW_URLS_EVENT_TYPE = "org.matrix.room.preview_urls";
/**
* Gets and sets settings at the "room" level.
*/
class RoomSettingsHandler extends _MatrixClientBackedSettingsHandler.default {
constructor(watchers) {
super();
(0, _defineProperty2.default)(this, "onEvent", (event, state, prevEvent) => {
const roomId = event.getRoomId();
const room = this.client.getRoom(roomId);
// Note: in tests and during the encryption setup on initial load we might not have
// rooms in the store, so we just quietly ignore the problem. If we log it then we'll
// just end up spamming the logs a few thousand times. It is perfectly fine for us
// to ignore the problem as the app will not have loaded enough to care yet.
if (!room) return;
// ignore state updates which are not current
if (room && state !== room.currentState) return;
if (event.getType() === "org.matrix.room.preview_urls") {
let val = event.getContent()["disable"];
if (typeof val !== "boolean") {
val = null;
} else {
val = !val;
}
this.watchers.notifyUpdate("urlPreviewsEnabled", roomId, _SettingLevel.SettingLevel.ROOM, val);
} else if (event.getType() === DEFAULT_SETTINGS_EVENT_TYPE) {
// Figure out what changed and fire those updates
const prevContent = prevEvent?.getContent() ?? {};
const changedSettings = (0, _objects.objectKeyChanges)(prevContent, event.getContent());
for (const settingName of changedSettings) {
this.watchers.notifyUpdate(settingName, roomId, _SettingLevel.SettingLevel.ROOM, event.getContent()[settingName]);
}
}
});
this.watchers = watchers;
}
initMatrixClient(oldClient, newClient) {
if (oldClient) {
oldClient.removeListener(_matrix.RoomStateEvent.Events, this.onEvent);
}
newClient.on(_matrix.RoomStateEvent.Events, this.onEvent);
}
getValue(settingName, roomId) {
// Special case URL previews
if (settingName === "urlPreviewsEnabled") {
const content = this.getSettings(roomId, "org.matrix.room.preview_urls") || {};
// Check to make sure that we actually got a boolean
if (typeof content["disable"] !== "boolean") return null;
return !content["disable"];
}
const settings = this.getSettings(roomId) || {};
return settings[settingName];
}
// helper function to send state event then await it being echoed back
async sendStateEvent(roomId, eventType, field, value) {
const content = this.getSettings(roomId, eventType) || {};
content[field] = value;
const {
event_id: eventId
} = await this.client.sendStateEvent(roomId, eventType, content);
const deferred = (0, _utils.defer)();
const handler = event => {
if (event.getId() !== eventId) return;
this.client.off(_matrix.RoomStateEvent.Events, handler);
deferred.resolve();
};
this.client.on(_matrix.RoomStateEvent.Events, handler);
await deferred.promise;
}
setValue(settingName, roomId, newValue) {
switch (settingName) {
// Special case URL previews
case "urlPreviewsEnabled":
return this.sendStateEvent(roomId, "org.matrix.room.preview_urls", "disable", !newValue);
default:
return this.sendStateEvent(roomId, DEFAULT_SETTINGS_EVENT_TYPE, settingName, newValue);
}
}
canSetValue(settingName, roomId) {
const room = this.client.getRoom(roomId);
let eventType = DEFAULT_SETTINGS_EVENT_TYPE;
if (settingName === "urlPreviewsEnabled") eventType = "org.matrix.room.preview_urls";
return room?.currentState.maySendStateEvent(eventType, this.client.getUserId()) ?? false;
}
isSupported() {
return !!this.client;
}
getSettings(roomId, eventType = DEFAULT_SETTINGS_EVENT_TYPE) {
const event = this.client.getRoom(roomId)?.currentState.getStateEvents(eventType, "");
if (!event?.getContent()) return null;
return (0, _objects.objectClone)(event.getContent()); // clone to prevent mutation
}
}
exports.default = RoomSettingsHandler;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbWF0cml4IiwicmVxdWlyZSIsIl91dGlscyIsIl9NYXRyaXhDbGllbnRCYWNrZWRTZXR0aW5nc0hhbmRsZXIiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX29iamVjdHMiLCJfU2V0dGluZ0xldmVsIiwiREVGQVVMVF9TRVRUSU5HU19FVkVOVF9UWVBFIiwiUFJFVklFV19VUkxTX0VWRU5UX1RZUEUiLCJSb29tU2V0dGluZ3NIYW5kbGVyIiwiTWF0cml4Q2xpZW50QmFja2VkU2V0dGluZ3NIYW5kbGVyIiwiY29uc3RydWN0b3IiLCJ3YXRjaGVycyIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJkZWZhdWx0IiwiZXZlbnQiLCJzdGF0ZSIsInByZXZFdmVudCIsInJvb21JZCIsImdldFJvb21JZCIsInJvb20iLCJjbGllbnQiLCJnZXRSb29tIiwiY3VycmVudFN0YXRlIiwiZ2V0VHlwZSIsInZhbCIsImdldENvbnRlbnQiLCJub3RpZnlVcGRhdGUiLCJTZXR0aW5nTGV2ZWwiLCJST09NIiwicHJldkNvbnRlbnQiLCJjaGFuZ2VkU2V0dGluZ3MiLCJvYmplY3RLZXlDaGFuZ2VzIiwic2V0dGluZ05hbWUiLCJpbml0TWF0cml4Q2xpZW50Iiwib2xkQ2xpZW50IiwibmV3Q2xpZW50IiwicmVtb3ZlTGlzdGVuZXIiLCJSb29tU3RhdGVFdmVudCIsIkV2ZW50cyIsIm9uRXZlbnQiLCJvbiIsImdldFZhbHVlIiwiY29udGVudCIsImdldFNldHRpbmdzIiwic2V0dGluZ3MiLCJzZW5kU3RhdGVFdmVudCIsImV2ZW50VHlwZSIsImZpZWxkIiwidmFsdWUiLCJldmVudF9pZCIsImV2ZW50SWQiLCJkZWZlcnJlZCIsImRlZmVyIiwiaGFuZGxlciIsImdldElkIiwib2ZmIiwicmVzb2x2ZSIsInByb21pc2UiLCJzZXRWYWx1ZSIsIm5ld1ZhbHVlIiwiY2FuU2V0VmFsdWUiLCJtYXlTZW5kU3RhdGVFdmVudCIsImdldFVzZXJJZCIsImlzU3VwcG9ydGVkIiwiZ2V0U3RhdGVFdmVudHMiLCJvYmplY3RDbG9uZSIsImV4cG9ydHMiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2V0dGluZ3MvaGFuZGxlcnMvUm9vbVNldHRpbmdzSGFuZGxlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuQ29weXJpZ2h0IDIwMjQgTmV3IFZlY3RvciBMdGQuXG5Db3B5cmlnaHQgMjAxOSwgMjAyMCBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuQ29weXJpZ2h0IDIwMTcgVHJhdmlzIFJhbHN0b25cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IHsgTWF0cml4Q2xpZW50LCBNYXRyaXhFdmVudCwgUm9vbVN0YXRlLCBSb29tU3RhdGVFdmVudCwgU3RhdGVFdmVudHMgfSBmcm9tIFwibWF0cml4LWpzLXNkay9zcmMvbWF0cml4XCI7XG5pbXBvcnQgeyBkZWZlciB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy91dGlsc1wiO1xuXG5pbXBvcnQgTWF0cml4Q2xpZW50QmFja2VkU2V0dGluZ3NIYW5kbGVyIGZyb20gXCIuL01hdHJpeENsaWVudEJhY2tlZFNldHRpbmdzSGFuZGxlclwiO1xuaW1wb3J0IHsgb2JqZWN0Q2xvbmUsIG9iamVjdEtleUNoYW5nZXMgfSBmcm9tIFwiLi4vLi4vdXRpbHMvb2JqZWN0c1wiO1xuaW1wb3J0IHsgU2V0dGluZ0xldmVsIH0gZnJvbSBcIi4uL1NldHRpbmdMZXZlbFwiO1xuaW1wb3J0IHsgV2F0Y2hNYW5hZ2VyIH0gZnJvbSBcIi4uL1dhdGNoTWFuYWdlclwiO1xuXG5jb25zdCBERUZBVUxUX1NFVFRJTkdTX0VWRU5UX1RZUEUgPSBcImltLnZlY3Rvci53ZWIuc2V0dGluZ3NcIjtcbmNvbnN0IFBSRVZJRVdfVVJMU19FVkVOVF9UWVBFID0gXCJvcmcubWF0cml4LnJvb20ucHJldmlld191cmxzXCI7XG5cbnR5cGUgUm9vbVNldHRpbmdzRXZlbnRUeXBlID0gdHlwZW9mIERFRkFVTFRfU0VUVElOR1NfRVZFTlRfVFlQRSB8IHR5cGVvZiBQUkVWSUVXX1VSTFNfRVZFTlRfVFlQRTtcblxuLyoqXG4gKiBHZXRzIGFuZCBzZXRzIHNldHRpbmdzIGF0IHRoZSBcInJvb21cIiBsZXZlbC5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUm9vbVNldHRpbmdzSGFuZGxlciBleHRlbmRzIE1hdHJpeENsaWVudEJhY2tlZFNldHRpbmdzSGFuZGxlciB7XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSB3YXRjaGVyczogV2F0Y2hNYW5hZ2VyKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGluaXRNYXRyaXhDbGllbnQob2xkQ2xpZW50OiBNYXRyaXhDbGllbnQsIG5ld0NsaWVudDogTWF0cml4Q2xpZW50KTogdm9pZCB7XG4gICAgICAgIGlmIChvbGRDbGllbnQpIHtcbiAgICAgICAgICAgIG9sZENsaWVudC5yZW1vdmVMaXN0ZW5lcihSb29tU3RhdGVFdmVudC5FdmVudHMsIHRoaXMub25FdmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBuZXdDbGllbnQub24oUm9vbVN0YXRlRXZlbnQuRXZlbnRzLCB0aGlzLm9uRXZlbnQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgb25FdmVudCA9IChldmVudDogTWF0cml4RXZlbnQsIHN0YXRlOiBSb29tU3RhdGUsIHByZXZFdmVudDogTWF0cml4RXZlbnQgfCBudWxsKTogdm9pZCA9PiB7XG4gICAgICAgIGNvbnN0IHJvb21JZCA9IGV2ZW50LmdldFJvb21JZCgpITtcbiAgICAgICAgY29uc3Qgcm9vbSA9IHRoaXMuY2xpZW50LmdldFJvb20ocm9vbUlkKTtcblxuICAgICAgICAvLyBOb3RlOiBpbiB0ZXN0cyBhbmQgZHVyaW5nIHRoZSBlbmNyeXB0aW9uIHNldHVwIG9uIGluaXRpYWwgbG9hZCB3ZSBtaWdodCBub3QgaGF2ZVxuICAgICAgICAvLyByb29tcyBpbiB0aGUgc3RvcmUsIHNvIHdlIGp1c3QgcXVpZXRseSBpZ25vcmUgdGhlIHByb2JsZW0uIElmIHdlIGxvZyBpdCB0aGVuIHdlJ2xsXG4gICAgICAgIC8vIGp1c3QgZW5kIHVwIHNwYW1taW5nIHRoZSBsb2dzIGEgZmV3IHRob3VzYW5kIHRpbWVzLiBJdCBpcyBwZXJmZWN0bHkgZmluZSBmb3IgdXNcbiAgICAgICAgLy8gdG8gaWdub3JlIHRoZSBwcm9ibGVtIGFzIHRoZSBhcHAgd2lsbCBub3QgaGF2ZSBsb2FkZWQgZW5vdWdoIHRvIGNhcmUgeWV0LlxuICAgICAgICBpZiAoIXJvb20pIHJldHVybjtcblxuICAgICAgICAvLyBpZ25vcmUgc3RhdGUgdXBkYXRlcyB3aGljaCBhcmUgbm90IGN1cnJlbnRcbiAgICAgICAgaWYgKHJvb20gJiYgc3RhdGUgIT09IHJvb20uY3VycmVudFN0YXRlKSByZXR1cm47XG5cbiAgICAgICAgaWYgKGV2ZW50LmdldFR5cGUoKSA9PT0gXCJvcmcubWF0cml4LnJvb20ucHJldmlld191cmxzXCIpIHtcbiAgICAgICAgICAgIGxldCB2YWwgPSBldmVudC5nZXRDb250ZW50KClbXCJkaXNhYmxlXCJdO1xuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWwgIT09IFwiYm9vbGVhblwiKSB7XG4gICAgICAgICAgICAgICAgdmFsID0gbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsID0gIXZhbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy53YXRjaGVycy5ub3RpZnlVcGRhdGUoXCJ1cmxQcmV2aWV3c0VuYWJsZWRcIiwgcm9vbUlkLCBTZXR0aW5nTGV2ZWwuUk9PTSwgdmFsKTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC5nZXRUeXBlKCkgPT09IERFRkFVTFRfU0VUVElOR1NfRVZFTlRfVFlQRSkge1xuICAgICAgICAgICAgLy8gRmlndXJlIG91dCB3aGF0IGNoYW5nZWQgYW5kIGZpcmUgdGhvc2UgdXBkYXRlc1xuICAgICAgICAgICAgY29uc3QgcHJldkNvbnRlbnQgPSBwcmV2RXZlbnQ/LmdldENvbnRlbnQoKSA/PyB7fTtcbiAgICAgICAgICAgIGNvbnN0IGNoYW5nZWRTZXR0aW5ncyA9IG9iamVjdEtleUNoYW5nZXM8UmVjb3JkPHN0cmluZywgYW55Pj4ocHJldkNvbnRlbnQsIGV2ZW50LmdldENvbnRlbnQoKSk7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHNldHRpbmdOYW1lIG9mIGNoYW5nZWRTZXR0aW5ncykge1xuICAgICAgICAgICAgICAgIHRoaXMud2F0Y2hlcnMubm90aWZ5VXBkYXRlKHNldHRpbmdOYW1lLCByb29tSWQsIFNldHRpbmdMZXZlbC5ST09NLCBldmVudC5nZXRDb250ZW50KClbc2V0dGluZ05hbWVdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH07XG5cbiAgICBwdWJsaWMgZ2V0VmFsdWUoc2V0dGluZ05hbWU6IHN0cmluZywgcm9vbUlkOiBzdHJpbmcpOiBhbnkge1xuICAgICAgICAvLyBTcGVjaWFsIGNhc2UgVVJMIHByZXZpZXdzXG4gICAgICAgIGlmIChzZXR0aW5nTmFtZSA9PT0gXCJ1cmxQcmV2aWV3c0VuYWJsZWRcIikge1xuICAgICAgICAgICAgY29uc3QgY29udGVudCA9IHRoaXMuZ2V0U2V0dGluZ3Mocm9vbUlkLCBcIm9yZy5tYXRyaXgucm9vbS5wcmV2aWV3X3VybHNcIikgfHwge307XG5cbiAgICAgICAgICAgIC8vIENoZWNrIHRvIG1ha2Ugc3VyZSB0aGF0IHdlIGFjdHVhbGx5IGdvdCBhIGJvb2xlYW5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgY29udGVudFtcImRpc2FibGVcIl0gIT09IFwiYm9vbGVhblwiKSByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIHJldHVybiAhY29udGVudFtcImRpc2FibGVcIl07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBzZXR0aW5ncyA9IHRoaXMuZ2V0U2V0dGluZ3Mocm9vbUlkKSB8fCB7fTtcbiAgICAgICAgcmV0dXJuIHNldHRpbmdzW3NldHRpbmdOYW1lXTtcbiAgICB9XG5cbiAgICAvLyBoZWxwZXIgZnVuY3Rpb24gdG8gc2VuZCBzdGF0ZSBldmVudCB0aGVuIGF3YWl0IGl0IGJlaW5nIGVjaG9lZCBiYWNrXG4gICAgcHJpdmF0ZSBhc3luYyBzZW5kU3RhdGVFdmVudDxLIGV4dGVuZHMgUm9vbVNldHRpbmdzRXZlbnRUeXBlLCBGIGV4dGVuZHMga2V5b2YgU3RhdGVFdmVudHNbS10+KFxuICAgICAgICByb29tSWQ6IHN0cmluZyxcbiAgICAgICAgZXZlbnRUeXBlOiBLLFxuICAgICAgICBmaWVsZDogRixcbiAgICAgICAgdmFsdWU6IFN0YXRlRXZlbnRzW0tdW0ZdLFxuICAgICk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBjb25zdCBjb250ZW50ID0gdGhpcy5nZXRTZXR0aW5ncyhyb29tSWQsIGV2ZW50VHlwZSkgfHwge307XG4gICAgICAgIGNvbnRlbnRbZmllbGRdID0gdmFsdWU7XG5cbiAgICAgICAgY29uc3QgeyBldmVudF9pZDogZXZlbnRJZCB9ID0gYXdhaXQgdGhpcy5jbGllbnQuc2VuZFN0YXRlRXZlbnQocm9vbUlkLCBldmVudFR5cGUsIGNvbnRlbnQpO1xuXG4gICAgICAgIGNvbnN0IGRlZmVycmVkID0gZGVmZXI8dm9pZD4oKTtcbiAgICAgICAgY29uc3QgaGFuZGxlciA9IChldmVudDogTWF0cml4RXZlbnQpOiB2b2lkID0+IHtcbiAgICAgICAgICAgIGlmIChldmVudC5nZXRJZCgpICE9PSBldmVudElkKSByZXR1cm47XG4gICAgICAgICAgICB0aGlzLmNsaWVudC5vZmYoUm9vbVN0YXRlRXZlbnQuRXZlbnRzLCBoYW5kbGVyKTtcbiAgICAgICAgICAgIGRlZmVycmVkLnJlc29sdmUoKTtcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5jbGllbnQub24oUm9vbVN0YXRlRXZlbnQuRXZlbnRzLCBoYW5kbGVyKTtcblxuICAgICAgICBhd2FpdCBkZWZlcnJlZC5wcm9taXNlO1xuICAgIH1cblxuICAgIHB1YmxpYyBzZXRWYWx1ZShzZXR0aW5nTmFtZTogc3RyaW5nLCByb29tSWQ6IHN0cmluZywgbmV3VmFsdWU6IGFueSk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBzd2l0Y2ggKHNldHRpbmdOYW1lKSB7XG4gICAgICAgICAgICAvLyBTcGVjaWFsIGNhc2UgVVJMIHByZXZpZXdzXG4gICAgICAgICAgICBjYXNlIFwidXJsUHJldmlld3NFbmFibGVkXCI6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2VuZFN0YXRlRXZlbnQocm9vbUlkLCBcIm9yZy5tYXRyaXgucm9vbS5wcmV2aWV3X3VybHNcIiwgXCJkaXNhYmxlXCIsICFuZXdWYWx1ZSk7XG5cbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2VuZFN0YXRlRXZlbnQocm9vbUlkLCBERUZBVUxUX1NFVFRJTkdTX0VWRU5UX1RZUEUsIHNldHRpbmdOYW1lLCBuZXdWYWx1ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY2FuU2V0VmFsdWUoc2V0dGluZ05hbWU6IHN0cmluZywgcm9vbUlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgY29uc3Qgcm9vbSA9IHRoaXMuY2xpZW50LmdldFJvb20ocm9vbUlkKTtcblxuICAgICAgICBsZXQgZXZlbnRUeXBlID0gREVGQVVMVF9TRVRUSU5HU19FVkVOVF9UWVBFO1xuICAgICAgICBpZiAoc2V0dGluZ05hbWUgPT09IFwidXJsUHJldmlld3NFbmFibGVkXCIpIGV2ZW50VHlwZSA9IFwib3JnLm1hdHJpeC5yb29tLnByZXZpZXdfdXJsc1wiO1xuXG4gICAgICAgIHJldHVybiByb29tPy5jdXJyZW50U3RhdGUubWF5U2VuZFN0YXRlRXZlbnQoZXZlbnRUeXBlLCB0aGlzLmNsaWVudC5nZXRVc2VySWQoKSEpID8/IGZhbHNlO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc1N1cHBvcnRlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICEhdGhpcy5jbGllbnQ7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRTZXR0aW5ncyhyb29tSWQ6IHN0cmluZywgZXZlbnRUeXBlID0gREVGQVVMVF9TRVRUSU5HU19FVkVOVF9UWVBFKTogYW55IHtcbiAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLmNsaWVudC5nZXRSb29tKHJvb21JZCk/LmN1cnJlbnRTdGF0ZS5nZXRTdGF0ZUV2ZW50cyhldmVudFR5cGUsIFwiXCIpO1xuICAgICAgICBpZiAoIWV2ZW50Py5nZXRDb250ZW50KCkpIHJldHVybiBudWxsO1xuICAgICAgICByZXR1cm4gb2JqZWN0Q2xvbmUoZXZlbnQuZ2V0Q29udGVudCgpKTsgLy8gY2xvbmUgdG8gcHJldmVudCBtdXRhdGlvblxuICAgIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFTQSxJQUFBQSxPQUFBLEdBQUFDLE9BQUE7QUFDQSxJQUFBQyxNQUFBLEdBQUFELE9BQUE7QUFFQSxJQUFBRSxrQ0FBQSxHQUFBQyxzQkFBQSxDQUFBSCxPQUFBO0FBQ0EsSUFBQUksUUFBQSxHQUFBSixPQUFBO0FBQ0EsSUFBQUssYUFBQSxHQUFBTCxPQUFBO0FBZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFVQSxNQUFNTSwyQkFBMkIsR0FBRyx3QkFBd0I7QUFDNUQsTUFBTUMsdUJBQXVCLEdBQUcsOEJBQThCO0FBSTlEO0FBQ0E7QUFDQTtBQUNlLE1BQU1DLG1CQUFtQixTQUFTQywwQ0FBaUMsQ0FBQztFQUN4RUMsV0FBV0EsQ0FBaUJDLFFBQXNCLEVBQUU7SUFDdkQsS0FBSyxDQUFDLENBQUM7SUFBQyxJQUFBQyxnQkFBQSxDQUFBQyxPQUFBLG1CQVdNLENBQUNDLEtBQWtCLEVBQUVDLEtBQWdCLEVBQUVDLFNBQTZCLEtBQVc7TUFDN0YsTUFBTUMsTUFBTSxHQUFHSCxL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