@esolve/ng-esolve-connect 0.109.0 → 0.110.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.
Files changed (39) hide show
  1. package/esm2022/lib/auth/index.mjs +3 -4
  2. package/esm2022/lib/auth/interceptors/esolve-auth.interceptor.mjs +32 -0
  3. package/esm2022/lib/auth/interceptors/index.mjs +2 -0
  4. package/esm2022/lib/auth/providers/esolve-eurus-auto-login.provider.mjs +2 -2
  5. package/esm2022/lib/auth/services/esolve-auth.service.mjs +288 -0
  6. package/esm2022/lib/auth/services/esolve-otp.service.mjs +77 -0
  7. package/esm2022/lib/auth/services/index.mjs +3 -0
  8. package/esm2022/lib/core/esolve-config.service.mjs +37 -40
  9. package/esm2022/lib/core/esolve-connect-config.interface.mjs +1 -1
  10. package/esm2022/lib/core/providers/index.mjs +2 -2
  11. package/esm2022/lib/core/providers/ng-esolve-connect.provider.mjs +19 -0
  12. package/esm2022/lib/coupons/esolve-coupons.service.mjs +8 -6
  13. package/esm2022/lib/session/esolve-session.service.mjs +89 -89
  14. package/esm2022/lib/shared/cookie/esolve-cookie-options.interface.mjs +2 -0
  15. package/esm2022/lib/shared/cookie/esolve-cookie.service.mjs +5 -5
  16. package/esm2022/lib/shared/cookie/index.mjs +2 -2
  17. package/esm2022/lib/vouchers/esolve-vouchers.service.mjs +8 -6
  18. package/fesm2022/esolve-ng-esolve-connect.mjs +304 -315
  19. package/fesm2022/esolve-ng-esolve-connect.mjs.map +1 -1
  20. package/lib/auth/index.d.ts +2 -3
  21. package/lib/auth/interceptors/esolve-auth.interceptor.d.ts +2 -0
  22. package/lib/auth/interceptors/index.d.ts +1 -0
  23. package/lib/auth/{esolve-auth.service.d.ts → services/esolve-auth.service.d.ts} +1 -1
  24. package/lib/auth/{esolve-otp.service.d.ts → services/esolve-otp.service.d.ts} +3 -3
  25. package/lib/auth/services/index.d.ts +2 -0
  26. package/lib/core/esolve-config.service.d.ts +14 -10
  27. package/lib/core/esolve-connect-config.interface.d.ts +6 -6
  28. package/lib/core/providers/index.d.ts +1 -1
  29. package/lib/session/esolve-session.service.d.ts +12 -5
  30. package/lib/shared/cookie/esolve-cookie-options.interface.d.ts +7 -0
  31. package/lib/shared/cookie/esolve-cookie.service.d.ts +3 -2
  32. package/lib/shared/cookie/index.d.ts +2 -1
  33. package/package.json +1 -1
  34. package/esm2022/lib/auth/esolve-auth-interceptor.service.mjs +0 -42
  35. package/esm2022/lib/auth/esolve-auth.service.mjs +0 -286
  36. package/esm2022/lib/auth/esolve-otp.service.mjs +0 -77
  37. package/esm2022/lib/core/providers/provide-ng-esolve-connect.function.mjs +0 -24
  38. package/lib/auth/esolve-auth-interceptor.service.d.ts +0 -10
  39. /package/lib/core/providers/{provide-ng-esolve-connect.function.d.ts → ng-esolve-connect.provider.d.ts} +0 -0
@@ -1,7 +1,6 @@
1
- export * from './esolve-auth.service';
2
- export * from './esolve-auth-interceptor.service';
3
- export * from './esolve-otp.service';
1
+ export * from './services';
4
2
  export * from './models';
5
3
  export * from './types';
4
+ export * from './interceptors';
6
5
  export * from './interfaces';
7
6
  export * from './providers';
@@ -0,0 +1,2 @@
1
+ import { HttpInterceptorFn } from '@angular/common/http';
2
+ export declare const esolveAuthInterceptor: HttpInterceptorFn;
@@ -0,0 +1 @@
1
+ export { esolveAuthInterceptor } from './esolve-auth.interceptor';
@@ -1,5 +1,5 @@
1
1
  import { Observable } from 'rxjs';
2
- import { EsolveAuthGetResponse, EsolveAuthResult } from './types';
2
+ import { EsolveAuthGetResponse, EsolveAuthResult } from '../types';
3
3
  import * as i0 from "@angular/core";
