@ngrdt/router 0.0.7 → 0.0.9
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 +229 -28
- package/esm2022/lib/rdt-route/rdt-angular-route.mjs +11 -6
- package/esm2022/lib/rdt-route/rdt-route.mjs +93 -14
- package/esm2022/lib/rdt-route/utils.mjs +15 -2
- package/esm2022/lib/services/rdt-cannot-be-entered.token.mjs +6 -2
- package/esm2022/lib/services/rdt-router.service.mjs +3 -2
- package/fesm2022/ngrdt-router.mjs +120 -19
- package/fesm2022/ngrdt-router.mjs.map +1 -1
- package/lib/rdt-route/rdt-route.d.ts +85 -3
- package/lib/rdt-route/utils.d.ts +11 -0
- package/lib/services/rdt-cannot-be-entered.token.d.ts +6 -1
- package/lib/services/rdt-router.service.d.ts +5 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,54 +1,255 @@
|
|
|
1
1
|
# @ngrdt/router
|
|
2
2
|
|
|
3
|
+
Main use for this package is to define routes and their parameters in one place in app. It is recommended to define special `routes` module in every app using `@ngrdt/router` where all `RdtRoute` objects are defined using `RdtRouteBuilder`. Individual application modules then import these objects, define Angular routes and provide implementation details such as which component is rendered, state, guards, etc.
|
|
4
|
+
|
|
5
|
+
This approach ensures that each route is defined exactly once and can be easily edited if necessary. `@ngrdt/router` also provides set of useful tools to help you with common routing tasks.
|
|
6
|
+
|
|
3
7
|
### Instalation
|
|
4
8
|
|
|
5
9
|
`npm install @ngrdt/router`
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
## Basic usage
|
|
12
|
+
|
|
13
|
+
### Application routes file
|
|
14
|
+
|
|
15
|
+
Create special `nx` library (not `NgModule`) for instance `@example-app/routes`. In this library you will create file called `routes.ts` and in it individual `RdtRoute` objects like so:
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
export const DASHBOARD_ITEM_ROUTE = new RdtRouteBuilder()
|
|
19
|
+
.setName('Dashboard item')
|
|
20
|
+
.setPath(':id')
|
|
21
|
+
.setParam('id', 'number')
|
|
22
|
+
.build();
|
|
23
|
+
|
|
24
|
+
export const DASHBOARD_ROUTE = new RdtRouteBuilder()
|
|
25
|
+
.setName('Dashboard')
|
|
26
|
+
.setPath('dashboard')
|
|
27
|
+
.setChildren(DASHBOARD_ITEM_ROUTE)
|
|
28
|
+
.build();
|
|
29
|
+
|
|
30
|
+
export const SETTINGS_ROUTE = new RdtRouteBuilder()
|
|
31
|
+
.setName('Settings')
|
|
32
|
+
.setPath('settings')
|
|
33
|
+
.setCanBeEntered(() =>
|
|
34
|
+
inject(ExampleAppPermissionService).hasPermission('SETTINGS_ACCESS')
|
|
35
|
+
)
|
|
36
|
+
.build();
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This file should only contain imports to interfaces used by `RdtRouteBuilder` as template parameter. No component, ngModule or guards such as `CanActivateFn` should be imported here. This approach will save you later headache with circular dependency.
|
|
40
|
+
|
|
41
|
+
`RdtRouterService` needs to be aware of all routes defined therefore you must provide it in your `ApplicationConfig` like so:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { RDT_ROUTES_PROVIDER, RdtRoute } from '@ngrdt/router';
|
|
45
|
+
import * as ALL_ROUTES_OBJ from './rdt-routes';
|
|
46
|
+
const ALL_ROUTES = Object.values(ALL_ROUTES_OBJ) as RdtRoute[];
|
|
47
|
+
|
|
48
|
+
export const appConfig: ApplicationConfig = {
|
|
49
|
+
providers: [
|
|
50
|
+
{
|
|
51
|
+
provide: RDT_ROUTES_PROVIDER,
|
|
52
|
+
useValue: ALL_ROUTES,
|
|
53
|
+
},
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Angular routes files
|
|
8
59
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
.
|
|
60
|
+
Now you have to bind `RdtRoute` objects to individual modules, components, states, effects, guards and other implementation details. Instead of defining routes directly you import `RdtRoute` from `@example-app/routes` and then define `routes.ts` like so:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
export const routes: Route[] = [
|
|
64
|
+
DASHBOARD_ROUTE.toAngularRoute()
|
|
65
|
+
.setComponent(DashboardComponent)
|
|
66
|
+
.setChildren(
|
|
67
|
+
DASHBOARD_ITEM_ROUTE.toAngularRoute()
|
|
68
|
+
.setComponent(DashboardItemComponent)
|
|
69
|
+
.addCanDeactivate(preventDataLossGuardFn)
|
|
70
|
+
.build()
|
|
71
|
+
)
|
|
72
|
+
.build(),
|
|
73
|
+
]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This array is then used as in regular Angular project. Note that child routes must be added as children here as well.
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
### Child routes and parameters
|
|
80
|
+
|
|
81
|
+
You may nest child routes and also create routes with typed parameters to link them with particular type.
|
|
82
|
+
|
|
83
|
+
For instance lets say there's a route displaying users which has a child route to display more information about a single user. By providing `User` type to `RdtRouteBuilder` and defining types of parameters we can use `RdtRoute` object to parse path to extract parameters.
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
interface User {
|
|
87
|
+
userId: number;
|
|
88
|
+
name: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export const USER_DETAIL_ROUTE = new RdtRouteBuilder<User>()
|
|
92
|
+
.setName('User detail')
|
|
93
|
+
.setPath(':userId/:name')
|
|
94
|
+
.setParam('userId', 'number')
|
|
95
|
+
.setParam('name', 'string')
|
|
14
96
|
.build();
|
|
97
|
+
|
|
98
|
+
export const USER_LIST_ROUTE = new RdtRouteBuilder()
|
|
99
|
+
.setName('Users')
|
|
100
|
+
.setPath('users')
|
|
101
|
+
.setChildren(USER_DETAIL_ROUTE)
|
|
102
|
+
.build();
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Then we navigate to user detail like so:
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
const params: Partial<User> = {
|
|
109
|
+
userId: 123,
|
|
110
|
+
name: 'Josef',
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
inject(RdtRouterService).navigate(USER_DETAIL_ROUTE, params);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`RdtRouterService` is aware of the type so you can use it to parse absolute path into `User` object. Route knows `userId` is `number` so it will parse it. If parameter is missing or is of wrong type, then `parseAbsoluteUrl` returns `null`. Return value is a wrapper object with `get(route: RdtRoute)` method to get parsed parameters of given route or its parents.
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
const user: User = USER_DETAIL_ROUTE
|
|
121
|
+
.parse('/users/123/Josef')
|
|
122
|
+
.get(USER_DETAIL_ROUTE);
|
|
15
123
|
```
|
|
16
124
|
|
|
17
|
-
###
|
|
125
|
+
### More parameter examples
|
|
126
|
+
|
|
127
|
+
#### Static parameters
|
|
128
|
+
|
|
129
|
+
Imagine your app contains list of users and each user has set of tasks. The routes are defined as follows:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
interface User {
|
|
133
|
+
userId: number,
|
|
134
|
+
name: string,
|
|
135
|
+
address: string,
|
|
136
|
+
tasks: Task[]
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
interface Task {
|
|
140
|
+
taskId: number,
|
|
141
|
+
description: string
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
export const TASK_DETAIL_ROUTE = new RdtRouteBuilder<Task>()
|
|
146
|
+
.setName('Task detail')
|
|
147
|
+
.setPath('task/:taskId')
|
|
148
|
+
.setParam('taskId', 'number')
|
|
149
|
+
.build();
|
|
18
150
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
.
|
|
22
|
-
.
|
|
23
|
-
.
|
|
151
|
+
export const USER_DETAIL_ROUTE = new RdtRouteBuilder<User>()
|
|
152
|
+
.setName('User detail')
|
|
153
|
+
.setPath(':userId')
|
|
154
|
+
.setParam('userId', 'number')
|
|
155
|
+
.setChildren(TASK_DETAIL_ROUTE)
|
|
24
156
|
.build();
|
|
25
157
|
|
|
26
|
-
|
|
158
|
+
export const USER_LIST_ROUTE = new RdtRouteBuilder()
|
|
159
|
+
.setName('Users')
|
|
160
|
+
.setPath('user')
|
|
161
|
+
.setChildren(USER_DETAIL_ROUTE)
|
|
162
|
+
.build();
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
This translates into path `/user/:userId/task/:taskId` for task detail route.
|
|
166
|
+
|
|
167
|
+
Now inside `UserDetailComponent` there's a for loop rendering individual tasks and you want to have links to them. You cannot use directly:
|
|
168
|
+
|
|
169
|
+
```html
|
|
170
|
+
<button [rdtRouterLink]="TASK_DETAIL_ROUTE" [params]="task"></button>
|
|
27
171
|
```
|
|
172
|
+
Because task does not specify `userId`. For this you must provide static parameters for every parent route - `User` for `USER_DETAIL_ROUTE` in this case:
|
|
28
173
|
|
|
29
|
-
|
|
174
|
+
```typescript
|
|
175
|
+
@Input()
|
|
176
|
+
user!: User;
|
|
30
177
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
178
|
+
taskRoute!: RdtRoute<Task>;
|
|
179
|
+
|
|
180
|
+
ngOnInit() {
|
|
181
|
+
this.taskRoute = TASK_DETAIL_ROUTE.withStaticParams(USER_DETAIL_ROUTE, this.user);
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
Method `withStaticParams()` returns clone of `TASK_DETAIL_ROUTE` and all of its parent routes while fixing parameters. You can chain calling `withStaticParams` with itself or other method calls.
|
|
34
185
|
|
|
35
|
-
|
|
36
|
-
|
|
186
|
+
```html
|
|
187
|
+
<button [rdtRouterLink]="taskRoute" [params]="task"></button>
|
|
37
188
|
```
|
|
38
189
|
|
|
39
|
-
|
|
190
|
+
## Ecosystem
|
|
191
|
+
|
|
192
|
+
### RdtRouterLink
|
|
193
|
+
|
|
194
|
+
`RdtRouterLink` is equivalent of `RouterLink` in Angular. It supports basically the same functionality, but adds type safety. `RdtRouterLink` will be disabled if `canBeEntered` of its route returns `false`.
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
readonly userRoute = USER_DETAIL_ROUTE;
|
|
198
|
+
readonly user$ = inject(UserService).getUser$();
|
|
199
|
+
```
|
|
40
200
|
|
|
41
201
|
```html
|
|
42
|
-
<button
|
|
202
|
+
<button
|
|
203
|
+
[rdtRouterLink]="userRoute"
|
|
204
|
+
[params]="user$ | async"
|
|
205
|
+
target="_blank">
|
|
206
|
+
Link to user
|
|
207
|
+
</button>
|
|
43
208
|
```
|
|
44
209
|
|
|
45
|
-
###
|
|
210
|
+
### RdtMenu
|
|
46
211
|
|
|
47
|
-
|
|
48
|
-
private readonly rdtRouter: RdtRouterService = inject(RdtRouterService);
|
|
212
|
+
`RdtRoute` can be passed directly into `RdtMenuItem`. If `canBeEntered` returns `false`, then the item won't be visible. This is useful to hide items user has no permission for.
|
|
49
213
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
214
|
+
Method `withStaticParams` lets us provide parameters for given `RdtRoute`, because `RdtMenuItem` does not accept route parameters.
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
public getMenuItems(): RdtMenuItem[] {
|
|
218
|
+
const user: Partial<User> = {
|
|
219
|
+
userId: 123,
|
|
220
|
+
name: 'Josef'
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
return [
|
|
224
|
+
{
|
|
225
|
+
label: 'All users',
|
|
226
|
+
routerLink: USER_LIST_ROUTE
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
label: 'Josef',
|
|
230
|
+
routerLink: USER_DETAIL_ROUTE.withStaticParams(user)
|
|
231
|
+
}
|
|
232
|
+
];
|
|
233
|
+
}
|
|
54
234
|
```
|
|
235
|
+
|
|
236
|
+
### RdtAngularRoute
|
|
237
|
+
|
|
238
|
+
`RdtAngularRoute` is a container class for `RdtRoute` which functionally does two things: verifies that routes were defined correctly and enables you to provide guards, effects, component or module. Don't forget to call `build()` for it to generate Angular `Route`.
|
|
239
|
+
|
|
240
|
+
### RdtRouterService
|
|
241
|
+
|
|
242
|
+
`RdtRouterService` has similar features as Angular `Router`.
|
|
243
|
+
|
|
244
|
+
#### `parseAbsoluteUrl()`
|
|
245
|
+
Method will parse absolute path, recognize `RdtRoute` and parse its parameters. If no parameter is provided, then window location is used.
|
|
246
|
+
|
|
247
|
+
#### `navigateBack()`
|
|
248
|
+
|
|
249
|
+
Will push parent route to navigation stack. Function works anywhere in the app unlike similar Angular-based solution using `ActivatedRoute`.
|
|
250
|
+
|
|
251
|
+
Hitting native browser back button will take you back forward. In case you want true back function, use `inject(Location).back()` which removes from navigation stack, but can potentially take you outside of the app or close browser window.
|
|
252
|
+
|
|
253
|
+
#### `previousUrl` and `currentUrl`
|
|
254
|
+
|
|
255
|
+
Cached sync values of previous and current path values. For example `/dashboard` or `/user/123/task/xyz`.
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Location } from '@angular/common';
|
|
1
2
|
import { EnvironmentInjector, inject, runInInjectionContext, } from '@angular/core';
|
|
2
3
|
import { Router, } from '@angular/router';
|
|
3
4
|
import { RDT_CANNOT_BE_ENTERED_PROVIDER } from '../services/rdt-cannot-be-entered.token';
|
|
@@ -76,19 +77,23 @@ export class RdtAngularRoute {
|
|
|
76
77
|
},
|
|
77
78
|
},
|
|
78
79
|
};
|
|
79
|
-
const guard = () => {
|
|
80
|
+
const guard = (route, state) => {
|
|
80
81
|
const injector = inject(EnvironmentInjector);
|
|
81
82
|
if (runInInjectionContext(injector, this.route.canBeEntered.bind(this.route))) {
|
|
82
83
|
return true;
|
|
83
84
|
}
|
|
84
85
|
else {
|
|
85
|
-
const
|
|
86
|
-
|
|
86
|
+
const router = inject(Router);
|
|
87
|
+
const location = inject(Location);
|
|
88
|
+
let url = inject(RDT_CANNOT_BE_ENTERED_PROVIDER);
|
|
89
|
+
if (typeof url === 'function') {
|
|
90
|
+
url = runInInjectionContext(injector, url.bind(url, location.path(), state.url, this.route));
|
|
91
|
+
}
|
|
87
92
|
if (typeof url === 'string') {
|
|
88
|
-
return
|
|
93
|
+
return router.parseUrl(url);
|
|
89
94
|
}
|
|
90
95
|
else {
|
|
91
|
-
return
|
|
96
|
+
return false;
|
|
92
97
|
}
|
|
93
98
|
}
|
|
94
99
|
};
|
|
@@ -184,4 +189,4 @@ export class RdtAngularRoute {
|
|
|
184
189
|
}
|
|
185
190
|
}
|
|
186
191
|
}
|
|
187
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmR0LWFuZ3VsYXItcm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9AbmdyZHQvcm91dGVyL3NyYy9saWIvcmR0LXJvdXRlL3JkdC1hbmd1bGFyLXJvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxtQkFBbUIsRUFFbkIsTUFBTSxFQUVOLHFCQUFxQixHQUV0QixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBUUwsTUFBTSxHQUdQLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDekYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBR2xELE1BQU0sT0FBTyxlQUFlO0lBQ2xCLEtBQUssQ0FBYztJQUNuQixRQUFRLEdBQVksRUFBRSxDQUFDO0lBRS9CLCtDQUErQztJQUN2QyxZQUFZLENBQXdCO0lBQ3BDLFNBQVMsQ0FBYTtJQUN0QixTQUFTLEdBQXdDLEVBQUUsQ0FBQztJQUNwRCxTQUFTLEdBQTBDLEVBQUUsQ0FBQztJQUN0RCxXQUFXLEdBQW9CLEVBQUUsQ0FBQztJQUNsQyxnQkFBZ0IsR0FBeUIsRUFBRSxDQUFDO0lBQzVDLGFBQWEsR0FBeUIsRUFBRSxDQUFDO0lBQ3pDLHFCQUFxQixDQUF5QjtJQUV0RCxZQUFZLEtBQWtCO1FBQzVCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxPQUFPLENBQUMsR0FBRyxTQUEwQjtRQUNuQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLFNBQVMsQ0FBQyxDQUFDO1FBQ2xDLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELFNBQVMsQ0FBQyxRQUE4QjtRQUN0QyxJQUFJLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQztRQUM3QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxZ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TUFDaEIsK0pBQStKLElBQUksQ0FBQyxRQUFRO3FCQUN6SyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUM7cUJBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUNoQixDQUFDO1lBQ0osQ0FBQztZQUNELE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSyxDQUFDLENBQUM7WUFDL0MsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDcEQsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ1YsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ1YsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDbkMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7b0JBQ3BCLE1BQU0sSUFBSSxLQUFLLENBQ2I7NENBQ2dDLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FDcEQsQ0FBQztnQkFDSixDQUFDO1lBQ0gsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIEVudmlyb25tZW50SW5qZWN0b3IsXHJcbiAgRW52aXJvbm1lbnRQcm92aWRlcnMsXHJcbiAgaW5qZWN0LFxyXG4gIFByb3ZpZGVyLFxyXG4gIHJ1bkluSW5qZWN0aW9uQ29udGV4dCxcclxuICBUeXBlLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1xyXG4gIENhbkFjdGl2YXRlQ2hpbGRGbixcclxuICBDYW5BY3RpdmF0ZUZuLFxyXG4gIENhbkRlYWN0aXZhdGVGbixcclxuICBDYW5NYXRjaEZuLFxyXG4gIExvYWRDaGlsZHJlbkNhbGxiYWNrLFxyXG4gIFJlc29sdmVGbixcclxuICBSb3V0ZSxcclxuICBSb3V0ZXIsXHJcbiAgUnVuR3VhcmRzQW5kUmVzb2x2ZXJzLFxyXG4gIFVybFNlZ21lbnQsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcclxuaW1wb3J0IHsgUkRUX0NBTk5PVF9CRV9FTlRFUkVEX1BST1ZJREVSIH0gZnJvbSAnLi4vc2VydmljZXMvcmR0LWNhbm5vdC1iZS1lbnRlcmVkLnRva2VuJztcclxuaW1wb3J0IHsgUmR0TmF2aWdhdGlvblNvdXJjZSB9IGZyb20gJy4vY29uc3RhbnRzJztcclxuaW1wb3J0IHsgUmR0Um91dGUgfSBmcm9tICcuL3JkdC1yb3V0ZSc7XHJcblxyXG5leHBvcnQgY2xhc3MgUmR0QW5ndWxhclJvdXRlPFQgZXh0ZW5kcyBvYmplY3Q+IHtcclxuICBwcml2YXRlIHJvdXRlOiBSZHRSb3V0ZTxUPjtcclxuICBwcml2YXRlIGNoaWxkcmVuOiBSb3V0ZVtdID0gW107XHJcblxyXG4gIC8vIE11c3QgYmUgc2V0IGZyb20gY29tcG9uZW50IGRlY2xhcmF0aW9uIGZpbGVzXHJcbiAgcHJpdmF0ZSBsb2FkQ2hpbGRyZW4/OiBMb2FkQ2hpbGRyZW5DYWxsYmFjaztcclxuICBwcml2YXRlIGNvbXBvbmVudD86IFR5cGU8YW55PjtcclxuICBwcml2YXRlIHByb3ZpZGVyczogKFByb3ZpZGVyIHwgRW52aXJvbm1lbnRQcm92aWRlcnMpW10gPSBbXTtcclxuICBwcml2YXRlIHJlc29sdmVyczogeyBba2V5OiBzdHJpbmddOiBSZXNvbHZlRm48dW5rbm93bj4gfSA9IHt9O1xyXG4gIHByaXZhdGUgY2FuQWN0aXZhdGU6IENhbkFjdGl2YXRlRm5bXSA9IFtdO1xyXG4gIHByaXZhdGUgY2FuQWN0aXZhdGVDaGlsZDogQ2FuQWN0aXZhdGVDaGlsZEZuW10gPSBbXTtcclxuICBwcml2YXRlIGNhbkRlYWN0aXZhdGU6IENhbkRlYWN0aXZhdGVGbjxUPltdID0gW107XHJcbiAgcHJpdmF0ZSBydW5HdWFyZHNBbmRSZXNvbHZlcnM/OiBSdW5HdWFyZHNBbmRSZXNvbHZlcnM7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHJvdXRlOiBSZHRSb3V0ZTxUPikge1xyXG4gICAgdGhpcy5yb3V0ZSA9IHJvdXRlO1xyXG4gIH1cclxuXHJcbiAgcHJvdmlkZSguLi5wcm92aWRlcnM6IFR5cGU8dW5rbm93bj5bXSkge1xyXG4gICAgdGhpcy5wcm92aWRlcnMucHVzaCguLi5wcm92aWRlcnMpO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBzZXRNb2R1bGUoY2FsbGJhY2s6IExvYWRDaGlsZHJlbkNhbGxiYWNrKSB7XHJcbiAgICB0aGlzLmxvYWRDaGlsZHJlbiA9IGNhbGxiYWNrO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBzZXRDb21wb25lbnQoY29tcDogVHlwZTxhbnk+KSB7XHJcbiAgICB0aGlzLmNvbXBvbmVudCA9IGNvbXA7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHNldENoaWxkcmVuKC4uLnJvdXRlczogUm91dGVbXSkge1xyXG4gICAgdGhpcy5jaGlsZHJlbiA9IHJvdXRlcztcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgYWRkUmVzb2x2ZShwYXJhbU5hbWU6IHN0cmluZywgcmVzb2x2ZXI6IFJlc29sdmVGbjx1bmtub3duPikge1xyXG4gICAgdGhpcy5yZXNvbHZlcnNbcGFyYW1OYW1lXSA9IHJlc29sdmVyO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBhZGRDYW5BY3RpdmF0ZSguLi5mbnM6IENhbkFjdGl2YXRlRm5bXSkge1xyXG4gICAgdGhpcy5jYW5BY3RpdmF0ZS5wdXNoKC4uLmZucyk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIGFkZENhbkRlYWN0aXZhdGUoLi4uZm5zOiBDYW5EZWFjdGl2YXRlRm48YW55PltdKSB7XHJcbiAgICB0aGlzLmNhbkRlYWN0aXZhdGUucHVzaCguLi5mbnMpO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBhZGRDYW5BY3RpdmF0ZUNoaWxkKC4uLmZuczogQ2FuQWN0aXZhdGVDaGlsZEZuW10pIHtcclxuICAgIHRoaXMuY2FuQWN0aXZhdGVDaGlsZC5wdXNoKC4uLmZucyk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHNldFJ1bkd1YXJkc0FuZFJlc29sdmVycyh2YWx1ZTogUnVuR3VhcmRzQW5kUmVzb2x2ZXJzKSB7XHJcbiAgICB0aGlzLnJ1bkd1YXJkc0FuZFJlc29sdmVycyA9IHZhbHVlO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBidWlsZCgpOiBSb3V0ZSB7XHJcbiAgICB0aGlzLmNoZWNrQ2hpbGRyZW5NYXRjaCgpO1xyXG5cclxuICAgIGxldCByZXM6IFJvdXRlID0ge1xyXG4gICAgICBwYXRoOiB0aGlzLnJvdXRlLnBhdGgsXHJcbiAgICAgIHByb3ZpZGVyczogdGhpcy5wcm92aWRlcnMsXHJcbiAgICAgIHRpdGxlOiB0aGlzLnJvdXRlLm5hbWUsXHJcbiAgICAgIGNhbk1hdGNoOiB0aGlzLmdldENhbk1hdGNoKCksXHJcbiAgICB9O1xyXG5cclxuICAgIGlmICh0aGlzLmNvbXBvbmVudCkge1xyXG4gICAgICByZXMuY29tcG9uZW50ID0gdGhpcy5jb21wb25lbnQ7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMubG9hZENoaWxkcmVuKSB7XHJcbiAgICAgIHJlcy5sb2FkQ2hpbGRyZW4gPSB0aGlzLmxvYWRDaGlsZHJlbjtcclxuICAgIH1cclxuXHJcbiAgICByZXMuZGF0YSA9IHtcclxuICAgICAgYnJlYWRjcnVtYjoge1xyXG4gICAgICAgIGxhYmVsOiB0aGlzLnJvdXRlLm5hbWUsXHJcbiAgICAgICAgZGlzYWJsZTogdGhpcy5yb3V0ZS5lbnRyeURpc2FibGVkLFxyXG4gICAgICAgIHN0YXRpY1N0YXRlUGFyYW1zOiB7XHJcbiAgICAgICAgICBzcmM6IFJkdE5hdmlnYXRpb25Tb3VyY2UuQlJFQURDUlVNQixcclxuICAgICAgICB9LFxyXG4gICAgICB9LFxyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdCBndWFyZCA9ICgpID0+IHtcclxuICAgICAgY29uc3QgaW5qZWN0b3IgPSBpbmplY3QoRW52aXJvbm1lbnRJbmplY3Rvcik7XHJcbiAgICAgIGlmIChcclxuICAgICAgICBydW5JbkluamVjdGlvbkNvbnRleHQoXHJcbiAgICAgICAgICBpbmplY3RvcixcclxuICAgICAgICAgIHRoaXMucm91dGUuY2FuQmVFbnRlcmVkLmJpbmQodGhpcy5yb3V0ZSlcclxuICAgICAgICApXHJcbiAgICAgICkge1xyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNvbnN0IHVybCA9IGluamVjdChSRFRfQ0FOTk9UX0JFX0VOVEVSRURfUFJPVklERVIpO1xyXG4gICAgICAgIGNvbnNvbGUubG9nKCd1cmwnLCB1cmwpO1xyXG4gICAgICAgIGlmICh0eXBlb2YgdXJsID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgcmV0dXJuIGluamVjdChSb3V0ZXIpLnBhcnNlVXJsKHVybCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHJldHVybiB1cmw7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gICAgdGhpcy5jYW5BY3RpdmF0ZS5wdXNoKGd1YXJkKTtcclxuICAgIHRoaXMuY2FuQWN0aXZhdGVDaGlsZC5wdXNoKGd1YXJkKTtcclxuXHJcbiAgICByZXMuY2FuQWN0aXZhdGUgPSB0aGlzLmNhbkFjdGl2YXRlO1xyXG4gICAgcmVzLmNhbkRlYWN0aXZhdGUgPSB0aGlzLmNhbkRlYWN0aXZhdGU7XHJcblxyXG4gICAgLy8gSWYgY2hpbGRyZW4gZXhpc3QsIGNoYW5nZVxyXG4gICAgLy8ge1xyXG4gICAgLy8gICAgcGF0aDogJy9wYXRoJyxcclxuICAgIC8vICAgIGNvbXBvbmVudDogRmVhdHVyZUNvbXBvbmVudCxcclxuICAgIC8vICAgIGNoaWxkcmVuOiBbLi4uXVxyXG4gICAgLy8gfVxyXG4gICAgLy8gaW50b1xyXG4gICAgLy8ge1xyXG4gICAgLy8gICAgcGF0aDogJy9wYXRoJyxcclxuICAgIC8vICAgIGNoaWxkcmVuOiBbXHJcbiAgICAvLyAgICAgIHtcclxuICAgIC8vICAgICAgICBwYXRoOiAnJyxcclxuICAgIC8vICAgICAgICBjb21wb25lbnQ6IEZlYXR1cmVDb21wb25lbnRcclxuICAgIC8vICAgICAgfSxcclxuICAgIC8vICAgIC4uLlxyXG4gICAgLy8gICAgXVxyXG4gICAgLy8gICAgfVxyXG4gICAgaWYgKHRoaXMuY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xyXG4gICAgICBpZiAodGhpcy5sb2FkQ2hpbGRyZW4gfHwgdGhpcy5jb21wb25lbnQpIHtcclxuICAgICAgICBjb25zdCBwYXRoID0gcmVzLnBhdGg7XHJcbiAgICAgICAgcmVzLnBhdGggPSAnJztcclxuICAgICAgICByZXMucGF0aE1hdGNoID0gJ2Z1bGwnO1xyXG4gICAgICAgIHJlcy5jYW5NYXRjaCA9IHVuZGVmaW5lZDtcclxuICAgICAgICByZXMgPSB7XHJcbiAgICAgICAgICBwYXRoOiBwYXRoLFxyXG4gICAgICAgICAgY2hpbGRyZW46IFtyZXMsIC4uLnRoaXMuY2hpbGRyZW5dLFxyXG4gICAgICAgICAgY2FuQWN0aXZhdGVDaGlsZDogdGhpcy5jYW5BY3RpdmF0ZUNoaWxkLFxyXG4gICAgICAgICAgY2FuTWF0Y2g6IHRoaXMuZ2V0Q2FuTWF0Y2goKSxcclxuICAgICAgICB9O1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJlcy5jaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW47XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZXNvbHZlcnMpLmxlbmd0aCA+IDApIHtcclxuICAgICAgcmVzLnJlc29sdmUgPSB0aGlzLnJlc29sdmVycztcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5ydW5HdWFyZHNBbmRSZXNvbHZlcnMpIHtcclxuICAgICAgcmVzLnJ1bkd1YXJkc0FuZFJlc29sdmVycyA9IHRoaXMucnVuR3VhcmRzQW5kUmVzb2x2ZXJzO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiByZXM7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldENhbk1hdGNoKCk6IENhbk1hdGNoRm5bXSB8IHVuZGVmaW5lZCB7XHJcbiAgICBjb25zdCBwYXJhbU1hcCA9IHRoaXMucm91dGUucGFyYW1NYXA7XHJcbiAgICBjb25zdCBoYXNOdW1iZXJQYXJhbXMgPSBPYmplY3Qua2V5cyhwYXJhbU1hcCkuc29tZShcclxuICAgICAgKHApID0+IHBhcmFtTWFwW3AgYXMga2V5b2YgVF0gPT09ICdudW1iZXInXHJcbiAgICApO1xyXG4gICAgaWYgKCFoYXNOdW1iZXJQYXJhbXMpIHtcclxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuICAgIGNvbnN0IHJvdXRlU2VnbWVudExlbmd0aCA9IHRoaXMucm91dGUucGF0aC5zcGxpdCgnLycpLmxlbmd0aDtcclxuICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChgXiR7dGhpcy5yb3V0ZS5yZWdleC5zb3VyY2V9JGApO1xyXG4gICAgcmV0dXJuIFtcclxuICAgICAgKHJvdXRlOiBSb3V0ZSwgc2VnbWVudHM6IFVybFNlZ21lbnRbXSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHBhdGggPSBzZWdtZW50c1xyXG4gICAgICAgICAgLnNsaWNlKDAsIHJvdXRlU2VnbWVudExlbmd0aClcclxuICAgICAgICAgIC5tYXAoKHMpID0+IHMucGF0aClcclxuICAgICAgICAgIC5qb2luKCcvJyk7XHJcbiAgICAgICAgcmV0dXJuIHJlZ2V4LnRlc3QocGF0aCk7XHJcbiAgICAgIH0sXHJcbiAgICBdO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjaGVja0NoaWxkcmVuTWF0Y2goKSB7XHJcbiAgICAvLyBDaGVjayB0aGF0IGFsbCByb3V0ZXMgYXJlIHByZXNlbnQgaWYgcm91dGUgaXMgbm90XHJcbiAgICAvLyBsYXp5IGxvYWRlZCBtb2R1bGUuXHJcbiAgICBpZiAoXHJcbiAgICAgICF0aGlzLmxvYWRDaGlsZHJlbiAmJlxyXG4gICAgICAodGhpcy5yb3V0ZS5jaGlsZHJlbi5sZW5ndGggPiAwIHx8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoID4gMClcclxuICAgICkge1xyXG4gICAgICBpZiAodGhpcy5jaGlsZHJlbi5sZW5ndGggPCB0aGlzLnJvdXRlLmNoaWxkcmVuLmxlbmd0aCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcclxuICAgICAgICAgIGBSZHRSb3V0ZSAke3RoaXMucm91dGUubmFtZX0gaGFzICR7XHJcbiAgICAgICAgICAgIHRoaXMucm91dGUuY2hpbGRyZW4ubGVuZ3RoXHJcbiAgICAgICAgICB9IGNoaWxkcmVuLCBidXQgUmR0QW5ndWxhclJvdXRlIGhhcyAke1xyXG4gICAgICAgICAgICB0aGlzLmNoaWxkcmVuLmxlbmd0aFxyXG4gICAgICAgICAgfS4gVGhlc2UgbnVtYmVycyBtdXN0IG1hdGNoLiBEaWQgeW91IGZvcmdldCB0byBjYWxsIC5zZXRDaGlsZHJlbigpIG1ldGhvZCBpbiBnbG9iYWwgcm91dGVzIGRlZmluaXRpb24/IFJvdXRlcyB3aXRoIGZvbGxvd2luZyBuYW1lcyBzaG91bGQgYmUgcHJlc2VudDogJHt0aGlzLnJvdXRlLmNoaWxkcmVuXHJcbiAgICAgICAgICAgIC5tYXAoKGNoKSA9PiBjaC5uYW1lKVxyXG4gICAgICAgICAgICAuam9pbignLCAnKX1gXHJcbiAgICAgICAgKTtcclxuICAgICAgfSBlbHNlIGlmICh0aGlzLmNoaWxkcmVuLmxlbmd0aCA+IHRoaXMucm91dGUuY2hpbGRyZW4ubGVuZ3RoKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxyXG4gICAgICAgICAgYFJkdFJvdXRlICR7dGhpcy5yb3V0ZS5uYW1lfSBoYXMgJHtcclxuICAgICAgICAgICAgdGhpcy5yb3V0ZS5jaGlsZHJlbi5sZW5ndGhcclxuICAgICAgICAgIH0gY2hpbGRyZW4sIGJ1dCBSZHRBbmd1bGFyUm91dGUgaGFzICR7XHJcbiAgICAgICAgICAgIHRoaXMuY2hpbGRyZW4ubGVuZ3RoXHJcbiAgICAgICAgICB9LiBUaGVzZSBudW1iZXJzIG11c3QgbWF0Y2guIERpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgLnNldENoaWxkcmVuKCkgbWV0aG9kIGluIGZlYXR1cmUgc2hlbGwgcm91dGVzIGRlZmluaXRpb24/IFJvdXRlcyB3aXRoIGZvbGxvd2luZyBwYXRocyBzaG91bGQgYmUgcHJlc2VudDogJHt0aGlzLmNoaWxkcmVuXHJcbiAgICAgICAgICAgIC5tYXAoKGNoKSA9PiBjaC5wYXRoKVxyXG4gICAgICAgICAgICAuam9pbignLCAnKX1gXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBuMSA9IHRoaXMuY2hpbGRyZW4ubWFwKChjaCkgPT4gY2gucGF0aCEpO1xyXG4gICAgICBjb25zdCBuMiA9IHRoaXMucm91dGUuY2hpbGRyZW4ubWFwKChjaCkgPT4gY2gucGF0aCk7XHJcbiAgICAgIG4xLnNvcnQoKTtcclxuICAgICAgbjIuc29ydCgpO1xyXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG4xLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKG4xW2ldICE9PSBuMltpXSkge1xyXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxyXG4gICAgICAgICAgICBgUGF0aHMgb2YgY2hpbGRyZW4gcHJvdmlkZWQgaW4gUmR0Um91dGUgYW5kXHJcbiAgICAgICAgICAgIFJkdEFuZ3VsYXJSb3V0ZSBkbyBub3QgbWF0Y2guICR7bjFbaV19ICE9ICR7bjJbaV19YFxyXG4gICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbn1cclxuIl19
|
|
192
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmR0LWFuZ3VsYXItcm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9AbmdyZHQvcm91dGVyL3NyYy9saWIvcmR0LXJvdXRlL3JkdC1hbmd1bGFyLXJvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQ0wsbUJBQW1CLEVBRW5CLE1BQU0sRUFFTixxQkFBcUIsR0FFdEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQVNMLE1BQU0sR0FJUCxNQUFNLGlCQUFpQixDQUFDO0FBQ3pCLE9BQU8sRUFBRSw4QkFBOEIsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUdsRCxNQUFNLE9BQU8sZUFBZTtJQUNsQixLQUFLLENBQWM7SUFDbkIsUUFBUSxHQUFZLEVBQUUsQ0FBQztJQUUvQiwrQ0FBK0M7SUFDdkMsWUFBWSxDQUF3QjtJQUNwQyxTQUFTLENBQWE7SUFDdEIsU0FBUyxHQUF3QyxFQUFFLENBQUM7SUFDcEQsU0FBUyxHQUEwQyxFQUFFLENBQUM7SUFDdEQsV0FBVyxHQUFvQixFQUFFLENBQUM7SUFDbEMsZ0JBQWdCLEdBQXlCLEVBQUUsQ0FBQztJQUM1QyxhQUFhLEdBQXlCLEVBQUUsQ0FBQztJQUN6QyxxQkFBcUIsQ0FBeUI7SUFFdEQsWUFBWSxLQUFrQjtRQUM1QixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUNyQixDQUFDO0lBRUQsT0FBTyxDQUFDLEdBQUcsU0FBMEI7UUFDbkMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsR0FBRyxTQUFTLENBQUMsQ0FBQztRQUNsQyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxTQUFTLENBQUMsUUFBOEI7UUFDdEMsSUFBSSxDQUFDLFlBQVksR0FBRyxRQUFR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QUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUNwRCxDQUFDO2dCQUNKLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExvY2F0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHtcclxuICBFbnZpcm9ubWVudEluamVjdG9yLFxyXG4gIEVudmlyb25tZW50UHJvdmlkZXJzLFxyXG4gIGluamVjdCxcclxuICBQcm92aWRlcixcclxuICBydW5JbkluamVjdGlvbkNvbnRleHQsXHJcbiAgVHlwZSxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtcclxuICBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90LFxyXG4gIENhbkFjdGl2YXRlQ2hpbGRGbixcclxuICBDYW5BY3RpdmF0ZUZuLFxyXG4gIENhbkRlYWN0aXZhdGVGbixcclxuICBDYW5NYXRjaEZuLFxyXG4gIExvYWRDaGlsZHJlbkNhbGxiYWNrLFxyXG4gIFJlc29sdmVGbixcclxuICBSb3V0ZSxcclxuICBSb3V0ZXIsXHJcbiAgUm91dGVyU3RhdGVTbmFwc2hvdCxcclxuICBSdW5HdWFyZHNBbmRSZXNvbHZlcnMsXHJcbiAgVXJsU2VnbWVudCxcclxufSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5pbXBvcnQgeyBSRFRfQ0FOTk9UX0JFX0VOVEVSRURfUFJPVklERVIgfSBmcm9tICcuLi9zZXJ2aWNlcy9yZHQtY2Fubm90LWJlLWVudGVyZWQudG9rZW4nO1xyXG5pbXBvcnQgeyBSZHROYXZpZ2F0aW9uU291cmNlIH0gZnJvbSAnLi9jb25zdGFudHMnO1xyXG5pbXBvcnQgeyBSZHRSb3V0ZSB9IGZyb20gJy4vcmR0LXJvdXRlJztcclxuXHJcbmV4cG9ydCBjbGFzcyBSZHRBbmd1bGFyUm91dGU8VCBleHRlbmRzIG9iamVjdD4ge1xyXG4gIHByaXZhdGUgcm91dGU6IFJkdFJvdXRlPFQ+O1xyXG4gIHByaXZhdGUgY2hpbGRyZW46IFJvdXRlW10gPSBbXTtcclxuXHJcbiAgLy8gTXVzdCBiZSBzZXQgZnJvbSBjb21wb25lbnQgZGVjbGFyYXRpb24gZmlsZXNcclxuICBwcml2YXRlIGxvYWRDaGlsZHJlbj86IExvYWRDaGlsZHJlbkNhbGxiYWNrO1xyXG4gIHByaXZhdGUgY29tcG9uZW50PzogVHlwZTxhbnk+O1xyXG4gIHByaXZhdGUgcHJvdmlkZXJzOiAoUHJvdmlkZXIgfCBFbnZpcm9ubWVudFByb3ZpZGVycylbXSA9IFtdO1xyXG4gIHByaXZhdGUgcmVzb2x2ZXJzOiB7IFtrZXk6IHN0cmluZ106IFJlc29sdmVGbjx1bmtub3duPiB9ID0ge307XHJcbiAgcHJpdmF0ZSBjYW5BY3RpdmF0ZTogQ2FuQWN0aXZhdGVGbltdID0gW107XHJcbiAgcHJpdmF0ZSBjYW5BY3RpdmF0ZUNoaWxkOiBDYW5BY3RpdmF0ZUNoaWxkRm5bXSA9IFtdO1xyXG4gIHByaXZhdGUgY2FuRGVhY3RpdmF0ZTogQ2FuRGVhY3RpdmF0ZUZuPFQ+W10gPSBbXTtcclxuICBwcml2YXRlIHJ1bkd1YXJkc0FuZFJlc29sdmVycz86IFJ1bkd1YXJkc0FuZFJlc29sdmVycztcclxuXHJcbiAgY29uc3RydWN0b3Iocm91dGU6IFJkdFJvdXRlPFQ+KSB7XHJcbiAgICB0aGlzLnJvdXRlID0gcm91dGU7XHJcbiAgfVxyXG5cclxuICBwcm92aWRlKC4uLnByb3ZpZGVyczogVHlwZTx1bmtub3duPltdKSB7XHJcbiAgICB0aGlzLnByb3ZpZGVycy5wdXNoKC4uLnByb3ZpZGVycyk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHNldE1vZHVsZShjYWxsYmFjazogTG9hZENoaWxkcmVuQ2FsbGJhY2spIHtcclxuICAgIHRoaXMubG9hZENoaWxkcmVuID0gY2FsbGJhY2s7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIHNldENvbXBvbmVudChjb21wOiBUeXBlPGFueT4pIHtcclxuICAgIHRoaXMuY29tcG9uZW50ID0gY29tcDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgc2V0Q2hpbGRyZW4oLi4ucm91dGVzOiBSb3V0ZVtdKSB7XHJcbiAgICB0aGlzLmNoaWxkcmVuID0gcm91dGVzO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICBhZGRSZXNvbHZlKHBhcmFtTmFtZTogc3RyaW5nLCByZXNvbHZlcjogUmVzb2x2ZUZuPHVua25vd24+KSB7XHJcbiAgICB0aGlzLnJlc29sdmVyc1twYXJhbU5hbWVdID0gcmVzb2x2ZXI7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIGFkZENhbkFjdGl2YXRlKC4uLmZuczogQ2FuQWN0aXZhdGVGbltdKSB7XHJcbiAgICB0aGlzLmNhbkFjdGl2YXRlLnB1c2goLi4uZm5zKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgYWRkQ2FuRGVhY3RpdmF0ZSguLi5mbnM6IENhbkRlYWN0aXZhdGVGbjxhbnk+W10pIHtcclxuICAgIHRoaXMuY2FuRGVhY3RpdmF0ZS5wdXNoKC4uLmZucyk7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIGFkZENhbkFjdGl2YXRlQ2hpbGQoLi4uZm5zOiBDYW5BY3RpdmF0ZUNoaWxkRm5bXSkge1xyXG4gICAgdGhpcy5jYW5BY3RpdmF0ZUNoaWxkLnB1c2goLi4uZm5zKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgc2V0UnVuR3VhcmRzQW5kUmVzb2x2ZXJzKHZhbHVlOiBSdW5HdWFyZHNBbmRSZXNvbHZlcnMpIHtcclxuICAgIHRoaXMucnVuR3VhcmRzQW5kUmVzb2x2ZXJzID0gdmFsdWU7XHJcbiAgICByZXR1cm4gdGhpcztcclxuICB9XHJcblxyXG4gIGJ1aWxkKCk6IFJvdXRlIHtcclxuICAgIHRoaXMuY2hlY2tDaGlsZHJlbk1hdGNoKCk7XHJcblxyXG4gICAgbGV0IHJlczogUm91dGUgPSB7XHJcbiAgICAgIHBhdGg6IHRoaXMucm91dGUucGF0aCxcclxuICAgICAgcHJvdmlkZXJzOiB0aGlzLnByb3ZpZGVycyxcclxuICAgICAgdGl0bGU6IHRoaXMucm91dGUubmFtZSxcclxuICAgICAgY2FuTWF0Y2g6IHRoaXMuZ2V0Q2FuTWF0Y2goKSxcclxuICAgIH07XHJcblxyXG4gICAgaWYgKHRoaXMuY29tcG9uZW50KSB7XHJcbiAgICAgIHJlcy5jb21wb25lbnQgPSB0aGlzLmNvbXBvbmVudDtcclxuICAgIH0gZWxzZSBpZiAodGhpcy5sb2FkQ2hpbGRyZW4pIHtcclxuICAgICAgcmVzLmxvYWRDaGlsZHJlbiA9IHRoaXMubG9hZENoaWxkcmVuO1xyXG4gICAgfVxyXG5cclxuICAgIHJlcy5kYXRhID0ge1xyXG4gICAgICBicmVhZGNydW1iOiB7XHJcbiAgICAgICAgbGFiZWw6IHRoaXMucm91dGUubmFtZSxcclxuICAgICAgICBkaXNhYmxlOiB0aGlzLnJvdXRlLmVudHJ5RGlzYWJsZWQsXHJcbiAgICAgICAgc3RhdGljU3RhdGVQYXJhbXM6IHtcclxuICAgICAgICAgIHNyYzogUmR0TmF2aWdhdGlvblNvdXJjZS5CUkVBRENSVU1CLFxyXG4gICAgICAgIH0sXHJcbiAgICAgIH0sXHJcbiAgICB9O1xyXG5cclxuICAgIGNvbnN0IGd1YXJkOiBDYW5BY3RpdmF0ZUZuID0gKFxyXG4gICAgICByb3V0ZTogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCxcclxuICAgICAgc3RhdGU6IFJvdXRlclN0YXRlU25hcHNob3RcclxuICAgICkgPT4ge1xyXG4gICAgICBjb25zdCBpbmplY3RvciA9IGluamVjdChFbnZpcm9ubWVudEluamVjdG9yKTtcclxuICAgICAgaWYgKFxyXG4gICAgICAgIHJ1bkluSW5qZWN0aW9uQ29udGV4dChcclxuICAgICAgICAgIGluamVjdG9yLFxyXG4gICAgICAgICAgdGhpcy5yb3V0ZS5jYW5CZUVudGVyZWQuYmluZCh0aGlzLnJvdXRlKVxyXG4gICAgICAgIClcclxuICAgICAgKSB7XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29uc3Qgcm91dGVyID0gaW5qZWN0KFJvdXRlcik7XHJcbiAgICAgICAgY29uc3QgbG9jYXRpb24gPSBpbmplY3QoTG9jYXRpb24pO1xyXG4gICAgICAgIGxldCB1cmwgPSBpbmplY3QoUkRUX0NBTk5PVF9CRV9FTlRFUkVEX1BST1ZJREVSKTtcclxuICAgICAgICBpZiAodHlwZW9mIHVybCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgdXJsID0gcnVuSW5JbmplY3Rpb25Db250ZXh0KFxyXG4gICAgICAgICAgICBpbmplY3RvcixcclxuICAgICAgICAgICAgdXJsLmJpbmQodXJsLCBsb2NhdGlvbi5wYXRoKCksIHN0YXRlLnVybCwgdGhpcy5yb3V0ZSlcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0eXBlb2YgdXJsID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgcmV0dXJuIHJvdXRlci5wYXJzZVVybCh1cmwpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gICAgdGhpcy5jYW5BY3RpdmF0ZS5wdXNoKGd1YXJkKTtcclxuICAgIHRoaXMuY2FuQWN0aXZhdGVDaGlsZC5wdXNoKGd1YXJkKTtcclxuXHJcbiAgICByZXMuY2FuQWN0aXZhdGUgPSB0aGlzLmNhbkFjdGl2YXRlO1xyXG4gICAgcmVzLmNhbkRlYWN0aXZhdGUgPSB0aGlzLmNhbkRlYWN0aXZhdGU7XHJcblxyXG4gICAgLy8gSWYgY2hpbGRyZW4gZXhpc3QsIGNoYW5nZVxyXG4gICAgLy8ge1xyXG4gICAgLy8gICAgcGF0aDogJy9wYXRoJyxcclxuICAgIC8vICAgIGNvbXBvbmVudDogRmVhdHVyZUNvbXBvbmVudCxcclxuICAgIC8vICAgIGNoaWxkcmVuOiBbLi4uXVxyXG4gICAgLy8gfVxyXG4gICAgLy8gaW50b1xyXG4gICAgLy8ge1xyXG4gICAgLy8gICAgcGF0aDogJy9wYXRoJyxcclxuICAgIC8vICAgIGNoaWxkcmVuOiBbXHJcbiAgICAvLyAgICAgIHtcclxuICAgIC8vICAgICAgICBwYXRoOiAnJyxcclxuICAgIC8vICAgICAgICBjb21wb25lbnQ6IEZlYXR1cmVDb21wb25lbnRcclxuICAgIC8vICAgICAgfSxcclxuICAgIC8vICAgIC4uLlxyXG4gICAgLy8gICAgXVxyXG4gICAgLy8gICAgfVxyXG4gICAgaWYgKHRoaXMuY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xyXG4gICAgICBpZiAodGhpcy5sb2FkQ2hpbGRyZW4gfHwgdGhpcy5jb21wb25lbnQpIHtcclxuICAgICAgICBjb25zdCBwYXRoID0gcmVzLnBhdGg7XHJcbiAgICAgICAgcmVzLnBhdGggPSAnJztcclxuICAgICAgICByZXMucGF0aE1hdGNoID0gJ2Z1bGwnO1xyXG4gICAgICAgIHJlcy5jYW5NYXRjaCA9IHVuZGVmaW5lZDtcclxuICAgICAgICByZXMgPSB7XHJcbiAgICAgICAgICBwYXRoOiBwYXRoLFxyXG4gICAgICAgICAgY2hpbGRyZW46IFtyZXMsIC4uLnRoaXMuY2hpbGRyZW5dLFxyXG4gICAgICAgICAgY2FuQWN0aXZhdGVDaGlsZDogdGhpcy5jYW5BY3RpdmF0ZUNoaWxkLFxyXG4gICAgICAgICAgY2FuTWF0Y2g6IHRoaXMuZ2V0Q2FuTWF0Y2goKSxcclxuICAgICAgICB9O1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJlcy5jaGlsZHJlbiA9IHRoaXMuY2hpbGRyZW47XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5yZXNvbHZlcnMpLmxlbmd0aCA+IDApIHtcclxuICAgICAgcmVzLnJlc29sdmUgPSB0aGlzLnJlc29sdmVycztcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5ydW5HdWFyZHNBbmRSZXNvbHZlcnMpIHtcclxuICAgICAgcmVzLnJ1bkd1YXJkc0FuZFJlc29sdmVycyA9IHRoaXMucnVuR3VhcmRzQW5kUmVzb2x2ZXJzO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiByZXM7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldENhbk1hdGNoKCk6IENhbk1hdGNoRm5bXSB8IHVuZGVmaW5lZCB7XHJcbiAgICBjb25zdCBwYXJhbU1hcCA9IHRoaXMucm91dGUucGFyYW1NYXA7XHJcbiAgICBjb25zdCBoYXNOdW1iZXJQYXJhbXMgPSBPYmplY3Qua2V5cyhwYXJhbU1hcCkuc29tZShcclxuICAgICAgKHApID0+IHBhcmFtTWFwW3AgYXMga2V5b2YgVF0gPT09ICdudW1iZXInXHJcbiAgICApO1xyXG4gICAgaWYgKCFoYXNOdW1iZXJQYXJhbXMpIHtcclxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH1cclxuICAgIGNvbnN0IHJvdXRlU2VnbWVudExlbmd0aCA9IHRoaXMucm91dGUucGF0aC5zcGxpdCgnLycpLmxlbmd0aDtcclxuICAgIGNvbnN0IHJlZ2V4ID0gbmV3IFJlZ0V4cChgXiR7dGhpcy5yb3V0ZS5yZWdleC5zb3VyY2V9JGApO1xyXG4gICAgcmV0dXJuIFtcclxuICAgICAgKHJvdXRlOiBSb3V0ZSwgc2VnbWVudHM6IFVybFNlZ21lbnRbXSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHBhdGggPSBzZWdtZW50c1xyXG4gICAgICAgICAgLnNsaWNlKDAsIHJvdXRlU2VnbWVudExlbmd0aClcclxuICAgICAgICAgIC5tYXAoKHMpID0+IHMucGF0aClcclxuICAgICAgICAgIC5qb2luKCcvJyk7XHJcbiAgICAgICAgcmV0dXJuIHJlZ2V4LnRlc3QocGF0aCk7XHJcbiAgICAgIH0sXHJcbiAgICBdO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjaGVja0NoaWxkcmVuTWF0Y2goKSB7XHJcbiAgICAvLyBDaGVjayB0aGF0IGFsbCByb3V0ZXMgYXJlIHByZXNlbnQgaWYgcm91dGUgaXMgbm90XHJcbiAgICAvLyBsYXp5IGxvYWRlZCBtb2R1bGUuXHJcbiAgICBpZiAoXHJcbiAgICAgICF0aGlzLmxvYWRDaGlsZHJlbiAmJlxyXG4gICAgICAodGhpcy5yb3V0ZS5jaGlsZHJlbi5sZW5ndGggPiAwIHx8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoID4gMClcclxuICAgICkge1xyXG4gICAgICBpZiAodGhpcy5jaGlsZHJlbi5sZW5ndGggPCB0aGlzLnJvdXRlLmNoaWxkcmVuLmxlbmd0aCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcclxuICAgICAgICAgIGBSZHRSb3V0ZSAke3RoaXMucm91dGUubmFtZX0gaGFzICR7XHJcbiAgICAgICAgICAgIHRoaXMucm91dGUuY2hpbGRyZW4ubGVuZ3RoXHJcbiAgICAgICAgICB9IGNoaWxkcmVuLCBidXQgUmR0QW5ndWxhclJvdXRlIGhhcyAke1xyXG4gICAgICAgICAgICB0aGlzLmNoaWxkcmVuLmxlbmd0aFxyXG4gICAgICAgICAgfS4gVGhlc2UgbnVtYmVycyBtdXN0IG1hdGNoLiBEaWQgeW91IGZvcmdldCB0byBjYWxsIC5zZXRDaGlsZHJlbigpIG1ldGhvZCBpbiBnbG9iYWwgcm91dGVzIGRlZmluaXRpb24/IFJvdXRlcyB3aXRoIGZvbGxvd2luZyBuYW1lcyBzaG91bGQgYmUgcHJlc2VudDogJHt0aGlzLnJvdXRlLmNoaWxkcmVuXHJcbiAgICAgICAgICAgIC5tYXAoKGNoKSA9PiBjaC5uYW1lKVxyXG4gICAgICAgICAgICAuam9pbignLCAnKX1gXHJcbiAgICAgICAgKTtcclxuICAgICAgfSBlbHNlIGlmICh0aGlzLmNoaWxkcmVuLmxlbmd0aCA+IHRoaXMucm91dGUuY2hpbGRyZW4ubGVuZ3RoKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxyXG4gICAgICAgICAgYFJkdFJvdXRlICR7dGhpcy5yb3V0ZS5uYW1lfSBoYXMgJHtcclxuICAgICAgICAgICAgdGhpcy5yb3V0ZS5jaGlsZHJlbi5sZW5ndGhcclxuICAgICAgICAgIH0gY2hpbGRyZW4sIGJ1dCBSZHRBbmd1bGFyUm91dGUgaGFzICR7XHJcbiAgICAgICAgICAgIHRoaXMuY2hpbGRyZW4ubGVuZ3RoXHJcbiAgICAgICAgICB9LiBUaGVzZSBudW1iZXJzIG11c3QgbWF0Y2guIERpZCB5b3UgZm9yZ2V0IHRvIGNhbGwgLnNldENoaWxkcmVuKCkgbWV0aG9kIGluIGZlYXR1cmUgc2hlbGwgcm91dGVzIGRlZmluaXRpb24/IFJvdXRlcyB3aXRoIGZvbGxvd2luZyBwYXRocyBzaG91bGQgYmUgcHJlc2VudDogJHt0aGlzLmNoaWxkcmVuXHJcbiAgICAgICAgICAgIC5tYXAoKGNoKSA9PiBjaC5wYXRoKVxyXG4gICAgICAgICAgICAuam9pbignLCAnKX1gXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgICBjb25zdCBuMSA9IHRoaXMuY2hpbGRyZW4ubWFwKChjaCkgPT4gY2gucGF0aCEpO1xyXG4gICAgICBjb25zdCBuMiA9IHRoaXMucm91dGUuY2hpbGRyZW4ubWFwKChjaCkgPT4gY2gucGF0aCk7XHJcbiAgICAgIG4xLnNvcnQoKTtcclxuICAgICAgbjIuc29ydCgpO1xyXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG4xLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgaWYgKG4xW2ldICE9PSBuMltpXSkge1xyXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxyXG4gICAgICAgICAgICBgUGF0aHMgb2YgY2hpbGRyZW4gcHJvdmlkZWQgaW4gUmR0Um91dGUgYW5kXHJcbiAgICAgICAgICAgIFJkdEFuZ3VsYXJSb3V0ZSBkbyBub3QgbWF0Y2guICR7bjFbaV19ICE9ICR7bjJbaV19YFxyXG4gICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcbn1cclxuIl19
|