matrix-react-sdk
Version:
SDK for matrix.org using React
230 lines (183 loc) • 28.6 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 _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var WhoIsTyping = _interopRequireWildcard(require("../../../WhoIsTyping"));
var _Timer = _interopRequireDefault(require("../../../utils/Timer"));
var _MatrixClientPeg = require("../../../MatrixClientPeg");
var _MemberAvatar = _interopRequireDefault(require("../avatars/MemberAvatar"));
var _replaceableComponent = require("../../../utils/replaceableComponent");
var _dec, _class, _class2, _temp;
let WhoIsTypingTile = (_dec = (0, _replaceableComponent.replaceableComponent)("views.rooms.WhoIsTypingTile"), _dec(_class = (_temp = _class2 = class WhoIsTypingTile extends _react.default.Component {
constructor(...args) {
super(...args);
(0, _defineProperty2.default)(this, "state", {
usersTyping: WhoIsTyping.usersTypingApartFromMe(this.props.room),
// a map with userid => Timer to delay
// hiding the "x is typing" message for a
// user so hiding it can coincide
// with the sent message by the other side
// resulting in less timeline jumpiness
delayedStopTypingTimers: {}
});
(0, _defineProperty2.default)(this, "isVisible", () => {
return this._isVisible(this.state);
});
(0, _defineProperty2.default)(this, "onRoomTimeline", (event, room) => {
if (room?.roomId === this.props.room?.roomId) {
const userId = event.getSender(); // remove user from usersTyping
const usersTyping = this.state.usersTyping.filter(m => m.userId !== userId);
this.setState({
usersTyping
}); // abort timer if any
this._abortUserTimer(userId);
}
});
(0, _defineProperty2.default)(this, "onRoomMemberTyping", (ev, member) => {
const usersTyping = WhoIsTyping.usersTypingApartFromMeAndIgnored(this.props.room);
this.setState({
delayedStopTypingTimers: this._updateDelayedStopTypingTimers(usersTyping),
usersTyping
});
});
}
componentDidMount() {
_MatrixClientPeg.MatrixClientPeg.get().on("RoomMember.typing", this.onRoomMemberTyping);
_MatrixClientPeg.MatrixClientPeg.get().on("Room.timeline", this.onRoomTimeline);
}
componentDidUpdate(_, prevState) {
const wasVisible = this._isVisible(prevState);
const isVisible = this._isVisible(this.state);
if (this.props.onShown && !wasVisible && isVisible) {
this.props.onShown();
} else if (this.props.onHidden && wasVisible && !isVisible) {
this.props.onHidden();
}
}
componentWillUnmount() {
// we may have entirely lost our client as we're logging out before clicking login on the guest bar...
const client = _MatrixClientPeg.MatrixClientPeg.get();
if (client) {
client.removeListener("RoomMember.typing", this.onRoomMemberTyping);
client.removeListener("Room.timeline", this.onRoomTimeline);
}
Object.values(this.state.delayedStopTypingTimers).forEach(t => t.abort());
}
_isVisible(state) {
return state.usersTyping.length !== 0 || Object.keys(state.delayedStopTypingTimers).length !== 0;
}
_updateDelayedStopTypingTimers(usersTyping) {
const usersThatStoppedTyping = this.state.usersTyping.filter(a => {
return !usersTyping.some(b => a.userId === b.userId);
});
const usersThatStartedTyping = usersTyping.filter(a => {
return !this.state.usersTyping.some(b => a.userId === b.userId);
}); // abort all the timers for the users that started typing again
usersThatStartedTyping.forEach(m => {
const timer = this.state.delayedStopTypingTimers[m.userId];
if (timer) {
timer.abort();
}
}); // prepare new delayedStopTypingTimers object to update state with
let delayedStopTypingTimers = Object.assign({}, this.state.delayedStopTypingTimers); // remove members that started typing again
delayedStopTypingTimers = usersThatStartedTyping.reduce((delayedStopTypingTimers, m) => {
delete delayedStopTypingTimers[m.userId];
return delayedStopTypingTimers;
}, delayedStopTypingTimers); // start timer for members that stopped typing
delayedStopTypingTimers = usersThatStoppedTyping.reduce((delayedStopTypingTimers, m) => {
if (!delayedStopTypingTimers[m.userId]) {
const timer = new _Timer.default(5000);
delayedStopTypingTimers[m.userId] = timer;
timer.start();
timer.finished().then(() => this._removeUserTimer(m.userId), // on elapsed
() => {
/* aborted */
});
}
return delayedStopTypingTimers;
}, delayedStopTypingTimers);
return delayedStopTypingTimers;
}
_abortUserTimer(userId) {
const timer = this.state.delayedStopTypingTimers[userId];
if (timer) {
timer.abort();
this._removeUserTimer(userId);
}
}
_removeUserTimer(userId) {
const timer = this.state.delayedStopTypingTimers[userId];
if (timer) {
const delayedStopTypingTimers = Object.assign({}, this.state.delayedStopTypingTimers);
delete delayedStopTypingTimers[userId];
this.setState({
delayedStopTypingTimers
});
}
}
_renderTypingIndicatorAvatars(users, limit) {
let othersCount = 0;
if (users.length > limit) {
othersCount = users.length - limit + 1;
users = users.slice(0, limit - 1);
}
const avatars = users.map(u => {
return /*#__PURE__*/_react.default.createElement(_MemberAvatar.default, {
key: u.userId,
member: u,
width: 24,
height: 24,
resizeMethod: "crop",
viewUserOnClick: true
});
});
if (othersCount > 0) {
avatars.push( /*#__PURE__*/_react.default.createElement("span", {
className: "mx_WhoIsTypingTile_remainingAvatarPlaceholder",
key: "others"
}, "+", othersCount));
}
return avatars;
}
render() {
let usersTyping = this.state.usersTyping;
const stoppedUsersOnTimer = Object.keys(this.state.delayedStopTypingTimers).map(userId => this.props.room.getMember(userId)); // append the users that have been reported not typing anymore
// but have a timeout timer running so they can disappear
// when a message comes in
usersTyping = usersTyping.concat(stoppedUsersOnTimer); // sort them so the typing members don't change order when
// moved to delayedStopTypingTimers
usersTyping.sort((a, b) => a.name.localeCompare(b.name));
const typingString = WhoIsTyping.whoIsTypingString(usersTyping, this.props.whoIsTypingLimit);
if (!typingString) {
return /*#__PURE__*/_react.default.createElement("div", {
className: "mx_WhoIsTypingTile_empty"
});
}
return /*#__PURE__*/_react.default.createElement("li", {
className: "mx_WhoIsTypingTile",
"aria-atomic": "true"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "mx_WhoIsTypingTile_avatars"
}, this._renderTypingIndicatorAvatars(usersTyping, this.props.whoIsTypingLimit)), /*#__PURE__*/_react.default.createElement("div", {
className: "mx_WhoIsTypingTile_label"
}, typingString));
}
}, (0, _defineProperty2.default)(_class2, "propTypes", {
// the room this statusbar is representing.
room: _propTypes.default.object.isRequired,
onShown: _propTypes.default.func,
onHidden: _propTypes.default.func,
// Number of names to display in typing indication. E.g. set to 3, will
// result in "X, Y, Z and 100 others are typing."
whoIsTypingLimit: _propTypes.default.number
}), (0, _defineProperty2.default)(_class2, "defaultProps", {
whoIsTypingLimit: 3
}), _temp)) || _class);
exports.default = WhoIsTypingTile;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL3Jvb21zL1dob0lzVHlwaW5nVGlsZS5qcyJdLCJuYW1lcyI6WyJXaG9Jc1R5cGluZ1RpbGUiLCJSZWFjdCIsIkNvbXBvbmVudCIsInVzZXJzVHlwaW5nIiwiV2hvSXNUeXBpbmciLCJ1c2Vyc1R5cGluZ0FwYXJ0RnJvbU1lIiwicHJvcHMiLCJyb29tIiwiZGVsYXllZFN0b3BUeXBpbmdUaW1lcnMiLCJfaXNWaXNpYmxlIiwic3RhdGUiLCJldmVudCIsInJvb21JZCIsInVzZXJJZCIsImdldFNlbmRlciIsImZpbHRlciIsIm0iLCJzZXRTdGF0ZSIsIl9hYm9ydFVzZXJUaW1lciIsImV2IiwibWVtYmVyIiwidXNlcnNUeXBpbmdBcGFydEZyb21NZUFuZElnbm9yZWQiLCJfdXBkYXRlRGVsYXllZFN0b3BUeXBpbmdUaW1lcnMiLCJjb21wb25lbnREaWRNb3VudCIsIk1hdHJpeENsaWVudFBlZyIsImdldCIsIm9uIiwib25Sb29tTWVtYmVyVHlwaW5nIiwib25Sb29tVGltZWxpbmUiLCJjb21wb25lbnREaWRVcGRhdGUiLCJfIiwicHJldlN0YXRlIiwid2FzVmlzaWJsZSIsImlzVmlzaWJsZSIsIm9uU2hvd24iLCJvbkhpZGRlbiIsImNvbXBvbmVudFdpbGxVbm1vdW50IiwiY2xpZW50IiwicmVtb3ZlTGlzdGVuZXIiLCJPYmplY3QiLCJ2YWx1ZXMiLCJmb3JFYWNoIiwidCIsImFib3J0IiwibGVuZ3RoIiwia2V5cyIsInVzZXJzVGhhdFN0b3BwZWRUeXBpbmciLCJhIiwic29tZSIsImIiLCJ1c2Vyc1RoYXRTdGFydGVkVHlwaW5nIiwidGltZXIiLCJhc3NpZ24iLCJyZWR1Y2UiLCJUaW1lciIsInN0YXJ0IiwiZmluaXNoZWQiLCJ0aGVuIiwiX3JlbW92ZVVzZXJUaW1lciIsIl9yZW5kZXJUeXBpbmdJbmRpY2F0b3JBdmF0YXJzIiwidXNlcnMiLCJsaW1pdCIsIm90aGVyc0NvdW50Iiwic2xpY2UiLCJhdmF0YXJzIiwibWFwIiwidSIsInB1c2giLCJyZW5kZXIiLCJzdG9wcGVkVXNlcnNPblRpbWVyIiwiZ2V0TWVtYmVyIiwiY29uY2F0Iiwic29ydCIsIm5hbWUiLCJsb2NhbGVDb21wYXJlIiwidHlwaW5nU3RyaW5nIiwid2hvSXNUeXBpbmdTdHJpbmciLCJ3aG9Jc1R5cGluZ0xpbWl0IiwiUHJvcFR5cGVzIiwib2JqZWN0IiwiaXNSZXF1aXJlZCIsImZ1bmMiLCJudW1iZXIiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFpQkE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7SUFHcUJBLGUsV0FEcEIsZ0RBQXFCLDZCQUFyQixDLG1DQUFELE1BQ3FCQSxlQURyQixTQUM2Q0MsZUFBTUMsU0FEbkQsQ0FDNkQ7QUFBQTtBQUFBO0FBQUEsaURBZWpEO0FBQ0pDLE1BQUFBLFdBQVcsRUFBRUMsV0FBVyxDQUFDQyxzQkFBWixDQUFtQyxLQUFLQyxLQUFMLENBQVdDLElBQTlDLENBRFQ7QUFFSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0FDLE1BQUFBLHVCQUF1QixFQUFFO0FBUHJCLEtBZmlEO0FBQUEscURBc0Q3QyxNQUFNO0FBQ2QsYUFBTyxLQUFLQyxVQUFMLENBQWdCLEtBQUtDLEtBQXJCLENBQVA7QUFDSCxLQXhEd0Q7QUFBQSwwREEwRHhDLENBQUNDLEtBQUQsRUFBUUosSUFBUixLQUFpQjtBQUM5QixVQUFJQSxJQUFJLEVBQUVLLE1BQU4sS0FBaUIsS0FBS04sS0FBTCxDQUFXQyxJQUFYLEVBQWlCSyxNQUF0QyxFQUE4QztBQUMxQyxjQUFNQyxNQUFNLEdBQUdGLEtBQUssQ0FBQ0csU0FBTixFQUFmLENBRDBDLENBRTFDOztBQUNBLGNBQU1YLFdBQVcsR0FBRyxLQUFLTyxLQUFMLENBQVdQLFdBQVgsQ0FBdUJZLE1BQXZCLENBQStCQyxDQUFELElBQU9BLENBQUMsQ0FBQ0gsTUFBRixLQUFhQSxNQUFsRCxDQUFwQjtBQUNBLGFBQUtJLFFBQUwsQ0FBYztBQUFDZCxVQUFB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QUFXdUUsZ0JBRk0sQ0FBckI7O0FBSUEsUUFBSSxDQUFDRixZQUFMLEVBQW1CO0FBQ2YsMEJBQVE7QUFBSyxRQUFBLFNBQVMsRUFBQztBQUFmLFFBQVI7QUFDSDs7QUFFRCx3QkFDSTtBQUFJLE1BQUEsU0FBUyxFQUFDLG9CQUFkO0FBQW1DLHFCQUFZO0FBQS9DLG9CQUNJO0FBQUssTUFBQSxTQUFTLEVBQUM7QUFBZixPQUNNLEtBQUtoQiw2QkFBTCxDQUFtQ3hELFdBQW5DLEVBQWdELEtBQUtHLEtBQUwsQ0FBV3VFLGdCQUEzRCxDQUROLENBREosZUFJSTtBQUFLLE1BQUEsU0FBUyxFQUFDO0FBQWYsT0FDTUYsWUFETixDQUpKLENBREo7QUFVSDs7QUFqTXdELEMsc0RBQ3RDO0FBQ2Y7QUFDQXBFLEVBQUFBLElBQUksRUFBRXVFLG1CQUFVQyxNQUFWLENBQWlCQyxVQUZSO0FBR2Y5QyxFQUFBQSxPQUFPLEVBQUU0QyxtQkFBVUcsSUFISjtBQUlmOUMsRUFBQUEsUUFBUSxFQUFFMkMsbUJBQVVHLElBSkw7QUFLZjtBQUNBO0FBQ0FKLEVBQUFBLGdCQUFnQixFQUFFQyxtQkFBVUk7QUFQYixDLDBEQVVHO0FBQ2xCTCxFQUFBQSxnQkFBZ0IsRUFBRTtBQURBLEMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuQ29weXJpZ2h0IDIwMTUsIDIwMTYgT3Blbk1hcmtldCBMdGRcbkNvcHlyaWdodCAyMDE3LCAyMDE4IE5ldyBWZWN0b3IgTHRkXG5cbkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG55b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG5Zb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG5Vbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG5kaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG5XSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cblNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbmxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuKi9cblxuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcbmltcG9ydCBQcm9wVHlwZXMgZnJvbSAncHJvcC10eXBlcyc7XG5pbXBvcnQgKiBhcyBXaG9Jc1R5cGluZyBmcm9tICcuLi8uLi8uLi9XaG9Jc1R5cGluZyc7XG5pbXBvcnQgVGltZXIgZnJvbSAnLi4vLi4vLi4vdXRpbHMvVGltZXInO1xuaW1wb3J0IHtNYXRyaXhDbGllbnRQZWd9IGZyb20gJy4uLy4uLy4uL01hdHJpeENsaWVudFBlZyc7XG5pbXBvcnQgTWVtYmVyQXZhdGFyIGZyb20gJy4uL2F2YXRhcnMvTWVtYmVyQXZhdGFyJztcbmltcG9ydCB7cmVwbGFjZWFibGVDb21wb25lbnR9IGZyb20gXCIuLi8uLi8uLi91dGlscy9yZXBsYWNlYWJsZUNvbXBvbmVudFwiO1xuXG5AcmVwbGFjZWFibGVDb21wb25lbnQoXCJ2aWV3cy5yb29tcy5XaG9Jc1R5cGluZ1RpbGVcIilcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFdob0lzVHlwaW5nVGlsZSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gICAgc3RhdGljIHByb3BUeXBlcyA9IHtcbiAgICAgICAgLy8gdGhlIHJvb20gdGhpcyBzdGF0dXNiYXIgaXMgcmVwcmVzZW50aW5nLlxuICAgICAgICByb29tOiBQcm9wVHlwZXMub2JqZWN0LmlzUmVxdWlyZWQsXG4gICAgICAgIG9uU2hvd246IFByb3BUeXBlcy5mdW5jLFxuICAgICAgICBvbkhpZGRlbjogUHJvcFR5cGVzLmZ1bmMsXG4gICAgICAgIC8vIE51bWJlciBvZiBuYW1lcyB0byBkaXNwbGF5IGluIHR5cGluZyBpbmRpY2F0aW9uLiBFLmcuIHNldCB0byAzLCB3aWxsXG4gICAgICAgIC8vIHJlc3VsdCBpbiBcIlgsIFksIFogYW5kIDEwMCBvdGhlcnMgYXJlIHR5cGluZy5cIlxuICAgICAgICB3aG9Jc1R5cGluZ0xpbWl0OiBQcm9wVHlwZXMubnVtYmVyLFxuICAgIH07XG5cbiAgICBzdGF0aWMgZGVmYXVsdFByb3BzID0ge1xuICAgICAgICB3aG9Jc1R5cGluZ0xpbWl0OiAzLFxuICAgIH07XG5cbiAgICBzdGF0ZSA9IHtcbiAgICAgICAgdXNlcnNUeXBpbmc6IFdob0lzVHlwaW5nLnVzZXJzVHlwaW5nQXBhcnRGcm9tTWUodGhpcy5wcm9wcy5yb29tKSxcbiAgICAgICAgLy8gYSBtYXAgd2l0aCB1c2VyaWQgPT4gVGltZXIgdG8gZGVsYXlcbiAgICAgICAgLy8gaGlkaW5nIHRoZSBcInggaXMgdHlwaW5nXCIgbWVzc2FnZSBmb3IgYVxuICAgICAgICAvLyB1c2VyIHNvIGhpZGluZyBpdCBjYW4gY29pbmNpZGVcbiAgICAgICAgLy8gd2l0aCB0aGUgc2VudCBtZXNzYWdlIGJ5IHRoZSBvdGhlciBzaWRlXG4gICAgICAgIC8vIHJlc3VsdGluZyBpbiBsZXNzIHRpbWVsaW5lIGp1bXBpbmVzc1xuICAgICAgICBkZWxheWVkU3RvcFR5cGluZ1RpbWVyczoge30sXG4gICAgfTtcblxuICAgIGNvbXBvbmVudERpZE1vdW50KCkge1xuICAgICAgICBNYXRyaXhDbGllbnRQZWcuZ2V0KCkub24oXCJSb29tTWVtYmVyLnR5cGluZ1wiLCB0aGlzLm9uUm9vbU1lbWJlclR5cGluZyk7XG4gICAgICAgIE1hdHJpeENsaWVudFBlZy5nZXQoKS5vbihcIlJvb20udGltZWxpbmVcIiwgdGhpcy5vblJvb21UaW1lbGluZSk7XG4gICAgfVxuXG4gICAgY29tcG9uZW50RGlkVXBkYXRlKF8sIHByZXZTdGF0ZSkge1xuICAgICAgICBjb25zdCB3YXNWaXNpYmxlID0gdGhpcy5faXNWaXNpYmxlKHByZXZTdGF0ZSk7XG4gICAgICAgIGNvbnN0IGlzVmlzaWJsZSA9IHRoaXMuX2lzVmlzaWJsZSh0aGlzLnN0YXRlKTtcbiAgICAgICAgaWYgKHRoaXMucHJvcHMub25TaG93biAmJiAhd2FzVmlzaWJsZSAmJiBpc1Zpc2libGUpIHtcbiAgICAgICAgICAgIHRoaXMucHJvcHMub25TaG93bigpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMucHJvcHMub25IaWRkZW4gJiYgd2FzVmlzaWJsZSAmJiAhaXNWaXNpYmxlKSB7XG4gICAgICAgICAgICB0aGlzLnByb3BzLm9uSGlkZGVuKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgLy8gd2UgbWF5IGhhdmUgZW50aXJlbHkgbG9zdCBvdXIgY2xpZW50IGFzIHdlJ3JlIGxvZ2dpbmcgb3V0IGJlZm9yZSBjbGlja2luZyBsb2dpbiBvbiB0aGUgZ3Vlc3QgYmFyLi4uXG4gICAgICAgIGNvbnN0IGNsaWVudCA9IE1hdHJpeENsaWVudFBlZy5nZXQoKTtcbiAgICAgICAgaWYgKGNsaWVudCkge1xuICAgICAgICAgICAgY2xpZW50LnJlbW92ZUxpc3RlbmVyKFwiUm9vbU1lbWJlci50eXBpbmdcIiwgdGhpcy5vblJvb21NZW1iZXJUeXBpbmcpO1xuICAgICAgICAgICAgY2xpZW50LnJlbW92ZUxpc3RlbmVyKFwiUm9vbS50aW1lbGluZVwiLCB0aGlzLm9uUm9vbVRpbWVsaW5lKTtcbiAgICAgICAgfVxuICAgICAgICBPYmplY3QudmFsdWVzKHRoaXMuc3RhdGUuZGVsYXllZFN0b3BUeXBpbmdUaW1lcnMpLmZvckVhY2goKHQpID0+IHQuYWJvcnQoKSk7XG4gICAgfVxuXG4gICAgX2lzVmlzaWJsZShzdGF0ZSkge1xuICAgICAgICByZXR1cm4gc3RhdGUudXNlcnNUeXBpbmcubGVuZ3RoICE9PSAwIHx8IE9iamVjdC5rZXlzKHN0YXRlLmRlbGF5ZWRTdG9wVHlwaW5nVGltZXJzKS5sZW5ndGggIT09IDA7XG4gICAgfVxuXG4gICAgaXNWaXNpYmxlID0gKCkgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5faXNWaXNpYmxlKHRoaXMuc3RhdGUpO1xuICAgIH07XG5cbiAgICBvblJvb21UaW1lbGluZSA9IChldmVudCwgcm9vbSkgPT4ge1xuICAgICAgICBpZiAocm9vbT8ucm9vbUlkID09PSB0aGlzLnByb3BzLnJvb20/LnJvb21JZCkge1xuICAgICAgICAgICAgY29uc3QgdXNlcklkID0gZXZlbnQuZ2V0U2VuZGVyKCk7XG4gICAgICAgICAgICAvLyByZW1vdmUgdXNlciBmcm9tIHVzZXJzVHlwaW5nXG4gICAgICAgICAgICBjb25zdCB1c2Vyc1R5cGluZyA9IHRoaXMuc3RhdGUudXNlcnNUeXBpbmcuZmlsdGVyKChtKSA9PiBtLnVzZXJJZCAhPT0gdXNlcklkKTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe3VzZXJzVHlwaW5nfSk7XG4gICAgICAgICAgICAvLyBhYm9ydCB0aW1lciBpZiBhbnlcbiAgICAgICAgICAgIHRoaXMuX2Fib3J0VXNlclRpbWVyKHVzZXJJZCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgb25Sb29tTWVtYmVyVHlwaW5nID0gKGV2LCBtZW1iZXIpID0+IHtcbiAgICAgICAgY29uc3QgdXNlcnNUeXBpbmcgPSBXaG9Jc1R5cGluZy51c2Vyc1R5cGluZ0FwYXJ0RnJvbU1lQW5kSWdub3JlZCh0aGlzLnByb3BzLnJvb20pO1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGRlbGF5ZWRTdG9wVHlwaW5nVGltZXJzOiB0aGlzLl91cGRhdGVEZWxheWVkU3RvcFR5cGluZ1RpbWVycyh1c2Vyc1R5cGluZyksXG4gICAgICAgICAgICB1c2Vyc1R5cGluZyxcbiAgICAgICAgfSk7XG4gICAgfTtcblxuICAgIF91cGRhdGVEZWxheWVkU3RvcFR5cGluZ1RpbWVycyh1c2Vyc1R5cGluZykge1xuICAgICAgICBjb25zdCB1c2Vyc1RoYXRTdG9wcGVkVHlwaW5nID0gdGhpcy5zdGF0ZS51c2Vyc1R5cGluZy5maWx0ZXIoKGEpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAhdXNlcnNUeXBpbmcuc29tZSgoYikgPT4gYS51c2VySWQgPT09IGIudXNlcklkKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHVzZXJzVGhhdFN0YXJ0ZWRUeXBpbmcgPSB1c2Vyc1R5cGluZy5maWx0ZXIoKGEpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAhdGhpcy5zdGF0ZS51c2Vyc1R5cGluZy5zb21lKChiKSA9PiBhLnVzZXJJZCA9PT0gYi51c2VySWQpO1xuICAgICAgICB9KTtcbiAgICAgICAgLy8gYWJvcnQgYWxsIHRoZSB0aW1lcnMgZm9yIHRoZSB1c2VycyB0aGF0IHN0YXJ0ZWQgdHlwaW5nIGFnYWluXG4gICAgICAgIHVzZXJzVGhhdFN0YXJ0ZWRUeXBpbmcuZm9yRWFjaCgobSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdGltZXIgPSB0aGlzLnN0YXRlLmRlbGF5ZWRTdG9wVHlwaW5nVGltZXJzW20udXNlcklkXTtcbiAgICAgICAgICAgIGlmICh0aW1lcikge1xuICAgICAgICAgICAgICAgIHRpbWVyLmFib3J0KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBwcmVwYXJlIG5ldyBkZWxheWVkU3RvcFR5cGluZ1RpbWVycyBvYmplY3QgdG8gdXBkYXRlIHN0YXRlIHdpdGhcbiAgICAgICAgbGV0IGRlbGF5ZWRTdG9wVHlwaW5nVGltZXJzID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5zdGF0ZS5kZWxheWVkU3RvcFR5cGluZ1RpbWVycyk7XG4gICAgICAgIC8vIHJlbW92ZSBtZW1iZXJzIHRoYXQgc3RhcnRlZCB0eXBpbmcgYWdhaW5cbiAgICAgICAgZGVsYXllZFN0b3BUeXBpbmdUaW1lcnMgPSB1c2Vyc1RoYXRTdGFydGVkVHlwaW5nLnJlZHVjZSgoZGVsYXllZFN0b3BUeXBpbmdUaW1lcnMsIG0pID0+IHtcbiAgICAgICAgICAgIGRlbGV0ZSBkZWxheWVkU3RvcFR5cGluZ1RpbWVyc1ttLnVzZXJJZF07XG4gICAgICAgICAgICByZXR1cm4gZGVsYXllZFN0b3BUeXBpbmdUaW1lcnM7XG4gICAgICAgIH0sIGRlbGF5ZWRTdG9wVHlwaW5nVGltZXJzKTtcbiAgICAgICAgLy8gc3RhcnQgdGltZXIgZm9yIG1lbWJlcnMgdGhhdCBzdG9wcGVkIHR5cGluZ1xuICAgICAgICBkZWxheWVkU3RvcFR5cGluZ1RpbWVycyA9IHVzZXJzVGhhdFN0b3BwZWRUeXBpbmcucmVkdWNlKChkZWxheWVkU3RvcFR5cGluZ1RpbWVycywgbSkgPT4ge1xuICAgICAgICAgICAgaWYgKCFkZWxheWVkU3RvcFR5cGluZ1RpbWVyc1ttLnVzZXJJZF0pIHtcbiAgICAgICAgICAgICAgICBjb25zdCB0aW1lciA9IG5ldyBUaW1lcig1MDAwKTtcbiAgICAgICAgICAgICAgICBkZWxheWVkU3RvcFR5cGluZ1RpbWVyc1ttLnVzZXJJZF0gPSB0aW1lcjtcbiAgICAgICAgICAgICAgICB0aW1lci5zdGFydCgpO1xuICAgICAgICAgICAgICAgIHRpbWVyLmZpbmlzaGVkKCkudGhlbihcbiAgICAgICAgICAgICAgICAgICAgKCkgPT4gdGhpcy5fcmVtb3ZlVXNlclRpbWVyKG0udXNlcklkKSwgLy8gb24gZWxhcHNlZFxuICAgICAgICAgICAgICAgICAgICAoKSA9PiB7LyogYWJvcnRlZCAqL30sXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBkZWxheWVkU3RvcFR5cGluZ1RpbWVycztcbiAgICAgICAgfSwgZGVsYXllZFN0b3BUeXBpbmdUaW1lcnMpO1xuXG4gICAgICAgIHJldHVybiBkZWxheWVkU3RvcFR5cGluZ1RpbWVycztcbiAgICB9XG5cbiAgICBfYWJvcnRVc2VyVGltZXIodXNlcklkKSB7XG4gICAgICAgIGNvbnN0IHRpbWVyID0gdGhpcy5zdGF0ZS5kZWxheWVkU3RvcFR5cGluZ1RpbWVyc1t1c2VySWRdO1xuICAgICAgICBpZiAodGltZXIpIHtcbiAgICAgICAgICAgIHRpbWVyLmFib3J0KCk7XG4gICAgICAgICAgICB0aGlzLl9yZW1vdmVVc2VyVGltZXIodXNlcklkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9yZW1vdmVVc2VyVGltZXIodXNlcklkKSB7XG4gICAgICAgIGNvbnN0IHRpbWVyID0gdGhpcy5zdGF0ZS5kZWxheWVkU3RvcFR5cGluZ1RpbWVyc1t1c2VySWRdO1xuICAgICAgICBpZiAodGltZXIpIHtcbiAgICAgICAgICAgIGNvbnN0IGRlbGF5ZWRTdG9wVHlwaW5nVGltZXJzID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5zdGF0ZS5kZWxheWVkU3RvcFR5cGluZ1RpbWVycyk7XG4gICAgICAgICAgICBkZWxldGUgZGVsYXllZFN0b3BUeXBpbmdUaW1lcnNbdXNlcklkXTtcbiAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe2RlbGF5ZWRTdG9wVHlwaW5nVGltZXJzfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBfcmVuZGVyVHlwaW5nSW5kaWNhdG9yQXZhdGFycyh1c2VycywgbGltaXQpIHtcbiAgICAgICAgbGV0IG90aGVyc0NvdW50ID0gMDtcbiAgICAgICAgaWYgKHVzZXJzLmxlbmd0aCA+IGxpbWl0KSB7XG4gICAgICAgICAgICBvdGhlcnNDb3VudCA9IHVzZXJzLmxlbmd0aCAtIGxpbWl0ICsgMTtcbiAgICAgICAgICAgIHVzZXJzID0gdXNlcnMuc2xpY2UoMCwgbGltaXQgLSAxKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGF2YXRhcnMgPSB1c2Vycy5tYXAoKHUpID0+IHtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgPE1lbWJlckF2YXRhclxuICAgICAgICAgICAgICAgICAgICBrZXk9e3UudXNlcklkfVxuICAgICAgICAgICAgICAgICAgICBtZW1iZXI9e3V9XG4gICAgICAgICAgICAgICAgICAgIHdpZHRoPXsyNH1cbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0PXsyNH1cbiAgICAgICAgICAgICAgICAgICAgcmVzaXplTWV0aG9kPVwiY3JvcFwiXG4gICAgICAgICAgICAgICAgICAgIHZpZXdVc2VyT25DbGljaz17dHJ1ZX1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKG90aGVyc0NvdW50ID4gMCkge1xuICAgICAgICAgICAgYXZhdGFycy5wdXNoKFxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cIm14X1dob0lzVHlwaW5nVGlsZV9yZW1haW5pbmdBdmF0YXJQbGFjZWhvbGRlclwiIGtleT1cIm90aGVyc1wiPlxuICAgICAgICAgICAgICAgICAgICAreyBvdGhlcnNDb3VudCB9XG4gICAgICAgICAgICAgICAgPC9zcGFuPixcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gYXZhdGFycztcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCB1c2Vyc1R5cGluZyA9IHRoaXMuc3RhdGUudXNlcnNUeXBpbmc7XG4gICAgICAgIGNvbnN0IHN0b3BwZWRVc2Vyc09uVGltZXIgPSBPYmplY3Qua2V5cyh0aGlzLnN0YXRlLmRlbGF5ZWRTdG9wVHlwaW5nVGltZXJzKVxuICAgICAgICAgICAgLm1hcCgodXNlcklkKSA9PiB0aGlzLnByb3BzLnJvb20uZ2V0TWVtYmVyKHVzZXJJZCkpO1xuICAgICAgICAvLyBhcHBlbmQgdGhlIHVzZXJzIHRoYXQgaGF2ZSBiZWVuIHJlcG9ydGVkIG5vdCB0eXBpbmcgYW55bW9yZVxuICAgICAgICAvLyBidXQgaGF2ZSBhIHRpbWVvdXQgdGltZXIgcnVubmluZyBzbyB0aGV5IGNhbiBkaXNhcHBlYXJcbiAgICAgICAgLy8gd2hlbiBhIG1lc3NhZ2UgY29tZXMgaW5cbiAgICAgICAgdXNlcnNUeXBpbmcgPSB1c2Vyc1R5cGluZy5jb25jYXQoc3RvcHBlZFVzZXJzT25UaW1lcik7XG4gICAgICAgIC8vIHNvcnQgdGhlbSBzbyB0aGUgdHlwaW5nIG1lbWJlcnMgZG9uJ3QgY2hhbmdlIG9yZGVyIHdoZW5cbiAgICAgICAgLy8gbW92ZWQgdG8gZGVsYXllZFN0b3BUeXBpbmdUaW1lcnNcbiAgICAgICAgdXNlcnNUeXBpbmcuc29ydCgoYSwgYikgPT4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKSk7XG5cbiAgICAgICAgY29uc3QgdHlwaW5nU3RyaW5nID0gV2hvSXNUeXBpbmcud2hvSXNUeXBpbmdTdHJpbmcoXG4gICAgICAgICAgICB1c2Vyc1R5cGluZyxcbiAgICAgICAgICAgIHRoaXMucHJvcHMud2hvSXNUeXBpbmdMaW1pdCxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCF0eXBpbmdTdHJpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiAoPGRpdiBjbGFzc05hbWU9XCJteF9XaG9Jc1R5cGluZ1RpbGVfZW1wdHlcIiAvPik7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGxpIGNsYXNzTmFtZT1cIm14X1dob0lzVHlwaW5nVGlsZVwiIGFyaWEtYXRvbWljPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibXhfV2hvSXNUeXBpbmdUaWxlX2F2YXRhcnNcIj5cbiAgICAgICAgICAgICAgICAgICAgeyB0aGlzLl9yZW5kZXJUeXBpbmdJbmRpY2F0b3JBdmF0YXJzKHVzZXJzVHlwaW5nLCB0aGlzLnByb3BzLndob0lzVHlwaW5nTGltaXQpIH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cIm14X1dob0lzVHlwaW5nVGlsZV9sYWJlbFwiPlxuICAgICAgICAgICAgICAgICAgICB7IHR5cGluZ1N0cmluZyB9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2xpPlxuICAgICAgICApO1xuICAgIH1cbn1cbiJdfQ==