UNPKG

matrix-react-sdk

Version:
168 lines (160 loc) 25.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.NaturalAlgorithm = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _logger = require("matrix-js-sdk/src/logger"); var _tagSorting = require("../tag-sorting"); var _OrderingAlgorithm = require("./OrderingAlgorithm"); var _models = require("../../models"); var _RoomNotificationStateStore = require("../../../notifications/RoomNotificationStateStore"); /* Copyright 2024 New Vector Ltd. Copyright 2020 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. */ /** * Uses the natural tag sorting algorithm order to determine tag ordering. No * additional behavioural changes are present. */ class NaturalAlgorithm extends _OrderingAlgorithm.OrderingAlgorithm { constructor(tagId, initialSortingAlgorithm) { super(tagId, initialSortingAlgorithm); (0, _defineProperty2.default)(this, "cachedCategorizedOrderedRooms", { defaultRooms: [], mutedRooms: [] }); } setRooms(rooms) { const { defaultRooms, mutedRooms } = this.categorizeRooms(rooms); this.cachedCategorizedOrderedRooms = { defaultRooms: (0, _tagSorting.sortRoomsWithAlgorithm)(defaultRooms, this.tagId, this.sortingAlgorithm), mutedRooms: (0, _tagSorting.sortRoomsWithAlgorithm)(mutedRooms, this.tagId, this.sortingAlgorithm) }; this.buildCachedOrderedRooms(); } handleRoomUpdate(room, cause) { const isSplice = cause === _models.RoomUpdateCause.NewRoom || cause === _models.RoomUpdateCause.RoomRemoved; const isInPlace = cause === _models.RoomUpdateCause.Timeline || cause === _models.RoomUpdateCause.ReadReceipt || cause === _models.RoomUpdateCause.PossibleMuteChange; const isMuted = this.isMutedToBottom && this.getRoomIsMuted(room); if (!isSplice && !isInPlace) { throw new Error(`Unsupported update cause: ${cause}`); } if (cause === _models.RoomUpdateCause.NewRoom) { if (isMuted) { this.cachedCategorizedOrderedRooms.mutedRooms = (0, _tagSorting.sortRoomsWithAlgorithm)([...this.cachedCategorizedOrderedRooms.mutedRooms, room], this.tagId, this.sortingAlgorithm); } else { this.cachedCategorizedOrderedRooms.defaultRooms = (0, _tagSorting.sortRoomsWithAlgorithm)([...this.cachedCategorizedOrderedRooms.defaultRooms, room], this.tagId, this.sortingAlgorithm); } this.buildCachedOrderedRooms(); return true; } else if (cause === _models.RoomUpdateCause.RoomRemoved) { return this.removeRoom(room); } else if (cause === _models.RoomUpdateCause.PossibleMuteChange) { if (this.isMutedToBottom) { return this.onPossibleMuteChange(room); } else { return false; } } // TODO: Optimize this to avoid useless operations: https://github.com/vector-im/element-web/issues/14457 // For example, we can skip updates to alphabetic (sometimes) and manually ordered tags if (isMuted) { this.cachedCategorizedOrderedRooms.mutedRooms = (0, _tagSorting.sortRoomsWithAlgorithm)(this.cachedCategorizedOrderedRooms.mutedRooms, this.tagId, this.sortingAlgorithm); } else { this.cachedCategorizedOrderedRooms.defaultRooms = (0, _tagSorting.sortRoomsWithAlgorithm)(this.cachedCategorizedOrderedRooms.defaultRooms, this.tagId, this.sortingAlgorithm); } this.buildCachedOrderedRooms(); return true; } /** * Remove a room from the cached room list * @param room Room to remove * @returns {boolean} true when room list should update as result */ removeRoom(room) { const defaultIndex = this.cachedCategorizedOrderedRooms.defaultRooms.findIndex(r => r.roomId === room.roomId); if (defaultIndex > -1) { this.cachedCategorizedOrderedRooms.defaultRooms.splice(defaultIndex, 1); this.buildCachedOrderedRooms(); return true; } const mutedIndex = this.cachedCategorizedOrderedRooms.mutedRooms.findIndex(r => r.roomId === room.roomId); if (mutedIndex > -1) { this.cachedCategorizedOrderedRooms.mutedRooms.splice(mutedIndex, 1); this.buildCachedOrderedRooms(); return true; } _logger.logger.warn(`Tried to remove unknown room from ${this.tagId}: ${room.roomId}`); // room was not in cached lists, no update return false; } /** * Sets cachedOrderedRooms from cachedCategorizedOrderedRooms */ buildCachedOrderedRooms() { this.cachedOrderedRooms = [...this.cachedCategorizedOrderedRooms.defaultRooms, ...this.cachedCategorizedOrderedRooms.mutedRooms]; } getRoomIsMuted(room) { // It's fine for us to call this a lot because it's cached, and we shouldn't be // wasting anything by doing so as the store holds single references const state = _RoomNotificationStateStore.RoomNotificationStateStore.instance.getRoomState(room); return state.muted; } categorizeRooms(rooms) { if (!this.isMutedToBottom) { return { defaultRooms: rooms, mutedRooms: [] }; } return rooms.reduce((acc, room) => { if (this.getRoomIsMuted(room)) { acc.mutedRooms.push(room); } else { acc.defaultRooms.push(room); } return acc; }, { defaultRooms: [], mutedRooms: [] }); } onPossibleMuteChange(room) { const isMuted = this.getRoomIsMuted(room); if (isMuted) { const defaultIndex = this.cachedCategorizedOrderedRooms.defaultRooms.findIndex(r => r.roomId === room.roomId); // room has been muted if (defaultIndex > -1) { // remove from the default list this.cachedCategorizedOrderedRooms.defaultRooms.splice(defaultIndex, 1); // add to muted list and reorder this.cachedCategorizedOrderedRooms.mutedRooms = (0, _tagSorting.sortRoomsWithAlgorithm)([...this.cachedCategorizedOrderedRooms.mutedRooms, room], this.tagId, this.sortingAlgorithm); // rebuild this.buildCachedOrderedRooms(); return true; } } else { const mutedIndex = this.cachedCategorizedOrderedRooms.mutedRooms.findIndex(r => r.roomId === room.roomId); // room has been unmuted if (mutedIndex > -1) { // remove from the muted list this.cachedCategorizedOrderedRooms.mutedRooms.splice(mutedIndex, 1); // add to default list and reorder this.cachedCategorizedOrderedRooms.defaultRooms = (0, _tagSorting.sortRoomsWithAlgorithm)([...this.cachedCategorizedOrderedRooms.defaultRooms, room], this.tagId, this.sortingAlgorithm); // rebuild this.buildCachedOrderedRooms(); return true; } } return false; } } exports.NaturalAlgorithm = NaturalAlgorithm; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbG9nZ2VyIiwicmVxdWlyZSIsIl90YWdTb3J0aW5nIiwiX09yZGVyaW5nQWxnb3JpdGhtIiwiX21vZGVscyIsIl9Sb29tTm90aWZpY2F0aW9uU3RhdGVTdG9yZSIsIk5hdHVyYWxBbGdvcml0aG0iLCJPcmRlcmluZ0FsZ29yaXRobSIsImNvbnN0cnVjdG9yIiwidGFnSWQiLCJpbml0aWFsU29ydGluZ0FsZ29yaXRobSIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJkZWZhdWx0IiwiZGVmYXVsdFJvb21zIiwibXV0ZWRSb29tcyIsInNldFJvb21zIiwicm9vbXMiLCJjYXRlZ29yaXplUm9vbXMiLCJjYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcyIsInNvcnRSb29tc1dpdGhBbGdvcml0aG0iLCJzb3J0aW5nQWxnb3JpdGhtIiwiYnVpbGRDYWNoZWRPcmRlcmVkUm9vbXMiLCJoYW5kbGVSb29tVXBkYXRlIiwicm9vbSIsImNhdXNlIiwiaXNTcGxpY2UiLCJSb29tVXBkYXRlQ2F1c2UiLCJOZXdSb29tIiwiUm9vbVJlbW92ZWQiLCJpc0luUGxhY2UiLCJUaW1lbGluZSIsIlJlYWRSZWNlaXB0IiwiUG9zc2libGVNdXRlQ2hhbmdlIiwiaXNNdXRlZCIsImlzTXV0ZWRUb0JvdHRvbSIsImdldFJvb21Jc011dGVkIiwiRXJyb3IiLCJyZW1vdmVSb29tIiwib25Qb3NzaWJsZU11dGVDaGFuZ2UiLCJkZWZhdWx0SW5kZXgiLCJmaW5kSW5kZXgiLCJyIiwicm9vbUlkIiwic3BsaWNlIiwibXV0ZWRJbmRleCIsImxvZ2dlciIsIndhcm4iLCJjYWNoZWRPcmRlcmVkUm9vbXMiLCJzdGF0ZSIsIlJvb21Ob3RpZmljYXRpb25TdGF0ZVN0b3JlIiwiaW5zdGFuY2UiLCJnZXRSb29tU3RhdGUiLCJtdXRlZCIsInJlZHVjZSIsImFjYyIsInB1c2giLCJleHBvcnRzIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL3N0b3Jlcy9yb29tLWxpc3QvYWxnb3JpdGhtcy9saXN0LW9yZGVyaW5nL05hdHVyYWxBbGdvcml0aG0udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMjAgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IHsgUm9vbSB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9tYXRyaXhcIjtcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9sb2dnZXJcIjtcblxuaW1wb3J0IHsgU29ydEFsZ29yaXRobSB9IGZyb20gXCIuLi9tb2RlbHNcIjtcbmltcG9ydCB7IHNvcnRSb29tc1dpdGhBbGdvcml0aG0gfSBmcm9tIFwiLi4vdGFnLXNvcnRpbmdcIjtcbmltcG9ydCB7IE9yZGVyaW5nQWxnb3JpdGhtIH0gZnJvbSBcIi4vT3JkZXJpbmdBbGdvcml0aG1cIjtcbmltcG9ydCB7IFJvb21VcGRhdGVDYXVzZSwgVGFnSUQgfSBmcm9tIFwiLi4vLi4vbW9kZWxzXCI7XG5pbXBvcnQgeyBSb29tTm90aWZpY2F0aW9uU3RhdGVTdG9yZSB9IGZyb20gXCIuLi8uLi8uLi9ub3RpZmljYXRpb25zL1Jvb21Ob3RpZmljYXRpb25TdGF0ZVN0b3JlXCI7XG5cbnR5cGUgTmF0dXJhbENhdGVnb3JpemVkUm9vbU1hcCA9IHtcbiAgICBkZWZhdWx0Um9vbXM6IFJvb21bXTtcbiAgICBtdXRlZFJvb21zOiBSb29tW107XG59O1xuXG4vKipcbiAqIFVzZXMgdGhlIG5hdHVyYWwgdGFnIHNvcnRpbmcgYWxnb3JpdGhtIG9yZGVyIHRvIGRldGVybWluZSB0YWcgb3JkZXJpbmcuIE5vXG4gKiBhZGRpdGlvbmFsIGJlaGF2aW91cmFsIGNoYW5nZXMgYXJlIHByZXNlbnQuXG4gKi9cbmV4cG9ydCBjbGFzcyBOYXR1cmFsQWxnb3JpdGhtIGV4dGVuZHMgT3JkZXJpbmdBbGdvcml0aG0ge1xuICAgIHByaXZhdGUgY2FjaGVkQ2F0ZWdvcml6ZWRPcmRlcmVkUm9vbXM6IE5hdHVyYWxDYXRlZ29yaXplZFJvb21NYXAgPSB7XG4gICAgICAgIGRlZmF1bHRSb29tczogW10sXG4gICAgICAgIG11dGVkUm9vbXM6IFtdLFxuICAgIH07XG4gICAgcHVibGljIGNvbnN0cnVjdG9yKHRhZ0lkOiBUYWdJRCwgaW5pdGlhbFNvcnRpbmdBbGdvcml0aG06IFNvcnRBbGdvcml0aG0pIHtcbiAgICAgICAgc3VwZXIodGFnSWQsIGluaXRpYWxTb3J0aW5nQWxnb3JpdGhtKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0Um9vbXMocm9vbXM6IFJvb21bXSk6IHZvaWQge1xuICAgICAgICBjb25zdCB7IGRlZmF1bHRSb29tcywgbXV0ZWRSb29tcyB9ID0gdGhpcy5jYXRlZ29yaXplUm9vbXMocm9vbXMpO1xuXG4gICAgICAgIHRoaXMuY2FjaGVkQ2F0ZWdvcml6ZWRPcmRlcmVkUm9vbXMgPSB7XG4gICAgICAgICAgICBkZWZhdWx0Um9vbXM6IHNvcnRSb29tc1dpdGhBbGdvcml0aG0oZGVmYXVsdFJvb21zLCB0aGlzLnRhZ0lkLCB0aGlzLnNvcnRpbmdBbGdvcml0aG0pLFxuICAgICAgICAgICAgbXV0ZWRSb29tczogc29ydFJvb21zV2l0aEFsZ29yaXRobShtdXRlZFJvb21zLCB0aGlzLnRhZ0lkLCB0aGlzLnNvcnRpbmdBbGdvcml0aG0pLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLmJ1aWxkQ2FjaGVkT3JkZXJlZFJvb21zKCk7XG4gICAgfVxuXG4gICAgcHVibGljIGhhbmRsZVJvb21VcGRhdGUocm9vbTogUm9vbSwgY2F1c2U6IFJvb21VcGRhdGVDYXVzZSk6IGJvb2xlYW4ge1xuICAgICAgICBjb25zdCBpc1NwbGljZSA9IGNhdXNlID09PSBSb29tVXBkYXRlQ2F1c2UuTmV3Um9vbSB8fCBjYXVzZSA9PT0gUm9vbVVwZGF0ZUNhdXNlLlJvb21SZW1vdmVkO1xuICAgICAgICBjb25zdCBpc0luUGxhY2UgPVxuICAgICAgICAgICAgY2F1c2UgPT09IFJvb21VcGRhdGVDYXVzZS5UaW1lbGluZSB8fFxuICAgICAgICAgICAgY2F1c2UgPT09IFJvb21VcGRhdGVDYXVzZS5SZWFkUmVjZWlwdCB8fFxuICAgICAgICAgICAgY2F1c2UgPT09IFJvb21VcGRhdGVDYXVzZS5Qb3NzaWJsZU11dGVDaGFuZ2U7XG4gICAgICAgIGNvbnN0IGlzTXV0ZWQgPSB0aGlzLmlzTXV0ZWRUb0JvdHRvbSAmJiB0aGlzLmdldFJvb21Jc011dGVkKHJvb20pO1xuXG4gICAgICAgIGlmICghaXNTcGxpY2UgJiYgIWlzSW5QbGFjZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCB1cGRhdGUgY2F1c2U6ICR7Y2F1c2V9YCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoY2F1c2UgPT09IFJvb21VcGRhdGVDYXVzZS5OZXdSb29tKSB7XG4gICAgICAgICAgICBpZiAoaXNNdXRlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY2FjaGVkQ2F0ZWdvcml6ZWRPcmRlcmVkUm9vbXMubXV0ZWRSb29tcyA9IHNvcnRSb29tc1dpdGhBbGdvcml0aG0oXG4gICAgICAgICAgICAgICAgICAgIFsuLi50aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLm11dGVkUm9vbXMsIHJvb21dLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRhZ0lkLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNvcnRpbmdBbGdvcml0aG0sXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcy5kZWZhdWx0Um9vbXMgPSBzb3J0Um9vbXNXaXRoQWxnb3JpdGhtKFxuICAgICAgICAgICAgICAgICAgICBbLi4udGhpcy5jYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcy5kZWZhdWx0Um9vbXMsIHJvb21dLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRhZ0lkLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNvcnRpbmdBbGdvcml0aG0sXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuYnVpbGRDYWNoZWRPcmRlcmVkUm9vbXMoKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKGNhdXNlID09PSBSb29tVXBkYXRlQ2F1c2UuUm9vbVJlbW92ZWQpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnJlbW92ZVJvb20ocm9vbSk7XG4gICAgICAgIH0gZWxzZSBpZiAoY2F1c2UgPT09IFJvb21VcGRhdGVDYXVzZS5Qb3NzaWJsZU11dGVDaGFuZ2UpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmlzTXV0ZWRUb0JvdHRvbSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9uUG9zc2libGVNdXRlQ2hhbmdlKHJvb20pO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBUT0RPOiBPcHRpbWl6ZSB0aGlzIHRvIGF2b2lkIHVzZWxlc3Mgb3BlcmF0aW9uczogaHR0cHM6Ly9naXRodWIuY29tL3ZlY3Rvci1pbS9lbGVtZW50LXdlYi9pc3N1ZXMvMTQ0NTdcbiAgICAgICAgLy8gRm9yIGV4YW1wbGUsIHdlIGNhbiBza2lwIHVwZGF0ZXMgdG8gYWxwaGFiZXRpYyAoc29tZXRpbWVzKSBhbmQgbWFudWFsbHkgb3JkZXJlZCB0YWdzXG4gICAgICAgIGlmIChpc011dGVkKSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLm11dGVkUm9vbXMgPSBzb3J0Um9vbXNXaXRoQWxnb3JpdGhtKFxuICAgICAgICAgICAgICAgIHRoaXMuY2FjaGVkQ2F0ZWdvcml6ZWRPcmRlcmVkUm9vbXMubXV0ZWRSb29tcyxcbiAgICAgICAgICAgICAgICB0aGlzLnRhZ0lkLFxuICAgICAgICAgICAgICAgIHRoaXMuc29ydGluZ0FsZ29yaXRobSxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLmRlZmF1bHRSb29tcyA9IHNvcnRSb29tc1dpdGhBbGdvcml0aG0oXG4gICAgICAgICAgICAgICAgdGhpcy5jYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcy5kZWZhdWx0Um9vbXMsXG4gICAgICAgICAgICAgICAgdGhpcy50YWdJZCxcbiAgICAgICAgICAgICAgICB0aGlzLnNvcnRpbmdBbGdvcml0aG0sXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYnVpbGRDYWNoZWRPcmRlcmVkUm9vbXMoKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGEgcm9vbSBmcm9tIHRoZSBjYWNoZWQgcm9vbSBsaXN0XG4gICAgICogQHBhcmFtIHJvb20gUm9vbSB0byByZW1vdmVcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSB3aGVuIHJvb20gbGlzdCBzaG91bGQgdXBkYXRlIGFzIHJlc3VsdFxuICAgICAqL1xuICAgIHByaXZhdGUgcmVtb3ZlUm9vbShyb29tOiBSb29tKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGRlZmF1bHRJbmRleCA9IHRoaXMuY2FjaGVkQ2F0ZWdvcml6ZWRPcmRlcmVkUm9vbXMuZGVmYXVsdFJvb21zLmZpbmRJbmRleCgocikgPT4gci5yb29tSWQgPT09IHJvb20ucm9vbUlkKTtcbiAgICAgICAgaWYgKGRlZmF1bHRJbmRleCA+IC0xKSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLmRlZmF1bHRSb29tcy5zcGxpY2UoZGVmYXVsdEluZGV4LCAxKTtcbiAgICAgICAgICAgIHRoaXMuYnVpbGRDYWNoZWRPcmRlcmVkUm9vbXMoKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG11dGVkSW5kZXggPSB0aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLm11dGVkUm9vbXMuZmluZEluZGV4KChyKSA9PiByLnJvb21JZCA9PT0gcm9vbS5yb29tSWQpO1xuICAgICAgICBpZiAobXV0ZWRJbmRleCA+IC0xKSB7XG4gICAgICAgICAgICB0aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLm11dGVkUm9vbXMuc3BsaWNlKG11dGVkSW5kZXgsIDEpO1xuICAgICAgICAgICAgdGhpcy5idWlsZENhY2hlZE9yZGVyZWRSb29tcygpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBsb2dnZXIud2FybihgVHJpZWQgdG8gcmVtb3ZlIHVua25vd24gcm9vbSBmcm9tICR7dGhpcy50YWdJZH06ICR7cm9vbS5yb29tSWR9YCk7XG4gICAgICAgIC8vIHJvb20gd2FzIG5vdCBpbiBjYWNoZWQgbGlzdHMsIG5vIHVwZGF0ZVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0cyBjYWNoZWRPcmRlcmVkUm9vbXMgZnJvbSBjYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tc1xuICAgICAqL1xuICAgIHByaXZhdGUgYnVpbGRDYWNoZWRPcmRlcmVkUm9vbXMoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2FjaGVkT3JkZXJlZFJvb21zID0gW1xuICAgICAgICAgICAgLi4udGhpcy5jYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcy5kZWZhdWx0Um9vbXMsXG4gICAgICAgICAgICAuLi50aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLm11dGVkUm9vbXMsXG4gICAgICAgIF07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRSb29tSXNNdXRlZChyb29tOiBSb29tKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIEl0J3MgZmluZSBmb3IgdXMgdG8gY2FsbCB0aGlzIGEgbG90IGJlY2F1c2UgaXQncyBjYWNoZWQsIGFuZCB3ZSBzaG91bGRuJ3QgYmVcbiAgICAgICAgLy8gd2FzdGluZyBhbnl0aGluZyBieSBkb2luZyBzbyBhcyB0aGUgc3RvcmUgaG9sZHMgc2luZ2xlIHJlZmVyZW5jZXNcbiAgICAgICAgY29uc3Qgc3RhdGUgPSBSb29tTm90aWZpY2F0aW9uU3RhdGVTdG9yZS5pbnN0YW5jZS5nZXRSb29tU3RhdGUocm9vbSk7XG4gICAgICAgIHJldHVybiBzdGF0ZS5tdXRlZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNhdGVnb3JpemVSb29tcyhyb29tczogUm9vbVtdKTogTmF0dXJhbENhdGVnb3JpemVkUm9vbU1hcCB7XG4gICAgICAgIGlmICghdGhpcy5pc011dGVkVG9Cb3R0b20pIHtcbiAgICAgICAgICAgIHJldHVybiB7IGRlZmF1bHRSb29tczogcm9vbXMsIG11dGVkUm9vbXM6IFtdIH07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJvb21zLnJlZHVjZTxOYXR1cmFsQ2F0ZWdvcml6ZWRSb29tTWFwPihcbiAgICAgICAgICAgIChhY2MsIHJvb206IFJvb20pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5nZXRSb29tSXNNdXRlZChyb29tKSkge1xuICAgICAgICAgICAgICAgICAgICBhY2MubXV0ZWRSb29tcy5wdXNoKHJvb20pO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGFjYy5kZWZhdWx0Um9vbXMucHVzaChyb29tKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFjYztcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7IGRlZmF1bHRSb29tczogW10sIG11dGVkUm9vbXM6IFtdIH0gYXMgTmF0dXJhbENhdGVnb3JpemVkUm9vbU1hcCxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIG9uUG9zc2libGVNdXRlQ2hhbmdlKHJvb206IFJvb20pOiBib29sZWFuIHtcbiAgICAgICAgY29uc3QgaXNNdXRlZCA9IHRoaXMuZ2V0Um9vbUlzTXV0ZWQocm9vbSk7XG4gICAgICAgIGlmIChpc011dGVkKSB7XG4gICAgICAgICAgICBjb25zdCBkZWZhdWx0SW5kZXggPSB0aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLmRlZmF1bHRSb29tcy5maW5kSW5kZXgoXG4gICAgICAgICAgICAgICAgKHIpID0+IHIucm9vbUlkID09PSByb29tLnJvb21JZCxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIC8vIHJvb20gaGFzIGJlZW4gbXV0ZWRcbiAgICAgICAgICAgIGlmIChkZWZhdWx0SW5kZXggPiAtMSkge1xuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBmcm9tIHRoZSBkZWZhdWx0IGxpc3RcbiAgICAgICAgICAgICAgICB0aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLmRlZmF1bHRSb29tcy5zcGxpY2UoZGVmYXVsdEluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICAvLyBhZGQgdG8gbXV0ZWQgbGlzdCBhbmQgcmVvcmRlclxuICAgICAgICAgICAgICAgIHRoaXMuY2FjaGVkQ2F0ZWdvcml6ZWRPcmRlcmVkUm9vbXMubXV0ZWRSb29tcyA9IHNvcnRSb29tc1dpdGhBbGdvcml0aG0oXG4gICAgICAgICAgICAgICAgICAgIFsuLi50aGlzLmNhY2hlZENhdGVnb3JpemVkT3JkZXJlZFJvb21zLm11dGVkUm9vbXMsIHJvb21dLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRhZ0lkLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNvcnRpbmdBbGdvcml0aG0sXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAvLyByZWJ1aWxkXG4gICAgICAgICAgICAgICAgdGhpcy5idWlsZENhY2hlZE9yZGVyZWRSb29tcygpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgbXV0ZWRJbmRleCA9IHRoaXMuY2FjaGVkQ2F0ZWdvcml6ZWRPcmRlcmVkUm9vbXMubXV0ZWRSb29tcy5maW5kSW5kZXgoKHIpID0+IHIucm9vbUlkID09PSByb29tLnJvb21JZCk7XG5cbiAgICAgICAgICAgIC8vIHJvb20gaGFzIGJlZW4gdW5tdXRlZFxuICAgICAgICAgICAgaWYgKG11dGVkSW5kZXggPiAtMSkge1xuICAgICAgICAgICAgICAgIC8vIHJlbW92ZSBmcm9tIHRoZSBtdXRlZCBsaXN0XG4gICAgICAgICAgICAgICAgdGhpcy5jYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcy5tdXRlZFJvb21zLnNwbGljZShtdXRlZEluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICAvLyBhZGQgdG8gZGVmYXVsdCBsaXN0IGFuZCByZW9yZGVyXG4gICAgICAgICAgICAgICAgdGhpcy5jYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcy5kZWZhdWx0Um9vbXMgPSBzb3J0Um9vbXNXaXRoQWxnb3JpdGhtKFxuICAgICAgICAgICAgICAgICAgICBbLi4udGhpcy5jYWNoZWRDYXRlZ29yaXplZE9yZGVyZWRSb29tcy5kZWZhdWx0Um9vbXMsIHJvb21dLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRhZ0lkLFxuICAgICAgICAgICAgICAgICAgICB0aGlzLnNvcnRpbmdBbGdvcml0aG0sXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAvLyByZWJ1aWxkXG4gICAgICAgICAgICAgICAgdGhpcy5idWlsZENhY2hlZE9yZGVyZWRSb29tcygpO1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFTQSxJQUFBQSxPQUFBLEdBQUFDLE9BQUE7QUFHQSxJQUFBQyxXQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxrQkFBQSxHQUFBRixPQUFBO0FBQ0EsSUFBQUcsT0FBQSxHQUFBSCxPQUFBO0FBQ0EsSUFBQUksMkJBQUEsR0FBQUosT0FBQTtBQWZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQWdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNPLE1BQU1LLGdCQUFnQixTQUFTQyxvQ0FBaUIsQ0FBQztFQUs3Q0MsV0FBV0EsQ0FBQ0MsS0FBWSxFQUFFQyx1QkFBc0MsRUFBRTtJQUNyRSxLQUFLLENBQUNELEtBQUssRUFBRUMsdUJBQXVCLENBQUM7SUFBQyxJQUFBQyxnQkFBQSxDQUFBQyxPQUFBLHlDQUx5QjtNQUMvREMsWUFBWSxFQUFFLEVBQUU7TUFDaEJDLFVBQVUsRUFBRTtJQUNoQixDQUFDO0VBR0Q7RUFFT0MsUUFBUUEsQ0FBQ0MsS0FBYSxFQUFRO0lBQ2pDLE1BQU07TUFBRUgsWUFBWTtNQUFFQztJQUFXLENBQUMsR0FBRyxJQUFJLENBQUNHLGVBQWUsQ0FBQ0QsS0FBSyxDQUFDO0lBRWhFLElBQUksQ0FBQ0UsNkJBQTZCLEdBQUc7TUFDakNMLFlBQVksRUFBRSxJQUFBTSxrQ0FBc0IsRUFBQ04sWUFBWSxFQUFFLElBQUksQ0FBQ0osS0FBSyxFQUFFLElBQUksQ0FBQ1csZ0JBQWdCLENBQUM7TUFDckZOLFVBQVUsRUFBRSxJQUFBSyxrQ0FBc0IsRUFBQ0wsVUFBVSxFQUFFLElBQUksQ0FBQ0wsS0FBSyxFQUFFLElBQUksQ0FBQ1csZ0JBQWdCO0lBQ3BGLENBQUM7SUFDRCxJQUFJLENBQUNDLHVCQUF1QixDQUFDLENBQUM7RUFDbEM7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