@uql/core 0.4.82 → 0.4.85

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 CHANGED
@@ -1,14 +1,12 @@
1
1
  # [uql](https://uql.io) · [![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/rogerpadilla/uql/blob/main/LICENSE) [![tests](https://github.com/rogerpadilla/uql/actions/workflows/tests.yml/badge.svg)](https://github.com/rogerpadilla/uql) [![coverage status](https://coveralls.io/repos/rogerpadilla/uql/badge.svg?branch=main)](https://coveralls.io/r/rogerpadilla/uql?branch=main) [![npm version](https://badge.fury.io/js/%40uql%2Fcore.svg)](https://badge.fury.io/js/%40uql%2Fcore)
2
2
 
3
- [Learn how to use uql in your own project](https://uql.io).
3
+ Learn more of uql in the website https://uql.io :high_brightness:
4
4
 
5
- # Getting Started
5
+ # Quick Start
6
6
 
7
- `uql` is a flexible and efficient `ORM`, with declarative `JSON` syntax and smart type-safety.
7
+ `uql` is a flexible and efficient `ORM`, with declarative `JSON` syntax and really smart type-safety.
8
8
 
9
- Given it is just a small library with serializable `JSON` syntax, the queries can be written in the client (web/mobile) and send to the backend, or just use `uql` directly in the backend, or even use it in a mobile app with an embedded database.
10
-
11
- ![autocomplete demo](https://uql.io/code.gif)
9
+ The `uql` queries can be safely written in the frontend (browser/mobile) and sent to the backend; or only use `uql` in the backend, or even in a mobile app with an embedded database (like `sqlite`).
12
10
 
13
11
  ## <a name="features"></a> Features
14
12
 
@@ -18,21 +16,8 @@ Given it is just a small library with serializable `JSON` syntax, the queries ca
18
16
  - `$project`, `$filter`, `$sort`, `$limit` works at multiple levels (including deep relations and their fields).
19
17
  - declarative and imperative `transactions`.
20
18
  - `soft-delete`, `virtual fields`, `repositories`, `connection pooling`.
21
- - different kinds of `relations` between entities.
22
19
  - transparent support for `inheritance` patterns between entities.
23
20
  - supports `Postgres`, `MySQL`, `MariaDB`, `SQLite`, `MongoDB` (beta).
24
- - plugins for frameworks: `express` (more coming).
25
-
26
- ## Table of Contents
27
-
28
- 1. [Installation](#installation)
29
- 2. [Configuration](#configuration)
30
- 3. [Entities](#entities)
31
- 4. [Declarative Transactions](#declarative-transactions)
32
- 5. [Imperative Transactions](#imperative-transactions)
33
- 6. [Generate REST APIs with Express](#express)
34
- 7. [Consume REST APIs from the Frontend](#client)
35
- 8. [FAQs](#faq)
36
21
 
37
22
  ## <a name="installation"></a> Installation
38
23
 
@@ -48,62 +33,64 @@ Given it is just a small library with serializable `JSON` syntax, the queries ca
48
33
  yarn add @uql/core
49
34
  ```
50
35
 
51
- 1. Install one of the following packages according to your database:
36
+ 2. Install one of the specific packages according to your database:
52
37
 
53
- | Database | Package |
54
- | ------------ | --------------- |
55
- | `MySQL` | `@uql/mysql` |
56
- | `MariaDB` | `@uql/maria` |
57
- | `PostgreSQL` | `@uql/postgres` |
58
- | `SQLite` | `@uql/sqlite` |
59
- | `MongoDB` | `@uql/mongo` |
38
+ | Database | Package |
39
+ | ------------ | --------------- |
40
+ | `MySQL` | `@uql/mysql` |
41
+ | `PostgreSQL` | `@uql/postgres` |
42
+ | `MariaDB` | `@uql/maria` |
43
+ | `MongoDB` | `@uql/mongo` |
44
+ | `SQLite` | `@uql/sqlite` |
60
45
 
61
- E.g. for `PostgreSQL`
46
+ E.g. for `PostgreSQL`
62
47
 
63
- ```sh
64
- npm install @uql/postgres --save
65
- ```
48
+ ```sh
49
+ npm install @uql/postgres --save
50
+ ```
66
51
 
67
- or with _yarn_
52
+ or with _yarn_
68
53
 
69
- ```sh
70
- yarn add @uql/postgres
71
- ```
54
+ ```sh
55
+ yarn add @uql/postgres
56
+ ```
72
57
 
73
- 1. Additionally, your `tsconfig.json` needs the following flags:
58
+ 3. Additionally, your `tsconfig.json` may need the following flags:
74
59
 
75
- ```json
76
- "target": "es6", // or a more recent ecmascript version.
77
- "experimentalDecorators": true,
78
- "emitDecoratorMetadata": true
79
- ```
60
+ ```json
61
+ "target": "es6", // or a more recent ecmascript version.
62
+ "experimentalDecorators": true,
63
+ "emitDecoratorMetadata": true
64
+ ```
80
65
 
81
66
  ## <a name="configuration"></a> Configuration
82
67
 
83
- Initialization should be done once (e.g. in one of the bootstrap files of your app).
68
+ A default querier-pool can be set in any of the bootstrap files of your app (e.g. in the `server.ts`).
84
69
 
85
70
  ```ts
86
- import { setOptions } from '@uql/core';
71
+ import { setDefaultQuerierPool } from '@uql/core';
87
72
  import { PgQuerierPool } from '@uql/postgres';
88
73
 
89
- setOptions({
90
- querierPool: new PgQuerierPool(
91
- {
92
- host: 'localhost',
93
- user: 'theUser',
94
- password: 'thePassword',
95
- database: 'theDatabase',
96
- },
97
- console.log
98
- ),
99
- });
74
+ const querierPool = new PgQuerierPool(
75
+ {
76
+ host: 'localhost',
77
+ user: 'theUser',
78
+ password: 'thePassword',
79
+ database: 'theDatabase',
80
+ },
81
+ // a logger can optionally be passed so the SQL queries are logged
82
+ console.log
83
+ );
84
+
85
+ setDefaultQuerierPool(querierPool);
100
86
  ```
101
87
 
102
- ## <a name="entities"></a> Entities
88
+ ## <a name="definition-of-entities"></a> Definition of Entities
103
89
 
104
90
  Take any dump class (aka DTO) and annotate it with the decorators from `'@uql/core/entity'`.
105
91
 
106
92
  ```ts
93
+ import { v4 as uuidv4 } from 'uuid';
107
94
  import { Field, ManyToOne, Id, OneToMany, Entity, OneToOne, ManyToMany } from '@uql/core/entity';
108
95
 
109
96
  @Entity()
@@ -111,21 +98,21 @@ export class Profile {
111
98
  /**
112
99
  * primary key
113
100
  */
114
- @Id()
115
- id?: number;
101
+ @Id({ onInsert: uuidv4 })
102
+ id?: string;
116
103
  @Field()
117
104
  picture?: string;
118
105
  /**
119
106
  * foreign-keys are really simple to specify.
120
107
  */
121
108
  @Field({ reference: () => User })
122
- creatorId?: number;
109
+ creatorId?: string;
123
110
  }
124
111
 
125
112
  @Entity()
126
113
  export class User {
127
- @Id()
128
- id?: number;
114
+ @Id({ onInsert: uuidv4 })
115
+ id?: string;
129
116
  @Field()
130
117
  name?: string;
131
118
  @Field()
@@ -141,8 +128,8 @@ export class User {
141
128
 
142
129
  @Entity()
143
130
  export class MeasureUnitCategory {
144
- @Id()
145
- id?: number;
131
+ @Id({ onInsert: uuidv4 })
132
+ id?: string;
146
133
  @Field()
147
134
  name?: string;
148
135
  @OneToMany({ entity: () => MeasureUnit, mappedBy: (measureUnit) => measureUnit.category })
@@ -151,232 +138,35 @@ export class MeasureUnitCategory {
151
138
 
152
139
  @Entity()
153
140
  export class MeasureUnit {
154
- @Id()
155
- id?: number;
141
+ @Id({ onInsert: uuidv4 })
142
+ id?: string;
156
143
  @Field()
157
144
  name?: string;
158
145
  @Field({ reference: () => MeasureUnitCategory })
159
- categoryId?: number;
146
+ categoryId?: string;
160
147
  @ManyToOne({ cascade: 'persist' })
161
148
  category?: MeasureUnitCategory;
162
149
  }
163
-
164
- @Entity()
165
- export class Item {
166
- @Id()
167
- id?: number;
168
- @Field()
169
- name?: string;
170
- @Field()
171
- description?: string;
172
- @Field()
173
- code?: string;
174
- @ManyToMany({ entity: () => Tag, through: () => ItemTag, cascade: true })
175
- tags?: Tag[];
176
- }
177
-
178
- @Entity()
179
- export class Tag {
180
- @Id()
181
- id?: number;
182
- @Field()
183
- name?: string;
184
- @ManyToMany({ entity: () => Item, mappedBy: (item) => item.tags })
185
- items?: Item[];
186
- }
187
-
188
- @Entity()
189
- export class ItemTag {
190
- @Id()
191
- id?: number;
192
- @Field({ reference: () => Item })
193
- itemId?: number;
194
- @Field({ reference: () => Tag })
195
- tagId?: number;
196
- }
197
150
  ```
198
151
 
199
- ## <a name="declarative-transactions"></a> Declarative Transactions
200
-
201
- Both, _declarative_ and _imperative_ transactions are supported, with the former you can just describe the scope of your transactions, with the later you have more flexibility (hence more responsibility).
202
-
203
- To use Declarative Transactions (using the `@Transactional` decorator):
204
-
205
- 1. take any service class, annotate the wanted function with the `@Transactional` decorator.
206
- 2. inject the querier instance by decorating one of the function's arguments with `@InjectQuerier`.
152
+ ## <a name="creation-of-queries"></a> Creation of Queries
207
153
 
208
154
  ```ts
209
- import { Querier } from '@uql/core/type';
210
- import { Transactional, InjectQuerier } from '@uql/core/querier';
211
-
212
- class ConfirmationService {
213
- @Transactional()
214
- async confirm(confirmation: Confirmation, @InjectQuerier() querier?: Querier): Promise<void> {
215
- if (confirmation.type === 'register') {
216
- await querier.insertOne(User, {
217
- name: confirmation.name,
218
- email: confirmation.email,
219
- password: confirmation.password,
220
- });
221
- } else {
222
- await querier.updateOneById(User, confirmation.creatorId, {
223
- password: confirmation.password,
224
- });
225
- }
226
- await querier.updateOneById(Confirmation, confirmation.id, { status: 1 });
227
- }
228
- }
155
+ import { getQuerier, getRepository } from '@uql/core';
156
+ import { User } from './entity';
229
157
 
230
- export const confirmationService = new ConfirmationService();
231
-
232
- /**
233
- * then you could just import the constant `confirmationService` in another file,
234
- * and when you call `confirmAction` function, all the operations there
235
- * will (automatically) run inside a single transaction.
236
- */
237
- await confirmationService.confirmAction(data);
238
- ```
158
+ const querier = await getQuerier();
239
159
 
240
- ## <a name="imperative-transactions"></a> Imperative Transactions
241
-
242
- `uql` supports both, _declarative_ and _imperative_ transactions, with the former you can just describe the scope of your transactions, with the later you have more flexibility (hence more responsibility).
243
-
244
- To use Imperative Transactions:
245
-
246
- 1. obtain the `querier` object with `await getQuerier()`.
247
- 2. run the transaction with `await querier.transaction(callback)`.
248
- 3. perform the different operations using the same `querier` (or `repositories`) inside your `callback` function.
160
+ const users = await querier.findMany(User, {
161
+ $project: { id: true, email: true, profile: ['id', 'picture'] },
162
+ $filter: { email: { $iendsWith: '@google.com' } },
163
+ $sort: { createdAt: -1 },
164
+ $limit: 100,
165
+ });
249
166
 
250
- ```ts
251
- import { getQuerier } from '@uql/core';
252
-
253
- async function confirm(confirmation: Confirmation): Promise<void> {
254
- const querier = await getQuerier();
255
- await querier.transaction(async () => {
256
- if (confirmation.action === 'signup') {
257
- await querier.insertOne(User, {
258
- name: confirmation.name,
259
- email: confirmation.email,
260
- password: confirmation.password,
261
- });
262
- } else {
263
- await querier.updateOneById(User, confirmation.creatorId, {
264
- password: confirmation.password,
265
- });
266
- }
267
- await querier.updateOneById(Confirmation, confirmation.id, { status: 1 });
268
- });
269
- }
167
+ await querier.release();
270
168
  ```
271
169
 
272
170
  ---
273
171
 
274
- That &#9650; can also be implemented as this &#9660; (for more granular control):
275
-
276
- ```ts
277
- async function confirm(confirmation: Confirmation): Promise<void> {
278
- const querier = await getQuerier();
279
- try {
280
- await querier.beginTransaction();
281
- if (confirmation.action === 'signup') {
282
- await querier.insertOne(User, {
283
- name: confirmation.name,
284
- email: confirmation.email,
285
- password: confirmation.password,
286
- });
287
- } else {
288
- await querier.updateOneById(User, confirmation.creatorId, {
289
- password: confirmation.password,
290
- });
291
- }
292
- await querier.updateOneById(Confirmation, confirmation.id, { status: 1 });
293
- await querier.commitTransaction();
294
- } catch (error) {
295
- await querier.rollbackTransaction();
296
- throw error;
297
- } finally {
298
- await querier.release();
299
- }
300
- }
301
- ```
302
-
303
- ## <a name="express"></a> Autogenerate REST APIs with Express
304
-
305
- A `express` plugin is provided to automatically generate REST APIs for your entities.
306
-
307
- 1. Install express plugin in your server project:
308
-
309
- ```sh
310
- npm install @uql/express --save
311
- ```
312
-
313
- or with _yarn_
314
-
315
- ```sh
316
- yarn add @uql/express
317
- ```
318
-
319
- 1. Initialize the `express` middleware in your server code to generate REST APIs for your entities
320
-
321
- ```ts
322
- import * as express from 'express';
323
- import { augmentFilter } from '@uql/core/util';
324
- import { Query, QueryFilter, EntityMeta } from '@uql/core/type';
325
- import { querierMiddleware } from '@uql/express';
326
-
327
- const app = express();
328
-
329
- app
330
- // ...
331
- .use(
332
- '/api',
333
-
334
- // this will generate REST APIs for the entities.
335
- querierMiddleware({
336
- // all entities will be automatically exposed unless
337
- // 'include' or 'exclude' options are provided.
338
- exclude: [Confirmation],
339
-
340
- // `augmentQuery` callback allows to extend all then queries that are requested to the API,
341
- // so it is a good place to add additional filters to the queries,
342
- // e.g. for multi tenant apps.
343
- augmentQuery: <E>(meta: EntityMeta<E>, qm: Query<E>, req: express.Request): Query<E> => {
344
- // ensure the user can only see the data that belongs to his company.
345
- qm.$filter = augmentFilter(meta, qm.$filter, { companyId: req.identity.companyId } as QueryFilter<E>);
346
- return qm;
347
- },
348
- })
349
- );
350
- ```
351
-
352
- ## <a name="client"></a> Easily call the generated REST APIs from the Client
353
-
354
- A client plugin (for browser/mobile) is provided to easily consume the REST APIs from the frontend.
355
-
356
- 1. Install client plugin in your frontend project:
357
-
358
- ```sh
359
- npm install @uql/client --save
360
- ```
361
-
362
- or with _yarn_
363
-
364
- ```sh
365
- yarn add @uql/client
366
- ```
367
-
368
- 1. Use the client to call the `uql` CRUD API
369
-
370
- ```ts
371
- import { getRepository } from '@uql/client';
372
-
373
- // 'User' is an entity class.
374
- const userRepository = getRepository(User);
375
-
376
- const users = await userRepository.findMany({
377
- $project: { email: true, profile: ['picture'] },
378
- $filter: { email: { $endsWith: '@domain.com' } },
379
- $sort: { createdAt: -1 },
380
- $limit: 100,
381
- });
382
- ```
172
+ See more in https://uql.io :high_brightness:
@@ -13,9 +13,6 @@ function defineField(entity, key, opts = {}) {
13
13
  const type = inferType(entity, key);
14
14
  opts = { ...opts, type };
15
15
  }
16
- if (typeof opts.reference === 'function') {
17
- opts = { ...opts, reference: { entity: opts.reference } };
18
- }
19
16
  meta.fields[key] = { ...meta.fields[key], ...{ name: key, ...opts } };
20
17
  return meta;
21
18
  }
@@ -135,31 +132,32 @@ function fillInverseSideRelations(relOpts) {
135
132
  const relEntity = relOpts.entity();
136
133
  const relMeta = getMeta(relEntity);
137
134
  relOpts.mappedBy = getMappedByRelationKey(relOpts);
138
- // reversing references here makes the SQL generation simpler (no need to check for `mappedBy`)
139
- const { cardinality, references, through } = relMeta.relations[relOpts.mappedBy];
140
- if (cardinality === '11' || cardinality === 'm1') {
141
- relOpts.references = references.map(({ local, foreign }) => ({
142
- local: foreign,
143
- foreign: local,
144
- }));
135
+ if (relMeta.fields[relOpts.mappedBy]) {
136
+ relOpts.references = [{ local: relMeta.id, foreign: relOpts.mappedBy }];
137
+ return;
145
138
  }
146
- else {
147
- relOpts.references = references.slice().reverse();
148
- relOpts.through = through;
139
+ const mappedByRelation = relMeta.relations[relOpts.mappedBy];
140
+ if (relOpts.cardinality === 'm1' || relOpts.cardinality === 'mm') {
141
+ relOpts.references = mappedByRelation.references.slice().reverse();
142
+ relOpts.through = mappedByRelation.through;
143
+ return;
149
144
  }
145
+ relOpts.references = mappedByRelation.references.map(({ local, foreign }) => ({
146
+ local: foreign,
147
+ foreign: local,
148
+ }));
150
149
  }
151
150
  function fillThroughRelations(entity) {
152
151
  const meta = ensureMeta(entity);
153
152
  meta.relations = (0, util_1.getKeys)(meta.fields).reduce((relations, key) => {
154
153
  const { reference } = meta.fields[key];
155
154
  if (reference) {
156
- const relEntityGetter = reference.entity;
157
- const relEntity = relEntityGetter();
155
+ const relEntity = reference();
158
156
  const relMeta = ensureMeta(relEntity);
159
157
  const relKey = key.slice(0, -relMeta.id.length);
160
158
  const relOpts = {
159
+ entity: reference,
161
160
  cardinality: 'm1',
162
- entity: relEntityGetter,
163
161
  references: [{ local: key, foreign: relMeta.id }],
164
162
  };
165
163
  relations[relKey] = relOpts;
@@ -177,7 +175,9 @@ function getMappedByRelationKey(relOpts) {
177
175
  return relOpts.mappedBy;
178
176
  }
179
177
  function getRelationKeyMap(meta) {
180
- return (0, util_1.getKeys)(meta.relations).reduce((acc, key) => {
178
+ return (0, util_1.getKeys)(meta.fields)
179
+ .concat((0, util_1.getKeys)(meta.relations))
180
+ .reduce((acc, key) => {
181
181
  acc[key] = key;
182
182
  return acc;
183
183
  }, {});
@@ -220,4 +220,4 @@ function isValidEntityType(type) {
220
220
  type !== Object);
221
221
  }
222
222
  exports.isValidEntityType = isValidEntityType;
223
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmaW5pdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9lbnRpdHkvZGVjb3JhdG9yL2RlZmluaXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNEJBQTBCO0FBQzFCLHlDQUEwRTtBQWMxRSxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUM7QUFDMUIsTUFBTSxPQUFPLEdBQUcsNEJBQTRCLENBQUM7QUFDN0MsTUFBTSxLQUFLLEdBQW9DLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFDO0FBQzVFLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUM7QUFFeEIsU0FBZ0IsV0FBVyxDQUFJLE1BQWUsRUFBRSxHQUFXLEVBQUUsT0FBcUIsRUFBRTtJQUNsRixNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDaEMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7UUFDZCxNQUFNLElBQUksR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3BDLElBQUksR0FBRyxFQUFFLEdBQUcsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDO0tBQzFCO0lBQ0QsSUFBSSxPQUFPLElBQUksQ0FBQyxTQUFTLEtBQUssVUFBVSxFQUFFO1FBQ3hDLElBQUksR0FBRyxFQUFFLEdBQUcsSUFBSSxFQUFFLFNBQVMsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQztLQUMzRDtJQUNELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLEVBQUUsRUFBRSxDQUFDO0lBQ3RFLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQVhELGtD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Q0QsTUFBTSxDQUFDLE1BQU0sR0FBRyxFQUFFLEdBQUcsWUFBWSxFQUFFLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ3RELE1BQU0sQ0FBQyxTQUFTLEdBQUcsRUFBRSxHQUFHLE1BQU0sQ0FBQyxTQUFTLEVBQUUsR0FBRyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUM7QUFDbEUsQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFJLE1BQWUsRUFBRSxHQUFXO0lBQ2hELE9BQU8sT0FBTyxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsTUFBTSxDQUFDLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQztBQUNuRSxDQUFDO0FBRUQsU0FBUyxlQUFlLENBQUksTUFBZSxFQUFFLEdBQVc7SUFDdEQsTUFBTSxZQUFZLEdBQUcsU0FBUyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsQ0FBQztJQUM1QyxNQUFNLFdBQVcsR0FBRyxpQkFBaUIsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNwRCxJQUFJLENBQUMsV0FBVyxFQUFFO1FBQ2hCLE1BQU0sU0FBUyxDQUFDLElBQUksTUFBTSxDQUFDLElBQUksSUFBSSxHQUFHLCtDQUErQyxZQUFZLEVBQUUsSUFBSSxHQUFHLENBQUMsQ0FBQztLQUM3RztJQUNELE9BQU8sWUFBWSxDQUFDO0FBQ3RCLENBQUM7QUFFRCxTQUFnQixpQkFBaUIsQ0FBQyxJQUFTO0lBQ3pDLE9BQU8sQ0FDTCxPQUFPLElBQUksS0FBSyxVQUFVO1FBQzFCLElBQUksS0FBSyxPQUFPO1FBQ2hCLElBQUksS0FBSyxNQUFNO1FBQ2YsSUFBSSxLQUFLLE1BQU07UUFDZixJQUFJLEtBQUssTUFBTTtRQUNmLElBQUksS0FBSyxJQUFJO1FBQ2IsSUFBSSxLQUFLLE1BQU07UUFDZixJQUFJLEtBQUssTUFBTSxDQUNoQixDQUFDO0FBQ0osQ0FBQztBQVhELDhDQVdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICdyZWZsZWN0LW1ldGFkYXRhJztcbmltcG9ydCB7IGhhc0tleXMsIGxvd2VyRmlyc3QsIGdldEtleXMsIHVwcGVyRmlyc3QgfSBmcm9tICdAdXFsL2NvcmUvdXRpbCc7XG5pbXBvcnQge1xuICBSZWxhdGlvbk9wdGlvbnMsXG4gIEZpZWxkT3B0aW9ucyxcbiAgRW50aXR5T3B0aW9ucyxcbiAgRW50aXR5TWV0YSxcbiAgVHlwZSxcbiAgUmVsYXRpb25LZXlNYXAsXG4gIFJlZmVyZW5jZU9wdGlvbnMsXG4gIFJlbGF0aW9uS2V5LFxuICBGaWVsZEtleSxcbiAgSWRLZXksXG59IGZyb20gJ0B1cWwvY29yZS90eXBlJztcblxuY29uc3QgaG9sZGVyID0gZ2xvYmFsVGhpcztcbmNvbnN0IG1ldGFLZXkgPSAnQHVxbC9jb3JlL2VudGl0eS9kZWNvcmF0b3InO1xuY29uc3QgbWV0YXM6IE1hcDxUeXBlPGFueT4sIEVudGl0eU1ldGE8YW55Pj4gPSBob2xkZXJbbWV0YUtleV0gPz8gbmV3IE1hcCgpO1xuaG9sZGVyW21ldGFLZXldID0gbWV0YXM7XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZpbmVGaWVsZDxFPihlbnRpdHk6IFR5cGU8RT4sIGtleTogc3RyaW5nLCBvcHRzOiBGaWVsZE9wdGlvbnMgPSB7fSk6IEVudGl0eU1ldGE8RT4ge1xuICBjb25zdCBtZXRhID0gZW5zdXJlTWV0YShlbnRpdHkpO1xuICBpZiAoIW9wdHMudHlwZSkge1xuICAgIGNvbnN0IHR5cGUgPSBpbmZlclR5cGUoZW50aXR5LCBrZXkpO1xuICAgIG9wdHMgPSB7IC4uLm9wdHMsIHR5cGUgfTtcbiAgfVxuICBpZiAodHlwZW9mIG9wdHMucmVmZXJlbmNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgb3B0cyA9IHsgLi4ub3B0cywgcmVmZXJlbmNlOiB7IGVudGl0eTogb3B0cy5yZWZlcmVuY2UgfSB9O1xuICB9XG4gIG1ldGEuZmllbGRzW2tleV0gPSB7IC4uLm1ldGEuZmllbGRzW2tleV0sIC4uLnsgbmFtZToga2V5LCAuLi5vcHRzIH0gfTtcbiAgcmV0dXJuIG1ldGE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZpbmVJZDxFPihlbnRpdHk6IFR5cGU8RT4sIGtleTogc3RyaW5nLCBvcHRzOiBGaWVsZE9wdGlvbnMpOiBFbnRpdHlNZXRhPEU+IHtcbiAgY29uc3QgbWV0YSA9IGVuc3VyZU1ldGEoZW50aXR5KTtcbiAgY29uc3QgaWQgPSBnZXRJZEtleShtZXRhKTtcbiAgaWYgKGlkKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKGAnJHtlbnRpdHkubmFtZX0nIG11c3QgaGF2ZSBhIHNpbmdsZSBmaWVsZCBkZWNvcmF0ZWQgd2l0aCBASWRgKTtcbiAgfVxuICByZXR1cm4gZGVmaW5lRmllbGQoZW50aXR5LCBrZXksIHsgLi4ub3B0cywgaXNJZDogdHJ1ZSB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZmluZVJlbGF0aW9uPEU+KGVudGl0eTogVHlwZTxFPiwga2V5OiBzdHJpbmcsIG9wdHM6IFJlbGF0aW9uT3B0aW9uczxFPik6IEVudGl0eU1ldGE8RT4ge1xuICBpZiAoIW9wdHMuZW50aXR5KSB7XG4gICAgY29uc3QgaW5mZXJyZWRUeXBlID0gaW5mZXJFbnRpdHlUeXBlKGVudGl0eSwga2V5KTtcbiAgICBvcHRzLmVudGl0eSA9ICgpID0+IGluZmVycmVkVHlwZTtcbiAgfVxuICBjb25zdCBtZXRhID0gZW5zdXJlTWV0YShlbnRpdHkpO1xuICBtZXRhLnJlbGF0aW9uc1trZXldID0geyAuLi5tZXRhLnJlbGF0aW9uc1trZXldLCAuLi5vcHRzIH07XG4gIHJldHVybiBtZXRhO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVmaW5lRW50aXR5PEU+KGVudGl0eTogVHlwZTxFPiwgb3B0czogRW50aXR5T3B0aW9ucyA9IHt9KTogRW50aXR5TWV0YTxFPiB7XG4gIGNvbnN0IG1ldGEgPSBlbnN1cmVNZXRhKGVudGl0eSk7XG5cbiAgaWYgKCFoYXNLZXlzKG1ldGEuZmllbGRzKSkge1xuICAgIHRocm93IFR5cGVFcnJvcihgJyR7ZW50aXR5Lm5hbWV9JyBtdXN0IGhhdmUgZmllbGRzYCk7XG4gIH1cblxuICBjb25zdCBvbkRlbGV0ZUtleXMgPSBnZXRLZXlzKG1ldGEuZmllbGRzKS5maWx0ZXIoKGtleSkgPT4gbWV0YS5maWVsZHNba2V5XS5vbkRlbGV0ZSkgYXMgRmllbGRLZXk8RT5bXTtcblxuICBpZiAob25EZWxldGVLZXlzLmxlbmd0aCA+IDEpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IoYCcke2VudGl0eS5uYW1lfScgbXVzdCBoYXZlIG9uZSBmaWVsZCB3aXRoICdvbkRlbGV0ZScgYXMgbWF4aW11bWApO1xuICB9XG5cbiAgaWYgKG9wdHMuc29mdERlbGV0ZSkge1xuICAgIGlmICghb25EZWxldGVLZXlzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgVHlwZUVycm9yKGAnJHtlbnRpdHkubmFtZX0nIG11c3QgaGF2ZSBvbmUgZmllbGQgd2l0aCAnb25EZWxldGUnIHRvIGVuYWJsZSAnc29mdERlbGV0ZSdgKTtcbiAgICB9XG4gICAgbWV0YS5zb2Z0RGVsZXRlID0gb25EZWxldGVLZXlzWzBdO1xuICB9XG5cbiAgbWV0YS5uYW1lID0gb3B0cy5uYW1lID8/IGVudGl0eS5uYW1lO1xuICBsZXQgcHJvdG86IEZ1bmN0aW9uQ29uc3RydWN0b3IgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoZW50aXR5LnByb3RvdHlwZSk7XG5cbiAgd2hpbGUgKHByb3RvLmNvbnN0cnVjdG9yICE9PSBPYmplY3QpIHtcbiAgICBjb25zdCBwYXJlbnRNZXRhID0gZW5zdXJlTWV0YShwcm90by5jb25zdHJ1Y3RvciBhcyBUeXBlPEU+KTtcbiAgICBleHRlbmRNZXRhKG1ldGEsIHBhcmVudE1ldGEpO1xuICAgIHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvKTtcbiAgfVxuXG4gIGNvbnN0IGlkID0gZ2V0SWRLZXkobWV0YSk7XG4gIGlmICghaWQpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IoYCcke2VudGl0eS5uYW1lfScgbXVzdCBoYXZlIG9uZSBmaWVsZCBkZWNvcmF0ZWQgd2l0aCBASWRgKTtcbiAgfVxuICBtZXRhLmlkID0gaWQ7XG5cbiAgcmV0dXJuIG1ldGE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbnRpdGllcygpOiBUeXBlPGFueT5bXSB7XG4gIHJldHVybiBbLi4ubWV0YXMuZW50cmllcygpXS5yZWR1Y2UoKGFjYywgW2tleSwgdmFsXSkgPT4ge1xuICAgIGlmICh2YWwuaWQpIHtcbiAgICAgIGFjYy5wdXNoKGtleSk7XG4gICAgfVxuICAgIHJldHVybiBhY2M7XG4gIH0sIFtdKTtcbn1cblxuZnVuY3Rpb24gZW5zdXJlTWV0YTxFPihlbnRpdHk6IFR5cGU8RT4pOiBFbnRpdHlNZXRhPEU+IHtcbiAgbGV0IG1ldGEgPSBtZXRhcy5nZXQoZW50aXR5KTtcbiAgaWYgKG1ldGEpIHtcbiAgICByZXR1cm4gbWV0YTtcbiAgfVxuICBtZXRhID0geyBlbnRpdHksIGZpZWxkczoge30sIHJlbGF0aW9uczoge30gfTtcbiAgbWV0YXMuc2V0KGVudGl0eSwgbWV0YSk7XG4gIHJldHVybiBtZXRhO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWV0YTxFPihlbnRpdHk6IFR5cGU8RT4pOiBFbnRpdHlNZXRhPEU+IHtcbiAgY29uc3QgbWV0YSA9IG1ldGFzLmdldChlbnRpdHkpO1xuICBpZiAoIW1ldGEpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IoYCcke2VudGl0eS5uYW1lfScgaXMgbm90IGFuIGVudGl0eWApO1xuICB9XG4gIGlmIChtZXRhLnByb2Nlc3NlZCkge1xuICAgIHJldHVybiBtZXRhO1xuICB9XG4gIG1ldGEucHJvY2Vzc2VkID0gdHJ1ZTtcbiAgcmV0dXJuIGZpbGxSZWxhdGlvbnMobWV0YSk7XG59XG5cbmZ1bmN0aW9uIGZpbGxSZWxhdGlvbnM8RT4obWV0YTogRW50aXR5TWV0YTxFPik6IEVudGl0eU1ldGE8RT4ge1xuICBmb3IgKGNvbnN0IHJlbEtleSBpbiBtZXRhLnJlbGF0aW9ucykge1xuICAgIGNvbnN0IHJlbE9wdHMgPSBtZXRhLnJlbGF0aW9uc1tyZWxLZXkgYXMgUmVsYXRpb25LZXk8RT5dO1xuXG4gICAgaWYgKHJlbE9wdHMucmVmZXJlbmNlcykge1xuICAgICAgLy8gcmVmZXJlbmNlcyB3ZXJlIG1hbnVhbGx5IHNwZWNpZmllZFxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHJlbE9wdHMubWFwcGVkQnkpIHtcbiAgICAgIGZpbGxJbnZlcnNlU2lkZVJlbGF0aW9ucyhyZWxPcHRzKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHJlbEVudGl0eSA9IHJlbE9wdHMuZW50aXR5KCk7XG4gICAgY29uc3QgcmVsTWV0YSA9IGVuc3VyZU1ldGEocmVsRW50aXR5KTtcblxuICAgIGlmIChyZWxPcHRzLmNhcmRpbmFsaXR5ID09PSAnbW0nKSB7XG4gICAgICBjb25zdCBpZE5hbWUgPSBtZXRhLmZpZWxkc1ttZXRhLmlkXS5uYW1lO1xuICAgICAgY29uc3QgcmVsSWROYW1lID0gcmVsTWV0YS5maWVsZHNbcmVsTWV0YS5pZF0ubmFtZTtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGxvd2VyRmlyc3QobWV0YS5uYW1lKSArIHVwcGVyRmlyc3QoaWROYW1lKTtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGxvd2VyRmlyc3QocmVsTWV0YS5uYW1lKSArIHVwcGVyRmlyc3QocmVsSWROYW1lKTtcbiAgICAgIHJlbE9wdHMucmVmZXJlbmNlcyA9IFtcbiAgICAgICAgeyBsb2NhbDogc291cmNlLCBmb3JlaWduOiBtZXRhLmlkIH0sXG4gICAgICAgIHsgbG9jYWw6IHRhcmdldCwgZm9yZWlnbjogcmVsTWV0YS5pZCB9LFxuICAgICAgXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVsT3B0cy5yZWZlcmVuY2VzID0gW3sgbG9jYWw6IGAke3JlbEtleX1JZGAsIGZvcmVpZ246IHJlbE1ldGEuaWQgfV07XG4gICAgfVxuXG4gICAgaWYgKHJlbE9wdHMudGhyb3VnaCkge1xuICAgICAgZmlsbFRocm91Z2hSZWxhdGlvbnMocmVsT3B0cy50aHJvdWdoKCkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtZXRhO1xufVxuXG5mdW5jdGlvbiBmaWxsSW52ZXJzZVNpZGVSZWxhdGlvbnM8RT4ocmVsT3B0czogUmVsYXRpb25PcHRpb25zPEU+KTogdm9pZCB7XG4gIGNvbnN0IHJlbEVudGl0eSA9IHJlbE9wdHMuZW50aXR5KCk7XG4gIGNvbnN0IHJlbE1ldGEgPSBnZXRNZXRhKHJlbEVudGl0eSk7XG4gIHJlbE9wdHMubWFwcGVkQnkgPSBnZXRNYXBwZWRCeVJlbGF0aW9uS2V5KHJlbE9wdHMpO1xuXG4gIC8vIHJldmVyc2luZyByZWZlcmVuY2VzIGhlcmUgbWFrZXMgdGhlIFNRTCBnZW5lcmF0aW9uIHNpbXBsZXIgKG5vIG5lZWQgdG8gY2hlY2sgZm9yIGBtYXBwZWRCeWApXG4gIGNvbnN0IHsgY2FyZGluYWxpdHksIHJlZmVyZW5jZXMsIHRocm91Z2ggfSA9IHJlbE1ldGEucmVsYXRpb25zW3JlbE9wdHMubWFwcGVkQnldO1xuICBpZiAoY2FyZGluYWxpdHkgPT09ICcxMScgfHwgY2FyZGluYWxpdHkgPT09ICdtMScpIHtcbiAgICByZWxPcHRzLnJlZmVyZW5jZXMgPSByZWZlcmVuY2VzLm1hcCgoeyBsb2NhbCwgZm9yZWlnbiB9KSA9PiAoe1xuICAgICAgbG9jYWw6IGZvcmVpZ24sXG4gICAgICBmb3JlaWduOiBsb2NhbCxcbiAgICB9KSk7XG4gIH0gZWxzZSB7XG4gICAgcmVsT3B0cy5yZWZlcmVuY2VzID0gcmVmZXJlbmNlcy5zbGljZSgpLnJldmVyc2UoKTtcbiAgICByZWxPcHRzLnRocm91Z2ggPSB0aHJvdWdoO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZpbGxUaHJvdWdoUmVsYXRpb25zPEU+KGVudGl0eTogVHlwZTxFPik6IHZvaWQge1xuICBjb25zdCBtZXRhID0gZW5zdXJlTWV0YShlbnRpdHkpO1xuICBtZXRhLnJlbGF0aW9ucyA9IGdldEtleXMobWV0YS5maWVsZHMpLnJlZHVjZSgocmVsYXRpb25zLCBrZXkpID0+IHtcbiAgICBjb25zdCB7IHJlZmVyZW5jZSB9ID0gbWV0YS5maWVsZHNba2V5XTtcbiAgICBpZiAocmVmZXJlbmNlKSB7XG4gICAgICBjb25zdCByZWxFbnRpdHlHZXR0ZXIgPSAocmVmZXJlbmNlIGFzIFJlZmVyZW5jZU9wdGlvbnMpLmVudGl0eTtcbiAgICAgIGNvbnN0IHJlbEVudGl0eSA9IHJlbEVudGl0eUdldHRlcigpO1xuICAgICAgY29uc3QgcmVsTWV0YSA9IGVuc3VyZU1ldGEocmVsRW50aXR5KTtcbiAgICAgIGNvbnN0IHJlbEtleSA9IGtleS5zbGljZSgwLCAtcmVsTWV0YS5pZC5sZW5ndGgpO1xuICAgICAgY29uc3QgcmVsT3B0czogUmVsYXRpb25PcHRpb25zID0ge1xuICAgICAgICBjYXJkaW5hbGl0eTogJ20xJyxcbiAgICAgICAgZW50aXR5OiByZWxFbnRpdHlHZXR0ZXIsXG4gICAgICAgIHJlZmVyZW5jZXM6IFt7IGxvY2FsOiBrZXksIGZvcmVpZ246IHJlbE1ldGEuaWQgfV0sXG4gICAgICB9O1xuICAgICAgcmVsYXRpb25zW3JlbEtleV0gPSByZWxPcHRzO1xuICAgIH1cbiAgICByZXR1cm4gcmVsYXRpb25zO1xuICB9LCB7fSk7XG59XG5cbmZ1bmN0aW9uIGdldE1hcHBlZEJ5UmVsYXRpb25LZXk8RT4ocmVsT3B0czogUmVsYXRpb25PcHRpb25zPEU+KTogUmVsYXRpb25LZXk8RT4ge1xuICBpZiAodHlwZW9mIHJlbE9wdHMubWFwcGVkQnkgPT09ICdmdW5jdGlvbicpIHtcbiAgICBjb25zdCByZWxFbnRpdHkgPSByZWxPcHRzLmVudGl0eSgpO1xuICAgIGNvbnN0IHJlbE1ldGEgPSBlbnN1cmVNZXRhKHJlbEVudGl0eSk7XG4gICAgY29uc3Qga2V5TWFwID0gZ2V0UmVsYXRpb25LZXlNYXAocmVsTWV0YSk7XG4gICAgcmV0dXJuIHJlbE9wdHMubWFwcGVkQnkoa2V5TWFwKTtcbiAgfVxuICByZXR1cm4gcmVsT3B0cy5tYXBwZWRCeTtcbn1cblxuZnVuY3Rpb24gZ2V0UmVsYXRpb25LZXlNYXA8RT4obWV0YTogRW50aXR5TWV0YTxFPik6IFJlbGF0aW9uS2V5TWFwPEU+IHtcbiAgcmV0dXJuIGdldEtleXMobWV0YS5yZWxhdGlvbnMpLnJlZHVjZSgoYWNjLCBrZXkpID0+IHtcbiAgICBhY2Nba2V5XSA9IGtleTtcbiAgICByZXR1cm4gYWNjO1xuICB9LCB7fSBhcyBSZWxhdGlvbktleU1hcDxFPik7XG59XG5cbmZ1bmN0aW9uIGdldElkS2V5PEU+KG1ldGE6IEVudGl0eU1ldGE8RT4pOiBJZEtleTxFPiB7XG4gIGNvbnN0IGlkID0gZ2V0S2V5cyhtZXRhLmZpZWxkcykuZmluZCgoa2V5KSA9PiBtZXRhLmZpZWxkc1trZXldPy5pc0lkKTtcbiAgcmV0dXJuIGlkIGFzIElkS2V5PEU+O1xufVxuXG5mdW5jdGlvbiBleHRlbmRNZXRhPEU+KHRhcmdldDogRW50aXR5TWV0YTxFPiwgc291cmNlOiBFbnRpdHlNZXRhPEU+KTogdm9pZCB7XG4gIGNvbnN0IHNvdXJjZUZpZWxkcyA9IHsgLi4uc291cmNlLmZpZWxkcyB9O1xuICBjb25zdCB0YXJnZXRJZCA9IGdldElkS2V5KHRhcmdldCk7XG4gIGlmICh0YXJnZXRJZCkge1xuICAgIGNvbnN0IHNvdXJjZUlkID0gZ2V0SWRLZXkoc291cmNlKTtcbiAgICBpZiAoc291cmNlSWQpIHtcbiAgICAgIGRlbGV0ZSBzb3VyY2VGaWVsZHNbc291cmNlSWRdO1xuICAgIH1cbiAgfVxuICB0YXJnZXQuZmllbGRzID0geyAuLi5zb3VyY2VGaWVsZHMsIC4uLnRhcmdldC5maWVsZHMgfTtcbiAgdGFyZ2V0LnJlbGF0aW9ucyA9IHsgLi4uc291cmNlLnJlbGF0aW9ucywgLi4udGFyZ2V0LnJlbGF0aW9ucyB9O1xufVxuXG5mdW5jdGlvbiBpbmZlclR5cGU8RT4oZW50aXR5OiBUeXBlPEU+LCBrZXk6IHN0cmluZyk6IGFueSB7XG4gIHJldHVybiBSZWZsZWN0LmdldE1ldGFkYXRhKCdkZXNpZ246dHlwZScsIGVudGl0eS5wcm90b3R5cGUsIGtleSk7XG59XG5cbmZ1bmN0aW9uIGluZmVyRW50aXR5VHlwZTxFPihlbnRpdHk6IFR5cGU8RT4sIGtleTogc3RyaW5nKTogVHlwZTxhbnk+IHtcbiAgY29uc3QgaW5mZXJyZWRUeXBlID0gaW5mZXJUeXBlKGVudGl0eSwga2V5KTtcbiAgY29uc3QgaXNWYWxpZFR5cGUgPSBpc1ZhbGlkRW50aXR5VHlwZShpbmZlcnJlZFR5cGUpO1xuICBpZiAoIWlzVmFsaWRUeXBlKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKGAnJHtlbnRpdHkubmFtZX0uJHtrZXl9JyB0eXBlIHdhcyBhdXRvLWluZmVycmVkIHdpdGggaW52YWxpZCB0eXBlICcke2luZmVycmVkVHlwZT8ubmFtZX0nYCk7XG4gIH1cbiAgcmV0dXJuIGluZmVycmVkVHlwZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRFbnRpdHlUeXBlKHR5cGU6IGFueSk6IHR5cGUgaXMgVHlwZTxhbnk+IHtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgIHR5cGUgIT09IEJvb2xlYW4gJiZcbiAgICB0eXBlICE9PSBTdHJpbmcgJiZcbiAgICB0eXBlICE9PSBOdW1iZXIgJiZcbiAgICB0eXBlICE9PSBCaWdJbnQgJiZcbiAgICB0eXBlICE9PSBEYXRlICYmXG4gICAgdHlwZSAhPT0gU3ltYm9sICYmXG4gICAgdHlwZSAhPT0gT2JqZWN0XG4gICk7XG59XG4iXX0=
223
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmaW5pdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9lbnRpdHkvZGVjb3JhdG9yL2RlZmluaXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNEJBQTBCO0FBQzFCLHlDQUEwRTtBQUcxRSxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUM7QUFDMUIsTUFBTSxPQUFPLEdBQUcsNEJBQTRCLENBQUM7QUFDN0MsTUFBTSxLQUFLLEdBQW9DLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLEdBQUcsRUFBRSxDQUFDO0FBQzVFLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUM7QUFFeEIsU0FBZ0IsV0FBVyxDQUFJLE1BQWUsRUFBRSxHQUFXLEVBQUUsT0FBcUIsRUFBRTtJQUNsRixNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDaEMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7UUFDZCxNQUFNLElBQUksR0FBRyxTQUFTLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3BDLElBQUksR0FBRyxFQUFFLEdBQUcsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDO0tBQzFCO0lBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksRUFBRSxFQUFFLENBQUM7SUFDdEUsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBUkQsa0NBUUM7QUFFRCxTQUFnQixRQUFRLENBQUksTUFBZSxFQUFFLEdBQVcsRUFBRSxJQUFrQjtJQUMxRSxNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDaEMsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFD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dGVudCI6WyJpbXBvcnQgJ3JlZmxlY3QtbWV0YWRhdGEnO1xuaW1wb3J0IHsgaGFzS2V5cywgbG93ZXJGaXJzdCwgZ2V0S2V5cywgdXBwZXJGaXJzdCB9IGZyb20gJ0B1cWwvY29yZS91dGlsJztcbmltcG9ydCB7IFJlbGF0aW9uT3B0aW9ucywgRmllbGRPcHRpb25zLCBFbnRpdHlPcHRpb25zLCBFbnRpdHlNZXRhLCBUeXBlLCBSZWxhdGlvbktleU1hcCwgUmVsYXRpb25LZXksIEtleSwgRmllbGRLZXksIElkS2V5IH0gZnJvbSAnQHVxbC9jb3JlL3R5cGUnO1xuXG5jb25zdCBob2xkZXIgPSBnbG9iYWxUaGlzO1xuY29uc3QgbWV0YUtleSA9ICdAdXFsL2NvcmUvZW50aXR5L2RlY29yYXRvcic7XG5jb25zdCBtZXRhczogTWFwPFR5cGU8YW55PiwgRW50aXR5TWV0YTxhbnk+PiA9IGhvbGRlclttZXRhS2V5XSA/PyBuZXcgTWFwKCk7XG5ob2xkZXJbbWV0YUtleV0gPSBtZXRhcztcblxuZXhwb3J0IGZ1bmN0aW9uIGRlZmluZUZpZWxkPEU+KGVudGl0eTogVHlwZTxFPiwga2V5OiBzdHJpbmcsIG9wdHM6IEZpZWxkT3B0aW9ucyA9IHt9KTogRW50aXR5TWV0YTxFPiB7XG4gIGNvbnN0IG1ldGEgPSBlbnN1cmVNZXRhKGVudGl0eSk7XG4gIGlmICghb3B0cy50eXBlKSB7XG4gICAgY29uc3QgdHlwZSA9IGluZmVyVHlwZShlbnRpdHksIGtleSk7XG4gICAgb3B0cyA9IHsgLi4ub3B0cywgdHlwZSB9O1xuICB9XG4gIG1ldGEuZmllbGRzW2tleV0gPSB7IC4uLm1ldGEuZmllbGRzW2tleV0sIC4uLnsgbmFtZToga2V5LCAuLi5vcHRzIH0gfTtcbiAgcmV0dXJuIG1ldGE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBkZWZpbmVJZDxFPihlbnRpdHk6IFR5cGU8RT4sIGtleTogc3RyaW5nLCBvcHRzOiBGaWVsZE9wdGlvbnMpOiBFbnRpdHlNZXRhPEU+IHtcbiAgY29uc3QgbWV0YSA9IGVuc3VyZU1ldGEoZW50aXR5KTtcbiAgY29uc3QgaWQgPSBnZXRJZEtleShtZXRhKTtcbiAgaWYgKGlkKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKGAnJHtlbnRpdHkubmFtZX0nIG11c3QgaGF2ZSBhIHNpbmdsZSBmaWVsZCBkZWNvcmF0ZWQgd2l0aCBASWRgKTtcbiAgfVxuICByZXR1cm4gZGVmaW5lRmllbGQoZW50aXR5LCBrZXksIHsgLi4ub3B0cywgaXNJZDogdHJ1ZSB9KTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZmluZVJlbGF0aW9uPEU+KGVudGl0eTogVHlwZTxFPiwga2V5OiBzdHJpbmcsIG9wdHM6IFJlbGF0aW9uT3B0aW9uczxFPik6IEVudGl0eU1ldGE8RT4ge1xuICBpZiAoIW9wdHMuZW50aXR5KSB7XG4gICAgY29uc3QgaW5mZXJyZWRUeXBlID0gaW5mZXJFbnRpdHlUeXBlKGVudGl0eSwga2V5KTtcbiAgICBvcHRzLmVudGl0eSA9ICgpID0+IGluZmVycmVkVHlwZTtcbiAgfVxuICBjb25zdCBtZXRhID0gZW5zdXJlTWV0YShlbnRpdHkpO1xuICBtZXRhLnJlbGF0aW9uc1trZXldID0geyAuLi5tZXRhLnJlbGF0aW9uc1trZXldLCAuLi5vcHRzIH07XG4gIHJldHVybiBtZXRhO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZGVmaW5lRW50aXR5PEU+KGVudGl0eTogVHlwZTxFPiwgb3B0czogRW50aXR5T3B0aW9ucyA9IHt9KTogRW50aXR5TWV0YTxFPiB7XG4gIGNvbnN0IG1ldGEgPSBlbnN1cmVNZXRhKGVudGl0eSk7XG5cbiAgaWYgKCFoYXNLZXlzKG1ldGEuZmllbGRzKSkge1xuICAgIHRocm93IFR5cGVFcnJvcihgJyR7ZW50aXR5Lm5hbWV9JyBtdXN0IGhhdmUgZmllbGRzYCk7XG4gIH1cblxuICBjb25zdCBvbkRlbGV0ZUtleXMgPSBnZXRLZXlzKG1ldGEuZmllbGRzKS5maWx0ZXIoKGtleSkgPT4gbWV0YS5maWVsZHNba2V5XS5vbkRlbGV0ZSkgYXMgRmllbGRLZXk8RT5bXTtcblxuICBpZiAob25EZWxldGVLZXlzLmxlbmd0aCA+IDEpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IoYCcke2VudGl0eS5uYW1lfScgbXVzdCBoYXZlIG9uZSBmaWVsZCB3aXRoICdvbkRlbGV0ZScgYXMgbWF4aW11bWApO1xuICB9XG5cbiAgaWYgKG9wdHMuc29mdERlbGV0ZSkge1xuICAgIGlmICghb25EZWxldGVLZXlzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgVHlwZUVycm9yKGAnJHtlbnRpdHkubmFtZX0nIG11c3QgaGF2ZSBvbmUgZmllbGQgd2l0aCAnb25EZWxldGUnIHRvIGVuYWJsZSAnc29mdERlbGV0ZSdgKTtcbiAgICB9XG4gICAgbWV0YS5zb2Z0RGVsZXRlID0gb25EZWxldGVLZXlzWzBdO1xuICB9XG5cbiAgbWV0YS5uYW1lID0gb3B0cy5uYW1lID8/IGVudGl0eS5uYW1lO1xuICBsZXQgcHJvdG86IEZ1bmN0aW9uQ29uc3RydWN0b3IgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YoZW50aXR5LnByb3RvdHlwZSk7XG5cbiAgd2hpbGUgKHByb3RvLmNvbnN0cnVjdG9yICE9PSBPYmplY3QpIHtcbiAgICBjb25zdCBwYXJlbnRNZXRhID0gZW5zdXJlTWV0YShwcm90by5jb25zdHJ1Y3RvciBhcyBUeXBlPEU+KTtcbiAgICBleHRlbmRNZXRhKG1ldGEsIHBhcmVudE1ldGEpO1xuICAgIHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvKTtcbiAgfVxuXG4gIGNvbnN0IGlkID0gZ2V0SWRLZXkobWV0YSk7XG4gIGlmICghaWQpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IoYCcke2VudGl0eS5uYW1lfScgbXVzdCBoYXZlIG9uZSBmaWVsZCBkZWNvcmF0ZWQgd2l0aCBASWRgKTtcbiAgfVxuICBtZXRhLmlkID0gaWQ7XG5cbiAgcmV0dXJuIG1ldGE7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRFbnRpdGllcygpOiBUeXBlPGFueT5bXSB7XG4gIHJldHVybiBbLi4ubWV0YXMuZW50cmllcygpXS5yZWR1Y2UoKGFjYywgW2tleSwgdmFsXSkgPT4ge1xuICAgIGlmICh2YWwuaWQpIHtcbiAgICAgIGFjYy5wdXNoKGtleSk7XG4gICAgfVxuICAgIHJldHVybiBhY2M7XG4gIH0sIFtdKTtcbn1cblxuZnVuY3Rpb24gZW5zdXJlTWV0YTxFPihlbnRpdHk6IFR5cGU8RT4pOiBFbnRpdHlNZXRhPEU+IHtcbiAgbGV0IG1ldGEgPSBtZXRhcy5nZXQoZW50aXR5KTtcbiAgaWYgKG1ldGEpIHtcbiAgICByZXR1cm4gbWV0YTtcbiAgfVxuICBtZXRhID0geyBlbnRpdHksIGZpZWxkczoge30sIHJlbGF0aW9uczoge30gfTtcbiAgbWV0YXMuc2V0KGVudGl0eSwgbWV0YSk7XG4gIHJldHVybiBtZXRhO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWV0YTxFPihlbnRpdHk6IFR5cGU8RT4pOiBFbnRpdHlNZXRhPEU+IHtcbiAgY29uc3QgbWV0YSA9IG1ldGFzLmdldChlbnRpdHkpO1xuICBpZiAoIW1ldGEpIHtcbiAgICB0aHJvdyBUeXBlRXJyb3IoYCcke2VudGl0eS5uYW1lfScgaXMgbm90IGFuIGVudGl0eWApO1xuICB9XG4gIGlmIChtZXRhLnByb2Nlc3NlZCkge1xuICAgIHJldHVybiBtZXRhO1xuICB9XG4gIG1ldGEucHJvY2Vzc2VkID0gdHJ1ZTtcbiAgcmV0dXJuIGZpbGxSZWxhdGlvbnMobWV0YSk7XG59XG5cbmZ1bmN0aW9uIGZpbGxSZWxhdGlvbnM8RT4obWV0YTogRW50aXR5TWV0YTxFPik6IEVudGl0eU1ldGE8RT4ge1xuICBmb3IgKGNvbnN0IHJlbEtleSBpbiBtZXRhLnJlbGF0aW9ucykge1xuICAgIGNvbnN0IHJlbE9wdHMgPSBtZXRhLnJlbGF0aW9uc1tyZWxLZXkgYXMgUmVsYXRpb25LZXk8RT5dO1xuXG4gICAgaWYgKHJlbE9wdHMucmVmZXJlbmNlcykge1xuICAgICAgLy8gcmVmZXJlbmNlcyB3ZXJlIG1hbnVhbGx5IHNwZWNpZmllZFxuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKHJlbE9wdHMubWFwcGVkQnkpIHtcbiAgICAgIGZpbGxJbnZlcnNlU2lkZVJlbGF0aW9ucyhyZWxPcHRzKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHJlbEVudGl0eSA9IHJlbE9wdHMuZW50aXR5KCk7XG4gICAgY29uc3QgcmVsTWV0YSA9IGVuc3VyZU1ldGEocmVsRW50aXR5KTtcblxuICAgIGlmIChyZWxPcHRzLmNhcmRpbmFsaXR5ID09PSAnbW0nKSB7XG4gICAgICBjb25zdCBpZE5hbWUgPSBtZXRhLmZpZWxkc1ttZXRhLmlkXS5uYW1lO1xuICAgICAgY29uc3QgcmVsSWROYW1lID0gcmVsTWV0YS5maWVsZHNbcmVsTWV0YS5pZF0ubmFtZTtcbiAgICAgIGNvbnN0IHNvdXJjZSA9IGxvd2VyRmlyc3QobWV0YS5uYW1lKSArIHVwcGVyRmlyc3QoaWROYW1lKTtcbiAgICAgIGNvbnN0IHRhcmdldCA9IGxvd2VyRmlyc3QocmVsTWV0YS5uYW1lKSArIHVwcGVyRmlyc3QocmVsSWROYW1lKTtcbiAgICAgIHJlbE9wdHMucmVmZXJlbmNlcyA9IFtcbiAgICAgICAgeyBsb2NhbDogc291cmNlLCBmb3JlaWduOiBtZXRhLmlkIH0sXG4gICAgICAgIHsgbG9jYWw6IHRhcmdldCwgZm9yZWlnbjogcmVsTWV0YS5pZCB9LFxuICAgICAgXTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVsT3B0cy5yZWZlcmVuY2VzID0gW3sgbG9jYWw6IGAke3JlbEtleX1JZGAsIGZvcmVpZ246IHJlbE1ldGEuaWQgfV07XG4gICAgfVxuXG4gICAgaWYgKHJlbE9wdHMudGhyb3VnaCkge1xuICAgICAgZmlsbFRocm91Z2hSZWxhdGlvbnMocmVsT3B0cy50aHJvdWdoKCkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtZXRhO1xufVxuXG5mdW5jdGlvbiBmaWxsSW52ZXJzZVNpZGVSZWxhdGlvbnM8RT4ocmVsT3B0czogUmVsYXRpb25PcHRpb25zPEU+KTogdm9pZCB7XG4gIGNvbnN0IHJlbEVudGl0eSA9IHJlbE9wdHMuZW50aXR5KCk7XG4gIGNvbnN0IHJlbE1ldGEgPSBnZXRNZXRhKHJlbEVudGl0eSk7XG4gIHJlbE9wdHMubWFwcGVkQnkgPSBnZXRNYXBwZWRCeVJlbGF0aW9uS2V5KHJlbE9wdHMpO1xuXG4gIGlmIChyZWxNZXRhLmZpZWxkc1tyZWxPcHRzLm1hcHBlZEJ5IGFzIEZpZWxkS2V5PEU+XSkge1xuICAgIHJlbE9wdHMucmVmZXJlbmNlcyA9IFt7IGxvY2FsOiByZWxNZXRhLmlkLCBmb3JlaWduOiByZWxPcHRzLm1hcHBlZEJ5IH1dO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IG1hcHBlZEJ5UmVsYXRpb24gPSByZWxNZXRhLnJlbGF0aW9uc1tyZWxPcHRzLm1hcHBlZEJ5IGFzIFJlbGF0aW9uS2V5PEU+XTtcblxuICBpZiAocmVsT3B0cy5jYXJkaW5hbGl0eSA9PT0gJ20xJyB8fCByZWxPcHRzLmNhcmRpbmFsaXR5ID09PSAnbW0nKSB7XG4gICAgcmVsT3B0cy5yZWZlcmVuY2VzID0gbWFwcGVkQnlSZWxhdGlvbi5yZWZlcmVuY2VzLnNsaWNlKCkucmV2ZXJzZSgpO1xuICAgIHJlbE9wdHMudGhyb3VnaCA9IG1hcHBlZEJ5UmVsYXRpb24udGhyb3VnaDtcbiAgICByZXR1cm47XG4gIH1cblxuICByZWxPcHRzLnJlZmVyZW5jZXMgPSBtYXBwZWRCeVJlbGF0aW9uLnJlZmVyZW5jZXMubWFwKCh7IGxvY2FsLCBmb3JlaWduIH0pID0+ICh7XG4gICAgbG9jYWw6IGZvcmVpZ24sXG4gICAgZm9yZWlnbjogbG9jYWwsXG4gIH0pKTtcbn1cblxuZnVuY3Rpb24gZmlsbFRocm91Z2hSZWxhdGlvbnM8RT4oZW50aXR5OiBUeXBlPEU+KTogdm9pZCB7XG4gIGNvbnN0IG1ldGEgPSBlbnN1cmVNZXRhKGVudGl0eSk7XG4gIG1ldGEucmVsYXRpb25zID0gZ2V0S2V5cyhtZXRhLmZpZWxkcykucmVkdWNlKChyZWxhdGlvbnMsIGtleSkgPT4ge1xuICAgIGNvbnN0IHsgcmVmZXJlbmNlIH0gPSBtZXRhLmZpZWxkc1trZXkgYXMgRmllbGRLZXk8RT5dO1xuICAgIGlmIChyZWZlcmVuY2UpIHtcbiAgICAgIGNvbnN0IHJlbEVudGl0eSA9IHJlZmVyZW5jZSgpO1xuICAgICAgY29uc3QgcmVsTWV0YSA9IGVuc3VyZU1ldGEocmVsRW50aXR5KTtcbiAgICAgIGNvbnN0IHJlbEtleSA9IGtleS5zbGljZSgwLCAtcmVsTWV0YS5pZC5sZW5ndGgpO1xuICAgICAgY29uc3QgcmVsT3B0czogUmVsYXRpb25PcHRpb25zID0ge1xuICAgICAgICBlbnRpdHk6IHJlZmVyZW5jZSxcbiAgICAgICAgY2FyZGluYWxpdHk6ICdtMScsXG4gICAgICAgIHJlZmVyZW5jZXM6IFt7IGxvY2FsOiBrZXksIGZvcmVpZ246IHJlbE1ldGEuaWQgfV0sXG4gICAgICB9O1xuICAgICAgcmVsYXRpb25zW3JlbEtleV0gPSByZWxPcHRzO1xuICAgIH1cbiAgICByZXR1cm4gcmVsYXRpb25zO1xuICB9LCB7fSk7XG59XG5cbmZ1bmN0aW9uIGdldE1hcHBlZEJ5UmVsYXRpb25LZXk8RT4ocmVsT3B0czogUmVsYXRpb25PcHRpb25zPEU+KTogS2V5PEU+IHtcbiAgaWYgKHR5cGVvZiByZWxPcHRzLm1hcHBlZEJ5ID09PSAnZnVuY3Rpb24nKSB7XG4gICAgY29uc3QgcmVsRW50aXR5ID0gcmVsT3B0cy5lbnRpdHkoKTtcbiAgICBjb25zdCByZWxNZXRhID0gZW5zdXJlTWV0YShyZWxFbnRpdHkpO1xuICAgIGNvbnN0IGtleU1hcCA9IGdldFJlbGF0aW9uS2V5TWFwKHJlbE1ldGEpO1xuICAgIHJldHVybiByZWxPcHRzLm1hcHBlZEJ5KGtleU1hcCk7XG4gIH1cbiAgcmV0dXJuIHJlbE9wdHMubWFwcGVkQnk7XG59XG5cbmZ1bmN0aW9uIGdldFJlbGF0aW9uS2V5TWFwPEU+KG1ldGE6IEVudGl0eU1ldGE8RT4pOiBSZWxhdGlvbktleU1hcDxFPiB7XG4gIHJldHVybiBnZXRLZXlzKG1ldGEuZmllbGRzKVxuICAgIC5jb25jYXQoZ2V0S2V5cyhtZXRhLnJlbGF0aW9ucykpXG4gICAgLnJlZHVjZSgoYWNjLCBrZXkpID0+IHtcbiAgICAgIGFjY1trZXldID0ga2V5O1xuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSBhcyBSZWxhdGlvbktleU1hcDxFPik7XG59XG5cbmZ1bmN0aW9uIGdldElkS2V5PEU+KG1ldGE6IEVudGl0eU1ldGE8RT4pOiBJZEtleTxFPiB7XG4gIGNvbnN0IGlkID0gZ2V0S2V5cyhtZXRhLmZpZWxkcykuZmluZCgoa2V5KSA9PiBtZXRhLmZpZWxkc1trZXldPy5pc0lkKTtcbiAgcmV0dXJuIGlkIGFzIElkS2V5PEU+O1xufVxuXG5mdW5jdGlvbiBleHRlbmRNZXRhPEU+KHRhcmdldDogRW50aXR5TWV0YTxFPiwgc291cmNlOiBFbnRpdHlNZXRhPEU+KTogdm9pZCB7XG4gIGNvbnN0IHNvdXJjZUZpZWxkcyA9IHsgLi4uc291cmNlLmZpZWxkcyB9O1xuICBjb25zdCB0YXJnZXRJZCA9IGdldElkS2V5KHRhcmdldCk7XG4gIGlmICh0YXJnZXRJZCkge1xuICAgIGNvbnN0IHNvdXJjZUlkID0gZ2V0SWRLZXkoc291cmNlKTtcbiAgICBpZiAoc291cmNlSWQpIHtcbiAgICAgIGRlbGV0ZSBzb3VyY2VGaWVsZHNbc291cmNlSWRdO1xuICAgIH1cbiAgfVxuICB0YXJnZXQuZmllbGRzID0geyAuLi5zb3VyY2VGaWVsZHMsIC4uLnRhcmdldC5maWVsZHMgfTtcbiAgdGFyZ2V0LnJlbGF0aW9ucyA9IHsgLi4uc291cmNlLnJlbGF0aW9ucywgLi4udGFyZ2V0LnJlbGF0aW9ucyB9O1xufVxuXG5mdW5jdGlvbiBpbmZlclR5cGU8RT4oZW50aXR5OiBUeXBlPEU+LCBrZXk6IHN0cmluZyk6IGFueSB7XG4gIHJldHVybiBSZWZsZWN0LmdldE1ldGFkYXRhKCdkZXNpZ246dHlwZScsIGVudGl0eS5wcm90b3R5cGUsIGtleSk7XG59XG5cbmZ1bmN0aW9uIGluZmVyRW50aXR5VHlwZTxFPihlbnRpdHk6IFR5cGU8RT4sIGtleTogc3RyaW5nKTogVHlwZTxhbnk+IHtcbiAgY29uc3QgaW5mZXJyZWRUeXBlID0gaW5mZXJUeXBlKGVudGl0eSwga2V5KTtcbiAgY29uc3QgaXNWYWxpZFR5cGUgPSBpc1ZhbGlkRW50aXR5VHlwZShpbmZlcnJlZFR5cGUpO1xuICBpZiAoIWlzVmFsaWRUeXBlKSB7XG4gICAgdGhyb3cgVHlwZUVycm9yKGAnJHtlbnRpdHkubmFtZX0uJHtrZXl9JyB0eXBlIHdhcyBhdXRvLWluZmVycmVkIHdpdGggaW52YWxpZCB0eXBlICcke2luZmVycmVkVHlwZT8ubmFtZX0nYCk7XG4gIH1cbiAgcmV0dXJuIGluZmVycmVkVHlwZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzVmFsaWRFbnRpdHlUeXBlKHR5cGU6IGFueSk6IHR5cGUgaXMgVHlwZTxhbnk+IHtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgdHlwZSA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgIHR5cGUgIT09IEJvb2xlYW4gJiZcbiAgICB0eXBlICE9PSBTdHJpbmcgJiZcbiAgICB0eXBlICE9PSBOdW1iZXIgJiZcbiAgICB0eXBlICE9PSBCaWdJbnQgJiZcbiAgICB0eXBlICE9PSBEYXRlICYmXG4gICAgdHlwZSAhPT0gU3ltYm9sICYmXG4gICAgdHlwZSAhPT0gT2JqZWN0XG4gICk7XG59XG4iXX0=