@isaiahiroko/ng-interceptors
Version:
Angular interceptors for token authorization, local and remote store synchronization and global notification
221 lines (213 loc) • 18.1 kB
JavaScript
import { Injectable } from '@angular/core';
import { AuthService } from '@isaiahiroko/ng-utils';
import { __read } from 'tslib';
import { finalize, retryWhen, zip, mergeMap, catchError } from 'rxjs/operators';
import { range, timer, throwError } from 'rxjs';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var AuthInterceptor = /** @class */ (function () {
function AuthInterceptor(auth) {
this.auth = auth;
}
/**
* @param {?} req
* @param {?} next
* @return {?}
*/
AuthInterceptor.prototype.intercept = /**
* @param {?} req
* @param {?} next
* @return {?}
*/
function (req, next) {
/** @type {?} */
var authReq = req.clone({
headers: req.headers.set('Authorization', this.auth.token()),
});
// send cloned request with header to the next handler.
return next.handle(authReq);
};
AuthInterceptor.decorators = [
{ type: Injectable },
];
/** @nocollapse */
AuthInterceptor.ctorParameters = function () { return [
{ type: AuthService }
]; };
return AuthInterceptor;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var LoaderServiceContract = /** @class */ (function () {
function LoaderServiceContract() {
}
/**
* @param {?=} type
* @return {?}
*/
LoaderServiceContract.prototype.start = /**
* @param {?=} type
* @return {?}
*/
function (type) { };
/**
* @return {?}
*/
LoaderServiceContract.prototype.stop = /**
* @return {?}
*/
function () { };
/**
* @param {?} message
* @param {?=} title
* @return {?}
*/
LoaderServiceContract.prototype.notify = /**
* @param {?} message
* @param {?=} title
* @return {?}
*/
function (message, title) { };
/**
* @param {?} message
* @param {?=} title
* @return {?}
*/
LoaderServiceContract.prototype.toast = /**
* @param {?} message
* @param {?=} title
* @return {?}
*/
function (message, title) { };
return LoaderServiceContract;
}());
var NotifInterceptor = /** @class */ (function () {
function NotifInterceptor(notif) {
this.notif = notif;
}
/**
* @param {?} req
* @param {?} next
* @return {?}
*/
NotifInterceptor.prototype.intercept = /**
* @param {?} req
* @param {?} next
* @return {?}
*/
function (req, next) {
var _this = this;
this.notif.start();
// extend server response observable with logging
return next.handle(req).pipe(
// things don't always work as planned
// if things go wrong, try again three times
// however, delay trial in an incremental manner (multipl of 1 second)
retryWhen(function (attempts) {
return attempts.pipe(zip(range(1, 4)), mergeMap(function (_a) {
var _b = __read(_a, 2), error = _b[0], i = _b[1];
_this.notif.start('query');
if (i > 2) {
return throwError(error);
}
return timer(i * 1000);
}));
}),
// catchError http errors and turn to observable of undefined
catchError(function (e) {
/** @type {?} */
var title;
/** @type {?} */
var message;
_this.notif.start('buffer');
if (e.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
title = 'Client Error';
message = e.error.message;
}
else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
title = 'Network Info';
message = e.statusText + " (" + e.status + ")";
// message = e.message
}
if (e.status === 401) ;
console.error({ title: title, message: message });
// catche //re throw
// throw {title, message}
// return of({ e: {title, message} })
// return empty()
return throwError({ title: title, message: message });
}), finalize(function () {
_this.notif.stop();
}));
};
NotifInterceptor.decorators = [
{ type: Injectable },
];
/** @nocollapse */
NotifInterceptor.ctorParameters = function () { return [
{ type: LoaderServiceContract }
]; };
return NotifInterceptor;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
var StoreSyncInterceptor = /** @class */ (function () {
function StoreSyncInterceptor() {
}
// constructor(private cache: RequestCache) {}
/**
* @param {?} req
* @param {?} next
* @return {?}
*/
StoreSyncInterceptor.prototype.intercept = /**
* @param {?} req
* @param {?} next
* @return {?}
*/
function (req, next) {
// continue if not cachable.
// if (!isCachable(req)) { return next.handle(req); }
{
return next.handle(req);
}
// cache-or-fetch
// const cachedResponse = this.cache.get(req);
// return cachedResponse ?
// of(cachedResponse) : sendRequest(req, next, this.cache);
};
StoreSyncInterceptor.decorators = [
{ type: Injectable },
];
return StoreSyncInterceptor;
}());
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/** @type {?} */
var INTERCEPTORS = [
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
// { provide: HTTP_INTERCEPTORS, useClass: StoreSyncInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: NotifInterceptor, multi: true }
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
export { INTERCEPTORS, StoreSyncInterceptor, AuthInterceptor, LoaderServiceContract, NotifInterceptor };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaXNhaWFoaXJva28tbmctaW50ZXJjZXB0b3JzLmpzLm1hcCIsInNvdXJjZXMiOlsibmc6Ly9AaXNhaWFoaXJva28vbmctaW50ZXJjZXB0b3JzL2xpYi9hdXRoLmludGVyY2VwdG9yLnRzIiwibmc6Ly9AaXNhaWFoaXJva28vbmctaW50ZXJjZXB0b3JzL2xpYi9ub3RpZi5pbnRlcmNlcHRvci50cyIsIm5nOi8vQGlzYWlhaGlyb2tvL25nLWludGVyY2VwdG9ycy9saWIvc3RvcmUtc3luYy5pbnRlcmNlcHRvci50cyIsIm5nOi8vQGlzYWlhaGlyb2tvL25nLWludGVyY2VwdG9ycy9saWIvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnXHJcbmltcG9ydCB7IEh0dHBJbnRlcmNlcHRvciwgSHR0cFJlcXVlc3QsIEh0dHBIYW5kbGVyLCBIdHRwRXZlbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCdcclxuXHJcbmltcG9ydCB7IEF1dGhTZXJ2aWNlIH0gZnJvbSAnQGlzYWlhaGlyb2tvL25nLXV0aWxzJ1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBBdXRoSW50ZXJjZXB0b3IgaW1wbGVtZW50cyBIdHRwSW50ZXJjZXB0b3Ige1xyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgYXV0aDogQXV0aFNlcnZpY2UpIHt9XHJcblxyXG4gIGludGVyY2VwdChyZXE6IEh0dHBSZXF1ZXN0PGFueT4sIG5leHQ6IEh0dHBIYW5kbGVyKTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4ge1xyXG4gICAgLy8gR2V0IHRoZSBhdXRoIHRva2VuIGZyb20gdGhlIHNlcnZpY2UuXHJcbiAgICAvLyBDbG9uZSB0aGUgcmVxdWVzdCBhbmQgcmVwbGFjZSB0aGUgb3JpZ2luYWwgaGVhZGVycyB3aXRoXHJcbiAgICAvLyBjbG9uZWQgaGVhZGVycywgdXBkYXRlZCB3aXRoIHRoZSBhdXRob3JpemF0aW9uLlxyXG4gICAgY29uc3QgYXV0aFJlcSA9IHJlcS5jbG9uZSh7XHJcbiAgICAgIGhlYWRlcnM6IHJlcS5oZWFkZXJzLnNldCgnQXV0aG9yaXphdGlvbicsIHRoaXMuYXV0aC50b2tlbigpKSxcclxuICAgIH0pXHJcblxyXG4gICAgLy8gc2VuZCBjbG9uZWQgcmVxdWVzdCB3aXRoIGhlYWRlciB0byB0aGUgbmV4dCBoYW5kbGVyLlxyXG4gICAgcmV0dXJuIG5leHQuaGFuZGxlKGF1dGhSZXEpXHJcbiAgfVxyXG59XHJcbiIsImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJ1xyXG5pbXBvcnQgeyBIdHRwUmVxdWVzdCwgSHR0cEhhbmRsZXIsIEh0dHBJbnRlcmNlcHRvciwgSHR0cEV2ZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnXHJcblxyXG5pbXBvcnQgeyBmaW5hbGl6ZSwgcmV0cnlXaGVuLCB6aXAsIG1lcmdlTWFwLCBjYXRjaEVycm9yIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnXHJcbmltcG9ydCB7IHJhbmdlLCAgdGltZXIsICB0aHJvd0Vycm9yLCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcydcclxuXHJcbmV4cG9ydCBjbGFzcyBMb2FkZXJTZXJ2aWNlQ29udHJhY3Qge1xyXG4gIHN0YXJ0ICh0eXBlPzogc3RyaW5nKSB7fVxyXG4gIHN0b3AgKCkge31cclxuICBub3RpZnkgKG1lc3NhZ2U6IHN0cmluZywgdGl0bGU/OiBzdHJpbmcpIHt9XHJcbiAgdG9hc3QgKG1lc3NhZ2U6IHN0cmluZywgdGl0bGU/OiBzdHJpbmcpIHt9XHJcbn1cclxuXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIE5vdGlmSW50ZXJjZXB0b3IgaW1wbGVtZW50cyBIdHRwSW50ZXJjZXB0b3Ige1xyXG4gIGNvbnN0cnVjdG9yIChcclxuICAgIHByaXZhdGUgbm90aWY6IExvYWRlclNlcnZpY2VDb250cmFjdCxcclxuICApIHt9XHJcblxyXG4gIGludGVyY2VwdCAocmVxOiBIdHRwUmVxdWVzdDxhbnk+LCBuZXh0OiBIdHRwSGFuZGxlcik6IE9ic2VydmFibGU8SHR0cEV2ZW50PGFueT4+IHtcclxuICAgIHRoaXMubm90aWYuc3RhcnQoKVxyXG5cclxuICAgIC8vIGV4dGVuZCBzZXJ2ZXIgcmVzcG9uc2Ugb2JzZXJ2YWJsZSB3aXRoIGxvZ2dpbmdcclxuICAgIHJldHVybiBuZXh0LmhhbmRsZShyZXEpLnBpcGUoXHJcbiAgICAgIC8vIHRoaW5ncyBkb24ndCBhbHdheXMgd29yayBhcyBwbGFubmVkXHJcbiAgICAgIC8vIGlmIHRoaW5ncyBnbyB3cm9uZywgdHJ5IGFnYWluIHRocmVlIHRpbWVzXHJcbiAgICAgIC8vIGhvd2V2ZXIsIGRlbGF5IHRyaWFsIGluIGFuIGluY3JlbWVudGFsIG1hbm5lciAobXVsdGlwbCBvZiAxIHNlY29uZClcclxuICAgICAgcmV0cnlXaGVuKChhdHRlbXB0cykgPT4ge1xyXG4gICAgICAgIHJldHVybiBhdHRlbXB0cy5waXBlKFxyXG4gICAgICAgICAgemlwKHJhbmdlKDEsIDQpKSxcclxuICAgICAgICAgIG1lcmdlTWFwKChbZXJyb3IsIGldKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMubm90aWYuc3RhcnQoJ3F1ZXJ5JylcclxuICAgICAgICAgICAgaWYgKGkgPiAyKSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIHRocm93RXJyb3IoZXJyb3IpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHRpbWVyKGkgKiAxMDAwKVxyXG4gICAgICAgICAgfSlcclxuICAgICAgICApXHJcbiAgICAgIH0pLFxyXG5cclxuICAgICAgLy8gY2F0Y2hFcnJvciBodHRwIGVycm9ycyBhbmQgdHVybiB0byBvYnNlcnZhYmxlIG9mIHVuZGVmaW5lZFxyXG4gICAgICBjYXRjaEVycm9yKChlKSA9PiB7XHJcbiAgICAgICAgbGV0IHRpdGxlLCBtZXNzYWdlXHJcblxyXG4gICAgICAgIHRoaXMubm90aWYuc3RhcnQoJ2J1ZmZlcicpXHJcblxyXG4gICAgICAgIGlmIChlLmVycm9yIGluc3RhbmNlb2YgRXJyb3JFdmVudCkge1xyXG4gICAgICAgICAgLy8gQSBjbGllbnQtc2lkZSBvciBuZXR3b3JrIGVycm9yIG9jY3VycmVkLiBIYW5kbGUgaXQgYWNjb3JkaW5nbHkuXHJcbiAgICAgICAgICB0aXRsZSA9ICdDbGllbnQgRXJyb3InXHJcbiAgICAgICAgICBtZXNzYWdlID0gZS5lcnJvci5tZXNzYWdlXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIFRoZSBiYWNrZW5kIHJldHVybmVkIGFuIHVuc3VjY2Vzc2Z1bCByZXNwb25zZSBjb2RlLlxyXG4gICAgICAgICAgLy8gVGhlIHJlc3BvbnNlIGJvZHkgbWF5IGNvbnRhaW4gY2x1ZXMgYXMgdG8gd2hhdCB3ZW50IHdyb25nLFxyXG4gICAgICAgICAgdGl0bGUgPSAnTmV0d29yayBJbmZvJ1xyXG4gICAgICAgICAgbWVzc2FnZSA9IGAke2Uuc3RhdHVzVGV4dH0gKCR7ZS5zdGF0dXN9KWBcclxuICAgICAgICAgIC8vIG1lc3NhZ2UgPSBlLm1lc3NhZ2VcclxuICAgICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgICAgaWYoZS5zdGF0dXMgPT09IDQwMSl7XHJcbiAgICAgICAgICAvLyB0aGlzLm5vdGlmLm5vdGlmeSgnVGhlIHVzZXJuYW1lL3Bhc3N3b3JkIGlzIHdyb25nJywgJ1VuYXV0aG9yaXplZCcpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2V7XHJcbiAgICAgICAgICAvLyB0aGlzLm5vdGlmLnRvYXN0KG1lc3NhZ2UsIHRpdGxlKVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc29sZS5lcnJvcih7IHRpdGxlLCBtZXNzYWdlIH0pO1xyXG4gICAgICAgIFxyXG4gICAgICAgIC8vIGNhdGNoZSAvL3JlIHRocm93XHJcbiAgICAgICAgLy8gdGhyb3cge3RpdGxlLCBtZXNzYWdlfVxyXG4gICAgICAgIC8vIHJldHVybiBvZih7IGU6IHt0aXRsZSwgbWVzc2FnZX0gfSlcclxuICAgICAgICAvLyByZXR1cm4gZW1wdHkoKVxyXG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKHsgdGl0bGUsIG1lc3NhZ2V9KVxyXG4gICAgICB9KSxcclxuICAgICAgZmluYWxpemUoKCkgPT4ge1xyXG4gICAgICAgIHRoaXMubm90aWYuc3RvcCgpXHJcbiAgICAgIH0pLFxyXG4gICAgKVxyXG4gIH1cclxufVxyXG4iLCJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSdcclxuaW1wb3J0IHtcclxuICBIdHRwSW50ZXJjZXB0b3IsXHJcbiAgSHR0cFJlcXVlc3QsXHJcbiAgSHR0cEhhbmRsZXIsXHJcbiAgSHR0cEV2ZW50LFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJ1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBTdG9yZVN5bmNJbnRlcmNlcHRvciBpbXBsZW1lbnRzIEh0dHBJbnRlcmNlcHRvciB7XHJcbiAgLy8gY29uc3RydWN0b3IocHJpdmF0ZSBjYWNoZTogUmVxdWVzdENhY2hlKSB7fVxyXG5cclxuICBpbnRlcmNlcHQocmVxOiBIdHRwUmVxdWVzdDxhbnk+LCBuZXh0OiBIdHRwSGFuZGxlcik6IE9ic2VydmFibGU8SHR0cEV2ZW50PGFueT4+ICB7XHJcbiAgICAvLyBjb250aW51ZSBpZiBub3QgY2FjaGFibGUuXHJcbiAgICAvLyBpZiAoIWlzQ2FjaGFibGUocmVxKSkgeyByZXR1cm4gbmV4dC5oYW5kbGUocmVxKTsgfVxyXG4gICAgaWYgKHRydWUpIHtcclxuICAgICAgcmV0dXJuIG5leHQuaGFuZGxlKHJlcSlcclxuICAgIH1cclxuXHJcbiAgICAvLyBjYWNoZS1vci1mZXRjaFxyXG4gICAgLy8gY29uc3QgY2FjaGVkUmVzcG9uc2UgPSB0aGlzLmNhY2hlLmdldChyZXEpO1xyXG4gICAgLy8gcmV0dXJuIGNhY2hlZFJlc3BvbnNlID9cclxuICAgIC8vICAgb2YoY2FjaGVkUmVzcG9uc2UpIDogc2VuZFJlcXVlc3QocmVxLCBuZXh0LCB0aGlzLmNhY2hlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBzZXJ2ZXIgcmVzcG9uc2Ugb2JzZXJ2YWJsZSBieSBzZW5kaW5nIHJlcXVlc3QgdG8gYG5leHQoKWAuXHJcbiAgICogV2lsbCBhZGQgdGhlIHJlc3BvbnNlIHRvIHRoZSBjYWNoZSBvbiB0aGUgd2F5IG91dC5cclxuICAgKi9cclxuICAvLyAgc2VuZFJlcXVlc3QoXHJcbiAgLy8gICAgIHJlcTogSHR0cFJlcXVlc3Q8YW55PixcclxuICAvLyAgICAgbmV4dDogSHR0cEhhbmRsZXIsXHJcbiAgLy8gICAgIGNhY2hlOiBSZXF1ZXN0Q2FjaGUpOiBPYnNlcnZhYmxlPEh0dHBFdmVudDxhbnk+PiB7XHJcblxyXG4gIC8vICAgICAvLyBObyBoZWFkZXJzIGFsbG93ZWQgaW4gbnBtIHNlYXJjaCByZXF1ZXN0XHJcbiAgLy8gICAgIGNvbnN0IG5vSGVhZGVyUmVxID0gcmVxLmNsb25lKHsgaGVhZGVyczogbmV3IEh0dHBIZWFkZXJzKCkgfSk7XHJcblxyXG4gIC8vICAgICByZXR1cm4gbmV4dC5oYW5kbGUobm9IZWFkZXJSZXEpLnBpcGUoXHJcbiAgLy8gICAgICAgdGFwKGV2ZW50ID0+IHtcclxuICAvLyAgICAgICAgIC8vIFRoZXJlIG1heSBiZSBvdGhlciBldmVudHMgYmVzaWRlcyB0aGUgcmVzcG9uc2UuXHJcbiAgLy8gICAgICAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBIdHRwUmVzcG9uc2UpIHtcclxuICAvLyAgICAgICAgICAgY2FjaGUucHV0KHJlcSwgZXZlbnQpOyAvLyBVcGRhdGUgdGhlIGNhY2hlLlxyXG4gIC8vICAgICAgICAgfVxyXG4gIC8vICAgICAgIH0pXHJcbiAgLy8gICAgICk7XHJcbiAgLy8gICB9XHJcblxyXG4gIC8vIGNhY2hlLXRoZW4tcmVmcmVzaFxyXG4gIC8vIGlmIChyZXEuaGVhZGVycy5nZXQoJ3gtcmVmcmVzaCcpKSB7XHJcbiAgLy8gICAgIGNvbnN0IHJlc3VsdHMkID0gc2VuZFJlcXVlc3QocmVxLCBuZXh0LCB0aGlzLmNhY2hlKTtcclxuICAvLyAgICAgcmV0dXJuIGNhY2hlZFJlc3BvbnNlID9cclxuICAvLyAgICAgICByZXN1bHRzJC5waXBlKCBzdGFydFdpdGgoY2FjaGVkUmVzcG9uc2UpICkgOlxyXG4gIC8vICAgICAgIHJlc3VsdHMkO1xyXG4gIC8vICAgfVxyXG59XHJcbiIsImltcG9ydCB7IFN0b3JlU3luY0ludGVyY2VwdG9yIH0gZnJvbSAnLi9zdG9yZS1zeW5jLmludGVyY2VwdG9yJ1xyXG5pbXBvcnQgeyBBdXRoSW50ZXJjZXB0b3IgfSBmcm9tICcuL2F1dGguaW50ZXJjZXB0b3InXHJcbmltcG9ydCB7IE5vdGlmSW50ZXJjZXB0b3IgfSBmcm9tICcuL25vdGlmLmludGVyY2VwdG9yJ1xyXG5pbXBvcnQgeyBIVFRQX0lOVEVSQ0VQVE9SUyB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJ1xyXG5cclxuZXhwb3J0IGNvbnN0IElOVEVSQ0VQVE9SUzogYW55W10gPSBbXHJcbiAgeyBwcm92aWRlOiBIVFRQX0lOVEVSQ0VQVE9SUywgdXNlQ2xhc3M6IEF1dGhJbnRlcmNlcHRvciwgbXVsdGk6IHRydWUgfSxcclxuICAvLyB7IHByb3ZpZGU6IEhUVFBfSU5URVJDRVBUT1JTLCB1c2VDbGFzczogU3RvcmVTeW5jSW50ZXJjZXB0b3IsIG11bHRpOiB0cnVlIH0sXHJcbiAgeyBwcm92aWRlOiBIVFRQX0lOVEVSQ0VQVE9SUywgdXNlQ2xhc3M6IE5vdGlmSW50ZXJjZXB0b3IsIG11bHRpOiB0cnVlIH1cclxuXVxyXG5cclxuZXhwb3J0ICogZnJvbSAnLi9zdG9yZS1zeW5jLmludGVyY2VwdG9yJ1xyXG5leHBvcnQgKiBmcm9tICcuL2F1dGguaW50ZXJjZXB0b3InXHJcbmV4cG9ydCAqIGZyb20g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