matrix-react-sdk
Version:
SDK for matrix.org using React
274 lines (219 loc) • 30.9 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _SettingsStore = _interopRequireDefault(require("../../../settings/SettingsStore"));
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var sdk = _interopRequireWildcard(require("../../../index"));
var _dispatcher = _interopRequireDefault(require("../../../dispatcher/dispatcher"));
var _languageHandler = require("../../../languageHandler");
var _MatrixClientPeg = require("../../../MatrixClientPeg");
var _actions = require("../../../dispatcher/actions");
var _replaceableComponent = require("../../../utils/replaceableComponent");
var _dec, _class, _class2, _temp;
let MemberTile = (_dec = (0, _replaceableComponent.replaceableComponent)("views.rooms.MemberTile"), _dec(_class = (_temp = _class2 = class MemberTile extends _react.default.Component {
constructor(props) {
super(props);
(0, _defineProperty2.default)(this, "onRoomStateEvents", ev => {
if (ev.getType() !== "m.room.encryption") return;
const {
roomId
} = this.props.member;
if (ev.getRoomId() !== roomId) return; // The room is encrypted now.
const cli = _MatrixClientPeg.MatrixClientPeg.get();
cli.removeListener("RoomState.events", this.onRoomStateEvents);
this.setState({
isRoomEncrypted: true
});
this.updateE2EStatus();
});
(0, _defineProperty2.default)(this, "onUserTrustStatusChanged", (userId, trustStatus) => {
if (userId !== this.props.member.userId) return;
this.updateE2EStatus();
});
(0, _defineProperty2.default)(this, "onDeviceVerificationChanged", (userId, deviceId, deviceInfo) => {
if (userId !== this.props.member.userId) return;
this.updateE2EStatus();
});
(0, _defineProperty2.default)(this, "_onStatusMessageCommitted", () => {
// The `User` object has observed a status message change.
this.setState({
statusMessage: this.getStatusMessage()
});
});
(0, _defineProperty2.default)(this, "onClick", e => {
_dispatcher.default.dispatch({
action: _actions.Action.ViewUser,
member: this.props.member
});
});
this.state = {
statusMessage: this.getStatusMessage(),
isRoomEncrypted: false,
e2eStatus: null
};
}
componentDidMount() {
const cli = _MatrixClientPeg.MatrixClientPeg.get();
if (_SettingsStore.default.getValue("feature_custom_status")) {
const {
user
} = this.props.member;
if (user) {
user.on("User._unstable_statusMessage", this._onStatusMessageCommitted);
}
}
const {
roomId
} = this.props.member;
if (roomId) {
const isRoomEncrypted = cli.isRoomEncrypted(roomId);
this.setState({
isRoomEncrypted
});
if (isRoomEncrypted) {
cli.on("userTrustStatusChanged", this.onUserTrustStatusChanged);
cli.on("deviceVerificationChanged", this.onDeviceVerificationChanged);
this.updateE2EStatus();
} else {
// Listen for room to become encrypted
cli.on("RoomState.events", this.onRoomStateEvents);
}
}
}
componentWillUnmount() {
const cli = _MatrixClientPeg.MatrixClientPeg.get();
const {
user
} = this.props.member;
if (user) {
user.removeListener("User._unstable_statusMessage", this._onStatusMessageCommitted);
}
if (cli) {
cli.removeListener("RoomState.events", this.onRoomStateEvents);
cli.removeListener("userTrustStatusChanged", this.onUserTrustStatusChanged);
cli.removeListener("deviceVerificationChanged", this.onDeviceVerificationChanged);
}
}
async updateE2EStatus() {
const cli = _MatrixClientPeg.MatrixClientPeg.get();
const {
userId
} = this.props.member;
const isMe = userId === cli.getUserId();
const userTrust = cli.checkUserTrust(userId);
if (!userTrust.isCrossSigningVerified()) {
this.setState({
e2eStatus: userTrust.wasCrossSigningVerified() ? "warning" : "normal"
});
return;
}
const devices = cli.getStoredDevicesForUser(userId);
const anyDeviceUnverified = devices.some(device => {
const {
deviceId
} = device; // For your own devices, we use the stricter check of cross-signing
// verification to encourage everyone to trust their own devices via
// cross-signing so that other users can then safely trust you.
// For other people's devices, the more general verified check that
// includes locally verified devices can be used.
const deviceTrust = cli.checkDeviceTrust(userId, deviceId);
return isMe ? !deviceTrust.isCrossSigningVerified() : !deviceTrust.isVerified();
});
this.setState({
e2eStatus: anyDeviceUnverified ? "warning" : "verified"
});
}
getStatusMessage() {
const {
user
} = this.props.member;
if (!user) {
return "";
}
return user._unstable_statusMessage;
}
shouldComponentUpdate(nextProps, nextState) {
if (this.member_last_modified_time === undefined || this.member_last_modified_time < nextProps.member.getLastModifiedTime()) {
return true;
}
if (nextProps.member.user && (this.user_last_modified_time === undefined || this.user_last_modified_time < nextProps.member.user.getLastModifiedTime())) {
return true;
}
if (nextState.isRoomEncrypted !== this.state.isRoomEncrypted || nextState.e2eStatus !== this.state.e2eStatus) {
return true;
}
return false;
}
_getDisplayName() {
return this.props.member.name;
}
getPowerLabel() {
return (0, _languageHandler._t)("%(userName)s (power %(powerLevelNumber)s)", {
userName: this.props.member.userId,
powerLevelNumber: this.props.member.powerLevel
});
}
render() {
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
const EntityTile = sdk.getComponent('rooms.EntityTile');
const member = this.props.member;
const name = this._getDisplayName();
const presenceState = member.user ? member.user.presence : null;
let statusMessage = null;
if (member.user && _SettingsStore.default.getValue("feature_custom_status")) {
statusMessage = this.state.statusMessage;
}
const av = /*#__PURE__*/_react.default.createElement(MemberAvatar, {
member: member,
width: 36,
height: 36,
"aria-hidden": "true"
});
if (member.user) {
this.user_last_modified_time = member.user.getLastModifiedTime();
}
this.member_last_modified_time = member.getLastModifiedTime();
const powerStatusMap = new Map([[100, EntityTile.POWER_STATUS_ADMIN], [50, EntityTile.POWER_STATUS_MODERATOR]]); // Find the nearest power level with a badge
let powerLevel = this.props.member.powerLevel;
for (const [pl] of powerStatusMap) {
if (this.props.member.powerLevel >= pl) {
powerLevel = pl;
break;
}
}
const powerStatus = powerStatusMap.get(powerLevel);
let e2eStatus;
if (this.state.isRoomEncrypted) {
e2eStatus = this.state.e2eStatus;
}
return /*#__PURE__*/_react.default.createElement(EntityTile, (0, _extends2.default)({}, this.props, {
presenceState: presenceState,
presenceLastActiveAgo: member.user ? member.user.lastActiveAgo : 0,
presenceLastTs: member.user ? member.user.lastPresenceTs : 0,
presenceCurrentlyActive: member.user ? member.user.currentlyActive : false,
avatarJsx: av,
title: this.getPowerLabel(),
name: name,
powerStatus: powerStatus,
showPresence: this.props.showPresence,
subtextLabel: statusMessage,
e2eStatus: e2eStatus,
onClick: this.onClick
}));
}
}, (0, _defineProperty2.default)(_class2, "propTypes", {
member: _propTypes.default.any.isRequired,
// RoomMember
showPresence: _propTypes.default.bool
}), (0, _defineProperty2.default)(_class2, "defaultProps", {
showPresence: true
}), _temp)) || _class);
exports.default = MemberTile;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL3Jvb21zL01lbWJlclRpbGUuanMiXSwibmFtZXMiOlsiTWVtYmVyVGlsZSIsIlJlYWN0IiwiQ29tcG9uZW50IiwiY29uc3RydWN0b3IiLCJwcm9wcyIsImV2IiwiZ2V0VHlwZSIsInJvb21JZCIsIm1lbWJlciIsImdldFJvb21JZCIsImNsaSIsIk1hdHJpeENsaWVudFBlZyIsImdldCIsInJlbW92ZUxpc3RlbmVyIiwib25Sb29tU3RhdGVFdmVudHMiLCJzZXRTdGF0ZSIsImlzUm9vbUVuY3J5cHRlZCIsInVwZGF0ZUUyRVN0YXR1cyIsInVzZXJJZCIsInRydXN0U3RhdHVzIiwiZGV2aWNlSWQiLCJkZXZpY2VJbmZvIiwic3RhdHVzTWVzc2FnZSIsImdldFN0YXR1c01lc3NhZ2UiLCJlIiwiZGlzIiwiZGlzcGF0Y2giLCJhY3Rpb24iLCJBY3Rpb24iLCJWaWV3VXNlciIsInN0YXRlIiwiZTJlU3RhdHVzIiwiY29tcG9uZW50RGlkTW91bnQiLCJTZXR0aW5nc1N0b3JlIiwiZ2V0VmFsdWUiLCJ1c2VyIiwib24iLCJfb25TdGF0dXNNZXNzYWdlQ29tbWl0dGVkIiwib25Vc2VyVHJ1c3RTdGF0dXNDaGFuZ2VkIiwib25EZXZpY2VWZXJpZmljYXRpb25DaGFuZ2VkIiwiY29tcG9uZW50V2lsbFVubW91bnQiLCJpc01lIiwiZ2V0VXNlcklkIiwidXNlclRydXN0IiwiY2hlY2tVc2VyVHJ1c3QiLCJpc0Nyb3NzU2lnbmluZ1ZlcmlmaWVkIiwid2FzQ3Jvc3NTaWduaW5nVmVyaWZpZWQiLCJkZXZpY2VzIiwiZ2V0U3RvcmVkRGV2aWNlc0ZvclVzZXIiLCJhbnlEZXZpY2VVbnZlcmlmaWVkIiwic29tZSIsImRldmljZSIsImRldmljZVRydXN0IiwiY2hlY2tEZXZpY2VUcnVzdCIsImlzVmVyaWZpZWQiLCJfdW5zdGFibGVfc3RhdHVzTWVzc2FnZSIsInNob3VsZENvbXBvbmVudFVwZGF0ZSIsIm5leHRQcm9wcyIsIm5leHRTdGF0ZSIsIm1lbWJlcl9sYXN0X21vZGlmaWVkX3RpbWUiLCJ1bmRlZmluZWQiLCJnZXRMYXN0TW9kaWZpZWRUaW1lIiwidXNlcl9sYXN0X21vZGlmaWVkX3RpbWUiLCJfZ2V0RGlzcGxheU5hbWUiLCJuYW1lIiwiZ2V0UG93ZXJMYWJlbCIsInVzZXJOYW1lIiwicG93ZXJMZXZlbE51bWJlciIsInBvd2VyTGV2ZWwiLCJyZW5kZXIiLCJNZW1iZXJBdmF0YXIiLCJzZGsiLCJnZXRDb21wb25lbnQiLCJFbnRpdHlUaWxlIiwicHJlc2VuY2VTdGF0ZSIsInByZXNlbmNlIiwiYXYiLCJwb3dlclN0YXR1c01hcCIsIk1hcCIsIlBPV0VSX1NUQVRVU19BRE1JTiIsIlBPV0VSX1NUQVRVU19NT0RFUkFUT1IiLCJwbCIsInBvd2VyU3RhdHVzIiwibGFzdEFjdGl2ZUFnbyIsImxhc3RQcmVzZW5jZVRzIiwiY3VycmVudGx5QWN0aXZlIiwic2hvd1ByZXNlbmNlIiwib25DbGljayIsIlByb3BUeXBlcyIsImFueSIsImlzUmVxdWlyZWQiLCJib29sIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFpQkE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7SUFHcUJBLFUsV0FEcEIsZ0RBQXFCLHdCQUFyQixDLG1DQUFELE1BQ3FCQSxVQURyQixTQUN3Q0MsZUFBTUMsU0FEOUMsQ0FDd0Q7QUFVcERDLEVBQUFBLFdBQVcsQ0FBQ0MsS0FBRCxFQUFRO0FBQ2YsVUFBTUEsS0FBTjtBQURlLDZEQXVEQ0MsRUFBRSxJQUFJO0FBQ3RCLFVBQUlBLEVBQUUsQ0FBQ0MsT0FBSCxPQUFpQixtQkFBckIsRUFBMEM7QUFDMUMsWUFBTTtBQUFFQyxRQUFBQTtBQUFGLFVBQWEsS0FBS0gsS0FBTCxDQUFXSSxNQUE5QjtBQUNBLFVBQUlILEVBQUUsQ0FBQ0ksU0FBSCxPQUFtQkYsTUFBdkIsRUFBK0IsT0FIVCxDQUt0Qjs7QUFDQSxZQUFNRyxHQUFHLEdBQUdDLGlDQUFn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QVBYO0FBUUksTUFBQSxJQUFJLEVBQUVELElBUlY7QUFTSSxNQUFBLFdBQVcsRUFBRWtCLFdBVGpCO0FBVUksTUFBQSxZQUFZLEVBQUUsS0FBSzlFLEtBQUwsQ0FBV2tGLFlBVjdCO0FBV0ksTUFBQSxZQUFZLEVBQUVoRSxhQVhsQjtBQVlJLE1BQUEsU0FBUyxFQUFFUyxTQVpmO0FBYUksTUFBQSxPQUFPLEVBQUUsS0FBS3dEO0FBYmxCLE9BREo7QUFpQkg7O0FBek9tRCxDLHNEQUNqQztBQUNmL0UsRUFBQUEsTUFBTSxFQUFFZ0YsbUJBQVVDLEdBQVYsQ0FBY0MsVUFEUDtBQUNtQjtBQUNsQ0osRUFBQUEsWUFBWSxFQUFFRSxtQkFBVUc7QUFGVCxDLDBEQUtHO0FBQ2xCTCxFQUFBQSxZQUFZLEVBQUU7QUFESSxDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDE1LCAyMDE2IE9wZW5NYXJrZXQgTHRkXG5Db3B5cmlnaHQgMjAxOSwgMjAyMCBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuXG5MaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xueW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG5cbiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcblxuVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG5TZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG5saW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiovXG5cbmltcG9ydCBTZXR0aW5nc1N0b3JlIGZyb20gXCIuLi8uLi8uLi9zZXR0aW5ncy9TZXR0aW5nc1N0b3JlXCI7XG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IFByb3BUeXBlcyBmcm9tICdwcm9wLXR5cGVzJztcbmltcG9ydCAqIGFzIHNkayBmcm9tIFwiLi4vLi4vLi4vaW5kZXhcIjtcbmltcG9ydCBkaXMgZnJvbSBcIi4uLy4uLy4uL2Rpc3BhdGNoZXIvZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgX3QgfSBmcm9tICcuLi8uLi8uLi9sYW5ndWFnZUhhbmRsZXInO1xuaW1wb3J0IHsgTWF0cml4Q2xpZW50UGVnIH0gZnJvbSBcIi4uLy4uLy4uL01hdHJpeENsaWVudFBlZ1wiO1xuaW1wb3J0IHtBY3Rpb259IGZyb20gXCIuLi8uLi8uLi9kaXNwYXRjaGVyL2FjdGlvbnNcIjtcbmltcG9ydCB7cmVwbGFjZWFibGVDb21wb25lbnR9IGZyb20gXCIuLi8uLi8uLi91dGlscy9yZXBsYWNlYWJsZUNvbXBvbmVudFwiO1xuXG5AcmVwbGFjZWFibGVDb21wb25lbnQoXCJ2aWV3cy5yb29tcy5NZW1iZXJUaWxlXCIpXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNZW1iZXJUaWxlIGV4dGVuZHMgUmVhY3QuQ29tcG9uZW50IHtcbiAgICBzdGF0aWMgcHJvcFR5cGVzID0ge1xuICAgICAgICBtZW1iZXI6IFByb3BUeXBlcy5hbnkuaXNSZXF1aXJlZCwgLy8gUm9vbU1lbWJlclxuICAgICAgICBzaG93UHJlc2VuY2U6IFByb3BUeXBlcy5ib29sLFxuICAgIH07XG5cbiAgICBzdGF0aWMgZGVmYXVsdFByb3BzID0ge1xuICAgICAgICBzaG93UHJlc2VuY2U6IHRydWUsXG4gICAgfTtcblxuICAgIGNvbnN0cnVjdG9yKHByb3BzKSB7XG4gICAgICAgIHN1cGVyKHByb3BzKTtcblxuICAgICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAgICAgc3RhdHVzTWVzc2FnZTogdGhpcy5nZXRTdGF0dXNNZXNzYWdlKCksXG4gICAgICAgICAgICBpc1Jvb21FbmNyeXB0ZWQ6IGZhbHNlLFxuICAgICAgICAgICAgZTJlU3RhdHVzOiBudWxsLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICBjb25zdCBjbGkgPSBNYXRyaXhDbGllbnRQZWcuZ2V0KCk7XG5cbiAgICAgICAgaWYgKFNldHRpbmdzU3RvcmUuZ2V0VmFsdWUoXCJmZWF0dXJlX2N1c3RvbV9zdGF0dXNcIikpIHtcbiAgICAgICAgICAgIGNvbnN0IHsgdXNlciB9ID0gdGhpcy5wcm9wcy5tZW1iZXI7XG4gICAgICAgICAgICBpZiAodXNlcikge1xuICAgICAgICAgICAgICAgIHVzZXIub24oXCJVc2VyLl91bnN0YWJsZV9zdGF0dXNNZXNzYWdlXCIsIHRoaXMuX29uU3RhdHVzTWVzc2FnZUNvbW1pdHRlZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7IHJvb21JZCB9ID0gdGhpcy5wcm9wcy5tZW1iZXI7XG4gICAgICAgIGlmIChyb29tSWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGlzUm9vbUVuY3J5cHRlZCA9IGNsaS5pc1Jvb21FbmNyeXB0ZWQocm9vbUlkKTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIGlzUm9vbUVuY3J5cHRlZCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgaWYgKGlzUm9vbUVuY3J5cHRlZCkge1xuICAgICAgICAgICAgICAgIGNsaS5vbihcInVzZXJUcnVzdFN0YXR1c0NoYW5nZWRcIiwgdGhpcy5vblVzZXJUcnVzdFN0YXR1c0NoYW5nZWQpO1xuICAgICAgICAgICAgICAgIGNsaS5vbihcImRldmljZVZlcmlmaWNhdGlvbkNoYW5nZWRcIiwgdGhpcy5vbkRldmljZVZlcmlmaWNhdGlvbkNoYW5nZWQpO1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlRTJFU3RhdHVzKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIExpc3RlbiBmb3Igcm9vbSB0byBiZWNvbWUgZW5jcnlwdGVkXG4gICAgICAgICAgICAgICAgY2xpLm9uKFwiUm9vbVN0YXRlLmV2ZW50c1wiLCB0aGlzLm9uUm9vbVN0YXRlRXZlbnRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbXBvbmVudFdpbGxVbm1vdW50KCkge1xuICAgICAgICBjb25zdCBjbGkgPSBNYXRyaXhDbGllbnRQZWcuZ2V0KCk7XG5cbiAgICAgICAgY29uc3QgeyB1c2VyIH0gPSB0aGlzLnByb3BzLm1lbWJlcjtcbiAgICAgICAgaWYgKHVzZXIpIHtcbiAgICAgICAgICAgIHVzZXIucmVtb3ZlTGlzdGVuZXIoXG4gICAgICAgICAgICAgICAgXCJVc2VyLl91bnN0YWJsZV9zdGF0dXNNZXNzYWdlXCIsXG4gICAgICAgICAgICAgICAgdGhpcy5fb25TdGF0dXNNZXNzYWdlQ29tbWl0dGVkLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjbGkpIHtcbiAgICAgICAgICAgIGNsaS5yZW1vdmVMaXN0ZW5lcihcIlJvb21TdGF0ZS5ldmVudHNcIiwgdGhpcy5vblJvb21TdGF0ZUV2ZW50cyk7XG4gICAgICAgICAgICBjbGkucmVtb3ZlTGlzdGVuZXIoXCJ1c2VyVHJ1c3RTdGF0dXNDaGFuZ2VkXCIsIHRoaXMub25Vc2VyVHJ1c3RTdGF0dXNDaGFuZ2VkKTtcbiAgICAgICAgICAgIGNsaS5yZW1vdmVMaXN0ZW5lcihcImRldmljZVZlcmlmaWNhdGlvbkNoYW5nZWRcIiwgdGhpcy5vbkRldmljZVZlcmlmaWNhdGlvbkNoYW5nZWQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25Sb29tU3RhdGVFdmVudHMgPSBldiA9PiB7XG4gICAgICAgIGlmIChldi5nZXRUeXBlKCkgIT09IFwibS5yb29tLmVuY3J5cHRpb25cIikgcmV0dXJuO1xuICAgICAgICBjb25zdCB7IHJvb21JZCB9ID0gdGhpcy5wcm9wcy5tZW1iZXI7XG4gICAgICAgIGlmIChldi5nZXRSb29tSWQoKSAhPT0gcm9vbUlkKSByZXR1cm47XG5cbiAgICAgICAgLy8gVGhlIHJvb20gaXMgZW5jcnlwdGVkIG5vdy5cbiAgICAgICAgY29uc3QgY2xpID0gTWF0cml4Q2xpZW50UGVnLmdldCgpO1xuICAgICAgICBjbGkucmVtb3ZlTGlzdGVuZXIoXCJSb29tU3RhdGUuZXZlbnRzXCIsIHRoaXMub25Sb29tU3RhdGVFdmVudHMpO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGlzUm9vbUVuY3J5cHRlZDogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMudXBkYXRlRTJFU3RhdHVzKCk7XG4gICAgfTtcblxuICAgIG9uVXNlclRydXN0U3RhdHVzQ2hhbmdlZCA9ICh1c2VySWQsIHRydXN0U3RhdHVzKSA9PiB7XG4gICAgICAgIGlmICh1c2VySWQgIT09IHRoaXMucHJvcHMubWVtYmVyLnVzZXJJZCkgcmV0dXJuO1xuICAgICAgICB0aGlzLnVwZGF0ZUUyRVN0YXR1cygpO1xuICAgIH07XG5cbiAgICBvbkRldmljZVZlcmlmaWNhdGlvbkNoYW5nZWQgPSAodXNlcklkLCBkZXZpY2VJZCwgZGV2aWNlSW5mbykgPT4ge1xuICAgICAgICBpZiAodXNlcklkICE9PSB0aGlzLnByb3BzLm1lbWJlci51c2VySWQpIHJldHVybjtcbiAgICAgICAgdGhpcy51cGRhdGVFMkVTdGF0dXMoKTtcbiAgICB9O1xuXG4gICAgYXN5bmMgdXBkYXRlRTJFU3RhdHVzKCkge1xuICAgICAgICBjb25zdCBjbGkgPSBNYXRyaXhDbGllbnRQZWcuZ2V0KCk7XG4gICAgICAgIGNvbnN0IHsgdXNlcklkIH0gPSB0aGlzLnByb3BzLm1lbWJlcjtcbiAgICAgICAgY29uc3QgaXNNZSA9IHVzZXJJZCA9PT0gY2xpLmdldFVzZXJJZCgpO1xuICAgICAgICBjb25zdCB1c2VyVHJ1c3QgPSBjbGkuY2hlY2tVc2VyVHJ1c3QodXNlcklkKTtcbiAgICAgICAgaWYgKCF1c2VyVHJ1c3QuaXNDcm9zc1NpZ25pbmdWZXJpZmllZCgpKSB7XG4gICAgICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBlMmVTdGF0dXM6IHVzZXJUcnVzdC53YXNDcm9zc1NpZ25pbmdWZXJpZmllZCgpID8gXCJ3YXJuaW5nXCIgOiBcIm5vcm1hbFwiLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkZXZpY2VzID0gY2xpLmdldFN0b3JlZERldmljZXNGb3JVc2VyKHVzZXJJZCk7XG4gICAgICAgIGNvbnN0IGFueURldmljZVVudmVyaWZpZWQgPSBkZXZpY2VzLnNvbWUoZGV2aWNlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgZGV2aWNlSWQgfSA9IGRldmljZTtcbiAgICAgICAgICAgIC8vIEZvciB5b3VyIG93biBkZXZpY2VzLCB3ZSB1c2UgdGhlIHN0cmljdGVyIGNoZWNrIG9mIGNyb3NzLXNpZ25pbmdcbiAgICAgICAgICAgIC8vIHZlcmlmaWNhdGlvbiB0byBlbmNvdXJhZ2UgZXZlcnlvbmUgdG8gdHJ1c3QgdGhlaXIgb3duIGRldmljZXMgdmlhXG4gICAgICAgICAgICAvLyBjcm9zcy1zaWduaW5nIHNvIHRoYXQgb3RoZXIgdXNlcnMgY2FuIHRoZW4gc2FmZWx5IHRydXN0IHlvdS5cbiAgICAgICAgICAgIC8vIEZvciBvdGhlciBwZW9wbGUncyBkZXZpY2VzLCB0aGUgbW9yZSBnZW5lcmFsIHZlcmlmaWVkIGNoZWNrIHRoYXRcbiAgICAgICAgICAgIC8vIGluY2x1ZGVzIGxvY2FsbHkgdmVyaWZpZWQgZGV2aWNlcyBjYW4gYmUgdXNlZC5cbiAgICAgICAgICAgIGNvbnN0IGRldmljZVRydXN0ID0gY2xpLmNoZWNrRGV2aWNlVHJ1c3QodXNlcklkLCBkZXZpY2VJZCk7XG4gICAgICAgICAgICByZXR1cm4gaXNNZSA/ICFkZXZpY2VUcnVzdC5pc0Nyb3NzU2lnbmluZ1ZlcmlmaWVkKCkgOiAhZGV2aWNlVHJ1c3QuaXNWZXJpZmllZCgpO1xuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBlMmVTdGF0dXM6IGFueURldmljZVVudmVyaWZpZWQgPyBcIndhcm5pbmdcIiA6IFwidmVyaWZpZWRcIixcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgZ2V0U3RhdHVzTWVzc2FnZSgpIHtcbiAgICAgICAgY29uc3QgeyB1c2VyIH0gPSB0aGlzLnByb3BzLm1lbWJlcjtcbiAgICAgICAgaWYgKCF1c2VyKSB7XG4gICAgICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdXNlci5fdW5zdGFibGVfc3RhdHVzTWVzc2FnZTtcbiAgICB9XG5cbiAgICBfb25TdGF0dXNNZXNzYWdlQ29tbWl0dGVkID0gKCkgPT4ge1xuICAgICAgICAvLyBUaGUgYFVzZXJgIG9iamVjdCBoYXMgb2JzZXJ2ZWQgYSBzdGF0dXMgbWVzc2FnZSBjaGFuZ2UuXG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc3RhdHVzTWVzc2FnZTogdGhpcy5nZXRTdGF0dXNNZXNzYWdlKCksXG4gICAgICAgIH0pO1xuICAgIH07XG5cbiAgICBzaG91bGRDb21wb25lbnRVcGRhdGUobmV4dFByb3BzLCBuZXh0U3RhdGUpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdGhpcy5tZW1iZXJfbGFzdF9tb2RpZmllZF90aW1lID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICAgIHRoaXMubWVtYmVyX2xhc3RfbW9kaWZpZWRfdGltZSA8IG5leHRQcm9wcy5tZW1iZXIuZ2V0TGFzdE1vZGlmaWVkVGltZSgpXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgbmV4dFByb3BzLm1lbWJlci51c2VyICYmXG4gICAgICAgICAgICAodGhpcy51c2VyX2xhc3RfbW9kaWZpZWRfdGltZSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgICB0aGlzLnVzZXJfbGFzdF9tb2RpZmllZF90aW1lIDwgbmV4dFByb3BzLm1lbWJlci51c2VyLmdldExhc3RNb2RpZmllZFRpbWUoKSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoXG4gICAgICAgICAgICBuZXh0U3RhdGUuaXNSb29tRW5jcnlwdGVkICE9PSB0aGlzLnN0YXRlLmlzUm9vbUVuY3J5cHRlZCB8fFxuICAgICAgICAgICAgbmV4dFN0YXRlLmUyZVN0YXR1cyAhPT0gdGhpcy5zdGF0ZS5lMmVTdGF0dXNcbiAgICAgICAgKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgb25DbGljayA9IGUgPT4ge1xuICAgICAgICBkaXMuZGlzcGF0Y2goe1xuICAgICAgICAgICAgYWN0aW9uOiBBY3Rpb24uVmlld1VzZXIsXG4gICAgICAgICAgICBtZW1iZXI6IHRoaXMucHJvcHMubWVtYmVyLFxuICAgICAgICB9KTtcbiAgICB9O1xuXG4gICAgX2dldERpc3BsYXlOYW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wcy5tZW1iZXIubmFtZTtcbiAgICB9XG5cbiAgICBnZXRQb3dlckxhYmVsKCkge1xuICAgICAgICByZXR1cm4gX3QoXCIlKHVzZXJOYW1lKXMgKHBvd2VyICUocG93ZXJMZXZlbE51bWJlcilzKVwiLCB7XG4gICAgICAgICAgICB1c2VyTmFtZTogdGhpcy5wcm9wcy5tZW1iZXIudXNlcklkLFxuICAgICAgICAgICAgcG93ZXJMZXZlbE51bWJlcjogdGhpcy5wcm9wcy5tZW1iZXIucG93ZXJMZXZlbCxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmVuZGVyKCkge1xuICAgICAgICBjb25zdCBNZW1iZXJBdmF0YXIgPSBzZGsuZ2V0Q29tcG9uZW50KCdhdmF0YXJzLk1lbWJlckF2YXRhcicpO1xuICAgICAgICBjb25zdCBFbnRpdHlUaWxlID0gc2RrLmdldENvbXBvbmVudCgncm9vbXMuRW50aXR5VGlsZScpO1xuXG4gICAgICAgIGNvbnN0IG1lbWJlciA9IHRoaXMucHJvcHMubWVtYmVyO1xuICAgICAgICBjb25zdCBuYW1lID0gdGhpcy5fZ2V0RGlzcGxheU5hbWUoKTtcbiAgICAgICAgY29uc3QgcHJlc2VuY2VTdGF0ZSA9IG1lbWJlci51c2VyID8gbWVtYmVyLnVzZXIucHJlc2VuY2UgOiBudWxsO1xuXG4gICAgICAgIGxldCBzdGF0dXNNZXNzYWdlID0gbnVsbDtcbiAgICAgICAgaWYgKG1lbWJlci51c2VyICYmIFNldHRpbmdzU3RvcmUuZ2V0VmFsdWUoXCJmZWF0dXJlX2N1c3RvbV9zdGF0dXNcIikpIHtcbiAgICAgICAgICAgIHN0YXR1c01lc3NhZ2UgPSB0aGlzLnN0YXRlLnN0YXR1c01lc3NhZ2U7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhdiA9IChcbiAgICAgICAgICAgIDxNZW1iZXJBdmF0YXIgbWVtYmVyPXttZW1iZXJ9IHdpZHRoPXszNn0gaGVpZ2h0PXszNn0gYXJpYS1oaWRkZW49XCJ0cnVlXCIgLz5cbiAgICAgICAgKTtcblxuICAgICAgICBpZiAobWVtYmVyLnVzZXIpIHtcbiAgICAgICAgICAgIHRoaXMudXNlcl9sYXN0X21vZGlmaWVkX3RpbWUgPSBtZW1iZXIudXNlci5nZXRMYXN0TW9kaWZpZWRUaW1lKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5tZW1iZXJfbGFzdF9tb2RpZmllZF90aW1lID0gbWVtYmVyLmdldExhc3RNb2RpZmllZFRpbWUoKTtcblxuICAgICAgICBjb25zdCBwb3dlclN0YXR1c01hcCA9IG5ldyBNYXAoW1xuICAgICAgICAgICAgWzEwMCwgRW50aXR5VGlsZS5QT1dFUl9TVEFUVVNfQURNSU5dLFxuICAgICAgICAgICAgWzUwLCBFbnRpdHlUaWxlLlBPV0VSX1NUQVRVU19NT0RFUkFUT1JdLFxuICAgICAgICBdKTtcblxuICAgICAgICAvLyBGaW5kIHRoZSBuZWFyZXN0IHBvd2VyIGxldmVsIHdpdGggYSBiYWRnZVxuICAgICAgICBsZXQgcG93ZXJMZXZlbCA9IHRoaXMucHJvcHMubWVtYmVyLnBvd2VyTGV2ZWw7XG4gICAgICAgIGZvciAoY29uc3QgW3BsXSBvZiBwb3dlclN0YXR1c01hcCkge1xuICAgICAgICAgICAgaWYgKHRoaXMucHJvcHMubWVtYmVyLnBvd2VyTGV2ZWwgPj0gcGwpIHtcbiAgICAgICAgICAgICAgICBwb3dlckxldmVsID0gcGw7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwb3dlclN0YXR1cyA9IHBvd2VyU3RhdHVzTWFwLmdldChwb3dlckxldmVsKTtcblxuICAgICAgICBsZXQgZTJlU3RhdHVzO1xuICAgICAgICBpZiAodGhpcy5zdGF0ZS5pc1Jvb21FbmNyeXB0ZWQpIHtcbiAgICAgICAgICAgIGUyZVN0YXR1cyA9IHRoaXMuc3RhdGUuZTJlU3RhdHVzO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxFbnRpdHlUaWxlXG4gICAgICAgICAgICAgICAgey4uLnRoaXMucHJvcHN9XG4gICAgICAgICAgICAgICAgcHJlc2VuY2VTdGF0ZT17cHJlc2VuY2VTdGF0ZX1cbiAgICAgICAgICAgICAgICBwcmVzZW5jZUxhc3RBY3RpdmVBZ289e21lbWJlci51c2VyID8gbWVtYmVyLnVzZXIubGFzdEFjdGl2ZUFnbyA6IDB9XG4gICAgICAgICAgICAgICAgcHJlc2VuY2VMYXN0VHM9e21lbWJlci51c2VyID8gbWVtYmVyLnVzZXIubGFzdFByZXNlbmNlVHMgOiAwfVxuICAgICAgICAgICAgICAgIHByZXNlbmNlQ3VycmVudGx5QWN0aXZlPXttZW1iZXIudXNlciA/IG1lbWJlci51c2VyLmN1cnJlbnRseUFjdGl2ZSA6IGZhbHNlfVxuICAgICAgICAgICAgICAgIGF2YXRhckpzeD17YXZ9XG4gICAgICAgICAgICAgICAgdGl0bGU9e3RoaXMuZ2V0UG93ZXJMYWJlbCgpfVxuICAgICAgICAgICAgICAgIG5hbWU9e25hbWV9XG4gICAgICAgICAgICAgICAgcG93ZXJTdGF0dXM9e3Bvd2VyU3RhdHVzfVxuICAgICAgICAgICAgICAgIHNob3dQcmVzZW5jZT17dGhpcy5wcm9wcy5zaG93UHJlc2VuY2V9XG4gICAgICAgICAgICAgICAgc3VidGV4dExhYmVsPXtzdGF0dXNNZXNzYWdlfVxuICAgICAgICAgICAgICAgIGUyZVN0YXR1cz17ZTJlU3RhdHVzfVxuICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3RoaXMub25DbGlja31cbiAgICAgICAgICAgIC8+XG4gICAgICAgICk7XG4gICAgfVxufVxuIl19