ehandler
Version:
Exception handler for Angular Applications
448 lines (438 loc) • 38.2 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common/http'), require('rxjs/operators'), require('toastr'), require('@angular/platform-browser/animations')) :
typeof define === 'function' && define.amd ? define('ehandler', ['exports', '@angular/core', '@angular/common/http', 'rxjs/operators', 'toastr', '@angular/platform-browser/animations'], factory) :
(factory((global.ehandler = {}),global.ng.core,global.ng.common.http,global.rxjs.operators,null,global.ng.platformBrowser.animations));
}(this, (function (exports,i0,http,operators,toastr,animations) { 'use strict';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var HookService = (function () {
function HookService(http$$1, config) {
this.http = http$$1;
this.config = config;
}
/**
* Send Message
*/
/**
* Send Message
* @param {?} payload
* @return {?}
*/
HookService.prototype.sendMessage = /**
* Send Message
* @param {?} payload
* @return {?}
*/
function (payload) {
this.http.post(this.config.hook, payload, { observe: 'response', responseType: 'text' }).subscribe(function (response) {
console.info('Message sent');
});
};
/**
* Send Exception to hook
*/
/**
* Send Exception to hook
* @param {?} error
* @param {?=} couse
* @return {?}
*/
HookService.prototype.exceptionNotify = /**
* Send Exception to hook
* @param {?} error
* @param {?=} couse
* @return {?}
*/
function (error, couse) {
var _this = this;
if (couse === void 0) {
couse = '';
}
/** @type {?} */
var status = error.status ? error.status : 'Application Error';
/** *
* Error Payload
@type {?} */
var payload = {
text: '--------------------------[ ' + status + ' ]--------------------------',
attachments: [
{
author_name: 'Cause: ' + couse + '\nURL: ' + window.location.href,
title: 'Message: ' + error.message,
text: 'Date: ' + new Date() + '\nUserAgent: ' + navigator.userAgent +
'\n---------------------------------------------------------'
}
]
};
if (!this.bugged) {
/** @type {?} */
var headers = new http.HttpHeaders({
'Content-Type': 'text/plain'
});
this.http.post(this.config.hook, JSON.stringify(payload), { observe: 'response', responseType: 'text', headers: headers })
.pipe(operators.catchError(function (e) {
_this.bugged = true;
console.log('Hook stopped working');
throw e;
}))
.subscribe(function (response) {
console.log('Exception Sent');
});
}
};
HookService.decorators = [
{ type: i0.Injectable },
];
/** @nocollapse */
HookService.ctorParameters = function () {
return [
{ type: http.HttpClient },
{ type: undefined, decorators: [{ type: i0.Inject, args: ['configurations',] }] }
];
};
return HookService;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var EHandlerService = (function () {
function EHandlerService(injector, config, hook) {
this.injector = injector;
this.config = config;
this.hook = hook;
}
/**
* Global Error Handler
*/
/**
* Global Error Handler
* @param {?} error
* @return {?}
*/
EHandlerService.prototype.handleError = /**
* Global Error Handler
* @param {?} error
* @return {?}
*/
function (error) {
/** *
* Error Message for view
@type {?} */
var message;
/** *
* Error TimeStamp
@type {?} */
var date = new Date();
/**
* Handle errors occured while making server call
*/
if (error instanceof http.HttpErrorResponse) {
message = this.config.message.statusException;
/**
* If UnAuthorized
* Else If Server Error
*/
switch (error.status) {
case 400:
case 401:
this.logout();
break;
case 500:
message = this.config.message.serverException;
}
// Backend returns unsuccessful response codes such as 404, 500 etc.
this.statusMessage(error, date);
}
else {
// A client-side or network error occurred.
this.commonMessage(error, date);
message = this.config.message.appException;
}
this.errorMSG(message);
};
/**
* Logout of system
*/
/**
* Logout of system
* @param {?=} message
* @return {?}
*/
EHandlerService.prototype.logout = /**
* Logout of system
* @param {?=} message
* @return {?}
*/
function (message) {
var _this = this;
toastr.error(this.config.message.unAuthenticated);
if (message) {
toastr.error(message);
}
setTimeout(function () {
window.location.replace(_this.config.logout);
}, 5000);
};
/**
* Show Error Message
*/
/**
* Show Error Message
* @param {?} message
* @param {?=} code
* @return {?}
*/
EHandlerService.prototype.errorMSG = /**
* Show Error Message
* @param {?} message
* @param {?=} code
* @return {?}
*/
function (message, code) {
if (code === void 0) {
code = null;
}
toastr.error(message, code);
};
/**
* Log Error Message
*/
/**
* Log Error Message
* @param {?} error
* @param {?=} date
* @return {?}
*/
EHandlerService.prototype.statusMessage = /**
* Log Error Message
* @param {?} error
* @param {?=} date
* @return {?}
*/
function (error, date) {
if (date === void 0) {
date = new Date();
}
console.error('--------------------------------------------\n', 'Backend returned status code: ' + error.status + '\n', 'Response body ehandler:' + error.message + '\n', date + '\n', '--------------------------------------------');
this.hook.exceptionNotify(error.message, '----HTTP Error----');
};
/**
* Log Common Error
*/
/**
* Log Common Error
* @param {?} error
* @param {?=} date
* @return {?}
*/
EHandlerService.prototype.commonMessage = /**
* Log Common Error
* @param {?} error
* @param {?=} date
* @return {?}
*/
function (error, date) {
if (date === void 0) {
date = new Date();
}
console.error('--------------------------------------------\n', 'An error occurred ehandler:' + error.message + '\n', date + '\n', '--------------------------------------------');
this.hook.exceptionNotify(error.message, '----Common Error----');
};
EHandlerService.decorators = [
{ type: i0.Injectable, args: [{
providedIn: 'root'
},] },
];
/** @nocollapse */
EHandlerService.ctorParameters = function () {
return [
{ type: i0.Injector },
{ type: undefined, decorators: [{ type: i0.Inject, args: ['configurations',] }] },
{ type: HookService }
];
};
/** @nocollapse */ EHandlerService.ngInjectableDef = i0.defineInjectable({ factory: function EHandlerService_Factory() { return new EHandlerService(i0.inject(i0.INJECTOR), i0.inject("configurations"), i0.inject(HookService)); }, token: EHandlerService, providedIn: "root" });
return EHandlerService;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
var EIntercepterService = (function () {
function EIntercepterService(config, eh) {
this.config = config;
this.eh = eh;
}
/**
* @param {?} req
* @param {?} next
* @return {?}
*/
EIntercepterService.prototype.intercept = /**
* @param {?} req
* @param {?} next
* @return {?}
*/
function (req, next) {
var _this = this;
return next.handle(req).pipe(operators.map(function (event) {
if (event instanceof http.HttpResponse) {
/** @type {?} */
var requestData = event.body;
if (requestData) {
if (requestData.exception && requestData.exception.code) {
try {
if (_this.config && _this.config.logoutCodes && _this.config.logoutCodes.indexOf(requestData.exception.code) !== -1) {
_this.eh.logout();
}
else {
/** @type {?} */
var error = {
code: requestData.exception.code,
message: requestData.exception.message
};
_this.eh.errorMSG(error.message, error.code);
_this.eh.statusMessage(error);
}
}
catch (e) {
console.log('There was an error while trying to send message');
}
}
else if (requestData.error && requestData.error.code) {
try {
if (_this.config && _this.config.logoutCodes && _this.config.logoutCodes.indexOf(requestData.error.code) !== -1) {
_this.eh.logout();
}
else {
/** @type {?} */
var error = {
code: requestData.error.code,
message: requestData.error.message
};
_this.eh.errorMSG(error.message, error.code);
_this.eh.statusMessage(error);
}
}
catch (e) {
console.log('There was an error while trying to send message');
}
}
}
}
return event;
}), operators.catchError(function (error) {
_this.eh.handleError(error);
throw error;
}), operators.finalize(function () { }));
};
EIntercepterService.decorators = [
{ type: i0.Injectable },
];
/** @nocollapse */
EIntercepterService.ctorParameters = function () {
return [
{ type: undefined, decorators: [{ type: i0.Inject, args: ['configurations',] }] },
{ type: EHandlerService }
];
};
return EIntercepterService;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/** @type {?} */
var InitialConfig = {
message: {
unAuthenticated: 'Xahiş olunur sistemə daxil olun!',
statusException: 'Status xətası',
serverException: 'Server xətası',
appException: 'Sistem xətası'
},
logout: '/logout',
logoutCodes: [
401,
1005,
1006,
1014,
1015,
1016,
1017,
1401,
],
hook: 'https://hooks.slack.com/services/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',
};
var EHandlerModule = (function () {
function EHandlerModule() {
}
/**
* @param {?=} configurations
* @return {?}
*/
EHandlerModule.forRoot = /**
* @param {?=} configurations
* @return {?}
*/
function (configurations) {
if (configurations === void 0) {
configurations = InitialConfig;
}
return {
ngModule: EHandlerModule,
providers: [
{ provide: 'configurations', useValue: configurations },
],
};
};
/**
* @return {?}
*/
EHandlerModule.forChild = /**
* @return {?}
*/
function () {
return {
ngModule: EHandlerModule,
};
};
EHandlerModule.decorators = [
{ type: i0.NgModule, args: [{
imports: [
http.HttpClientModule,
animations.BrowserAnimationsModule
],
providers: [
{ provide: i0.ErrorHandler, useClass: EHandlerService },
{
provide: http.HTTP_INTERCEPTORS,
useClass: EIntercepterService,
multi: true
},
HookService
],
declarations: [],
exports: []
},] },
];
return EHandlerModule;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
exports.EHandlerService = EHandlerService;
exports.EIntercepterService = EIntercepterService;
exports.InitialConfig = InitialConfig;
exports.EHandlerModule = EHandlerModule;
exports.ɵb = HookService;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWhhbmRsZXIudW1kLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9laGFuZGxlci9saWIvaG9vay5zZXJ2aWNlLnRzIiwibmc6Ly9laGFuZGxlci9saWIvZWhhbmRsZXIuc2VydmljZS50cyIsIm5nOi8vZWhhbmRsZXIvbGliL2VpbnRlcmNlcHRlci5zZXJ2aWNlLnRzIiwibmc6Ly9laGFuZGxlci9saWIvZWhhbmRsZXIubW9kdWxlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7SW5qZWN0LCBJbmplY3RhYmxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtIdHRwQ2xpZW50LCBIdHRwSGVhZGVyc30gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQge0NvbmZpZ30gZnJvbSAnLi9jb25zdC9jb25maWcnO1xyXG5pbXBvcnQge2NhdGNoRXJyb3IsIG1hcH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5cclxuQEluamVjdGFibGUoKVxyXG5cclxuZXhwb3J0IGNsYXNzIEhvb2tTZXJ2aWNlIHtcclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsIEBJbmplY3QoJ2NvbmZpZ3VyYXRpb25zJykgcHJpdmF0ZSBjb25maWc6IENvbmZpZykge31cclxuICBwcml2YXRlIGJ1Z2dlZDogYm9vbGVhbjtcclxuICAvKipcclxuICAgKiBTZW5kIE1lc3NhZ2VcclxuICAgKi9cclxuICBzZW5kTWVzc2FnZShwYXlsb2FkOiBhbnkpIHtcclxuICAgIHRoaXMuaHR0cC5wb3N0KHRoaXMuY29uZmlnLmhvb2ssIHBheWxvYWQsIHtvYnNlcnZlOiAncmVzcG9uc2UnLCByZXNwb25zZVR5cGU6ICd0ZXh0J30pLnN1YnNjcmliZSggcmVzcG9uc2UgPT4ge1xyXG4gICAgICBjb25zb2xlLmluZm8oJ01lc3NhZ2Ugc2VudCcpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiAgU2VuZCBFeGNlcHRpb24gdG8gaG9va1xyXG4gICAqL1xyXG4gIGV4Y2VwdGlvbk5vdGlmeShlcnJvciwgY291c2UgPSAnJykge1xyXG4gICAgY29uc3Qgc3RhdHVzID0gZXJyb3Iuc3RhdHVzID8gZXJyb3Iuc3RhdHVzIDogJ0FwcGxpY2F0aW9uIEVycm9yJztcclxuICAgIC8qKlxyXG4gICAgICogRXJyb3IgUGF5bG9hZFxyXG4gICAgICovXHJcbiAgICBjb25zdCBwYXlsb2FkID0ge1xyXG4gICAgICB0ZXh0OiAnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1bICcgKyBzdGF0dXMgKyAnIF0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLScsXHJcbiAgICAgIGF0dGFjaG1lbnRzOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgYXV0aG9yX25hbWU6ICdDYXVzZTogJyArIGNvdXNlICsgJ1xcblVSTDogJyArIHdpbmRvdy5sb2NhdGlvbi5ocmVmLFxyXG4gICAgICAgICAgdGl0bGU6ICdNZXNzYWdlOiAnICsgZXJyb3IubWVzc2FnZSxcclxuICAgICAgICAgIHRleHQ6ICdEYXRlOiAnICsgbmV3IERhdGUoKSArICdcXG5Vc2VyQWdlbnQ6ICcgKyBuYXZpZ2F0b3IudXNlckFnZW50ICtcclxuICAgICAgICAgICdcXG4tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9O1xyXG4gICAgaWYgKCF0aGlzLmJ1Z2dlZCkge1xyXG4gICAgICBjb25zdCBoZWFkZXJzID0gbmV3IEh0dHBIZWFkZXJzKHtcclxuICAgICAgICAnQ29udGVudC1UeXBlJzogJ3RleHQvcGxhaW4nXHJcbiAgICAgIH0pXHJcbiAgICAgIHRoaXMuaHR0cC5wb3N0KHRoaXMuY29uZmlnLmhvb2ssIEpTT04uc3RyaW5naWZ5KHBheWxvYWQpLCB7b2JzZXJ2ZTogJ3Jlc3BvbnNlJywgcmVzcG9uc2VUeXBlOiAndGV4dCcsIGhlYWRlcnN9KVxyXG4gICAgICAgIC5waXBlKFxyXG4gICAgICAgICAgY2F0Y2hFcnJvcihlID0+IHtcclxuICAgICAgICAgICAgdGhpcy5idWdnZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZygnSG9vayBzdG9wcGVkIHdvcmtpbmcnKTtcclxuICAgICAgICAgICAgdGhyb3cgZTtcclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgKVxyXG4gICAgICAgIC5zdWJzY3JpYmUoIHJlc3BvbnNlID0+IHtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKCdFeGNlcHRpb24gU2VudCcpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICB9XHJcbn1cclxuIiwiaW1wb3J0IHtFcnJvckhhbmRsZXIsIEluamVjdCwgSW5qZWN0YWJsZSwgSW5qZWN0b3J9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge0h0dHBFcnJvclJlc3BvbnNlfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XHJcbmltcG9ydCB7Q29uZmlnfSBmcm9tICcuL2NvbnN0L2NvbmZpZyc7XHJcbmltcG9ydCB7SG9va1NlcnZpY2V9IGZyb20gJy4vaG9vay5zZXJ2aWNlJztcclxuaW1wb3J0ICogYXMgdG9hc3RyIGZyb20gJ3RvYXN0cic7XHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCdcclxufSlcclxuZXhwb3J0IGNsYXNzIEVIYW5kbGVyU2VydmljZSBpbXBsZW1lbnRzIEVycm9ySGFuZGxlciB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvcixcclxuICAgIEBJbmplY3QoJ2NvbmZpZ3VyYXRpb25zJykgcHJpdmF0ZSBjb25maWc6IENvbmZpZyxcclxuICAgIHByaXZhdGUgaG9vazogSG9va1NlcnZpY2UsXHJcbiAgKSB7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIEdsb2JhbCBFcnJvciBIYW5kbGVyXHJcbiAgICovXHJcbiAgaGFuZGxlRXJyb3IoZXJyb3I6IGFueSkge1xyXG4gICAgLyoqXHJcbiAgICAgKiBFcnJvciBNZXNzYWdlIGZvciB2aWV3XHJcbiAgICAgKi9cclxuICAgIGxldCBtZXNzYWdlOiBzdHJpbmc7XHJcbiAgICAvKipcclxuICAgICAqIEVycm9yIFRpbWVTdGFtcFxyXG4gICAgICovXHJcbiAgICBjb25zdCBkYXRlOiBEYXRlID0gbmV3IERhdGUoKTtcclxuICAgIC8qKlxyXG4gICAgICogSGFuZGxlIGVycm9ycyBvY2N1cmVkIHdoaWxlIG1ha2luZyBzZXJ2ZXIgY2FsbFxyXG4gICAgICovXHJcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBIdHRwRXJyb3JSZXNwb25zZSkge1xyXG4gICAgICBtZXNzYWdlID0gdGhpcy5jb25maWcubWVzc2FnZS5zdGF0dXNFeGNlcHRpb247XHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBJZiBVbkF1dGhvcml6ZWRcclxuICAgICAgICogRWxzZSBJZiBTZXJ2ZXIgRXJyb3JcclxuICAgICAgICovXHJcbiAgICAgIHN3aXRjaCAoZXJyb3Iuc3RhdHVzKSB7XHJcbiAgICAgICAgY2FzZSA0MDA6XHJcbiAgICAgICAgY2FzZSA0MDE6XHJcbiAgICAgICAgICB0aGlzLmxvZ291dCgpO1xyXG4gICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSA1MDA6XHJcbiAgICAgICAgICBtZXNzYWdlID0gdGhpcy5jb25maWcubWVzc2FnZS5zZXJ2ZXJFeGNlcHRpb247XHJcbiAgICAgIH1cclxuICAgICAgLy8gQmFja2VuZCByZXR1cm5zIHVuc3VjY2Vzc2Z1bCByZXNwb25zZSBjb2RlcyBzdWNoIGFzIDQwNCwgNTAwIGV0Yy5cclxuICAgICAgdGhpcy5zdGF0dXNNZXNzYWdlKGVycm9yLCBkYXRlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIEEgY2xpZW50LXNpZGUgb3IgbmV0d29yayBlcnJvciBvY2N1cnJlZC5cclxuICAgICAgdGhpcy5jb21tb25NZXNzYWdlKGVycm9yLCBkYXRlKTtcclxuICAgICAgbWVzc2FnZSA9IHRoaXMuY29uZmlnLm1lc3NhZ2UuYXBwRXhjZXB0aW9uO1xyXG4gICAgfVxyXG4gICAgdGhpcy5lcnJvck1TRyhtZXNzYWdlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExvZ291dCBvZiBzeXN0ZW1cclxuICAgKi9cclxuICBsb2dvdXQobWVzc2FnZT86IHN0cmluZykge1xyXG4gICAgdG9hc3RyLmVycm9yKHRoaXMuY29uZmlnLm1lc3NhZ2UudW5BdXRoZW50aWNhdGVkKTtcclxuICAgIGlmIChtZXNzYWdlKSB7XHJcbiAgICAgIHRvYXN0ci5lcnJvcihtZXNzYWdlKTtcclxuICAgIH1cclxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICB3aW5kb3cubG9jYXRpb24ucmVwbGFjZSh0aGlzLmNvbmZpZy5sb2dvdXQpO1xyXG4gICAgfSwgNTAwMCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTaG93IEVycm9yIE1lc3NhZ2VcclxuICAgKi9cclxuICBlcnJvck1TRyhtZXNzYWdlLCBjb2RlID0gbnVsbCkge1xyXG4gICAgdG9hc3RyLmVycm9yKG1lc3NhZ2UsIGNvZGUpO1xyXG4gIH1cclxuICAvKipcclxuICAgKiBMb2cgRXJyb3IgTWVzc2FnZVxyXG4gICAqL1xyXG4gIHN0YXR1c01lc3NhZ2UoZXJyb3IsIGRhdGUgPSBuZXcgRGF0ZSgpKSB7XHJcbiAgICBjb25zb2xlLmVycm9yKFxyXG4gICAgICAnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cXG4nLFxyXG4gICAgICAnQmFja2VuZCByZXR1cm5lZCBzdGF0dXMgY29kZTogJyArIGVycm9yLnN0YXR1cyArICdcXG4nLFxyXG4gICAgICAnUmVzcG9uc2UgYm9keSBlaGFuZGxlcjonICsgZXJyb3IubWVzc2FnZSArICdcXG4nLFxyXG4gICAgICBkYXRlICsgJ1xcbicsXHJcbiAgICAgICctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSdcclxuICAgICk7XHJcbiAgICAgIHRoaXMuaG9vay5leGNlcHRpb25Ob3RpZnkoZXJyb3IubWVzc2FnZSwgJy0tLS1IVFRQIEVycm9yLS0tLScpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9nIENvbW1vbiBFcnJvclxyXG4gICAqL1xyXG4gIGNvbW1vbk1lc3NhZ2UoZXJyb3IsIGRhdGUgPSBuZXcgRGF0ZSgpKSB7XHJcbiAgICBjb25zb2xlLmVycm9yKFxyXG4gICAgICAnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cXG4nLFxyXG4gICAgICAnQW4gZXJyb3Igb2NjdXJyZWQgZWhhbmRsZXI6JyArIGVycm9yLm1lc3NhZ2UgKyAnXFxuJyxcclxuICAgICAgZGF0ZSArICdcXG4nLFxyXG4gICAgICAnLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0nXHJcbiAgICApO1xyXG4gICAgdGhpcy5ob29rLmV4Y2VwdGlvbk5vdGlmeShlcnJvci5tZXNzYWdlLCAnLS0tLUNvbW1vbiBFcnJvci0tLS0nKTtcclxuICB9XHJcbn1cclxuIiwiaW1wb3J0IHtJbmplY3QsIEluamVjdGFibGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtIdHRwRXZlbnQsIEh0dHBIYW5kbGVyLCBIdHRwSW50ZXJjZXB0b3IsIEh0dHBSZXF1ZXN0LCBIdHRwUmVzcG9uc2V9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7T2JzZXJ2YWJsZX0gZnJvbSAncnhqcyc7XG5pbXBvcnQge2NhdGNoRXJyb3IsIGZpbmFsaXplLCBtYXB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7Q29uZmlnfSBmcm9tICcuL2NvbnN0L2NvbmZpZyc7XG5pbXBvcnQge0VIYW5kbGVyU2VydmljZX0gZnJvbSAnLi9laGFuZGxlci5zZXJ2aWNlJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIEVJbnRlcmNlcHRlclNlcnZpY2UgaW1wbGVtZW50cyBIdHRwSW50ZXJjZXB0b3Ige1xuICBjb25zdHJ1Y3RvcihASW5qZWN0KCdjb25maWd1cmF0aW9ucycpIHByaXZhdGUgY29uZmlnOiBDb25maWcsIHByaXZhdGUgZWg6IEVIYW5kbGVyU2VydmljZSkgeyB9XG4gIGludGVyY2VwdChcbiAgICByZXE6IEh0dHBSZXF1ZXN0PGFueT4sXG4gICAgbmV4dDogSHR0cEhhbmRsZXJcbiAgKTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4ge1xuICAgIHJldHVybiBuZXh0LmhhbmRsZShyZXEpLnBpcGUoXG4gICAgICBtYXAoZXZlbnQgPT4ge1xuICAgICAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBIdHRwUmVzcG9uc2UpIHtcbiAgICAgICAgICBjb25zdCByZXF1ZXN0RGF0YSA9IGV2ZW50LmJvZHk7XG4gICAgICAgICAgaWYgKHJlcXVlc3REYXRhKSB7XG4gICAgICAgICAgICBpZiAocmVxdWVzdERhdGEuZXhjZXB0aW9uICYmIHJlcXVlc3REYXRhLmV4Y2VwdGlvbi5jb2RlKSB7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnICYmIHRoaXMuY29uZmlnLmxvZ291dENvZGVzICYmIHRoaXMuY29uZmlnLmxvZ291dENvZGVzLmluZGV4T2YocmVxdWVzdERhdGEuZXhjZXB0aW9uLmNvZGUpICE9PSAtMSApIHtcbiAgICAgICAgICAgICAgICAgIHRoaXMuZWgubG9nb3V0KCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGVycm9yID0ge1xuICAgICAgICAgICAgICAgICAgICBjb2RlOiByZXF1ZXN0RGF0YS5leGNlcHRpb24uY29kZSxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogcmVxdWVzdERhdGEuZXhjZXB0aW9uLm1lc3NhZ2VcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIHRoaXMuZWguZXJyb3JNU0coZXJyb3IubWVzc2FnZSwgZXJyb3IuY29kZSk7XG4gICAgICAgICAgICAgICAgICB0aGlzLmVoLnN0YXR1c01lc3NhZ2UoZXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdUaGVyZSB3YXMgYW4gZXJyb3Igd2hpbGUgdHJ5aW5nIHRvIHNlbmQgbWVzc2FnZScpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHJlcXVlc3REYXRhLmVycm9yICYmIHJlcXVlc3REYXRhLmVycm9yLmNvZGUpIHtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5jb25maWcgJiYgdGhpcy5jb25maWcubG9nb3V0Q29kZXMgJiYgdGhpcy5jb25maWcubG9nb3V0Q29kZXMuaW5kZXhPZihyZXF1ZXN0RGF0YS5lcnJvci5jb2RlKSAhPT0gLTEgKSB7XG4gICAgICAgICAgICAgICAgICB0aGlzLmVoLmxvZ291dCgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IHtcbiAgICAgICAgICAgICAgICAgICAgY29kZTogcmVxdWVzdERhdGEuZXJyb3IuY29kZSxcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogcmVxdWVzdERhdGEuZXJyb3IubWVzc2FnZVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgdGhpcy5laC5lcnJvck1TRyhlcnJvci5tZXNzYWdlLCBlcnJvci5jb2RlKTtcbiAgICAgICAgICAgICAgICAgIHRoaXMuZWguc3RhdHVzTWVzc2FnZShlcnJvcik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coJ1RoZXJlIHdhcyBhbiBlcnJvciB3aGlsZSB0cnlpbmcgdG8gc2VuZCBtZXNzYWdlJyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGV2ZW50O1xuICAgICAgfSksXG4gICAgICBjYXRjaEVycm9yKGVycm9yID0+IHtcbiAgICAgICAgdGhpcy5laC5oYW5kbGVFcnJvcihlcnJvcik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfSksXG4gICAgICBmaW5hbGl6ZSgoKSA9PiB7fSlcbiAgICApO1xuICB9XG59XG4iLCJpbXBvcnQge0Vycm9ySGFuZGxlciwgTW9kdWxlV2l0aFByb3ZpZGVycywgTmdNb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtDb25maWd9IGZyb20gJy4vY29uc3QvY29uZmlnJztcbmltcG9ydCB7RUludGVyY2VwdGVyU2VydmljZX0gZnJvbSAnLi9laW50ZXJjZXB0ZXIuc2VydmljZSc7XG5pbXBvcnQge0VIYW5kbGVyU2VydmljZX0gZnJvbSAnLi9laGFuZGxlci5zZXJ2aWNlJztcbmltcG9ydCB7SFRUUF9JTlRFUkNFUFRPUlMsIEh0dHBDbGllbnRNb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7QnJvd3NlckFuaW1hdGlvbnNNb2R1bGV9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXIvYW5pbWF0aW9ucyc7XG5pbXBvcnQge0hvb2tTZXJ2aWNlfSBmcm9tICcuL2hvb2suc2VydmljZSc7XG5cbmV4cG9ydCBjb25zdCBJbml0aWFsQ29uZmlnOiBDb25maWcgPSB7XG4gIG1lc3NhZ2U6IHtcbiAgICB1bkF1dGhlbnRpY2F0ZWQ6ICdYYWhpw4XCnyBvbHVudXIgc2lzdGVtw4nCmSBkYXhpbCBvbHVuIScsXG4gICAgc3RhdHVzRXhjZXB0aW9uOiAnU3RhdHVzIHjDicKZdGFzw4TCsScsXG4gICAgc2VydmVyRXhjZXB0aW9uOiAnU2VydmVyIHjDicKZdGFzw4TCsScsXG4gICAgYXBwRXhjZXB0aW9uOiAnU2lzdGVtIHjDicKZdGFzw4TCsSdcbiAgfSxcbiAgbG9nb3V0OiAnL2xvZ291dCcsXG4gIGxvZ291dENvZGVzOiBbXG4gICAgNDAxLCAgLy8gQnUgw4PCvG52YW5hIGljYXrDicKZbml6IHlveGR1clxuICAgIDEwMDUsIC8vIFlvdSBhcmUgbm90IGFsbG93ZWQgdG8gcmVxdWVzdCB0aGlzIHJlc291cmNlXG4gICAgMTAwNiwgLy8gVG9rZW4gdGFww4TCsWxtYWTDhMKxXG4gICAgMTAxNCwgLy8gVG9rZW4gdGFww4TCsWxtYWTDhMKxLCB6w4nCmWhtw4nCmXQgb2xtYXNhIHNpc3RlbcOJwpkgeWVuaWTDicKZbiBkYXhpbCBvbHVuXG4gICAgMTAxNSwgLy8gU2l6aW4gc2lzdGVtbMOJwplyZMOJwpluIGlzdGlmw4nCmWTDicKZIGjDg8K8cXVxdW51eiB5b3hkdXJcbiAgICAxMDE2LCAvLyBTaXppbiBidSBzaXN0ZW3DicKZIGlzdGlmw4nCmWTDicKZIGjDg8K8cXVxdW51eiB5b3hkdXJcbiAgICAxMDE3LCAvLyBTZXNzaXlhIGJhw4TCn2xhbm3DhMKxw4XCn2TDhMKxciwgesOJwplobcOJwpl0IG9sbWFzYSBzaXN0ZW3DicKZIHllbmlkw4nCmW4gZGF4aWwgb2x1bi5cbiAgICAxNDAxLCAvLyBTZXNzaXlhIG3Dg8K8ZGTDicKZdGkgYml0bWnDhcKfZGlyLCB6w4nCmWhtw4nCmXQgb2xtYXpzYSBzaXN0ZW3DicKZIHllbmlkw4nCmW4gZGF4aWwgb2x1blxuICAgIC8vIDE0MDIgIC8vIFNpemluIGJ1IHNlcnZpc8OJwpkgaWNhesOJwpluaXogeW94ZHVyXG4gIF0sXG4gIGhvb2s6ICdodHRwczovL2hvb2tzLnNsYWNrLmNvbS9zZXJ2aWNlcy9UQzEwR0g0OFovQkMyQTI5WTJaL3RweFYwaUlIaGoyZlRTNkZPMFBBMUN6YycsXG59XG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtcbiAgICBIdHRwQ2xpZW50TW9kdWxlLFxuICAgIEJyb3dzZXJBbmltYXRpb25zTW9kdWxlXG4gIF0sXG4gIHByb3ZpZGVyczogW1xuICAgIHsgcHJvdmlkZTogRXJyb3JIYW5kbGVyLCB1c2VDbGFzczogRUhhbmRsZXJTZXJ2aWNlIH0sXG4gICAge1xuICAgICAgcHJvdmlkZTogSFRUUF9JTlRFUkNFUFRPUlMsXG4gICAgICB1c2VDbGFzczogRUludGVyY2VwdGVyU2VydmljZSxcbiAgICAgIG11bHRpOiB0cnVlXG4gICAgfSxcbiAgICBIb29rU2VydmljZVxuICBdLFxuICBkZWNsYXJhdGlvbnM6IFtdLFxuICBleHBvcnRzOiBbXVxufSlcbmV4cG9ydCBjbGFzcyBFSGFuZGxlck1vZHVsZSB7XG4gIHN0YXRpYyBmb3JSb290KGNvbmZpZ3VyYXRpb25zID0gSW5pdGlhbENvbmZpZyk6IE1vZHVsZVdpdGhQcm92aWRlcnMge1xuICAgIHJldHVybiB7XG4gICAgICBuZ01vZHVsZTogRUhhbmRsZXJNb2R1bGUsXG4gICAgICBwcm92aWRlcnM6IFtcbiAgICAgICAge3Byb3ZpZGU6ICdjb25maWd1cmF0aW9ucycsIHVzZVZhbHVlOiBjb25maWd1cmF0aW9uc30sXG4gICAgICBdLFxuICAgIH07XG4gIH1cbiAgc3RhdGljIGZvckNoaWxkKCk6IE1vZHVsZVdpdGhQcm92aWRlcnMge1xuXG4gICAgcmV0dXJue1xuICAgICAgbmdNb2R1bGU6IEVIYW5kbGVyTW9kdWxlLFxuICAgIH07XG5cbiAgfVxuXG59XG4iXSwibmFtZXMiOlsiaHR0cCIsIkh0dHBIZWFkZXJzIiwiY2F0Y2hFcnJvciIsIkluamVjdGFibGUiLCJIdHRwQ2xpZW50IiwiSW5qZWN0IiwiSHR0cEVycm9yUmVzcG9uc2UiLCJ0b2FzdHIuZXJyb3IiLCJJbmplY3RvciIsIm1hcCIsIkh0dHBSZXNwb25zZSIsImZpbmFsaXplIiwiTmdNb2R1bGUiLCJIdHRwQ2xpZW50TW9kdWxlIiwiQnJvd3NlckFuaW1hdGlvbnNNb2R1bGUiLCJFcnJvckhhbmRsZXIiLCJIVFRQX0lOVEVSQ0VQVE9SUyJdLCJtYXBwaW5ncyI6Ijs7Ozs7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