@pazznetwork/ngx-chat
Version:
[](https://travis-ci.com/pazznetwork/ngx-chat) [](https://coveralls.io/github/pazzn
100 lines • 18.2 kB
JavaScript
import { xml } from '@xmpp/client';
import { BehaviorSubject } from 'rxjs';
import { AbstractXmppPlugin } from './abstract-xmpp-plugin';
export const MUC_SUB_FEATURE_ID = 'urn:xmpp:mucsub:0';
export var MUC_SUB_EVENT_TYPE;
(function (MUC_SUB_EVENT_TYPE) {
MUC_SUB_EVENT_TYPE["presence"] = "urn:xmpp:mucsub:nodes:presence";
MUC_SUB_EVENT_TYPE["messages"] = "urn:xmpp:mucsub:nodes:messages";
MUC_SUB_EVENT_TYPE["affiliations"] = "urn:xmpp:mucsub:nodes:affiliations";
MUC_SUB_EVENT_TYPE["subscribers"] = "urn:xmpp:mucsub:nodes:subscribers";
MUC_SUB_EVENT_TYPE["config"] = "urn:xmpp:mucsub:nodes:config";
MUC_SUB_EVENT_TYPE["subject"] = "urn:xmpp:mucsub:nodes:subject";
MUC_SUB_EVENT_TYPE["system"] = "urn:xmpp:mucsub:nodes:system";
})(MUC_SUB_EVENT_TYPE || (MUC_SUB_EVENT_TYPE = {}));
/**
* support for https://docs.ejabberd.im/developer/xmpp-clients-bots/extensions/muc-sub/
*/
export class MucSubPlugin extends AbstractXmppPlugin {
constructor(xmppChatAdapter, serviceDiscoveryPlugin) {
super();
this.xmppChatAdapter = xmppChatAdapter;
this.serviceDiscoveryPlugin = serviceDiscoveryPlugin;
this.supportsMucSub$ = new BehaviorSubject('unknown');
}
onBeforeOnline() {
return this.determineSupportForMucSub();
}
async determineSupportForMucSub() {
let isSupported;
try {
const service = await this.serviceDiscoveryPlugin.findService('conference', 'text');
isSupported = service.features.includes(MUC_SUB_FEATURE_ID);
}
catch (e) {
isSupported = false;
}
this.supportsMucSub$.next(isSupported);
}
onOffline() {
this.supportsMucSub$.next('unknown');
}
async subscribeRoom(roomJid, nodes = []) {
const nick = this.xmppChatAdapter.chatConnectionService.userJid.local;
await this.xmppChatAdapter.chatConnectionService.sendIq(makeSubscribeRoomStanza(roomJid, nick, nodes));
}
async unsubscribeRoom(roomJid) {
await this.xmppChatAdapter.chatConnectionService.sendIq(makeUnsubscribeRoomStanza(roomJid));
}
/**
* A room moderator can unsubscribe others providing the their jid as attribute to the information query (iq)
* see: https://docs.ejabberd.im/developer/xmpp-clients-bots/extensions/muc-sub/#unsubscribing-from-a-muc-room
* @param roomJid for the room to be unsubscribed from
* @param jid user id to be unsubscribed
*/
unsubscribeJidFromRoom(roomJid, jid) {
this.xmppChatAdapter.chatConnectionService.sendIq(xml('iq', { type: 'set', to: roomJid }, xml('unsubscribe', { xmlns: 'urn:xmpp:mucsub:0', jid })));
}
/**
* A user can query the MUC service to get their list of subscriptions.
* see: https://docs.ejabberd.im/developer/xmpp-clients-bots/extensions/muc-sub/#g dd ddetting-list-of-subscribed-rooms
*/
async getSubscribedRooms() {
const { local, domain } = this.xmppChatAdapter.chatConnectionService.userJid;
const from = `${local}@${domain}`;
const subscriptions = await this.xmppChatAdapter.chatConnectionService.sendIq(xml('iq', { type: 'get', from, to: 'muc.' + domain }, xml('subscriptions', { xmlns: 'urn:xmpp:mucsub:0' })));
return subscriptions.getChildren('subscription').map(sub => sub.getAttr('jid'));
}
/**
* A subscriber or room moderator can get the list of subscribers by sending <subscriptions/> request directly to the room JID.
* see: https://docs.ejabberd.im/developer/xmpp-clients-bots/extensions/muc-sub/#getting-list-of-subscribers-of-a-room
* @param roomJid of the room the get a subscriber list from
*/
getSubscribers(roomJid) {
this.xmppChatAdapter.chatConnectionService.sendIq(xml('iq', { type: 'get', to: roomJid }, xml('subscriptions', { xmlns: 'urn:xmpp:mucsub:0' })));
}
async retrieveSubscriptions() {
const service = await this.serviceDiscoveryPlugin.findService('conference', 'text');
const result = await this.xmppChatAdapter.chatConnectionService.sendIq(makeRetrieveSubscriptionsStanza(service.jid));
const subscriptions = result
.getChild('subscriptions', MUC_SUB_FEATURE_ID)
?.getChildren('subscription')
?.map(subscriptionElement => {
const subscribedEvents = subscriptionElement
.getChildren('event')
?.map(eventElement => eventElement.attrs.node) ?? [];
return [subscriptionElement.attrs.jid, subscribedEvents];
});
return new Map(subscriptions);
}
}
function makeSubscribeRoomStanza(roomJid, nick, nodes) {
return xml('iq', { type: 'set', to: roomJid }, xml('subscribe', { xmlns: MUC_SUB_FEATURE_ID, nick }, ...nodes.map(node => xml('event', { node }))));
}
function makeUnsubscribeRoomStanza(roomJid) {
return xml('iq', { type: 'set', to: roomJid }, xml('unsubscribe', { xmlns: MUC_SUB_FEATURE_ID }));
}
function makeRetrieveSubscriptionsStanza(conferenceServiceJid) {
return xml('iq', { type: 'get', to: conferenceServiceJid }, xml('subscriptions', { xmlns: MUC_SUB_FEATURE_ID }));
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVjLXN1Yi5wbHVnaW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL3NlcnZpY2VzL2FkYXB0ZXJzL3htcHAvcGx1Z2lucy9tdWMtc3ViLnBsdWdpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ25DLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFdkMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFJNUQsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUcsbUJBQW1CLENBQUM7QUFFdEQsTUFBTSxDQUFOLElBQVksa0JBUVg7QUFSRCxXQUFZLGtCQUFrQjtJQUMxQixpRUFBMkMsQ0FBQTtJQUMzQyxpRUFBMkMsQ0FBQTtJQUMzQyx5RUFBbUQsQ0FBQTtJQUNuRCx1RUFBaUQsQ0FBQTtJQUNqRCw2REFBdUMsQ0FBQTtJQUN2QywrREFBeUMsQ0FBQTtJQUN6Qyw2REFBdUMsQ0FBQTtBQUMzQyxDQUFDLEVBUlcsa0JBQWtCLEtBQWxCLGtCQUFrQixRQVE3QjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFlBQWEsU0FBUSxrQkFBa0I7SUFHaEQsWUFDcUIsZUFBZ0MsRUFDaEMsc0JBQThDO1FBRS9ELEtBQUssRUFBRSxDQUFDO1FBSFMsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLDJCQUFzQixHQUF0QixzQkFBc0IsQ0FBd0I7UUFKbEQsb0JBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBc0IsU0FBUyxDQUFDLENBQUM7SUFPdkYsQ0FBQztJQUVELGNBQWM7UUFDVixPQUFPLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDO0lBQzVDLENBQUM7SUFFTyxLQUFLLENBQUMseUJBQXlCO1FBQ25DLElBQUksV0FBb0IsQ0FBQztRQUN6QixJQUFJO1lBQ0EsTUFBTSxPQUFPLEdB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RUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBQyxFQUN2QyxHQUFHLENBQUMsYUFBYSxFQUFFLEVBQUMsS0FBSyxFQUFFLGtCQUFrQixFQUFDLENBQUMsQ0FDeEMsQ0FBQztBQUNoQixDQUFDO0FBRUQsU0FBUywrQkFBK0IsQ0FBQyxvQkFBNEI7SUFDakUsT0FBTyxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUUsb0JBQW9CLEVBQUMsRUFDcEQsR0FBRyxDQUFDLGVBQWUsRUFBRSxFQUFDLEtBQUssRUFBRSxrQkFBa0IsRUFBQyxDQUFDLENBQzFDLENBQUM7QUFDaEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHhtbCB9IGZyb20gJ0B4bXBwL2NsaWVudCc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFhtcHBDaGF0QWRhcHRlciB9IGZyb20gJy4uL3htcHAtY2hhdC1hZGFwdGVyLnNlcnZpY2UnO1xuaW1wb3J0IHsgQWJzdHJhY3RYbXBwUGx1Z2luIH0gZnJvbSAnLi9hYnN0cmFjdC14bXBwLXBsdWdpbic7XG5pbXBvcnQgeyBTZXJ2aWNlRGlzY292ZXJ5UGx1Z2luIH0gZnJvbSAnLi9zZXJ2aWNlLWRpc2NvdmVyeS5wbHVnaW4nO1xuaW1wb3J0IHsgU3RhbnphIH0gZnJvbSAnLi4vLi4vLi4vLi4vY29yZS9zdGFuemEnO1xuXG5leHBvcnQgY29uc3QgTVVDX1NVQl9GRUFUVVJFX0lEID0gJ3Vybjp4bXBwOm11Y3N1YjowJztcblxuZXhwb3J0IGVudW0gTVVDX1NVQl9FVkVOVF9UWVBFIHtcbiAgICBwcmVzZW5jZSA9ICd1cm46eG1wcDptdWNzdWI6bm9kZXM6cHJlc2VuY2UnLFxuICAgIG1lc3NhZ2VzID0gJ3Vybjp4bXBwOm11Y3N1Yjpub2RlczptZXNzYWdlcycsXG4gICAgYWZmaWxpYXRpb25zID0gJ3Vybjp4bXBwOm11Y3N1Yjpub2RlczphZmZpbGlhdGlvbnMnLFxuICAgIHN1YnNjcmliZXJzID0gJ3Vybjp4bXBwOm11Y3N1Yjpub2RlczpzdWJzY3JpYmVycycsXG4gICAgY29uZmlnID0gJ3Vybjp4bXBwOm11Y3N1Yjpub2Rlczpjb25maWcnLFxuICAgIHN1YmplY3QgPSAndXJuOnhtcHA6bXVjc3ViOm5vZGVzOnN1YmplY3QnLFxuICAgIHN5c3RlbSA9ICd1cm46eG1wcDptdWNzdWI6bm9kZXM6c3lzdGVtJyxcbn1cblxuLyoqXG4gKiBzdXBwb3J0IGZvciBodHRwczovL2RvY3MuZWphYmJlcmQuaW0vZGV2ZWxvcGVyL3htcHAtY2xpZW50cy1ib3RzL2V4dGVuc2lvbnMvbXVjLXN1Yi9cbiAqL1xuZXhwb3J0IGNsYXNzIE11Y1N1YlBsdWdpbiBleHRlbmRzIEFic3RyYWN0WG1wcFBsdWdpbiB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBzdXBwb3J0c011Y1N1YiQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4gfCAndW5rbm93bic+KCd1bmtub3duJyk7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSB4bXBwQ2hhdEFkYXB0ZXI6IFhtcHBDaGF0QWRhcHRlcixcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBzZXJ2aWNlRGlzY292ZXJ5UGx1Z2luOiBTZXJ2aWNlRGlzY292ZXJ5UGx1Z2luLFxuICAgICkge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIG9uQmVmb3JlT25saW5lKCk6IFByb21pc2VMaWtlPHZvaWQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGV0ZXJtaW5lU3VwcG9ydEZvck11Y1N1YigpO1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZGV0ZXJtaW5lU3VwcG9ydEZvck11Y1N1YigpIHtcbiAgICAgICAgbGV0IGlzU3VwcG9ydGVkOiBib29sZWFuO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgY29uc3Qgc2VydmljZSA9IGF3YWl0IHRoaXMuc2VydmljZURpc2NvdmVyeVBsdWdpbi5maW5kU2VydmljZSgnY29uZmVyZW5jZScsICd0ZXh0Jyk7XG4gICAgICAgICAgICBpc1N1cHBvcnRlZCA9IHNlcnZpY2UuZmVhdHVyZXMuaW5jbHVkZXMoTVVDX1NVQl9GRUFUVVJFX0lEKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgaXNTdXBwb3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN1cHBvcnRzTXVjU3ViJC5uZXh0KGlzU3VwcG9ydGVkKTtcbiAgICB9XG5cbiAgICBvbk9mZmxpbmUoKSB7XG4gICAgICAgIHRoaXMuc3VwcG9ydHNNdWNTdWIkLm5leHQoJ3Vua25vd24nKTtcbiAgICB9XG5cbiAgICBhc3luYyBzdWJzY3JpYmVSb29tKHJvb21KaWQ6IHN0cmluZywgbm9kZXM6IHN0cmluZ1tdID0gW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgY29uc3QgbmljayA9IHRoaXMueG1wcENoYXRBZGFwdGVyLmNoYXRDb25uZWN0aW9uU2VydmljZS51c2VySmlkLmxvY2FsO1xuICAgICAgICBhd2FpdCB0aGlzLnhtcHBDaGF0QWRhcHRlci5jaGF0Q29ubmVjdGlvblNlcnZpY2Uuc2VuZElxKFxuICAgICAgICAgICAgbWFrZVN1YnNjcmliZVJvb21TdGFuemEocm9vbUppZCwgbmljaywgbm9kZXMpXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgYXN5bmMgdW5zdWJzY3JpYmVSb29tKHJvb21KaWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLnhtcHBDaGF0QWRhcHRlci5jaGF0Q29ubmVjdGlvblNlcnZpY2Uuc2VuZElxKFxuICAgICAgICAgICAgbWFrZVVuc3Vic2NyaWJlUm9vbVN0YW56YShyb29tSmlkKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEEgcm9vbSBtb2RlcmF0b3IgY2FuIHVuc3Vic2NyaWJlIG90aGVycyBwcm92aWRpbmcgdGhlIHRoZWlyIGppZCBhcyBhdHRyaWJ1dGUgdG8gdGhlIGluZm9ybWF0aW9uIHF1ZXJ5IChpcSlcbiAgICAgKiBzZWU6IGh0dHBzOi8vZG9jcy5lamFiYmVyZC5pbS9kZXZlbG9wZXIveG1wcC1jbGllbnRzLWJvdHMvZXh0ZW5zaW9ucy9tdWMtc3ViLyN1bnN1YnNjcmliaW5nLWZyb20tYS1tdWMtcm9vbVxuICAgICAqIEBwYXJhbSByb29tSmlkIGZvciB0aGUgcm9vbSB0byBiZSB1bnN1YnNjcmliZWQgZnJvbVxuICAgICAqIEBwYXJhbSBqaWQgdXNlciBpZCB0byBiZSB1bnN1YnNjcmliZWRcbiAgICAgKi9cbiAgICB1bnN1YnNjcmliZUppZEZyb21Sb29tKHJvb21KaWQ6IHN0cmluZywgamlkOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy54bXBwQ2hhdEFkYXB0ZXIuY2hhdENvbm5lY3Rpb25TZXJ2aWNlLnNlbmRJcShcbiAgICAgICAgICAgIHhtbCgnaXEnLCB7dHlwZTogJ3NldCcsIHRvOiByb29tSmlkfSxcbiAgICAgICAgICAgICAgICB4bWwoJ3Vuc3Vic2NyaWJlJywge3htbG5zOiAndXJuOnhtcHA6bXVjc3ViOjAnLCBqaWR9KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSB1c2VyIGNhbiBxdWVyeSB0aGUgTVVDIHNlcnZpY2UgdG8gZ2V0IHRoZWlyIGxpc3Qgb2Ygc3Vic2NyaXB0aW9ucy5cbiAgICAgKiBzZWU6IGh0dHBzOi8vZG9jcy5lamFiYmVyZC5pbS9kZXZlbG9wZXIveG1wcC1jbGllbnRzLWJvdHMvZXh0ZW5zaW9ucy9tdWMtc3ViLyNnIGRkIGRkZXR0aW5nLWxpc3Qtb2Ytc3Vic2NyaWJlZC1yb29tc1xuICAgICAqL1xuICAgIGFzeW5jIGdldFN1YnNjcmliZWRSb29tcygpIHtcbiAgICAgICAgY29uc3Qge2xvY2FsLCBkb21haW59ID0gdGhpcy54bXBwQ2hhdEFkYXB0ZXIuY2hhdENvbm5lY3Rpb25TZXJ2aWNlLnVzZXJKaWQ7XG4gICAgICAgIGNvbnN0IGZyb20gPSBgJHtsb2NhbH1AJHtkb21haW59YDtcbiAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9ucyA9IGF3YWl0IHRoaXMueG1wcENoYXRBZGFwdGVyLmNoYXRDb25uZWN0aW9uU2VydmljZS5zZW5kSXEoXG4gICAgICAgICAgICB4bWwoJ2lxJywge3R5cGU6ICdnZXQnLCBmcm9tLCB0bzogJ211Yy4nICsgZG9tYWlufSxcbiAgICAgICAgICAgICAgICB4bWwoJ3N1YnNjcmlwdGlvbnMnLCB7eG1sbnM6ICd1cm46eG1wcDptdWNzdWI6MCd9KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBzdWJzY3JpcHRpb25zLmdldENoaWxkcmVuKCdzdWJzY3JpcHRpb24nKS5tYXAoc3ViID0+IHN1Yi5nZXRBdHRyKCdqaWQnKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQSBzdWJzY3JpYmVyIG9yIHJvb20gbW9kZXJhdG9yIGNhbiBnZXQgdGhlIGxpc3Qgb2Ygc3Vic2NyaWJlcnMgYnkgc2VuZGluZyA8c3Vic2NyaXB0aW9ucy8+IHJlcXVlc3QgZGlyZWN0bHkgdG8gdGhlIHJvb20gSklELlxuICAgICAqIHNlZTogaHR0cHM6Ly9kb2NzLmVqYWJiZXJkLmltL2RldmVsb3Blci94bXBwLWNsaWVudHMtYm90cy9leHRlbnNpb25zL211Yy1zdWIvI2dldHRpbmctbGlzdC1vZi1zdWJzY3JpYmVycy1vZi1hLXJvb21cbiAgICAgKiBAcGFyYW0gcm9vbUppZCBvZiB0aGUgcm9vbSB0aGUgZ2V0IGEgc3Vic2NyaWJlciBsaXN0IGZyb21cbiAgICAgKi9cbiAgICBnZXRTdWJzY3JpYmVycyhyb29tSmlkOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy54bXBwQ2hhdEFkYXB0ZXIuY2hhdENvbm5lY3Rpb25TZXJ2aWNlLnNlbmRJcShcbiAgICAgICAgICAgIHhtbCgnaXEnLCB7dHlwZTogJ2dldCcsIHRvOiByb29tSmlkfSxcbiAgICAgICAgICAgICAgICB4bWwoJ3N1YnNjcmlwdGlvbnMnLCB7eG1sbnM6ICd1cm46eG1wcDptdWNzdWI6MCd9KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgYXN5bmMgcmV0cmlldmVTdWJzY3JpcHRpb25zKCk6IFByb21pc2U8TWFwPHN0cmluZywgc3RyaW5nW10+PiB7XG4gICAgICAgIGNvbnN0IHNlcnZpY2UgPSBhd2FpdCB0aGlzLnNlcnZpY2VEaXNjb3ZlcnlQbHVnaW4uZmluZFNlcnZpY2UoJ2NvbmZlcmVuY2UnLCAndGV4dCcpO1xuXG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMueG1wcENoYXRBZGFwdGVyLmNoYXRDb25uZWN0aW9uU2VydmljZS5zZW5kSXEoXG4gICAgICAgICAgICBtYWtlUmV0cmlldmVTdWJzY3JpcHRpb25zU3RhbnphKHNlcnZpY2UuamlkKVxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHN1YnNjcmlwdGlvbnMgPSByZXN1bHRcbiAgICAgICAgICAgIC5nZXRDaGlsZCgnc3Vic2NyaXB0aW9ucycsIE1VQ19TVUJfRkVBVFVSRV9JRClcbiAgICAgICAgICAgID8uZ2V0Q2hpbGRyZW4oJ3N1YnNjcmlwdGlvbicpXG4gICAgICAgICAgICA/Lm1hcChzdWJzY3JpcHRpb25FbGVtZW50ID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBzdWJzY3JpYmVkRXZlbnRzOiBzdHJpbmdbXSA9IHN1YnNjcmlwdGlvbkVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgLmdldENoaWxkcmVuKCdldmVudCcpXG4gICAgICAgICAgICAgICAgICAgID8ubWFwKGV2ZW50RWxlbWVudCA9PiBldmVudEVsZW1lbnQuYXR0cnMubm9kZSkgPz8gW107XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtzdWJzY3JpcHRpb25FbGVtZW50LmF0dHJzLmppZCBhcyBzdHJpbmcsIHN1YnNjcmliZWRFdmVudHNdIGFzIGNvbnN0O1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgcmV0dXJuIG5ldyBNYXAoc3Vic2NyaXB0aW9ucyk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBtYWtlU3Vic2NyaWJlUm9vbVN0YW56YShyb29tSmlkOiBzdHJpbmcsIG5pY2s6IHN0cmluZywgbm9kZXM6IHJlYWRvbmx5IHN0cmluZ1tdKTogU3RhbnphIHtcbiAgICByZXR1cm4geG1sKCdpcScsIHt0eXBlOiAnc2V0JywgdG86IHJvb21KaWR9LFxuICAgICAgICB4bWwoJ3N1YnNjcmliZScsIHt4bWxuczogTVVDX1NVQl9GRUFUVVJFX0lELCBuaWNrfSxcbiAgICAgICAgICAgIC4uLm5vZGVzLm1hcChub2RlID0+IHhtbCgnZXZlbnQnLCB7bm9kZX0pKVxuICAgICAgICApXG4gICAgKSBhcyBTdGFuemE7XG59XG5cbmZ1bmN0aW9uIG1ha2VVbnN1YnNjcmliZVJvb21TdGFuemEocm9vbUppZDogc3RyaW5nKTogU3RhbnphIHtcbiAgICByZXR1cm4geG1sKCdpcScsIHt0eXBlOiAnc2V0JywgdG86IHJvb21KaWR9LFxuICAgICAgICB4bWwoJ3Vuc3Vic2NyaWJlJywge3htbG5zOiBNVUNfU1VCX0ZFQVRVUkVfSUR9KVxuICAgICkgYXMgU3RhbnphO1xufVxuXG5mdW5jdGlvbiBtYWtlUmV0cmlldmVTdWJzY3JpcHRpb25zU3RhbnphKGNvbmZlcmVuY2VTZXJ2aWNlSmlkOiBzdHJpbmcpOiBTdGFuemEge1xuICAgIHJldHVybiB4bWwoJ2lxJywge3R5cGU6ICdnZXQnLCB0bzogY29uZmVyZW5jZVNlcnZpY2VKaWR9LFxuICAgICAgICB4bWwoJ3N1YnNjcmlwdGlvbnMnLCB7eG1sbnM6IE1VQ19TVUJfRkVBVFVSRV9JRH0pXG4gICAgKSBhcyBTdGFuemE7XG59XG4iXX0=