ngx-sp-auth 0.0.0-watch
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/README.md +24 -0
- package/esm2022/lib/auth.module.mjs +87 -0
- package/esm2022/lib/auth.service.mjs +306 -0
- package/esm2022/lib/components/login/login.component.mjs +326 -0
- package/esm2022/lib/components/menu-lateral/dropdown/primary-dropdown/primary-dropdown.component.mjs +68 -0
- package/esm2022/lib/components/menu-lateral/dropdown/secondary-dropdown/secondary-dropdown.component.mjs +32 -0
- package/esm2022/lib/components/menu-lateral/menu/list-estab.service.mjs +55 -0
- package/esm2022/lib/components/menu-lateral/menu/menu-lateral.component.mjs +235 -0
- package/esm2022/lib/components/menu-lateral/menu/selecao-estabelecimentos-modal/selecao-estabelecimentos-modal.component.mjs +200 -0
- package/esm2022/lib/components/menu-lateral/menu-services.service.mjs +151 -0
- package/esm2022/lib/components/menu-lateral/model/iestabelecimento.model.mjs +2 -0
- package/esm2022/lib/components/menu-lateral/model/imenu-item-structure.model.mjs +2 -0
- package/esm2022/lib/components/menu-lateral/model/imenu.model.mjs +12 -0
- package/esm2022/lib/components/menu-lateral/model/infrausuarioimg.mjs +12 -0
- package/esm2022/lib/components/menu-lateral/model/isubmenu-item-structure.model.mjs +2 -0
- package/esm2022/lib/components/menu-lateral/model/ret-estabelecimento-session.mjs +10 -0
- package/esm2022/lib/components/menu-lateral/model/ret-infrausuarioemail.mjs +8 -0
- package/esm2022/lib/components/menu-lateral/model/ret-infrausuarioimg.mjs +11 -0
- package/esm2022/lib/components/menu-lateral/model/usuario-img.mjs +8 -0
- package/esm2022/lib/components/menu-lateral/submenus/dynamic-menu/dynamic-menu.component.mjs +54 -0
- package/esm2022/lib/components/menu-lateral/submenus/notif-submenu/notif-submenu.component.mjs +14 -0
- package/esm2022/lib/components/nova-senha/nova-senhacomponent.mjs +191 -0
- package/esm2022/lib/custom/custom-login.service.mjs +52 -0
- package/esm2022/lib/custom/custom-menu.service.mjs +88 -0
- package/esm2022/lib/custom/menu-config.service.mjs +70 -0
- package/esm2022/lib/custom/models/icustom-login-service.mjs +2 -0
- package/esm2022/lib/custom/models/icustom-menu-service.mjs +2 -0
- package/esm2022/lib/custom/models/imenu-config.mjs +2 -0
- package/esm2022/lib/environments/environments.service.mjs +21 -0
- package/esm2022/lib/environments/models/ienvironments.mjs +2 -0
- package/esm2022/lib/guards/auth-guard.mjs +34 -0
- package/esm2022/lib/guards/external-login-guard.mjs +88 -0
- package/esm2022/lib/guards/login-guard.mjs +35 -0
- package/esm2022/lib/interceptors/auth-aplic.interceptor.mjs +41 -0
- package/esm2022/lib/interceptors/auth-infra.interceptor.mjs +30 -0
- package/esm2022/lib/models/code-2fa.mjs +2 -0
- package/esm2022/lib/models/custom-propriedades-login.mjs +3 -0
- package/esm2022/lib/models/forgotten-password-form.mjs +2 -0
- package/esm2022/lib/models/login-form.mjs +2 -0
- package/esm2022/lib/models/login.mjs +2 -0
- package/esm2022/lib/models/nova-senha-form.mjs +2 -0
- package/esm2022/lib/models/password-recup.mjs +2 -0
- package/esm2022/lib/models/payload.mjs +2 -0
- package/esm2022/lib/models/ret-login.mjs +21 -0
- package/esm2022/lib/models/ret-token.mjs +8 -0
- package/esm2022/lib/models/token.mjs +2 -0
- package/esm2022/lib/server/ret-server-config.mjs +9 -0
- package/esm2022/lib/server/server.service.mjs +38 -0
- package/esm2022/lib/storage/auth-storage.service.mjs +409 -0
- package/esm2022/ngx-sp-auth.mjs +5 -0
- package/esm2022/public-api.mjs +37 -0
- package/fesm2022/ngx-sp-auth.mjs +2520 -0
- package/fesm2022/ngx-sp-auth.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/auth.module.d.ts +21 -0
- package/lib/auth.service.d.ts +42 -0
- package/lib/components/login/login.component.d.ts +67 -0
- package/lib/components/menu-lateral/dropdown/primary-dropdown/primary-dropdown.component.d.ts +20 -0
- package/lib/components/menu-lateral/dropdown/secondary-dropdown/secondary-dropdown.component.d.ts +12 -0
- package/lib/components/menu-lateral/menu/list-estab.service.d.ts +19 -0
- package/lib/components/menu-lateral/menu/menu-lateral.component.d.ts +74 -0
- package/lib/components/menu-lateral/menu/selecao-estabelecimentos-modal/selecao-estabelecimentos-modal.component.d.ts +71 -0
- package/lib/components/menu-lateral/menu-services.service.d.ts +31 -0
- package/lib/components/menu-lateral/model/iestabelecimento.model.d.ts +4 -0
- package/lib/components/menu-lateral/model/imenu-item-structure.model.d.ts +12 -0
- package/lib/components/menu-lateral/model/imenu.model.d.ts +40 -0
- package/lib/components/menu-lateral/model/infrausuarioimg.d.ts +9 -0
- package/lib/components/menu-lateral/model/isubmenu-item-structure.model.d.ts +9 -0
- package/lib/components/menu-lateral/model/ret-estabelecimento-session.d.ts +8 -0
- package/lib/components/menu-lateral/model/ret-infrausuarioemail.d.ts +6 -0
- package/lib/components/menu-lateral/model/ret-infrausuarioimg.d.ts +9 -0
- package/lib/components/menu-lateral/model/usuario-img.d.ts +5 -0
- package/lib/components/menu-lateral/submenus/dynamic-menu/dynamic-menu.component.d.ts +25 -0
- package/lib/components/menu-lateral/submenus/notif-submenu/notif-submenu.component.d.ts +8 -0
- package/lib/components/nova-senha/nova-senhacomponent.d.ts +48 -0
- package/lib/custom/custom-login.service.d.ts +38 -0
- package/lib/custom/custom-menu.service.d.ts +48 -0
- package/lib/custom/menu-config.service.d.ts +32 -0
- package/lib/custom/models/icustom-login-service.d.ts +13 -0
- package/lib/custom/models/icustom-menu-service.d.ts +10 -0
- package/lib/custom/models/imenu-config.d.ts +7 -0
- package/lib/environments/environments.service.d.ts +11 -0
- package/lib/environments/models/ienvironments.d.ts +4 -0
- package/lib/guards/auth-guard.d.ts +14 -0
- package/lib/guards/external-login-guard.d.ts +21 -0
- package/lib/guards/login-guard.d.ts +24 -0
- package/lib/interceptors/auth-aplic.interceptor.d.ts +22 -0
- package/lib/interceptors/auth-infra.interceptor.d.ts +16 -0
- package/lib/models/code-2fa.d.ts +4 -0
- package/lib/models/custom-propriedades-login.d.ts +11 -0
- package/lib/models/forgotten-password-form.d.ts +5 -0
- package/lib/models/login-form.d.ts +5 -0
- package/lib/models/login.d.ts +4 -0
- package/lib/models/nova-senha-form.d.ts +5 -0
- package/lib/models/password-recup.d.ts +5 -0
- package/lib/models/payload.d.ts +9 -0
- package/lib/models/ret-login.d.ts +20 -0
- package/lib/models/ret-token.d.ts +6 -0
- package/lib/models/token.d.ts +8 -0
- package/lib/server/ret-server-config.d.ts +7 -0
- package/lib/server/server.service.d.ts +14 -0
- package/lib/storage/auth-storage.service.d.ts +90 -0
- package/package.json +25 -0
- package/public-api.d.ts +36 -0
- package/src/assets/imgs/Property1-cadeado.png +0 -0
- package/src/assets/imgs/Property1-calendariofino.png +0 -0
- package/src/assets/imgs/Property1-mao.png +0 -0
- package/src/assets/styles/styles.novo.scss +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# NgxSpAuth
|
|
2
|
+
|
|
3
|
+
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 17.3.0.
|
|
4
|
+
|
|
5
|
+
## Code scaffolding
|
|
6
|
+
|
|
7
|
+
Run `ng generate component component-name --project ngx-sp-auth` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ngx-sp-auth`.
|
|
8
|
+
> Note: Don't forget to add `--project ngx-sp-auth` or else it will be added to the default project in your `angular.json` file.
|
|
9
|
+
|
|
10
|
+
## Build
|
|
11
|
+
|
|
12
|
+
Run `ng build ngx-sp-auth` to build the project. The build artifacts will be stored in the `dist/` directory.
|
|
13
|
+
|
|
14
|
+
## Publishing
|
|
15
|
+
|
|
16
|
+
After building your library with `ng build ngx-sp-auth`, go to the dist folder `cd dist/ngx-sp-auth` and run `npm publish`.
|
|
17
|
+
|
|
18
|
+
## Running unit tests
|
|
19
|
+
|
|
20
|
+
Run `ng test ngx-sp-auth` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
|
21
|
+
|
|
22
|
+
## Further help
|
|
23
|
+
|
|
24
|
+
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { NgModule } from '@angular/core';
|
|
3
|
+
import { ReactiveFormsModule } from '@angular/forms';
|
|
4
|
+
import { RouterLink, RouterOutlet } from '@angular/router';
|
|
5
|
+
import { PopoverModule } from 'ngx-bootstrap/popover';
|
|
6
|
+
import { TooltipModule } from 'ngx-bootstrap/tooltip';
|
|
7
|
+
import { NgxPaginationModule } from 'ngx-pagination';
|
|
8
|
+
import { InfraModule } from 'ngx-sp-infra';
|
|
9
|
+
import { LoginComponent } from '../lib/components/login/login.component';
|
|
10
|
+
import { PrimaryDropdownComponent } from '../lib/components/menu-lateral/dropdown/primary-dropdown/primary-dropdown.component';
|
|
11
|
+
import { SecondaryDropdownComponent } from '../lib/components/menu-lateral/dropdown/secondary-dropdown/secondary-dropdown.component';
|
|
12
|
+
import { MenuLateralComponent } from '../lib/components/menu-lateral/menu/menu-lateral.component';
|
|
13
|
+
import { SelecaoEstabelecimentosModalComponent } from '../lib/components/menu-lateral/menu/selecao-estabelecimentos-modal/selecao-estabelecimentos-modal.component';
|
|
14
|
+
import { DynamicMenuComponent } from '../lib/components/menu-lateral/submenus/dynamic-menu/dynamic-menu.component';
|
|
15
|
+
import { NotifSubmenuComponent } from '../lib/components/menu-lateral/submenus/notif-submenu/notif-submenu.component';
|
|
16
|
+
import { NovaSenhaComponent } from '../lib/components/nova-senha/nova-senhacomponent';
|
|
17
|
+
import * as i0 from "@angular/core";
|
|
18
|
+
export class AuthModule {
|
|
19
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
20
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.12", ngImport: i0, type: AuthModule, declarations: [LoginComponent,
|
|
21
|
+
NovaSenhaComponent,
|
|
22
|
+
PrimaryDropdownComponent,
|
|
23
|
+
SecondaryDropdownComponent,
|
|
24
|
+
SelecaoEstabelecimentosModalComponent,
|
|
25
|
+
MenuLateralComponent,
|
|
26
|
+
DynamicMenuComponent,
|
|
27
|
+
NotifSubmenuComponent], imports: [CommonModule,
|
|
28
|
+
ReactiveFormsModule,
|
|
29
|
+
InfraModule,
|
|
30
|
+
NgxPaginationModule,
|
|
31
|
+
PopoverModule,
|
|
32
|
+
TooltipModule,
|
|
33
|
+
CommonModule,
|
|
34
|
+
RouterLink,
|
|
35
|
+
RouterOutlet], exports: [LoginComponent,
|
|
36
|
+
NovaSenhaComponent,
|
|
37
|
+
PrimaryDropdownComponent,
|
|
38
|
+
SecondaryDropdownComponent,
|
|
39
|
+
SelecaoEstabelecimentosModalComponent,
|
|
40
|
+
MenuLateralComponent,
|
|
41
|
+
DynamicMenuComponent,
|
|
42
|
+
NotifSubmenuComponent] }); }
|
|
43
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthModule, imports: [CommonModule,
|
|
44
|
+
ReactiveFormsModule,
|
|
45
|
+
InfraModule,
|
|
46
|
+
NgxPaginationModule,
|
|
47
|
+
PopoverModule,
|
|
48
|
+
TooltipModule,
|
|
49
|
+
CommonModule] }); }
|
|
50
|
+
}
|
|
51
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthModule, decorators: [{
|
|
52
|
+
type: NgModule,
|
|
53
|
+
args: [{
|
|
54
|
+
declarations: [
|
|
55
|
+
LoginComponent,
|
|
56
|
+
NovaSenhaComponent,
|
|
57
|
+
PrimaryDropdownComponent,
|
|
58
|
+
SecondaryDropdownComponent,
|
|
59
|
+
SelecaoEstabelecimentosModalComponent,
|
|
60
|
+
MenuLateralComponent,
|
|
61
|
+
DynamicMenuComponent,
|
|
62
|
+
NotifSubmenuComponent
|
|
63
|
+
],
|
|
64
|
+
imports: [
|
|
65
|
+
CommonModule,
|
|
66
|
+
ReactiveFormsModule,
|
|
67
|
+
InfraModule,
|
|
68
|
+
NgxPaginationModule,
|
|
69
|
+
PopoverModule,
|
|
70
|
+
TooltipModule,
|
|
71
|
+
CommonModule,
|
|
72
|
+
RouterLink,
|
|
73
|
+
RouterOutlet
|
|
74
|
+
],
|
|
75
|
+
exports: [
|
|
76
|
+
LoginComponent,
|
|
77
|
+
NovaSenhaComponent,
|
|
78
|
+
PrimaryDropdownComponent,
|
|
79
|
+
SecondaryDropdownComponent,
|
|
80
|
+
SelecaoEstabelecimentosModalComponent,
|
|
81
|
+
MenuLateralComponent,
|
|
82
|
+
DynamicMenuComponent,
|
|
83
|
+
NotifSubmenuComponent
|
|
84
|
+
]
|
|
85
|
+
}]
|
|
86
|
+
}] });
|
|
87
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5tb2R1bGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc3AtYXV0aC9zcmMvbGliL2F1dGgubW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3RELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzNDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx5Q0FBeUMsQ0FBQztBQUN6RSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxxRkFBcUYsQ0FBQztBQUMvSCxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSx5RkFBeUYsQ0FBQztBQUNySSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw0REFBNEQsQ0FBQztBQUNsRyxPQUFPLEVBQUUscUNBQXFDLEVBQUUsTUFBTSw2R0FBNkcsQ0FBQztBQUNwSyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw2RUFBNkUsQ0FBQztBQUNuSCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwrRUFBK0UsQ0FBQztBQUN0SCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxrREFBa0QsQ0FBQzs7QUFvQ3RGLE1BQU0sT0FBTyxVQUFVOytHQUFWLFVBQVU7Z0hBQVYsVUFBVSxpQkEvQm5CLGNBQWM7WUFDZCxrQkFBa0I7WUFDbEIsd0JBQXdCO1lBQ3hCLDBCQUEwQjtZQUMxQixxQ0FBcUM7WUFDckMsb0JBQW9CO1lBQ3BCLG9CQUFvQjtZQUNwQixxQkFBcUIsYUFHckIsWUFBWTtZQUNaLG1CQUFtQjtZQUNuQixXQUFXO1lBQ1gsbUJBQW1CO1lBQ25CLGFBQWE7WUFDYixhQUFhO1lBQ2IsWUFBWTtZQUNaLFVBQVU7WUFDVixZQUFZLGFBR1osY0FBYztZQUNkLGtCQUFrQjtZQUNsQix3QkFBd0I7WUFDeEIsMEJBQTBCO1lBQzFCLHFDQUFxQztZQUNyQyxvQkFBb0I7WUFDcEIsb0JBQW9CO1lBQ3BCLHFCQUFxQjtnSEFHWixVQUFVLFlBckJuQixZQUFZO1lBQ1osbUJBQW1CO1lBQ25CLFdBQVc7WUFDWCxtQkFBbUI7WUFDbkIsYUFBYTtZQUNiLGFBQWE7WUFDYixZQUFZOzs0RkFlSCxVQUFVO2tCQWpDdEIsUUFBUTttQkFBQztvQkFDUixZQUFZLEVBQUU7d0JBQ1osY0FBYzt3QkFDZCxrQkFBa0I7d0JBQ2xCLHdCQUF3Qjt3QkFDeEIsMEJBQTBCO3dCQUMxQixxQ0FBcUM7d0JBQ3JDLG9CQUFvQjt3QkFDcEIsb0JBQW9CO3dCQUNwQixxQkFBcUI7cUJBQ3RCO29CQUNELE9BQU8sRUFBRTt3QkFDUCxZQUFZO3dCQUNaLG1CQUFtQjt3QkFDbkIsV0FBVzt3QkFDWCxtQkFBbUI7d0JBQ25CLGFBQWE7d0JBQ2IsYUFBYTt3QkFDYixZQUFZO3dCQUNaLFVBQVU7d0JBQ1YsWUFBWTtxQkFDYjtvQkFDRCxPQUFPLEVBQUU7d0JBQ1AsY0FBYzt3QkFDZCxrQkFBa0I7d0JBQ2xCLHdCQUF3Qjt3QkFDeEIsMEJBQTBCO3dCQUMxQixxQ0FBcUM7d0JBQ3JDLG9CQUFvQjt3QkFDcEIsb0JBQW9CO3dCQUNwQixxQkFBcUI7cUJBQ3RCO2lCQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcclxuaW1wb3J0IHsgUm91dGVyTGluaywgUm91dGVyT3V0bGV0IH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcclxuaW1wb3J0IHsgUG9wb3Zlck1vZHVsZSB9IGZyb20gJ25neC1ib290c3RyYXAvcG9wb3Zlcic7XHJcbmltcG9ydCB7IFRvb2x0aXBNb2R1bGUgfSBmcm9tICduZ3gtYm9vdHN0cmFwL3Rvb2x0aXAnO1xyXG5pbXBvcnQgeyBOZ3hQYWdpbmF0aW9uTW9kdWxlIH0gZnJvbSAnbmd4LXBhZ2luYXRpb24nO1xyXG5pbXBvcnQgeyBJbmZyYU1vZHVsZSB9IGZyb20gJ25neC1zcC1pbmZyYSc7XHJcbmltcG9ydCB7IExvZ2luQ29tcG9uZW50IH0gZnJvbSAnLi4vbGliL2NvbXBvbmVudHMvbG9naW4vbG9naW4uY29tcG9uZW50JztcclxuaW1wb3J0IHsgUHJpbWFyeURyb3Bkb3duQ29tcG9uZW50IH0gZnJvbSAnLi4vbGliL2NvbXBvbmVudHMvbWVudS1sYXRlcmFsL2Ryb3Bkb3duL3ByaW1hcnktZHJvcGRvd24vcHJpbWFyeS1kcm9wZG93bi5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBTZWNvbmRhcnlEcm9wZG93bkNvbXBvbmVudCB9IGZyb20gJy4uL2xpYi9jb21wb25lbnRzL21lbnUtbGF0ZXJhbC9kcm9wZG93bi9zZWNvbmRhcnktZHJvcGRvd24vc2Vjb25kYXJ5LWRyb3Bkb3duLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IE1lbnVMYXRlcmFsQ29tcG9uZW50IH0gZnJvbSAnLi4vbGliL2NvbXBvbmVudHMvbWVudS1sYXRlcmFsL21lbnUvbWVudS1sYXRlcmFsLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IFNlbGVjYW9Fc3RhYmVsZWNpbWVudG9zTW9kYWxDb21wb25lbnQgfSBmcm9tICcuLi9saWIvY29tcG9uZW50cy9tZW51LWxhdGVyYWwvbWVudS9zZWxlY2FvLWVzdGFiZWxlY2ltZW50b3MtbW9kYWwvc2VsZWNhby1lc3RhYmVsZWNpbWVudG9zLW1vZGFsLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IER5bmFtaWNNZW51Q29tcG9uZW50IH0gZnJvbSAnLi4vbGliL2NvbXBvbmVudHMvbWVudS1sYXRlcmFsL3N1Ym1lbnVzL2R5bmFtaWMtbWVudS9keW5hbWljLW1lbnUuY29tcG9uZW50JztcclxuaW1wb3J0IHsgTm90aWZTdWJtZW51Q29tcG9uZW50IH0gZnJvbSAnLi4vbGliL2NvbXBvbmVudHMvbWVudS1sYXRlcmFsL3N1Ym1lbnVzL25vdGlmLXN1Ym1lbnUvbm90aWYtc3VibWVudS5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBOb3ZhU2VuaGFDb21wb25lbnQgfSBmcm9tICcuLi9saWIvY29tcG9uZW50cy9ub3ZhLXNlbmhhL25vdmEtc2VuaGFjb21wb25lbnQnO1xyXG5cclxuXHJcbkBOZ01vZHVsZSh7XHJcbiAgZGVjbGFyYXRpb25zOiBbXHJcbiAgICBMb2dpbkNvbXBvbmVudCxcclxuICAgIE5vdmFTZW5oYUNvbXBvbmVudCxcclxuICAgIFByaW1hcnlEcm9wZG93bkNvbXBvbmVudCxcclxuICAgIFNlY29uZGFyeURyb3Bkb3duQ29tcG9uZW50LFxyXG4gICAgU2VsZWNhb0VzdGFiZWxlY2ltZW50b3NNb2RhbENvbXBvbmVudCxcclxuICAgIE1lbnVMYXRlcmFsQ29tcG9uZW50LFxyXG4gICAgRHluYW1pY01lbnVDb21wb25lbnQsXHJcbiAgICBOb3RpZlN1Ym1lbnVDb21wb25lbnRcclxuICBdLFxyXG4gIGltcG9ydHM6IFtcclxuICAgIENvbW1vbk1vZHVsZSxcclxuICAgIFJlYWN0aXZlRm9ybXNNb2R1bGUsXHJcbiAgICBJbmZyYU1vZHVsZSxcclxuICAgIE5neFBhZ2luYXRpb25Nb2R1bGUsXHJcbiAgICBQb3BvdmVyTW9kdWxlLFxyXG4gICAgVG9vbHRpcE1vZHVsZSxcclxuICAgIENvbW1vbk1vZHVsZSxcclxuICAgIFJvdXRlckxpbmssXHJcbiAgICBSb3V0ZXJPdXRsZXRcclxuICBdLFxyXG4gIGV4cG9ydHM6IFtcclxuICAgIExvZ2luQ29tcG9uZW50LFxyXG4gICAgTm92YVNlbmhhQ29tcG9uZW50LFxyXG4gICAgUHJpbWFyeURyb3Bkb3duQ29tcG9uZW50LFxyXG4gICAgU2Vjb25kYXJ5RHJvcGRvd25Db21wb25lbnQsXHJcbiAgICBTZWxlY2FvRXN0YWJlbGVjaW1lbnRvc01vZGFsQ29tcG9uZW50LFxyXG4gICAgTWVudUxhdGVyYWxDb21wb25lbnQsXHJcbiAgICBEeW5hbWljTWVudUNvbXBvbmVudCxcclxuICAgIE5vdGlmU3VibWVudUNvbXBvbmVudFxyXG4gIF1cclxufSlcclxuZXhwb3J0IGNsYXNzIEF1dGhNb2R1bGUgeyB9Il19
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { HttpHeaders, HttpParams } from '@angular/common/http';
|
|
2
|
+
import { Injectable } from '@angular/core';
|
|
3
|
+
import { map, take, tap } from 'rxjs/operators';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "@angular/common/http";
|
|
6
|
+
import * as i2 from "@angular/router";
|
|
7
|
+
import * as i3 from "./storage/auth-storage.service";
|
|
8
|
+
import * as i4 from "../lib/custom/custom-login.service";
|
|
9
|
+
import * as i5 from "ngx-sp-infra";
|
|
10
|
+
export class AuthService {
|
|
11
|
+
// #endregion PRIVATE
|
|
12
|
+
// #endregion ==========> PROPERTIES <==========
|
|
13
|
+
constructor(_httpClient, _router, _authStorageService, _customLoginService, _ipServiceService) {
|
|
14
|
+
this._httpClient = _httpClient;
|
|
15
|
+
this._router = _router;
|
|
16
|
+
this._authStorageService = _authStorageService;
|
|
17
|
+
this._customLoginService = _customLoginService;
|
|
18
|
+
this._ipServiceService = _ipServiceService;
|
|
19
|
+
// #region ==========> PROPERTIES <==========
|
|
20
|
+
// #region PRIVATE
|
|
21
|
+
// private readonly _HOSTNAME: any = window.location.hostname.includes("localhost")
|
|
22
|
+
// ? `http://${window.location.hostname}`
|
|
23
|
+
// : `https://${window.location.hostname}`;
|
|
24
|
+
this._HOSTNAME = "https://siscandesv6.sispro.com.br";
|
|
25
|
+
this._BASE_URL = `${this._HOSTNAME}/SisproErpCloud/Service_Private/Infra/SpInfra2LoginWS/api/LoginSisproERP`; // SpInfra2WS
|
|
26
|
+
this._HTTP_HEADERS = new HttpHeaders().set('Content-Type', 'application/json');
|
|
27
|
+
this.ip = "undefined";
|
|
28
|
+
this.city = "undefined";
|
|
29
|
+
this.state = "undefined";
|
|
30
|
+
this.country = "undefined";
|
|
31
|
+
//this._BASE_URL = !environment.production ? this._BASE_URL : `${environment.SpInfra2LoginWS}/LoginSisproERP`;
|
|
32
|
+
this._BASE_URL.includes("localhost") || this._BASE_URL.includes('127.0.0.1')
|
|
33
|
+
? this._BASE_URL
|
|
34
|
+
: this._BASE_URL = "https://siscandesv6.sispro.com.br/SisproErpCloud/Service_Private/Infra/SpInfra2LoginWS/api/LoginSisproERP";
|
|
35
|
+
this.getParms();
|
|
36
|
+
}
|
|
37
|
+
// #region ==========> SERVICE METHODS <==========
|
|
38
|
+
// #region GET
|
|
39
|
+
getParms() {
|
|
40
|
+
this.ip = "undefined";
|
|
41
|
+
this._ipServiceService.getIPAddress().subscribe({
|
|
42
|
+
next: (res) => {
|
|
43
|
+
this.ip = res.ip;
|
|
44
|
+
},
|
|
45
|
+
error: (error) => {
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
this.city = "undefined";
|
|
49
|
+
this.state = "undefined";
|
|
50
|
+
this.country = "undefined";
|
|
51
|
+
this._ipServiceService.getDataUser().subscribe({
|
|
52
|
+
next: (res) => {
|
|
53
|
+
this.city = res.city;
|
|
54
|
+
this.state = res.region_code;
|
|
55
|
+
this.country = res.country_name;
|
|
56
|
+
},
|
|
57
|
+
error: (error) => {
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
geHostName() {
|
|
62
|
+
let product = window.location.pathname;
|
|
63
|
+
let index = product.indexOf("/auth/login");
|
|
64
|
+
if (index != -1) {
|
|
65
|
+
product = product.substring(0, index);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
product = "";
|
|
69
|
+
}
|
|
70
|
+
return this._HOSTNAME + product;
|
|
71
|
+
}
|
|
72
|
+
// #endregion GET
|
|
73
|
+
// #region POST
|
|
74
|
+
/** Realiza o login no sistema
|
|
75
|
+
* @param login Informações do formulário de login
|
|
76
|
+
* @returns Observable com os dados do login realizado, seja erro ou sucesso
|
|
77
|
+
*/
|
|
78
|
+
login(parmsLogin) {
|
|
79
|
+
let login = {
|
|
80
|
+
usuario: parmsLogin.usuario,
|
|
81
|
+
senha: parmsLogin.senha
|
|
82
|
+
};
|
|
83
|
+
const params = new HttpParams()
|
|
84
|
+
.set('dominio', parmsLogin.dominio)
|
|
85
|
+
.set('urlServidor', this.geHostName())
|
|
86
|
+
.set('ip', this.ip)
|
|
87
|
+
.set('browse', `${this._ipServiceService.getDataBrowserUser().browser} - ${this._ipServiceService.getDataBrowserUser().so}`)
|
|
88
|
+
.set('localization', `${this.city}, ${this.state}, ${this.country}`);
|
|
89
|
+
const url = `${this._BASE_URL}/ValidateLogin`;
|
|
90
|
+
const headers = this._HTTP_HEADERS;
|
|
91
|
+
return this._httpClient
|
|
92
|
+
.post(url, login, { 'params': params, 'headers': headers })
|
|
93
|
+
.pipe(take(1), tap((response) => {
|
|
94
|
+
if (response.FeedbackMessage != "") {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (response.Error) {
|
|
98
|
+
throw Error(response.ErrorMessage);
|
|
99
|
+
}
|
|
100
|
+
if (response.InitializePassword) {
|
|
101
|
+
//Inicializar password
|
|
102
|
+
this._authStorageService.logout();
|
|
103
|
+
}
|
|
104
|
+
else if (response.InfraInAuthTypeId == 1 && response.InfraIn2FaTypeId != null && response.InfraIn2FaTypeId == 1 && response.Is2FaEnabled) {
|
|
105
|
+
//Inicializar Autenticação Local 2 Fatores via Email
|
|
106
|
+
this._authStorageService.logout();
|
|
107
|
+
this._authStorageService.ip = this.ip;
|
|
108
|
+
this._authStorageService.tenantId = response.TenantId;
|
|
109
|
+
this._authStorageService.infraUsuarioId = response.InfraUsuarioId;
|
|
110
|
+
this._authStorageService.user = login.usuario;
|
|
111
|
+
this._authStorageService.userName = response.UserName;
|
|
112
|
+
this._authStorageService.dominio = response.Dominio;
|
|
113
|
+
this._authStorageService.isExternalLogin = false;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
this._authStorageService.ignoreCheckLogin = true;
|
|
117
|
+
this._authStorageService.isLoggedInSub.next(true);
|
|
118
|
+
this._authStorageService.ip = this.ip;
|
|
119
|
+
this._authStorageService.tenantId = response.TenantId;
|
|
120
|
+
this._authStorageService.infraUsuarioId = response.InfraUsuarioId;
|
|
121
|
+
this._authStorageService.infraEstabId = response.EstabelecimentoId;
|
|
122
|
+
this._authStorageService.infraEstabNome = response.NomeEstabelecimento;
|
|
123
|
+
this._authStorageService.infraEmpresaId = response.EmpresaId;
|
|
124
|
+
this._authStorageService.infraEmpresaNome = response.NomeEmpresa;
|
|
125
|
+
this._authStorageService.user = login.usuario;
|
|
126
|
+
this._authStorageService.userName = response.UserName;
|
|
127
|
+
this._authStorageService.authToken = response.Token;
|
|
128
|
+
this._authStorageService.dominio = response.Dominio;
|
|
129
|
+
this._authStorageService.isExternalLogin = false;
|
|
130
|
+
// Método com customizações para inicializações do Login
|
|
131
|
+
this._customLoginService.authLogin();
|
|
132
|
+
if (this._authStorageService.urlRedirect == '' || this._authStorageService.urlRedirect == '/' || this._authStorageService.urlRedirect == '/auth/login') {
|
|
133
|
+
// Método com customizações para redirecionamento da tela inicial após login ok
|
|
134
|
+
this._customLoginService.authNavigateToPage(this._router);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
this._router.navigate([this._authStorageService.urlRedirect]);
|
|
138
|
+
}
|
|
139
|
+
this._authStorageService.urlRedirect = "/";
|
|
140
|
+
}
|
|
141
|
+
}));
|
|
142
|
+
}
|
|
143
|
+
loginExternal(dominio, user, password) {
|
|
144
|
+
let login = {
|
|
145
|
+
usuario: user,
|
|
146
|
+
senha: password
|
|
147
|
+
};
|
|
148
|
+
const params = new HttpParams()
|
|
149
|
+
.set('dominio', dominio);
|
|
150
|
+
const url = `${this._BASE_URL}/ValidateExternalLogin`;
|
|
151
|
+
const headers = this._HTTP_HEADERS;
|
|
152
|
+
return this._httpClient
|
|
153
|
+
.post(url, login, { 'params': params, 'headers': headers })
|
|
154
|
+
.pipe(take(1), tap((response) => {
|
|
155
|
+
if (!response.Error) {
|
|
156
|
+
this._authStorageService.isLoggedInSub.next(true);
|
|
157
|
+
this._authStorageService.ip = this.ip;
|
|
158
|
+
this._authStorageService.tenantId = response.TenantId;
|
|
159
|
+
this._authStorageService.infraUsuarioId = response.InfraUsuarioId;
|
|
160
|
+
this._authStorageService.infraEstabId = response.EstabelecimentoId;
|
|
161
|
+
this._authStorageService.infraEstabNome = response.NomeEstabelecimento;
|
|
162
|
+
this._authStorageService.infraEmpresaId = response.EmpresaId;
|
|
163
|
+
this._authStorageService.infraEmpresaNome = response.NomeEmpresa;
|
|
164
|
+
this._authStorageService.user = login.usuario;
|
|
165
|
+
this._authStorageService.userName = response.UserName;
|
|
166
|
+
this._authStorageService.authToken = response.Token;
|
|
167
|
+
this._authStorageService.dominio = response.Dominio;
|
|
168
|
+
this._authStorageService.isExternalLogin = true;
|
|
169
|
+
}
|
|
170
|
+
}), map((response) => {
|
|
171
|
+
return response.Error;
|
|
172
|
+
}));
|
|
173
|
+
}
|
|
174
|
+
logout() {
|
|
175
|
+
this._authStorageService.logout();
|
|
176
|
+
localStorage.removeItem('configsServerUser');
|
|
177
|
+
localStorage.removeItem('configsServerPassword');
|
|
178
|
+
// Método com customizações para inicializações do Logout
|
|
179
|
+
this._customLoginService.authLogout();
|
|
180
|
+
this._router.navigate(["/auth/login"]);
|
|
181
|
+
}
|
|
182
|
+
validateAuthentication2Fa(code) {
|
|
183
|
+
let Code2Fa = {
|
|
184
|
+
infraUsuarioId: this._authStorageService.infraUsuarioId,
|
|
185
|
+
code: code
|
|
186
|
+
};
|
|
187
|
+
const params = new HttpParams()
|
|
188
|
+
.set('domain', this._authStorageService.dominio)
|
|
189
|
+
.set('user', this._authStorageService.user)
|
|
190
|
+
.set('userName', this._authStorageService.userName);
|
|
191
|
+
const url = `${this._BASE_URL}/ValidadeLogin2FaWithEmail`;
|
|
192
|
+
const headers = this._HTTP_HEADERS;
|
|
193
|
+
return this._httpClient
|
|
194
|
+
.post(url, Code2Fa, { 'params': params, 'headers': headers })
|
|
195
|
+
.pipe(take(1), tap((response) => {
|
|
196
|
+
if (response.Error) {
|
|
197
|
+
throw Error(response.ErrorMessage);
|
|
198
|
+
}
|
|
199
|
+
this._authStorageService.ignoreCheckLogin = true;
|
|
200
|
+
this._authStorageService.isLoggedInSub.next(true);
|
|
201
|
+
this._authStorageService.ip = this.ip;
|
|
202
|
+
this._authStorageService.tenantId = response.TenantId;
|
|
203
|
+
this._authStorageService.infraUsuarioId = response.InfraUsuarioId;
|
|
204
|
+
this._authStorageService.infraEstabId = response.EstabelecimentoId;
|
|
205
|
+
this._authStorageService.infraEstabNome = response.NomeEstabelecimento;
|
|
206
|
+
this._authStorageService.infraEmpresaId = response.EmpresaId;
|
|
207
|
+
this._authStorageService.infraEmpresaNome = response.NomeEmpresa;
|
|
208
|
+
this._authStorageService.user = this._authStorageService.user;
|
|
209
|
+
this._authStorageService.userName = response.UserName;
|
|
210
|
+
this._authStorageService.authToken = response.Token;
|
|
211
|
+
this._authStorageService.dominio = response.Dominio;
|
|
212
|
+
this._authStorageService.isExternalLogin = false;
|
|
213
|
+
// Método com customizações para inicializações do Login
|
|
214
|
+
this._customLoginService.authLogin();
|
|
215
|
+
if (this._authStorageService.urlRedirect == '' || this._authStorageService.urlRedirect == '/' || this._authStorageService.urlRedirect == '/auth/login') {
|
|
216
|
+
// Método com customizações para redirecionamento da tela inicial após login ok
|
|
217
|
+
this._customLoginService.authNavigateToPage(this._router);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
this._router.navigate([this._authStorageService.urlRedirect]);
|
|
221
|
+
}
|
|
222
|
+
this._authStorageService.urlRedirect = "/";
|
|
223
|
+
}));
|
|
224
|
+
}
|
|
225
|
+
GetNewCode2Fa() {
|
|
226
|
+
const params = new HttpParams()
|
|
227
|
+
.set('domain', this._authStorageService.dominio)
|
|
228
|
+
.set('user', this._authStorageService.user)
|
|
229
|
+
.set('ip', this.ip)
|
|
230
|
+
.set('browse', `${this._ipServiceService.getDataBrowserUser().browser} - ${this._ipServiceService.getDataBrowserUser().so}`)
|
|
231
|
+
.set('localization', `${this.city}, ${this.state}, ${this.country}`);
|
|
232
|
+
const url = `${this._BASE_URL}/GetNewCode2FaWithEmail`;
|
|
233
|
+
const headers = this._HTTP_HEADERS;
|
|
234
|
+
return this._httpClient
|
|
235
|
+
.post(url, null, { 'params': params, 'headers': headers })
|
|
236
|
+
.pipe(take(1), tap((response) => {
|
|
237
|
+
if (response.Error) {
|
|
238
|
+
throw Error(response.ErrorMessage);
|
|
239
|
+
}
|
|
240
|
+
}));
|
|
241
|
+
}
|
|
242
|
+
forgottenPassword(parms) {
|
|
243
|
+
this._authStorageService.logout();
|
|
244
|
+
const params = new HttpParams()
|
|
245
|
+
.set('domain', parms.dominioFgtPsw)
|
|
246
|
+
.set('user', parms.usuarioFgtPsw)
|
|
247
|
+
.set('urlServidor', this.geHostName())
|
|
248
|
+
.set('ip', this.ip)
|
|
249
|
+
.set('browse', `${this._ipServiceService.getDataBrowserUser().browser} - ${this._ipServiceService.getDataBrowserUser().so}`)
|
|
250
|
+
.set('localization', `${this.city}, ${this.state}, ${this.country}`);
|
|
251
|
+
const headers = this._HTTP_HEADERS;
|
|
252
|
+
const url = `${this._BASE_URL}/ForgottenPassword`;
|
|
253
|
+
return this._httpClient
|
|
254
|
+
.post(url, null, { 'params': params, 'headers': headers })
|
|
255
|
+
.pipe(take(1), tap((response) => {
|
|
256
|
+
if (response.Error) {
|
|
257
|
+
throw Error(response.ErrorMessage);
|
|
258
|
+
}
|
|
259
|
+
}));
|
|
260
|
+
}
|
|
261
|
+
recoverPassword(dominio, usuario, parms) {
|
|
262
|
+
let recupPassword = {
|
|
263
|
+
password: parms.password,
|
|
264
|
+
confirmPassword: parms.confirmPassword,
|
|
265
|
+
code: parms.code
|
|
266
|
+
};
|
|
267
|
+
const params = new HttpParams()
|
|
268
|
+
.set('domain', dominio)
|
|
269
|
+
.set('user', usuario);
|
|
270
|
+
const headers = this._HTTP_HEADERS;
|
|
271
|
+
const url = `${this._BASE_URL}/RecoverPassword`;
|
|
272
|
+
return this._httpClient
|
|
273
|
+
.post(url, recupPassword, { 'params': params, 'headers': headers })
|
|
274
|
+
.pipe(take(1), tap((response) => {
|
|
275
|
+
if (response.Error) {
|
|
276
|
+
throw Error(response.ErrorMessage);
|
|
277
|
+
}
|
|
278
|
+
}));
|
|
279
|
+
}
|
|
280
|
+
createPassword(dominio, usuario, parms) {
|
|
281
|
+
let recupPassword = {
|
|
282
|
+
password: parms.password,
|
|
283
|
+
confirmPassword: parms.confirmPassword,
|
|
284
|
+
code: parms.code
|
|
285
|
+
};
|
|
286
|
+
const params = new HttpParams()
|
|
287
|
+
.set('domain', dominio)
|
|
288
|
+
.set('user', usuario);
|
|
289
|
+
const headers = this._HTTP_HEADERS;
|
|
290
|
+
const url = `${this._BASE_URL}/CreatePassword`;
|
|
291
|
+
return this._httpClient
|
|
292
|
+
.post(url, recupPassword, { 'params': params, 'headers': headers })
|
|
293
|
+
.pipe(take(1), tap((response) => {
|
|
294
|
+
if (response.Error) {
|
|
295
|
+
throw Error(response.ErrorMessage);
|
|
296
|
+
}
|
|
297
|
+
}));
|
|
298
|
+
}
|
|
299
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthService, deps: [{ token: i1.HttpClient }, { token: i2.Router }, { token: i3.AuthStorageService }, { token: i4.LibCustomLoginService }, { token: i5.IpServiceService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
300
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthService, providedIn: 'root' }); }
|
|
301
|
+
}
|
|
302
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AuthService, decorators: [{
|
|
303
|
+
type: Injectable,
|
|
304
|
+
args: [{ providedIn: 'root' }]
|
|
305
|
+
}], ctorParameters: () => [{ type: i1.HttpClient }, { type: i2.Router }, { type: i3.AuthStorageService }, { type: i4.LibCustomLoginService }, { type: i5.IpServiceService }] });
|
|
306
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNwLWF1dGgvc3JjL2xpYi9hdXRoLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFjLFdBQVcsRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMzRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBSzNDLE9BQU8sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7Ozs7O0FBa0JoRCxNQUFNLE9BQU8sV0FBVztJQW1CdEIscUJBQXFCO0lBRXJCLGdEQUFnRDtJQUVoRCxZQUNVLFdBQXVCLEVBQ3ZCLE9BQWUsRUFDZixtQkFBdUMsRUFDdkMsbUJBQTBDLEVBQzFDLGlCQUFtQztRQUpuQyxnQkFBVyxHQUFYLFdBQVcsQ0FBWTtRQUN2QixZQUFPLEdBQVAsT0FBTyxDQUFRO1FBQ2Ysd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFvQjtRQUN2Qyx3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXVCO1FBQzFDLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBa0I7UUExQjdDLDZDQUE2QztRQUU3QyxrQkFBa0I7UUFFbEIsbUZBQW1GO1FBQ25GLDJDQUEyQztRQUMzQyw2Q0FBNkM7UUFFNUIsY0FBUyxHQUFRLG1DQUFtQyxDQUFDO1FBRXJELGNBQVMsR0FBVyxHQUFHLElBQUksQ0FBQyxTQUFTLDBFQUEwRSxDQUFDLENBQUMsYUFBYTtRQUM5SCxrQkFBYSxHQUFHLElBQUksV0FBVyxFQUFFLENBQUMsR0FBRyxDQUFDLGNBQWMsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1FBQ25GLE9BQUUsR0FBVyxXQUFXLENBQUM7UUFDekIsU0FBSSxHQUFXLFdBQVcsQ0FBQztRQUMzQixVQUFLLEdBQVcsV0FBVyxDQUFDO1FBQzVCLFlBQU8sR0FBVyxXQUFXLENBQUM7UUFhcEMsOEdBQThHO1FBQzlHLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQztZQUMxRSxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVM7WUFDaEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUcsMkdBQTJHLENBQUM7UUFFakksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxrREFBa0Q7SUFFbEQsY0FBYztJQUVOLFFBQVE7UUFDZCxJQUFJLENBQUMsRUFBRSxHQUFHLFdBQVcsQ0FBQztRQUV0QixJQUFJLENBQUMsaUJBQWlCLENBQUMsWUFBWSxFQUFFLENBQUMsU0FBUyxDQUFDO1lBQzlDLElBQUksRUFBRSxDQUFDLEdBQVEsRUFBRSxFQUFFO2dCQUNqQixJQUFJLENBQUMsRUFBRSxHQUFHLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDbkIsQ0FBQztZQUNELEtBQUssRUFBRSxDQUFDLEtBQVUsRUFBRSxFQUFFO1lBQ3RCLENBQUM7U0FDRixDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsSUFBSSxHQUFHLFdBQVcsQ0FBQztRQUN4QixJQUFJLENBQUMsS0FBSyxHQUFHLFdBQVcsQ0FBQztRQUN6QixJQUFJLENBQUMsT0FBTyxHQUFHLFdBQVcsQ0FBQztRQUUzQixJQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxFQUFFLENBQUMsU0FBUyxDQUFDO1lBQzdDLElBQUksRUFBRSxDQUFDLEdBQVEsRUFBRSxFQUFFO2dCQUNqQixJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLFdBQVcsQ0FBQztnQkFDN0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDO1lBQ2xDLENBQUM7WUFDRCxLQUFLLEVBQUUsQ0FBQyxLQUFVLEVBQUUsRUFBRTtZQUN0QixDQUFDO1NBQ0YsQ0FBQyxDQUFDO0lBRUwsQ0FBQztJQUVPLFVBQVU7UUFDaEIsSUFBSSxPQUFPLEdBQVcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUM7UUFFL0MsSUFBSSxLQUFLLEdBQVcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUVuRCxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ2hCLE9BQU8sR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN4QyxDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDZixDQUFDO1FBRUQsT0FBTyxJQUFJLENBQUMsU0FBUyxHQUFHLE9BQU8sQ0FBQztJQUNsQyxDQUFDO0lBRUQsaUJBQWlCO0lBRWpCLGVBQWU7SUFFZjs7O01BR0U7SUFDSyxLQUFLLENBQUMsVUFBcUI7UUFFaEMsSUFBSSxLQUFLLEdBQVU7WUFDakIsT0FBTyxFQUFFLFVBQVUsQ0FBQyxPQUFPO1lBQzNCLEtBQUssRUFBRSxVQUFVLENBQUMsS0FBSztTQUN4QixDQUFBO1FBRUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxVQUFVLEVBQUU7YUFFNUIsR0FBRyxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsT0FBTyxDQUFDO2FBQ2xDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2FBQ3JDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQzthQUNsQixHQUFHLENBQUMsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDLGtCQUFrQixFQUFFLENBQUMsT0FBTyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO2FBQzNILEdBQUcsQ0FBQyxjQUFjLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxLQUFLLEtBQUssSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFFdkUsTUFBTSxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsU0FBUyxnQkFBZ0IsQ0FBQztRQUU5QyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBRW5DLE9BQU8sSUFBSSxDQUFDLFdBQVc7YUFDcEIsSUFBSSxDQUFXLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsQ0FBQzthQUNwRSxJQUFJLENBQ0gsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNQLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBRWYsSUFBSSxRQUFRLENBQUMsZUFBZSxJQUFJLEVBQUUsRUFBRSxDQUFDO2dCQUNuQyxPQUFPO1lBQ1QsQ0FBQztZQUVELElBQUksUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNuQixNQUFNLEtBQUssQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDckMsQ0FBQztZQUVELElBQUksUUFBUSxDQUFDLGtCQUFrQixFQUFFLENBQUM7Z0JBQ2hDLHNCQUFzQjtnQkFDdEIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxDQUFDO1lBRXBDLENBQUM7aUJBQU0sSUFBSSxRQUFRLENBQUMsaUJBQWlCLElBQUksQ0FBQyxJQUFJLFFBQVEsQ0FBQyxnQkFBZ0IsSUFBSSxJQUFJLElBQUksUUFBUSxDQUFDLGdCQUFnQixJQUFJLENBQUMsSUFBSSxRQUFRLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQzNJLG9EQUFvRDtnQkFDcEQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUVsQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQztnQkFDdEQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDO2dCQUNsRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUM7Z0JBQzlDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQztnQkFDdEQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDO2dCQUNwRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztZQUVuRCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLG1CQUFtQixDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztnQkFFakQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBRWxELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDdEMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDO2dCQUN0RCxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYyxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUM7Z0JBQ2xFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDLGlCQUFpQixDQUFDO2dCQUNuRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYyxHQUFHLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQztnQkFDdkUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDO2dCQUM3RCxJQUFJLENBQUMsbUJBQW1CLENBQUMsZ0JBQWdCLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQztnQkFDakUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO2dCQUM5QyxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUM7Z0JBQ3RELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQztnQkFDcEQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDO2dCQUNwRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztnQkFFakQsd0RBQXdEO2dCQUN4RCxJQUFJLENBQUMsbUJBQW1CLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBRXJDLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsSUFBSSxFQUFFLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsSUFBSSxhQUFhLEVBQUUsQ0FBQztvQkFDdkosK0VBQStFO29CQUMvRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUM1RCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztnQkFDaEUsQ0FBQztnQkFFRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsV0FBVyxHQUFHLEdBQUcsQ0FBQztZQUM3QyxDQUFDO1FBRUgsQ0FBQyxDQUFDLENBQ0gsQ0FBQztJQUNOLENBQUM7SUFFTSxhQUFhLENBQUMsT0FBZSxFQUFFLElBQVksRUFBRSxRQUFnQjtRQUVsRSxJQUFJLEtBQUssR0FBVTtZQUNqQixPQUFPLEVBQUUsSUFBSTtZQUNiLEtBQUssRUFBRSxRQUFRO1NBQ2hCLENBQUE7UUFFRCxNQUFNLE1BQU0sR0FBRyxJQUFJLFVBQVUsRUFBRTthQUM1QixHQUFHLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRTNCLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsd0JBQXdCLENBQUM7UUFFdEQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztRQUVuQyxPQUFPLElBQUksQ0FBQyxXQUFXO2FBQ3BCLElBQUksQ0FBVyxHQUFHLEVBQUUsS0FBSyxFQUFFLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLENBQUM7YUFDcEUsSUFBSSxDQUNILElBQUksQ0FBQyxDQUFDLENBQUMsRUFDUCxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUVmLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ3BCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUVsRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ3RDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQztnQkFDdEQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDO2dCQUNsRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQyxpQkFBaUIsQ0FBQztnQkFDbkUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUMsbUJBQW1CLENBQUM7Z0JBQ3ZFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxjQUFjLEdBQUcsUUFBUSxDQUFDLFNBQVMsQ0FBQztnQkFDN0QsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGdCQUFnQixHQUFHLFFBQVEsQ0FBQyxXQUFXLENBQUM7Z0JBQ2pFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQztnQkFDOUMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsUUFBUSxDQUFDO2dCQUN0RCxJQUFJLENBQUMsbUJBQW1CLENBQUMsU0FBUyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7Z0JBQ3BELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQztnQkFDcEQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7WUFDbEQsQ0FBQztRQUVILENBQUMsQ0FBQyxFQUNGLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQ2YsT0FBTyxRQUFRLENBQUMsS0FBSyxDQUFDO1FBQ3hCLENBQUMsQ0FDQSxDQUVGLENBQUM7SUFDTixDQUFDO0lBRU0sTUFBTTtRQUNYLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUVsQyxZQUFZLENBQUMsVUFBVSxDQUFDLG1CQUFtQixDQUFDLENBQUM7UUFDN0MsWUFBWSxDQUFDLFVBQVUsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBRWpELHlEQUF5RDtRQUN6RCxJQUFJLENBQUMsbUJBQW1CLENBQUMsVUFBVSxFQUFFLENBQUM7UUFFdEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFTSx5QkFBeUIsQ0FBQyxJQUFZO1FBRTNDLElBQUksT0FBTyxHQUFZO1lBQ3JCLGNBQWMsRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYztZQUN2RCxJQUFJLEVBQUUsSUFBSTtTQUNYLENBQUE7UUFFRCxNQUFNLE1BQU0sR0FBRyxJQUFJLFVBQVUsRUFBRTthQUM1QixHQUFHLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUM7YUFDL0MsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDO2FBQzFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxDQUFBO1FBRXJELE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsNEJBQTRCLENBQUM7UUFFMUQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztRQUVuQyxPQUFPLElBQUksQ0FBQyxXQUFXO2FBQ3BCLElBQUksQ0FBVyxHQUFHLEVBQUUsT0FBTyxFQUFFLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLENBQUM7YUFDdEUsSUFBSSxDQUNILElBQUksQ0FBQyxDQUFDLENBQUMsRUFDUCxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUVmLElBQUksUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNuQixNQUFNLEtBQUssQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDckMsQ0FBQztZQUVELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7WUFFakQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFbEQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEVBQUUsR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3RDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQztZQUN0RCxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYyxHQUFHLFFBQVEsQ0FBQyxjQUFjLENBQUM7WUFDbEUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFlBQVksR0FBRyxRQUFRLENBQUMsaUJBQWlCLENBQUM7WUFDbkUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUMsbUJBQW1CLENBQUM7WUFDdkUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGNBQWMsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDO1lBQzdELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxnQkFBZ0IsR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDO1lBQ2pFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQztZQUM5RCxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUM7WUFDdEQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDO1lBQ3BELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLEdBQUcsUUFBUSxDQUFDLE9BQU8sQ0FBQztZQUNwRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztZQUVqRCx3REFBd0Q7WUFDeEQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFNBQVMsRUFBRSxDQUFDO1lBRXJDLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsSUFBSSxFQUFFLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsSUFBSSxhQUFhLEVBQUUsQ0FBQztnQkFDdkosK0VBQStFO2dCQUMvRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzVELENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQ2hFLENBQUM7WUFFRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsV0FBVyxHQUFHLEdBQUcsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FFSCxDQUFDO0lBQ04sQ0FBQztJQUVNLGFBQWE7UUFFbEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxVQUFVLEVBQUU7YUFDNUIsR0FBRyxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDO2FBQy9DLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQzthQUMxQyxHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUM7YUFDbEIsR0FBRyxDQUFDLFFBQVEsRUFBRSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLE9BQU8sTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQzthQUMzSCxHQUFHLENBQUMsY0FBYyxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsS0FBSyxLQUFLLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBRXZFLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMseUJBQXlCLENBQUM7UUFFdkQsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztRQUVuQyxPQUFPLElBQUksQ0FBQyxXQUFXO2FBQ3BCLElBQUksQ0FBVyxHQUFHLEVBQUUsSUFBSSxFQUFFLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLENBQUM7YUFDbkUsSUFBSSxDQUNILElBQUksQ0FBQyxDQUFDLENBQUMsRUFDUCxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUVmLElBQUksUUFBUSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUNuQixNQUFNLEtBQUssQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDckMsQ0FBQztRQUVILENBQUMsQ0FBQyxDQUVILENBQUM7SUFDTixDQUFDO0lBRU0saUJBQWlCLENBQUMsS0FBNEI7UUFFbkQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxDQUFDO1FBRWxDLE1BQU0sTUFBTSxHQUFHLElBQUksVUFBVSxFQUFFO2FBQzVCLEdBQUcsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLGFBQWEsQ0FBQzthQUNsQyxHQUFHLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQyxhQUFhLENBQUM7YUFDaEMsR0FBRyxDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7YUFDckMsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDO2FBQ2xCLEdBQUcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxPQUFPLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixDQUFDLGtCQUFrQixFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7YUFDM0gsR0FBRyxDQUFDLGNBQWMsRUFBRSxHQUFHLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLEtBQUssS0FBSyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUV2RSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBRW5DLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsb0JBQW9CLENBQUM7UUFFbEQsT0FBTyxJQUFJLENBQUMsV0FBVzthQUNwQixJQUFJLENBQVcsR0FBRyxFQUFFLElBQUksRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxDQUFDO2FBQ25FLElBQUksQ0FDSCxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQ1AsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFFZixJQUFJLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDbkIsTUFBTSxLQUFLLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3JDLENBQUM7UUFFSCxDQUFDLENBQUMsQ0FFSCxDQUFDO0lBRU4sQ0FBQztJQUVNLGVBQWUsQ0FBQyxPQUFlLEVBQUUsT0FBZSxFQUFFLEtBQW9CO1FBRTNFLElBQUksYUFBYSxHQUFrQjtZQUNqQyxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVE7WUFDeEIsZUFBZSxFQUFFLEtBQUssQ0FBQyxlQUFlO1lBQ3RDLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSTtTQUNqQixDQUFBO1FBRUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxVQUFVLEVBQUU7YUFDNUIsR0FBRyxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUM7YUFDdEIsR0FBRyxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQTtRQUV2QixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBRW5DLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsa0JBQWtCLENBQUM7UUFFaEQsT0FBTyxJQUFJLENBQUMsV0FBVzthQUNwQixJQUFJLENBQVcsR0FBRyxFQUFFLGFBQWEsRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxDQUFDO2FBQzVFLElBQUksQ0FDSCxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQ1AsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFFZixJQUFJLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDbkIsTUFBTSxLQUFLLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3JDLENBQUM7UUFFSCxDQUFDLENBQUMsQ0FFSCxDQUFDO0lBRU4sQ0FBQztJQUVNLGNBQWMsQ0FBQyxPQUFlLEVBQUUsT0FBZSxFQUFFLEtBQW9CO1FBRTFFLElBQUksYUFBYSxHQUFrQjtZQUNqQyxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVE7WUFDeEIsZUFBZSxFQUFFLEtBQUssQ0FBQyxlQUFlO1lBQ3RDLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSTtTQUNqQixDQUFBO1FBRUQsTUFBTSxNQUFNLEdBQUcsSUFBSSxVQUFVLEVBQUU7YUFDNUIsR0FBRyxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUM7YUFDdEIsR0FBRyxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQTtRQUV2QixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBRW5DLE1BQU0sR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsaUJBQWlCLENBQUM7UUFFL0MsT0FBTyxJQUFJLENBQUMsV0FBVzthQUNwQixJQUFJLENBQVcsR0FBRyxFQUFFLGFBQWEsRUFBRSxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxDQUFDO2FBQzVFLElBQUksQ0FDSCxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQ1AsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFFZixJQUFJLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDbkIsTUFBTSxLQUFLLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3JDLENBQUM7UUFFSCxDQUFDLENBQUMsQ0FDSCxDQUFDO0lBQ04sQ0FBQzsrR0E1WlUsV0FBVzttSEFBWCxXQUFXLGNBSFIsTUFBTTs7NEZBR1QsV0FBVztrQkFKdkIsVUFBVTttQkFDVCxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwQ2xpZW50LCBIdHRwSGVhZGVycywgSHR0cFBhcmFtcyB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5pbXBvcnQgeyBMaWJDdXN0b21Mb2dpblNlcnZpY2UgfSBmcm9tICcuLi9saWIvY3VzdG9tL2N1c3RvbS1sb2dpbi5zZXJ2aWNlJztcclxuXHJcbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgbWFwLCB0YWtlLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5cclxuaW1wb3J0IHsgQ29kZTJGYSB9IGZyb20gJy4vbW9kZWxzL2NvZGUtMmZhJztcclxuaW1wb3J0IHsgRm9yZ290dGVuUGFzc3dvcmRGb3JtIH0gZnJvbSAnLi9tb2RlbHMvZm9yZ290dGVuLXBhc3N3b3JkLWZvcm0nO1xyXG5pbXBvcnQgeyBMb2dpbiB9IGZyb20gJy4vbW9kZWxzL2xvZ2luJztcclxuaW1wb3J0IHsgTG9naW5Gb3JtIH0gZnJvbSAnLi9tb2RlbHMvbG9naW4tZm9ybSc7XHJcbmltcG9ydCB7IE5vdmFTZW5oYUZvcm0gfSBmcm9tICcuL21vZGVscy9ub3ZhLXNlbmhhLWZvcm0nO1xyXG5pbXBvcnQgeyBQYXNzd29yZFJlY3VwIH0gZnJvbSAnLi9tb2RlbHMvcGFzc3dvcmQtcmVjdXAnO1xyXG5pbXBvcnQgeyBSZXRMb2dpbiB9IGZyb20gJy4vbW9kZWxzL3JldC1sb2dpbic7XHJcblxyXG5pbXBvcnQgeyBJcFNlcnZpY2VTZXJ2aWNlLCBSZXRFcnJvciB9IGZyb20gJ25neC1zcC1pbmZyYSc7XHJcbmltcG9ydCB7IEF1dGhTdG9yYWdlU2VydmljZSB9IGZyb20gJy4vc3RvcmFnZS9hdXRoLXN0b3JhZ2Uuc2VydmljZSc7XHJcblxyXG5ASW5qZWN0YWJsZShcclxuICB7IHByb3ZpZGVkSW46ICdyb290JyB9XHJcbilcclxuXHJcbmV4cG9ydCBjbGFzcyBBdXRoU2VydmljZSB7XHJcblxyXG4gIC8vICNyZWdpb24gPT09PT09PT09PT4gUFJPUEVSVElFUyA8PT09PT09PT09PVxyXG5cclxuICAvLyAjcmVnaW9uIFBSSVZBVEVcclxuXHJcbiAgLy8gcHJpdmF0ZSByZWFkb25seSBfSE9TVE5BTUU6IGFueSA9IHdpbmRvdy5sb2NhdGlvbi5ob3N0bmFtZS5pbmNsdWRlcyhcImxvY2FsaG9zdFwiKVxyXG4gIC8vICAgPyBgaHR0cDovLyR7d2luZG93LmxvY2F0aW9uLmhvc3RuYW1lfWBcclxuICAvLyAgIDogYGh0dHBzOi8vJHt3aW5kb3cubG9jYXRpb24uaG9zdG5hbWV9YDtcclxuXHJcbiAgcHJpdmF0ZSByZWFkb25seSBfSE9TVE5BTUU6IGFueSA9IFwiaHR0cHM6Ly9zaXNjYW5kZXN2Ni5zaXNwcm8uY29tLmJyXCI7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgX0JBU0VfVVJMOiBzdHJpbmcgPSBgJHt0aGlzLl9IT1NUTkFNRX0vU2lzcHJvRXJwQ2xvdWQvU2VydmljZV9Qcml2YXRlL0luZnJhL1NwSW5mcmEyTG9naW5XUy9hcGkvTG9naW5TaXNwcm9FUlBgOyAvLyBTcEluZnJhMldTXHJcbiAgcHJpdmF0ZSByZWFkb25seSBfSFRUUF9IRUFERVJTID0gbmV3IEh0dHBIZWFkZXJzKCkuc2V0KCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xyXG4gIHByaXZhdGUgaXA6IHN0cmluZyA9IFwidW5kZWZpbmVkXCI7XHJcbiAgcHJpdmF0ZSBjaXR5OiBzdHJpbmcgPSBcInVuZGVmaW5lZFwiO1xyXG4gIHByaXZhdGUgc3RhdGU6IHN0cmluZyA9IFwidW5kZWZpbmVkXCI7XHJcbiAgcHJpdmF0ZSBjb3VudHJ5OiBzdHJpbmcgPSBcInVuZGVmaW5lZFwiO1xyXG5cclxuICAvLyAjZW5kcmVnaW9uIFBSSVZBVEVcclxuXHJcbiAgLy8gI2VuZHJlZ2lvbiA9PT09PT09PT09PiBQUk9QRVJUSUVTIDw9PT09PT09PT09XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBfaHR0cENsaWVudDogSHR0cENsaWVudCxcclxuICAgIHByaXZhdGUgX3JvdXRlcjogUm91dGVyLFxyXG4gICAgcHJpdmF0ZSBfYXV0aFN0b3JhZ2VTZXJ2aWNlOiBBdXRoU3RvcmFnZVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIF9jdXN0b21Mb2dpblNlcnZpY2U6IExpYkN1c3RvbUxvZ2luU2VydmljZSxcclxuICAgIHByaXZhdGUgX2lwU2VydmljZVNlcnZpY2U6IElwU2VydmljZVNlcnZpY2UsXHJcbiAgKSB7XHJcbiAgICAvL3RoaXMuX0JBU0VfVVJMID0gIWVudmlyb25tZW50LnByb2R1Y3Rpb24gPyB0aGlzLl9CQVNFX1VSTCA6IGAke2Vudmlyb25tZW50LlNwSW5mcmEyTG9naW5XU30vTG9naW5TaXNwcm9FUlBgO1xyXG4gICAgdGhpcy5fQkFTRV9VUkwuaW5jbHVkZXMoXCJsb2NhbGhvc3RcIikgfHwgdGhpcy5fQkFTRV9VUkwuaW5jbHVkZXMoJzEyNy4wLjAuMScpXHJcbiAgICAgID8gdGhpcy5fQkFTRV9VUkxcclxuICAgICAgOiB0aGlzLl9CQVNFX1VSTCA9IFwiaHR0cHM6Ly9zaXNjYW5kZXN2Ni5zaXNwcm8uY29tLmJyL1Npc3Byb0VycENsb3VkL1NlcnZpY2VfUHJpdmF0ZS9JbmZyYS9TcEluZnJhMkxvZ2luV1MvYXBpL0xvZ2luU2lzcHJvRVJQXCI7XHJcblxyXG4gICAgdGhpcy5nZXRQYXJtcygpO1xyXG4gIH1cclxuXHJcbiAgLy8gI3JlZ2lvbiA9PT09PT09PT09PiBTRVJWSUNFIE1FVEhPRFMgPD09PT09PT09PT1cclxuXHJcbiAgLy8gI3JlZ2lvbiBHRVRcclxuXHJcbiAgcHJpdmF0ZSBnZXRQYXJtcygpOiB2b2lkIHtcclxuICAgIHRoaXMuaXAgPSBcInVuZGVmaW5lZFwiO1xyXG5cclxuICAgIHRoaXMuX2lwU2VydmljZVNlcnZpY2UuZ2V0SVBBZGRyZXNzKCkuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XHJcbiAgICAgICAgdGhpcy5pcCA9IHJlcy5pcDtcclxuICAgICAgfSxcclxuICAgICAgZXJyb3I6IChlcnJvcjogYW55KSA9PiB7XHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLmNpdHkgPSBcInVuZGVmaW5lZFwiO1xyXG4gICAgdGhpcy5zdGF0ZSA9IFwidW5kZWZpbmVkXCI7XHJcbiAgICB0aGlzLmNvdW50cnkgPSBcInVuZGVmaW5lZFwiO1xyXG5cclxuICAgIHRoaXMuX2lwU2VydmljZVNlcnZpY2UuZ2V0RGF0YVVzZXIoKS5zdWJzY3JpYmUoe1xyXG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcclxuICAgICAgICB0aGlzLmNpdHkgPSByZXMuY2l0eTtcclxuICAgICAgICB0aGlzLnN0YXRlID0gcmVzLnJlZ2lvbl9jb2RlO1xyXG4gICAgICAgIHRoaXMuY291bnRyeSA9IHJlcy5jb3VudHJ5X25hbWU7XHJcbiAgICAgIH0sXHJcbiAgICAgIGVycm9yOiAoZXJyb3I6IGFueSkgPT4ge1xyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcblxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZUhvc3ROYW1lKCk6IHN0cmluZyB7XHJcbiAgICBsZXQgcHJvZHVjdDogc3RyaW5nID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lO1xyXG5cclxuICAgIGxldCBpbmRleDogbnVtYmVyID0gcHJvZHVjdC5pbmRleE9mKFwiL2F1dGgvbG9naW5cIik7XHJcblxyXG4gICAgaWYgKGluZGV4ICE9IC0xKSB7XHJcbiAgICAgIHByb2R1Y3QgPSBwcm9kdWN0LnN1YnN0cmluZygwLCBpbmRleCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBwcm9kdWN0ID0gXCJcIjtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5fSE9TVE5BTUUgKyBwcm9kdWN0O1xyXG4gIH1cclxuXHJcbiAgLy8gI2VuZHJlZ2lvbiBHRVRcclxuXHJcbiAgLy8gI3JlZ2lvbiBQT1NUXHJcblxyXG4gIC8qKiBSZWFsaXphIG8gbG9naW4gbm8gc2lzdGVtYVxyXG4gICogQHBhcmFtIGxvZ2luIEluZm9ybWHDp8O1ZXMgZG8gZm9ybXVsw6FyaW8gZGUgbG9naW5cclxuICAqIEByZXR1cm5zIE9ic2VydmFibGUgY29tIG9zIGRhZG9zIGRvIGxvZ2luIHJlYWxpemFkbywgc2VqYSBlcnJvIG91IHN1Y2Vzc29cclxuICAqL1xyXG4gIHB1YmxpYyBsb2dpbihwYXJtc0xvZ2luOiBMb2dpbkZvcm0pOiBPYnNlcnZhYmxlPFJldExvZ2luPiB7XHJcblxyXG4gICAgbGV0IGxvZ2luOiBMb2dpbiA9IHtcclxuICAgICAgdXN1YXJpbzogcGFybXNMb2dpbi51c3VhcmlvLFxyXG4gICAgICBzZW5oYTogcGFybXNMb2dpbi5zZW5oYVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBIdHRwUGFyYW1zKClcclxuXHJcbiAgICAgIC5zZXQoJ2RvbWluaW8nLCBwYXJtc0xvZ2luLmRvbWluaW8pXHJcbiAgICAgIC5zZXQoJ3VybFNlcnZpZG9yJywgdGhpcy5nZUhvc3ROYW1lKCkpXHJcbiAgICAgIC5zZXQoJ2lwJywgdGhpcy5pcClcclxuICAgICAgLnNldCgnYnJvd3NlJywgYCR7dGhpcy5faXBTZXJ2aWNlU2VydmljZS5nZXREYXRhQnJvd3NlclVzZXIoKS5icm93c2VyfSAtICR7dGhpcy5faXBTZXJ2aWNlU2VydmljZS5nZXREYXRhQnJvd3NlclVzZXIoKS5zb31gKVxyXG4gICAgICAuc2V0KCdsb2NhbGl6YXRpb24nLCBgJHt0aGlzLmNpdHl9LCAke3RoaXMuc3RhdGV9LCAke3RoaXMuY291bnRyeX1gKTtcclxuXHJcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLl9CQVNFX1VSTH0vVmFsaWRhdGVMb2dpbmA7XHJcblxyXG4gICAgY29uc3QgaGVhZGVycyA9IHRoaXMuX0hUVFBfSEVBREVSUztcclxuXHJcbiAgICByZXR1cm4gdGhpcy5faHR0cENsaWVudFxyXG4gICAgICAucG9zdDxSZXRMb2dpbj4odXJsLCBsb2dpbiwgeyAncGFyYW1zJzogcGFyYW1zLCAnaGVhZGVycyc6IGhlYWRlcnMgfSlcclxuICAgICAgLnBpcGUoXHJcbiAgICAgICAgdGFrZSgxKSxcclxuICAgICAgICB0YXAoKHJlc3BvbnNlKSA9PiB7XHJcblxyXG4gICAgICAgICAgaWYgKHJlc3BvbnNlLkZlZWRiYWNrTWVzc2FnZSAhPSBcIlwiKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpZiAocmVzcG9uc2UuRXJyb3IpIHtcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IocmVzcG9uc2UuRXJyb3JNZXNzYWdlKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpZiAocmVzcG9uc2UuSW5pdGlhbGl6ZVBhc3N3b3JkKSB7XHJcbiAgICAgICAgICAgIC8vSW5pY2lhbGl6YXIgcGFzc3dvcmRcclxuICAgICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLmxvZ291dCgpO1xyXG5cclxuICAgICAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2UuSW5mcmFJbkF1dGhUeXBlSWQgPT0gMSAmJiByZXNwb25zZS5JbmZyYUluMkZhVHlwZUlkICE9IG51bGwgJiYgcmVzcG9uc2UuSW5mcmFJbjJGYVR5cGVJZCA9PSAxICYmIHJlc3BvbnNlLklzMkZhRW5hYmxlZCkge1xyXG4gICAgICAgICAgICAvL0luaWNpYWxpemFyIEF1dGVudGljYcOnw6NvIExvY2FsIDIgRmF0b3JlcyB2aWEgRW1haWxcclxuICAgICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLmxvZ291dCgpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLmlwID0gdGhpcy5pcDtcclxuICAgICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLnRlbmFudElkID0gcmVzcG9uc2UuVGVuYW50SWQ7XHJcbiAgICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS5pbmZyYVVzdWFyaW9JZCA9IHJlc3BvbnNlLkluZnJhVXN1YXJpb0lkO1xyXG4gICAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UudXNlciA9IGxvZ2luLnVzdWFyaW87XHJcbiAgICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS51c2VyTmFtZSA9IHJlc3BvbnNlLlVzZXJOYW1lO1xyXG4gICAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuZG9taW5pbyA9IHJlc3BvbnNlLkRvbWluaW87XHJcbiAgICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS5pc0V4dGVybmFsTG9naW4gPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuaWdub3JlQ2hlY2tMb2dpbiA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuaXNMb2dnZWRJblN1Yi5uZXh0KHRydWUpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLmlwID0gdGhpcy5pcDtcclxuICAgICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLnRlbmFudElkID0gcmVzcG9uc2UuVGVuYW50SWQ7XHJcbiAgICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS5pbmZyYVVzdWFyaW9JZCA9IHJlc3BvbnNlLkluZnJhVXN1YXJpb0lkO1xyXG4gICAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuaW5mcmFFc3RhYklkID0gcmVzcG9uc2UuRXN0YWJlbGVjaW1lbnRvSWQ7XHJcbiAgICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS5pbmZyYUVzdGFiTm9tZSA9IHJlc3BvbnNlLk5vbWVFc3RhYmVsZWNpbWVudG87XHJcbiAgICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS5pbmZyYUVtcHJlc2FJZCA9IHJlc3BvbnNlLkVtcHJlc2FJZDtcclxuICAgICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLmluZnJhRW1wcmVzYU5vbWUgPSByZXNwb25zZS5Ob21lRW1wcmVzYTtcclxuICAgICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLnVzZXIgPSBsb2dpbi51c3VhcmlvO1xyXG4gICAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UudXNlck5hbWUgPSByZXNwb25zZS5Vc2VyTmFtZTtcclxuICAgICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLmF1dGhUb2tlbiA9IHJlc3BvbnNlLlRva2VuO1xyXG4gICAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuZG9taW5pbyA9IHJlc3BvbnNlLkRvbWluaW87XHJcbiAgICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS5pc0V4dGVybmFsTG9naW4gPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIC8vIE3DqXRvZG8gY29tIGN1c3RvbWl6YcOnw7VlcyBwYXJhIGluaWNpYWxpemHDp8O1ZXMgZG8gTG9naW5cclxuICAgICAgICAgICAgdGhpcy5fY3VzdG9tTG9naW5TZXJ2aWNlLmF1dGhMb2dpbigpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS51cmxSZWRpcmVjdCA9PSAnJyB8fCB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UudXJsUmVkaXJlY3QgPT0gJy8nIHx8IHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS51cmxSZWRpcmVjdCA9PSAnL2F1dGgvbG9naW4nKSB7XHJcbiAgICAgICAgICAgICAgLy8gTcOpdG9kbyBjb20gY3VzdG9taXphw6fDtWVzIHBhcmEgcmVkaXJlY2lvbmFtZW50byBkYSB0ZWxhIGluaWNpYWwgYXDDs3MgbG9naW4gb2tcclxuICAgICAgICAgICAgICB0aGlzLl9jdXN0b21Mb2dpblNlcnZpY2UuYXV0aE5hdmlnYXRlVG9QYWdlKHRoaXMuX3JvdXRlcik7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgdGhpcy5fcm91dGVyLm5hdmlnYXRlKFt0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UudXJsUmVkaXJlY3RdKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLnVybFJlZGlyZWN0ID0gXCIvXCI7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbG9naW5FeHRlcm5hbChkb21pbmlvOiBzdHJpbmcsIHVzZXI6IHN0cmluZywgcGFzc3dvcmQ6IHN0cmluZyk6IE9ic2VydmFibGU8Ym9vbGVhbj4ge1xyXG5cclxuICAgIGxldCBsb2dpbjogTG9naW4gPSB7XHJcbiAgICAgIHVzdWFyaW86IHVzZXIsXHJcbiAgICAgIHNlbmhhOiBwYXNzd29yZFxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBIdHRwUGFyYW1zKClcclxuICAgICAgLnNldCgnZG9taW5pbycsIGRvbWluaW8pO1xyXG5cclxuICAgIGNvbnN0IHVybCA9IGAke3RoaXMuX0JBU0VfVVJMfS9WYWxpZGF0ZUV4dGVybmFsTG9naW5gO1xyXG5cclxuICAgIGNvbnN0IGhlYWRlcnMgPSB0aGlzLl9IVFRQX0hFQURFUlM7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuX2h0dHBDbGllbnRcclxuICAgICAgLnBvc3Q8UmV0TG9naW4+KHVybCwgbG9naW4sIHsgJ3BhcmFtcyc6IHBhcmFtcywgJ2hlYWRlcnMnOiBoZWFkZXJzIH0pXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIHRha2UoMSksXHJcbiAgICAgICAgdGFwKChyZXNwb25zZSkgPT4ge1xyXG5cclxuICAgICAgICAgIGlmICghcmVzcG9uc2UuRXJyb3IpIHtcclxuICAgICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLmlzTG9nZ2VkSW5TdWIubmV4dCh0cnVlKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS5pcCA9IHRoaXMuaXA7XHJcbiAgICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS50ZW5hbnRJZCA9IHJlc3BvbnNlLlRlbmFudElkO1xyXG4gICAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuaW5mcmFVc3VhcmlvSWQgPSByZXNwb25zZS5JbmZyYVVzdWFyaW9JZDtcclxuICAgICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLmluZnJhRXN0YWJJZCA9IHJlc3BvbnNlLkVzdGFiZWxlY2ltZW50b0lkO1xyXG4gICAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuaW5mcmFFc3RhYk5vbWUgPSByZXNwb25zZS5Ob21lRXN0YWJlbGVjaW1lbnRvO1xyXG4gICAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuaW5mcmFFbXByZXNhSWQgPSByZXNwb25zZS5FbXByZXNhSWQ7XHJcbiAgICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS5pbmZyYUVtcHJlc2FOb21lID0gcmVzcG9uc2UuTm9tZUVtcHJlc2E7XHJcbiAgICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS51c2VyID0gbG9naW4udXN1YXJpbztcclxuICAgICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLnVzZXJOYW1lID0gcmVzcG9uc2UuVXNlck5hbWU7XHJcbiAgICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS5hdXRoVG9rZW4gPSByZXNwb25zZS5Ub2tlbjtcclxuICAgICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLmRvbWluaW8gPSByZXNwb25zZS5Eb21pbmlvO1xyXG4gICAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuaXNFeHRlcm5hbExvZ2luID0gdHJ1ZTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSksXHJcbiAgICAgICAgbWFwKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlLkVycm9yO1xyXG4gICAgICAgIH1cclxuICAgICAgICApXHJcblxyXG4gICAgICApO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGxvZ291dCgpIHtcclxuICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS5sb2dvdXQoKTtcclxuXHJcbiAgICBsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbSgnY29uZmlnc1NlcnZlclVzZXInKTtcclxuICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKCdjb25maWdzU2VydmVyUGFzc3dvcmQnKTtcclxuXHJcbiAgICAvLyBNw6l0b2RvIGNvbSBjdXN0b21pemHDp8O1ZXMgcGFyYSBpbmljaWFsaXphw6fDtWVzIGRvIExvZ291dFxyXG4gICAgdGhpcy5fY3VzdG9tTG9naW5TZXJ2aWNlLmF1dGhMb2dvdXQoKTtcclxuXHJcbiAgICB0aGlzLl9yb3V0ZXIubmF2aWdhdGUoW1wiL2F1dGgvbG9naW5cIl0pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHZhbGlkYXRlQXV0aGVudGljYXRpb24yRmEoY29kZTogc3RyaW5nKTogT2JzZXJ2YWJsZTxSZXRMb2dpbj4ge1xyXG5cclxuICAgIGxldCBDb2RlMkZhOiBDb2RlMkZhID0ge1xyXG4gICAgICBpbmZyYVVzdWFyaW9JZDogdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLmluZnJhVXN1YXJpb0lkLFxyXG4gICAgICBjb2RlOiBjb2RlXHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgcGFyYW1zID0gbmV3IEh0dHBQYXJhbXMoKVxyXG4gICAgICAuc2V0KCdkb21haW4nLCB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuZG9taW5pbylcclxuICAgICAgLnNldCgndXNlcicsIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS51c2VyKVxyXG4gICAgICAuc2V0KCd1c2VyTmFtZScsIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS51c2VyTmFtZSlcclxuXHJcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLl9CQVNFX1VSTH0vVmFsaWRhZGVMb2dpbjJGYVdpdGhFbWFpbGA7XHJcblxyXG4gICAgY29uc3QgaGVhZGVycyA9IHRoaXMuX0hUVFBfSEVBREVSUztcclxuXHJcbiAgICByZXR1cm4gdGhpcy5faHR0cENsaWVudFxyXG4gICAgICAucG9zdDxSZXRMb2dpbj4odXJsLCBDb2RlMkZhLCB7ICdwYXJhbXMnOiBwYXJhbXMsICdoZWFkZXJzJzogaGVhZGVycyB9KVxyXG4gICAgICAucGlwZShcclxuICAgICAgICB0YWtlKDEpLFxyXG4gICAgICAgIHRhcCgocmVzcG9uc2UpID0+IHtcclxuXHJcbiAgICAgICAgICBpZiAocmVzcG9uc2UuRXJyb3IpIHtcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IocmVzcG9uc2UuRXJyb3JNZXNzYWdlKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuaWdub3JlQ2hlY2tMb2dpbiA9IHRydWU7XHJcblxyXG4gICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLmlzTG9nZ2VkSW5TdWIubmV4dCh0cnVlKTtcclxuXHJcbiAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuaXAgPSB0aGlzLmlwO1xyXG4gICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLnRlbmFudElkID0gcmVzcG9uc2UuVGVuYW50SWQ7XHJcbiAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuaW5mcmFVc3VhcmlvSWQgPSByZXNwb25zZS5JbmZyYVVzdWFyaW9JZDtcclxuICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS5pbmZyYUVzdGFiSWQgPSByZXNwb25zZS5Fc3RhYmVsZWNpbWVudG9JZDtcclxuICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS5pbmZyYUVzdGFiTm9tZSA9IHJlc3BvbnNlLk5vbWVFc3RhYmVsZWNpbWVudG87XHJcbiAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuaW5mcmFFbXByZXNhSWQgPSByZXNwb25zZS5FbXByZXNhSWQ7XHJcbiAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UuaW5mcmFFbXByZXNhTm9tZSA9IHJlc3BvbnNlLk5vbWVFbXByZXNhO1xyXG4gICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLnVzZXIgPSB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UudXNlcjtcclxuICAgICAgICAgIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS51c2VyTmFtZSA9IHJlc3BvbnNlLlVzZXJOYW1lO1xyXG4gICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLmF1dGhUb2tlbiA9IHJlc3BvbnNlLlRva2VuO1xyXG4gICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLmRvbWluaW8gPSByZXNwb25zZS5Eb21pbmlvO1xyXG4gICAgICAgICAgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLmlzRXh0ZXJuYWxMb2dpbiA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgIC8vIE3DqXRvZG8gY29tIGN1c3RvbWl6YcOnw7VlcyBwYXJhIGluaWNpYWxpemHDp8O1ZXMgZG8gTG9naW5cclxuICAgICAgICAgIHRoaXMuX2N1c3RvbUxvZ2luU2VydmljZS5hdXRoTG9naW4oKTtcclxuXHJcbiAgICAgICAgICBpZiAodGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLnVybFJlZGlyZWN0ID09ICcnIHx8IHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS51cmxSZWRpcmVjdCA9PSAnLycgfHwgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLnVybFJlZGlyZWN0ID09ICcvYXV0aC9sb2dpbicpIHtcclxuICAgICAgICAgICAgLy8gTcOpdG9kbyBjb20gY3VzdG9taXphw6fDtWVzIHBhcmEgcmVkaXJlY2lvbmFtZW50byBkYSB0ZWxhIGluaWNpYWwgYXDDs3MgbG9naW4gb2tcclxuICAgICAgICAgICAgdGhpcy5fY3VzdG9tTG9naW5TZXJ2aWNlLmF1dGhOYXZpZ2F0ZVRvUGFnZSh0aGlzLl9yb3V0ZXIpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fcm91dGVyLm5hdmlnYXRlKFt0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UudXJsUmVkaXJlY3RdKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UudXJsUmVkaXJlY3QgPSBcIi9cIjtcclxuICAgICAgICB9KVxyXG5cclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBHZXROZXdDb2RlMkZhKCk6IE9ic2VydmFibGU8UmV0RXJyb3I+IHtcclxuXHJcbiAgICBjb25zdCBwYXJhbXMgPSBuZXcgSHR0cFBhcmFtcygpXHJcbiAgICAgIC5zZXQoJ2RvbWFpbicsIHRoaXMuX2F1dGhTdG9yYWdlU2VydmljZS5kb21pbmlvKVxyXG4gICAgICAuc2V0KCd1c2VyJywgdGhpcy5fYXV0aFN0b3JhZ2VTZXJ2aWNlLnVzZXIpXHJcbiAgICAgIC5zZXQoJ2lwJywgdGhpcy5pcClcclxuICAgICAgLnNldCgnYnJvd3NlJywgYCR7dGhpcy5faXBTZXJ2aWNlU2VydmljZS5nZXREYXRhQnJvd3NlclVzZXIoKS5icm93c2VyfSAtICR7dGhpcy5faXBTZXJ2aWNlU2VydmljZS5nZXREYXRhQnJvd3NlclVzZXIoKS5zb31gKVxyXG4gICAgICAuc2V0KCdsb2NhbGl6YXRpb24nLCBgJHt0aGlzLmNpdHl9LCAke3RoaXMuc3RhdGV9LCAke3RoaXMuY291bnRyeX1gKTtcclxuXHJcbiAgICBjb25zdCB1cmwgPSBgJHt0aGlzLl9CQVNFX1VSTH0vR2V0TmV3Q29kZTJGYVdpdGhFbWFpbGA7XHJcblxyXG4gICAgY29uc3QgaGVhZGVycyA9IHRoaXMuX0hUVFBfSEVBREVSUztcclxuXHJcbiAgICByZXR1cm4gdGhpcy5faHR0cENsaWVudFxyXG4gICAgICAucG9zdDxSZXRMb2dpbj4odXJsLCBudWxsLCB7ICdwYXJhbXMnOiBwYXJhbXMsICdoZWFkZXJzJzogaGVhZGVycyB9KVxyXG4gICAgICAucGlwZShcclxuICAgICAgICB0YWtlKDEpLFxyXG4gICAgICAgIHRhcCgocmVzcG9uc2UpID0+IHtcclxuXHJcbiAgICAgICAgICBpZiAocmVzcG9uc2UuRXJyb3IpIHtcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IocmVzcG9uc2UuRXJyb3JNZXNzYWdlKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSlcclxuXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZm9yZ290dGVuUGFzc3dvcmQocGFybXM6IEZvcmdvdHRlblBhc3N3b3JkRm9ybSk6IE9ic2VydmFibGU8UmV0RXJyb3I+IHtcclxuXHJcbiAgICB0aGlzLl9hdXRoU3RvcmFnZVNlcnZpY2UubG9nb3V0KCk7XHJcblxyXG4gICAgY29uc3QgcGFyYW1zID0gbmV3IEh0dHBQYXJhbXMoKVxyXG4gICAgICAuc2V0KCdkb21haW4nLCBwYXJtcy5kb21pbmlvRmd0UHN3KVxyXG4gICAgICAuc2V0KCd1c2VyJywgcGFybXMudXN1YXJpb0ZndFBzdylcclxuICAgICAgLnNldCgndXJsU2Vydmlkb3InLCB0aGlzLmdlSG9zdE5hbWUoKSlcclxuICAgICAgLnNldCgnaXAnLCB0aGlzLmlwKVxyXG4gICAgICAuc2V0KCdicm93c2UnLCBgJHt0aGlzLl9pcFNlcnZpY2VTZXJ2aWNlLmdldERhdGFCcm93c2VyVXNlcigpLmJyb3dzZXJ9IC0gJHt0aGlzLl9pcFNlcnZpY2VTZXJ2aWNlLmdldERhdGFCcm93c2VyVXNlcigpLnNvfWApXHJcbiAgICAgIC5zZXQoJ2xvY2FsaXphdGlvbicsIGAke3RoaXMuY2l0eX0sICR7dGhpcy5zdGF0ZX0sICR7dGhpcy5jb3VudHJ5fWApO1xyXG5cclxuICAgIGNvbnN0IGhlYWRlcnMgPSB0aGlzLl9IVFRQX0hFQURFUlM7XHJcblxyXG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5fQkFTRV9VUkx9L0ZvcmdvdHRlblBhc3N3b3JkYDtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5faHR0cENsaWVudFxyXG4gICAgICAucG9zdDxSZXRFcnJvcj4odXJsLCBudWxsLCB7ICdwYXJhbXMnOiBwYXJhbXMsICdoZWFkZXJzJzogaGVhZGVycyB9KVxyXG4gICAgICAucGlwZShcclxuICAgICAgICB0YWtlKDEpLFxyXG4gICAgICAgIHRhcCgocmVzcG9uc2UpID0+IHtcclxuXHJcbiAgICAgICAgICBpZiAocmVzcG9uc2UuRXJyb3IpIHtcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IocmVzcG9uc2UuRXJyb3JNZXNzYWdlKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSlcclxuXHJcbiAgICAgICk7XHJcblxyXG4gIH1cclxuXHJcbiAgcHVibGljIHJlY292ZXJQYXNzd29yZChkb21pbmlvOiBzdHJpbmcsIHVzdWFyaW86IHN0cmluZywgcGFybXM6IE5vdmFTZW5oYUZvcm0pOiBPYnNlcnZhYmxlPFJldEVycm9yPiB7XHJcblxyXG4gICAgbGV0IHJlY3VwUGFzc3dvcmQ6IFBhc3N3b3JkUmVjdXAgPSB7XHJcbiAgICAgIHBhc3N3b3JkOiBwYXJtcy5wYXNzd29yZCxcclxuICAgICAgY29uZmlybVBhc3N3b3JkOiBwYXJtcy5jb25maXJtUGFzc3dvcmQsXHJcbiAgICAgIGNvZGU6IHBhcm1zLmNvZGVcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBwYXJhbXMgPSBuZXcgSHR0cFBhcmFtcygpXHJcbiAgICAgIC5zZXQoJ2RvbWFpbicsIGRvbWluaW8pXHJcbiAgICAgIC5zZXQoJ3VzZXInLCB1c3VhcmlvKVxyXG5cclxuICAgIGNvbnN0IGhlYWRlcnMgPSB0aGlzLl9IVFRQX0hFQURFUlM7XHJcblxyXG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5fQkFTRV9VUkx9L1JlY292ZXJQYXNzd29yZGA7XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuX2h0dHBDbGllbnRcclxuICAgICAgLnBvc3Q8UmV0RXJyb3I+KHVybCwgcmVjdXBQYXNzd29yZCwgeyAncGFyYW1zJzogcGFyYW1zLCAnaGVhZGVycyc6IGhlYWRlcnMgfSlcclxuICAgICAgLnBpcGUoXHJcbiAgICAgICAgdGFrZSgxKSxcclxuICAgICAgICB0YXAoKHJlc3BvbnNlKSA9PiB7XHJcblxyXG4gICAgICAgICAgaWYgKHJlc3BvbnNlLkVycm9yKSB7XHJcbiAgICAgICAgICAgIHRocm93IEVycm9yKHJlc3BvbnNlLkVycm9yTWVzc2FnZSk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH0pXHJcblxyXG4gICAgICApO1xyXG5cclxuICB9XHJcblxyXG4gIHB1YmxpYyBjcmVhdGVQYXNzd29yZChkb21pbmlvOiBzdHJpbmcsIHVzdWFyaW86IHN0cmluZywgcGFybXM6IE5vdmFTZW5oYUZvcm0pOiBPYnNlcnZhYmxlPFJldEVycm9yPiB7XHJcblxyXG4gICAgbGV0IHJlY3VwUGFzc3dvcmQ6IFBhc3N3b3JkUmVjdXAgPSB7XHJcbiAgICAgIHBhc3N3b3JkOiBwYXJtcy5wYXNzd29yZCxcclxuICAgICAgY29uZmlybVBhc3N3b3JkOiBwYXJtcy5jb25maXJtUGFzc3dvcmQsXHJcbiAgICAgIGNvZGU6IHBhcm1zLmNvZGVcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBwYXJhbXMgPSBuZXcgSHR0cFBhcmFtcygpXHJcbiAgICAgIC5zZXQoJ2RvbWFpbicsIGRvbWluaW8pXHJcbiAgICAgIC5zZXQoJ3VzZXInLCB1c3VhcmlvKVxyXG5cclxuICAgIGNvbnN0IGhlYWRlcnMgPSB0aGlzLl9IVFRQX0hFQURFUlM7XHJcblxyXG4gICAgY29uc3QgdXJsID0gYCR7dGhpcy5fQkFTRV9VUkx9L0NyZWF0ZVBhc3N3b3JkYDtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5faHR0cENsaWVudFxyXG4gICAgICAucG9zdDxSZXRFcnJvcj4odXJsLCByZWN1cFBhc3N3b3JkLCB7ICdwYXJhbXMnOiBwYXJhbXMsICdoZWFkZXJzJzogaGVhZGVycyB9KVxyXG4gICAgICAucGlwZShcclxuICAgICAgICB0YWtlKDEpLFxyXG4gICAgICAgIHRhcCgocmVzcG9uc2UpID0+IHtcclxuXHJcbiAgICAgICAgICBpZiAocmVzcG9uc2UuRXJyb3IpIHtcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IocmVzcG9uc2UuRXJyb3JNZXNzYWdlKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIC8vICNlbmRyZWdpb24gUE9TVFxyXG5cclxuICAvLyAjZW5kcmVnaW9uID09PT09PT09PT0+IFNFUlZJQ0UgTUVUSE9EUyA8PT09PT09PT09PVxyXG5cclxuICAvLyAjcmVnaW9uID09PT09PT09PT0+IFVUSUxTIDw9PT09PT09PT09XHJcblxyXG4gIC8vICNlbmRyZWdpb24gPT09PT09PT09PT4gVVRJTFMgPD09PT09PT09PT1cclxufVxyXG4iXX0=
|