4
4
  export declare class EsolveAuthService {
5
5
  private readonly config;
@@ -1,7 +1,7 @@
1
1
  import { Observable } from 'rxjs';
2
- import { EsolveCaptchaOptions } from '../captcha';
3
- import { EsolveOtpAction } from './types';
4
- import { EsolveOtp, EsolveOtpValidation } from './models';
2
+ import { EsolveCaptchaOptions } from '../../captcha';
3
+ import { EsolveOtpAction } from '../types';
4
+ import { EsolveOtp, EsolveOtpValidation } from '../models';
5
5
  import * as i0 from "@angular/core";
6
6
  export declare class EsolveOtpService {
7
7
  private readonly config;
@@ -0,0 +1,2 @@
1
+ export { EsolveAuthService } from './esolve-auth.service';
2
+ export { EsolveOtpService } from './esolve-otp.service';
@@ -1,25 +1,29 @@
1
1
  import { EsolveConnectConfig } from './esolve-connect-config.interface';
2
2
  import * as i0 from "@angular/core";
3
3
  export declare class EsolveConfigService implements EsolveConnectConfig {
4
+ private readonly config;
5
+ wsid: string;
4
6
  api_url: string;
5
7
  site_url: string;
6
- wsid: string;
8
+ native: boolean;
9
+ device_designation: string;
7
10
  title_prefix: string;
8
11
  title_suffix: string;
9
12
  title_separator: string;
10
13
  default_seo_title: string;
11
14
  default_seo_description: string;
12
15
  default_seo_keywords: string;
13
- native: boolean;
14
- session_storage_key: string;
15
- coupon_storage_key: string;
16
- voucher_storage_key: string;
17
- device_designation: string;
18
- legacy_cdn?: string;
19
- cdn?: string;
20
- ftg_cdn?: string;
21
- error_image_path?: string;
16
+ session_cookie_key: string;
17
+ coupon_cookie_key: string;
18
+ voucher_cookie_key: string;
19
+ legacy_cdn: string | undefined;
20
+ cdn: string | undefined;
21
+ ftg_cdn: string | undefined;
22
+ error_image_path: string | undefined;
22
23
  constructor();
24
+ updateWsid(wsid: string): void;
25
+ udpateCdn(cdn?: string, ftg_cdn?: string): void;
26
+ udpateLegacyCdn(cdn?: string): void;
23
27
  static ɵfac: i0.ɵɵFactoryDeclaration<EsolveConfigService, never>;
24
28
  static ɵprov: i0.ɵɵInjectableDeclaration<EsolveConfigService>;
25
29
  }
@@ -39,17 +39,17 @@ export interface EsolveConnectConfig {
39
39
  */
40
40
  default_seo_keywords?: string;
41
41
  /**
42
- * Key for user session local storage (Default is `_ng_eslv_token`)
42
+ * Key for user session cookie storage (Default is `_ng_eslv_token`)
43
43
  */
44
- session_storage_key?: string;
44
+ session_cookie_key?: string;
45
45
  /**
46
- * Key for coupon local storage (Default is `_ng_eslv_coupons`)
46
+ * Key for coupon cookie storage (Default is `_ng_eslv_coupons`)
47
47
  */
48
- coupon_storage_key?: string;
48
+ coupon_cookie_key?: string;
49
49
  /**
50
- * Key for voucher local storage (Default is `_ng_eslv_vouchers`)
50
+ * Key for voucher cookie storage (Default is `_ng_eslv_vouchers`)
51
51
  */
52
- voucher_storage_key?: string;
52
+ voucher_cookie_key?: string;
53
53
  /**
54
54
  * Indicates whether the implementation is a native app or a website. If it is a native
55
55
  * app, the `device_designation` is required for native app features to be enabled
@@ -1 +1 @@
1
- export * from './provide-ng-esolve-connect.function';
1
+ export { provideNgEsolveConnect } from './ng-esolve-connect.provider';
@@ -5,6 +5,16 @@ export declare class EsolveSessionService {
5
5
  private readonly is_browser;
6
6
  private readonly config;
7
7
  private readonly cookieService;
8
+ private readonly storage_key;
9
+ protected readonly token: import("@angular/core").WritableSignal<string>;
10
+ protected readonly user_id: import("@angular/core").WritableSignal<number>;
11
+ protected readonly access_level: import("@angular/core").WritableSignal<number>;
12
+ protected readonly location_id: import("@angular/core").WritableSignal<number>;
13
+ protected readonly addresses_id: import("@angular/core").WritableSignal<number>;
14
+ protected readonly shipping_id: import("@angular/core").WritableSignal<number>;
15
+ protected readonly clients_id: import("@angular/core").WritableSignal<number>;
16
+ protected readonly state_hash: import("@angular/core").Signal<string>;
17
+ protected readonly session: import("@angular/core").Signal<EsolveSession>;
8
18
  private token$;
9
19
  private user_id$;
10
20
  private access_level$;
@@ -12,9 +22,7 @@ export declare class EsolveSessionService {
12
22
  private addresses_id$;
13
23
  private shipping_id$;
14
24
  private clients_id$;
15
- private state_hash;
16
- private _session;
17
- private storage_key;
25
+ private session$;
18
26
  private timer_start;
19
27
  private timer_stop;
20
28
  private expire;
@@ -53,8 +61,7 @@ export declare class EsolveSessionService {
53
61
  getCachedSession(): string | null;
54
62
  reset(): void;
55
63
  handleSession(session: EsolveSession, expiry_date_unix: number, grace_unix: number): void;
56
- handleUpdateSession({ user_id, location_id, addresses_id, shipping_id, clients_id, token, }: EsolveSessionUpdateOptions): void;
57
- private initSession;
64
+ handleUpdateSession(options: EsolveSessionUpdateOptions): void;
58
65
  private setStorageKey;
59
66
  private getCache;
60
67
  private setCache;
@@ -0,0 +1,7 @@
1
+ export interface EsolveCookieOptions {
2
+ expires?: Date;
3
+ path?: string;
4
+ domain?: string;
5
+ secure?: boolean;
6
+ sameSite?: 'Lax' | 'None' | 'Strict';
7
+ }
@@ -1,10 +1,11 @@
1
+ import { EsolveCookieOptions } from './esolve-cookie-options.interface';
1
2
  import * as i0 from "@angular/core";
2
3
  export declare class EsolveCookieService {
3
4
  private readonly cookieService;
4
5
  check(name: string): boolean;
5
6
  get(name: string): string;
6
- set(name: string, value: string, expires?: Date, path?: string, domain?: string, secure?: boolean): void;
7
- delete(name: string, path?: string, domain?: string, secure?: boolean): void;
7
+ set(name: string, value: string, options?: EsolveCookieOptions): void;
8
+ delete(name: string, options?: Omit<EsolveCookieOptions, 'expires'>): void;
8
9
  static ɵfac: i0.ɵɵFactoryDeclaration<EsolveCookieService, never>;
9
10
  static ɵprov: i0.ɵɵInjectableDeclaration<EsolveCookieService>;
10
11
  }
@@ -1 +1,2 @@
1
- export * from './esolve-cookie.service';
1
+ export { EsolveCookieOptions } from './esolve-cookie-options.interface';
2
+ export { EsolveCookieService } from './esolve-cookie.service';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esolve/ng-esolve-connect",
3
- "version": "0.109.0",
3
+ "version": "0.110.0",
4
4
  "homepage": "https://www.esolve.co.za/",
5
5
  "description": "An Angular library that speaks to an eSolve instance's API",
6
6
  "peerDependencies": {
@@ -1,42 +0,0 @@
1
- import { Injectable, inject } from '@angular/core';
2
- import { EsolveSessionService } from '../session';
3
- import { EsolveConfigService } from '../core';
4
- import * as i0 from "@angular/core";
5
- export class EsolveAuthInterceptorService {
6
- constructor() {
7
- this.config = inject(EsolveConfigService);
8
- this.session = inject(EsolveSessionService);
9
- }
10
- intercept(req, next) {
11
- if (req.url.startsWith(`${this.config.api_url}/`)) {
12
- const service_identifier = req.url.replace(`${this.config.api_url}/`, '');
13
- const modified_url = req.url;
14
- let params = req.params;
15
- let headers = req.headers;
16
- if (this.session.isValid()) {
17
- if (service_identifier !== 'get-access-token.php') {
18
- headers = headers.set('Authorization', `Bearer ${this.session.getToken()}`);
19
- }
20
- const state_hash = this.session.getStateHash();
21
- headers = headers.set('X-Esolve-State-Hash', state_hash);
22
- }
23
- params = params.set('ws_id', this.config.wsid);
24
- if (this.config.native && this.config.device_designation) {
25
- headers = headers.set('X-Device-Designation', this.config.device_designation);
26
- }
27
- const modified_req = req.clone({
28
- url: modified_url,
29
- params,
30
- headers,
31
- });
32
- return next.handle(modified_req);
33
- }
34
- return next.handle(req);
35
- }
36
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: EsolveAuthInterceptorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
37
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: EsolveAuthInterceptorService }); }
38
- }
39
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: EsolveAuthInterceptorService, decorators: [{
40
- type: Injectable
41
- }] });
42
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXNvbHZlLWF1dGgtaW50ZXJjZXB0b3Iuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvbmctZXNvbHZlLWNvbm5lY3Qvc3JjL2xpYi9hdXRoL2Vzb2x2ZS1hdXRoLWludGVyY2VwdG9yLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFVbkQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ2xELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLFNBQVMsQ0FBQzs7QUFHOUMsTUFBTSxPQUFPLDRCQUE0QjtJQUR6QztRQUVxQixXQUFNLEdBQUcsTUFBTSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDckMsWUFBTyxHQUFHLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0tBZ0QzRDtJQTlDVSxTQUFTLENBQ1osR0FBcUIsRUFDckIsSUFBaUI7UUFFakIsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ2hELE1BQU0sa0JBQWtCLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQ3RDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEdBQUcsRUFDekIsRUFBRSxDQUNMLENBQUM7WUFFRixNQUFNLFlBQVksR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDO1lBQzdCLElBQUksTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7WUFDeEIsSUFBSSxPQUFPLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQztZQUUxQixJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztnQkFDekIsSUFBSSxrQkFBa0IsS0FBSyxzQkFBc0IsRUFBRSxDQUFDO29CQUNoRCxPQUFPLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FDakIsZUFBZSxFQUNmLFVBQVUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsRUFBRSxDQUN0QyxDQUFDO2dCQUNOLENBQUM7Z0JBRUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQztnQkFDL0MsT0FBTyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDN0QsQ0FBQztZQUVELE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRS9DLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO2dCQUN2RCxPQUFPLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FDakIsc0JBQXNCLEVBQ3RCLElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLENBQ2pDLENBQUM7WUFDTixDQUFDO1lBRUQsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQztnQkFDM0IsR0FBRyxFQUFFLFlBQVk7Z0JBQ2pCLE1BQU07Z0JBQ04sT0FBTzthQUNWLENBQUMsQ0FBQztZQUVILE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNyQyxDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzVCLENBQUM7OEdBakRRLDRCQUE0QjtrSEFBNUIsNEJBQTRCOzsyRkFBNUIsNEJBQTRCO2tCQUR4QyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICAgIEh0dHBJbnRlcmNlcHRvcixcbiAgICBIdHRwUmVxdWVzdCxcbiAgICBIdHRwSGFuZGxlcixcbiAgICBIdHRwRXZlbnQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBFc29sdmVTZXNzaW9uU2VydmljZSB9IGZyb20gJy4uL3Nlc3Npb24nO1xuaW1wb3J0IHsgRXNvbHZlQ29uZmlnU2VydmljZSB9IGZyb20gJy4uL2NvcmUnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgRXNvbHZlQXV0aEludGVyY2VwdG9yU2VydmljZSBpbXBsZW1lbnRzIEh0dHBJbnRlcmNlcHRvciB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25maWcgPSBpbmplY3QoRXNvbHZlQ29uZmlnU2VydmljZSk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBzZXNzaW9uID0gaW5qZWN0KEVzb2x2ZVNlc3Npb25TZXJ2aWNlKTtcblxuICAgIHB1YmxpYyBpbnRlcmNlcHQoXG4gICAgICAgIHJlcTogSHR0cFJlcXVlc3Q8YW55PixcbiAgICAgICAgbmV4dDogSHR0cEhhbmRsZXIsXG4gICAgKTogT2JzZXJ2YWJsZTxIdHRwRXZlbnQ8YW55Pj4ge1xuICAgICAgICBpZiAocmVxLnVybC5zdGFydHNXaXRoKGAke3RoaXMuY29uZmlnLmFwaV91cmx9L2ApKSB7XG4gICAgICAgICAgICBjb25zdCBzZXJ2aWNlX2lkZW50aWZpZXIgPSByZXEudXJsLnJlcGxhY2UoXG4gICAgICAgICAgICAgICAgYCR7dGhpcy5jb25maWcuYXBpX3VybH0vYCxcbiAgICAgICAgICAgICAgICAnJyxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGNvbnN0IG1vZGlmaWVkX3VybCA9IHJlcS51cmw7XG4gICAgICAgICAgICBsZXQgcGFyYW1zID0gcmVxLnBhcmFtcztcbiAgICAgICAgICAgIGxldCBoZWFkZXJzID0gcmVxLmhlYWRlcnM7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnNlc3Npb24uaXNWYWxpZCgpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHNlcnZpY2VfaWRlbnRpZmllciAhPT0gJ2dldC1hY2Nlc3MtdG9rZW4ucGhwJykge1xuICAgICAgICAgICAgICAgICAgICBoZWFkZXJzID0gaGVhZGVycy5zZXQoXG4gICAgICAgICAgICAgICAgICAgICAgICAnQXV0aG9yaXphdGlvbicsXG4gICAgICAgICAgICAgICAgICAgICAgICBgQmVhcmVyICR7dGhpcy5zZXNzaW9uLmdldFRva2VuKCl9YCxcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBzdGF0ZV9oYXNoID0gdGhpcy5zZXNzaW9uLmdldFN0YXRlSGFzaCgpO1xuICAgICAgICAgICAgICAgIGhlYWRlcnMgPSBoZWFkZXJzLnNldCgnWC1Fc29sdmUtU3RhdGUtSGFzaCcsIHN0YXRlX2hhc2gpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBwYXJhbXMgPSBwYXJhbXMuc2V0KCd3c19pZCcsIHRoaXMuY29uZmlnLndzaWQpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5jb25maWcubmF0aXZlICYmIHRoaXMuY29uZmlnLmRldmljZV9kZXNpZ25hdGlvbikge1xuICAgICAgICAgICAgICAgIGhlYWRlcnMgPSBoZWFkZXJzLnNldChcbiAgICAgICAgICAgICAgICAgICAgJ1gtRGV2aWNlLURlc2lnbmF0aW9uJyxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWcuZGV2aWNlX2Rlc2lnbmF0aW9uLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IG1vZGlmaWVkX3JlcSA9IHJlcS5jbG9uZSh7XG4gICAgICAgICAgICAgICAgdXJsOiBtb2RpZmllZF91cmwsXG4gICAgICAgICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIG5leHQuaGFuZGxlKG1vZGlmaWVkX3JlcSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV4dC5oYW5kbGUocmVxKTtcbiAgICB9XG59XG4iXX0=
@@ -1,286 +0,0 @@
1
- import { inject, Injectable } from '@angular/core';
2
- import { HttpClient, HttpParams, HttpHeaders, } from '@angular/common/http';
3
- import { catchError, firstValueFrom, map, of, switchMap, tap, throwError, } from 'rxjs';
4
- import { EsolveConfigService } from '../core';
5
- import { EsolveErrorHandlerService } from '../shared';
6
- import { EsolveSessionService } from '../session';
7
- import * as i0 from "@angular/core";
8
- export class EsolveAuthService {
9
- constructor() {
10
- this.config = inject(EsolveConfigService);
11
- this.http = inject(HttpClient);
12
- this.session = inject(EsolveSessionService);
13
- this.errorHandler = inject(EsolveErrorHandlerService);
14
- this.session
15
- .onSessionEnd()
16
- .pipe(switchMap(() => this.checkAccessToken()), catchError(() => of(null)))
17
- .subscribe((result) => {
18
- if (result) {
19
- this.handleAuthentication(result);
20
- }
21
- else {
22
- this.session.expireSession();
23
- }
24
- });
25
- this.session.onExpire().subscribe(() => {
26
- this.logout().catch(() => {
27
- // Deal with error gracefully
28
- });
29
- });
30
- }
31
- getAccessToken(email, password, anonymous = false) {
32
- let params = new HttpParams();
33
- if (anonymous) {
34
- params = params.set('anonymous', true);
35
- }
36
- if (email !== '') {
37
- params = params.set('email', email);
38
- }
39
- if (password !== '') {
40
- params = params.set('password', password);
41
- }
42
- return this.http
43
- .get(`${this.config.api_url}/get-access-token.php`, {
44
- params,
45
- headers: new HttpHeaders({
46
- 'Accept-Language': '*',
47
- }),
48
- })
49
- .pipe(tap((response) => {
50
- if (response.type === 'error' ||
51
- response.type === 'exception') {
52
- throw response;
53
- }
54
- }), catchError(this.handleError), tap((response) => {
55
- this.handleAuthentication(response.additional_data);
56
- }));
57
- }
58
- getAnonymousSession() {
59
- return this.getAccessToken('', '', true);
60
- }
61
- async autoLogin() {
62
- let result = await this.restore();
63
- try {
64
- if (!result) {
65
- const response = await firstValueFrom(this.getAnonymousSession());
66
- result = response.additional_data;
67
- }
68
- this.handleAuthentication(result);
69
- }
70
- catch (error) {
71
- console.error(error);
72
- }
73
- }
74
- login(email, password) {
75
- const body = {
76
- login: {
77
- email,
78
- password,
79
- },
80
- };
81
- return this.http
82
- .post(`${this.config.api_url}/set-login.php`, body, {
83
- headers: {
84
- 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;',
85
- },
86
- responseType: 'json',
87
- observe: 'body',
88
- })
89
- .pipe(map((response) => {
90
- if (response.responses === undefined ||
91
- response.responses.length <= 0) {
92
- throw response;
93
- }
94
- const login_response = response.responses[0];
95
- const result = response.additional_data;
96
- if (login_response.status.state !== 'success' &&
97
- login_response.status.state !== 'warning') {
98
- throw login_response;
99
- }
100
- for (const response_log of login_response.log) {
101
- if (response_log.type === 'success' &&
102
- response_log.message_code === 'login_success') {
103
- const user_id = +login_response.esolve_id;
104
- if (Array.isArray(result)) {
105
- throw new Error('Invalid login');
106
- }
107
- this.handleAuthentication({
108
- key: result.key,
109
- user_id: result.user_id,
110
- access_level: result.access_level,
111
- location_id: result.location_id,
112
- addresses_id: result.addresses_id,
113
- shipping_id: result.shipping_id,
114
- expires: result.expires,
115
- expiry_time: result.expiry_time,
116
- grace_period: result.grace_period,
117
- clients_id: result.clients_id,
118
- });
119
- return user_id;
120
- }
121
- }
122
- throw login_response;
123
- }), catchError((errorRes) => {
124
- return this.errorHandler.handleHttpPostError('set-login', errorRes);
125
- }));
126
- }
127
- async logout() {
128
- this.session.stopTimer();
129
- const response = await firstValueFrom(this.http
130
- .post(`${this.config.api_url}/set-logout.php`, {}, {
131
- headers: {
132
- 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;',
133
- },
134
- responseType: 'json',
135
- observe: 'body',
136
- })
137
- .pipe(map((response) => {
138
- if (response.responses === undefined ||
139
- response.responses.length <= 0) {
140
- throw response;
141
- }
142
- const logout_response = response.responses[0];
143
- const result = response.additional_data;
144
- if (logout_response.status.state !== 'success' &&
145
- logout_response.status.state !== 'warning') {
146
- throw logout_response;
147
- }
148
- for (const response_log of logout_response.log) {
149
- if (response_log.type === 'success' &&
150
- response_log.message_code === 'logout_success') {
151
- if (Array.isArray(result)) {
152
- throw new Error('Invalid logout');
153
- }
154
- this.handleAuthentication({
155
- key: result.key,
156
- user_id: result.user_id,
157
- access_level: result.access_level,
158
- location_id: result.location_id,
159
- addresses_id: result.addresses_id,
160
- shipping_id: result.shipping_id,
161
- expires: result.expires,
162
- expiry_time: result.expiry_time,
163
- grace_period: result.grace_period,
164
- clients_id: result.clients_id,
165
- });
166
- return result;
167
- }
168
- }
169
- throw logout_response;
170
- }), catchError((errorRes) => {
171
- return this.errorHandler.handleHttpPostError('set-logout', errorRes);
172
- })));
173
- return response;
174
- }
175
- async validateCachedTokens() {
176
- let valid = false;
177
- try {
178
- const session = this.session.getCachedSession();
179
- if (!session) {
180
- throw new Error('Invalid session');
181
- }
182
- const result = await this.checkAccessToken(session);
183
- if (!result.key) {
184
- throw new Error('Invalid key');
185
- }
186
- valid = true;
187
- }
188
- catch (error) {
189
- console.error(error);
190
- this.session.reset();
191
- }
192
- return valid;
193
- }
194
- async checkAccessToken(token = this.session.getToken()) {
195
- if (token === '') {
196
- throw new Error('Invalid Token');
197
- }
198
- const response = await firstValueFrom(this.http.get(`${this.config.api_url}/get-access-token.php`, {
199
- headers: new HttpHeaders({
200
- 'Accept-Language': '*',
201
- Authorization: `Bearer ${token}`,
202
- }),
203
- }));
204
- if (response.type === 'error' || response.type === 'exception') {
205
- throw response;
206
- }
207
- const additional_data = response.additional_data;
208
- if (!additional_data.key_okay) {
209
- throw response;
210
- }
211
- if (additional_data.key) {
212
- token = additional_data.key;
213
- }
214
- const result = {
215
- key: token,
216
- expires: +additional_data.expires,
217
- expiry_time: +additional_data.expiry_time,
218
- grace_period: +additional_data.grace_period,
219
- location_id: +additional_data.location_id,
220
- user_id: +additional_data.user_id,
221
- access_level: +additional_data.access_level,
222
- addresses_id: +additional_data.addresses_id,
223
- shipping_id: +additional_data.shipping_id,
224
- clients_id: +additional_data.clients_id,
225
- };
226
- return result;
227
- }
228
- async restore() {
229
- try {
230
- const token = this.session.getCachedSession();
231
- if (!token) {
232
- throw new Error('Invalid token');
233
- }
234
- const result = await this.checkAccessToken(token);
235
- return result;
236
- }
237
- catch (error) {
238
- console.error(error);
239
- this.session.reset();
240
- }
241
- return null;
242
- }
243
- // Handlers
244
- handleExternalAuthentication(result) {
245
- this.handleAuthentication(result);
246
- }
247
- handleAuthentication(result) {
248
- if (!result.key) {
249
- return;
250
- }
251
- this.session.handleSession({
252
- token: result.key,
253
- user_id: +result.user_id,
254
- access_level: +result.access_level,
255
- location_id: +result.location_id,
256
- addresses_id: +result.addresses_id,
257
- shipping_id: +result.shipping_id,
258
- clients_id: +result.clients_id,
259
- }, +result.expiry_time, +result.grace_period);
260
- }
261
- handleError(errorRes) {
262
- const error = {
263
- message: 'An unknown error occurred',
264
- data: {},
265
- };
266
- if (!errorRes.type || !errorRes.service_type || !errorRes.message) {
267
- return throwError(() => error);
268
- }
269
- if (errorRes.message.trim() !== '') {
270
- error.message = errorRes.message;
271
- }
272
- if (errorRes.additional_data) {
273
- error.data = errorRes.additional_data;
274
- }
275
- return throwError(() => error);
276
- }
277
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: EsolveAuthService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
278
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: EsolveAuthService, providedIn: 'root' }); }
279
- }
280
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.6", ngImport: i0, type: EsolveAuthService, decorators: [{
281
- type: Injectable,
282
- args: [{
283
- providedIn: 'root',
284
- }]
285
- }], ctorParameters: () => [] });
286
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXNvbHZlLWF1dGguc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvbmctZXNvbHZlLWNvbm5lY3Qvc3JjL2xpYi9hdXRoL2Vzb2x2ZS1hdXRoLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkQsT0FBTyxFQUNILFVBQVUsRUFDVixVQUFVLEVBRVYsV0FBVyxHQUNkLE1BQU0sc0JBQXNCLENBQUM7QUFFOUIsT0FBTyxFQUNILFVBQVUsRUFDVixjQUFjLEVBQ2QsR0FBRyxFQUVILEVBQUUsRUFDRixTQUFTLEVBQ1QsR0FBRyxFQUNILFVBQVUsR0FDYixNQUFNLE1BQU0sQ0FBQztBQUVkLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUM5QyxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFdEQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sWUFBWSxDQUFDOztBQWFsRCxNQUFNLE9BQU8saUJBQWlCO0lBTTFCO1FBTGlCLFdBQU0sR0FBRyxNQUFNLENBQUMsbUJBQW1CLENBQUMsQ0FBQztRQUNyQyxTQUFJLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzFCLFlBQU8sR0FBRyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUN2QyxpQkFBWSxHQUFHLE1BQU0sQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBRzlELElBQUksQ0FBQyxPQUFPO2FBQ1AsWUFBWSxFQUFFO2FBQ2QsSUFBSSxDQUNELFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxFQUN4QyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQzdCO2FBQ0EsU0FBUyxDQUFDLENB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RUFBRSxDQUFDLE1BQU0sQ0FBQyxZQUFZO1lBQ2xDLFdBQVcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxXQUFXO1lBQ2hDLFVBQVUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxVQUFVO1NBQ2pDLEVBQ0QsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUNuQixDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQ3ZCLENBQUM7SUFDTixDQUFDO0lBRU8sV0FBVyxDQUNmLFFBQXlEO1FBRXpELE1BQU0sS0FBSyxHQUFHO1lBQ1YsT0FBTyxFQUFFLDJCQUEyQjtZQUNwQyxJQUFJLEVBQUUsRUFBRTtTQUNYLENBQUM7UUFFRixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDaEUsT0FBTyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDbkMsQ0FBQztRQUVELElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQztZQUNqQyxLQUFLLENBQUMsT0FBTyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUM7UUFDckMsQ0FBQztRQUVELElBQUksUUFBUSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQzNCLEtBQUssQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQztRQUMxQyxDQUFDO1FBRUQsT0FBTyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbkMsQ0FBQzs4R0F4WVEsaUJBQWlCO2tIQUFqQixpQkFBaUIsY0FGZCxNQUFNOzsyRkFFVCxpQkFBaUI7a0JBSDdCLFVBQVU7bUJBQUM7b0JBQ1IsVUFBVSxFQUFFLE1BQU07aUJBQ3JCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICAgIEh0dHBDbGllbnQsXG4gICAgSHR0cFBhcmFtcyxcbiAgICBIdHRwRXJyb3JSZXNwb25zZSxcbiAgICBIdHRwSGVhZGVycyxcbn0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuXG5pbXBvcnQge1xuICAgIGNhdGNoRXJyb3IsXG4gICAgZmlyc3RWYWx1ZUZyb20sXG4gICAgbWFwLFxuICAgIE9ic2VydmFibGUsXG4gICAgb2YsXG4gICAgc3dpdGNoTWFwLFxuICAgIHRhcCxcbiAgICB0aHJvd0Vycm9yLFxufSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgRXNvbHZlQ29uZmlnU2VydmljZSB9IGZyb20gJy4uL2NvcmUnO1xuaW1wb3J0IHsgRXNvbHZlRXJyb3JIYW5kbGVyU2VydmljZSB9IGZyb20gJy4uL3NoYXJlZCc7XG5cbmltcG9ydCB7IEVzb2x2ZVNlc3Npb25TZXJ2aWNlIH0gZnJvbSAnLi4vc2Vzc2lvbic7XG5cbmltcG9ydCB7XG4gICAgRXNvbHZlQXV0aEdldFJlc3BvbnNlLFxuICAgIEVzb2x2ZUF1dGhDaGVja1Jlc3BvbnNlLFxuICAgIEVzb2x2ZUF1dGhSZXN1bHQsXG4gICAgRXNvbHZlTG9naW5SZXNwb25zZSxcbiAgICBFc29sdmVMb2dvdXRSZXNwb25zZSxcbn0gZnJvbSAnLi90eXBlcyc7XG5cbkBJbmplY3RhYmxlKHtcbiAgICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIEVzb2x2ZUF1dGhTZXJ2aWNlIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbmZpZyA9IGluamVjdChFc29sdmVDb25maWdTZXJ2aWNlKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGh0dHAgPSBpbmplY3QoSHR0cENsaWVudCk7XG4gICAgcHJpdmF0ZSByZWFkb25seSBzZXNzaW9uID0gaW5qZWN0KEVzb2x2ZVNlc3Npb25TZXJ2aWNlKTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGVycm9ySGFuZGxlciA9IGluamVjdChFc29sdmVFcnJvckhhbmRsZXJTZXJ2aWNlKTtcblxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLnNlc3Npb25cbiAgICAgICAgICAgIC5vblNlc3Npb25FbmQoKVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuY2hlY2tBY2Nlc3NUb2tlbigpKSxcbiAgICAgICAgICAgICAgICBjYXRjaEVycm9yKCgpID0+IG9mKG51bGwpKSxcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVBdXRoZW50aWNhdGlvbihyZXN1bHQpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2Vzc2lvbi5leHBpcmVTZXNzaW9uKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5zZXNzaW9uLm9uRXhwaXJlKCkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMubG9nb3V0KCkuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIERlYWwgd2l0aCBlcnJvciBncmFjZWZ1bGx5XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldEFjY2Vzc1Rva2VuKFxuICAgICAgICBlbWFpbDogc3RyaW5nLFxuICAgICAgICBwYXNzd29yZDogc3RyaW5nLFxuICAgICAgICBhbm9ueW1vdXMgPSBmYWxzZSxcbiAgICApOiBPYnNlcnZhYmxlPEVzb2x2ZUF1dGhHZXRSZXNwb25zZT4ge1xuICAgICAgICBsZXQgcGFyYW1zID0gbmV3IEh0dHBQYXJhbXMoKTtcblxuICAgICAgICBpZiAoYW5vbnltb3VzKSB7XG4gICAgICAgICAgICBwYXJhbXMgPSBwYXJhbXMuc2V0KCdhbm9ueW1vdXMnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbWFpbCAhPT0gJycpIHtcbiAgICAgICAgICAgIHBhcmFtcyA9IHBhcmFtcy5zZXQoJ2VtYWlsJywgZW1haWwpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhc3N3b3JkICE9PSAnJykge1xuICAgICAgICAgICAgcGFyYW1zID0gcGFyYW1zLnNldCgncGFzc3dvcmQnLCBwYXNzd29yZCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5odHRwXG4gICAgICAgICAgICAuZ2V0PEVzb2x2ZUF1dGhHZXRSZXNwb25zZT4oXG4gICAgICAgICAgICAgICAgYCR7dGhpcy5jb25maWcuYXBpX3VybH0vZ2V0LWFjY2Vzcy10b2tlbi5waHBgLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgICAgICAgICAgICBoZWFkZXJzOiBuZXcgSHR0cEhlYWRlcnMoe1xuICAgICAgICAgICAgICAgICAgICAgICAgJ0FjY2VwdC1MYW5ndWFnZSc6ICcqJyxcbiAgICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIClcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgIHRhcCgocmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UudHlwZSA9PT0gJ2Vycm9yJyB8fFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UudHlwZSA9PT0gJ2V4Y2VwdGlvbidcbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyByZXNwb25zZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIGNhdGNoRXJyb3IodGhpcy5oYW5kbGVFcnJvciksXG4gICAgICAgICAgICAgICAgdGFwKChyZXNwb25zZSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZUF1dGhlbnRpY2F0aW9uKHJlc3BvbnNlLmFkZGl0aW9uYWxfZGF0YSk7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXRBbm9ueW1vdXNTZXNzaW9uKCk6IE9ic2VydmFibGU8RXNvbHZlQXV0aEdldFJlc3BvbnNlPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEFjY2Vzc1Rva2VuKCcnLCAnJywgdHJ1ZSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGF1dG9Mb2dpbigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IHRoaXMucmVzdG9yZSgpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20oXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZ2V0QW5vbnltb3VzU2Vzc2lvbigpLFxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXNwb25zZS5hZGRpdGlvbmFsX2RhdGE7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuaGFuZGxlQXV0aGVudGljYXRpb24ocmVzdWx0KTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGxvZ2luKGVtYWlsOiBzdHJpbmcsIHBhc3N3b3JkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPG51bWJlcj4ge1xuICAgICAgICBjb25zdCBib2R5ID0ge1xuICAgICAgICAgICAgbG9naW46IHtcbiAgICAgICAgICAgICAgICBlbWFpbCxcbiAgICAgICAgICAgICAgICBwYXNzd29yZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH07XG5cbiAgICAgICAgcmV0dXJuIHRoaXMuaHR0cFxuICAgICAgICAgICAgLnBvc3Q8RXNvbHZlTG9naW5SZXNwb25zZT4oXG4gICAgICAgICAgICAgICAgYCR7dGhpcy5jb25maWcuYXBpX3VybH0vc2V0LWxvZ2luLnBocGAsXG4gICAgICAgICAgICAgICAgYm9keSxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICdDb250ZW50LVR5cGUnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7Y2hhcnNldD11dGYtODsnLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICByZXNwb25zZVR5cGU6ICdqc29uJyxcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZTogJ2JvZHknLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICBtYXAoKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLnJlc3BvbnNlcyA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5yZXNwb25zZXMubGVuZ3RoIDw9IDBcbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyByZXNwb25zZTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxvZ2luX3Jlc3BvbnNlID0gcmVzcG9uc2UucmVzcG9uc2VzWzBdO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSByZXNwb25zZS5hZGRpdGlvbmFsX2RhdGE7XG5cbiAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgbG9naW5fcmVzcG9uc2Uuc3RhdHVzLnN0YXRlICE9PSAnc3VjY2VzcycgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2luX3Jlc3BvbnNlLnN0YXR1cy5zdGF0ZSAhPT0gJ3dhcm5pbmcnXG4gICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbG9naW5fcmVzcG9uc2U7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHJlc3BvbnNlX2xvZyBvZiBsb2dpbl9yZXNwb25zZS5sb2cpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZV9sb2cudHlwZSA9PT0gJ3N1Y2Nlc3MnICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VfbG9nLm1lc3NhZ2VfY29kZSA9PT0gJ2xvZ2luX3N1Y2Nlc3MnXG4gICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1c2VyX2lkID0gK2xvZ2luX3Jlc3BvbnNlLmVzb2x2ZV9pZDtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGxvZ2luJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVBdXRoZW50aWNhdGlvbih7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleTogcmVzdWx0LmtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlcl9pZDogcmVzdWx0LnVzZXJfaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY2Vzc19sZXZlbDogcmVzdWx0LmFjY2Vzc19sZXZlbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYXRpb25faWQ6IHJlc3VsdC5sb2NhdGlvbl9pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzc2VzX2lkOiByZXN1bHQuYWRkcmVzc2VzX2lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGlwcGluZ19pZDogcmVzdWx0LnNoaXBwaW5nX2lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBpcmVzOiByZXN1bHQuZXhwaXJlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwaXJ5X3RpbWU6IHJlc3VsdC5leHBpcnlfdGltZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JhY2VfcGVyaW9kOiByZXN1bHQuZ3JhY2VfcGVyaW9kLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGllbnRzX2lkOiByZXN1bHQuY2xpZW50c19pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB1c2VyX2lkO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbG9naW5fcmVzcG9uc2U7XG4gICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3JSZXM6IEh0dHBFcnJvclJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmVycm9ySGFuZGxlci5oYW5kbGVIdHRwUG9zdEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3NldC1sb2dpbicsXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvclJlcyxcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICk7XG4gICAgfVxuXG4gICAgcHVibGljIGFzeW5jIGxvZ291dCgpIHtcbiAgICAgICAgdGhpcy5zZXNzaW9uLnN0b3BUaW1lcigpO1xuXG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmlyc3RWYWx1ZUZyb208RXNvbHZlQXV0aFJlc3VsdD4oXG4gICAgICAgICAgICB0aGlzLmh0dHBcbiAgICAgICAgICAgICAgICAucG9zdDxFc29sdmVMb2dvdXRSZXNwb25zZT4oXG4gICAgICAgICAgICAgICAgICAgIGAke3RoaXMuY29uZmlnLmFwaV91cmx9L3NldC1sb2dvdXQucGhwYCxcbiAgICAgICAgICAgICAgICAgICAge30sXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQ29udGVudC1UeXBlJzpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZDtjaGFyc2V0PXV0Zi04OycsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VUeXBlOiAnanNvbicsXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlOiAnYm9keScsXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICAgICAgICBtYXAoKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UucmVzcG9uc2VzID09PSB1bmRlZmluZWQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS5yZXNwb25zZXMubGVuZ3RoIDw9IDBcbiAgICAgICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IHJlc3BvbnNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBsb2dvdXRfcmVzcG9uc2UgPSByZXNwb25zZS5yZXNwb25zZXNbMF07XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSByZXNwb25zZS5hZGRpdGlvbmFsX2RhdGE7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dvdXRfcmVzcG9uc2Uuc3RhdHVzLnN0YXRlICE9PSAnc3VjY2VzcycgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2dvdXRfcmVzcG9uc2Uuc3RhdHVzLnN0YXRlICE9PSAnd2FybmluZydcbiAgICAgICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IGxvZ291dF9yZXNwb25zZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCByZXNwb25zZV9sb2cgb2YgbG9nb3V0X3Jlc3BvbnNlLmxvZykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2VfbG9nLnR5cGUgPT09ICdzdWNjZXNzJyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZV9sb2cubWVzc2FnZV9jb2RlID09PSAnbG9nb3V0X3N1Y2Nlc3MnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBsb2dvdXQnKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaGFuZGxlQXV0aGVudGljYXRpb24oe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5OiByZXN1bHQua2V5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNlcl9pZDogcmVzdWx0LnVzZXJfaWQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2Nlc3NfbGV2ZWw6IHJlc3VsdC5hY2Nlc3NfbGV2ZWwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhdGlvbl9pZDogcmVzdWx0LmxvY2F0aW9uX2lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzc2VzX2lkOiByZXN1bHQuYWRkcmVzc2VzX2lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hpcHBpbmdfaWQ6IHJlc3VsdC5zaGlwcGluZ19pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGlyZXM6IHJlc3VsdC5leHBpcmVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwaXJ5X3RpbWU6IHJlc3VsdC5leHBpcnlfdGltZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyYWNlX3BlcmlvZDogcmVzdWx0LmdyYWNlX3BlcmlvZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaWVudHNfaWQ6IHJlc3VsdC5jbGllbnRzX2lkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbG9nb3V0X3Jlc3BvbnNlO1xuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3JSZXM6IEh0dHBFcnJvclJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5lcnJvckhhbmRsZXIuaGFuZGxlSHR0cFBvc3RFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc2V0LWxvZ291dCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JSZXMsXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYXN5bmMgdmFsaWRhdGVDYWNoZWRUb2tlbnMoKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgICAgIGxldCB2YWxpZCA9IGZhbHNlO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBzZXNzaW9uID0gdGhpcy5zZXNzaW9uLmdldENhY2hlZFNlc3Npb24oKTtcblxuICAgICAgICAgICAgaWYgKCFzZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHNlc3Npb24nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5jaGVja0FjY2Vzc1Rva2VuKHNlc3Npb24pO1xuXG4gICAgICAgICAgICBpZiAoIXJlc3VsdC5rZXkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQga2V5Jyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhbGlkID0gdHJ1ZTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuXG4gICAgICAgICAgICB0aGlzLnNlc3Npb24ucmVzZXQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB2YWxpZDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGNoZWNrQWNjZXNzVG9rZW4oXG4gICAgICAgIHRva2VuID0gdGhpcy5zZXNzaW9uLmdldFRva2VuKCksXG4gICAgKTogUHJvbWlzZTxFc29sdmVBdXRoUmVzdWx0PiB7XG4gICAgICAgIGlmICh0b2tlbiA9PT0gJycpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBUb2tlbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmaXJzdFZhbHVlRnJvbShcbiAgICAgICAgICAgIHRoaXMuaHR0cC5nZXQ8RXNvbHZlQXV0aENoZWNrUmVzcG9uc2U+KFxuICAgICAgICAgICAgICAgIGAke3RoaXMuY29uZmlnLmFwaV91cmx9L2dldC1hY2Nlc3MtdG9rZW4ucGhwYCxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGhlYWRlcnM6IG5ldyBIdHRwSGVhZGVycyh7XG4gICAgICAgICAgICAgICAgICAgICAgICAnQWNjZXB0LUxhbmd1YWdlJzogJyonLFxuICAgICAgICAgICAgICAgICAgICAgICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke3Rva2VufWAsXG4gICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICApLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChyZXNwb25zZS50eXBlID09PSAnZXJyb3InIHx8IHJlc3BvbnNlLnR5cGUgPT09ICdleGNlcHRpb24nKSB7XG4gICAgICAgICAgICB0aHJvdyByZXNwb25zZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGFkZGl0aW9uYWxfZGF0YSA9IHJlc3BvbnNlLmFkZGl0aW9uYWxfZGF0YTtcblxuICAgICAgICBpZiAoIWFkZGl0aW9uYWxfZGF0YS5rZXlfb2theSkge1xuICAgICAgICAgICAgdGhyb3cgcmVzcG9uc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoYWRkaXRpb25hbF9kYXRhLmtleSkge1xuICAgICAgICAgICAgdG9rZW4gPSBhZGRpdGlvbmFsX2RhdGEua2V5O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzdWx0OiBFc29sdmVBdXRoUmVzdWx0ID0ge1xuICAgICAgICAgICAga2V5OiB0b2tlbixcbiAgICAgICAgICAgIGV4cGlyZXM6ICthZGRpdGlvbmFsX2RhdGEuZXhwaXJlcyxcbiAgICAgICAgICAgIGV4cGlyeV90aW1lOiArYWRkaXRpb25hbF9kYXRhLmV4cGlyeV90aW1lLFxuICAgICAgICAgICAgZ3JhY2VfcGVyaW9kOiArYWRkaXRpb25hbF9kYXRhLmdyYWNlX3BlcmlvZCxcbiAgICAgICAgICAgIGxvY2F0aW9uX2lkOiArYWRkaXRpb25hbF9kYXRhLmxvY2F0aW9uX2lkLFxuICAgICAgICAgICAgdXNlcl9pZDogK2FkZGl0aW9uYWxfZGF0YS51c2VyX2lkLFxuICAgICAgICAgICAgYWNjZXNzX2xldmVsOiArYWRkaXRpb25hbF9kYXRhLmFjY2Vzc19sZXZlbCxcbiAgICAgICAgICAgIGFkZHJlc3Nlc19pZDogK2FkZGl0aW9uYWxfZGF0YS5hZGRyZXNzZXNfaWQsXG4gICAgICAgICAgICBzaGlwcGluZ19pZDogK2FkZGl0aW9uYWxfZGF0YS5zaGlwcGluZ19pZCxcbiAgICAgICAgICAgIGNsaWVudHNfaWQ6ICthZGRpdGlvbmFsX2RhdGEuY2xpZW50c19pZCxcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHByaXZhdGUgYXN5bmMgcmVzdG9yZSgpOiBQcm9taXNlPEVzb2x2ZUF1dGhSZXN1bHQgfCBudWxsPiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB0b2tlbiA9IHRoaXMuc2Vzc2lvbi5nZXRDYWNoZWRTZXNzaW9uKCk7XG5cbiAgICAgICAgICAgIGlmICghdG9rZW4pIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgdG9rZW4nKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5jaGVja0FjY2Vzc1Rva2VuKHRva2VuKTtcblxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuXG4gICAgICAgICAgICB0aGlzLnNlc3Npb24ucmVzZXQoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIEhhbmRsZXJzXG5cbiAgICBwdWJsaWMgaGFuZGxlRXh0ZXJuYWxBdXRoZW50aWNhdGlvbihyZXN1bHQ6IEVzb2x2ZUF1dGhSZXN1bHQpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5oYW5kbGVBdXRoZW50aWNhdGlvbihyZXN1bHQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaGFuZGxlQXV0aGVudGljYXRpb24ocmVzdWx0OiBFc29sdmVBdXRoUmVzdWx0KTogdm9pZCB7XG4gICAgICAgIGlmICghcmVzdWx0LmtleSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zZXNzaW9uLmhhbmRsZVNlc3Npb24oXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdG9rZW46IHJlc3VsdC5rZXksXG4gICAgICAgICAgICAgICAgdXNlcl9pZDogK3Jlc3VsdC51c2VyX2lkLFxuICAgICAgICAgICAgICAgIGFjY2Vzc19sZXZlbDogK3Jlc3VsdC5hY2Nlc3NfbGV2ZWwsXG4gICAgICAgICAgICAgICAgbG9jYXRpb25faWQ6ICtyZXN1bHQubG9jYXRpb25faWQsXG4gICAgICAgICAgICAgICAgYWRkcmVzc2VzX2lkOiArcmVzdWx0LmFkZHJlc3Nlc19pZCxcbiAgICAgICAgICAgICAgICBzaGlwcGluZ19pZDogK3Jlc3VsdC5zaGlwcGluZ19pZCxcbiAgICAgICAgICAgICAgICBjbGllbnRzX2lkOiArcmVzdWx0LmNsaWVudHNfaWQsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgK3Jlc3VsdC5leHBpcnlfdGltZSxcbiAgICAgICAgICAgICtyZXN1bHQuZ3JhY2VfcGVyaW9kLFxuICAgICAgICApO1xuICAgIH1cblxuICAgIHByaXZhdGUgaGFuZGxlRXJyb3IoXG4gICAgICAgIGVycm9yUmVzOiBFc29sdmVBdXRoR2V0UmVzcG9uc2UgfCBFc29sdmVBdXRoQ2hlY2tSZXNwb25zZSxcbiAgICApOiBPYnNlcnZhYmxlPG5ldmVyPiB7XG4gICAgICAgIGNvbnN0IGVycm9yID0ge1xuICAgICAgICAgICAgbWVzc2FnZTogJ0FuIHVua25vd24gZXJyb3Igb2NjdXJyZWQnLFxuICAgICAgICAgICAgZGF0YToge30sXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKCFlcnJvclJlcy50eXBlIHx8ICFlcnJvclJlcy5zZXJ2aWNlX3R5cGUgfHwgIWVycm9yUmVzLm1lc3NhZ2UpIHtcbiAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycm9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlcnJvclJlcy5tZXNzYWdlLnRyaW0oKSAhPT0gJycpIHtcbiAgICAgICAgICAgIGVycm9yLm1lc3NhZ2UgPSBlcnJvclJlcy5tZXNzYWdlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVycm9yUmVzLmFkZGl0aW9uYWxfZGF0YSkge1xuICAgICAgICAgICAgZXJyb3IuZGF0YSA9IGVycm9yUmVzLmFkZGl0aW9uYWxfZGF0YTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycm9yKTtcbiAgICB9XG59XG4iXX0=