UNPKG

matrix-react-sdk

Version:
158 lines (147 loc) 21.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.avatarUrlForMember = avatarUrlForMember; exports.avatarUrlForRoom = avatarUrlForRoom; exports.avatarUrlForUser = avatarUrlForUser; exports.defaultAvatarUrlForString = defaultAvatarUrlForString; exports.getAvatarTextColor = getAvatarTextColor; exports.getInitialLetter = getInitialLetter; var _compoundWeb = require("@vector-im/compound-web"); var _DMRoomMap = _interopRequireDefault(require("./utils/DMRoomMap")); var _Media = require("./customisations/Media"); var _isLocalRoom = require("./utils/localRoom/isLocalRoom"); var _strings = require("./utils/strings"); /* Copyright 2024 New Vector Ltd. Copyright 2015, 2016 OpenMarket Ltd SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ /** * Hardcoded from the Compound colors. * Shade for background as defined in the compound web implementation * https://github.com/vector-im/compound-web/blob/main/src/components/Avatar */ const AVATAR_BG_COLORS = ["#e9f2ff", "#faeefb", "#e3f7ed", "#ffecf0", "#ffefe4", "#e3f5f8", "#f1efff", "#e0f8d9"]; const AVATAR_TEXT_COLORS = ["#043894", "#671481", "#004933", "#7e0642", "#850000", "#004077", "#4c05b5", "#004b00"]; // Not to be used for BaseAvatar urls as that has similar default avatar fallback already function avatarUrlForMember(member, width, height, resizeMethod) { let url; if (member?.getMxcAvatarUrl()) { url = (0, _Media.mediaFromMxc)(member.getMxcAvatarUrl()).getThumbnailOfSourceHttp(width, height, resizeMethod); } if (!url) { // member can be null here currently since on invites, the JS SDK // does not have enough info to build a RoomMember object for // the inviter. url = defaultAvatarUrlForString(member ? member.userId : ""); } return url; } /** * Determines the HEX color to use in the avatar pills * @param id the user or room ID * @returns the text color to use on the avatar */ function getAvatarTextColor(id) { // eslint-disable-next-line react-hooks/rules-of-hooks const index = (0, _compoundWeb.useIdColorHash)(id); return AVATAR_TEXT_COLORS[index - 1]; } function avatarUrlForUser(user, width, height, resizeMethod) { if (!user.avatarUrl) return null; return (0, _Media.mediaFromMxc)(user.avatarUrl).getThumbnailOfSourceHttp(width, height, resizeMethod); } function isValidHexColor(color) { return typeof color === "string" && (color.length === 7 || color.length === 9) && color.charAt(0) === "#" && !color.slice(1).split("").some(c => isNaN(parseInt(c, 16))); } function urlForColor(color) { const size = 40; const canvas = document.createElement("canvas"); canvas.width = size; canvas.height = size; const ctx = canvas.getContext("2d"); // bail out when using jsdom in unit tests if (!ctx) { return ""; } ctx.fillStyle = color; ctx.fillRect(0, 0, size, size); return canvas.toDataURL(); } // XXX: Ideally we'd clear this cache when the theme changes // but since this function is at global scope, it's a bit // hard to install a listener here, even if there were a clear event to listen to const colorToDataURLCache = new Map(); function defaultAvatarUrlForString(s) { if (!s) return ""; // XXX: should never happen but empirically does by evidence of a rageshake // eslint-disable-next-line react-hooks/rules-of-hooks const colorIndex = (0, _compoundWeb.useIdColorHash)(s); // overwritten color value in custom themes const cssVariable = `--avatar-background-colors_${colorIndex}`; const cssValue = getComputedStyle(document.body).getPropertyValue(cssVariable); const color = cssValue || AVATAR_BG_COLORS[colorIndex - 1]; let dataUrl = colorToDataURLCache.get(color); if (!dataUrl) { // validate color as this can come from account_data // with custom theming if (isValidHexColor(color)) { dataUrl = urlForColor(color); colorToDataURLCache.set(color, dataUrl); } else { dataUrl = ""; } } return dataUrl; } /** * returns the first (non-sigil) character of 'name', * converted to uppercase * @param {string} name * @return {string} the first letter */ function getInitialLetter(name) { if (!name) { // XXX: We should find out what causes the name to sometimes be falsy. console.trace("`name` argument to `getInitialLetter` not supplied"); return undefined; } if (name.length < 1) { return undefined; } const initial = name[0]; if ((initial === "@" || initial === "#" || initial === "+") && name[1]) { name = name.substring(1); } return (0, _strings.getFirstGrapheme)(name).toUpperCase(); } function avatarUrlForRoom(room, width, height, resizeMethod) { if (!room) return null; // null-guard if (room.getMxcAvatarUrl()) { const media = (0, _Media.mediaFromMxc)(room.getMxcAvatarUrl() ?? undefined); if (width !== undefined && height !== undefined) { return media.getThumbnailOfSourceHttp(width, height, resizeMethod); } return media.srcHttp; } // space rooms cannot be DMs so skip the rest if (room.isSpaceRoom()) return null; // If the room is not a DM don't fallback to a member avatar if (!_DMRoomMap.default.shared().getUserIdForRoomId(room.roomId) && !(0, _isLocalRoom.isLocalRoom)(room)) { return null; } // If there are only two members in the DM use the avatar of the other member const otherMember = room.getAvatarFallbackMember(); if (otherMember?.getMxcAvatarUrl()) { const media = (0, _Media.mediaFromMxc)(otherMember.getMxcAvatarUrl()); if (width !== undefined && height !== undefined) { return media.getThumbnailOfSourceHttp(width, height, resizeMethod); } return media.srcHttp; } return null; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfY29tcG91bmRXZWIiLCJyZXF1aXJlIiwiX0RNUm9vbU1hcCIsIl9pbnRlcm9wUmVxdWlyZURlZmF1bHQiLCJfTWVkaWEiLCJfaXNMb2NhbFJvb20iLCJfc3RyaW5ncyIsIkFWQVRBUl9CR19DT0xPUlMiLCJBVkFUQVJfVEVYVF9DT0xPUlMiLCJhdmF0YXJVcmxGb3JNZW1iZXIiLCJtZW1iZXIiLCJ3aWR0aCIsImhlaWdodCIsInJlc2l6ZU1ldGhvZCIsInVybCIsImdldE14Y0F2YXRhclVybCIsIm1lZGlhRnJvbU14YyIsImdldFRodW1ibmFpbE9mU291cmNlSHR0cCIsImRlZmF1bHRBdmF0YXJVcmxGb3JTdHJpbmciLCJ1c2VySWQiLCJnZXRBdmF0YXJUZXh0Q29sb3IiLCJpZCIsImluZGV4IiwidXNlSWRDb2xvckhhc2giLCJhdmF0YXJVcmxGb3JVc2VyIiwidXNlciIsImF2YXRhclVybCIsImlzVmFsaWRIZXhDb2xvciIsImNvbG9yIiwibGVuZ3RoIiwiY2hhckF0Iiwic2xpY2UiLCJzcGxpdCIsInNvbWUiLCJjIiwiaXNOYU4iLCJwYXJzZUludCIsInVybEZvckNvbG9yIiwic2l6ZSIsImNhbnZhcyIsImRvY3VtZW50IiwiY3JlYXRlRWxlbWVudCIsImN0eCIsImdldENvbnRleHQiLCJmaWxsU3R5bGUiLCJmaWxsUmVjdCIsInRvRGF0YVVSTCIsImNvbG9yVG9EYXRhVVJMQ2FjaGUiLCJNYXAiLCJzIiwiY29sb3JJbmRleCIsImNzc1ZhcmlhYmxlIiwiY3NzVmFsdWUiLCJnZXRDb21wdXRlZFN0eWxlIiwiYm9keSIsImdldFByb3BlcnR5VmFsdWUiLCJkYXRhVXJsIiwiZ2V0Iiwic2V0IiwiZ2V0SW5pdGlhbExldHRlciIsIm5hbWUiLCJjb25zb2xlIiwidHJhY2UiLCJ1bmRlZmluZWQiLCJpbml0aWFsIiwic3Vic3RyaW5nIiwiZ2V0Rmlyc3RHcmFwaGVtZSIsInRvVXBwZXJDYXNlIiwiYXZhdGFyVXJsRm9yUm9vbSIsInJvb20iLCJtZWRpYSIsInNyY0h0dHAiLCJpc1NwYWNlUm9vbSIsIkRNUm9vbU1hcCIsInNoYXJlZCIsImdldFVzZXJJZEZvclJvb21JZCIsInJvb21JZCIsImlzTG9jYWxSb29tIiwib3RoZXJNZW1iZXIiLCJnZXRBdmF0YXJGYWxsYmFja01lbWJlciJdLCJzb3VyY2VzIjpbIi4uL3NyYy9BdmF0YXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMTUsIDIwMTYgT3Blbk1hcmtldCBMdGRcblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IHsgUm9vbU1lbWJlciwgVXNlciwgUm9vbSwgUmVzaXplTWV0aG9kIH0gZnJvbSBcIm1hdHJpeC1qcy1zZGsvc3JjL21hdHJpeFwiO1xuaW1wb3J0IHsgdXNlSWRDb2xvckhhc2ggfSBmcm9tIFwiQHZlY3Rvci1pbS9jb21wb3VuZC13ZWJcIjtcblxuaW1wb3J0IERNUm9vbU1hcCBmcm9tIFwiLi91dGlscy9ETVJvb21NYXBcIjtcbmltcG9ydCB7IG1lZGlhRnJvbU14YyB9IGZyb20gXCIuL2N1c3RvbWlzYXRpb25zL01lZGlhXCI7XG5pbXBvcnQgeyBpc0xvY2FsUm9vbSB9IGZyb20gXCIuL3V0aWxzL2xvY2FsUm9vbS9pc0xvY2FsUm9vbVwiO1xuaW1wb3J0IHsgZ2V0Rmlyc3RHcmFwaGVtZSB9IGZyb20gXCIuL3V0aWxzL3N0cmluZ3NcIjtcblxuLyoqXG4gKiBIYXJkY29kZWQgZnJvbSB0aGUgQ29tcG91bmQgY29sb3JzLlxuICogU2hhZGUgZm9yIGJhY2tncm91bmQgYXMgZGVmaW5lZCBpbiB0aGUgY29tcG91bmQgd2ViIGltcGxlbWVudGF0aW9uXG4gKiBodHRwczovL2dpdGh1Yi5jb20vdmVjdG9yLWltL2NvbXBvdW5kLXdlYi9ibG9iL21haW4vc3JjL2NvbXBvbmVudHMvQXZhdGFyXG4gKi9cbmNvbnN0IEFWQVRBUl9CR19DT0xPUlMgPSBbXCIjZTlmMmZmXCIsIFwiI2ZhZWVmYlwiLCBcIiNlM2Y3ZWRcIiwgXCIjZmZlY2YwXCIsIFwiI2ZmZWZlNFwiLCBcIiNlM2Y1ZjhcIiwgXCIjZjFlZmZmXCIsIFwiI2UwZjhkOVwiXTtcbmNvbnN0IEFWQVRBUl9URVhUX0NPTE9SUyA9IFtcIiMwNDM4OTRcIiwgXCIjNjcxNDgxXCIsIFwiIzAwNDkzM1wiLCBcIiM3ZTA2NDJcIiwgXCIjODUwMDAwXCIsIFwiIzAwNDA3N1wiLCBcIiM0YzA1YjVcIiwgXCIjMDA0YjAwXCJdO1xuXG4vLyBOb3QgdG8gYmUgdXNlZCBmb3IgQmFzZUF2YXRhciB1cmxzIGFzIHRoYXQgaGFzIHNpbWlsYXIgZGVmYXVsdCBhdmF0YXIgZmFsbGJhY2sgYWxyZWFkeVxuZXhwb3J0IGZ1bmN0aW9uIGF2YXRhclVybEZvck1lbWJlcihcbiAgICBtZW1iZXI6IFJvb21NZW1iZXIgfCB1bmRlZmluZWQsXG4gICAgd2lkdGg6IG51bWJlcixcbiAgICBoZWlnaHQ6IG51bWJlcixcbiAgICByZXNpemVNZXRob2Q6IFJlc2l6ZU1ldGhvZCxcbik6IHN0cmluZyB7XG4gICAgbGV0IHVybDogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgICBpZiAobWVtYmVyPy5nZXRNeGNBdmF0YXJVcmwoKSkge1xuICAgICAgICB1cmwgPSBtZWRpYUZyb21NeGMobWVtYmVyLmdldE14Y0F2YXRhclVybCgpKS5nZXRUaHVtYm5haWxPZlNvdXJjZUh0dHAod2lkdGgsIGhlaWdodCwgcmVzaXplTWV0aG9kKTtcbiAgICB9XG4gICAgaWYgKCF1cmwpIHtcbiAgICAgICAgLy8gbWVtYmVyIGNhbiBiZSBudWxsIGhlcmUgY3VycmVudGx5IHNpbmNlIG9uIGludml0ZXMsIHRoZSBKUyBTREtcbiAgICAgICAgLy8gZG9lcyBub3QgaGF2ZSBlbm91Z2ggaW5mbyB0byBidWlsZCBhIFJvb21NZW1iZXIgb2JqZWN0IGZvclxuICAgICAgICAvLyB0aGUgaW52aXRlci5cbiAgICAgICAgdXJsID0gZGVmYXVsdEF2YXRhclVybEZvclN0cmluZyhtZW1iZXIgPyBtZW1iZXIudXNlcklkIDogXCJcIik7XG4gICAgfVxuICAgIHJldHVybiB1cmw7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyB0aGUgSEVYIGNvbG9yIHRvIHVzZSBpbiB0aGUgYXZhdGFyIHBpbGxzXG4gKiBAcGFyYW0gaWQgdGhlIHVzZXIgb3Igcm9vbSBJRFxuICogQHJldHVybnMgdGhlIHRleHQgY29sb3IgdG8gdXNlIG9uIHRoZSBhdmF0YXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEF2YXRhclRleHRDb2xvcihpZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaG9va3MvcnVsZXMtb2YtaG9va3NcbiAgICBjb25zdCBpbmRleCA9IHVzZUlkQ29sb3JIYXNoKGlkKTtcblxuICAgIHJldHVybiBBVkFUQVJfVEVYVF9DT0xPUlNbaW5kZXggLSAxXTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGF2YXRhclVybEZvclVzZXIoXG4gICAgdXNlcjogUGljazxVc2VyLCBcImF2YXRhclVybFwiPixcbiAgICB3aWR0aDogbnVtYmVyLFxuICAgIGhlaWdodDogbnVtYmVyLFxuICAgIHJlc2l6ZU1ldGhvZD86IFJlc2l6ZU1ldGhvZCxcbik6IHN0cmluZyB8IG51bGwge1xuICAgIGlmICghdXNlci5hdmF0YXJVcmwpIHJldHVybiBudWxsO1xuICAgIHJldHVybiBtZWRpYUZyb21NeGModXNlci5hdmF0YXJVcmwpLmdldFRodW1ibmFpbE9mU291cmNlSHR0cCh3aWR0aCwgaGVpZ2h0LCByZXNpemVNZXRob2QpO1xufVxuXG5mdW5jdGlvbiBpc1ZhbGlkSGV4Q29sb3IoY29sb3I6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICAgIHR5cGVvZiBjb2xvciA9PT0gXCJzdHJpbmdcIiAmJlxuICAgICAgICAoY29sb3IubGVuZ3RoID09PSA3IHx8IGNvbG9yLmxlbmd0aCA9PT0gOSkgJiZcbiAgICAgICAgY29sb3IuY2hhckF0KDApID09PSBcIiNcIiAmJlxuICAgICAgICAhY29sb3JcbiAgICAgICAgICAgIC5zbGljZSgxKVxuICAgICAgICAgICAgLnNwbGl0KFwiXCIpXG4gICAgICAgICAgICAuc29tZSgoYykgPT4gaXNOYU4ocGFyc2VJbnQoYywgMTYpKSlcbiAgICApO1xufVxuXG5mdW5jdGlvbiB1cmxGb3JDb2xvcihjb2xvcjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBzaXplID0gNDA7XG4gICAgY29uc3QgY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImNhbnZhc1wiKTtcbiAgICBjYW52YXMud2lkdGggPSBzaXplO1xuICAgIGNhbnZhcy5oZWlnaHQgPSBzaXplO1xuICAgIGNvbnN0IGN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KFwiMmRcIik7XG4gICAgLy8gYmFpbCBvdXQgd2hlbiB1c2luZyBqc2RvbSBpbiB1bml0IHRlc3RzXG4gICAgaWYgKCFjdHgpIHtcbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgfVxuICAgIGN0eC5maWxsU3R5bGUgPSBjb2xvcjtcbiAgICBjdHguZmlsbFJlY3QoMCwgMCwgc2l6ZSwgc2l6ZSk7XG4gICAgcmV0dXJuIGNhbnZhcy50b0RhdGFVUkwoKTtcbn1cblxuLy8gWFhYOiBJZGVhbGx5IHdlJ2QgY2xlYXIgdGhpcyBjYWNoZSB3aGVuIHRoZSB0aGVtZSBjaGFuZ2VzXG4vLyBidXQgc2luY2UgdGhpcyBmdW5jdGlvbiBpcyBhdCBnbG9iYWwgc2NvcGUsIGl0J3MgYSBiaXRcbi8vIGhhcmQgdG8gaW5zdGFsbCBhIGxpc3RlbmVyIGhlcmUsIGV2ZW4gaWYgdGhlcmUgd2VyZSBhIGNsZWFyIGV2ZW50IHRvIGxpc3RlbiB0b1xuY29uc3QgY29sb3JUb0RhdGFVUkxDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0QXZhdGFyVXJsRm9yU3RyaW5nKHM6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKCFzKSByZXR1cm4gXCJcIjsgLy8gWFhYOiBzaG91bGQgbmV2ZXIgaGFwcGVuIGJ1dCBlbXBpcmljYWxseSBkb2VzIGJ5IGV2aWRlbmNlIG9mIGEgcmFnZXNoYWtlXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL3J1bGVzLW9mLWhvb2tzXG4gICAgY29uc3QgY29sb3JJbmRleCA9IHVzZUlkQ29sb3JIYXNoKHMpO1xuICAgIC8vIG92ZXJ3cml0dGVuIGNvbG9yIHZhbHVlIGluIGN1c3RvbSB0aGVtZXNcbiAgICBjb25zdCBjc3NWYXJpYWJsZSA9IGAtLWF2YXRhci1iYWNrZ3JvdW5kLWNvbG9yc18ke2NvbG9ySW5kZXh9YDtcbiAgICBjb25zdCBjc3NWYWx1ZSA9IGdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZ2V0UHJvcGVydHlWYWx1ZShjc3NWYXJpYWJsZSk7XG4gICAgY29uc3QgY29sb3IgPSBjc3NWYWx1ZSB8fCBBVkFUQVJfQkdfQ09MT1JTW2NvbG9ySW5kZXggLSAxXTtcbiAgICBsZXQgZGF0YVVybCA9IGNvbG9yVG9EYXRhVVJMQ2FjaGUuZ2V0KGNvbG9yKTtcbiAgICBpZiAoIWRhdGFVcmwpIHtcbiAgICAgICAgLy8gdmFsaWRhdGUgY29sb3IgYXMgdGhpcyBjYW4gY29tZSBmcm9tIGFjY291bnRfZGF0YVxuICAgICAgICAvLyB3aXRoIGN1c3RvbSB0aGVtaW5nXG4gICAgICAgIGlmIChpc1ZhbGlkSGV4Q29sb3IoY29sb3IpKSB7XG4gICAgICAgICAgICBkYXRhVXJsID0gdXJsRm9yQ29sb3IoY29sb3IpO1xuICAgICAgICAgICAgY29sb3JUb0RhdGFVUkxDYWNoZS5zZXQoY29sb3IsIGRhdGFVcmwpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGF0YVVybCA9IFwiXCI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGRhdGFVcmw7XG59XG5cbi8qKlxuICogcmV0dXJucyB0aGUgZmlyc3QgKG5vbi1zaWdpbCkgY2hhcmFjdGVyIG9mICduYW1lJyxcbiAqIGNvbnZlcnRlZCB0byB1cHBlcmNhc2VcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHRoZSBmaXJzdCBsZXR0ZXJcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEluaXRpYWxMZXR0ZXIobmFtZTogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIW5hbWUpIHtcbiAgICAgICAgLy8gWFhYOiBXZSBzaG91bGQgZmluZCBvdXQgd2hhdCBjYXVzZXMgdGhlIG5hbWUgdG8gc29tZXRpbWVzIGJlIGZhbHN5LlxuICAgICAgICBjb25zb2xlLnRyYWNlKFwiYG5hbWVgIGFyZ3VtZW50IHRvIGBnZXRJbml0aWFsTGV0dGVyYCBub3Qgc3VwcGxpZWRcIik7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGlmIChuYW1lLmxlbmd0aCA8IDEpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBpbml0aWFsID0gbmFtZVswXTtcbiAgICBpZiAoKGluaXRpYWwgPT09IFwiQFwiIHx8IGluaXRpYWwgPT09IFwiI1wiIHx8IGluaXRpYWwgPT09IFwiK1wiKSAmJiBuYW1lWzFdKSB7XG4gICAgICAgIG5hbWUgPSBuYW1lLnN1YnN0cmluZygxKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZ2V0Rmlyc3RHcmFwaGVtZShuYW1lKS50b1VwcGVyQ2FzZSgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYXZhdGFyVXJsRm9yUm9vbShcbiAgICByb29tOiBSb29tIHwgbnVsbCxcbiAgICB3aWR0aD86IG51bWJlcixcbiAgICBoZWlnaHQ/OiBudW1iZXIsXG4gICAgcmVzaXplTWV0aG9kPzogUmVzaXplTWV0aG9kLFxuKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgaWYgKCFyb29tKSByZXR1cm4gbnVsbDsgLy8gbnVsbC1ndWFyZFxuXG4gICAgaWYgKHJvb20uZ2V0TXhjQXZhdGFyVXJsKCkpIHtcbiAgICAgICAgY29uc3QgbWVkaWEgPSBtZWRpYUZyb21NeGMocm9vbS5nZXRNeGNBdmF0YXJVcmwoKSA/PyB1bmRlZmluZWQpO1xuICAgICAgICBpZiAod2lkdGggIT09IHVuZGVmaW5lZCAmJiBoZWlnaHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuIG1lZGlhLmdldFRodW1ibmFpbE9mU291cmNlSHR0cCh3aWR0aCwgaGVpZ2h0LCByZXNpemVNZXRob2QpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZWRpYS5zcmNIdHRwO1xuICAgIH1cblxuICAgIC8vIHNwYWNlIHJvb21zIGNhbm5vdCBiZSBETXMgc28gc2tpcCB0aGUgcmVzdFxuICAgIGlmIChyb29tLmlzU3BhY2VSb29tKCkpIHJldHVybiBudWxsO1xuXG4gICAgLy8gSWYgdGhlIHJvb20gaXMgbm90IGEgRE0gZG9uJ3QgZmFsbGJhY2sgdG8gYSBtZW1iZXIgYXZhdGFyXG4gICAgaWYgKCFETVJvb21NYXAuc2hhcmVkKCkuZ2V0VXNlcklkRm9yUm9vbUlkKHJvb20ucm9vbUlkKSAmJiAhaXNMb2NhbFJvb20ocm9vbSkpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlcmUgYXJlIG9ubHkgdHdvIG1lbWJlcnMgaW4gdGhlIERNIHVzZSB0aGUgYXZhdGFyIG9mIHRoZSBvdGhlciBtZW1iZXJcbiAgICBjb25zdCBvdGhlck1lbWJlciA9IHJvb20uZ2V0QXZhdGFyRmFsbGJhY2tNZW1iZXIoKTtcbiAgICBpZiAob3RoZXJNZW1iZXI/LmdldE14Y0F2YXRhclVybCgpKSB7XG4gICAgICAgIGNvbnN0IG1lZGlhID0gbWVkaWFGcm9tTXhjKG90aGVyTWVtYmVyLmdldE14Y0F2YXRhclVybCgpKTtcbiAgICAgICAgaWYgKHdpZHRoICE9PSB1bmRlZmluZWQgJiYgaGVpZ2h0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBtZWRpYS5nZXRUaHVtYm5haWxPZlNvdXJjZUh0dHAod2lkdGgsIGhlaWdodCwgcmVzaXplTWV0aG9kKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVkaWEuc3JjSHR0cDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQVNBLElBQUFBLFlBQUEsR0FBQUMsT0FBQTtBQUVBLElBQUFDLFVBQUEsR0FBQUMsc0JBQUEsQ0FBQUYsT0FBQTtBQUNBLElBQUFHLE1BQUEsR0FBQUgsT0FBQTtBQUNBLElBQUFJLFlBQUEsR0FBQUosT0FBQTtBQUNBLElBQUFLLFFBQUEsR0FBQUwsT0FBQTtBQWRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQVVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFNTSxnQkFBZ0IsR0FBRyxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLENBQUM7QUFDakgsTUFBTUMsa0JBQWtCLEdBQUcsQ0FBQyxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxDQUFDOztBQUVuSDtBQUNPLFNBQVNDLGtCQUFrQkEsQ0FDOUJDLE1BQThCLEVBQzlCQyxLQUFhLEVBQ2JDLE1BQWMsRUFDZEMsWUFBMEIsRUFDcEI7RUFDTixJQUFJQyxHQUE4QjtFQUNsQyxJQUFJSixNQUFNLEVBQUVLLGVBQWUsQ0FBQyxDQUFDLEVBQUU7SUFDM0JELEdBQUcsR0FBRyxJQUFBRSxtQkFBWSxFQUFDTixNQUFNLENBQUNLLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQ0Usd0JBQXdCLENBQUNOLEtBQUssRUFB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