@huntsman-cancer-institute/authentication 15.5.2 → 15.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/authentication.service.d.ts +10 -2
- package/esm2020/authentication.service.mjs +47 -4
- package/esm2020/index.mjs +2 -2
- package/fesm2015/huntsman-cancer-institute-authentication.mjs +47 -4
- package/fesm2015/huntsman-cancer-institute-authentication.mjs.map +1 -1
- package/fesm2020/huntsman-cancer-institute-authentication.mjs +47 -4
- package/fesm2020/huntsman-cancer-institute-authentication.mjs.map +1 -1
- package/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -20,6 +20,8 @@ export declare let AUTHENTICATION_ROUTE: InjectionToken<string>;
|
|
|
20
20
|
export declare let AUTHENTICATION_MAX_INACTIVITY_MINUTES: InjectionToken<number>;
|
|
21
21
|
export declare let AUTHENTICATION_USER_COUNTDOWN_SECONDS: InjectionToken<number>;
|
|
22
22
|
export declare let AUTHENTICATION_IDP_INACTIVITY_MINUTES: InjectionToken<number>;
|
|
23
|
+
export declare let AUTHENTICATION_USE_UI_EVENTS_FOR_ACTIVITY: InjectionToken<boolean>;
|
|
24
|
+
export declare let AUTHENTICATION_APP_KEEP_ALIVE_ENDPOINT: InjectionToken<string>;
|
|
23
25
|
/**
|
|
24
26
|
* @since 1.0.0
|
|
25
27
|
*/
|
|
@@ -37,6 +39,8 @@ export declare class AuthenticationService {
|
|
|
37
39
|
private _maxInactivity;
|
|
38
40
|
private _userCountdownSeconds;
|
|
39
41
|
private _idpInactivityMinutes;
|
|
42
|
+
private _useUIEventsForActivity;
|
|
43
|
+
private _keepAliveEndpoint;
|
|
40
44
|
private locationStrategy;
|
|
41
45
|
/**
|
|
42
46
|
* The generic error message used when a server error is thrown without a status.
|
|
@@ -63,9 +67,10 @@ export declare class AuthenticationService {
|
|
|
63
67
|
private _refreshSubscription;
|
|
64
68
|
private _lastUserInteraction;
|
|
65
69
|
private _maxInactivityMinutes;
|
|
70
|
+
private _uiEvents;
|
|
66
71
|
private baseUrl;
|
|
67
72
|
private contextRoot;
|
|
68
|
-
constructor(_http: HttpClient, _router: Router, _localStorageService: CoolLocalStorage, _jwtHelper: JwtHelperService, authenticationProvider: AuthenticationProvider, _authenticationRoute: string, _logoutPath: string, _tokenEndpoint: string, _serverUrl: string, _directEndpoint: string, _maxInactivity: number, _userCountdownSeconds: number, _idpInactivityMinutes: number, locationStrategy: LocationStrategy);
|
|
73
|
+
constructor(_http: HttpClient, _router: Router, _localStorageService: CoolLocalStorage, _jwtHelper: JwtHelperService, authenticationProvider: AuthenticationProvider, _authenticationRoute: string, _logoutPath: string, _tokenEndpoint: string, _serverUrl: string, _directEndpoint: string, _maxInactivity: number, _userCountdownSeconds: number, _idpInactivityMinutes: number, _useUIEventsForActivity: boolean, _keepAliveEndpoint: string, locationStrategy: LocationStrategy);
|
|
69
74
|
getBaseUrl(): string;
|
|
70
75
|
getContextRoot(): string;
|
|
71
76
|
getHeaders(req: HttpRequest<any>): HttpHeaders;
|
|
@@ -81,6 +86,7 @@ export declare class AuthenticationService {
|
|
|
81
86
|
set redirectUrl(redirectUrl: string);
|
|
82
87
|
get redirectUrl(): string;
|
|
83
88
|
requestAccessToken(redirectOnSuccess: boolean): void;
|
|
89
|
+
makeKeepAliveRequest(): void;
|
|
84
90
|
/**
|
|
85
91
|
* Verifies whether or not a current user session exists.
|
|
86
92
|
*
|
|
@@ -90,6 +96,7 @@ export declare class AuthenticationService {
|
|
|
90
96
|
isAboutToTimeOut(): Observable<boolean>;
|
|
91
97
|
getTimeoutStart(): number;
|
|
92
98
|
tokenLocation(): string;
|
|
99
|
+
keepAliveLocation(): string;
|
|
93
100
|
directLoginLocation(): string;
|
|
94
101
|
logoutLocation(): string;
|
|
95
102
|
/**
|
|
@@ -110,6 +117,7 @@ export declare class AuthenticationService {
|
|
|
110
117
|
storeToken(token: string): void;
|
|
111
118
|
proceedIfAuthenticated(): boolean;
|
|
112
119
|
validateToken(token: string): boolean;
|
|
120
|
+
subscribeToUIActivity(): void;
|
|
113
121
|
subscribeToTokenRefresh(token: any): void;
|
|
114
122
|
unsubscribeFromTokenRefresh(): void;
|
|
115
123
|
getMaxViewPermission(): "view" | "viewident" | "viewlimited";
|
|
@@ -118,6 +126,6 @@ export declare class AuthenticationService {
|
|
|
118
126
|
private refreshTokenIfUserIsActive;
|
|
119
127
|
private hasValidConfig;
|
|
120
128
|
private handleError;
|
|
121
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<AuthenticationService, [null, null, null, null, null, null, null, null, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }]>;
|
|
129
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<AuthenticationService, [null, null, null, null, null, null, null, null, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }, { optional: true; }]>;
|
|
122
130
|
static ɵprov: i0.ɵɵInjectableDeclaration<AuthenticationService>;
|
|
123
131
|
}
|
|
@@ -5,7 +5,7 @@ import { Injectable, InjectionToken, Inject, Optional, isDevMode } from "@angula
|
|
|
5
5
|
import { LocationStrategy } from "@angular/common";
|
|
6
6
|
import { Router } from "@angular/router";
|
|
7
7
|
import { HttpClient, HttpHeaders } from "@angular/common/http";
|
|
8
|
-
import { interval, BehaviorSubject, throwError } from "rxjs";
|
|
8
|
+
import { interval, BehaviorSubject, throwError, fromEvent } from "rxjs";
|
|
9
9
|
import { catchError, map } from "rxjs/operators";
|
|
10
10
|
import { JwtHelperService } from "@auth0/angular-jwt";
|
|
11
11
|
import { AuthenticationProvider } from "./authentication.provider";
|
|
@@ -30,11 +30,13 @@ export let AUTHENTICATION_ROUTE = new InjectionToken("authentication_route");
|
|
|
30
30
|
export let AUTHENTICATION_MAX_INACTIVITY_MINUTES = new InjectionToken("authentication_max_inactivity");
|
|
31
31
|
export let AUTHENTICATION_USER_COUNTDOWN_SECONDS = new InjectionToken("authentication_user_countdown_seconds");
|
|
32
32
|
export let AUTHENTICATION_IDP_INACTIVITY_MINUTES = new InjectionToken("authentication_idp_inactivity_minutes");
|
|
33
|
+
export let AUTHENTICATION_USE_UI_EVENTS_FOR_ACTIVITY = new InjectionToken("authentication_use_ui_events_for_activity");
|
|
34
|
+
export let AUTHENTICATION_APP_KEEP_ALIVE_ENDPOINT = new InjectionToken("authentication_app_keep_alive_endpoint");
|
|
33
35
|
/**
|
|
34
36
|
* @since 1.0.0
|
|
35
37
|
*/
|
|
36
38
|
export class AuthenticationService {
|
|
37
|
-
constructor(_http, _router, _localStorageService, _jwtHelper, authenticationProvider, _authenticationRoute, _logoutPath, _tokenEndpoint, _serverUrl, _directEndpoint, _maxInactivity, _userCountdownSeconds, _idpInactivityMinutes, locationStrategy) {
|
|
39
|
+
constructor(_http, _router, _localStorageService, _jwtHelper, authenticationProvider, _authenticationRoute, _logoutPath, _tokenEndpoint, _serverUrl, _directEndpoint, _maxInactivity, _userCountdownSeconds, _idpInactivityMinutes, _useUIEventsForActivity, _keepAliveEndpoint, locationStrategy) {
|
|
38
40
|
this._http = _http;
|
|
39
41
|
this._router = _router;
|
|
40
42
|
this._localStorageService = _localStorageService;
|
|
@@ -48,6 +50,8 @@ export class AuthenticationService {
|
|
|
48
50
|
this._maxInactivity = _maxInactivity;
|
|
49
51
|
this._userCountdownSeconds = _userCountdownSeconds;
|
|
50
52
|
this._idpInactivityMinutes = _idpInactivityMinutes;
|
|
53
|
+
this._useUIEventsForActivity = _useUIEventsForActivity;
|
|
54
|
+
this._keepAliveEndpoint = _keepAliveEndpoint;
|
|
51
55
|
this.locationStrategy = locationStrategy;
|
|
52
56
|
this.userCountdownSeconds = 60;
|
|
53
57
|
this.idpInactivityMinutes = 5;
|
|
@@ -58,6 +62,7 @@ export class AuthenticationService {
|
|
|
58
62
|
this._isAuthenticatedSubject = new BehaviorSubject(false);
|
|
59
63
|
this._userIsAboutToTimeOut = new BehaviorSubject(false);
|
|
60
64
|
this._maxInactivityMinutes = 120;
|
|
65
|
+
this._uiEvents = ['keydown', 'click', 'wheel', 'mousemove'];
|
|
61
66
|
this.contextRoot = "";
|
|
62
67
|
if (isDevMode()) {
|
|
63
68
|
console.debug("window.location.href: " + window.location.href);
|
|
@@ -81,6 +86,10 @@ export class AuthenticationService {
|
|
|
81
86
|
if (_idpInactivityMinutes) {
|
|
82
87
|
this.idpInactivityMinutes = _idpInactivityMinutes;
|
|
83
88
|
}
|
|
89
|
+
//Subscribe to UI events for user activity
|
|
90
|
+
if (_useUIEventsForActivity) {
|
|
91
|
+
this.subscribeToUIActivity();
|
|
92
|
+
}
|
|
84
93
|
this.hasValidConfig();
|
|
85
94
|
//There could be a non-expired token in local storage.
|
|
86
95
|
let token = this.authenticationProvider.authToken;
|
|
@@ -150,6 +159,9 @@ export class AuthenticationService {
|
|
|
150
159
|
this.logout(true);
|
|
151
160
|
});
|
|
152
161
|
}
|
|
162
|
+
makeKeepAliveRequest() {
|
|
163
|
+
this._http.get(this.keepAliveLocation(), { withCredentials: true }).subscribe();
|
|
164
|
+
}
|
|
153
165
|
/**
|
|
154
166
|
* Verifies whether or not a current user session exists.
|
|
155
167
|
*
|
|
@@ -174,6 +186,14 @@ export class AuthenticationService {
|
|
|
174
186
|
return this._tokenEndpoint;
|
|
175
187
|
}
|
|
176
188
|
}
|
|
189
|
+
keepAliveLocation() {
|
|
190
|
+
if (this._serverUrl) {
|
|
191
|
+
return this._serverUrl + this._keepAliveEndpoint;
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
return this._keepAliveEndpoint;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
177
197
|
directLoginLocation() {
|
|
178
198
|
if (this._serverUrl) {
|
|
179
199
|
return this._serverUrl + this._directEndpoint;
|
|
@@ -280,6 +300,14 @@ export class AuthenticationService {
|
|
|
280
300
|
validateToken(token) {
|
|
281
301
|
return (token && !this._jwtHelper.isTokenExpired(token));
|
|
282
302
|
}
|
|
303
|
+
subscribeToUIActivity() {
|
|
304
|
+
this._uiEvents.forEach(event => fromEvent(document, event).subscribe(_ => {
|
|
305
|
+
//Only update activity on UI event if not already about to time out. Counter intuitive, but in this case we should have 60 second count-down dialog open.
|
|
306
|
+
if (this._userIsAboutToTimeOut.getValue() !== true) {
|
|
307
|
+
this.updateUserActivity();
|
|
308
|
+
}
|
|
309
|
+
}));
|
|
310
|
+
}
|
|
283
311
|
subscribeToTokenRefresh(token) {
|
|
284
312
|
let exp = this._jwtHelper.getTokenExpirationDate(token);
|
|
285
313
|
// Use a timer to periodically check timeouts
|
|
@@ -319,7 +347,12 @@ export class AuthenticationService {
|
|
|
319
347
|
refreshTokenIfUserIsActive() {
|
|
320
348
|
//Only refresh if the user has been active
|
|
321
349
|
if (this._lastUserInteraction && ((new Date().valueOf() - this._lastUserInteraction.valueOf()) <= (this._maxInactivityMinutes * 60 * 1000))) {
|
|
350
|
+
//Refresh the JWT
|
|
322
351
|
this.requestAccessToken(false);
|
|
352
|
+
//Might as well make application keep alive requests at the same time as refreshing tokens - more efficient & probably needs same logic
|
|
353
|
+
if (this._keepAliveEndpoint) {
|
|
354
|
+
this.makeKeepAliveRequest();
|
|
355
|
+
}
|
|
323
356
|
}
|
|
324
357
|
}
|
|
325
358
|
hasValidConfig() {
|
|
@@ -346,7 +379,7 @@ AuthenticationService.SEC_GOV_CLASS_HEADER = "SecurityGovernorClass";
|
|
|
346
379
|
AuthenticationService.SEC_GOV_ID_HEADER = "SecurityGovernorId";
|
|
347
380
|
AuthenticationService.DEIDENT_HEADER = "DeidentifiedContext";
|
|
348
381
|
AuthenticationService.LIMITED_HEADER = "LimitedContext";
|
|
349
|
-
AuthenticationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AuthenticationService, deps: [{ token: i1.HttpClient }, { token: i2.Router }, { token: i3.CoolLocalStorage }, { token: i4.JwtHelperService }, { token: i5.AuthenticationProvider }, { token: AUTHENTICATION_ROUTE }, { token: AUTHENTICATION_LOGOUT_PATH }, { token: AUTHENTICATION_TOKEN_ENDPOINT }, { token: AUTHENTICATION_SERVER_URL, optional: true }, { token: AUTHENTICATION_DIRECT_ENDPOINT, optional: true }, { token: AUTHENTICATION_MAX_INACTIVITY_MINUTES, optional: true }, { token: AUTHENTICATION_USER_COUNTDOWN_SECONDS, optional: true }, { token: AUTHENTICATION_IDP_INACTIVITY_MINUTES, optional: true }, { token: LocationStrategy, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
382
|
+
AuthenticationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AuthenticationService, deps: [{ token: i1.HttpClient }, { token: i2.Router }, { token: i3.CoolLocalStorage }, { token: i4.JwtHelperService }, { token: i5.AuthenticationProvider }, { token: AUTHENTICATION_ROUTE }, { token: AUTHENTICATION_LOGOUT_PATH }, { token: AUTHENTICATION_TOKEN_ENDPOINT }, { token: AUTHENTICATION_SERVER_URL, optional: true }, { token: AUTHENTICATION_DIRECT_ENDPOINT, optional: true }, { token: AUTHENTICATION_MAX_INACTIVITY_MINUTES, optional: true }, { token: AUTHENTICATION_USER_COUNTDOWN_SECONDS, optional: true }, { token: AUTHENTICATION_IDP_INACTIVITY_MINUTES, optional: true }, { token: AUTHENTICATION_USE_UI_EVENTS_FOR_ACTIVITY, optional: true }, { token: AUTHENTICATION_APP_KEEP_ALIVE_ENDPOINT, optional: true }, { token: LocationStrategy, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
350
383
|
AuthenticationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AuthenticationService });
|
|
351
384
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AuthenticationService, decorators: [{
|
|
352
385
|
type: Injectable
|
|
@@ -384,10 +417,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
384
417
|
}, {
|
|
385
418
|
type: Inject,
|
|
386
419
|
args: [AUTHENTICATION_IDP_INACTIVITY_MINUTES]
|
|
420
|
+
}] }, { type: undefined, decorators: [{
|
|
421
|
+
type: Optional
|
|
422
|
+
}, {
|
|
423
|
+
type: Inject,
|
|
424
|
+
args: [AUTHENTICATION_USE_UI_EVENTS_FOR_ACTIVITY]
|
|
425
|
+
}] }, { type: undefined, decorators: [{
|
|
426
|
+
type: Optional
|
|
427
|
+
}, {
|
|
428
|
+
type: Inject,
|
|
429
|
+
args: [AUTHENTICATION_APP_KEEP_ALIVE_ENDPOINT]
|
|
387
430
|
}] }, { type: i6.LocationStrategy, decorators: [{
|
|
388
431
|
type: Optional
|
|
389
432
|
}, {
|
|
390
433
|
type: Inject,
|
|
391
434
|
args: [LocationStrategy]
|
|
392
435
|
}] }]; } });
|
|
393
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aGVudGljYXRpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2F1dGhlbnRpY2F0aW9uL3NyYy9hdXRoZW50aWNhdGlvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsT0FBTyxFQUFDLFVBQVUsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDdEYsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDakQsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZDLE9BQU8sRUFBQyxVQUFVLEVBQUUsV0FBVyxFQUE0QixNQUFNLHNCQUFzQixDQUFDO0FBRXhGLE9BQU8sRUFBQyxRQUFRLEVBQWMsZUFBZSxFQUFnQixVQUFVLEVBQUssTUFBTSxNQUFNLENBQUM7QUFDekYsT0FBTyxFQUFDLFVBQVUsRUFBUyxHQUFHLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0RCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQztBQUVwRCxPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQzs7Ozs7Ozs7QUFFekQ7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxJQUFJLHlCQUF5QixHQUFHLElBQUksY0FBYyxDQUFTLGdDQUFnQyxDQUFDLENBQUM7QUFDcEcsTUFBTSxDQUFDLElBQUksMEJBQTBCLEdBQUcsSUFBSSxjQUFjLENBQVMsNEJBQTRCLENBQUMsQ0FBQztBQUNqRyxNQUFNLENBQUMsSUFBSSw4QkFBOEIsR0FBRyxJQUFJLGNBQWMsQ0FBUyxnQ0FBZ0MsQ0FBQyxDQUFDO0FBQ3pHLE1BQU0sQ0FBQyxJQUFJLDZCQUE2QixHQUFHLElBQUks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LENBQUM7QUFDdkQsdUNBQWlCLEdBQVcsb0JBQW9CLENBQUM7QUFDakQsb0NBQWMsR0FBVyxxQkFBcUIsQ0FBQztBQUMvQyxvQ0FBYyxHQUFXLGdCQUFnQixDQUFDO21IQWI5QyxxQkFBcUIsd0tBd0NaLG9CQUFvQixhQUNwQiwwQkFBMEIsYUFDMUIsNkJBQTZCLGFBQ2pCLHlCQUF5Qiw2QkFDekIsOEJBQThCLDZCQUM5QixxQ0FBcUMsNkJBQ3JDLHFDQUFxQyw2QkFDckMscUNBQXFDLDZCQUNyQyxnQkFBZ0I7dUhBaERyQyxxQkFBcUI7NEZBQXJCLHFCQUFxQjtrQkFEakMsVUFBVTs7MEJBeUNJLE1BQU07MkJBQUMsb0JBQW9COzswQkFDM0IsTUFBTTsyQkFBQywwQkFBMEI7OzBCQUNqQyxNQUFNOzJCQUFDLDZCQUE2Qjs7MEJBQ3BDLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMseUJBQXlCOzswQkFDNUMsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyw4QkFBOEI7OzBCQUNqRCxRQUFROzswQkFBSSxNQUFNOzJCQUFDLHFDQUFxQzs7MEJBQ3hELFFBQVE7OzBCQUFJLE1BQU07MkJBQUMscUNBQXFDOzswQkFDeEQsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxxQ0FBcUM7OzBCQUN4RCxRQUFROzswQkFBSSxNQUFNOzJCQUFDLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbIi8qXHJcbiAqIENvcHlyaWdodCAoYykgMjAxNiBIdW50c21hbiBDYW5jZXIgSW5zdGl0dXRlIGF0IHRoZSBVbml2ZXJzaXR5IG9mIFV0YWgsIENvbmZpZGVudGlhbCBhbmQgUHJvcHJpZXRhcnlcclxuICovXHJcbmltcG9ydCB7SW5qZWN0YWJsZSwgSW5qZWN0aW9uVG9rZW4sIEluamVjdCwgT3B0aW9uYWwsIGlzRGV2TW9kZX0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuaW1wb3J0IHtMb2NhdGlvblN0cmF0ZWd5fSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XHJcbmltcG9ydCB7Um91dGVyfSBmcm9tIFwiQGFuZ3VsYXIvcm91dGVyXCI7XHJcbmltcG9ydCB7SHR0cENsaWVudCwgSHR0cEhlYWRlcnMsIEh0dHBSZXF1ZXN0LCBIdHRwUmVzcG9uc2V9IGZyb20gXCJAYW5ndWxhci9jb21tb24vaHR0cFwiO1xyXG5cclxuaW1wb3J0IHtpbnRlcnZhbCwgT2JzZXJ2YWJsZSwgQmVoYXZpb3JTdWJqZWN0LCBTdWJzY3JpcHRpb24sIHRocm93RXJyb3IsIG9mfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQge2NhdGNoRXJyb3IsIGZpcnN0LCBtYXB9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xyXG5pbXBvcnQge0p3dEhlbHBlclNlcnZpY2V9IGZyb20gXCJAYXV0aDAvYW5ndWxhci1qd3RcIjtcclxuXHJcbmltcG9ydCB7QXV0aGVudGljYXRpb25Qcm92aWRlcn0gZnJvbSBcIi4vYXV0aGVudGljYXRpb24ucHJvdmlkZXJcIjtcclxuaW1wb3J0IHsgQ29vbExvY2FsU3RvcmFnZSB9IGZyb20gXCJAYW5ndWxhci1jb29sL3N0b3JhZ2VcIjtcclxuXHJcbi8qKlxyXG4gKiBUaGUgdG9rZW4gdXNlZCBmb3IgaW5qZWN0aW9uIG9mIHRoZSBzZXJ2ZXIgc2lkZSBlbmRwb2ludCBmb3IgdGhlIGN1cnJlbnRseSBhdXRoZW50aWNhdGVkIHN1YmplY3QuXHJcbiAqXHJcbiAqIEB0eXBlIHtJbmplY3Rpb25Ub2tlbn1cclxuICovXHJcbmV4cG9ydCBsZXQgQVVUSEVOVElDQVRJT05fU0VSVkVSX1VSTCA9IG5ldyBJbmplY3Rpb25Ub2tlbjxzdHJpbmc+KFwiYXV0aGVudGljYXRpb25fc2VydmVyX3Jlc3RfYXBpXCIpO1xyXG5leHBvcnQgbGV0IEFVVEhFTlRJQ0FUSU9OX0xPR09VVF9QQVRIID0gbmV3IEluamVjdGlvblRva2VuPHN0cmluZz4oXCJhdXRoZW50aWNhdGlvbl9sb2dvdXRfcGF0aFwiKTtcclxuZXhwb3J0IGxldCBBVVRIRU5USUNBVElPTl9ESVJFQ1RfRU5EUE9JTlQgPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nPihcImF1dGhlbnRpY2F0aW9uX2RpcmVjdF9lbmRwb2ludFwiKTtcclxuZXhwb3J0IGxldCBBVVRIRU5USUNBVElPTl9UT0tFTl9FTkRQT0lOVCA9IG5ldyBJbmplY3Rpb25Ub2tlbjxzdHJpbmc+KFwiYXV0aGVudGljYXRpb25fdG9rZW5fZW5kcG9pbnRcIik7XHJcbmV4cG9ydCBsZXQgQVVUSEVOVElDQVRJT05fUk9VVEUgPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nPihcImF1dGhlbnRpY2F0aW9uX3JvdXRlXCIpO1xyXG5leHBvcnQgbGV0IEFVVEhFTlRJQ0FUSU9OX01BWF9JTkFDVElWSVRZX01JTlVURVMgPSBuZXcgSW5qZWN0aW9uVG9rZW48bnVtYmVyPihcImF1dGhlbnRpY2F0aW9uX21heF9pbmFjdGl2aXR5XCIpO1xyXG5leHBvcnQgbGV0IEFVVEhFTlRJQ0FUSU9OX1VTRVJfQ09VTlRET1dOX1NFQ09ORFMgPSBuZXcgSW5qZWN0aW9uVG9rZW48bnVtYmVyPihcImF1dGhlbnRpY2F0aW9uX3VzZXJfY291bnRkb3duX3NlY29uZHNcIik7XHJcbmV4cG9ydCBsZXQgQVVUSEVOVElDQVRJT05fSURQX0lOQUNUSVZJVFlfTUlOVVRFUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxudW1iZXI+KFwiYXV0aGVudGljYXRpb25faWRwX2luYWN0aXZpdHlfbWludXRlc1wiKTtcclxuXHJcbi8qKlxyXG4gKiBAc2luY2UgMS4wLjBcclxuICovXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIEF1dGhlbnRpY2F0aW9uU2VydmljZSB7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSBnZW5lcmljIGVycm9yIG1lc3NhZ2UgdXNlZCB3aGVuIGEgc2VydmVyIGVycm9yIGlzIHRocm93biB3aXRob3V0IGEgc3RhdHVzLlxyXG4gICAqXHJcbiAgICogQHR5cGUge3N0cmluZ31cclxuICAgKi9cclxuICBwdWJsaWMgc3RhdGljIEdFTkVSSUNfRVJSX01TRzogc3RyaW5nID0gXCJTZXJ2ZXIgZXJyb3JcIjtcclxuXHJcbiAgcHJpdmF0ZSBzdGF0aWMgQ09OVEVOVF9UWVBFOiBzdHJpbmcgPSBcIkNvbnRlbnQtVHlwZVwiO1xyXG4gIHByaXZhdGUgc3RhdGljIFNFQ19HT1ZfQ0xBU1NfSEVBREVSOiBzdHJpbmcgPSBcIlNlY3VyaXR5R292ZXJub3JDbGFzc1wiO1xyXG4gIHByaXZhdGUgc3RhdGljIFNFQ19HT1ZfSURfSEVBREVSOiBzdHJpbmcgPSBcIlNlY3VyaXR5R292ZXJub3JJZFwiO1xyXG4gIHByaXZhdGUgc3RhdGljIERFSURFTlRfSEVBREVSOiBzdHJpbmcgPSBcIkRlaWRlbnRpZmllZENvbnRleHRcIjtcclxuICBwcml2YXRlIHN0YXRpYyBMSU1JVEVEX0hFQURFUjogc3RyaW5nID0gXCJMaW1pdGVkQ29udGV4dFwiO1xyXG5cclxuICBwdWJsaWMgdXNlckNvdW50ZG93blNlY29uZHM6IG51bWJlciA9IDYwO1xyXG4gIHB1YmxpYyBpZHBJbmFjdGl2aXR5TWludXRlczogbnVtYmVyID0gNTtcclxuXHJcbiAgcHVibGljIGNvbnRlbnRUeXBlOiBzdHJpbmcgPSBcImFwcGxpY2F0aW9uL2pzb25cIjtcclxuICBwdWJsaWMgc2VjdXJpdHlHb3Zlcm5vckNsYXNzOiBzdHJpbmc7XHJcbiAgcHVibGljIHNlY3VyaXR5R292ZXJub3JJZDogbnVtYmVyO1xyXG4gIHB1YmxpYyBsaW1pdGVkQ29udGV4dDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIHB1YmxpYyBkZWlkZW50aWZpZWRDb250ZXh0OiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIHByaXZhdGUgbWF4Vmlld1Blcm1pc3Npb246IEJlaGF2aW9yU3ViamVjdDxcInZpZXdcIiB8IFwidmlld2lkZW50XCIgfCBcInZpZXdsaW1pdGVkXCI+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxcInZpZXdcIiB8IFwidmlld2lkZW50XCIgfCBcInZpZXdsaW1pdGVkXCI+KFwidmlld2lkZW50XCIpO1xyXG4gIHByaXZhdGUgX2lzQXV0aGVudGljYXRlZFN1YmplY3Q6IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xyXG4gIHByaXZhdGUgX3VzZXJJc0Fib3V0VG9UaW1lT3V0OiBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcclxuICBwcml2YXRlIF9yZWRpcmVjdFVybDogc3RyaW5nO1xyXG4gIHByaXZhdGUgX3JlZnJlc2hTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcclxuICBwcml2YXRlIF9sYXN0VXNlckludGVyYWN0aW9uOiBEYXRlO1xyXG4gIHByaXZhdGUgX21heEluYWN0aXZpdHlNaW51dGVzOiBudW1iZXIgPSAxMjA7XHJcblxyXG4gIHByaXZhdGUgYmFzZVVybDogc3RyaW5nO1xyXG4gIHByaXZhdGUgY29udGV4dFJvb3Q6IHN0cmluZyA9IFwiXCI7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2h0dHA6IEh0dHBDbGllbnQsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSBfcm91dGVyOiBSb3V0ZXIsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSBfbG9jYWxTdG9yYWdlU2VydmljZTogQ29vbExvY2FsU3RvcmFnZSxcclxuICAgICAgICAgICAgICBwcml2YXRlIF9qd3RIZWxwZXI6IEp3dEhlbHBlclNlcnZpY2UsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSBhdXRoZW50aWNhdGlvblByb3ZpZGVyOiBBdXRoZW50aWNhdGlvblByb3ZpZGVyLFxyXG4gICAgICAgICAgICAgIEBJbmplY3QoQVVUSEVOVElDQVRJT05fUk9VVEUpIHByaXZhdGUgX2F1dGhlbnRpY2F0aW9uUm91dGU6IHN0cmluZyxcclxuICAgICAgICAgICAgICBASW5qZWN0KEFVVEhFTlRJQ0FUSU9OX0xPR09VVF9QQVRIKSBwcml2YXRlIF9sb2dvdXRQYXRoOiBzdHJpbmcsXHJcbiAgICAgICAgICAgICAgQEluamVjdChBVVRIRU5USUNBVElPTl9UT0tFTl9FTkRQT0lOVCkgcHJpdmF0ZSBfdG9rZW5FbmRwb2ludDogc3RyaW5nLFxyXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoQVVUSEVOVElDQVRJT05fU0VSVkVSX1VSTCkgcHJpdmF0ZSBfc2VydmVyVXJsOiBzdHJpbmcsXHJcbiAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChBVVRIRU5USUNBVElPTl9ESVJFQ1RfRU5EUE9JTlQpIHByaXZhdGUgX2RpcmVjdEVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChBVVRIRU5USUNBVElPTl9NQVhfSU5BQ1RJVklUWV9NSU5VVEVTKSBwcml2YXRlIF9tYXhJbmFjdGl2aXR5OiBudW1iZXIsXHJcbiAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChBVVRIRU5USUNBVElPTl9VU0VSX0NPVU5URE9XTl9TRUNPTkRTKSBwcml2YXRlIF91c2VyQ291bnRkb3duU2Vjb25kczogbnVtYmVyLFxyXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoQVVUSEVOVElDQVRJT05fSURQX0lOQUNUSVZJVFlfTUlOVVRFUykgcHJpdmF0ZSBfaWRwSW5hY3Rpdml0eU1pbnV0ZXM6IG51bWJlcixcclxuICAgICAgICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KExvY2F0aW9uU3RyYXRlZ3kpIHByaXZhdGUgbG9jYXRpb25TdHJhdGVneTogTG9jYXRpb25TdHJhdGVneSkge1xyXG4gICAgaWYgKGlzRGV2TW9kZSgpKSB7XHJcbiAgICAgIGNvbnNvbGUuZGVidWcoXCJ3aW5kb3cubG9jYXRpb24uaHJlZjogXCIgKyB3aW5kb3cubG9jYXRpb24uaHJlZik7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHdpbmRvdy5sb2NhdGlvbikge1xyXG4gICAgICBsZXQgcGFydHM6IHN0cmluZ1tdID0gd2luZG93LmxvY2F0aW9uLmhyZWYuc3BsaXQoXCIvXCIpO1xyXG4gICAgICB0aGlzLmJhc2VVcmwgPSBwYXJ0c1swXSArIFwiLy9cIiArIHBhcnRzWzJdO1xyXG4gICAgICBpZiAocGFydHMubGVuZ3RoID4gMykge1xyXG4gICAgICAgIHRoaXMuY29udGV4dFJvb3QgPSBwYXJ0c1szXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLl9sb2NhbFN0b3JhZ2VTZXJ2aWNlLmdldEl0ZW0oXCJtYXhWaWV3UGVybWlzc2lvblwiKSkge1xyXG4gICAgICB0aGlzLm1heFZpZXdQZXJtaXNzaW9uLm5leHQoPFwidmlld1wiIHwgXCJ2aWV3aWRlbnRcIiB8IFwidmlld2xpbWl0ZWRcIj50aGlzLl9sb2NhbFN0b3JhZ2VTZXJ2aWNlLmdldEl0ZW0oXCJtYXhWaWV3UGVybWlzc2lvblwiKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKF9tYXhJbmFjdGl2aXR5KSB7XHJcbiAgICAgIHRoaXMuX21heEluYWN0aXZpdHlNaW51dGVzID0gX21heEluYWN0aXZpdHk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKF91c2VyQ291bnRkb3duU2Vjb25kcykge1xyXG4gICAgICB0aGlzLnVzZXJDb3VudGRvd25TZWNvbmRzID0gX3VzZXJDb3VudGRvd25TZWNvbmRzO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChfaWRwSW5hY3Rpdml0eU1pbnV0ZXMpIHtcclxuICAgICAgdGhpcy5pZHBJbmFjdGl2aXR5TWludXRlcyA9IF9pZHBJbmFjdGl2aXR5TWludXRlcztcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmhhc1ZhbGlkQ29uZmlnKCk7XHJcblxyXG4gICAgLy9UaGVyZSBjb3VsZCBiZSBhIG5vbi1leHBpcmVkIHRva2VuIGluIGxvY2FsIHN0b3JhZ2UuXHJcbiAgICBsZXQgdG9rZW46IHN0cmluZyA9IHRoaXMuYXV0aGVudGljYXRpb25Qcm92aWRlci5hdXRoVG9rZW47XHJcbiAgICB0aGlzLnN0b3JlVG9rZW4odG9rZW4pO1xyXG4gIH1cclxuXHJcbiAgZ2V0QmFzZVVybCgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuICh0aGlzLmJhc2VVcmwpID8gdGhpcy5iYXNlVXJsIDogXCJcIjtcclxuICB9XHJcblxyXG4gIGdldENvbnRleHRSb290KCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5jb250ZXh0Um9vdDtcclxuICB9XHJcblxyXG4gIGdldEhlYWRlcnMocmVxOiBIdHRwUmVxdWVzdDxhbnk+KTogSHR0cEhlYWRlcnMge1xyXG4gICAgbGV0IGhlYWRlcnM6IEh0dHBIZWFkZXJzID0gcmVxLmhlYWRlcnM7XHJcblxyXG4gICAgLy9Eb24ndCBzZXQgY29udGVudCB0eXBlIGlmIGFscmVhZHkgc2V0XHJcbiAgICBpZiAoIXJlcS5oZWFkZXJzLmdldChBdXRoZW50aWNhdGlvblNlcnZpY2UuQ09OVEVOVF9UWVBFKSkge1xyXG4gICAgICBoZWFkZXJzID0gaGVhZGVycy5zZXQoQXV0aGVudGljYXRpb25TZXJ2aWNlLkNPTlRFTlRfVFlQRSwgdGhpcy5jb250ZW50VHlwZS50b1N0cmluZygpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoaGVhZGVycy5nZXQoQXV0aGVudGljYXRpb25TZXJ2aWNlLlNFQ19HT1ZfQ0xBU1NfSEVBREVSKSA9PT0gXCJcIikge1xyXG4gICAgICBoZWFkZXJzID0gaGVhZGVycy5kZWxldGUoQXV0aGVudGljYXRpb25TZXJ2aWNlLlNFQ19HT1ZfQ0xBU1NfSEVBREVSKTtcclxuICAgIH0gZWxzZSBpZiAodGhpcy5zZWN1cml0eUdvdmVybm9yQ2xhc3MgJiYgIWhlYWRlcnMuZ2V0KEF1dGhlbnRpY2F0aW9uU2VydmljZS5TRUNfR09WX0NMQVNTX0hFQURFUikpIHtcclxuICAgICAgaGVhZGVycyA9IGhlYWRlcnMuc2V0KEF1dGhlbnRpY2F0aW9uU2VydmljZS5TRUNfR09WX0NMQVNTX0hFQURFUiwgdGhpcy5zZWN1cml0eUdvdmVybm9yQ2xhc3MpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChoZWFkZXJzLmdldChBdXRoZW50aWNhdGlvblNlcnZpY2UuU0VDX0dPVl9JRF9IRUFERVIpID09PSBcIlwiKSB7XHJcbiAgICAgIGhlYWRlcnMgPSBoZWFkZXJzLmRlbGV0ZShBdXRoZW50aWNhdGlvblNlcnZpY2UuU0VDX0dPVl9JRF9IRUFERVIpO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLnNlY3VyaXR5R292ZXJub3JJZCAmJiAhaGVhZGVycy5nZXQoQXV0aGVudGljYXRpb25TZXJ2aWNlLlNFQ19HT1ZfSURfSEVBREVSKSkge1xyXG4gICAgICBoZWFkZXJzID0gaGVhZGVycy5zZXQoQXV0aGVudGljYXRpb25TZXJ2aWNlLlNFQ19HT1ZfSURfSEVBREVSLCB0aGlzLnNlY3VyaXR5R292ZXJub3JJZC50b1N0cmluZygpKTtcclxuICAgIH1cclxuXHJcbiAgICBoZWFkZXJzID0gaGVhZGVycy5zZXQoQXV0aGVudGljYXRpb25TZXJ2aWNlLkRFSURFTlRfSEVBREVSLCB0aGlzLmRlaWRlbnRpZmllZENvbnRleHQudG9TdHJpbmcoKSk7XHJcbiAgICBoZWFkZXJzID0gaGVhZGVycy5zZXQoQXV0aGVudGljYXRpb25TZXJ2aWNlLkxJTUlURURfSEVBREVSLCB0aGlzLmxpbWl0ZWRDb250ZXh0LnRvU3RyaW5nKCkpO1xyXG5cclxuICAgIHJldHVybiBoZWFkZXJzO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGF1dGhlbnRpY2F0aW9uVG9rZW5LZXkoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aGlzLmF1dGhlbnRpY2F0aW9uUHJvdmlkZXIuYXV0aGVudGljYXRpb25Ub2tlbktleTtcclxuICB9XHJcblxyXG4gIGdldCBhdXRoVG9rZW4oKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aGlzLmF1dGhlbnRpY2F0aW9uUHJvdmlkZXIuYXV0aFRva2VuO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHVwZGF0ZVVzZXJBY3Rpdml0eSgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLl9pc0F1dGhlbnRpY2F0ZWRTdWJqZWN0LnZhbHVlKSB7XHJcbiAgICAgIHRoaXMuX2xhc3RVc2VySW50ZXJhY3Rpb24gPSBuZXcgRGF0ZSgpO1xyXG4gICAgICB0aGlzLl91c2VySXNBYm91dFRvVGltZU91dC5uZXh0KGZhbHNlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEEgbXV0YXRvciBmb3IgaWRlbnRpZnlpbmcgdGhlIGNsaWVudHMgb3JpZ2luYWwgcmVxdWVzdCBsb2NhdGlvbi4gU2V0dGluZyB0aGlzIHZhbHVlIHdpbGwgaW5mbHVlbmNlIHRoZSBlbmQgbG9jYXRpb25cclxuICAgKiBuYXZpZ2F0ZWQgdG8gYnkge0BsaW5rICNuYXZpZ2F0ZVRvUGF0aH0uXHJcbiAgICpcclxuICAgKiBAcGFyYW0gcmVkaXJlY3RVcmwgbG9jYXRpb24gb2YgdGhlIHVzZXJzIHJlcXVlc3QgYmVmb3JlIGF1dGhlbnRpY2F0aW9uXHJcbiAgICovXHJcbiAgc2V0IHJlZGlyZWN0VXJsKHJlZGlyZWN0VXJsOiBzdHJpbmcpIHtcclxuICAgIHRoaXMuX3JlZGlyZWN0VXJsID0gcmVkaXJlY3RVcmw7XHJcbiAgfVxyXG5cclxuICBnZXQgcmVkaXJlY3RVcmwoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fcmVkaXJlY3RVcmw7XHJcbiAgfVxyXG5cclxuICByZXF1ZXN0QWNjZXNzVG9rZW4ocmVkaXJlY3RPblN1Y2Nlc3M6IGJvb2xlYW4pOiB2b2lkIHtcclxuXHJcbiAgICB0aGlzLl9odHRwLmdldCh0aGlzLnRva2VuTG9jYXRpb24oKSwge3dpdGhDcmVkZW50aWFsczogdHJ1ZX0pXHJcbiAgICAgIC5zdWJzY3JpYmUoXHJcbiAgICAgICAgKHJlc3BvbnNlOiBhbnkpID0+IHtcclxuICAgICAgICAgIHRoaXMuc3RvcmVUb2tlbihyZXNwb25zZS5hdXRoX3Rva2VuKTtcclxuICAgICAgICAgIGlmIChyZWRpcmVjdE9uU3VjY2Vzcykge1xyXG4gICAgICAgICAgICB0aGlzLnByb2NlZWRJZkF1dGhlbnRpY2F0ZWQoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgLy9Ub2tlbiByZWZyZXNoIGZhaWxlZC5cclxuICAgICAgICAgIHRoaXMubG9nb3V0KHRydWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFZlcmlmaWVzIHdoZXRoZXIgb3Igbm90IGEgY3VycmVudCB1c2VyIHNlc3Npb24gZXhpc3RzLlxyXG4gICAqXHJcbiAgICogQHJldHVybnMge09ic2VydmFibGU8Ym9vbGVhbj59IGV2YWx1YXRlcyB0byB0cnVlIGlmIHRoZSB1c2VyIGlzIGF1dGhlbnRpY2F0ZWQsIGZhbHNlIG90aGVyd2lzZS5cclxuICAgKi9cclxuICBpc0F1dGhlbnRpY2F0ZWQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XHJcbiAgICByZXR1cm4gdGhpcy5faXNBdXRoZW50aWNhdGVkU3ViamVjdC5hc09ic2VydmFibGUoKTtcclxuICB9XHJcblxyXG4gIGlzQWJvdXRUb1RpbWVPdXQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XHJcbiAgICByZXR1cm4gdGhpcy5fdXNlcklzQWJvdXRUb1RpbWVPdXQuYXNPYnNlcnZhYmxlKCk7XHJcbiAgfVxyXG5cclxuICBnZXRUaW1lb3V0U3RhcnQoKTogbnVtYmVyIHtcclxuICAgIGlmICh0aGlzLl9sYXN0VXNlckludGVyYWN0aW9uKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9sYXN0VXNlckludGVyYWN0aW9uLnZhbHVlT2YoKSArICgoKHRoaXMuX21heEluYWN0aXZpdHlNaW51dGVzICogNjApIC0gdGhpcy51c2VyQ291bnRkb3duU2Vjb25kcykgKiAxMDAwKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHRva2VuTG9jYXRpb24oKTogc3RyaW5nIHtcclxuICAgIGlmICh0aGlzLl9zZXJ2ZXJVcmwpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX3NlcnZlclVybCArIHRoaXMuX3Rva2VuRW5kcG9pbnQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gdGhpcy5fdG9rZW5FbmRwb2ludDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGRpcmVjdExvZ2luTG9jYXRpb24oKTogc3RyaW5nIHtcclxuICAgIGlmICh0aGlzLl9zZXJ2ZXJVcmwpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX3NlcnZlclVybCArIHRoaXMuX2RpcmVjdEVuZHBvaW50O1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX2RpcmVjdEVuZHBvaW50O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbG9nb3V0TG9jYXRpb24oKTogc3RyaW5nIHtcclxuICAgIGlmICh0aGlzLl9zZXJ2ZXJVcmwpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX3NlcnZlclVybCArIHRoaXMuX2xvZ291dFBhdGg7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gdGhpcy5fbG9nb3V0UGF0aDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEEgZnVuY3Rpb24gdG8gYXV0aGVudGljYXRlZCB0aGUgdXNlciB3aXRoIHRoZSBwcm92aWRlZCBjcmVkZW50aWFscy4gRmFpbHVyZSByZXN1bHRzIGluIGFuIGVycm9yIHRoYXQgZGVzY3JpYmVzIHRoZVxyXG4gICAqIHNlcnZlciByZXNwb25zZSAoc3RhdHVzIGFuZCBzdGF0dXMgbWVzc2FnZSkgYW5kIHNob3VsZCBiZSBhY3Rpb25hYmxlIGJ5IHRoZSBjbGllbnQgYXBwbGljYXRpb24uXHJcbiAgICpcclxuICAgKiBAcGFyYW0gdXNlcm5hbWUgb2YgdGhlIGF1dGhlbnRpY2F0aW5nIHVzZXIgdG8gdmVyaWZ5XHJcbiAgICogQHBhcmFtIHBhc3N3b3JkIG9mIHRoZSBhdXRoZW50aWNhdGluZyB1c2VyIHRvIHZlcmlmeVxyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlPFI+fSBkZXNjcmliaW5nIHRoZSByZXN1bHQgb2YgdGhlIGxvZ2luIGFjdGlvbiwgdHJ1ZSBvciBhbiBlcnJvclxyXG4gICAqL1xyXG4gIGxvZ2luKF91c2VybmFtZTogc3RyaW5nLCBfcGFzc3dvcmQ6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX2h0dHAucG9zdChcclxuICAgICAgdGhpcy5kaXJlY3RMb2dpbkxvY2F0aW9uKCksXHJcbiAgICAgIHt1c2VybmFtZTogX3VzZXJuYW1lLCBwYXNzd29yZDogX3Bhc3N3b3JkfSxcclxuICAgICAge29ic2VydmU6IFwicmVzcG9uc2VcIn1cclxuICAgICkucGlwZShtYXAoKHJlc3A6IEh0dHBSZXNwb25zZTxhbnk+KSA9PiB7XHJcbiAgICAgIGlmIChyZXNwLnN0YXR1cyA9PT0gMjAxKSB7XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQXV0aGVudGljYXRpb24gZmFpbGVkLiBcIiArIHJlc3Auc3RhdHVzICsgXCI6IFwiICsgcmVzcC5zdGF0dXNUZXh0KTtcclxuICAgICAgfVxyXG4gICAgfSksXHJcbiAgICAgIGNhdGNoRXJyb3IodGhpcy5oYW5kbGVFcnJvcikpO1xyXG4gIH1cclxuXHJcblxyXG4gIGNsZWFyTG9naW4oKTogT2JzZXJ2YWJsZTxSZXNwb25zZT4ge1xyXG4gICAgLy9Gcm9udC1lbmQgbG9nb3V0XHJcbiAgICB0cnkge1xyXG4gICAgICB0aGlzLl9sb2NhbFN0b3JhZ2VTZXJ2aWNlLnJlbW92ZUl0ZW0odGhpcy5hdXRoZW50aWNhdGlvblByb3ZpZGVyLmF1dGhlbnRpY2F0aW9uVG9rZW5LZXkpO1xyXG4gICAgICB0aGlzLnVuc3Vic2NyaWJlRnJvbVRva2VuUmVmcmVzaCgpO1xyXG4gICAgICB0aGlzLl9pc0F1dGhlbnRpY2F0ZWRTdWJqZWN0Lm5leHQoZmFsc2UpO1xyXG4gICAgICB0aGlzLl91c2VySXNBYm91dFRvVGltZU91dC5uZXh0KGZhbHNlKTtcclxuICAgIH0gY2F0Y2ggKEVycm9yKSB7XHJcbiAgICB9XHJcblxyXG4gICAgLy9CYWNrLWVuZCBsb2dvdXRcclxuICAgIGxldCBoZWFkZXJzID0gbmV3IEh0dHBIZWFkZXJzKCkuc2V0KEF1dGhlbnRpY2F0aW9uU2VydmljZS5DT05URU5UX1RZUEUsIFwidGV4dC9wbGFpblwiKTtcclxuICAgIHJldHVybiA8T2JzZXJ2YWJsZTxSZXNwb25zZT4+dGhpcy5faHR0cC5nZXQodGhpcy5sb2dvdXRMb2NhdGlvbigpLCB7aGVhZGVyczogaGVhZGVyc30pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQSBmdW5jdGlvbiB0byBzaWduYWwgdGhlIHRlcm1pbmF0aW9uIG9mIHRoZSBjdXJyZW50IHNlc3Npb24uIEludm9raW5nIHRoaXMgZnVuY3Rpb24gd2lsbCBjbGVhbiB1cCBhbnkgcmVsZXZhbnQgc3RhdGVcclxuICAgKiByZWxhdGVkIHRvIHRoZSBsYXN0IGFjdGl2ZSBzZXNzaW9uLlxyXG4gICAqL1xyXG4gIGxvZ291dChrZWVwQ3VycmVudFJvdXRlOiBib29sZWFuID0gZmFsc2UpOiB2b2lkIHtcclxuICAgIC8vUHJldmVudCBsb2dvdXQgaWYgYWxyZWFkeSBvbiBhdXRoZW50aWNhdGlvbiByb3V0ZS4gRG9pbmcgb3RoZXJ3aXNlIHNjcmV3cyB1cCBTQU1MXHJcbiAgICBpZiAoISB0aGlzLl9yb3V0ZXIucm91dGVyU3RhdGUgfHwgdGhpcy5fcm91dGVyLnJvdXRlclN0YXRlLnNuYXBzaG90LnVybCAhPT0gdGhpcy5fYXV0aGVudGljYXRpb25Sb3V0ZSkge1xyXG4gICAgICB0aGlzLl9yZWRpcmVjdFVybCA9IChrZWVwQ3VycmVudFJvdXRlICYmIHRoaXMuX3JvdXRlci5yb3V0ZXJTdGF0ZSAmJiB0aGlzLl9yb3V0ZXIucm91dGVyU3RhdGUuc25hcHNob3QpID8gdGhpcy5fcm91dGVyLnJvdXRlclN0YXRlLnNuYXBzaG90LnVybCA6IFwiXCI7XHJcblxyXG4gICAgICBpZiAodGhpcy5fcmVkaXJlY3RVcmwuc3RhcnRzV2l0aChcIi9cIikpIHtcclxuICAgICAgICB0aGlzLl9yZWRpcmVjdFVybCA9IHRoaXMuX3JlZGlyZWN0VXJsLnN1YnN0cmluZygxKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5jbGVhckxvZ2luKCkuc3Vic2NyaWJlKFxyXG4gICAgICAgIChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgICAgd2luZG93LmxvY2F0aW9uLnJlcGxhY2UodGhpcy5fcmVkaXJlY3RVcmwpO1xyXG4gICAgICAgICAgfSxcclxuICAgICAgICAoZXJyb3IpID0+IHtcclxuICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKHRoaXMuX3JlZGlyZWN0VXJsKTtcclxuICAgICAgICB9XHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzdG9yZVRva2VuKHRva2VuOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGxldCB2YWxpZCA9IHRoaXMudmFsaWRhdGVUb2tlbih0b2tlbik7XHJcblxyXG4gICAgLy8gdW5zdWJzY3JpYmUgZnJvbSByZWZlc2ggYmVmb3JlIHdlIGRlY2lkZSB3ZXRoZXIgdG8gcmVzdWJzY3JpYmVcclxuICAgIHRoaXMudW5zdWJzY3JpYmVGcm9tVG9rZW5SZWZyZXNoKCk7XHJcblxyXG4gICAgaWYgKHZhbGlkKSB7XHJcbiAgICAgIHRoaXMuX2xvY2FsU3RvcmFnZVNlcnZpY2Uuc2V0SXRlbSh0aGlzLmF1dGhlbnRpY2F0aW9uUHJvdmlkZXIuYXV0aGVudGljYXRpb25Ub2tlbktleSwgdG9rZW4pO1xyXG4gICAgICB0aGlzLnN1YnNjcmliZVRvVG9rZW5SZWZyZXNoKHRva2VuKTtcclxuXHJcbiAgICAgIC8vQ2hhbmdlIHRoZSBCZWhhdmlvclN1YmplY3QgaWYgdGhlIHVzZXIgd2FzIG5vdCBwcmV2aW91c2x5IGF1dGhlbnRpY2F0ZWQuXHJcbiAgICAgIC8vU2luY2Ugb3RoZXIgY29kZSBtYXkgYmUgc3Vic2NyaWJpbmcgdG8gdGhpcyBvYnNlcnZhYmxlLCB3ZSBkb24ndCB3YW50IHRvIGNhdXNlIG5ldyBldmVudHMgdG8gZmlyZSBpZiBqdXN0IHJlZnJlc2hpbmcgdGhlIEpXVC5cclxuICAgICAgaWYgKCEgdGhpcy5faXNBdXRoZW50aWNhdGVkU3ViamVjdC52YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuX2lzQXV0aGVudGljYXRlZFN1YmplY3QubmV4dCh0cnVlKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5fbG9jYWxTdG9yYWdlU2VydmljZS5yZW1vdmVJdGVtKHRoaXMuYXV0aGVudGljYXRpb25Qcm92aWRlci5hdXRoZW50aWNhdGlvblRva2VuS2V5KTtcclxuICAgICAgdGhpcy5faXNBdXRoZW50aWNhdGVkU3ViamVjdC5uZXh0KGZhbHNlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByb2NlZWRJZkF1dGhlbnRpY2F0ZWQoKTogYm9vbGVhbiB7XHJcbiAgICBpZiAoaXNEZXZNb2RlKCkpIHtcclxuICAgICAgY29uc29sZS5kZWJ1ZyhcIkF1dGhlbnRpY2F0aW9uU2VydmljZS5wcm9jZWVkSWZBdXRoZW50aWNhdGVkOiBcIiArIHRoaXMuX3JlZGlyZWN0VXJsKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5faXNBdXRoZW50aWNhdGVkU3ViamVjdC52YWx1ZSkge1xyXG4gICAgICAvL0xvZ2luIGNvdW50cyBhcyB1c2VyIGFjdGl2aXR5LCB0b29cclxuICAgICAgdGhpcy51cGRhdGVVc2VyQWN0aXZpdHkoKTtcclxuXHJcbiAgICAgIGlmICh0aGlzLl9yZWRpcmVjdFVybCAmJiB0aGlzLl9yZWRpcmVjdFVybCAmJiB0aGlzLl9yZWRpcmVjdFVybCAhPT0gXCJcIikge1xyXG4gICAgICAgIHRoaXMuX3JvdXRlci5uYXZpZ2F0ZUJ5VXJsKHRoaXMuX3JlZGlyZWN0VXJsKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLl9yb3V0ZXIubmF2aWdhdGUoW1wiXCJdKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB2YWxpZGF0ZVRva2VuKHRva2VuOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIHJldHVybiAodG9rZW4gJiYgIXRoaXMuX2p3dEhlbHBlci5pc1Rva2VuRXhwaXJlZCh0b2tlbikpO1xyXG4gIH1cclxuXHJcbiAgc3Vic2NyaWJlVG9Ub2tlblJlZnJlc2godG9rZW46IGFueSk6IHZvaWQge1xyXG4gICAgbGV0IGV4cCA9IHRoaXMuX2p3dEhlbHBlci5nZXRUb2tlbkV4cGlyYXRpb25EYXRlKHRva2VuKTtcclxuXHJcbiAgICAvLyBVc2UgYSB0aW1lciB0byBwZXJpb2RpY2FsbHkgY2hlY2sgdGltZW91dHNcclxuICAgIHRoaXMuX3JlZnJlc2hTdWJzY3JpcHRpb24gPSBpbnRlcnZhbCgxMDAwKVxyXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcclxuXHJcbiAgICAgICAgLy8gSWYgYSB0YWIgaXMgaW5hY3RpdmUgd2UgY2FuJ3Qga25vdyBpZiBvdXIgdGltZXIgaXMgYWNjdXJhdGVcclxuICAgICAgICAvLyBzbyB3aGVuIHRoZSBpbnRlcnZhbCBoaXRzIGNoZWNrIGFnYWluc3QgdGltZXN0YW1wc1xyXG4gICAgICAgIGlmICh0aGlzLl9pc0F1dGhlbnRpY2F0ZWRTdWJqZWN0LnZhbHVlICYmIERhdGUubm93KCkgPiB0aGlzLmdldFRpbWVvdXRTdGFydCgpKSB7XHJcbiAgICAgICAgICAvL0Rvbid0IHVwZGF0ZSB0aGUgc3ViamVjdCBtb3JlIHRoYW4gb25jZSEgRG9pbmcgc28gaW5pdGlhbGl6ZXMgbW9yZSB0aGFuIG9uZSBjb3VudGRvd24gdGltZXIhXHJcbiAgICAgICAgICBpZiAodGhpcy5fdXNlcklzQWJvdXRUb1RpbWVPdXQuZ2V0VmFsdWUoKSAhPT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl91c2VySXNBYm91dFRvVGltZU91dC5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gY2hlY2sgZm9yIHJlZnJlc2ggdG9rZW5cclxuICAgICAgICBsZXQgbXNUb0V4cGlyeSA9IChleHAudmFsdWVPZigpIC0gbmV3IERhdGUoKS52YWx1ZU9mKCkpO1xyXG5cclxuICAgICAgICAvLyBSZWZyZXNoIDYwIHNlY29uZHMgYmVmb3JlIGV4cGlyeVxyXG4gICAgICAgIGlmIChtc1RvRXhwaXJ5IDw9IDYwMDAwKSB7XHJcbiAgICAgICAgICB0aGlzLnJlZnJlc2hUb2tlbklmVXNlcklzQWN0aXZlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIHVuc3Vic2NyaWJlRnJvbVRva2VuUmVmcmVzaCgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLl9yZWZyZXNoU3Vic2NyaXB0aW9uICYmICEgdGhpcy5fcmVmcmVzaFN1YnNjcmlwdGlvbi5jbG9zZWQpIHtcclxuICAgICAgdGhpcy5fcmVmcmVzaFN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0TWF4Vmlld1Blcm1pc3Npb24oKTogXCJ2aWV3XCIgfCBcInZpZXdpZGVudFwiIHwgXCJ2aWV3bGltaXRlZFwiIHtcclxuICAgIHJldHVybiB0aGlzLm1heFZpZXdQZXJtaXNzaW9uLmdldFZhbHVlKCk7XHJcbiAgfVxyXG5cclxuICBnZXRNYXhWaWV3UGVybWlzc2lvblN1YmplY3QoKTogQmVoYXZpb3JTdWJqZWN0PFwidmlld1wiIHwgXCJ2aWV3aWRlbnRcIiB8IFwidmlld2xpbWl0ZWRcIj4ge1xyXG4gICAgcmV0dXJuIHRoaXMubWF4Vmlld1Blcm1pc3Npb247XHJcbiAgfVxyXG5cclxuICBzZXRNYXhWaWV3UGVybWlzc2lvbihtYXhWaWV3UGVybWlzc2lvbjogXCJ2aWV3XCIgfCBcInZpZXdpZGVudFwiIHwgXCJ2aWV3bGltaXRlZFwiKTogdm9pZCB7XHJcbiAgICB0aGlzLl9sb2NhbFN0b3JhZ2VTZXJ2aWNlLnNldEl0ZW0oXCJtYXhWaWV3UGVybWlzc2lvblwiLCBtYXhWaWV3UGVybWlzc2lvbik7XHJcbiAgICB0aGlzLm1heFZpZXdQZXJtaXNzaW9uLm5leHQobWF4Vmlld1Blcm1pc3Npb24pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZWZyZXNoVG9rZW5JZlVzZXJJc0FjdGl2ZSgpOiB2b2lkIHtcclxuICAgIC8vT25seSByZWZyZXNoIGlmIHRoZSB1c2VyIGhhcyBiZWVuIGFjdGl2ZVxyXG4gICAgaWYgKHRoaXMuX2xhc3RVc2VySW50ZXJhY3Rpb24gJiYgKChuZXcgRGF0ZSgpLnZhbHVlT2YoKSAtIHRoaXMuX2xhc3RVc2VySW50ZXJhY3Rpb24udmFsdWVPZigpKSA8PSAodGhpcy5fbWF4SW5hY3Rpdml0eU1pbnV0ZXMgKiA2MCAqIDEwMDApKSkge1xyXG4gICAgICB0aGlzLnJlcXVlc3RBY2Nlc3NUb2tlbihmYWxzZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGhhc1ZhbGlkQ29uZmlnKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuX3Rva2VuRW5kcG9pbnQgPT0gbnVsbCAmJiAodGhpcy5fc2VydmVyVXJsID09PSBudWxsIHx8IHRoaXMuX2xvZ291dFBhdGggPT09IG51bGwpKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkJVRyBBTEVSVCEgSW52YWxpZCBBdXRoZW50aWNhdGlvblNlcnZpY2UgY29uZmlndXJhdGlvbi4gTm8gdmFsaWQgY29uZmlndXJhdGlvbiBmb3IgYXV0aGVudGljYXRpb24gZW5kcG9pbnQocykuXCIpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuX2xvY2FsU3RvcmFnZVNlcnZpY2UgPT09IG51bGwgfHwgdGhpcy5hdXRoZW50aWNhdGlvblByb3ZpZGVyLmF1dGhlbnRpY2F0aW9uVG9rZW5LZXkgPT09IG51bGwpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQlVHIEFMRVJUISBJbnZhbGlkIEF1dGhlbnRpY2F0aW9uU2VydmljZSBjb25maWd1cmF0aW9uLiBObyB2YWxpZCBjb25maWd1cmF0aW9uIGZvciBsb2NhbCBzdG9yYWdlXCIpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBoYW5kbGVFcnJvcihlcnJvcjogYW55KSA6IE9ic2VydmFibGU8bmV2ZXI+IHtcclxuICAgIGxldCBlcnJNc2cgPSAoZXJyb3IubWVzc2FnZSkgPyBlcnJvci5tZXNzYWdlIDogQXV0aGVudGljYXRpb25TZXJ2aWNlLkdFTkVSSUNfRVJSX01TRztcclxuICAgIHJldHVybiB0aHJvd0Vycm9yKGVyck1zZyk7XHJcbiAgfVxyXG59XHJcbiJdfQ==
|
|
436
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aGVudGljYXRpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL2F1dGhlbnRpY2F0aW9uL3NyYy9hdXRoZW50aWNhdGlvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsT0FBTyxFQUFDLFVBQVUsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDdEYsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDakQsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZDLE9BQU8sRUFBQyxVQUFVLEVBQUUsV0FBVyxFQUE0QixNQUFNLHNCQUFzQixDQUFDO0FBRXhGLE9BQU8sRUFBQyxRQUFRLEVBQWMsZUFBZSxFQUFnQixVQUFVLEVBQU0sU0FBUyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ3BHLE9BQU8sRUFBQyxVQUFVLEVBQVMsR0FBRyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEQsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFFcEQsT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sMkJBQTJCLENBQUM7QUFDakUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7Ozs7Ozs7O0FBRXpEOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsSUFBSSx5QkFBeUIsR0FBRyxJQUFJLGNBQWMsQ0FBUyxnQ0FBZ0MsQ0FBQyxDQUFDO0FBQ3BHLE1BQU0sQ0FBQyxJQUFJLDBCQUEwQixHQUFHLElBQUksY0FBYyxDQUFTLDRCQUE0QixDQUFDLENBQUM7QUFDakcsTUFBTSxDQUFDLElBQUksOEJBQThCLEdBQUcsSUFBSSxjQUFjLENBQVMsZ0NBQWdDLENBQUMsQ0FBQztBQUN6RyxNQUFNLENBQUMsSUFBSSw2QkFBNkIs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QU8sVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzVCLENBQUM7O0FBL1pEOzs7O0dBSUc7QUFDVyxxQ0FBZSxHQUFXLGNBQWMsQ0FBQztBQUV4QyxrQ0FBWSxHQUFXLGNBQWMsQ0FBQztBQUN0QywwQ0FBb0IsR0FBVyx1QkFBdUIsQ0FBQztBQUN2RCx1Q0FBaUIsR0FBVyxvQkFBb0IsQ0FBQztBQUNqRCxvQ0FBYyxHQUFXLHFCQUFxQixDQUFDO0FBQy9DLG9DQUFjLEdBQVcsZ0JBQWdCLENBQUM7bUhBYjlDLHFCQUFxQix3S0F5Q1osb0JBQW9CLGFBQ3BCLDBCQUEwQixhQUMxQiw2QkFBNkIsYUFDakIseUJBQXlCLDZCQUN6Qiw4QkFBOEIsNkJBQzlCLHFDQUFxQyw2QkFDckMscUNBQXFDLDZCQUNyQyxxQ0FBcUMsNkJBQ3JDLHlDQUF5Qyw2QkFDekMsc0NBQXNDLDZCQUN0QyxnQkFBZ0I7dUhBbkRyQyxxQkFBcUI7NEZBQXJCLHFCQUFxQjtrQkFEakMsVUFBVTs7MEJBMENJLE1BQU07MkJBQUMsb0JBQW9COzswQkFDM0IsTUFBTTsyQkFBQywwQkFBMEI7OzBCQUNqQyxNQUFNOzJCQUFDLDZCQUE2Qjs7MEJBQ3BDLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMseUJBQXlCOzswQkFDNUMsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyw4QkFBOEI7OzBCQUNqRCxRQUFROzswQkFBSSxNQUFNOzJCQUFDLHFDQUFxQzs7MEJBQ3hELFFBQVE7OzBCQUFJLE1BQU07MkJBQUMscUNBQXFDOzswQkFDeEQsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxxQ0FBcUM7OzBCQUN4RCxRQUFROzswQkFBSSxNQUFNOzJCQUFDLHlDQUF5Qzs7MEJBQzVELFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsc0NBQXNDOzswQkFDekQsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxnQkFBZ0IiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxyXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYgSHVudHNtYW4gQ2FuY2VyIEluc3RpdHV0ZSBhdCB0aGUgVW5pdmVyc2l0eSBvZiBVdGFoLCBDb25maWRlbnRpYWwgYW5kIFByb3ByaWV0YXJ5XHJcbiAqL1xyXG5pbXBvcnQge0luamVjdGFibGUsIEluamVjdGlvblRva2VuLCBJbmplY3QsIE9wdGlvbmFsLCBpc0Rldk1vZGV9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcbmltcG9ydCB7TG9jYXRpb25TdHJhdGVneX0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vblwiO1xyXG5pbXBvcnQge1JvdXRlcn0gZnJvbSBcIkBhbmd1bGFyL3JvdXRlclwiO1xyXG5pbXBvcnQge0h0dHBDbGllbnQsIEh0dHBIZWFkZXJzLCBIdHRwUmVxdWVzdCwgSHR0cFJlc3BvbnNlfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uL2h0dHBcIjtcclxuXHJcbmltcG9ydCB7aW50ZXJ2YWwsIE9ic2VydmFibGUsIEJlaGF2aW9yU3ViamVjdCwgU3Vic2NyaXB0aW9uLCB0aHJvd0Vycm9yLCBvZiwgZnJvbUV2ZW50fSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQge2NhdGNoRXJyb3IsIGZpcnN0LCBtYXB9IGZyb20gXCJyeGpzL29wZXJhdG9yc1wiO1xyXG5pbXBvcnQge0p3dEhlbHBlclNlcnZpY2V9IGZyb20gXCJAYXV0aDAvYW5ndWxhci1qd3RcIjtcclxuXHJcbmltcG9ydCB7QXV0aGVudGljYXRpb25Qcm92aWRlcn0gZnJvbSBcIi4vYXV0aGVudGljYXRpb24ucHJvdmlkZXJcIjtcclxuaW1wb3J0IHsgQ29vbExvY2FsU3RvcmFnZSB9IGZyb20gXCJAYW5ndWxhci1jb29sL3N0b3JhZ2VcIjtcclxuXHJcbi8qKlxyXG4gKiBUaGUgdG9rZW4gdXNlZCBmb3IgaW5qZWN0aW9uIG9mIHRoZSBzZXJ2ZXIgc2lkZSBlbmRwb2ludCBmb3IgdGhlIGN1cnJlbnRseSBhdXRoZW50aWNhdGVkIHN1YmplY3QuXHJcbiAqXHJcbiAqIEB0eXBlIHtJbmplY3Rpb25Ub2tlbn1cclxuICovXHJcbmV4cG9ydCBsZXQgQVVUSEVOVElDQVRJT05fU0VSVkVSX1VSTCA9IG5ldyBJbmplY3Rpb25Ub2tlbjxzdHJpbmc+KFwiYXV0aGVudGljYXRpb25fc2VydmVyX3Jlc3RfYXBpXCIpO1xyXG5leHBvcnQgbGV0IEFVVEhFTlRJQ0FUSU9OX0xPR09VVF9QQVRIID0gbmV3IEluamVjdGlvblRva2VuPHN0cmluZz4oXCJhdXRoZW50aWNhdGlvbl9sb2dvdXRfcGF0aFwiKTtcclxuZXhwb3J0IGxldCBBVVRIRU5USUNBVElPTl9ESVJFQ1RfRU5EUE9JTlQgPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nPihcImF1dGhlbnRpY2F0aW9uX2RpcmVjdF9lbmRwb2ludFwiKTtcclxuZXhwb3J0IGxldCBBVVRIRU5USUNBVElPTl9UT0tFTl9FTkRQT0lOVCA9IG5ldyBJbmplY3Rpb25Ub2tlbjxzdHJpbmc+KFwiYXV0aGVudGljYXRpb25fdG9rZW5fZW5kcG9pbnRcIik7XHJcbmV4cG9ydCBsZXQgQVVUSEVOVElDQVRJT05fUk9VVEUgPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nPihcImF1dGhlbnRpY2F0aW9uX3JvdXRlXCIpO1xyXG5leHBvcnQgbGV0IEFVVEhFTlRJQ0FUSU9OX01BWF9JTkFDVElWSVRZX01JTlVURVMgPSBuZXcgSW5qZWN0aW9uVG9rZW48bnVtYmVyPihcImF1dGhlbnRpY2F0aW9uX21heF9pbmFjdGl2aXR5XCIpO1xyXG5leHBvcnQgbGV0IEFVVEhFTlRJQ0FUSU9OX1VTRVJfQ09VTlRET1dOX1NFQ09ORFMgPSBuZXcgSW5qZWN0aW9uVG9rZW48bnVtYmVyPihcImF1dGhlbnRpY2F0aW9uX3VzZXJfY291bnRkb3duX3NlY29uZHNcIik7XHJcbmV4cG9ydCBsZXQgQVVUSEVOVElDQVRJT05fSURQX0lOQUNUSVZJVFlfTUlOVVRFUyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxudW1iZXI+KFwiYXV0aGVudGljYXRpb25faWRwX2luYWN0aXZpdHlfbWludXRlc1wiKTtcclxuZXhwb3J0IGxldCBBVVRIRU5USUNBVElPTl9VU0VfVUlfRVZFTlRTX0ZPUl9BQ1RJVklUWSA9IG5ldyBJbmplY3Rpb25Ub2tlbjxib29sZWFuPihcImF1dGhlbnRpY2F0aW9uX3VzZV91aV9ldmVudHNfZm9yX2FjdGl2aXR5XCIpO1xyXG5leHBvcnQgbGV0IEFVVEhFTlRJQ0FUSU9OX0FQUF9LRUVQX0FMSVZFX0VORFBPSU5UID0gbmV3IEluamVjdGlvblRva2VuPHN0cmluZz4oXCJhdXRoZW50aWNhdGlvbl9hcHBfa2VlcF9hbGl2ZV9lbmRwb2ludFwiKTtcclxuXHJcbi8qKlxyXG4gKiBAc2luY2UgMS4wLjBcclxuICovXHJcbkBJbmplY3RhYmxlKClcclxuZXhwb3J0IGNsYXNzIEF1dGhlbnRpY2F0aW9uU2VydmljZSB7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSBnZW5lcmljIGVycm9yIG1lc3NhZ2UgdXNlZCB3aGVuIGEgc2VydmVyIGVycm9yIGlzIHRocm93biB3aXRob3V0IGEgc3RhdHVzLlxyXG4gICAqXHJcbiAgICogQHR5cGUge3N0cmluZ31cclxuICAgKi9cclxuICBwdWJsaWMgc3RhdGljIEdFTkVSSUNfRVJSX01TRzogc3RyaW5nID0gXCJTZXJ2ZXIgZXJyb3JcIjtcclxuXHJcbiAgcHJpdmF0ZSBzdGF0aWMgQ09OVEVOVF9UWVBFOiBzdHJpbmcgPSBcIkNvbnRlbnQtVHlwZVwiO1xyXG4gIHByaXZhdGUgc3RhdGljIFNFQ19HT1ZfQ0xBU1NfSEVBREVSOiBzdHJpbmcgPSBcIlNlY3VyaXR5R292ZXJub3JDbGFzc1wiO1xyXG4gIHByaXZhdGUgc3RhdGljIFNFQ19HT1ZfSURfSEVBREVSOiBzdHJpbmcgPSBcIlNlY3VyaXR5R292ZXJub3JJZFwiO1xyXG4gIHByaXZhdGUgc3RhdGljIERFSURFTlRfSEVBREVSOiBzdHJpbmcgPSBcIkRlaWRlbnRpZmllZENvbnRleHRcIjtcclxuICBwcml2YXRlIHN0YXRpYyBMSU1JVEVEX0hFQURFUjogc3RyaW5nID0gXCJMaW1pdGVkQ29udGV4dFwiO1xyXG5cclxuICBwdWJsaWMgdXNlckNvdW50ZG93blNlY29uZHM6IG51bWJlciA9IDYwO1xyXG4gIHB1YmxpYyBpZHBJbmFjdGl2aXR5TWludXRlczogbnVtYmVyID0gNTtcclxuXHJcbiAgcHVibGljIGNvbnRlbnRUeXBlOiBzdHJpbmcgPSBcImFwcGxpY2F0aW9uL2pzb25cIjtcclxuICBwdWJsaWMgc2VjdXJpdHlHb3Zlcm5vckNsYXNzOiBzdHJpbmc7XHJcbiAgcHVibGljIHNlY3VyaXR5R292ZXJub3JJZDogbnVtYmVyO1xyXG4gIHB1YmxpYyBsaW1pdGVkQ29udGV4dDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIHB1YmxpYyBkZWlkZW50aWZpZWRDb250ZXh0OiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIHByaXZhdGUgbWF4Vmlld1Blcm1pc3Npb246IEJlaGF2aW9yU3ViamVjdDxcInZpZXdcIiB8IFwidmlld2lkZW50XCIgfCBcInZpZXdsaW1pdGVkXCI+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxcInZpZXdcIiB8IFwidmlld2lkZW50XCIgfCBcInZpZXdsaW1pdGVkXCI+KFwidmlld2lkZW50XCIpO1xyXG4gIHByaXZhdGUgX2lzQXV0aGVudGljYXRlZFN1YmplY3Q6IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xyXG4gIHByaXZhdGUgX3VzZXJJc0Fib3V0VG9UaW1lT3V0OiBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcclxuICBwcml2YXRlIF9yZWRpcmVjdFVybDogc3RyaW5nO1xyXG4gIHByaXZhdGUgX3JlZnJlc2hTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcclxuICBwcml2YXRlIF9sYXN0VXNlckludGVyYWN0aW9uOiBEYXRlO1xyXG4gIHByaXZhdGUgX21heEluYWN0aXZpdHlNaW51dGVzOiBudW1iZXIgPSAxMjA7XHJcbiAgcHJpdmF0ZSBfdWlFdmVudHM6IHN0cmluZ1tdID0gWydrZXlkb3duJywgJ2NsaWNrJywgJ3doZWVsJywgJ21vdXNlbW92ZSddO1xyXG5cclxuICBwcml2YXRlIGJhc2VVcmw6IHN0cmluZztcclxuICBwcml2YXRlIGNvbnRleHRSb290OiBzdHJpbmcgPSBcIlwiO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9odHRwOiBIdHRwQ2xpZW50LFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgX3JvdXRlcjogUm91dGVyLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgX2xvY2FsU3RvcmFnZVNlcnZpY2U6IENvb2xMb2NhbFN0b3JhZ2UsXHJcbiAgICAgICAgICAgICAgcHJpdmF0ZSBfand0SGVscGVyOiBKd3RIZWxwZXJTZXJ2aWNlLFxyXG4gICAgICAgICAgICAgIHByaXZhdGUgYXV0aGVudGljYXRpb25Qcm92aWRlcjogQXV0aGVudGljYXRpb25Qcm92aWRlcixcclxuICAgICAgICAgICAgICBASW5qZWN0KEFVVEhFTlRJQ0FUSU9OX1JPVVRFKSBwcml2YXRlIF9hdXRoZW50aWNhdGlvblJvdXRlOiBzdHJpbmcsXHJcbiAgICAgICAgICAgICAgQEluamVjdChBVVRIRU5USUNBVElPTl9MT0dPVVRfUEFUSCkgcHJpdmF0ZSBfbG9nb3V0UGF0aDogc3RyaW5nLFxyXG4gICAgICAgICAgICAgIEBJbmplY3QoQVVUSEVOVElDQVRJT05fVE9LRU5fRU5EUE9JTlQpIHByaXZhdGUgX3Rva2VuRW5kcG9pbnQ6IHN0cmluZyxcclxuICAgICAgICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEFVVEhFTlRJQ0FUSU9OX1NFUlZFUl9VUkwpIHByaXZhdGUgX3NlcnZlclVybDogc3RyaW5nLFxyXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoQVVUSEVOVElDQVRJT05fRElSRUNUX0VORFBPSU5UKSBwcml2YXRlIF9kaXJlY3RFbmRwb2ludDogc3RyaW5nLFxyXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoQVVUSEVOVElDQVRJT05fTUFYX0lOQUNUSVZJVFlfTUlOVVRFUykgcHJpdmF0ZSBfbWF4SW5hY3Rpdml0eTogbnVtYmVyLFxyXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoQVVUSEVOVElDQVRJT05fVVNFUl9DT1VOVERPV05fU0VDT05EUykgcHJpdmF0ZSBfdXNlckNvdW50ZG93blNlY29uZHM6IG51bWJlcixcclxuICAgICAgICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEFVVEhFTlRJQ0FUSU9OX0lEUF9JTkFDVElWSVRZX01JTlVURVMpIHByaXZhdGUgX2lkcEluYWN0aXZpdHlNaW51dGVzOiBudW1iZXIsXHJcbiAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChBVVRIRU5USUNBVElPTl9VU0VfVUlfRVZFTlRTX0ZPUl9BQ1RJVklUWSkgcHJpdmF0ZSBfdXNlVUlFdmVudHNGb3JBY3Rpdml0eTogYm9vbGVhbixcclxuICAgICAgICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KEFVVEhFTlRJQ0FUSU9OX0FQUF9LRUVQX0FMSVZFX0VORFBPSU5UKSBwcml2YXRlIF9rZWVwQWxpdmVFbmRwb2ludDogc3RyaW5nLFxyXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTG9jYXRpb25TdHJhdGVneSkgcHJpdmF0ZSBsb2NhdGlvblN0cmF0ZWd5OiBMb2NhdGlvblN0cmF0ZWd5KSB7XHJcbiAgICBpZiAoaXNEZXZNb2RlKCkpIHtcclxuICAgICAgY29uc29sZS5kZWJ1ZyhcIndpbmRvdy5sb2NhdGlvbi5ocmVmOiBcIiArIHdpbmRvdy5sb2NhdGlvbi5ocmVmKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAod2luZG93LmxvY2F0aW9uKSB7XHJcbiAgICAgIGxldCBwYXJ0czogc3RyaW5nW10gPSB3aW5kb3cubG9jYXRpb24uaHJlZi5zcGxpdChcIi9cIik7XHJcbiAgICAgIHRoaXMuYmFzZVVybCA9IHBhcnRzWzBdICsgXCIvL1wiICsgcGFydHNbMl07XHJcbiAgICAgIGlmIChwYXJ0cy5sZW5ndGggPiAzKSB7XHJcbiAgICAgICAgdGhpcy5jb250ZXh0Um9vdCA9IHBhcnRzWzNdO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuX2xvY2FsU3RvcmFnZVNlcnZpY2UuZ2V0SXRlbShcIm1heFZpZXdQZXJtaXNzaW9uXCIpKSB7XHJcbiAgICAgIHRoaXMubWF4Vmlld1Blcm1pc3Npb24ubmV4dCg8XCJ2aWV3XCIgfCBcInZpZXdpZGVudFwiIHwgXCJ2aWV3bGltaXRlZFwiPnRoaXMuX2xvY2FsU3RvcmFnZVNlcnZpY2UuZ2V0SXRlbShcIm1heFZpZXdQZXJtaXNzaW9uXCIpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoX21heEluYWN0aXZpdHkpIHtcclxuICAgICAgdGhpcy5fbWF4SW5hY3Rpdml0eU1pbnV0ZXMgPSBfbWF4SW5hY3Rpdml0eTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoX3VzZXJDb3VudGRvd25TZWNvbmRzKSB7XHJcbiAgICAgIHRoaXMudXNlckNvdW50ZG93blNlY29uZHMgPSBfdXNlckNvdW50ZG93blNlY29uZHM7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKF9pZHBJbmFjdGl2aXR5TWludXRlcykge1xyXG4gICAgICB0aGlzLmlkcEluYWN0aXZpdHlNaW51dGVzID0gX2lkcEluYWN0aXZpdHlNaW51dGVzO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICAvL1N1YnNjcmliZSB0byBVSSBldmVudHMgZm9yIHVzZXIgYWN0aXZpdHlcclxuICAgIGlmIChfdXNlVUlFdmVudHNGb3JBY3Rpdml0eSkge1xyXG4gICAgICB0aGlzLnN1YnNjcmliZVRvVUlBY3Rpdml0eSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuaGFzVmFsaWRDb25maWcoKTtcclxuXHJcbiAgICAvL1RoZXJlIGNvdWxkIGJlIGEgbm9uLWV4cGlyZWQgdG9rZW4gaW4gbG9jYWwgc3RvcmFnZS5cclxuICAgIGxldCB0b2tlbjogc3RyaW5nID0gdGhpcy5hdXRoZW50aWNhdGlvblByb3ZpZGVyLmF1dGhUb2tlbjtcclxuICAgIHRoaXMuc3RvcmVUb2tlbih0b2tlbik7XHJcbiAgfVxyXG5cclxuICBnZXRCYXNlVXJsKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gKHRoaXMuYmFzZVVybCkgPyB0aGlzLmJhc2VVcmwgOiBcIlwiO1xyXG4gIH1cclxuXHJcbiAgZ2V0Q29udGV4dFJvb3QoKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aGlzLmNvbnRleHRSb290O1xyXG4gIH1cclxuXHJcbiAgZ2V0SGVhZGVycyhyZXE6IEh0dHBSZXF1ZXN0PGFueT4pOiBIdHRwSGVhZGVycyB7XHJcbiAgICBsZXQgaGVhZGVyczogSHR0cEhlYWRlcnMgPSByZXEuaGVhZGVycztcclxuXHJcbiAgICAvL0Rvbid0IHNldCBjb250ZW50IHR5cGUgaWYgYWxyZWFkeSBzZXRcclxuICAgIGlmICghcmVxLmhlYWRlcnMuZ2V0KEF1dGhlbnRpY2F0aW9uU2VydmljZS5DT05URU5UX1RZUEUpKSB7XHJcbiAgICAgIGhlYWRlcnMgPSBoZWFkZXJzLnNldChBdXRoZW50aWNhdGlvblNlcnZpY2UuQ09OVEVOVF9UWVBFLCB0aGlzLmNvbnRlbnRUeXBlLnRvU3RyaW5nKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChoZWFkZXJzLmdldChBdXRoZW50aWNhdGlvblNlcnZpY2UuU0VDX0dPVl9DTEFTU19IRUFERVIpID09PSBcIlwiKSB7XHJcbiAgICAgIGhlYWRlcnMgPSBoZWFkZXJzLmRlbGV0ZShBdXRoZW50aWNhdGlvblNlcnZpY2UuU0VDX0dPVl9DTEFTU19IRUFERVIpO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLnNlY3VyaXR5R292ZXJub3JDbGFzcyAmJiAhaGVhZGVycy5nZXQoQXV0aGVudGljYXRpb25TZXJ2aWNlLlNFQ19HT1ZfQ0xBU1NfSEVBREVSKSkge1xyXG4gICAgICBoZWFkZXJzID0gaGVhZGVycy5zZXQoQXV0aGVudGljYXRpb25TZXJ2aWNlLlNFQ19HT1ZfQ0xBU1NfSEVBREVSLCB0aGlzLnNlY3VyaXR5R292ZXJub3JDbGFzcyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGhlYWRlcnMuZ2V0KEF1dGhlbnRpY2F0aW9uU2VydmljZS5TRUNfR09WX0lEX0hFQURFUikgPT09IFwiXCIpIHtcclxuICAgICAgaGVhZGVycyA9IGhlYWRlcnMuZGVsZXRlKEF1dGhlbnRpY2F0aW9uU2VydmljZS5TRUNfR09WX0lEX0hFQURFUik7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMuc2VjdXJpdHlHb3Zlcm5vcklkICYmICFoZWFkZXJzLmdldChBdXRoZW50aWNhdGlvblNlcnZpY2UuU0VDX0dPVl9JRF9IRUFERVIpKSB7XHJcbiAgICAgIGhlYWRlcnMgPSBoZWFkZXJzLnNldChBdXRoZW50aWNhdGlvblNlcnZpY2UuU0VDX0dPVl9JRF9IRUFERVIsIHRoaXMuc2VjdXJpdHlHb3Zlcm5vcklkLnRvU3RyaW5nKCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGhlYWRlcnMgPSBoZWFkZXJzLnNldChBdXRoZW50aWNhdGlvblNlcnZpY2UuREVJREVOVF9IRUFERVIsIHRoaXMuZGVpZGVudGlmaWVkQ29udGV4dC50b1N0cmluZygpKTtcclxuICAgIGhlYWRlcnMgPSBoZWFkZXJzLnNldChBdXRoZW50aWNhdGlvblNlcnZpY2UuTElNSVRFRF9IRUFERVIsIHRoaXMubGltaXRlZENvbnRleHQudG9TdHJpbmcoKSk7XHJcblxyXG4gICAgcmV0dXJuIGhlYWRlcnM7XHJcbiAgfVxyXG5cclxuICBnZXQgYXV0aGVudGljYXRpb25Ub2tlbktleSgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuYXV0aGVudGljYXRpb25Qcm92aWRlci5hdXRoZW50aWNhdGlvblRva2VuS2V5O1xyXG4gIH1cclxuXHJcbiAgZ2V0IGF1dGhUb2tlbigpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuYXV0aGVudGljYXRpb25Qcm92aWRlci5hdXRoVG9rZW47XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgdXBkYXRlVXNlckFjdGl2aXR5KCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuX2lzQXV0aGVudGljYXRlZFN1YmplY3QudmFsdWUpIHtcclxuICAgICAgdGhpcy5fbGFzdFVzZXJJbnRlcmFjdGlvbiA9IG5ldyBEYXRlKCk7XHJcbiAgICAgIHRoaXMuX3VzZXJJc0Fib3V0VG9UaW1lT3V0Lm5leHQoZmFsc2UpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQSBtdXRhdG9yIGZvciBpZGVudGlmeWluZyB0aGUgY2xpZW50cyBvcmlnaW5hbCByZXF1ZXN0IGxvY2F0aW9uLiBTZXR0aW5nIHRoaXMgdmFsdWUgd2lsbCBpbmZsdWVuY2UgdGhlIGVuZCBsb2NhdGlvblxyXG4gICAqIG5hdmlnYXRlZCB0byBieSB7QGxpbmsgI25hdmlnYXRlVG9QYXRofS5cclxuICAgKlxyXG4gICAqIEBwYXJhbSByZWRpcmVjdFVybCBsb2NhdGlvbiBvZiB0aGUgdXNlcnMgcmVxdWVzdCBiZWZvcmUgYXV0aGVudGljYXRpb25cclxuICAgKi9cclxuICBzZXQgcmVkaXJlY3RVcmwocmVkaXJlY3RVcmw6IHN0cmluZykge1xyXG4gICAgdGhpcy5fcmVkaXJlY3RVcmwgPSByZWRpcmVjdFVybDtcclxuICB9XHJcblxyXG4gIGdldCByZWRpcmVjdFVybCgpIHtcclxuICAgIHJldHVybiB0aGlzLl9yZWRpcmVjdFVybDtcclxuICB9XHJcblxyXG4gIHJlcXVlc3RBY2Nlc3NUb2tlbihyZWRpcmVjdE9uU3VjY2VzczogYm9vbGVhbik6IHZvaWQge1xyXG5cclxuICAgIHRoaXMuX2h0dHAuZ2V0KHRoaXMudG9rZW5Mb2NhdGlvbigpLCB7d2l0aENyZWRlbnRpYWxzOiB0cnVlfSlcclxuICAgICAgLnN1YnNjcmliZShcclxuICAgICAgICAocmVzcG9uc2U6IGFueSkgPT4ge1xyXG4gICAgICAgICAgdGhpcy5zdG9yZVRva2VuKHJlc3BvbnNlLmF1dGhfdG9rZW4pO1xyXG4gICAgICAgICAgaWYgKHJlZGlyZWN0T25TdWNjZXNzKSB7XHJcbiAgICAgICAgICAgIHRoaXMucHJvY2VlZElmQXV0aGVudGljYXRlZCgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAvL1Rva2VuIHJlZnJlc2ggZmFpbGVkLlxyXG4gICAgICAgICAgdGhpcy5sb2dvdXQodHJ1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICApO1xyXG4gIH1cclxuICBcclxuICBtYWtlS2VlcEFsaXZlUmVxdWVzdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuX2h0dHAuZ2V0KHRoaXMua2VlcEFsaXZlTG9jYXRpb24oKSwge3dpdGhDcmVkZW50aWFsczogdHJ1ZX0pLnN1YnNjcmliZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVmVyaWZpZXMgd2hldGhlciBvciBub3QgYSBjdXJyZW50IHVzZXIgc2Vzc2lvbiBleGlzdHMuXHJcbiAgICpcclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZTxib29sZWFuPn0gZXZhbHVhdGVzIHRvIHRydWUgaWYgdGhlIHVzZXIgaXMgYXV0aGVudGljYXRlZCwgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAqL1xyXG4gIGlzQXV0aGVudGljYXRlZCgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcclxuICAgIHJldHVybiB0aGlzLl9pc0F1dGhlbnRpY2F0ZWRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xyXG4gIH1cclxuXHJcbiAgaXNBYm91dFRvVGltZU91dCgpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcclxuICAgIHJldHVybiB0aGlzLl91c2VySXNBYm91dFRvVGltZU91dC5hc09ic2VydmFibGUoKTtcclxuICB9XHJcblxyXG4gIGdldFRpbWVvdXRTdGFydCgpOiBudW1iZXIge1xyXG4gICAgaWYgKHRoaXMuX2xhc3RVc2VySW50ZXJhY3Rpb24pIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX2xhc3RVc2VySW50ZXJhY3Rpb24udmFsdWVPZigpICsgKCgodGhpcy5fbWF4SW5hY3Rpdml0eU1pbnV0ZXMgKiA2MCkgLSB0aGlzLnVzZXJDb3VudGRvd25TZWNvbmRzKSAqIDEwMDApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdG9rZW5Mb2NhdGlvbigpOiBzdHJpbmcge1xyXG4gICAgaWYgKHRoaXMuX3NlcnZlclVybCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fc2VydmVyVXJsICsgdGhpcy5fdG9rZW5FbmRwb2ludDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl90b2tlbkVuZHBvaW50O1xyXG4gICAgfVxyXG4gIH1cclxuICBcclxuICBrZWVwQWxpdmVMb2NhdGlvbigpOiBzdHJpbmcge1xyXG4gICAgaWYgKHRoaXMuX3NlcnZlclVybCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5fc2VydmVyVXJsICsgdGhpcy5fa2VlcEFsaXZlRW5kcG9pbnQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gdGhpcy5fa2VlcEFsaXZlRW5kcG9pbnQ7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBkaXJlY3RMb2dpbkxvY2F0aW9uKCk6IHN0cmluZyB7XHJcbiAgICBpZiAodGhpcy5fc2VydmVyVXJsKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9zZXJ2ZXJVcmwgKyB0aGlzLl9kaXJlY3RFbmRwb2ludDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9kaXJlY3RFbmRwb2ludDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGxvZ291dExvY2F0aW9uKCk6IHN0cmluZyB7XHJcbiAgICBpZiAodGhpcy5fc2VydmVyVXJsKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9zZXJ2ZXJVcmwgKyB0aGlzLl9sb2dvdXRQYXRoO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIHRoaXMuX2xvZ291dFBhdGg7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBIGZ1bmN0aW9uIHRvIGF1dGhlbnRpY2F0ZWQgdGhlIHVzZXIgd2l0aCB0aGUgcHJvdmlkZWQgY3JlZGVudGlhbHMuIEZhaWx1cmUgcmVzdWx0cyBpbiBhbiBlcnJvciB0aGF0IGRlc2NyaWJlcyB0aGVcclxuICAgKiBzZXJ2ZXIgcmVzcG9uc2UgKHN0YXR1cyBhbmQgc3RhdHVzIG1lc3NhZ2UpIGFuZCBzaG91bGQgYmUgYWN0aW9uYWJsZSBieSB0aGUgY2xpZW50IGFwcGxpY2F0aW9uLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIHVzZXJuYW1lIG9mIHRoZSBhdXRoZW50aWNhdGluZyB1c2VyIHRvIHZlcmlmeVxyXG4gICAqIEBwYXJhbSBwYXNzd29yZCBvZiB0aGUgYXV0aGVudGljYXRpbmcgdXNlciB0byB2ZXJpZnlcclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZTxSPn0gZGVzY3JpYmluZyB0aGUgcmVzdWx0IG9mIHRoZSBsb2dpbiBhY3Rpb24sIHRydWUgb3IgYW4gZXJyb3JcclxuICAgKi9cclxuICBsb2dpbihfdXNlcm5hbWU6IHN0cmluZywgX3Bhc3N3b3JkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcclxuICAgIHJldHVybiB0aGlzLl9odHRwLnBvc3QoXHJcbiAgICAgIHRoaXMuZGlyZWN0TG9naW5Mb2NhdGlvbigpLFxyXG4gICAgICB7dXNlcm5hbWU6IF91c2VybmFtZSwgcGFzc3dvcmQ6IF9wYXNzd29yZH0sXHJcbiAgICAgIHtvYnNlcnZlOiBcInJlc3BvbnNlXCJ9XHJcbiAgICApLnBpcGUobWFwKChyZXNwOiBIdHRwUmVzcG9uc2U8YW55PikgPT4ge1xyXG4gICAgICBpZiAocmVzcC5zdGF0dXMgPT09IDIwMSkge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkF1dGhlbnRpY2F0aW9uIGZhaWxlZC4gXCIgKyByZXNwLnN0YXR1cyArIFwiOiBcIiArIHJlc3Auc3RhdHVzVGV4dCk7XHJcbiAgICAgIH1cclxuICAgIH0pLFxyXG4gICAgICBjYXRjaEVycm9yKHRoaXMuaGFuZGxlRXJyb3IpKTtcclxuICB9XHJcblxyXG5cclxuICBjbGVhckxvZ2luKCk6IE9ic2VydmFibGU8UmVzcG9uc2U+IHtcclxuICAgIC8vRnJvbnQtZW5kIGxvZ291dFxyXG4gICAgdHJ5IHtcclxuICAgICAgdGhpcy5fbG9jYWxTdG9yYWdlU2VydmljZS5yZW1vdmVJdGVtKHRoaXMuYXV0aGVudGljYXRpb25Qcm92aWRlci5hdXRoZW50aWNhdGlvblRva2VuS2V5KTtcclxuICAgICAgdGhpcy51bnN1YnNjcmliZUZyb21Ub2tlblJlZnJlc2goKTtcclxuICAgICAgdGhpcy5faXNBdXRoZW50aWNhdGVkU3ViamVjdC5uZXh0KGZhbHNlKTtcclxuICAgICAgdGhpcy5fdXNlcklzQWJvdXRUb1RpbWVPdXQubmV4dChmYWxzZSk7XHJcbiAgICB9IGNhdGNoIChFcnJvcikge1xyXG4gICAgfVxyXG5cclxuICAgIC8vQmFjay1lbmQgbG9nb3V0XHJcbiAgICBsZXQgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycygpLnNldChBdXRoZW50aWNhdGlvblNlcnZpY2UuQ09OVEVOVF9UWVBFLCBcInRleHQvcGxhaW5cIik7XHJcbiAgICByZXR1cm4gPE9ic2VydmFibGU8UmVzcG9uc2U+PnRoaXMuX2h0dHAuZ2V0KHRoaXMubG9nb3V0TG9jYXRpb24oKSwge2hlYWRlcnM6IGhlYWRlcnN9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEEgZnVuY3Rpb24gdG8gc2lnbmFsIHRoZSB0ZXJtaW5hdGlvbiBvZiB0aGUgY3VycmVudCBzZXNzaW9uLiBJbnZva2luZyB0aGlzIGZ1bmN0aW9uIHdpbGwgY2xlYW4gdXAgYW55IHJlbGV2YW50IHN0YXRlXHJcbiAgICogcmVsYXRlZCB0byB0aGUgbGFzdCBhY3RpdmUgc2Vzc2lvbi5cclxuICAgKi9cclxuICBsb2dvdXQoa2VlcEN1cnJlbnRSb3V0ZTogYm9vbGVhbiA9IGZhbHNlKTogdm9pZCB7XHJcbiAgICAvL1ByZXZlbnQgbG9nb3V0IGlmIGFscmVhZHkgb24gYXV0aGVudGljYXRpb24gcm91dGUuIERvaW5nIG90aGVyd2lzZSBzY3Jld3MgdXAgU0FNTFxyXG4gICAgaWYgKCEgdGhpcy5fcm91dGVyLnJvdXRlclN0YXRlIHx8IHRoaXMuX3JvdXRlci5yb3V0ZXJTdGF0ZS5zbmFwc2hvdC51cmwgIT09IHRoaXMuX2F1dGhlbnRpY2F0aW9uUm91dGUpIHtcclxuICAgICAgdGhpcy5fcmVkaXJlY3RVcmwgPSAoa2VlcEN1cnJlbnRSb3V0ZSAmJiB0aGlzLl9yb3V0ZXIucm91dGVyU3RhdGUgJiYgdGhpcy5fcm91dGVyLnJvdXRlclN0YXRlLnNuYXBzaG90KSA/IHRoaXMuX3JvdXRlci5yb3V0ZXJTdGF0ZS5zbmFwc2hvdC51cmwgOiBcIlwiO1xyXG5cclxuICAgICAgaWYgKHRoaXMuX3JlZGlyZWN0VXJsLnN0YXJ0c1dpdGgoXCIvXCIpKSB7XHJcbiAgICAgICAgdGhpcy5fcmVkaXJlY3RVcmwgPSB0aGlzLl9yZWRpcmVjdFVybC5zdWJzdHJpbmcoMSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHRoaXMuY2xlYXJMb2dpbigpLnN1YnNjcmliZShcclxuICAgICAgICAocmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKHRoaXMuX3JlZGlyZWN0VXJsKTtcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICB3aW5kb3cubG9jYXRpb24ucmVwbGFjZSh0aGlzLl9yZWRpcmVjdFVybCk7XHJcbiAgICAgICAgfVxyXG4gICAgICApO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgc3RvcmVUb2tlbih0b2tlbjogc3RyaW5nKTogdm9pZCB7XHJcbiAgICBsZXQgdmFsaWQgPSB0aGlzLnZhbGlkYXRlVG9rZW4odG9rZW4pO1xyXG5cclxuICAgIC8vIHVuc3Vic2NyaWJlIGZyb20gcmVmZXNoIGJlZm9yZSB3ZSBkZWNpZGUgd2V0aGVyIHRvIHJlc3Vic2NyaWJlXHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlRnJvbVRva2VuUmVmcmVzaCgpO1xyXG5cclxuICAgIGlmICh2YWxpZCkge1xyXG4gICAgICB0aGlzLl9sb2NhbFN0b3JhZ2VTZXJ2aWNlLnNldEl0ZW0odGhpcy5hdXRoZW50aWNhdGlvblByb3ZpZGVyLmF1dGhlbnRpY2F0aW9uVG9rZW5LZXksIHRva2VuKTtcclxuICAgICAgdGhpcy5zdWJzY3JpYmVUb1Rva2VuUmVmcmVzaCh0b2tlbik7XHJcblxyXG4gICAgICAvL0NoYW5nZSB0aGUgQmVoYXZpb3JTdWJqZWN0IGlmIHRoZSB1c2VyIHdhcyBub3QgcHJldmlvdXNseSBhdXRoZW50aWNhdGVkLlxyXG4gICAgICAvL1NpbmNlIG90aGVyIGNvZGUgbWF5IGJlIHN1YnNjcmliaW5nIHRvIHRoaXMgb2JzZXJ2YWJsZSwgd2UgZG9uJ3Qgd2FudCB0byBjYXVzZSBuZXcgZXZlbnRzIHRvIGZpcmUgaWYganVzdCByZWZyZXNoaW5nIHRoZSBKV1QuXHJcbiAgICAgIGlmICghIHRoaXMuX2lzQXV0aGVudGljYXRlZFN1YmplY3QudmFsdWUpIHtcclxuICAgICAgICB0aGlzLl9pc0F1dGhlbnRpY2F0ZWRTdWJqZWN0Lm5leHQodHJ1ZSk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuX2xvY2FsU3RvcmFnZVNlcnZpY2UucmVtb3ZlSXRlbSh0aGlzLmF1dGhlbnRpY2F0aW9uUHJvdmlkZXIuYXV0aGVudGljYXRpb25Ub2tlbktleSk7XHJcbiAgICAgIHRoaXMuX2lzQXV0aGVudGljYXRlZFN1YmplY3QubmV4dChmYWxzZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcm9jZWVkSWZBdXRoZW50aWNhdGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgaWYgKGlzRGV2TW9kZSgpKSB7XHJcbiAgICAgIGNvbnNvbGUuZGVidWcoXCJBdXRoZW50aWNhdGlvblNlcnZpY2UucHJvY2VlZElmQXV0aGVudGljYXRlZDogXCIgKyB0aGlzLl9yZWRpcmVjdFVybCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuX2lzQXV0aGVudGljYXRlZFN1YmplY3QudmFsdWUpIHtcclxuICAgICAgLy9Mb2dpbiBjb3VudHMgYXMgdXNlciBhY3Rpdml0eSwgdG9vXHJcbiAgICAgIHRoaXMudXBkYXRlVXNlckFjdGl2aXR5KCk7XHJcblxyXG4gICAgICBpZiAodGhpcy5fcmVkaXJlY3RVcmwgJiYgdGhpcy5fcmVkaXJlY3RVcmwgJiYgdGhpcy5fcmVkaXJlY3RVcmwgIT09IFwiXCIpIHtcclxuICAgICAgICB0aGlzLl9yb3V0ZXIubmF2aWdhdGVCeVVybCh0aGlzLl9yZWRpcmVjdFVybCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5fcm91dGVyLm5hdmlnYXRlKFtcIlwiXSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdmFsaWRhdGVUb2tlbih0b2tlbjogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gKHRva2VuICYmICF0aGlzLl9qd3RIZWxwZXIuaXNUb2tlbkV4cGlyZWQodG9rZW4pKTtcclxuICB9XHJcbiAgXHJcbiAgc3Vic2NyaWJlVG9VSUFjdGl2aXR5KCl7XHJcbiAgICB0aGlzLl91aUV2ZW50cy5mb3JFYWNoKGV2ZW50ID0+XHJcbiAgICAgIGZyb21FdmVudChkb2N1bWVudCwgZXZlbnQpLnN1YnNjcmliZShfID0+IHtcclxuICAgICAgICAvL09ubHkgdXBkYXRlIGFjdGl2aXR5IG9uIFVJIGV2ZW50IGlmIG5vdCBhbHJlYWR5IGFib3V0IHRvIHRpbWUgb3V0LiBDb3VudGVyIGludHVpdGl2ZSwgYnV0IGluIHRoaXMgY2FzZSB3ZSBzaG91bGQgaGF2ZSA2MCBzZWNvbmQgY291bnQtZG93biBkaWFsb2cgb3Blbi5cclxuICAgICAgICBpZiAodGhpcy5fdXNlcklzQWJvdXRUb1RpbWVPdXQuZ2V0VmFsdWUoKSAhPT0gdHJ1ZSkge1xyXG4gICAgICAgICAgdGhpcy51cGRhdGVVc2VyQWN0aXZpdHkoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pXHJcbiAgICApOyAgICBcclxuICB9XHJcblxyXG4gIHN1YnNjcmliZVRvVG9rZW5SZWZyZXNoKHRva2VuOiBhbnkpOiB2b2lkIHtcclxuICAgIGxldCBleHAgPSB0aGlzLl9qd3RIZWxwZXIuZ2V0VG9rZW5FeHBpcmF0aW9uRGF0ZSh0b2tlbik7XHJcblxyXG4gICAgLy8gVXNlIGEgdGltZXIgdG8gcGVyaW9kaWNhbGx5IGNoZWNrIHRpbWVvdXRzXHJcbiAgICB0aGlzLl9yZWZyZXNoU3Vic2NyaXB0aW9uID0gaW50ZXJ2YWwoMTAwMClcclxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XHJcblxyXG4gICAgICAgIC8vIElmIGEgdGFiIGlzIGluYWN0aXZlIHdlIGNhbid0IGtub3cgaWYgb3VyIHRpbWVyIGlzIGFjY3VyYXRlXHJcbiAgICAgICAgLy8gc28gd2hlbiB0aGUgaW50ZXJ2YWwgaGl0cyBjaGVjayBhZ2FpbnN0IHRpbWVzdGFtcHNcclxuICAgICAgICBpZiAodGhpcy5faXNBdXRoZW50aWNhdGVkU3ViamVjdC52YWx1ZSAmJiBEYXRlLm5vdygpID4gdGhpcy5nZXRUaW1lb3V0U3RhcnQoKSkge1xyXG4gICAgICAgICAgLy9Eb24ndCB1cGRhdGUgdGhlIHN1YmplY3QgbW9yZSB0aGFuIG9uY2UhIERvaW5nIHNvIGluaXRpYWxpemVzIG1vcmUgdGhhbiBvbmUgY291bnRkb3duIHRpbWVyIVxyXG4gICAgICAgICAgaWYgKHRoaXMuX3VzZXJJc0Fib3V0VG9UaW1lT3V0LmdldFZhbHVlKCkgIT09IHRydWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fdXNlcklzQWJvdXRUb1RpbWVPdXQubmV4dCh0cnVlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGNoZWNrIGZvciByZWZyZXNoIHRva2VuXHJcbiAgICAgICAgbGV0IG1zVG9FeHBpcnkgPSAoZXhwLnZhbHVlT2YoKSAtIG5ldyBEYXRlKCkudmFsdWVPZigpKTtcclxuXHJcbiAgICAgICAgLy8gUmVmcmVzaCA2MCBzZWNvbmRzIGJlZm9yZSBleHBpcnlcclxuICAgICAgICBpZiAobXNUb0V4cGlyeSA8PSA2MDAwMCkge1xyXG4gICAgICAgICAgdGhpcy5yZWZyZXNoVG9rZW5JZlVzZXJJc0FjdGl2ZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgfVxyXG5cclxuICB1bnN1YnNjcmliZUZyb21Ub2tlblJlZnJlc2goKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5fcmVmcmVzaFN1YnNjcmlwdGlvbiAmJiAhIHRoaXMuX3JlZnJlc2hTdWJzY3JpcHRpb24uY2xvc2VkKSB7XHJcbiAgICAgIHRoaXMuX3JlZnJlc2hTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldE1heFZpZXdQZXJtaXNzaW9uKCk6IFwidmlld1wiIHwgXCJ2aWV3aWRlbnRcIiB8IFwidmlld2xpbWl0ZWRcIiB7XHJcbiAgICByZXR1cm4gdGhpcy5tYXhWaWV3UGVybWlzc2lvbi5nZXRWYWx1ZSgpO1xyXG4gIH1cclxuXHJcbiAgZ2V0TWF4Vmlld1Blcm1pc3Npb25TdWJqZWN0KCk6IEJlaGF2aW9yU3ViamVjdDxcInZpZXdcIiB8IFwidmlld2lkZW50XCIgfCBcInZpZXdsaW1pdGVkXCI+IHtcclxuICAgIHJldHVybiB0aGlzLm1heFZpZXdQZXJtaXNzaW9uO1xyXG4gIH1cclxuXHJcbiAgc2V0TWF4Vmlld1Blcm1pc3Npb24obWF4Vmlld1Blcm1pc3Npb246IFwidmlld1wiIHwgXCJ2aWV3aWRlbnRcIiB8IFwidmlld2xpbWl0ZWRcIik6IHZvaWQge1xyXG4gICAgdGhpcy5fbG9jYWxTdG9yYWdlU2VydmljZS5zZXRJdGVtKFwibWF4Vmlld1Blcm1pc3Npb25cIiwgbWF4Vmlld1Blcm1pc3Npb24pO1xyXG4gICAgdGhpcy5tYXhWaWV3UGVybWlzc2lvbi5uZXh0KG1heFZpZXdQZXJtaXNzaW9uKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgcmVmcmVzaFRva2VuSWZVc2VySXNBY3RpdmUoKTogdm9pZCB7XHJcbiAgICAvL09ubHkgcmVmcmVzaCBpZiB0aGUgdXNlciBoYXMgYmVlbiBhY3RpdmVcclxuICAgIGlmICh0aGlzLl9sYXN0VXNlckludGVyYWN0aW9uICYmICgobmV3IERhdGUoKS52YWx1ZU9mKCkgLSB0aGlzLl9sYXN0VXNlckludGVyYWN0aW9uLnZhbHVlT2YoKSkgPD0gKHRoaXMuX21heEluYWN0aXZpdHlNaW51dGVzICogNjAgKiAxMDAwKSkpIHtcclxuICAgICAgLy9SZWZyZXNoIHRoZSBKV1RcclxuICAgICAgdGhpcy5yZXF1ZXN0QWNjZXNzVG9rZW4oZmFsc2UpO1xyXG4gICAgICBcclxuICAgICAgLy9NaWdodCBhcyB3ZWxsIG1ha2UgYXBwbGljYXRpb24ga2VlcCBhbGl2ZSByZXF1ZXN0cyBhdCB0aGUgc2FtZSB0aW1lIGFzIHJlZnJlc2hpbmcgdG9rZW5zIC0gbW9yZSBlZmZpY2llbnQgJiBwcm9iYWJseSBuZWVkcyBzYW1lIGxvZ2ljXHJcbiAgICAgIGlmICh0aGlzLl9rZWVwQWxpdmVFbmRwb2ludCkge1xyXG4gICAgICAgIHRoaXMubWFrZUtlZXBBbGl2ZVJlcXVlc3QoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBoYXNWYWxpZENvbmZpZygpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLl90b2tlbkVuZHBvaW50ID09IG51bGwgJiYgKHRoaXMuX3NlcnZlclVybCA9PT0gbnVsbCB8fCB0aGlzLl9sb2dvdXRQYXRoID09PSBudWxsKSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJCVUcgQUxFUlQhIEludmFsaWQgQXV0aGVudGljYXRpb25TZXJ2aWNlIGNvbmZpZ3VyYXRpb24uIE5vIHZhbGlkIGNvbmZpZ3VyYXRpb24gZm9yIGF1dGhlbnRpY2F0aW9uIGVuZHBvaW50KHMpLlwiKTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLl9sb2NhbFN0b3JhZ2VTZXJ2aWNlID09PSBudWxsIHx8IHRoaXMuYXV0aGVudGljYXRpb25Qcm92aWRlci5hdXRoZW50aWNhdGlvblRva2VuS2V5ID09PSBudWxsKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkJVRyBBTEVSVCEgSW52YWxpZCBBdXRoZW50aWNhdGlvblNlcnZpY2UgY29uZmlndXJhdGlvbi4gTm8gdmFsaWQgY29uZmlndXJhdGlvbiBmb3IgbG9jYWwgc3RvcmFnZVwiKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgaGFuZGxlRXJyb3IoZXJyb3I6IGFueSkgOiBPYnNlcnZhYmxlPG5ldmVyPiB7XHJcbiAgICBsZXQgZXJyTXNnID0gKGVycm9yLm1lc3NhZ2UpID8gZXJyb3IubWVzc2FnZSA6IEF1dGhlbnRpY2F0aW9uU2VydmljZS5HRU5FUklDX0VSUl9NU0c7XHJcbiAgICByZXR1cm4gdGhyb3dFcnJvcihlcnJNc2cpO1xyXG4gIH1cclxufVxyXG4iXX0=
|
package/esm2020/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ export { AuthenticationModule } from "./authentication.module";
|
|
|
2
2
|
/**
|
|
3
3
|
* The injection tokens for service configuration.
|
|
4
4
|
*/
|
|
5
|
-
export { AUTHENTICATION_LOGOUT_PATH, AUTHENTICATION_SERVER_URL, AUTHENTICATION_TOKEN_ENDPOINT, AUTHENTICATION_DIRECT_ENDPOINT, AUTHENTICATION_ROUTE, AUTHENTICATION_MAX_INACTIVITY_MINUTES, AUTHENTICATION_USER_COUNTDOWN_SECONDS, AUTHENTICATION_IDP_INACTIVITY_MINUTES } from "./authentication.service";
|
|
5
|
+
export { AUTHENTICATION_LOGOUT_PATH, AUTHENTICATION_SERVER_URL, AUTHENTICATION_TOKEN_ENDPOINT, AUTHENTICATION_DIRECT_ENDPOINT, AUTHENTICATION_ROUTE, AUTHENTICATION_MAX_INACTIVITY_MINUTES, AUTHENTICATION_USER_COUNTDOWN_SECONDS, AUTHENTICATION_IDP_INACTIVITY_MINUTES, AUTHENTICATION_USE_UI_EVENTS_FOR_ACTIVITY, AUTHENTICATION_APP_KEEP_ALIVE_ENDPOINT } from "./authentication.service";
|
|
6
6
|
export { AUTHENTICATION_TOKEN_KEY } from "./authentication.provider";
|
|
7
7
|
export { AuthenticationComponent } from "./authentication.component";
|
|
8
8
|
export { DirectLoginComponent } from "./directlogin.component";
|
|
@@ -10,4 +10,4 @@ export { RouteGuardService } from "./route-guard.service";
|
|
|
10
10
|
export { AuthenticationService } from "./authentication.service";
|
|
11
11
|
export { TimeoutNotificationComponent } from "./timeout-notification.component";
|
|
12
12
|
export { AuthorizationInterceptor } from "./authorization.interceptor";
|
|
13
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wcm9qZWN0cy9hdXRoZW50aWNhdGlvbi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFFN0Q7O0dBRUc7QUFDSCxPQUFPLEVBQ0wsMEJBQTBCLEVBQzFCLHlCQUF5QixFQUN6Qiw2QkFBNkIsRUFDN0IsOEJBQThCLEVBQzlCLG9CQUFvQixFQUNwQixxQ0FBcUMsRUFDckMscUNBQXFDLEVBQ3JDLHFDQUFxQyxFQUNyQyx5Q0FBeUMsRUFDekMsc0NBQXNDLEVBQ3ZDLE1BQU0sMEJBQTBCLENBQUM7QUFFbEMsT0FBTyxFQUFDLHdCQUF3QixFQUFDLE1BQU0sMkJBQTJCLENBQUM7QUFFbkUsT0FBTyxFQUFDLHVCQUF1QixFQUFDLE1BQU0sNEJBQTRCLENBQUE7QUFDbEUsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0seUJBQXlCLENBQUE7QUFDNUQsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sdUJBQXVCLENBQUE7QUFDdkQsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sMEJBQTBCLENBQUE7QUFDOUQsT0FBTyxFQUFDLDRCQUE0QixFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFDOUUsT0FBTyxFQUFDLHdCQUF3QixFQUFDLE1BQU0sNkJBQTZCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQge0F1dGhlbnRpY2F0aW9uTW9kdWxlfSBmcm9tIFwiLi9hdXRoZW50aWNhdGlvbi5tb2R1bGVcIjtcclxuXHJcbi8qKlxyXG4gKiBUaGUgaW5qZWN0aW9uIHRva2VucyBmb3Igc2VydmljZSBjb25maWd1cmF0aW9uLlxyXG4gKi9cclxuZXhwb3J0IHtcclxuICBBVVRIRU5USUNBVElPTl9MT0dPVVRfUEFUSCxcclxuICBBVVRIRU5USUNBVElPTl9TRVJWRVJfVVJMLFxyXG4gIEFVVEhFTlRJQ0FUSU9OX1RPS0VOX0VORFBPSU5ULFxyXG4gIEFVVEhFTlRJQ0FUSU9OX0RJUkVDVF9FTkRQT0lOVCxcclxuICBBVVRIRU5USUNBVElPTl9ST1VURSxcclxuICBBVVRIRU5USUNBVElPTl9NQVhfSU5BQ1RJVklUWV9NSU5VVEVTLFxyXG4gIEFVVEhFTlRJQ0FUSU9OX1VTRVJfQ09VTlRET1dOX1NFQ09ORFMsXHJcbiAgQVVUSEVOVElDQVRJT05fSURQX0lOQUNUSVZJVFlfTUlOVVRFUyxcclxuICBBVVRIRU5USUNBVElPTl9VU0VfVUlfRVZFTlRTX0ZPUl9BQ1RJVklUWSxcclxuICBBVVRIRU5USUNBVElPTl9BUFBfS0VFUF9BTElWRV9FTkRQT0lOVFxyXG59IGZyb20gXCIuL2F1dGhlbnRpY2F0aW9uLnNlcnZpY2VcIjtcclxuXHJcbmV4cG9ydCB7QVVUSEVOVElDQVRJT05fVE9LRU5fS0VZfSBmcm9tIFwiLi9hdXRoZW50aWNhdGlvbi5wcm92aWRlclwiO1xyXG5cclxuZXhwb3J0IHtBdXRoZW50aWNhdGlvbkNvbXBvbmVudH0gZnJvbSBcIi4vYXV0aGVudGljYXRpb24uY29tcG9uZW50XCJcclxuZXhwb3J0IHtEaXJlY3RMb2dpbkNvbXBvbmVudH0gZnJvbSBcIi4vZGlyZWN0bG9naW4uY29tcG9uZW50XCJcclxuZXhwb3J0IHtSb3V0ZUd1YXJkU2VydmljZX0gZnJvbSBcIi4vcm91dGUtZ3VhcmQuc2VydmljZVwiXHJcbmV4cG9ydCB7QXV0aGVudGljYXRpb25TZXJ2aWNlfSBmcm9tIFwiLi9hdXRoZW50aWNhdGlvbi5zZXJ2aWNlXCJcclxuZXhwb3J0IHtUaW1lb3V0Tm90aWZpY2F0aW9uQ29tcG9uZW50fSBmcm9tIFwiLi90aW1lb3V0LW5vdGlmaWNhdGlvbi5jb21wb25lbnRcIjtcclxuZXhwb3J0IHtBdXRob3JpemF0aW9uSW50ZXJjZXB0b3J9IGZyb20gXCIuL2F1dGhvcml6YXRpb24uaW50ZXJjZXB0b3JcIjsiXX0=
|
|
@@ -12,7 +12,7 @@ import * as i1 from '@angular-cool/storage';
|
|
|
12
12
|
import { CoolStorageModule } from '@angular-cool/storage';
|
|
13
13
|
import * as i4 from '@auth0/angular-jwt';
|
|
14
14
|
import { JwtHelperService, JwtInterceptor, JWT_OPTIONS } from '@auth0/angular-jwt';
|
|
15
|
-
import { BehaviorSubject, interval, throwError, timer } from 'rxjs';
|
|
15
|
+
import { BehaviorSubject, fromEvent, interval, throwError, timer } from 'rxjs';
|
|
16
16
|
import { map, catchError, first, takeWhile } from 'rxjs/operators';
|
|
17
17
|
import * as i2$1 from '@angular/platform-browser';
|
|
18
18
|
import { trigger, state, style, transition, animate } from '@angular/animations';
|
|
@@ -67,11 +67,13 @@ let AUTHENTICATION_ROUTE = new InjectionToken("authentication_route");
|
|
|
67
67
|
let AUTHENTICATION_MAX_INACTIVITY_MINUTES = new InjectionToken("authentication_max_inactivity");
|
|
68
68
|
let AUTHENTICATION_USER_COUNTDOWN_SECONDS = new InjectionToken("authentication_user_countdown_seconds");
|
|
69
69
|
let AUTHENTICATION_IDP_INACTIVITY_MINUTES = new InjectionToken("authentication_idp_inactivity_minutes");
|
|
70
|
+
let AUTHENTICATION_USE_UI_EVENTS_FOR_ACTIVITY = new InjectionToken("authentication_use_ui_events_for_activity");
|
|
71
|
+
let AUTHENTICATION_APP_KEEP_ALIVE_ENDPOINT = new InjectionToken("authentication_app_keep_alive_endpoint");
|
|
70
72
|
/**
|
|
71
73
|
* @since 1.0.0
|
|
72
74
|
*/
|
|
73
75
|
class AuthenticationService {
|
|
74
|
-
constructor(_http, _router, _localStorageService, _jwtHelper, authenticationProvider, _authenticationRoute, _logoutPath, _tokenEndpoint, _serverUrl, _directEndpoint, _maxInactivity, _userCountdownSeconds, _idpInactivityMinutes, locationStrategy) {
|
|
76
|
+
constructor(_http, _router, _localStorageService, _jwtHelper, authenticationProvider, _authenticationRoute, _logoutPath, _tokenEndpoint, _serverUrl, _directEndpoint, _maxInactivity, _userCountdownSeconds, _idpInactivityMinutes, _useUIEventsForActivity, _keepAliveEndpoint, locationStrategy) {
|
|
75
77
|
this._http = _http;
|
|
76
78
|
this._router = _router;
|
|
77
79
|
this._localStorageService = _localStorageService;
|
|
@@ -85,6 +87,8 @@ class AuthenticationService {
|
|
|
85
87
|
this._maxInactivity = _maxInactivity;
|
|
86
88
|
this._userCountdownSeconds = _userCountdownSeconds;
|
|
87
89
|
this._idpInactivityMinutes = _idpInactivityMinutes;
|
|
90
|
+
this._useUIEventsForActivity = _useUIEventsForActivity;
|
|
91
|
+
this._keepAliveEndpoint = _keepAliveEndpoint;
|
|
88
92
|
this.locationStrategy = locationStrategy;
|
|
89
93
|
this.userCountdownSeconds = 60;
|
|
90
94
|
this.idpInactivityMinutes = 5;
|
|
@@ -95,6 +99,7 @@ class AuthenticationService {
|
|
|
95
99
|
this._isAuthenticatedSubject = new BehaviorSubject(false);
|
|
96
100
|
this._userIsAboutToTimeOut = new BehaviorSubject(false);
|
|
97
101
|
this._maxInactivityMinutes = 120;
|
|
102
|
+
this._uiEvents = ['keydown', 'click', 'wheel', 'mousemove'];
|
|
98
103
|
this.contextRoot = "";
|
|
99
104
|
if (isDevMode()) {
|
|
100
105
|
console.debug("window.location.href: " + window.location.href);
|
|
@@ -118,6 +123,10 @@ class AuthenticationService {
|
|
|
118
123
|
if (_idpInactivityMinutes) {
|
|
119
124
|
this.idpInactivityMinutes = _idpInactivityMinutes;
|
|
120
125
|
}
|
|
126
|
+
//Subscribe to UI events for user activity
|
|
127
|
+
if (_useUIEventsForActivity) {
|
|
128
|
+
this.subscribeToUIActivity();
|
|
129
|
+
}
|
|
121
130
|
this.hasValidConfig();
|
|
122
131
|
//There could be a non-expired token in local storage.
|
|
123
132
|
let token = this.authenticationProvider.authToken;
|
|
@@ -187,6 +196,9 @@ class AuthenticationService {
|
|
|
187
196
|
this.logout(true);
|
|
188
197
|
});
|
|
189
198
|
}
|
|
199
|
+
makeKeepAliveRequest() {
|
|
200
|
+
this._http.get(this.keepAliveLocation(), { withCredentials: true }).subscribe();
|
|
201
|
+
}
|
|
190
202
|
/**
|
|
191
203
|
* Verifies whether or not a current user session exists.
|
|
192
204
|
*
|
|
@@ -211,6 +223,14 @@ class AuthenticationService {
|
|
|
211
223
|
return this._tokenEndpoint;
|
|
212
224
|
}
|
|
213
225
|
}
|
|
226
|
+
keepAliveLocation() {
|
|
227
|
+
if (this._serverUrl) {
|
|
228
|
+
return this._serverUrl + this._keepAliveEndpoint;
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
return this._keepAliveEndpoint;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
214
234
|
directLoginLocation() {
|
|
215
235
|
if (this._serverUrl) {
|
|
216
236
|
return this._serverUrl + this._directEndpoint;
|
|
@@ -317,6 +337,14 @@ class AuthenticationService {
|
|
|
317
337
|
validateToken(token) {
|
|
318
338
|
return (token && !this._jwtHelper.isTokenExpired(token));
|
|
319
339
|
}
|
|
340
|
+
subscribeToUIActivity() {
|
|
341
|
+
this._uiEvents.forEach(event => fromEvent(document, event).subscribe(_ => {
|
|
342
|
+
//Only update activity on UI event if not already about to time out. Counter intuitive, but in this case we should have 60 second count-down dialog open.
|
|
343
|
+
if (this._userIsAboutToTimeOut.getValue() !== true) {
|
|
344
|
+
this.updateUserActivity();
|
|
345
|
+
}
|
|
346
|
+
}));
|
|
347
|
+
}
|
|
320
348
|
subscribeToTokenRefresh(token) {
|
|
321
349
|
let exp = this._jwtHelper.getTokenExpirationDate(token);
|
|
322
350
|
// Use a timer to periodically check timeouts
|
|
@@ -356,7 +384,12 @@ class AuthenticationService {
|
|
|
356
384
|
refreshTokenIfUserIsActive() {
|
|
357
385
|
//Only refresh if the user has been active
|
|
358
386
|
if (this._lastUserInteraction && ((new Date().valueOf() - this._lastUserInteraction.valueOf()) <= (this._maxInactivityMinutes * 60 * 1000))) {
|
|
387
|
+
//Refresh the JWT
|
|
359
388
|
this.requestAccessToken(false);
|
|
389
|
+
//Might as well make application keep alive requests at the same time as refreshing tokens - more efficient & probably needs same logic
|
|
390
|
+
if (this._keepAliveEndpoint) {
|
|
391
|
+
this.makeKeepAliveRequest();
|
|
392
|
+
}
|
|
360
393
|
}
|
|
361
394
|
}
|
|
362
395
|
hasValidConfig() {
|
|
@@ -383,7 +416,7 @@ AuthenticationService.SEC_GOV_CLASS_HEADER = "SecurityGovernorClass";
|
|
|
383
416
|
AuthenticationService.SEC_GOV_ID_HEADER = "SecurityGovernorId";
|
|
384
417
|
AuthenticationService.DEIDENT_HEADER = "DeidentifiedContext";
|
|
385
418
|
AuthenticationService.LIMITED_HEADER = "LimitedContext";
|
|
386
|
-
AuthenticationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AuthenticationService, deps: [{ token: i1$1.HttpClient }, { token: i2.Router }, { token: i1.CoolLocalStorage }, { token: i4.JwtHelperService }, { token: AuthenticationProvider }, { token: AUTHENTICATION_ROUTE }, { token: AUTHENTICATION_LOGOUT_PATH }, { token: AUTHENTICATION_TOKEN_ENDPOINT }, { token: AUTHENTICATION_SERVER_URL, optional: true }, { token: AUTHENTICATION_DIRECT_ENDPOINT, optional: true }, { token: AUTHENTICATION_MAX_INACTIVITY_MINUTES, optional: true }, { token: AUTHENTICATION_USER_COUNTDOWN_SECONDS, optional: true }, { token: AUTHENTICATION_IDP_INACTIVITY_MINUTES, optional: true }, { token: LocationStrategy, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
419
|
+
AuthenticationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AuthenticationService, deps: [{ token: i1$1.HttpClient }, { token: i2.Router }, { token: i1.CoolLocalStorage }, { token: i4.JwtHelperService }, { token: AuthenticationProvider }, { token: AUTHENTICATION_ROUTE }, { token: AUTHENTICATION_LOGOUT_PATH }, { token: AUTHENTICATION_TOKEN_ENDPOINT }, { token: AUTHENTICATION_SERVER_URL, optional: true }, { token: AUTHENTICATION_DIRECT_ENDPOINT, optional: true }, { token: AUTHENTICATION_MAX_INACTIVITY_MINUTES, optional: true }, { token: AUTHENTICATION_USER_COUNTDOWN_SECONDS, optional: true }, { token: AUTHENTICATION_IDP_INACTIVITY_MINUTES, optional: true }, { token: AUTHENTICATION_USE_UI_EVENTS_FOR_ACTIVITY, optional: true }, { token: AUTHENTICATION_APP_KEEP_ALIVE_ENDPOINT, optional: true }, { token: LocationStrategy, optional: true }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
387
420
|
AuthenticationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AuthenticationService });
|
|
388
421
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: AuthenticationService, decorators: [{
|
|
389
422
|
type: Injectable
|
|
@@ -422,6 +455,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
422
455
|
}, {
|
|
423
456
|
type: Inject,
|
|
424
457
|
args: [AUTHENTICATION_IDP_INACTIVITY_MINUTES]
|
|
458
|
+
}] }, { type: undefined, decorators: [{
|
|
459
|
+
type: Optional
|
|
460
|
+
}, {
|
|
461
|
+
type: Inject,
|
|
462
|
+
args: [AUTHENTICATION_USE_UI_EVENTS_FOR_ACTIVITY]
|
|
463
|
+
}] }, { type: undefined, decorators: [{
|
|
464
|
+
type: Optional
|
|
465
|
+
}, {
|
|
466
|
+
type: Inject,
|
|
467
|
+
args: [AUTHENTICATION_APP_KEEP_ALIVE_ENDPOINT]
|
|
425
468
|
}] }, { type: i4$1.LocationStrategy, decorators: [{
|
|
426
469
|
type: Optional
|
|
427
470
|
}, {
|
|
@@ -996,5 +1039,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImpo
|
|
|
996
1039
|
* Generated bundle index. Do not edit.
|
|
997
1040
|
*/
|
|
998
1041
|
|
|
999
|
-
export { AUTHENTICATION_DIRECT_ENDPOINT, AUTHENTICATION_IDP_INACTIVITY_MINUTES, AUTHENTICATION_LOGOUT_PATH, AUTHENTICATION_MAX_INACTIVITY_MINUTES, AUTHENTICATION_ROUTE, AUTHENTICATION_SERVER_URL, AUTHENTICATION_TOKEN_ENDPOINT, AUTHENTICATION_TOKEN_KEY, AUTHENTICATION_USER_COUNTDOWN_SECONDS, AuthenticationComponent, AuthenticationModule, AuthenticationService, AuthorizationInterceptor, DirectLoginComponent, RouteGuardService, TimeoutNotificationComponent };
|
|
1042
|
+
export { AUTHENTICATION_APP_KEEP_ALIVE_ENDPOINT, AUTHENTICATION_DIRECT_ENDPOINT, AUTHENTICATION_IDP_INACTIVITY_MINUTES, AUTHENTICATION_LOGOUT_PATH, AUTHENTICATION_MAX_INACTIVITY_MINUTES, AUTHENTICATION_ROUTE, AUTHENTICATION_SERVER_URL, AUTHENTICATION_TOKEN_ENDPOINT, AUTHENTICATION_TOKEN_KEY, AUTHENTICATION_USER_COUNTDOWN_SECONDS, AUTHENTICATION_USE_UI_EVENTS_FOR_ACTIVITY, AuthenticationComponent, AuthenticationModule, AuthenticationService, AuthorizationInterceptor, DirectLoginComponent, RouteGuardService, TimeoutNotificationComponent };
|
|
1000
1043
|
//# sourceMappingURL=huntsman-cancer-institute-authentication.mjs.map
|