@pazznetwork/ngx-chat
Version:
[](https://travis-ci.com/pazznetwork/ngx-chat) [](https://coveralls.io/github/pazzn
123 lines • 19.5 kB
JavaScript
import { xml } from '@xmpp/client';
import { BehaviorSubject, Subject } from 'rxjs';
import { filter } from 'rxjs/operators';
import { AbstractStanzaBuilder } from '../abstract-stanza-builder';
import { XmppResponseError } from '../xmpp-response.error';
import { AbstractXmppPlugin } from './abstract-xmpp-plugin';
import { serializeToSubmitForm } from '../../../../core/form';
export const PUBSUB_EVENT_XMLNS = 'http://jabber.org/protocol/pubsub#event';
class PublishStanzaBuilder extends AbstractStanzaBuilder {
constructor(options) {
super();
this.publishOptions = {
persistItems: false,
};
if (options) {
this.publishOptions = { ...this.publishOptions, ...options };
}
}
toStanza() {
const { node, id, persistItems } = this.publishOptions;
// necessary as a 'event-only' publish is currently broken in ejabberd, see
// https://github.com/processone/ejabberd/issues/2799
const data = this.publishOptions.data || xml('data');
return xml('iq', { type: 'set' }, xml('pubsub', { xmlns: 'http://jabber.org/protocol/pubsub' }, xml('publish', { node }, xml('item', { id }, data)), xml('publish-options', {}, serializeToSubmitForm({
type: 'submit',
instructions: [],
fields: [
{ type: 'hidden', variable: 'FORM_TYPE', value: 'http://jabber.org/protocol/pubsub#publish-options' },
{ type: 'boolean', variable: 'pubsub#persist_items', value: persistItems === true },
{ type: 'list-single', variable: 'pubsub#access_model', value: 'whitelist' },
],
}))));
}
}
class RetrieveDataStanzaBuilder extends AbstractStanzaBuilder {
constructor(node) {
super();
this.node = node;
}
toStanza() {
return xml('iq', { type: 'get' }, xml('pubsub', { xmlns: 'http://jabber.org/protocol/pubsub' }, xml('items', { node: this.node })));
}
}
/**
* XEP-0060 Publish Subscribe (https://xmpp.org/extensions/xep-0060.html)
* XEP-0223 Persistent Storage of Private Data via PubSub (https://xmpp.org/extensions/xep-0223.html)
*/
export class PublishSubscribePlugin extends AbstractXmppPlugin {
constructor(xmppChatAdapter, serviceDiscoveryPlugin) {
super();
this.xmppChatAdapter = xmppChatAdapter;
this.serviceDiscoveryPlugin = serviceDiscoveryPlugin;
this.publish$ = new Subject();
this.supportsPrivatePublish = new BehaviorSubject('unknown');
}
onBeforeOnline() {
return this.determineSupportForPrivatePublish();
}
onOffline() {
this.supportsPrivatePublish.next('unknown');
}
storePrivatePayloadPersistent(node, id, data) {
return new Promise((resolve, reject) => {
this.supportsPrivatePublish
.pipe(filter(support => support !== 'unknown'))
.subscribe((support) => {
if (!support) {
reject(new Error('does not support private publish subscribe'));
}
else {
resolve(this.xmppChatAdapter.chatConnectionService.sendIq(new PublishStanzaBuilder({ node, id, data, persistItems: true }).toStanza()));
}
});
});
}
privateNotify(node, data, id) {
return new Promise((resolve, reject) => {
this.supportsPrivatePublish
.pipe(filter(support => support !== 'unknown'))
.subscribe((support) => {
if (!support) {
reject(new Error('does not support private publish subscribe'));
}
else {
resolve(this.xmppChatAdapter.chatConnectionService.sendIq(new PublishStanzaBuilder({ node, id, data, persistItems: false }).toStanza()));
}
});
});
}
handleStanza(stanza) {
const eventElement = stanza.getChild('event', PUBSUB_EVENT_XMLNS);
if (stanza.is('message') && eventElement) {
this.publish$.next(eventElement);
return true;
}
return false;
}
async retrieveNodeItems(node) {
try {
const iqResponseStanza = await this.xmppChatAdapter.chatConnectionService.sendIq(new RetrieveDataStanzaBuilder(node).toStanza());
return iqResponseStanza.getChild('pubsub').getChild('items').getChildren('item');
}
catch (e) {
if (e instanceof XmppResponseError &&
(e.errorCondition === 'item-not-found' || e.errorCode === 404)) {
return [];
}
throw e;
}
}
async determineSupportForPrivatePublish() {
let isSupported;
try {
const service = await this.serviceDiscoveryPlugin.findService('pubsub', 'pep');
isSupported = service.features.includes('http://jabber.org/protocol/pubsub#publish-options');
}
catch (e) {
isSupported = false;
}
this.supportsPrivatePublish.next(isSupported);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGlzaC1zdWJzY3JpYmUucGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zZXJ2aWNlcy9hZGFwdGVycy94bXBwL3BsdWdpbnMvcHVibGlzaC1zdWJzY3JpYmUucGx1Z2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFbkMsT0FBTyxFQUFFLGVBQWUsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDaEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXhDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ25FLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRTNELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRTVELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRTlELE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLHlDQUF5QyxDQUFDO0FBUzVFLE1BQU0sb0JBQXFCLFNBQVEscUJBQXFCO0lBTXBELFlBQVksT0FBdUI7UUFDL0IsS0FBSyxFQUFFLENBQUM7UUFMSyxtQkFBYyxHQUFtQjtZQUM5QyxZQUFZLEVBQUUsS0FBSztTQUN0QixDQUFDO1FBSUUsSUFBSSxPQUFPLEVBQUU7WUFDVCxJQUFJLENBQUMsY0FBYyxHQUFHLEVBQUMsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLEdBQUcsT0FBTyxFQUFDLENBQUM7U0FDOUQ7SUFDTCxDQUFDO0lBRUQsUUFBUTtRQUNKLE1BQU0sRUFBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLFlBQVksRUFBQyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUM7UUFFckQsMkVBQTJFO1FBQzNFLHFEQUFxRDtRQUNyRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFckQsT0FBTyxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBQyxFQUMxQixHQUFHLENBQUMsUUFBUSxFQUFFLEVBQUMsS0FBSyxFQUFFLG1DQUFtQyxFQUFDLEVBQ3RELEdBQUcsQ0FBQyxTQUFTLEVBQUUsRUFBQyxJQUFJLEVBQUMsRUFDakIsR0FBRyxDQUFDLE1BQU0sRUFBRSxFQUFDLEVBQUUsRUFBQyxFQUFFLElBQUksQ0FBQyxDQUMxQixFQUNELEdBQUcsQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLEVBQ3JCLHFCQUFxQixDQUFDO1lBQ2xCLElBQUksRUFBRSxRQUFRO1lBQ2QsWUFBWSxFQUFFLEVBQUU7WUFDaEIsTUFBTSxFQUFFO2dCQUNKLEVBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxtREFBbUQsRUFBQztnQkFDbkcsRUFBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxzQkFBc0IsRUFBRSxLQUFLLEVBQUUsWUFBWSxLQUFLLElBQUksRUFBQztnQkFDakYsRUFBQyxJQUFJLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxxQkFBcUIsRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFDO2FBQzdFO1NBQ0osQ0FBQyxDQUNMLENBQ0osQ0FDSixDQUFDO0lBQ04sQ0FBQztDQUVKO0FBRUQsTUFBTSx5QkFBMEIsU0FBUSxxQkFBcUI7SUFFekQsWUFBNkIsSUFBWTtRQUNyQyxLQUFLLEVBQUUsQ0FBQztRQURpQixTQUFJLEdBQUosSUFBSSxDQUFRO0lBRXpDLENBQUM7SUFFRCxRQUFRO1FBQ0osT0FBTyxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUMsSUFBSSxFQUFFLEtBQUssRUFBQyxFQUMxQixHQUFHLENBQUMsUUFBUSxFQUFFLEVBQUMsS0FBSyxFQUFFLG1DQUFtQyxFQUFDLEVBQ3RELEdBQUcsQ0FBQyxPQUFPLEVBQUUsRUFBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBQyxDQUFDLENBQ2xDLENBQ0osQ0FBQztJQUNOLENBQUM7Q0FFSjtBQUVEOzs7R0FHRztBQUNILE1BQU0sT0FBTyxzQkFBdUIsU0FBUSxrQkFBa0I7SUFLMUQsWUFDcUIsZUFBZ0MsRUFDaEMsc0JBQThDO1FBRS9ELEtBQUssRUFBRSxDQUFDO1FBSFMsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLDJCQUFzQixHQUF0QixzQkFBc0IsQ0FBd0I7UUFMMUQsYUFBUSxHQUFHLElBQUksT0FBTyxFQUFVLENBQUM7UUFDekIsMkJBQXNCLEdBQUcsSUFBSSxlQUFlLENBQXNCLFNBQVMsQ0FBQyxDQUFDO0lBTzlGLENBQUM7SUFFRCxjQUFjO1FBQ1YsT0FBTyxJQUFJLENBQUMsaUNBQWlDLEVBQUUsQ0FBQztJQUNwRCxDQUFDO0lBRUQsU0FBUztRQUNMLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVELDZCQUE2QixDQUFDLElBQVksRUFBRSxFQUFVLEVBQUUsSUFBYTtRQUNqRSxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ25DLElBQUksQ0FBQyxzQkFBc0I7aUJBQ3RCLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEtBQUssU0FBUyxDQUFDLENBQUM7aUJBQzlDLFNBQVMsQ0FBQyxDQUFDLE9BQWdCLEVBQUUsRUFBRTtnQkFDNUIsSUFBSSxDQUFDLE9BQU8sRUFBRTtvQkFDVixNQUFNLENBQUMsSUFBSSxLQUFLLENBQUMsNENBQTRDLENBQUMsQ0FBQyxDQUFDO2lCQUNuRTtxQkFBTTtvQkFDSCxPQUFPLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLENBQ3JELElBQUksb0JBQW9CLENBQUMsRUFBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FDNUUsQ0FBQyxDQUFDO2lCQUNOO1lBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDWCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxhQUFhLENBQUMsSUFBWSxFQUFFLElBQWMsRUFBRSxFQUFXO1FBQ25ELE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDbkMsSUFBSSxDQUFDLHNCQUFzQjtpQkFDdEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLE9BQU8sS0FBSyxTQUFTLENBQUMsQ0FBQztpQkFDOUMsU0FBUyxDQUFDLENBQUMsT0FBZ0IsRUFBRSxFQUFFO2dCQUM1QixJQUFJLENBQUMsT0FBTyxFQUFFO29CQUNWLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDLENBQUM7aUJBQ25FO3FCQUFNO29CQUNILE9BQU8sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FDckQsSUFBSSxvQkFBb0IsQ0FBQyxFQUFDLElBQUksRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUM3RSxDQUFDLENBQUM7aUJBQ047WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNYLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELFlBQVksQ0FBQyxNQUFjO1FBQ3ZCLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLGtCQUFrQixDQUFXLENBQUM7UUFDNUUsSUFBSSxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLFlBQVksRUFBRTtZQUN0QyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUNqQyxPQUFPLElBQUksQ0FBQztTQUNmO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztJQUVELEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxJQUFZO1FBQ2hDLElBQUk7WUFDQSxNQUFNLGdCQUFnQixHQUFHLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLENBQzVFLElBQUkseUJBQXlCLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLENBQ2pELENBQUM7WUFDRixPQUFPLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQ3BGO1FBQUMsT0FBTyxDQUFDLEVBQUU7WUFDUixJQUFJLENBQUMsWUFBWSxpQkFBaUI7Z0JBQzlCLENBQUMsQ0FBQyxDQUFDLGNBQWMsS0FBSyxnQkFBZ0IsSUFBSSxDQUFDLENBQUMsU0FBUyxLQUFLLEdBQUcsQ0FBQyxFQUFFO2dCQUNoRSxPQUFPLEVBQUUsQ0FBQzthQUNiO1lBRUQsTUFBTSxDQUFDLENBQUM7U0FDWDtJQUNMLENBQUM7SUFFTyxLQUFLLENBQUMsaUNBQWlDO1FBQzNDLElBQUksV0FBb0IsQ0FBQztRQUN6QixJQUFJO1lBQ0EsTUFBTSxPQUFPLEdBQUcsTUFBTSxJQUFJLENBQUMsc0JBQXNCLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMvRSxXQUFXLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsbURBQW1ELENBQUMsQ0FBQztTQUNoRztRQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ1IsV0FBVyxHQUFHLEtBQUssQ0FBQztTQUN2QjtRQUNELElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDbEQsQ0FBQztDQUVKIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgeG1sIH0gZnJvbSAnQHhtcHAvY2xpZW50JztcbmltcG9ydCB7IEVsZW1lbnQgfSBmcm9tICdsdHgnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBmaWx0ZXIgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBJcVJlc3BvbnNlU3RhbnphLCBTdGFuemEgfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL3N0YW56YSc7XG5pbXBvcnQgeyBBYnN0cmFjdFN0YW56YUJ1aWxkZXIgfSBmcm9tICcuLi9hYnN0cmFjdC1zdGFuemEtYnVpbGRlcic7XG5pbXBvcnQgeyBYbXBwUmVzcG9uc2VFcnJvciB9IGZyb20gJy4uL3htcHAtcmVzcG9uc2UuZXJyb3InO1xuaW1wb3J0IHsgWG1wcENoYXRBZGFwdGVyIH0gZnJvbSAnLi4veG1wcC1jaGF0LWFkYXB0ZXIuc2VydmljZSc7XG5pbXBvcnQgeyBBYnN0cmFjdFhtcHBQbHVnaW4gfSBmcm9tICcuL2Fic3RyYWN0LXhtcHAtcGx1Z2luJztcbmltcG9ydCB7IFNlcnZpY2VEaXNjb3ZlcnlQbHVnaW4gfSBmcm9tICcuL3NlcnZpY2UtZGlzY292ZXJ5LnBsdWdpbic7XG5pbXBvcnQgeyBzZXJpYWxpemVUb1N1Ym1pdEZvcm0gfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL2Zvcm0nO1xuXG5leHBvcnQgY29uc3QgUFVCU1VCX0VWRU5UX1hNTE5TID0gJ2h0dHA6Ly9qYWJiZXIub3JnL3Byb3RvY29sL3B1YnN1YiNldmVudCc7XG5cbmludGVyZmFjZSBQdWJsaXNoT3B0aW9ucyB7XG4gICAgbm9kZT86IHN0cmluZztcbiAgICBpZD86IGFueTtcbiAgICBkYXRhPzogRWxlbWVudDtcbiAgICBwZXJzaXN0SXRlbXM/OiBib29sZWFuO1xufVxuXG5jbGFzcyBQdWJsaXNoU3RhbnphQnVpbGRlciBleHRlbmRzIEFic3RyYWN0U3RhbnphQnVpbGRlciB7XG5cbiAgICBwcml2YXRlIHJlYWRvbmx5IHB1Ymxpc2hPcHRpb25zOiBQdWJsaXNoT3B0aW9ucyA9IHtcbiAgICAgICAgcGVyc2lzdEl0ZW1zOiBmYWxzZSxcbiAgICB9O1xuXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogUHVibGlzaE9wdGlvbnMpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICAgICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgICAgICAgIHRoaXMucHVibGlzaE9wdGlvbnMgPSB7Li4udGhpcy5wdWJsaXNoT3B0aW9ucywgLi4ub3B0aW9uc307XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB0b1N0YW56YSgpIHtcbiAgICAgICAgY29uc3Qge25vZGUsIGlkLCBwZXJzaXN0SXRlbXN9ID0gdGhpcy5wdWJsaXNoT3B0aW9ucztcblxuICAgICAgICAvLyBuZWNlc3NhcnkgYXMgYSAnZXZlbnQtb25seScgcHVibGlzaCBpcyBjdXJyZW50bHkgYnJva2VuIGluIGVqYWJiZXJkLCBzZWVcbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL3Byb2Nlc3NvbmUvZWphYmJlcmQvaXNzdWVzLzI3OTlcbiAgICAgICAgY29uc3QgZGF0YSA9IHRoaXMucHVibGlzaE9wdGlvbnMuZGF0YSB8fCB4bWwoJ2RhdGEnKTtcblxuICAgICAgICByZXR1cm4geG1sKCdpcScsIHt0eXBlOiAnc2V0J30sXG4gICAgICAgICAgICB4bWwoJ3B1YnN1YicsIHt4bWxuczogJ2h0dHA6Ly9qYWJiZXIub3JnL3Byb3RvY29sL3B1YnN1Yid9LFxuICAgICAgICAgICAgICAgIHhtbCgncHVibGlzaCcsIHtub2RlfSxcbiAgICAgICAgICAgICAgICAgICAgeG1sKCdpdGVtJywge2lkfSwgZGF0YSksXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICB4bWwoJ3B1Ymxpc2gtb3B0aW9ucycsIHt9LFxuICAgICAgICAgICAgICAgICAgICBzZXJpYWxpemVUb1N1Ym1pdEZvcm0oe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogJ3N1Ym1pdCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBpbnN0cnVjdGlvbnM6IFtdLFxuICAgICAgICAgICAgICAgICAgICAgICAgZmllbGRzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3R5cGU6ICdoaWRkZW4nLCB2YXJpYWJsZTogJ0ZPUk1fVFlQRScsIHZhbHVlOiAnaHR0cDovL2phYmJlci5vcmcvcHJvdG9jb2wvcHVic3ViI3B1Ymxpc2gtb3B0aW9ucyd9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt0eXBlOiAnYm9vbGVhbicsIHZhcmlhYmxlOiAncHVic3ViI3BlcnNpc3RfaXRlbXMnLCB2YWx1ZTogcGVyc2lzdEl0ZW1zID09PSB0cnVlfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dHlwZTogJ2xpc3Qtc2luZ2xlJywgdmFyaWFibGU6ICdwdWJzdWIjYWNjZXNzX21vZGVsJywgdmFsdWU6ICd3aGl0ZWxpc3QnfSxcbiAgICAgICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICApLFxuICAgICAgICApO1xuICAgIH1cblxufVxuXG5jbGFzcyBSZXRyaWV2ZURhdGFTdGFuemFCdWlsZGVyIGV4dGVuZHMgQWJzdHJhY3RTdGFuemFCdWlsZGVyIHtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgbm9kZTogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKCk7XG4gICAgfVxuXG4gICAgdG9TdGFuemEoKSB7XG4gICAgICAgIHJldHVybiB4bWwoJ2lxJywge3R5cGU6ICdnZXQnfSxcbiAgICAgICAgICAgIHhtbCgncHVic3ViJywge3htbG5zOiAnaHR0cDovL2phYmJlci5vcmcvcHJvdG9jb2wvcHVic3ViJ30sXG4gICAgICAgICAgICAgICAgeG1sKCdpdGVtcycsIHtub2RlOiB0aGlzLm5vZGV9KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgfVxuXG59XG5cbi8qKlxuICogWEVQLTAwNjAgUHVibGlzaCBTdWJzY3JpYmUgKGh0dHBzOi8veG1wcC5vcmcvZXh0ZW5zaW9ucy94ZXAtMDA2MC5odG1sKVxuICogWEVQLTAyMjMgUGVyc2lzdGVudCBTdG9yYWdlIG9mIFByaXZhdGUgRGF0YSB2aWEgUHViU3ViIChodHRwczovL3htcHAub3JnL2V4dGVuc2lvbnMveGVwLTAyMjMuaHRtbClcbiAqL1xuZXhwb3J0IGNsYXNzIFB1Ymxpc2hTdWJzY3JpYmVQbHVnaW4gZXh0ZW5kcyBBYnN0cmFjdFhtcHBQbHVnaW4ge1xuXG4gICAgcmVhZG9ubHkgcHVibGlzaCQgPSBuZXcgU3ViamVjdDxTdGFuemE+KCk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBzdXBwb3J0c1ByaXZhdGVQdWJsaXNoID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuIHwgJ3Vua25vd24nPigndW5rbm93bicpO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgeG1wcENoYXRBZGFwdGVyOiBYbXBwQ2hhdEFkYXB0ZXIsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgc2VydmljZURpc2NvdmVyeVBsdWdpbjogU2VydmljZURpc2NvdmVyeVBsdWdpbixcbiAgICApIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICBvbkJlZm9yZU9ubGluZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGV0ZXJtaW5lU3VwcG9ydEZvclByaXZhdGVQdWJsaXNoKCk7XG4gICAgfVxuXG4gICAgb25PZmZsaW5lKCkge1xuICAgICAgICB0aGlzLnN1cHBvcnRzUHJpdmF0ZVB1Ymxpc2gubmV4dCgndW5rbm93bicpO1xuICAgIH1cblxuICAgIHN0b3JlUHJpdmF0ZVBheWxvYWRQZXJzaXN0ZW50KG5vZGU6IHN0cmluZywgaWQ6IHN0cmluZywgZGF0YTogRWxlbWVudCk6IFByb21pc2U8SXFSZXNwb25zZVN0YW56YTwncmVzdWx0Jz4+IHtcbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIHRoaXMuc3VwcG9ydHNQcml2YXRlUHVibGlzaFxuICAgICAgICAgICAgICAgIC5waXBlKGZpbHRlcihzdXBwb3J0ID0+IHN1cHBvcnQgIT09ICd1bmtub3duJykpXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZSgoc3VwcG9ydDogYm9vbGVhbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoIXN1cHBvcnQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoJ2RvZXMgbm90IHN1cHBvcnQgcHJpdmF0ZSBwdWJsaXNoIHN1YnNjcmliZScpKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUodGhpcy54bXBwQ2hhdEFkYXB0ZXIuY2hhdENvbm5lY3Rpb25TZXJ2aWNlLnNlbmRJcShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUHVibGlzaFN0YW56YUJ1aWxkZXIoe25vZGUsIGlkLCBkYXRhLCBwZXJzaXN0SXRlbXM6IHRydWV9KS50b1N0YW56YSgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZU5vdGlmeShub2RlOiBzdHJpbmcsIGRhdGE/OiBFbGVtZW50LCBpZD86IHN0cmluZyk6IFByb21pc2U8SXFSZXNwb25zZVN0YW56YT4ge1xuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5zdXBwb3J0c1ByaXZhdGVQdWJsaXNoXG4gICAgICAgICAgICAgICAgLnBpcGUoZmlsdGVyKHN1cHBvcnQgPT4gc3VwcG9ydCAhPT0gJ3Vua25vd24nKSlcbiAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKChzdXBwb3J0OiBib29sZWFuKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc3VwcG9ydCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignZG9lcyBub3Qgc3VwcG9ydCBwcml2YXRlIHB1Ymxpc2ggc3Vic2NyaWJlJykpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh0aGlzLnhtcHBDaGF0QWRhcHRlci5jaGF0Q29ubmVjdGlvblNlcnZpY2Uuc2VuZElxKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBQdWJsaXNoU3RhbnphQnVpbGRlcih7bm9kZSwgaWQsIGRhdGEsIHBlcnNpc3RJdGVtczogZmFsc2V9KS50b1N0YW56YSgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgKSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgaGFuZGxlU3RhbnphKHN0YW56YTogU3RhbnphKTogYm9vbGVhbiB7XG4gICAgICAgIGNvbnN0IGV2ZW50RWxlbWVudCA9IHN0YW56YS5nZXRDaGlsZCgnZXZlbnQnLCBQVUJTVUJfRVZFTlRfWE1MTlMpIGFzIFN0YW56YTtcbiAgICAgICAgaWYgKHN0YW56YS5pcygnbWVzc2FnZScpICYmIGV2ZW50RWxlbWVudCkge1xuICAgICAgICAgICAgdGhpcy5wdWJsaXNoJC5uZXh0KGV2ZW50RWxlbWVudCk7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgYXN5bmMgcmV0cmlldmVOb2RlSXRlbXMobm9kZTogc3RyaW5nKTogUHJvbWlzZTxFbGVtZW50W10+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGNvbnN0IGlxUmVzcG9uc2VTdGFuemEgPSBhd2FpdCB0aGlzLnhtcHBDaGF0QWRhcHRlci5jaGF0Q29ubmVjdGlvblNlcnZpY2Uuc2VuZElxKFxuICAgICAgICAgICAgICAgIG5ldyBSZXRyaWV2ZURhdGFTdGFuemFCdWlsZGVyKG5vZGUpLnRvU3RhbnphKCksXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIGlxUmVzcG9uc2VTdGFuemEuZ2V0Q2hpbGQoJ3B1YnN1YicpLmdldENoaWxkKCdpdGVtcycpLmdldENoaWxkcmVuKCdpdGVtJyk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGlmIChlIGluc3RhbmNlb2YgWG1wcFJlc3BvbnNlRXJyb3IgJiZcbiAgICAgICAgICAgICAgICAoZS5lcnJvckNvbmRpdGlvbiA9PT0gJ2l0ZW0tbm90LWZvdW5kJyB8fCBlLmVycm9yQ29kZSA9PT0gNDA0KSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgZGV0ZXJtaW5lU3VwcG9ydEZvclByaXZhdGVQdWJsaXNoKCkge1xuICAgICAgICBsZXQgaXNTdXBwb3J0ZWQ6IGJvb2xlYW47XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBzZXJ2aWNlID0gYXdhaXQgdGhpcy5zZXJ2aWNlRGlzY292ZXJ5UGx1Z2luLmZpbmRTZXJ2aWNlKCdwdWJzdWInLCAncGVwJyk7XG4gICAgICAgICAgICBpc1N1cHBvcnRlZCA9IHNlcnZpY2UuZmVhdHVyZXMuaW5jbHVkZXMoJ2h0dHA6Ly9qYWJiZXIub3JnL3Byb3RvY29sL3B1YnN1YiNwdWJsaXNoLW9wdGlvbnMnKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgaXNTdXBwb3J0ZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnN1cHBvcnRzUHJpdmF0ZVB1Ymxpc2gubmV4dChpc1N1cHBvcnRlZCk7XG4gICAgfVxuXG59XG4iXX0=