@universis/common
Version:
Universis - common directives and services
215 lines (214 loc) • 27.5 kB
JavaScript
import * as tslib_1 from "tslib";
import { Inject, Injectable, InjectionToken, Injector } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import { EventSourcePolyfill } from 'event-source-polyfill';
import { ConfigurationService } from '../../shared/services/configuration.service';
import { ActivatedUser } from '../../auth/services/activated-user.service';
import { takeUntil } from 'rxjs/operators';
export var ServerEventServiceStatus;
(function (ServerEventServiceStatus) {
ServerEventServiceStatus[ServerEventServiceStatus["Connecting"] = 0] = "Connecting";
ServerEventServiceStatus[ServerEventServiceStatus["Open"] = 1] = "Open";
ServerEventServiceStatus[ServerEventServiceStatus["Closed"] = 2] = "Closed";
})(ServerEventServiceStatus || (ServerEventServiceStatus = {}));
export let SERVER_EVENT_SUBSCRIBERS = new InjectionToken('server.event.subscribers');
export let SERVER_EVENT_CHILD_SUBSCRIBERS = new InjectionToken('server.event.child.subscribers');
export class ServerEventService {
constructor(configuration, injector, addSubscribers) {
this.configuration = configuration;
this.injector = injector;
this.addSubscribers = addSubscribers;
this.message = new BehaviorSubject(null);
this.error = new BehaviorSubject(null);
this._heartbeatTimeout = 120 * 1000;
this.subscribers = new Map();
this.destroy$ = new Subject();
this.configuration.loaded
.pipe(takeUntil(this.destroy$))
.subscribe(applicationConfiguration => {
if (applicationConfiguration != null) {
// inject activated user only after config is loaded
this.activatedUser = this.injector.get(ActivatedUser);
// load
this.load();
// and destroy subscription
this.closeSubscription();
}
});
}
closeSubscription() {
this.destroy$.next();
this.destroy$.complete();
}
load() {
if (this.configuration.config
&& this.configuration.config.settings
&& this.configuration.config.settings.serverEvent) {
const serverEvent = this.configuration.config.settings.serverEvent;
if (serverEvent.heartbeatTimeout) {
this._heartbeatTimeout = serverEvent.heartbeatTimeout;
}
}
if (Array.isArray(this.addSubscribers)) {
this.addSubscribers.forEach((addSubscriber) => {
this.subscribe(addSubscriber);
});
}
this.activatedUser.user.subscribe((user) => {
if (user == null) {
if (this.status === ServerEventServiceStatus.Open) {
this.close();
}
}
if (user) {
if (this.status === ServerEventServiceStatus.Open) {
this.close();
}
this.open();
}
});
}
/**
* Adds a server event subscriber
* @param token
*/
subscribe(token) {
const subscriber = this.injector.get(token);
if (subscriber == null) {
throw new Error('Server event subscriber cannot be instantiated.');
}
if (typeof subscriber.subscribe !== 'function') {
throw new Error('Expected an instance which implements ServerEventSubscriber.');
}
const observer = subscriber.subscribe.bind(subscriber);
this.subscribers.set(token, this.message.subscribe(observer));
}
/**
* Removes a server event subscriber
* @param token
*/
unsubscribe(token) {
const subscription = this.subscribers.get(token);
// if subscription is not null
if (subscription != null) {
// unsubscribe
subscription.unsubscribe();
}
// remove item
this.subscribers.delete(token);
}
get source() {
if (this.configuration.settings &&
this.configuration.settings.remote &&
this.configuration.settings.remote.server) {
return new URL('users/me/events/subscribe', this.configuration.settings.remote.server).toString();
}
return '/users/me/events/subscribe';
}
get heartbeatTimeout() {
return this._heartbeatTimeout;
}
get status() {
if (this.eventSource) {
return this.eventSource.readyState;
}
return ServerEventServiceStatus.Closed;
}
openAsync() {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
return this.open();
});
}
getUserSync() {
const value = sessionStorage.getItem('currentUser');
if (value == null) {
return;
}
return JSON.parse(value);
}
open() {
if (this.status === ServerEventServiceStatus.Open) {
return this;
}
const user = this.getUserSync();
const headers = {
'Accept': 'application/json',
'Authorization': `Bearer ${user.token.access_token}`
};
this.eventSource = new EventSourcePolyfill(this.source, {
heartbeatTimeout: this.heartbeatTimeout,
headers
});
const messageListener = this.onMessage.bind(this);
const errorListener = this.onError.bind(this);
this.eventSource.addEventListener('message', messageListener);
this.eventSource.addEventListener('error', errorListener);
// set heartbeat interval
this._heartbeatInterval = setInterval(() => {
// close
if (this.eventSource && this.eventSource.readyState !== ServerEventServiceStatus.Closed) {
this.eventSource.close();
}
const user = this.getUserSync();
if (user == null) {
return;
}
const headers = {
'Accept': 'application/json',
'Authorization': `Bearer ${user.token.access_token}`
};
// and create new
this.eventSource = new EventSourcePolyfill(this.source, {
heartbeatTimeout: this.heartbeatTimeout,
headers
});
// set listeners
this.eventSource.addEventListener('message', messageListener);
this.eventSource.addEventListener('error', errorListener);
}, this.heartbeatTimeout - 5000); // set heartbeat interval
return this;
}
onMessage(ev) {
// emit message
if (ev.type === 'message') {
let data = null;
if (typeof ev.data === 'string') {
data = JSON.parse(ev.data);
}
else if (typeof ev.data === 'object') {
data = ev.data;
}
if (data) {
this.message.next(data);
}
}
}
onError(ev) {
// emit error
if (ev.error) {
return this.error.next(ev.error);
}
return this.error.next(ev);
}
close() {
if (this.eventSource) {
this.eventSource.close();
return true;
}
// clear heartbeat interval
if (this._heartbeatInterval) {
clearInterval(this._heartbeatInterval);
}
return false;
}
}
ServerEventService.decorators = [
{ type: Injectable }
];
/** @nocollapse */
ServerEventService.ctorParameters = () => [
{ type: ConfigurationService },
{ type: Injector },
{ type: Array, decorators: [{ type: Inject, args: [SERVER_EVENT_SUBSCRIBERS,] }] }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLWV2ZW50LnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9AdW5pdmVyc2lzL2NvbW1vbi8iLCJzb3VyY2VzIjpbImV2ZW50cy9zZXJ2aWNlcy9zZXJ2ZXItZXZlbnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFDLE1BQU0sRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLFFBQVEsRUFBTyxNQUFNLGVBQWUsQ0FBQztBQUNqRixPQUFPLEVBQUMsZUFBZSxFQUFFLE9BQU8sRUFBZSxNQUFNLE1BQU0sQ0FBQztBQUM1RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUNuRixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDM0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE1BQU0sQ0FBTixJQUFZLHdCQUlYO0FBSkQsV0FBWSx3QkFBd0I7SUFDaEMsbUZBQVUsQ0FBQTtJQUNWLHVFQUFJLENBQUE7SUFDSiwyRUFBTSxDQUFBO0FBQ1YsQ0FBQyxFQUpXLHdCQUF3QixLQUF4Qix3QkFBd0IsUUFJbkM7QUFrQ0QsTUFBTSxDQUFDLElBQUksd0JBQXdCLEdBQUcsSUFBSSxjQUFjLENBQXFDLDBCQUEwQixDQUFDLENBQUM7QUFFekgsTUFBTSxDQUFDLElBQUksOEJBQThCLEdBQUcsSUFBSSxjQUFjLENBQXFDLGdDQUFnQyxDQUFDLENBQUM7QUFHckksTUFBTTtJQVVGLFlBQW9CLGFBQW1DLEVBQzNDLFFBQWtCLEVBQ2dCLGNBQWtEO1FBRjVFLGtCQUFhLEdBQWIsYUFBYSxDQUFzQjtRQUMzQyxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBQ2dCLG1CQUFjLEdBQWQsY0FBYyxDQUFvQztRQVh6RixZQUFPLEdBQXlCLElBQUksZUFBZSxDQUFNLElBQUksQ0FB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RSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQzlCO2lCQUFNLElBQUksT0FBTyxFQUFFLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRTtnQkFDcEMsSUFBSSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7YUFDbEI7WUFDRCxJQUFJLElBQUksRUFBRTtnQkFDTixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUMzQjtTQUNKO0lBQ0wsQ0FBQztJQUVTLE9BQU8sQ0FBQyxFQUFPO1FBQ3JCLGFBQWE7UUFDYixJQUFJLEVBQUUsQ0FBQyxLQUFLLEVBQUU7WUFDVixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNwQztRQUNELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVELEtBQUs7UUFDRCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDbEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN6QixPQUFPLElBQUksQ0FBQztTQUNmO1FBQ0QsMkJBQTJCO1FBQzNCLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFO1lBQ3pCLGFBQWEsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztTQUMxQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2pCLENBQUM7OztZQXpNSixVQUFVOzs7O1lBN0NGLG9CQUFvQjtZQUhlLFFBQVE7WUE2RGMsS0FBSyx1QkFBOUQsTUFBTSxTQUFDLHdCQUF3QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7SW5qZWN0LCBJbmplY3RhYmxlLCBJbmplY3Rpb25Ub2tlbiwgSW5qZWN0b3IsIFR5cGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtCZWhhdmlvclN1YmplY3QsIFN1YmplY3QsIFN1YnNjcmlwdGlvbn0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBFdmVudFNvdXJjZVBvbHlmaWxsIH0gZnJvbSAnZXZlbnQtc291cmNlLXBvbHlmaWxsJztcbmltcG9ydCB7IENvbmZpZ3VyYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2hhcmVkL3NlcnZpY2VzL2NvbmZpZ3VyYXRpb24uc2VydmljZSc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRVc2VyIH0gZnJvbSAnLi4vLi4vYXV0aC9zZXJ2aWNlcy9hY3RpdmF0ZWQtdXNlci5zZXJ2aWNlJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmV4cG9ydCBlbnVtIFNlcnZlckV2ZW50U2VydmljZVN0YXR1cyB7XG4gICAgQ29ubmVjdGluZyxcbiAgICBPcGVuLFxuICAgIENsb3NlZFxufVxuXG5kZWNsYXJlIGludGVyZmFjZSBVc2VyU25hcHNob3Qge1xuICAgIGlkPzogYW55O1xuICAgIG5hbWU6IHN0cmluZztcbiAgICB0b2tlbjoge1xuICAgICAgICBhY2Nlc3NfdG9rZW46IHN0cmluZztcbiAgICAgICAgc2NvcGU6IHN0cmluZztcbiAgICB9O1xufVxuXG5leHBvcnQgZGVjbGFyZSBpbnRlcmZhY2UgU2VydmVyRXZlbnQge1xuICAgIGlkPzogc3RyaW5nO1xuICAgIGFkZGl0aW9uYWxUeXBlPzogc3RyaW5nO1xuICAgIGVudGl0eVNldD86IHN0cmluZztcbiAgICBlbnRpdHlUeXBlPzogc3RyaW5nO1xuICAgIGVudGl0eUFjdGlvbj86IHN0cmluZztcbiAgICB0YXJnZXQ/OiBhbnk7XG4gICAgcmVzdWx0PzogYW55O1xuICAgIHN0YXR1cz86IGFueTtcbiAgICBlcnJvcj86IGFueTtcbiAgICByZWNpcGllbnQ/OiBzdHJpbmc7XG4gICAgc2NvcGU/OiBzdHJpbmc7XG4gICAgZGF0ZUNyZWF0ZWQ/OiBEYXRlO1xufVxuXG5leHBvcnQgZGVjbGFyZSBpbnRlcmZhY2UgU2VydmVyRXZlbnRTdWJzY3JpYmVyIHtcbiAgICBzdWJzY3JpYmU8VD4oZXZlbnQ6IFQpOiB2b2lkO1xufVxuXG5kZWNsYXJlIGludGVyZmFjZSBTZXJ2ZXJFdmVudFNlcnZpY2VDb25maWd1cmF0aW9uIHtcbiAgICBoZWFydGJlYXRUaW1lb3V0PzogbnVtYmVyO1xufVxuXG5leHBvcnQgbGV0IFNFUlZFUl9FVkVOVF9TVUJTQ1JJQkVSUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxBcnJheTxUeXBlPFNlcnZlckV2ZW50U3Vic2NyaWJlcj4+Pignc2VydmVyLmV2ZW50LnN1YnNjcmliZXJzJyk7XG5cbmV4cG9ydCBsZXQgU0VSVkVSX0VWRU5UX0NISUxEX1NVQlNDUklCRVJTID0gbmV3IEluamVjdGlvblRva2VuPEFycmF5PFR5cGU8U2VydmVyRXZlbnRTdWJzY3JpYmVyPj4+KCdzZXJ2ZXIuZXZlbnQuY2hpbGQuc3Vic2NyaWJlcnMnKTtcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFNlcnZlckV2ZW50U2VydmljZSB7XG4gICAgcHVibGljIG1lc3NhZ2U6IEJlaGF2aW9yU3ViamVjdDxhbnk+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxhbnk+KG51bGwpO1xuICAgIHB1YmxpYyBlcnJvcjogQmVoYXZpb3JTdWJqZWN0PGFueT4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGFueT4obnVsbCk7XG4gICAgcHJpdmF0ZSBldmVudFNvdXJjZTogRXZlbnRTb3VyY2VQb2x5ZmlsbDtcbiAgICBwcml2YXRlIF9oZWFydGJlYXRUaW1lb3V0ID0gMTIwICogMTAwMDtcbiAgICBwcml2YXRlIF9oZWFydGJlYXRJbnRlcnZhbDogYW55O1xuICAgIHByaXZhdGUgYWN0aXZhdGVkVXNlcjogQWN0aXZhdGVkVXNlcjtcbiAgICBwdWJsaWMgc3Vic2NyaWJlcnM6IE1hcDxhbnksIFN1YnNjcmlwdGlvbj4gPSBuZXcgTWFwKCk7XG4gICAgcHJpdmF0ZSBkZXN0cm95JDogU3ViamVjdDx2b2lkPiA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbmZpZ3VyYXRpb246IENvbmZpZ3VyYXRpb25TZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvcixcbiAgICAgICAgQEluamVjdChTRVJWRVJfRVZFTlRfU1VCU0NSSUJFUlMpIHByaXZhdGUgYWRkU3Vic2NyaWJlcnM6IEFycmF5PFR5cGU8U2VydmVyRXZlbnRTdWJzY3JpYmVyPj4pIHtcbiAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5sb2FkZWRcbiAgICAgICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgICAgICAgICAgLnN1YnNjcmliZShhcHBsaWNhdGlvbkNvbmZpZ3VyYXRpb24gPT4ge1xuICAgICAgICAgICAgICAgIGlmIChhcHBsaWNhdGlvbkNvbmZpZ3VyYXRpb24gIT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBpbmplY3QgYWN0aXZhdGVkIHVzZXIgb25seSBhZnRlciBjb25maWcgaXMgbG9hZGVkXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuYWN0aXZhdGVkVXNlciA9IHRoaXMuaW5qZWN0b3IuZ2V0KEFjdGl2YXRlZFVzZXIpO1xuICAgICAgICAgICAgICAgICAgICAvLyBsb2FkXG4gICAgICAgICAgICAgICAgICAgIHRoaXMubG9hZCgpO1xuICAgICAgICAgICAgICAgICAgICAvLyBhbmQgZGVzdHJveSBzdWJzY3JpcHRpb25cbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jbG9zZVN1YnNjcmlwdGlvbigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICBjbG9zZVN1YnNjcmlwdGlvbigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICBsb2FkKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5jb25maWd1cmF0aW9uLmNvbmZpZ1xuICAgICAgICAgICAgJiYgdGhpcy5jb25maWd1cmF0aW9uLmNvbmZpZy5zZXR0aW5nc1xuICAgICAgICAgICAgJiYgdGhpcy5jb25maWd1cmF0aW9uLmNvbmZpZy5zZXR0aW5ncy5zZXJ2ZXJFdmVudCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHNlcnZlckV2ZW50OiBTZXJ2ZXJFdmVudFNlcnZpY2VDb25maWd1cmF0aW9uID0gdGhpcy5jb25maWd1cmF0aW9uLmNvbmZpZy5zZXR0aW5ncy5zZXJ2ZXJFdmVudDtcbiAgICAgICAgICAgICAgICBpZiAoc2VydmVyRXZlbnQuaGVhcnRiZWF0VGltZW91dCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl9oZWFydGJlYXRUaW1lb3V0ID0gc2VydmVyRXZlbnQuaGVhcnRiZWF0VGltZW91dDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5hZGRTdWJzY3JpYmVycykpIHtcbiAgICAgICAgICAgIHRoaXMuYWRkU3Vic2NyaWJlcnMuZm9yRWFjaCgoYWRkU3Vic2NyaWJlcikgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuc3Vic2NyaWJlKGFkZFN1YnNjcmliZXIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5hY3RpdmF0ZWRVc2VyLnVzZXIuc3Vic2NyaWJlKCh1c2VyKSA9PiB7XG4gICAgICAgICAgICBpZiAodXNlciA9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdHVzID09PSBTZXJ2ZXJFdmVudFNlcnZpY2VTdGF0dXMuT3Blbikge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHVzZXIpIHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5zdGF0dXMgPT09IFNlcnZlckV2ZW50U2VydmljZVN0YXR1cy5PcGVuKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5vcGVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEFkZHMgYSBzZXJ2ZXIgZXZlbnQgc3Vic2NyaWJlclxuICAgICAqIEBwYXJhbSB0b2tlblxuICAgICAqL1xuICAgIHN1YnNjcmliZSh0b2tlbjogVHlwZTxTZXJ2ZXJFdmVudFN1YnNjcmliZXI+KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHN1YnNjcmliZXI6IFNlcnZlckV2ZW50U3Vic2NyaWJlciA9IHRoaXMuaW5qZWN0b3IuZ2V0PFNlcnZlckV2ZW50U3Vic2NyaWJlcj4odG9rZW4pO1xuICAgICAgICBpZiAoc3Vic2NyaWJlciA9PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlcnZlciBldmVudCBzdWJzY3JpYmVyIGNhbm5vdCBiZSBpbnN0YW50aWF0ZWQuJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBzdWJzY3JpYmVyLnN1YnNjcmliZSAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFeHBlY3RlZCBhbiBpbnN0YW5jZSB3aGljaCBpbXBsZW1lbnRzIFNlcnZlckV2ZW50U3Vic2NyaWJlci4nKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBvYnNlcnZlciA9IHN1YnNjcmliZXIuc3Vic2NyaWJlLmJpbmQoc3Vic2NyaWJlcik7XG4gICAgICAgIHRoaXMuc3Vic2NyaWJlcnMuc2V0KHRva2VuLCB0aGlzLm1lc3NhZ2Uuc3Vic2NyaWJlKG9ic2VydmVyKSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhIHNlcnZlciBldmVudCBzdWJzY3JpYmVyXG4gICAgICogQHBhcmFtIHRva2VuXG4gICAgICovXG4gICAgdW5zdWJzY3JpYmUodG9rZW46IFR5cGU8U2VydmVyRXZlbnRTdWJzY3JpYmVyPik6IHZvaWQge1xuICAgICAgICBjb25zdCBzdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiA9IHRoaXMuc3Vic2NyaWJlcnMuZ2V0KHRva2VuKTtcbiAgICAgICAgLy8gaWYgc3Vic2NyaXB0aW9uIGlzIG5vdCBudWxsXG4gICAgICAgIGlmIChzdWJzY3JpcHRpb24gIT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gdW5zdWJzY3JpYmVcbiAgICAgICAgICAgIHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHJlbW92ZSBpdGVtXG4gICAgICAgIHRoaXMuc3Vic2NyaWJlcnMuZGVsZXRlKHRva2VuKTtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IHNvdXJjZSgpOiBzdHJpbmcge1xuICAgICAgICBpZiAodGhpcy5jb25maWd1cmF0aW9uLnNldHRpbmdzICYmXG4gICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uc2V0dGluZ3MucmVtb3RlICYmXG4gICAgICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uc2V0dGluZ3MucmVtb3RlLnNlcnZlcikge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBVUkwoJ3VzZXJzL21lL2V2ZW50cy9zdWJzY3JpYmUnLCB0aGlzLmNvbmZpZ3VyYXRpb24uc2V0dGluZ3MucmVtb3RlLnNlcnZlcikudG9TdHJpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gJy91c2Vycy9tZS9ldmVudHMvc3Vic2NyaWJlJztcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgZ2V0IGhlYXJ0YmVhdFRpbWVvdXQoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2hlYXJ0YmVhdFRpbWVvdXQ7XG4gICAgfVxuXG4gICAgZ2V0IHN0YXR1cygpOiBTZXJ2ZXJFdmVudFNlcnZpY2VTdGF0dXMge1xuICAgICAgICBpZiAodGhpcy5ldmVudFNvdXJjZSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRTb3VyY2UucmVhZHlTdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU2VydmVyRXZlbnRTZXJ2aWNlU3RhdHVzLkNsb3NlZDtcbiAgICB9XG5cbiAgICBhc3luYyBvcGVuQXN5bmMoKTogUHJvbWlzZTxTZXJ2ZXJFdmVudFNlcnZpY2U+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3BlbigpO1xuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0VXNlclN5bmMoKTogVXNlclNuYXBzaG90IHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKCdjdXJyZW50VXNlcicpO1xuICAgICAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBKU09OLnBhcnNlKHZhbHVlKSBhcyBVc2VyU25hcHNob3Q7XG4gICAgfVxuXG4gICAgb3BlbigpOiB0aGlzIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdHVzID09PSBTZXJ2ZXJFdmVudFNlcnZpY2VTdGF0dXMuT3Blbikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdXNlcjogVXNlclNuYXBzaG90ID0gdGhpcy5nZXRVc2VyU3luYygpO1xuICAgICAgICBjb25zdCBoZWFkZXJzID0ge1xuICAgICAgICAgICAgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgICdBdXRob3JpemF0aW9uJzogYEJlYXJlciAke3VzZXIudG9rZW4uYWNjZXNzX3Rva2VufWBcbiAgICAgICAgfTtcbiAgICAgICAgdGhpcy5ldmVudFNvdXJjZSA9IG5ldyBFdmVudFNvdXJjZVBvbHlmaWxsKHRoaXMuc291cmNlLCB7XG4gICAgICAgICAgICBoZWFydGJlYXRUaW1lb3V0OiB0aGlzLmhlYXJ0YmVhdFRpbWVvdXQsXG4gICAgICAgICAgICBoZWFkZXJzXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBtZXNzYWdlTGlzdGVuZXIgPSB0aGlzLm9uTWVzc2FnZS5iaW5kKHRoaXMpO1xuICAgICAgICBjb25zdCBlcnJvckxpc3RlbmVyID0gdGhpcy5vbkVycm9yLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuZXZlbnRTb3VyY2UuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG1lc3NhZ2VMaXN0ZW5lcik7XG4gICAgICAgIHRoaXMuZXZlbnRTb3VyY2UuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCBlcnJvckxpc3RlbmVyKTtcbiAgICAgICAgLy8gc2V0IGhlYXJ0YmVhdCBpbnRlcnZhbFxuICAgICAgICB0aGlzLl9oZWFydGJlYXRJbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgIC8vIGNsb3NlXG4gICAgICAgICAgICBpZiAodGhpcy5ldmVudFNvdXJjZSAmJiB0aGlzLmV2ZW50U291cmNlLnJlYWR5U3RhdGUgIT09IFNlcnZlckV2ZW50U2VydmljZVN0YXR1cy5DbG9zZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50U291cmNlLmNsb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB1c2VyID0gdGhpcy5nZXRVc2VyU3luYygpO1xuICAgICAgICAgICAgaWYgKHVzZXIgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGhlYWRlcnMgPSB7XG4gICAgICAgICAgICAgICAgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgICAgICAnQXV0aG9yaXphdGlvbic6IGBCZWFyZXIgJHt1c2VyLnRva2VuLmFjY2Vzc190b2tlbn1gXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gYW5kIGNyZWF0ZSBuZXdcbiAgICAgICAgICAgIHRoaXMuZXZlbnRTb3VyY2UgPSBuZXcgRXZlbnRTb3VyY2VQb2x5ZmlsbCh0aGlzLnNvdXJjZSwge1xuICAgICAgICAgICAgICAgIGhlYXJ0YmVhdFRpbWVvdXQ6IHRoaXMuaGVhcnRiZWF0VGltZW91dCxcbiAgICAgICAgICAgICAgICBoZWFkZXJzXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIHNldCBsaXN0ZW5lcnNcbiAgICAgICAgICAgIHRoaXMuZXZlbnRTb3VyY2UuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG1lc3NhZ2VMaXN0ZW5lcik7XG4gICAgICAgICAgICB0aGlzLmV2ZW50U291cmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgZXJyb3JMaXN0ZW5lcik7XG4gICAgICAgIH0sIHRoaXMuaGVhcnRiZWF0VGltZW91dCAtIDUwMDApOyAvLyBzZXQgaGVhcnRiZWF0IGludGVydmFsXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBvbk1lc3NhZ2UoZXY6IGFueSk6IHZvaWQge1xuICAgICAgICAvLyBlbWl0IG1lc3NhZ2VcbiAgICAgICAgaWYgKGV2LnR5cGUgPT09ICdtZXNzYWdlJykge1xuICAgICAgICAgICAgbGV0IGRhdGE6IGFueSA9IG51bGw7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGV2LmRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoZXYuZGF0YSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBldi5kYXRhID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgIGRhdGEgPSBldi5kYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2UubmV4dChkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByb3RlY3RlZCBvbkVycm9yKGV2OiBhbnkpOiB2b2lkIHtcbiAgICAgICAgLy8gZW1pdCBlcnJvclxuICAgICAgICBpZiAoZXYuZXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVycm9yLm5leHQoZXYuZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmVycm9yLm5leHQoZXYpO1xuICAgIH1cblxuICAgIGNsb3NlKCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAodGhpcy5ldmVudFNvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5ldmVudFNvdXJjZS5jbG9zZSgpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY2xlYXIgaGVhcnRiZWF0IGludGVydmFsXG4gICAgICAgIGlmICh0aGlzLl9oZWFydGJlYXRJbnRlcnZhbCkge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLl9oZWFydGJlYXRJbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxufVxuIl19