@pazznetwork/ngx-chat
Version:
[](https://travis-ci.com/pazznetwork/ngx-chat) [](https://coveralls.io/github/pazzn
115 lines • 18.9 kB
JavaScript
import { jid as parseJid, xml } from '@xmpp/client';
import { Direction } from '../../../../core/message';
import { AbstractXmppPlugin } from './abstract-xmpp-plugin';
import { mucUserNs } from './multi-user-chat/multi-user-chat-constants';
export class MessageReceivedEvent {
constructor() {
this.discard = false;
}
}
/**
* Part of the XMPP Core Specification
* see: https://datatracker.ietf.org/doc/rfc6120/
*/
export class MessagePlugin extends AbstractXmppPlugin {
constructor(xmppChatAdapter, logService) {
super();
this.xmppChatAdapter = xmppChatAdapter;
this.logService = logService;
}
handleStanza(stanza, archiveDelayElement) {
if (this.isMessageStanza(stanza)) {
this.handleMessageStanza(stanza, archiveDelayElement);
return true;
}
return false;
}
sendMessage(contact, body) {
const messageStanza = xml('message', {
to: contact.jidBare.toString(),
from: this.xmppChatAdapter.chatConnectionService.userJid.toString(),
type: 'chat',
}, xml('body', {}, body));
const message = {
direction: Direction.out,
body,
datetime: new Date(),
delayed: false,
fromArchive: false,
};
this.xmppChatAdapter.plugins.forEach(plugin => plugin.beforeSendMessage(messageStanza, message));
contact.addMessage(message);
// TODO: on rejection mark message that it was not sent successfully
this.xmppChatAdapter.chatConnectionService.send(messageStanza).then(() => {
this.xmppChatAdapter.plugins.forEach(plugin => plugin.afterSendMessage(message, messageStanza));
}, (rej) => {
this.logService.error('rejected message ' + message.id, rej);
});
}
isMessageStanza(stanza) {
return stanza.name === 'message'
&& stanza.attrs.type !== 'groupchat'
&& stanza.attrs.type !== 'error'
&& !!stanza.getChildText('body')?.trim();
}
handleMessageStanza(messageStanza, archiveDelayElement) {
const isAddressedToMe = this.xmppChatAdapter.chatConnectionService.userJid.bare()
.equals(parseJid(messageStanza.attrs.to).bare());
const messageDirection = isAddressedToMe ? Direction.in : Direction.out;
const messageFromArchive = archiveDelayElement != null;
const delayElement = archiveDelayElement ?? messageStanza.getChild('delay');
const datetime = delayElement?.attrs.stamp
? new Date(delayElement.attrs.stamp)
: new Date() /* TODO: replace with entity time plugin */;
if (messageDirection === Direction.in && !messageFromArchive) {
this.logService.debug('message received <=', messageStanza.getChildText('body'));
}
const message = {
body: messageStanza.getChildText('body').trim(),
direction: messageDirection,
datetime,
delayed: !!delayElement,
fromArchive: messageFromArchive,
};
const messageReceivedEvent = new MessageReceivedEvent();
this.xmppChatAdapter.plugins.forEach(plugin => plugin.afterReceiveMessage(message, messageStanza, messageReceivedEvent));
if (messageReceivedEvent.discard) {
return;
}
const contactJid = isAddressedToMe ? messageStanza.attrs.from : messageStanza.attrs.to;
const contact = this.xmppChatAdapter.getOrCreateContactById(contactJid);
contact.addMessage(message);
const isRoomInviteMessage = messageStanza.getChild('x', mucUserNs)
|| messageStanza.getChild('x', MessagePlugin.MUC_DIRECT_INVITATION_NS);
if (isRoomInviteMessage) {
contact.pendingRoomInvite$.next(this.extractInvitationFromMessage(messageStanza));
}
if (messageDirection === Direction.in && !messageFromArchive) {
this.xmppChatAdapter.message$.next(contact);
}
}
extractInvitationFromMessage(messageStanza) {
const mediatedInvitation = messageStanza.getChild('x', mucUserNs);
if (mediatedInvitation) {
const inviteEl = mediatedInvitation.getChild('invite');
return {
from: parseJid(inviteEl.attrs.from),
roomJid: parseJid(messageStanza.attrs.from),
reason: inviteEl.getChildText('reason'),
password: mediatedInvitation.getChildText('password'),
};
}
const directInvitation = messageStanza.getChild('x', MessagePlugin.MUC_DIRECT_INVITATION_NS);
if (directInvitation) {
return {
from: parseJid(messageStanza.attrs.from),
roomJid: parseJid(directInvitation.attrs.jid),
reason: directInvitation.attrs.reason,
password: directInvitation.attrs.password,
};
}
throw new Error(`unknown invitation format: ${messageStanza.toString()}`);
}
}
MessagePlugin.MUC_DIRECT_INVITATION_NS = 'jabber:x:conference';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVzc2FnZS5wbHVnaW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2FkYXB0ZXJzL3htcHAvcGx1Z2lucy9tZXNzYWdlLnBsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsR0FBRyxJQUFJLFFBQVEsRUFBRSxHQUFHLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFcEQsT0FBTyxFQUFFLFNBQVMsRUFBVyxNQUFNLDBCQUEwQixDQUFDO0FBSTlELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzVELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUV4RSxNQUFNLE9BQU8sb0JBQW9CO0lBQWpDO1FBQ0ksWUFBTyxHQUFHLEtBQUssQ0FBQztJQUNwQixDQUFDO0NBQUE7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sYUFBYyxTQUFRLGtCQUFrQjtJQUdqRCxZQUNxQixlQUFnQyxFQUNoQyxVQUFzQjtRQUV2QyxLQUFLLEVBQUUsQ0FBQztRQUhTLG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQUNoQyxlQUFVLEdBQVYsVUFBVSxDQUFZO0lBRzNDLENBQUM7SUFFRCxZQUFZLENBQUMsTUFBYyxFQUFFLG1CQUE0QjtRQUNyRCxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDOUIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1lBQ3RELE9BQU8sSUFBSSxDQUFDO1NBQ2Y7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQWdCLEVBQUUsSUFBWTtRQUN0QyxNQUFNLGFBQWEsR0FBRyxHQUFHLENBQUMsU0FBUyxFQUFFO1lBQzdCLEVBQUUsRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFB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cG9ydCB7IGppZCBhcyBwYXJzZUppZCwgeG1sIH0gZnJvbSAnQHhtcHAvY2xpZW50JztcbmltcG9ydCB7IENvbnRhY3QsIEludml0YXRpb24gfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL2NvbnRhY3QnO1xuaW1wb3J0IHsgRGlyZWN0aW9uLCBNZXNzYWdlIH0gZnJvbSAnLi4vLi4vLi4vLi4vY29yZS9tZXNzYWdlJztcbmltcG9ydCB7IE1lc3NhZ2VXaXRoQm9keVN0YW56YSwgU3RhbnphIH0gZnJvbSAnLi4vLi4vLi4vLi4vY29yZS9zdGFuemEnO1xuaW1wb3J0IHsgTG9nU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2xvZy5zZXJ2aWNlJztcbmltcG9ydCB7IFhtcHBDaGF0QWRhcHRlciB9IGZyb20gJy4uL3htcHAtY2hhdC1hZGFwdGVyLnNlcnZpY2UnO1xuaW1wb3J0IHsgQWJzdHJhY3RYbXBwUGx1Z2luIH0gZnJvbSAnLi9hYnN0cmFjdC14bXBwLXBsdWdpbic7XG5pbXBvcnQgeyBtdWNVc2VyTnMgfSBmcm9tICcuL211bHRpLXVzZXItY2hhdC9tdWx0aS11c2VyLWNoYXQtY29uc3RhbnRzJztcblxuZXhwb3J0IGNsYXNzIE1lc3NhZ2VSZWNlaXZlZEV2ZW50IHtcbiAgICBkaXNjYXJkID0gZmFsc2U7XG59XG5cbi8qKlxuICogUGFydCBvZiB0aGUgWE1QUCBDb3JlIFNwZWNpZmljYXRpb25cbiAqIHNlZTogaHR0cHM6Ly9kYXRhdHJhY2tlci5pZXRmLm9yZy9kb2MvcmZjNjEyMC9cbiAqL1xuZXhwb3J0IGNsYXNzIE1lc3NhZ2VQbHVnaW4gZXh0ZW5kcyBBYnN0cmFjdFhtcHBQbHVnaW4ge1xuICAgIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IE1VQ19ESVJFQ1RfSU5WSVRBVElPTl9OUyA9ICdqYWJiZXI6eDpjb25mZXJlbmNlJztcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IHhtcHBDaGF0QWRhcHRlcjogWG1wcENoYXRBZGFwdGVyLFxuICAgICAgICBwcml2YXRlIHJlYWRvbmx5IGxvZ1NlcnZpY2U6IExvZ1NlcnZpY2UsXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgaGFuZGxlU3RhbnphKHN0YW56YTogU3RhbnphLCBhcmNoaXZlRGVsYXlFbGVtZW50PzogU3RhbnphKSB7XG4gICAgICAgIGlmICh0aGlzLmlzTWVzc2FnZVN0YW56YShzdGFuemEpKSB7XG4gICAgICAgICAgICB0aGlzLmhhbmRsZU1lc3NhZ2VTdGFuemEoc3RhbnphLCBhcmNoaXZlRGVsYXlFbGVtZW50KTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBzZW5kTWVzc2FnZShjb250YWN0OiBDb250YWN0LCBib2R5OiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgbWVzc2FnZVN0YW56YSA9IHhtbCgnbWVzc2FnZScsIHtcbiAgICAgICAgICAgICAgICB0bzogY29udGFjdC5qaWRCYXJlLnRvU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgZnJvbTogdGhpcy54bXBwQ2hhdEFkYXB0ZXIuY2hhdENvbm5lY3Rpb25TZXJ2aWNlLnVzZXJKaWQudG9TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICB0eXBlOiAnY2hhdCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgeG1sKCdib2R5Jywge30sIGJvZHkpLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IG1lc3NhZ2U6IE1lc3NhZ2UgPSB7XG4gICAgICAgICAgICBkaXJlY3Rpb246IERpcmVjdGlvbi5vdXQsXG4gICAgICAgICAgICBib2R5LFxuICAgICAgICAgICAgZGF0ZXRpbWU6IG5ldyBEYXRlKCksIC8vIFRPRE86IHJlcGxhY2Ugd2l0aCBlbnRpdHkgdGltZSBwbHVnaW5cbiAgICAgICAgICAgIGRlbGF5ZWQ6IGZhbHNlLFxuICAgICAgICAgICAgZnJvbUFyY2hpdmU6IGZhbHNlLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnhtcHBDaGF0QWRhcHRlci5wbHVnaW5zLmZvckVhY2gocGx1Z2luID0+IHBsdWdpbi5iZWZvcmVTZW5kTWVzc2FnZShtZXNzYWdlU3RhbnphLCBtZXNzYWdlKSk7XG4gICAgICAgIGNvbnRhY3QuYWRkTWVzc2FnZShtZXNzYWdlKTtcbiAgICAgICAgLy8gVE9ETzogb24gcmVqZWN0aW9uIG1hcmsgbWVzc2FnZSB0aGF0IGl0IHdhcyBub3Qgc2VudCBzdWNjZXNzZnVsbHlcbiAgICAgICAgdGhpcy54bXBwQ2hhdEFkYXB0ZXIuY2hhdENvbm5lY3Rpb25TZXJ2aWNlLnNlbmQobWVzc2FnZVN0YW56YSkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLnhtcHBDaGF0QWRhcHRlci5wbHVnaW5zLmZvckVhY2gocGx1Z2luID0+IHBsdWdpbi5hZnRlclNlbmRNZXNzYWdlKG1lc3NhZ2UsIG1lc3NhZ2VTdGFuemEpKTtcbiAgICAgICAgfSwgKHJlaikgPT4ge1xuICAgICAgICAgICAgdGhpcy5sb2dTZXJ2aWNlLmVycm9yKCdyZWplY3RlZCBtZXNzYWdlICcgKyBtZXNzYWdlLmlkLCByZWopO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzTWVzc2FnZVN0YW56YShzdGFuemE6IFN0YW56YSk6IHN0YW56YSBpcyBNZXNzYWdlV2l0aEJvZHlTdGFuemEge1xuICAgICAgICByZXR1cm4gc3RhbnphLm5hbWUgPT09ICdtZXNzYWdlJ1xuICAgICAgICAgICAgJiYgc3RhbnphLmF0dHJzLnR5cGUgIT09ICdncm91cGNoYXQnXG4gICAgICAgICAgICAmJiBzdGFuemEuYXR0cnMudHlwZSAhPT0gJ2Vycm9yJ1xuICAgICAgICAgICAgJiYgISFzdGFuemEuZ2V0Q2hpbGRUZXh0KCdib2R5Jyk/LnRyaW0oKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGhhbmRsZU1lc3NhZ2VTdGFuemEobWVzc2FnZVN0YW56YTogTWVzc2FnZVdpdGhCb2R5U3RhbnphLCBhcmNoaXZlRGVsYXlFbGVtZW50PzogU3RhbnphKSB7XG4gICAgICAgIGNvbnN0IGlzQWRkcmVzc2VkVG9NZSA9IHRoaXMueG1wcENoYXRBZGFwdGVyLmNoYXRDb25uZWN0aW9uU2VydmljZS51c2VySmlkLmJhcmUoKVxuICAgICAgICAgICAgLmVxdWFscyhwYXJzZUppZChtZXNzYWdlU3RhbnphLmF0dHJzLnRvKS5iYXJlKCkpO1xuICAgICAgICBjb25zdCBtZXNzYWdlRGlyZWN0aW9uID0gaXNBZGRyZXNzZWRUb01lID8gRGlyZWN0aW9uLmluIDogRGlyZWN0aW9uLm91dDtcblxuICAgICAgICBjb25zdCBtZXNzYWdlRnJvbUFyY2hpdmUgPSBhcmNoaXZlRGVsYXlFbGVtZW50ICE9IG51bGw7XG5cbiAgICAgICAgY29uc3QgZGVsYXlFbGVtZW50ID0gYXJjaGl2ZURlbGF5RWxlbWVudCA/PyBtZXNzYWdlU3RhbnphLmdldENoaWxkKCdkZWxheScpO1xuICAgICAgICBjb25zdCBkYXRldGltZSA9IGRlbGF5RWxlbWVudD8uYXR0cnMuc3RhbXBcbiAgICAgICAgICAgID8gbmV3IERhdGUoZGVsYXlFbGVtZW50LmF0dHJzLnN0YW1wKVxuICAgICAgICAgICAgOiBuZXcgRGF0ZSgpIC8qIFRPRE86IHJlcGxhY2Ugd2l0aCBlbnRpdHkgdGltZSBwbHVnaW4gKi87XG5cbiAgICAgICAgaWYgKG1lc3NhZ2VEaXJlY3Rpb24gPT09IERpcmVjdGlvbi5pbiAmJiAhbWVzc2FnZUZyb21BcmNoaXZlKSB7XG4gICAgICAgICAgICB0aGlzLmxvZ1NlcnZpY2UuZGVidWcoJ21lc3NhZ2UgcmVjZWl2ZWQgPD0nLCBtZXNzYWdlU3RhbnphLmdldENoaWxkVGV4dCgnYm9keScpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG1lc3NhZ2UgPSB7XG4gICAgICAgICAgICBib2R5OiBtZXNzYWdlU3RhbnphLmdldENoaWxkVGV4dCgnYm9keScpLnRyaW0oKSxcbiAgICAgICAgICAgIGRpcmVjdGlvbjogbWVzc2FnZURpcmVjdGlvbixcbiAgICAgICAgICAgIGRhdGV0aW1lLFxuICAgICAgICAgICAgZGVsYXllZDogISFkZWxheUVsZW1lbnQsXG4gICAgICAgICAgICBmcm9tQXJjaGl2ZTogbWVzc2FnZUZyb21BcmNoaXZlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGNvbnN0IG1lc3NhZ2VSZWNlaXZlZEV2ZW50ID0gbmV3IE1lc3NhZ2VSZWNlaXZlZEV2ZW50KCk7XG4gICAgICAgIHRoaXMueG1wcENoYXRBZGFwdGVyLnBsdWdpbnMuZm9yRWFjaChwbHVnaW4gPT4gcGx1Z2luLmFmdGVyUmVjZWl2ZU1lc3NhZ2UobWVzc2FnZSwgbWVzc2FnZVN0YW56YSwgbWVzc2FnZVJlY2VpdmVkRXZlbnQpKTtcblxuICAgICAgICBpZiAobWVzc2FnZVJlY2VpdmVkRXZlbnQuZGlzY2FyZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29udGFjdEppZCA9IGlzQWRkcmVzc2VkVG9NZSA/IG1lc3NhZ2VTdGFuemEuYXR0cnMuZnJvbSA6IG1lc3NhZ2VTdGFuemEuYXR0cnMudG87XG4gICAgICAgIGNvbnN0IGNvbnRhY3QgPSB0aGlzLnhtcHBDaGF0QWRhcHRlci5nZXRPckNyZWF0ZUNvbnRhY3RCeUlkKGNvbnRhY3RKaWQpO1xuICAgICAgICBjb250YWN0LmFkZE1lc3NhZ2UobWVzc2FnZSk7XG5cbiAgICAgICAgY29uc3QgaXNSb29tSW52aXRlTWVzc2FnZSA9XG4gICAgICAgICAgICBtZXNzYWdlU3RhbnphLmdldENoaWxkKCd4JywgbXVjVXNlck5zKVxuICAgICAgICAgICAgfHwgbWVzc2FnZVN0YW56YS5nZXRDaGlsZCgneCcsIE1lc3NhZ2VQbHVnaW4uTVVDX0RJUkVDVF9JTlZJVEFUSU9OX05TKTtcblxuICAgICAgICBpZiAoaXNSb29tSW52aXRlTWVzc2FnZSkge1xuICAgICAgICAgICAgY29udGFjdC5wZW5kaW5nUm9vbUludml0ZSQubmV4dCh0aGlzLmV4dHJhY3RJbnZpdGF0aW9uRnJvbU1lc3NhZ2UobWVzc2FnZVN0YW56YSkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1lc3NhZ2VEaXJlY3Rpb24gPT09IERpcmVjdGlvbi5pbiAmJiAhbWVzc2FnZUZyb21BcmNoaXZlKSB7XG4gICAgICAgICAgICB0aGlzLnhtcHBDaGF0QWRhcHRlci5tZXNzYWdlJC5uZXh0KGNvbnRhY3QpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBleHRyYWN0SW52aXRhdGlvbkZyb21NZXNzYWdlKG1lc3NhZ2VTdGFuemE6IE1lc3NhZ2VXaXRoQm9keVN0YW56YSk6IEludml0YXRpb24ge1xuICAgICAgICBjb25zdCBtZWRpYXRlZEludml0YXRpb24gPSBtZXNzYWdlU3RhbnphLmdldENoaWxkKCd4JywgbXVjVXNlck5zKTtcbiAgICAgICAgaWYgKG1lZGlhdGVkSW52aXRhdGlvbikge1xuICAgICAgICAgICAgY29uc3QgaW52aXRlRWwgPSBtZWRpYXRlZEludml0YXRpb24uZ2V0Q2hpbGQoJ2ludml0ZScpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBmcm9tOiBwYXJzZUppZChpbnZpdGVFbC5hdHRycy5mcm9tKSxcbiAgICAgICAgICAgICAgICByb29tSmlkOiBwYXJzZUppZChtZXNzYWdlU3RhbnphLmF0dHJzLmZyb20pLFxuICAgICAgICAgICAgICAgIHJlYXNvbjogaW52aXRlRWwuZ2V0Q2hpbGRUZXh0KCdyZWFzb24nKSxcbiAgICAgICAgICAgICAgICBwYXNzd29yZDogbWVkaWF0ZWRJbnZpdGF0aW9uLmdldENoaWxkVGV4dCgncGFzc3dvcmQnKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBkaXJlY3RJbnZpdGF0aW9uID0gbWVzc2FnZVN0YW56YS5nZXRDaGlsZCgneCcsIE1lc3NhZ2VQbHVnaW4uTVVDX0RJUkVDVF9JTlZJVEFUSU9OX05TKTtcbiAgICAgICAgaWYgKGRpcmVjdEludml0YXRpb24pIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgZnJvbTogcGFyc2VKaWQobWVzc2FnZVN0YW56YS5hdHRycy5mcm9tKSxcbiAgICAgICAgICAgICAgICByb29tSmlkOiBwYXJzZUppZChkaXJlY3RJbnZpdGF0aW9uLmF0dHJzLmppZCksXG4gICAgICAgICAgICAgICAgcmVhc29uOiBkaXJlY3RJbnZpdGF0aW9uLmF0dHJzLnJlYXNvbixcbiAgICAgICAgICAgICAgICBwYXNzd29yZDogZGlyZWN0SW52aXRhdGlvbi5hdHRycy5wYXNzd29yZCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVua25vd24gaW52aXRhdGlvbiBmb3JtYXQ6ICR7bWVzc2FnZVN0YW56YS50b1N0cmluZygpfWApO1xuICAgIH1cblxufVxuIl19