UNPKG

@universis/common

Version:

Universis - common directives and services

218 lines 28.6 kB
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'; import * as i0 from "@angular/core"; import * as i1 from "../../shared/services/configuration.service"; 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); }); } if (this.activatedUser) { 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; } async openAsync() { 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', }; if (user != null) { Object.assign(headers, { '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.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ServerEventService, deps: [{ token: i1.ConfigurationService }, { token: i0.Injector }, { token: SERVER_EVENT_SUBSCRIBERS }], target: i0.ɵɵFactoryTarget.Injectable }); ServerEventService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ServerEventService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ServerEventService, decorators: [{ type: Injectable }], ctorParameters: function () { return [{ type: i1.ConfigurationService }, { type: i0.Injector }, { type: Array, decorators: [{ type: Inject, args: [SERVER_EVENT_SUBSCRIBERS] }] }]; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLWV2ZW50LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZXZlbnRzL3NlcnZpY2VzL3NlcnZlci1ldmVudC5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxNQUFNLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBRSxRQUFRLEVBQU8sTUFBTSxlQUFlLENBQUM7QUFDakYsT0FBTyxFQUFDLGVBQWUsRUFBRSxPQUFPLEVBQWUsTUFBTSxNQUFNLENBQUM7QUFDNUQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDNUQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDbkYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBQzNFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7O0FBQzNDLE1BQU0sQ0FBTixJQUFZLHdCQUlYO0FBSkQsV0FBWSx3QkFBd0I7SUFDaEMsbUZBQVUsQ0FBQTtJQUNWLHVFQUFJLENBQUE7SUFDSiwyRUFBTSxDQUFBO0FBQ1YsQ0FBQyxFQUpXLHdCQUF3QixLQUF4Qix3QkFBd0IsUUFJbkM7QUFrQ0QsTUFBTSxDQUFDLElBQUksd0JBQXdCLEdBQUcsSUFBSSxjQUFjLENBQXFDLDBCQUEwQixDQUFDLENBQUM7QUFFekgsTUFBTSxDQUFDLElBQUksOEJBQThCLEdBQUcsSUFBSSxjQUFjLENBQXFDLGdDQUFnQyxDQUFDLENBQUM7QUFHckksTUFBTSxPQUFPLGtCQUFrQjtJQVUzQixZQUFvQixhQUFtQyxFQUMzQyxRQUFrQixFQUNnQixjQUFrRDtRQUY1RSxrQkFBYSxHQUFiLGFBQWEsQ0FBc0I7UUFDM0MsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNnQixtQkFBYyxHQUFkLGNBQWMsQ0FBb0M7UUFYekYsWUFBTyxHQUF5QixJQUFJLGVBQWUsQ0FBTSxJ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Y3QsIEluamVjdGFibGUsIEluamVjdGlvblRva2VuLCBJbmplY3RvciwgVHlwZX0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0JlaGF2aW9yU3ViamVjdCwgU3ViamVjdCwgU3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEV2ZW50U291cmNlUG9seWZpbGwgfSBmcm9tICdldmVudC1zb3VyY2UtcG9seWZpbGwnO1xuaW1wb3J0IHsgQ29uZmlndXJhdGlvblNlcnZpY2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvc2VydmljZXMvY29uZmlndXJhdGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7IEFjdGl2YXRlZFVzZXIgfSBmcm9tICcuLi8uLi9hdXRoL3NlcnZpY2VzL2FjdGl2YXRlZC11c2VyLnNlcnZpY2UnO1xuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuZXhwb3J0IGVudW0gU2VydmVyRXZlbnRTZXJ2aWNlU3RhdHVzIHtcbiAgICBDb25uZWN0aW5nLFxuICAgIE9wZW4sXG4gICAgQ2xvc2VkXG59XG5cbmRlY2xhcmUgaW50ZXJmYWNlIFVzZXJTbmFwc2hvdCB7XG4gICAgaWQ/OiBhbnk7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIHRva2VuOiB7XG4gICAgICAgIGFjY2Vzc190b2tlbjogc3RyaW5nO1xuICAgICAgICBzY29wZTogc3RyaW5nO1xuICAgIH07XG59XG5cbmV4cG9ydCBkZWNsYXJlIGludGVyZmFjZSBTZXJ2ZXJFdmVudCB7XG4gICAgaWQ/OiBzdHJpbmc7XG4gICAgYWRkaXRpb25hbFR5cGU/OiBzdHJpbmc7XG4gICAgZW50aXR5U2V0Pzogc3RyaW5nO1xuICAgIGVudGl0eVR5cGU/OiBzdHJpbmc7XG4gICAgZW50aXR5QWN0aW9uPzogc3RyaW5nO1xuICAgIHRhcmdldD86IGFueTtcbiAgICByZXN1bHQ/OiBhbnk7XG4gICAgc3RhdHVzPzogYW55O1xuICAgIGVycm9yPzogYW55O1xuICAgIHJlY2lwaWVudD86IHN0cmluZztcbiAgICBzY29wZT86IHN0cmluZztcbiAgICBkYXRlQ3JlYXRlZD86IERhdGU7XG59XG5cbmV4cG9ydCBkZWNsYXJlIGludGVyZmFjZSBTZXJ2ZXJFdmVudFN1YnNjcmliZXIge1xuICAgIHN1YnNjcmliZTxUPihldmVudDogVCk6IHZvaWQ7XG59XG5cbmRlY2xhcmUgaW50ZXJmYWNlIFNlcnZlckV2ZW50U2VydmljZUNvbmZpZ3VyYXRpb24ge1xuICAgIGhlYXJ0YmVhdFRpbWVvdXQ/OiBudW1iZXI7XG59XG5cbmV4cG9ydCBsZXQgU0VSVkVSX0VWRU5UX1NVQlNDUklCRVJTID0gbmV3IEluamVjdGlvblRva2VuPEFycmF5PFR5cGU8U2VydmVyRXZlbnRTdWJzY3JpYmVyPj4+KCdzZXJ2ZXIuZXZlbnQuc3Vic2NyaWJlcnMnKTtcblxuZXhwb3J0IGxldCBTRVJWRVJfRVZFTlRfQ0hJTERfU1VCU0NSSUJFUlMgPSBuZXcgSW5qZWN0aW9uVG9rZW48QXJyYXk8VHlwZTxTZXJ2ZXJFdmVudFN1YnNjcmliZXI+Pj4oJ3NlcnZlci5ldmVudC5jaGlsZC5zdWJzY3JpYmVycycpO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgU2VydmVyRXZlbnRTZXJ2aWNlIHtcbiAgICBwdWJsaWMgbWVzc2FnZTogQmVoYXZpb3JTdWJqZWN0PGFueT4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGFueT4obnVsbCk7XG4gICAgcHVibGljIGVycm9yOiBCZWhhdmlvclN1YmplY3Q8YW55PiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8YW55PihudWxsKTtcbiAgICBwcml2YXRlIGV2ZW50U291cmNlOiBFdmVudFNvdXJjZVBvbHlmaWxsO1xuICAgIHByaXZhdGUgX2hlYXJ0YmVhdFRpbWVvdXQgPSAxMjAgKiAxMDAwO1xuICAgIHByaXZhdGUgX2hlYXJ0YmVhdEludGVydmFsOiBhbnk7XG4gICAgcHJpdmF0ZSBhY3RpdmF0ZWRVc2VyOiBBY3RpdmF0ZWRVc2VyIHwgdW5kZWZpbmVkO1xuICAgIHB1YmxpYyBzdWJzY3JpYmVyczogTWFwPGFueSwgU3Vic2NyaXB0aW9uPiA9IG5ldyBNYXAoKTtcbiAgICBwcml2YXRlIGRlc3Ryb3kkOiBTdWJqZWN0PHZvaWQ+ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgY29uZmlndXJhdGlvbjogQ29uZmlndXJhdGlvblNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgaW5qZWN0b3I6IEluamVjdG9yLFxuICAgICAgICBASW5qZWN0KFNFUlZFUl9FVkVOVF9TVUJTQ1JJQkVSUykgcHJpdmF0ZSBhZGRTdWJzY3JpYmVyczogQXJyYXk8VHlwZTxTZXJ2ZXJFdmVudFN1YnNjcmliZXI+Pikge1xuICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLmxvYWRlZFxuICAgICAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgICAgICAgICAuc3Vic2NyaWJlKGFwcGxpY2F0aW9uQ29uZmlndXJhdGlvbiA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKGFwcGxpY2F0aW9uQ29uZmlndXJhdGlvbiAhPSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGluamVjdCBhY3RpdmF0ZWQgdXNlciBvbmx5IGFmdGVyIGNvbmZpZyBpcyBsb2FkZWRcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hY3RpdmF0ZWRVc2VyID0gdGhpcy5pbmplY3Rvci5nZXQoQWN0aXZhdGVkVXNlcik7XG4gICAgICAgICAgICAgICAgICAgIC8vIGxvYWRcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2FkKCk7XG4gICAgICAgICAgICAgICAgICAgIC8vIGFuZCBkZXN0cm95IHN1YnNjcmlwdGlvblxuICAgICAgICAgICAgICAgICAgICB0aGlzLmNsb3NlU3Vic2NyaXB0aW9uKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgIGNsb3NlU3Vic2NyaXB0aW9uKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICAgICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIGxvYWQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmNvbmZpZ3VyYXRpb24uY29uZmlnXG4gICAgICAgICAgICAmJiB0aGlzLmNvbmZpZ3VyYXRpb24uY29uZmlnLnNldHRpbmdzXG4gICAgICAgICAgICAmJiB0aGlzLmNvbmZpZ3VyYXRpb24uY29uZmlnLnNldHRpbmdzLnNlcnZlckV2ZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2VydmVyRXZlbnQ6IFNlcnZlckV2ZW50U2VydmljZUNvbmZpZ3VyYXRpb24gPSB0aGlzLmNvbmZpZ3VyYXRpb24uY29uZmlnLnNldHRpbmdzLnNlcnZlckV2ZW50O1xuICAgICAgICAgICAgICAgIGlmIChzZXJ2ZXJFdmVudC5oZWFydGJlYXRUaW1lb3V0KSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2hlYXJ0YmVhdFRpbWVvdXQgPSBzZXJ2ZXJFdmVudC5oZWFydGJlYXRUaW1lb3V0O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLmFkZFN1YnNjcmliZXJzKSkge1xuICAgICAgICAgICAgdGhpcy5hZGRTdWJzY3JpYmVycy5mb3JFYWNoKChhZGRTdWJzY3JpYmVyKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5zdWJzY3JpYmUoYWRkU3Vic2NyaWJlcik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hY3RpdmF0ZWRVc2VyKSB7XG4gICAgICAgICAgdGhpcy5hY3RpdmF0ZWRVc2VyLnVzZXIuc3Vic2NyaWJlKCh1c2VyKSA9PiB7XG4gICAgICAgICAgICBpZiAodXNlciA9PSBudWxsKSB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLnN0YXR1cyA9PT0gU2VydmVyRXZlbnRTZXJ2aWNlU3RhdHVzLk9wZW4pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh1c2VyKSB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLnN0YXR1cyA9PT0gU2VydmVyRXZlbnRTZXJ2aWNlU3RhdHVzLk9wZW4pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhpcy5vcGVuKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBZGRzIGEgc2VydmVyIGV2ZW50IHN1YnNjcmliZXJcbiAgICAgKiBAcGFyYW0gdG9rZW5cbiAgICAgKi9cbiAgICBzdWJzY3JpYmUodG9rZW46IFR5cGU8U2VydmVyRXZlbnRTdWJzY3JpYmVyPik6IHZvaWQge1xuICAgICAgICBjb25zdCBzdWJzY3JpYmVyOiBTZXJ2ZXJFdmVudFN1YnNjcmliZXIgPSB0aGlzLmluamVjdG9yLmdldDxTZXJ2ZXJFdmVudFN1YnNjcmliZXI+KHRva2VuKTtcbiAgICAgICAgaWYgKHN1YnNjcmliZXIgPT0gbnVsbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdTZXJ2ZXIgZXZlbnQgc3Vic2NyaWJlciBjYW5ub3QgYmUgaW5zdGFudGlhdGVkLicpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2Ygc3Vic2NyaWJlci5zdWJzY3JpYmUgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRXhwZWN0ZWQgYW4gaW5zdGFuY2Ugd2hpY2ggaW1wbGVtZW50cyBTZXJ2ZXJFdmVudFN1YnNjcmliZXIuJyk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3Qgb2JzZXJ2ZXIgPSBzdWJzY3JpYmVyLnN1YnNjcmliZS5iaW5kKHN1YnNjcmliZXIpO1xuICAgICAgICB0aGlzLnN1YnNjcmliZXJzLnNldCh0b2tlbiwgdGhpcy5tZXNzYWdlLnN1YnNjcmliZShvYnNlcnZlcikpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJlbW92ZXMgYSBzZXJ2ZXIgZXZlbnQgc3Vic2NyaWJlclxuICAgICAqIEBwYXJhbSB0b2tlblxuICAgICAqL1xuICAgIHVuc3Vic2NyaWJlKHRva2VuOiBUeXBlPFNlcnZlckV2ZW50U3Vic2NyaWJlcj4pOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gdGhpcy5zdWJzY3JpYmVycy5nZXQodG9rZW4pO1xuICAgICAgICAvLyBpZiBzdWJzY3JpcHRpb24gaXMgbm90IG51bGxcbiAgICAgICAgaWYgKHN1YnNjcmlwdGlvbiAhPSBudWxsKSB7XG4gICAgICAgICAgICAvLyB1bnN1YnNjcmliZVxuICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmVtb3ZlIGl0ZW1cbiAgICAgICAgdGhpcy5zdWJzY3JpYmVycy5kZWxldGUodG9rZW4pO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgc291cmNlKCk6IHN0cmluZyB7XG4gICAgICAgIGlmICh0aGlzLmNvbmZpZ3VyYXRpb24uc2V0dGluZ3MgJiZcbiAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5zZXR0aW5ncy5yZW1vdGUgJiZcbiAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvbi5zZXR0aW5ncy5yZW1vdGUuc2VydmVyKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFVSTCgndXNlcnMvbWUvZXZlbnRzL3N1YnNjcmliZScsIHRoaXMuY29uZmlndXJhdGlvbi5zZXR0aW5ncy5yZW1vdGUuc2VydmVyKS50b1N0cmluZygpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAnL3VzZXJzL21lL2V2ZW50cy9zdWJzY3JpYmUnO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgaGVhcnRiZWF0VGltZW91dCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5faGVhcnRiZWF0VGltZW91dDtcbiAgICB9XG5cbiAgICBnZXQgc3RhdHVzKCk6IFNlcnZlckV2ZW50U2VydmljZVN0YXR1cyB7XG4gICAgICAgIGlmICh0aGlzLmV2ZW50U291cmNlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudFNvdXJjZS5yZWFkeVN0YXRlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBTZXJ2ZXJFdmVudFNlcnZpY2VTdGF0dXMuQ2xvc2VkO1xuICAgIH1cblxuICAgIGFzeW5jIG9wZW5Bc3luYygpOiBQcm9taXNlPFNlcnZlckV2ZW50U2VydmljZT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5vcGVuKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRVc2VyU3luYygpOiBVc2VyU25hcHNob3QgfCB1bmRlZmluZWQge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oJ2N1cnJlbnRVc2VyJyk7XG4gICAgICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UodmFsdWUpIGFzIFVzZXJTbmFwc2hvdDtcbiAgICB9XG5cbiAgICBvcGVuKCk6IHRoaXMge1xuICAgICAgICBpZiAodGhpcy5zdGF0dXMgPT09IFNlcnZlckV2ZW50U2VydmljZVN0YXR1cy5PcGVuKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB1c2VyID0gdGhpcy5nZXRVc2VyU3luYygpO1xuICAgICAgICBjb25zdCBoZWFkZXJzID0ge1xuICAgICAgICAgICAgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHVzZXIgIT0gbnVsbCkge1xuICAgICAgICAgIE9iamVjdC5hc3NpZ24oaGVhZGVycywge1xuICAgICAgICAgICAgJ0F1dGhvcml6YXRpb24nOiBgQmVhcmVyICR7dXNlci50b2tlbi5hY2Nlc3NfdG9rZW59YFxuICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ldmVudFNvdXJjZSA9IG5ldyBFdmVudFNvdXJjZVBvbHlmaWxsKHRoaXMuc291cmNlLCB7XG4gICAgICAgICAgICBoZWFydGJlYXRUaW1lb3V0OiB0aGlzLmhlYXJ0YmVhdFRpbWVvdXQsXG4gICAgICAgICAgICBoZWFkZXJzXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBtZXNzYWdlTGlzdGVuZXIgPSB0aGlzLm9uTWVzc2FnZS5iaW5kKHRoaXMpO1xuICAgICAgICBjb25zdCBlcnJvckxpc3RlbmVyID0gdGhpcy5vbkVycm9yLmJpbmQodGhpcyk7XG4gICAgICAgIHRoaXMuZXZlbnRTb3VyY2UuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG1lc3NhZ2VMaXN0ZW5lcik7XG4gICAgICAgIHRoaXMuZXZlbnRTb3VyY2UuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCBlcnJvckxpc3RlbmVyKTtcbiAgICAgICAgLy8gc2V0IGhlYXJ0YmVhdCBpbnRlcnZhbFxuICAgICAgICB0aGlzLl9oZWFydGJlYXRJbnRlcnZhbCA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgICAgICAgIC8vIGNsb3NlXG4gICAgICAgICAgICBpZiAodGhpcy5ldmVudFNvdXJjZSAmJiB0aGlzLmV2ZW50U291cmNlLnJlYWR5U3RhdGUgIT09IFNlcnZlckV2ZW50U2VydmljZVN0YXR1cy5DbG9zZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmV2ZW50U291cmNlLmNsb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCB1c2VyID0gdGhpcy5nZXRVc2VyU3luYygpO1xuICAgICAgICAgICAgaWYgKHVzZXIgPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGhlYWRlcnMgPSB7XG4gICAgICAgICAgICAgICAgJ0FjY2VwdCc6ICdhcHBsaWNhdGlvbi9qc29uJyxcbiAgICAgICAgICAgICAgICAnQXV0aG9yaXphdGlvbic6IGBCZWFyZXIgJHt1c2VyLnRva2VuLmFjY2Vzc190b2tlbn1gXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgLy8gYW5kIGNyZWF0ZSBuZXdcbiAgICAgICAgICAgIHRoaXMuZXZlbnRTb3VyY2UgPSBuZXcgRXZlbnRTb3VyY2VQb2x5ZmlsbCh0aGlzLnNvdXJjZSwge1xuICAgICAgICAgICAgICAgIGhlYXJ0YmVhdFRpbWVvdXQ6IHRoaXMuaGVhcnRiZWF0VGltZW91dCxcbiAgICAgICAgICAgICAgICBoZWFkZXJzXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIC8vIHNldCBsaXN0ZW5lcnNcbiAgICAgICAgICAgIHRoaXMuZXZlbnRTb3VyY2UuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG1lc3NhZ2VMaXN0ZW5lcik7XG4gICAgICAgICAgICB0aGlzLmV2ZW50U291cmNlLmFkZEV2ZW50TGlzdGVuZXIoJ2Vycm9yJywgZXJyb3JMaXN0ZW5lcik7XG4gICAgICAgIH0sIHRoaXMuaGVhcnRiZWF0VGltZW91dCAtIDUwMDApOyAvLyBzZXQgaGVhcnRiZWF0IGludGVydmFsXG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBvbk1lc3NhZ2UoZXY6IGFueSk6IHZvaWQge1xuICAgICAgICAvLyBlbWl0IG1lc3NhZ2VcbiAgICAgICAgaWYgKGV2LnR5cGUgPT09ICdtZXNzYWdlJykge1xuICAgICAgICAgICAgbGV0IGRhdGE6IGFueSA9IG51bGw7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGV2LmRhdGEgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9IEpTT04ucGFyc2UoZXYuZGF0YSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBldi5kYXRhID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgIGRhdGEgPSBldi5kYXRhO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2UubmV4dChkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByb3RlY3RlZCBvbkVycm9yKGV2OiBhbnkpOiB2b2lkIHtcbiAgICAgICAgLy8gZW1pdCBlcnJvclxuICAgICAgICBpZiAoZXYuZXJyb3IpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVycm9yLm5leHQoZXYuZXJyb3IpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLmVycm9yLm5leHQoZXYpO1xuICAgIH1cblxuICAgIGNsb3NlKCk6IGJvb2xlYW4ge1xuICAgICAgICBpZiAodGhpcy5ldmVudFNvdXJjZSkge1xuICAgICAgICAgICAgdGhpcy5ldmVudFNvdXJjZS5jbG9zZSgpO1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gY2xlYXIgaGVhcnRiZWF0IGludGVydmFsXG4gICAgICAgIGlmICh0aGlzLl9oZWFydGJlYXRJbnRlcnZhbCkge1xuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLl9oZWFydGJlYXRJbnRlcnZhbCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxufVxuIl19