@decaf-ts/for-nest 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/dist/for-nest.cjs +2 -1213
  2. package/dist/for-nest.cjs.map +1 -0
  3. package/dist/for-nest.js +2 -0
  4. package/dist/for-nest.js.map +1 -0
  5. package/lib/RepoFactory.cjs +1 -1
  6. package/lib/RepoFactory.js.map +1 -0
  7. package/lib/cli-module.cjs +1 -1
  8. package/lib/cli-module.d.ts +1 -29
  9. package/lib/cli-module.js.map +1 -0
  10. package/lib/constants.cjs +1 -1
  11. package/lib/constants.js.map +1 -0
  12. package/lib/core-module.cjs +1 -1
  13. package/lib/core-module.js.map +1 -0
  14. package/lib/decoration.cjs +1 -1
  15. package/lib/decoration.js.map +1 -0
  16. package/lib/decorators/ApiProperty.cjs +1 -1
  17. package/lib/decorators/ApiProperty.js.map +1 -0
  18. package/lib/decorators/helpers.cjs +1 -1
  19. package/lib/decorators/helpers.js.map +1 -0
  20. package/lib/decorators/index.cjs +1 -1
  21. package/lib/decorators/index.js.map +1 -0
  22. package/lib/decorators.cjs +32 -0
  23. package/lib/decorators.d.ts +8 -0
  24. package/lib/decorators.js.map +1 -0
  25. package/lib/esm/RepoFactory.js +1 -1
  26. package/lib/esm/RepoFactory.js.map +1 -0
  27. package/lib/esm/cli-module.d.ts +1 -29
  28. package/lib/esm/cli-module.js +1 -1
  29. package/lib/esm/cli-module.js.map +1 -0
  30. package/lib/esm/constants.js +1 -1
  31. package/lib/esm/constants.js.map +1 -0
  32. package/lib/esm/core-module.js +1 -1
  33. package/lib/esm/core-module.js.map +1 -0
  34. package/lib/esm/decoration.js +1 -1
  35. package/lib/esm/decoration.js.map +1 -0
  36. package/lib/esm/decorators/ApiProperty.js +1 -1
  37. package/lib/esm/decorators/ApiProperty.js.map +1 -0
  38. package/lib/esm/decorators/helpers.js +1 -1
  39. package/lib/esm/decorators/helpers.js.map +1 -0
  40. package/lib/esm/decorators/index.js +1 -1
  41. package/lib/esm/decorators/index.js.map +1 -0
  42. package/lib/esm/decorators.d.ts +8 -0
  43. package/lib/esm/decorators.js +29 -0
  44. package/lib/esm/decorators.js.map +1 -0
  45. package/lib/esm/factory/NestBootstraper.d.ts +7 -8
  46. package/lib/esm/factory/NestBootstraper.js +9 -9
  47. package/lib/esm/factory/NestBootstraper.js.map +1 -0
  48. package/lib/esm/factory/errors/cors.js +1 -1
  49. package/lib/esm/factory/errors/cors.js.map +1 -0
  50. package/lib/esm/factory/errors/index.js +1 -1
  51. package/lib/esm/factory/errors/index.js.map +1 -0
  52. package/lib/esm/factory/exceptions/AuthorizationExceptionFilter.js +2 -2
  53. package/lib/esm/factory/exceptions/AuthorizationExceptionFilter.js.map +1 -0
  54. package/lib/esm/factory/exceptions/ConflictExceptionFilter.js +3 -3
  55. package/lib/esm/factory/exceptions/ConflictExceptionFilter.js.map +1 -0
  56. package/lib/esm/factory/exceptions/GlobalExceptionFilter.js +7 -3
  57. package/lib/esm/factory/exceptions/GlobalExceptionFilter.js.map +1 -0
  58. package/lib/esm/factory/exceptions/HttpExceptionFilter.js +3 -3
  59. package/lib/esm/factory/exceptions/HttpExceptionFilter.js.map +1 -0
  60. package/lib/esm/factory/exceptions/HttpResponseError.d.ts +0 -1
  61. package/lib/esm/factory/exceptions/HttpResponseError.js +4 -2
  62. package/lib/esm/factory/exceptions/HttpResponseError.js.map +1 -0
  63. package/lib/esm/factory/exceptions/NotFoundExceptionFilter.js +2 -2
  64. package/lib/esm/factory/exceptions/NotFoundExceptionFilter.js.map +1 -0
  65. package/lib/esm/factory/exceptions/ValidationExceptionFilter.js +3 -3
  66. package/lib/esm/factory/exceptions/ValidationExceptionFilter.js.map +1 -0
  67. package/lib/esm/factory/exceptions/index.d.ts +1 -0
  68. package/lib/esm/factory/exceptions/index.js +2 -1
  69. package/lib/esm/factory/exceptions/index.js.map +1 -0
  70. package/lib/esm/factory/index.js +1 -1
  71. package/lib/esm/factory/index.js.map +1 -0
  72. package/lib/esm/factory/openapi/SwaggerBuilder.js +1 -1
  73. package/lib/esm/factory/openapi/SwaggerBuilder.js.map +1 -0
  74. package/lib/esm/factory/openapi/SwaggerCustomUI.js +1 -1
  75. package/lib/esm/factory/openapi/SwaggerCustomUI.js.map +1 -0
  76. package/lib/esm/factory/openapi/constants.js +1 -1
  77. package/lib/esm/factory/openapi/constants.js.map +1 -0
  78. package/lib/esm/factory/openapi/index.js +1 -1
  79. package/lib/esm/factory/openapi/index.js.map +1 -0
  80. package/lib/esm/index.d.ts +1 -1
  81. package/lib/esm/index.js +3 -3
  82. package/lib/esm/index.js.map +1 -0
  83. package/lib/esm/model-module.js +37 -6
  84. package/lib/esm/model-module.js.map +1 -0
  85. package/lib/esm/module.js +1 -1
  86. package/lib/esm/module.js.map +1 -0
  87. package/lib/esm/types.js +1 -1
  88. package/lib/esm/types.js.map +1 -0
  89. package/lib/esm/utils.js +1 -1
  90. package/lib/esm/utils.js.map +1 -0
  91. package/lib/factory/NestBootstraper.cjs +9 -9
  92. package/lib/factory/NestBootstraper.d.ts +7 -8
  93. package/lib/factory/NestBootstraper.js.map +1 -0
  94. package/lib/factory/errors/cors.cjs +1 -1
  95. package/lib/factory/errors/cors.js.map +1 -0
  96. package/lib/factory/errors/index.cjs +1 -1
  97. package/lib/factory/errors/index.js.map +1 -0
  98. package/lib/factory/exceptions/AuthorizationExceptionFilter.cjs +1 -1
  99. package/lib/factory/exceptions/AuthorizationExceptionFilter.js.map +1 -0
  100. package/lib/factory/exceptions/ConflictExceptionFilter.cjs +2 -2
  101. package/lib/factory/exceptions/ConflictExceptionFilter.js.map +1 -0
  102. package/lib/factory/exceptions/GlobalExceptionFilter.cjs +6 -2
  103. package/lib/factory/exceptions/GlobalExceptionFilter.js.map +1 -0
  104. package/lib/factory/exceptions/HttpExceptionFilter.cjs +2 -2
  105. package/lib/factory/exceptions/HttpExceptionFilter.js.map +1 -0
  106. package/lib/factory/exceptions/HttpResponseError.cjs +4 -2
  107. package/lib/factory/exceptions/HttpResponseError.d.ts +0 -1
  108. package/lib/factory/exceptions/HttpResponseError.js.map +1 -0
  109. package/lib/factory/exceptions/NotFoundExceptionFilter.cjs +1 -1
  110. package/lib/factory/exceptions/NotFoundExceptionFilter.js.map +1 -0
  111. package/lib/factory/exceptions/ValidationExceptionFilter.cjs +2 -2
  112. package/lib/factory/exceptions/ValidationExceptionFilter.js.map +1 -0
  113. package/lib/factory/exceptions/index.cjs +2 -1
  114. package/lib/factory/exceptions/index.d.ts +1 -0
  115. package/lib/factory/exceptions/index.js.map +1 -0
  116. package/lib/factory/index.cjs +1 -1
  117. package/lib/factory/index.js.map +1 -0
  118. package/lib/factory/openapi/SwaggerBuilder.cjs +1 -1
  119. package/lib/factory/openapi/SwaggerBuilder.js.map +1 -0
  120. package/lib/factory/openapi/SwaggerCustomUI.cjs +1 -1
  121. package/lib/factory/openapi/SwaggerCustomUI.js.map +1 -0
  122. package/lib/factory/openapi/constants.cjs +1 -1
  123. package/lib/factory/openapi/constants.js.map +1 -0
  124. package/lib/factory/openapi/index.cjs +1 -1
  125. package/lib/factory/openapi/index.js.map +1 -0
  126. package/lib/index.cjs +3 -3
  127. package/lib/index.d.ts +1 -1
  128. package/lib/index.js.map +1 -0
  129. package/lib/model-module.cjs +36 -5
  130. package/lib/model-module.js.map +1 -0
  131. package/lib/module.cjs +1 -1
  132. package/lib/module.js.map +1 -0
  133. package/lib/types.cjs +1 -1
  134. package/lib/types.js.map +1 -0
  135. package/lib/utils.cjs +1 -1
  136. package/lib/utils.js.map +1 -0
  137. package/package.json +8 -49
  138. package/dist/for-nest.esm.cjs +0 -1185
@@ -1,1185 +0,0 @@
1
- import { Decoration, DecorationKeys, Metadata } from '@decaf-ts/decoration';
2
- import { InjectablesKeys } from '@decaf-ts/injectable-decorators';
3
- import { Injectable, Scope, Inject, Global, Module, Post, Body, Get, Param, Put, Delete, Controller, HttpStatus, Catch, HttpException, Logger } from '@nestjs/common';
4
- import { ValidationKeys, Model } from '@decaf-ts/decorator-validation';
5
- import { getTypeIsArrayTuple as getTypeIsArrayTuple$1 } from '@nestjs/swagger/dist/decorators/helpers';
6
- import { getEnumValues, getEnumType } from '@nestjs/swagger/dist/utils/enum.utils';
7
- import { DECORATORS } from '@nestjs/swagger/dist/constants';
8
- import { METHOD_METADATA } from '@nestjs/common/constants';
9
- import { isConstructor } from '@nestjs/common/utils/shared.utils';
10
- import { pickBy, negate, isUndefined, isArray } from 'lodash';
11
- import { METADATA_FACTORY_NAME } from '@nestjs/swagger/dist/plugin/plugin-constants';
12
- import { PersistenceKeys, Repository, Adapter, ForbiddenError } from '@decaf-ts/core';
13
- import { __decorate, __param, __metadata } from 'tslib';
14
- import { ModuleRef } from '@nestjs/core';
15
- import { Logging, toKebabCase, LoggedClass } from '@decaf-ts/logging';
16
- import { ApiOperation, ApiBody, ApiCreatedResponse, ApiBadRequestResponse, ApiUnprocessableEntityResponse, getSchemaPath, ApiParam, ApiOkResponse, ApiNotFoundResponse, ApiTags, ApiExtraModels, DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
17
- import { InternalError } from '@decaf-ts/db-decorators';
18
- import { readFileSync } from 'fs';
19
- import * as path from 'path';
20
-
21
- /* eslint-disable @typescript-eslint/no-unsafe-function-type */
22
- function createMethodDecorator(metakey, metadata, { overrideExisting } = { overrideExisting: true }) {
23
- return (target, key, descriptor) => {
24
- if (typeof metadata === "object") {
25
- const prevValue = Reflect.getMetadata(metakey, descriptor.value);
26
- if (prevValue && !overrideExisting) {
27
- return descriptor;
28
- }
29
- Reflect.defineMetadata(metakey, { ...prevValue, ...metadata }, descriptor.value);
30
- return descriptor;
31
- }
32
- Reflect.defineMetadata(metakey, metadata, descriptor.value);
33
- return descriptor;
34
- };
35
- }
36
- function createClassDecorator(metakey, metadata = []) {
37
- return (target) => {
38
- const prevValue = Reflect.getMetadata(metakey, target) || [];
39
- Reflect.defineMetadata(metakey, [...prevValue, ...metadata], target);
40
- return target;
41
- };
42
- }
43
- function createPropertyDecorator(metakey, metadata, overrideExisting = true) {
44
- return (target, propertyKey) => {
45
- const properties = Reflect.getMetadata(DECORATORS.API_MODEL_PROPERTIES_ARRAY, target) || [];
46
- const key = `:${propertyKey}`;
47
- if (!properties.includes(key)) {
48
- Reflect.defineMetadata(DECORATORS.API_MODEL_PROPERTIES_ARRAY, [...properties, `:${propertyKey}`], target);
49
- }
50
- const existingMetadata = Reflect.getMetadata(metakey, target, propertyKey);
51
- if (existingMetadata) {
52
- const newMetadata = pickBy(metadata, negate(isUndefined));
53
- const metadataToSave = overrideExisting
54
- ? {
55
- ...existingMetadata,
56
- ...newMetadata,
57
- }
58
- : {
59
- ...newMetadata,
60
- ...existingMetadata,
61
- };
62
- Reflect.defineMetadata(metakey, metadataToSave, target, propertyKey);
63
- }
64
- else {
65
- const type =
66
- // @ts-expect-error nest js override
67
- target?.constructor?.[METADATA_FACTORY_NAME]?.()[propertyKey]?.type ??
68
- Reflect.getMetadata("design:type", target, propertyKey);
69
- Reflect.defineMetadata(metakey, {
70
- type,
71
- ...pickBy(metadata, negate(isUndefined)),
72
- }, target, propertyKey);
73
- }
74
- };
75
- }
76
- function createMixedDecorator(metakey, metadata) {
77
- return (target, key, descriptor) => {
78
- if (descriptor) {
79
- let metadatas;
80
- if (Array.isArray(metadata)) {
81
- const previousMetadata = Reflect.getMetadata(metakey, descriptor.value) || [];
82
- metadatas = [...previousMetadata, ...metadata];
83
- }
84
- else {
85
- const previousMetadata = Reflect.getMetadata(metakey, descriptor.value) || {};
86
- metadatas = { ...previousMetadata, ...metadata };
87
- }
88
- Reflect.defineMetadata(metakey, metadatas, descriptor.value);
89
- return descriptor;
90
- }
91
- let metadatas;
92
- if (Array.isArray(metadata)) {
93
- const previousMetadata = Reflect.getMetadata(metakey, target) || [];
94
- metadatas = [...previousMetadata, ...metadata];
95
- }
96
- else {
97
- const previousMetadata = Reflect.getMetadata(metakey, target) || {};
98
- metadatas = Object.assign(Object.assign({}, previousMetadata), metadata);
99
- }
100
- Reflect.defineMetadata(metakey, metadatas, target);
101
- return target;
102
- };
103
- }
104
- function createParamDecorator(metadata, initial) {
105
- return (target, key, descriptor) => {
106
- const paramOptions = {
107
- ...initial,
108
- ...pickBy(metadata, negate(isUndefined)),
109
- };
110
- if (descriptor) {
111
- const parameters = Reflect.getMetadata(DECORATORS.API_PARAMETERS, descriptor.value) || [];
112
- Reflect.defineMetadata(DECORATORS.API_PARAMETERS, [...parameters, paramOptions], descriptor.value);
113
- return descriptor;
114
- }
115
- if (typeof target === "object") {
116
- return target;
117
- }
118
- const propertyKeys = Object.getOwnPropertyNames(target.prototype);
119
- for (const propertyKey of propertyKeys) {
120
- if (isConstructor(propertyKey)) {
121
- continue;
122
- }
123
- const methodDescriptor = Object.getOwnPropertyDescriptor(target.prototype, propertyKey);
124
- if (!methodDescriptor) {
125
- continue;
126
- }
127
- const isApiMethod = Reflect.hasMetadata(METHOD_METADATA, methodDescriptor.value);
128
- if (!isApiMethod) {
129
- continue;
130
- }
131
- const parameters = Reflect.getMetadata(DECORATORS.API_PARAMETERS, methodDescriptor.value) || [];
132
- Reflect.defineMetadata(DECORATORS.API_PARAMETERS, [...parameters, paramOptions], methodDescriptor.value);
133
- }
134
- };
135
- }
136
- function getTypeIsArrayTuple(input, isArrayFlag) {
137
- if (!input) {
138
- return [input, isArrayFlag];
139
- }
140
- if (isArrayFlag) {
141
- return [input, isArrayFlag];
142
- }
143
- const isInputArray = isArray(input);
144
- const type = isInputArray ? input[0] : input;
145
- return [type, isInputArray];
146
- }
147
-
148
- const isEnumArray = (opts) => (opts.isArray && "enum" in opts && opts.enum !== undefined);
149
- /**
150
- * @publicApi
151
- */
152
- function ApiProperty(options = {}) {
153
- return createApiPropertyDecorator(options);
154
- }
155
- function createApiPropertyDecorator(options = {}, overrideExisting = true) {
156
- const [type, isArray] = getTypeIsArrayTuple$1(options.type, options.isArray);
157
- options = {
158
- ...options,
159
- type,
160
- isArray,
161
- };
162
- if (isEnumArray(options)) {
163
- options.type = "array";
164
- const enumValues = getEnumValues(options.enum);
165
- options.items = {
166
- type: getEnumType(enumValues),
167
- enum: enumValues,
168
- };
169
- // @ts-expect-error nest swagger override
170
- delete options.enum;
171
- }
172
- else if ("enum" in options && options.enum !== undefined) {
173
- const enumValues = getEnumValues(options.enum);
174
- options.enum = enumValues;
175
- options.type = getEnumType(enumValues);
176
- }
177
- if (Array.isArray(options.type)) {
178
- options.type = "array";
179
- options.items = {
180
- type: "array",
181
- items: {
182
- type: options.type[0],
183
- },
184
- };
185
- }
186
- return createPropertyDecorator(DECORATORS.API_MODEL_PROPERTIES, options, overrideExisting);
187
- }
188
- function ApiPropertyOptional(options = {}) {
189
- return ApiProperty({
190
- ...options,
191
- required: false,
192
- });
193
- }
194
- function ApiResponseProperty(options = {}) {
195
- return ApiProperty({
196
- readOnly: true,
197
- ...options,
198
- });
199
- }
200
-
201
- Decoration.for(InjectablesKeys.INJECTABLE)
202
- .extend({
203
- decorator: function nestInjectable(category, cfg) {
204
- return Injectable({
205
- scope: cfg.singleton ? Scope.DEFAULT : Scope.REQUEST,
206
- durable: cfg.singleton ? undefined : true,
207
- });
208
- },
209
- })
210
- .apply();
211
- Decoration.for(InjectablesKeys.INJECT)
212
- .extend({
213
- decorator: function nestInject(category,
214
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
215
- cfg) {
216
- return function innerNestInject(target, propertyKey, descriptor) {
217
- return Inject(category || target)(target, propertyKey, descriptor);
218
- };
219
- },
220
- })
221
- .apply();
222
- Decoration.for(ValidationKeys.REQUIRED)
223
- .extend(ApiProperty({
224
- required: true,
225
- }))
226
- .apply();
227
- Decoration.for(ValidationKeys.MAX)
228
- .extend({
229
- decorator: function maxDec(max) {
230
- return ApiProperty({ maximum: max });
231
- },
232
- })
233
- .apply();
234
- Decoration.for(ValidationKeys.MIN)
235
- .extend({
236
- decorator: function minDec(min) {
237
- return ApiProperty({ minimum: min });
238
- },
239
- })
240
- .apply();
241
- Decoration.for(ValidationKeys.MAX_LENGTH)
242
- .extend({
243
- decorator: function maxLengthDec(max) {
244
- return ApiProperty({ maxLength: max });
245
- },
246
- })
247
- .apply();
248
- Decoration.for(ValidationKeys.MIN_LENGTH)
249
- .extend({
250
- decorator: function minLengthDec(min) {
251
- return ApiProperty({ minLength: min });
252
- },
253
- })
254
- .apply();
255
- //
256
- // Decoration.for(ValidationKeys.TYPE)
257
- // .extend({
258
- // decorator: function typeDec(type: (string | (() => string))[] | string | (() => string)) {
259
- // return ApiProperty({ type: type as any });
260
- // },
261
- // })
262
- // .apply();
263
- //
264
- // Decoration.for(ValidationKeys.DATE)
265
- // .extend({
266
- // decorator: function dateDec() {
267
- // return ApiProperty({ type: Date });
268
- // },
269
- // })
270
- // .apply();
271
- Decoration.for(ValidationKeys.LIST)
272
- .extend({
273
- decorator: function listDec(clazz) {
274
- const c = Array.isArray(clazz) ? clazz[0] : clazz;
275
- return ApiProperty({ type: [c] });
276
- },
277
- })
278
- .apply();
279
- //
280
- // Decoration.for(ValidationKeys.OPTION)
281
- // .extend({
282
- // decorator: function optionDec(options: string[] | Record<string, any>) {
283
- // const opts = Array.isArray(options) ? options : Object.values(options);
284
- // return ApiProperty({ enum: opts });
285
- // },
286
- // })
287
- // .apply();
288
- Decoration.for(ValidationKeys.PATTERN)
289
- .extend({
290
- decorator: function patternDec(pat) {
291
- return ApiProperty({
292
- pattern: typeof pat === "string" ? pat : pat.source,
293
- });
294
- },
295
- })
296
- .apply();
297
- Decoration.for(PersistenceKeys.COLUMN)
298
- .extend({
299
- decorator: function columnDec(name) {
300
- return ApiProperty({
301
- name: name,
302
- });
303
- },
304
- })
305
- .apply();
306
- Decoration.for(DecorationKeys.DESCRIPTION)
307
- .extend({
308
- decorator: function descriptionDec(description) {
309
- return ApiProperty({
310
- description: description,
311
- });
312
- },
313
- })
314
- .apply();
315
-
316
- const DECAF_MODULE_OPTIONS = "DecafModuleOptions";
317
- const DECAF_ADAPTER_ID = "DecafAdapter";
318
-
319
- var DecafCoreModule_1;
320
- let DecafCoreModule = class DecafCoreModule {
321
- static { DecafCoreModule_1 = this; }
322
- static { this._adapterInstance = null; }
323
- static get log() {
324
- if (!this._logger)
325
- this._logger = Logging.for(DecafCoreModule_1);
326
- return this._logger;
327
- }
328
- constructor(options, moduleRef) {
329
- this.options = options;
330
- this.moduleRef = moduleRef;
331
- }
332
- static async createAdapter(options) {
333
- if (!this._adapterInstance) {
334
- const log = this.log.for(this.createAdapter);
335
- log.info("Creating adapter instance...");
336
- this._adapterInstance = new options.adapter(options.conf, options.alias);
337
- log.info("Adapter instance created successfully!");
338
- }
339
- return this._adapterInstance;
340
- }
341
- static getAdapterInstance() {
342
- return this._adapterInstance;
343
- }
344
- static forRoot(options) {
345
- const typeOrmModuleOptions = {
346
- provide: DECAF_MODULE_OPTIONS,
347
- useValue: options,
348
- };
349
- const adapter = {
350
- useFactory: async (opts) => {
351
- return DecafCoreModule_1.createAdapter(opts);
352
- },
353
- provide: DECAF_ADAPTER_ID,
354
- durable: true,
355
- scope: Scope.DEFAULT,
356
- inject: [DECAF_MODULE_OPTIONS],
357
- };
358
- const providers = [adapter, typeOrmModuleOptions];
359
- const exports = [adapter];
360
- return {
361
- module: DecafCoreModule_1,
362
- providers,
363
- exports,
364
- };
365
- }
366
- async onApplicationShutdown() {
367
- const log = DecafCoreModule_1.log.for(this.onApplicationShutdown);
368
- const adapter = this.moduleRef.get(DECAF_ADAPTER_ID);
369
- try {
370
- if (adapter) {
371
- log.info("Shutting down");
372
- await adapter.shutdown();
373
- DecafCoreModule_1._adapterInstance = null;
374
- }
375
- }
376
- catch (e) {
377
- log.error(`Failed to shutdown application`, e);
378
- }
379
- }
380
- };
381
- DecafCoreModule = DecafCoreModule_1 = __decorate([
382
- Global(),
383
- Module({}),
384
- __param(0, Inject(DECAF_MODULE_OPTIONS)),
385
- __metadata("design:paramtypes", [Object, ModuleRef])
386
- ], DecafCoreModule);
387
-
388
- let RepoFactory = class RepoFactory {
389
- for(model) {
390
- model = typeof model === "string" ? Model.get(model) : model;
391
- if (!model) {
392
- throw new InternalError(`Failed to find repository for ${model}`);
393
- }
394
- return Repository.forModel(model);
395
- }
396
- };
397
- RepoFactory = __decorate([
398
- Injectable()
399
- ], RepoFactory);
400
-
401
- var DecafModelModule_1;
402
- let DecafModelModule = class DecafModelModule {
403
- static { DecafModelModule_1 = this; }
404
- static get log() {
405
- if (!this._logger)
406
- this._logger = Logging.for(DecafModelModule_1);
407
- return this._logger;
408
- }
409
- static toModelController(ModelClazz) {
410
- const log = this.log.for(this.toModelController);
411
- const tableName = Repository.table(ModelClazz);
412
- const routePath = toKebabCase(tableName);
413
- const modelClazzName = ModelClazz.name;
414
- log.debug(`Creating controller for model: ${modelClazzName}`);
415
- let DynamicModelController = class DynamicModelController extends LoggedClass {
416
- constructor(repoFactory) {
417
- super();
418
- this.repoFactory = repoFactory;
419
- log.info(`Registering dynamic controller for model: ${modelClazzName} route: /${routePath}`);
420
- try {
421
- this.repo = this.repoFactory.for(ModelClazz.name);
422
- this.pk = this.repo.pk;
423
- }
424
- catch (e) {
425
- this.log.error(`Failed to initialize repository for model "${ModelClazz.name}".`, e);
426
- }
427
- }
428
- async create(data) {
429
- const log = this.log.for(this.create);
430
- log.verbose(`creating new ${modelClazzName}`);
431
- let created;
432
- try {
433
- created = await this.repo.create(data);
434
- }
435
- catch (e) {
436
- log.error(`Failed to create new ${modelClazzName}`, e);
437
- throw e;
438
- }
439
- log.info(`created new ${modelClazzName} with id ${created[this.pk]}`);
440
- return created;
441
- }
442
- async read(id) {
443
- const log = this.log.for(this.read);
444
- let read;
445
- try {
446
- log.debug(`reading ${modelClazzName} with ${this.pk} ${id}`);
447
- read = await this.repo.read(id);
448
- }
449
- catch (e) {
450
- log.error(`Failed to read ${modelClazzName} with id ${id}`, e);
451
- throw e;
452
- }
453
- log.info(`read ${modelClazzName} with id ${read[this.pk]}`);
454
- return read;
455
- }
456
- async update(data) {
457
- const log = this.log.for(this.update);
458
- let updated;
459
- try {
460
- log.info(`updating ${modelClazzName} with ${this.pk} ${data[this.pk]}`);
461
- updated = await this.repo.create(data);
462
- }
463
- catch (e) {
464
- throw e;
465
- }
466
- return updated;
467
- }
468
- async delete(id) {
469
- const log = this.log.for(this.delete);
470
- let read;
471
- try {
472
- log.debug(`deleting ${modelClazzName} with ${this.pk} ${id}`);
473
- read = await this.repo.read(id);
474
- }
475
- catch (e) {
476
- log.error(`Failed to delete ${modelClazzName} with id ${id}`, e);
477
- throw e;
478
- }
479
- log.info(`deleted ${modelClazzName} with id ${read[this.pk]}`);
480
- return read;
481
- }
482
- };
483
- __decorate([
484
- Post(),
485
- ApiOperation({ summary: `Create a new ${modelClazzName}.` }),
486
- ApiBody({
487
- description: `Payload for ${modelClazzName}`,
488
- schema: { $ref: getSchemaPath(ModelClazz) },
489
- }),
490
- ApiCreatedResponse({
491
- description: `${modelClazzName} created successfully.`,
492
- }),
493
- ApiBadRequestResponse({ description: "Payload validation failed." }),
494
- ApiUnprocessableEntityResponse({
495
- description: "Repository rejected the provided payload.",
496
- }),
497
- __param(0, Body()),
498
- __metadata("design:type", Function),
499
- __metadata("design:paramtypes", [Object]),
500
- __metadata("design:returntype", Promise)
501
- ], DynamicModelController.prototype, "create", null);
502
- __decorate([
503
- Get(":id"),
504
- ApiOperation({ summary: `Retrieve a ${modelClazzName} record by id.` }),
505
- ApiParam({ name: "id", description: "Primary key" }),
506
- ApiOkResponse({
507
- description: `${modelClazzName} retrieved successfully.`,
508
- }),
509
- ApiNotFoundResponse({
510
- description: `No ${modelClazzName} record matches the provided identifier.`,
511
- }),
512
- __param(0, Param("id")),
513
- __metadata("design:type", Function),
514
- __metadata("design:paramtypes", [String]),
515
- __metadata("design:returntype", Promise)
516
- ], DynamicModelController.prototype, "read", null);
517
- __decorate([
518
- Put(":id"),
519
- ApiOperation({
520
- summary: `Replace an existing ${modelClazzName} record with a new payload.`,
521
- }),
522
- ApiBody({
523
- description: `Payload for replace a existing record of ${modelClazzName}`,
524
- schema: { $ref: getSchemaPath(ModelClazz) },
525
- }),
526
- ApiOkResponse({
527
- description: `${ModelClazz} record replaced successfully.`,
528
- }),
529
- ApiNotFoundResponse({
530
- description: `No ${modelClazzName} record matches the provided identifier.`,
531
- }),
532
- ApiBadRequestResponse({ description: "Payload validation failed." }),
533
- __param(0, Body()),
534
- __metadata("design:type", Function),
535
- __metadata("design:paramtypes", [Model]),
536
- __metadata("design:returntype", Promise)
537
- ], DynamicModelController.prototype, "update", null);
538
- __decorate([
539
- Delete(":id"),
540
- ApiOperation({ summary: `Delete a ${modelClazzName} record by id.` }),
541
- ApiParam({
542
- name: "id",
543
- description: `Primary key value of the ${modelClazzName} record to delete.`,
544
- }),
545
- ApiOkResponse({
546
- description: `${modelClazzName} record deleted successfully.`,
547
- }),
548
- ApiNotFoundResponse({
549
- description: `No ${modelClazzName} record matches the provided identifier.`,
550
- }),
551
- __param(0, Param("id")),
552
- __metadata("design:type", Function),
553
- __metadata("design:paramtypes", [String]),
554
- __metadata("design:returntype", Promise)
555
- ], DynamicModelController.prototype, "delete", null);
556
- DynamicModelController = __decorate([
557
- Controller(routePath),
558
- ApiTags(modelClazzName),
559
- ApiExtraModels(ModelClazz),
560
- __metadata("design:paramtypes", [RepoFactory])
561
- ], DynamicModelController);
562
- return DynamicModelController;
563
- }
564
- static forRoot(flavour) {
565
- const log = this.log.for(this.forRoot);
566
- log.info(`Generating controllers for flavour...`);
567
- const trackedModels = Adapter.models(flavour);
568
- const controllers = trackedModels.map(this.toModelController.bind(this));
569
- log.info(`Generated ${controllers.length} controllers`);
570
- return {
571
- module: DecafModelModule_1,
572
- controllers,
573
- providers: [RepoFactory],
574
- };
575
- }
576
- };
577
- DecafModelModule = DecafModelModule_1 = __decorate([
578
- Module({})
579
- ], DecafModelModule);
580
-
581
- var DecafModule_1;
582
- /**
583
- * @publicApi
584
- */
585
- let DecafModule = DecafModule_1 = class DecafModule {
586
- static async forRootAsync(options) {
587
- const { autoControllers } = options;
588
- const adapter = await DecafCoreModule.createAdapter(options);
589
- const flavour = adapter.flavour;
590
- const imports = [DecafCoreModule.forRoot(options)];
591
- if (autoControllers) {
592
- imports.push(DecafModelModule.forRoot(flavour));
593
- }
594
- return {
595
- module: DecafModule_1,
596
- imports: imports,
597
- };
598
- }
599
- };
600
- DecafModule = DecafModule_1 = __decorate([
601
- Module({})
602
- ], DecafModule);
603
-
604
- function repoForModel(model) {
605
- const m = Model.get(model);
606
- if (!m)
607
- throw new InternalError(`Failed to find repository for ${model}`);
608
- const repo = Repository.forModel(m);
609
- return repo;
610
- }
611
-
612
- class CorsError extends ForbiddenError {
613
- constructor(msg) {
614
- super(msg, CorsError.name);
615
- }
616
- }
617
-
618
- class HttpResponseError {
619
- constructor(request, responseError) {
620
- const status = responseError?.status ?? HttpStatus.INTERNAL_SERVER_ERROR;
621
- const message = responseError?.message ?? "Internal Server Error";
622
- const error = (responseError?.error ?? HttpStatus[status] ?? "HTTP_EXCEPTION")
623
- .toString()
624
- .toUpperCase();
625
- Object.assign(this, {
626
- status,
627
- message,
628
- error,
629
- timestamp: new Date().toISOString(),
630
- path: request.url,
631
- method: request.method,
632
- });
633
- }
634
- }
635
-
636
- class AuthorizationError extends Error {
637
- constructor(message = "Unauthorized") {
638
- super(message);
639
- this.name = "AuthorizationError";
640
- this.status = 401;
641
- this.code = "UNAUTHORIZED";
642
- Object.setPrototypeOf(this, AuthorizationError.prototype);
643
- }
644
- }
645
- let AuthorizationExceptionFilter = class AuthorizationExceptionFilter {
646
- catch(exception, host) {
647
- const ctx = host.switchToHttp();
648
- const request = ctx.getRequest();
649
- const response = ctx.getResponse();
650
- const httpResponseError = new HttpResponseError(request, {
651
- error: "UNAUTHORIZED",
652
- status: HttpStatus.UNAUTHORIZED,
653
- message: exception.message,
654
- });
655
- response.status(HttpStatus.UNAUTHORIZED).json(httpResponseError);
656
- }
657
- };
658
- AuthorizationExceptionFilter = __decorate([
659
- Catch(AuthorizationError)
660
- ], AuthorizationExceptionFilter);
661
-
662
- class ConflictError extends Error {
663
- constructor(message = "Conflict") {
664
- super(message);
665
- this.name = "ConflictError";
666
- this.status = 409;
667
- this.code = "CONFLICT";
668
- Object.setPrototypeOf(this, ConflictError.prototype);
669
- }
670
- }
671
- let ConflictExceptionFilter = class ConflictExceptionFilter {
672
- catch(exception, host) {
673
- const ctx = host.switchToHttp();
674
- const response = ctx.getResponse();
675
- const request = ctx.getRequest();
676
- const httpResponseError = new HttpResponseError(request, {
677
- status: HttpStatus.CONFLICT,
678
- message: exception.message,
679
- error: "CONFLICT"
680
- });
681
- response.status(httpResponseError.status).json(httpResponseError);
682
- }
683
- };
684
- ConflictExceptionFilter = __decorate([
685
- Catch(ConflictError)
686
- ], ConflictExceptionFilter);
687
-
688
- let GlobalExceptionFilter = class GlobalExceptionFilter {
689
- catch(exception, host) {
690
- const ctx = host.switchToHttp();
691
- const request = ctx.getRequest();
692
- const response = ctx.getResponse();
693
- let status = HttpStatus.INTERNAL_SERVER_ERROR;
694
- let message = "Internal Server Error";
695
- let error;
696
- if (exception instanceof HttpException) {
697
- const res = exception.getResponse();
698
- status = exception.getStatus();
699
- message = (res?.message || exception.message) ?? message;
700
- error = res?.error ?? exception.name;
701
- }
702
- else if (exception instanceof Error) {
703
- message = exception.message;
704
- error = exception.name;
705
- }
706
- const httpResponseError = new HttpResponseError(request, { status, message, error });
707
- response.status(httpResponseError.status).json(httpResponseError);
708
- }
709
- };
710
- GlobalExceptionFilter = __decorate([
711
- Catch()
712
- ], GlobalExceptionFilter);
713
-
714
- let HttpExceptionFilter = class HttpExceptionFilter {
715
- catch(exception, host) {
716
- const ctx = host.switchToHttp();
717
- const response = ctx.getResponse();
718
- const request = ctx.getRequest();
719
- const status = exception.getStatus();
720
- const httpResponseError = new HttpResponseError(request, {
721
- status,
722
- message: exception.message,
723
- error: exception.name
724
- });
725
- response.status(httpResponseError.status).json(httpResponseError);
726
- }
727
- };
728
- HttpExceptionFilter = __decorate([
729
- Catch(HttpException)
730
- ], HttpExceptionFilter);
731
-
732
- class NotFoundError extends Error {
733
- constructor(message = "Resource not found") {
734
- super(message);
735
- this.name = "NotFoundError";
736
- this.status = 404;
737
- this.code = "NOT_FOUND";
738
- Object.setPrototypeOf(this, NotFoundError.prototype);
739
- }
740
- }
741
- let NotFoundExceptionFilter = class NotFoundExceptionFilter {
742
- catch(exception, host) {
743
- const ctx = host.switchToHttp();
744
- const response = ctx.getResponse();
745
- const request = ctx.getRequest();
746
- const httpResponseError = new HttpResponseError(request, {
747
- status: HttpStatus.NOT_FOUND,
748
- message: exception.message,
749
- error: "NOT_FOUND",
750
- });
751
- response.status(httpResponseError.status).json(httpResponseError);
752
- }
753
- };
754
- NotFoundExceptionFilter = __decorate([
755
- Catch(NotFoundError)
756
- ], NotFoundExceptionFilter);
757
-
758
- class ValidationError extends Error {
759
- constructor(message = "Validation failed") {
760
- super(message);
761
- this.name = "ValidationError";
762
- this.status = 422;
763
- this.code = "VALIDATION_ERROR";
764
- Object.setPrototypeOf(this, ValidationError.prototype);
765
- }
766
- }
767
- let ValidationExceptionFilter = class ValidationExceptionFilter {
768
- catch(exception, host) {
769
- const ctx = host.switchToHttp();
770
- const response = ctx.getResponse();
771
- const request = ctx.getRequest();
772
- const httpResponseError = new HttpResponseError(request, {
773
- status: HttpStatus.UNPROCESSABLE_ENTITY,
774
- message: exception.message,
775
- error: "VALIDATION_ERROR"
776
- });
777
- response.status(httpResponseError.status).json(httpResponseError);
778
- }
779
- };
780
- ValidationExceptionFilter = __decorate([
781
- Catch(ValidationError)
782
- ], ValidationExceptionFilter);
783
-
784
- const SWAGGER_UI_CONSTANTS = {
785
- path: "docs",
786
- auth: {
787
- type: "http",
788
- scheme: "bearer",
789
- bearerFormat: "JWT",
790
- name: "Authorization",
791
- description: "Enter JWT token",
792
- in: "header",
793
- },
794
- topbarBgColor: "#000000",
795
- };
796
-
797
- class SwaggerCustomUI {
798
- // private readonly assetsPath: string = path.join(
799
- // __dirname,
800
- // "..",
801
- // "..",
802
- // "workdocs",
803
- // "assets"
804
- // );
805
- constructor(options) {
806
- this.options = {
807
- ...options,
808
- };
809
- }
810
- customCSS() {
811
- let css = "";
812
- if (this.options.topbarIconPath) {
813
- const img = this.b64(this.options.topbarIconPath);
814
- css += `.topbar-wrapper { content: url('data:image/png;base64,${img}'); width: 200px; height: auto; }\n`;
815
- }
816
- return (css +
817
- `
818
- .topbar-wrapper svg { visibility: hidden; }
819
- .swagger-ui .topbar { background-color: ${this.options.topbarBgColor || SWAGGER_UI_CONSTANTS.topbarBgColor}; }
820
- `);
821
- }
822
- getCustomOptions() {
823
- const favicon = {};
824
- if (this.options.faviconPath) {
825
- favicon["customfavIcon"] = this.b64(this.options.faviconPath, true);
826
- }
827
- return {
828
- customSiteTitle: this.options.title,
829
- ...favicon,
830
- customCss: this.customCSS(),
831
- swaggerOptions: {
832
- persistAuthorization: this.options.persistAuthorization,
833
- },
834
- jsonDocumentUrl: this.options.path
835
- ? `${this.options.path}/spec.json`
836
- : undefined,
837
- yamlDocumentUrl: this.options.path
838
- ? `${this.options.path}/spec.yaml`
839
- : undefined,
840
- };
841
- }
842
- b64(file, img = false) {
843
- const filePath = path.join(this.options.assetsPath || "", file);
844
- const b64 = readFileSync(filePath, { encoding: "base64" });
845
- return img ? "data:image/png;base64," + b64 : b64;
846
- }
847
- }
848
-
849
- class SwaggerBuilder {
850
- constructor(app, options) {
851
- this.app = app;
852
- this.options = options;
853
- }
854
- createDocument() {
855
- const description = this.options.path
856
- ? this.options.description +
857
- "" +
858
- `<br><br><a href="${this.options.path}/spec.json">OpenAPI JSON Spec</a> | ` +
859
- `<a href="${this.options.path}/spec.yaml">OpenAPI YAML Spec</a>`
860
- : this.options.description;
861
- const config = new DocumentBuilder()
862
- .setTitle(this.options.title)
863
- .setDescription(description)
864
- .setVersion(this.options.version || "0.0.1")
865
- .addBearerAuth(this.options.auth || SWAGGER_UI_CONSTANTS.auth)
866
- .build();
867
- return SwaggerModule.createDocument(this.app, config, {
868
- extraModels: this.options.extraModels || [],
869
- });
870
- }
871
- setupSwagger() {
872
- const document = this.createDocument();
873
- const swaggerUI = new SwaggerCustomUI({
874
- title: this.options.title,
875
- path: this.options.path || SWAGGER_UI_CONSTANTS.path,
876
- persistAuthorization: this.options.persistAuthorization ?? true,
877
- assetsPath: this.options.assetsPath,
878
- faviconPath: this.options.faviconFilePath,
879
- topbarIconPath: this.options.topbarIconFilePath,
880
- topbarBgColor: this.options.topbarBgColor,
881
- });
882
- SwaggerModule.setup(this.options.path || SWAGGER_UI_CONSTANTS.path, this.app, document, {
883
- ...swaggerUI.getCustomOptions(),
884
- });
885
- }
886
- }
887
-
888
- /**
889
- * @description
890
- * A fluent, static bootstrap class for initializing and configuring a NestJS application.
891
- *
892
- * @summary
893
- * The `NestBootstraper` class provides a chainable API for configuring
894
- * a NestJS application instance. It includes built-in methods for enabling
895
- * CORS, Helmet security, Swagger documentation, global pipes, filters,
896
- * interceptors, and starting the server.
897
- *
898
- * This class promotes consistency and reduces repetitive setup code
899
- * across multiple NestJS projects.
900
- *
901
- * @example
902
- * ```ts
903
- * import { NestFactory } from "@nestjs/core";
904
- * import { AppModule } from "./app.module";
905
- * import { MyLogger } from "./MyLogger";
906
- * import { NestBootstraper } from "@decaf-ts/for-nest";
907
- *
908
- * async function bootstrap() {
909
- * const app = await NestFactory.create(AppModule);
910
- *
911
- * await NestBootstraper
912
- * .initialize(app)
913
- * .enableLogger(new MyLogger())
914
- * .enableCors(["http://localhost:4200"])
915
- * .useHelmet()
916
- * .setupSwagger({
917
- * title: "OpenAPI by TradeMark™",
918
- * description: "TradeMark™ API documentation",
919
- * version: "1.0.0",
920
- * path: "api",
921
- * persistAuthorization: true,
922
- * topbarBgColor: "#2C3E50",
923
- * topbarIconPath: "/assets/logo.svg",
924
- * faviconPath: "/assets/favicon.ico"
925
- * })
926
- * .useGlobalFilters()
927
- * .useGlobalPipes(...)
928
- * .useGlobalInterceptors(...)
929
- * .start(3000);
930
- * }
931
- *
932
- * bootstrap();
933
- * ```
934
- * @class
935
- */
936
- class NestBootstraper {
937
- /**
938
- * @description
939
- * Returns the current logger instance, creating a default one if not set.
940
- *
941
- * @summary
942
- * Ensures that a valid `Logger` instance is always available
943
- * for logging bootstrap-related messages.
944
- *
945
- * @return {Logger} The active logger instance.
946
- */
947
- static get logger() {
948
- if (!this._logger) {
949
- // fallback
950
- this._logger = new Logger("NestBootstrap");
951
- }
952
- return this._logger;
953
- }
954
- /**
955
- * @description
956
- * Initializes the bootstrapper with a given NestJS application.
957
- *
958
- * @summary
959
- * Binds the provided NestJS app instance to the bootstrapper, enabling
960
- * chained configuration methods.
961
- *
962
- * @param {INestApplication} app - The NestJS application instance to initialize.
963
- * @return {typeof NestBootstraper} Returns the class for chaining configuration methods.
964
- */
965
- static initialize(app) {
966
- this.app = app;
967
- return this;
968
- }
969
- /**
970
- * @description
971
- * Enables or replaces the global logger for the NestJS application.
972
- *
973
- * @summary
974
- * If a custom logger is provided, it replaces the default logger. Otherwise,
975
- * a new logger named `"NestBootstrap"` is used. This logger is also registered
976
- * with the NestJS application.
977
- *
978
- * @param {Logger} [customLogger] - Optional custom logger instance.
979
- * @return {typeof NestBootstraper} Returns the class for chaining.
980
- */
981
- static enableLogger(customLogger) {
982
- this._logger = customLogger || new Logger("NestBootstrap");
983
- this.app.useLogger(this._logger);
984
- return this;
985
- }
986
- /**
987
- * @description
988
- * Enables Cross-Origin Resource Sharing (CORS) for the application.
989
- *
990
- * @summary
991
- * Allows defining either a wildcard origin (`"*"`) or a list of allowed origins.
992
- * Automatically accepts local development requests and those without origin headers.
993
- * Throws a `CorsError` for unauthorized origins.
994
- *
995
- * @param {'*' | string[]} [origins=[]] - List of allowed origins or `"*"` to allow all.
996
- * @param {string[]} [allowMethods=['GET', 'POST', 'PUT', 'DELETE']] - Allowed HTTP methods.
997
- * @return {typeof NestBootstraper} Returns the class for chaining configuration.
998
- *
999
- */
1000
- static enableCors(origins = [], allowMethods = ["GET", "POST", "PUT", "DELETE"]) {
1001
- const allowedOrigins = origins === "*" ? "*" : origins.map((o) => o.trim().toLowerCase());
1002
- const corsOptions = {
1003
- origin: (origin, callback) => {
1004
- // Allow request without origin...
1005
- if (!origin)
1006
- return callback(null, true);
1007
- if (allowedOrigins === "*" ||
1008
- (Array.isArray(allowedOrigins) &&
1009
- allowedOrigins.includes(origin.toLowerCase()))) {
1010
- return callback(null, true);
1011
- }
1012
- callback(new CorsError(`Origin ${origin} not allowed`));
1013
- },
1014
- credentials: true,
1015
- methods: allowMethods.join(","),
1016
- };
1017
- this.app.enableCors(corsOptions);
1018
- return this;
1019
- }
1020
- /**
1021
- * @description
1022
- * Applies the Helmet middleware for enhanced security.
1023
- *
1024
- * @summary
1025
- * Dynamically loads the `helmet` package if available and registers it
1026
- * as middleware to improve HTTP header security. If not installed, logs a warning
1027
- * and continues execution without throwing errors.
1028
- *
1029
- * @param {Record<string, any>} [options] - Optional configuration passed to Helmet.
1030
- * @return {typeof NestBootstraper} Returns the class for chaining configuration.
1031
- */
1032
- static useHelmet(options) {
1033
- try {
1034
- // eslint-disable-next-line @typescript-eslint/no-require-imports
1035
- const helmet = require("helmet"); // Dynamic import to avoid hard dependency
1036
- this.app.use(helmet(options));
1037
- this.logger.log("Helmet middleware enabled successfully.");
1038
- }
1039
- catch (e) {
1040
- this.logger.warn("Helmet not installed. Skipping middleware.");
1041
- }
1042
- return this;
1043
- }
1044
- /**
1045
- * @description
1046
- * Configures and initializes Swagger UI for API documentation.
1047
- *
1048
- * @summary
1049
- * Uses the `SwaggerBuilder` utility to configure API documentation
1050
- * with detailed customization for title, version, paths, and colors.
1051
- * Swagger is automatically exposed at the configured path.
1052
- *
1053
- * @param {SwaggerSetupOptions} options - Swagger configuration options.
1054
- * @return {typeof NestBootstraper} Returns the class for chaining configuration.
1055
- */
1056
- static setupSwagger(options) {
1057
- const swagger = new SwaggerBuilder(this.app, {
1058
- title: options.title,
1059
- description: options.description,
1060
- version: options.version,
1061
- path: options.path || "api",
1062
- persistAuthorization: options.persistAuthorization ?? true,
1063
- assetsPath: options.assetsPath,
1064
- faviconFilePath: options.faviconPath,
1065
- topbarIconFilePath: options.topbarIconPath,
1066
- topbarBgColor: options.topbarBgColor,
1067
- });
1068
- swagger.setupSwagger();
1069
- return this;
1070
- }
1071
- /**
1072
- * @description
1073
- * Registers one or more global validation pipes.
1074
- *
1075
- * @summary
1076
- * Enables request payload validation and transformation globally across
1077
- * the entire NestJS application. Multiple pipes can be chained together
1078
- * for modular input validation.
1079
- *
1080
- * @param {...PipeTransform[]} pipes - Pipe instances to register globally.
1081
- * @return {typeof NestBootstraper} Returns the class for chaining.
1082
- */
1083
- static useGlobalPipes(...pipes) {
1084
- if (pipes.length > 0)
1085
- this.app.useGlobalPipes(...pipes);
1086
- return this;
1087
- }
1088
- /**
1089
- * @description
1090
- * Registers one or more global exception filters.
1091
- *
1092
- * @summary
1093
- * If no filters are provided, it automatically registers a default
1094
- * set of standard exception filters for common error types like
1095
- * `HttpException`, `ValidationException`, `ConflictException`, and others.
1096
- *
1097
- * @param {...ExceptionFilter[]} filters - Optional filters to apply globally.
1098
- * @return {typeof NestBootstraper} Returns the class for chaining configuration.
1099
- */
1100
- static useGlobalFilters(...filters) {
1101
- const defaultFilters = [
1102
- new HttpExceptionFilter(),
1103
- new ValidationExceptionFilter(),
1104
- new NotFoundExceptionFilter(),
1105
- new ConflictExceptionFilter(),
1106
- new AuthorizationExceptionFilter(),
1107
- new GlobalExceptionFilter(),
1108
- ];
1109
- this.app.useGlobalFilters(...(filters.length > 0 ? filters : defaultFilters));
1110
- return this;
1111
- }
1112
- /**
1113
- * @description
1114
- * Registers global interceptors for request and response transformation.
1115
- *
1116
- * @summary
1117
- * Interceptors allow advanced request/response manipulation such as
1118
- * serialization, logging, or transformation. Multiple interceptors
1119
- * can be added for modular configuration.
1120
- *
1121
- * @param {...NestInterceptor[]} interceptors - Interceptor instances to register.
1122
- * @return {typeof NestBootstraper} Returns the class for chaining configuration.
1123
- */
1124
- static useGlobalInterceptors(...interceptors) {
1125
- if (interceptors.length > 0)
1126
- this.app.useGlobalInterceptors(...interceptors);
1127
- return this;
1128
- }
1129
- /**
1130
- * @description
1131
- * Starts the NestJS application and binds it to the given port and host.
1132
- *
1133
- * @summary
1134
- * Listens on the specified port and optionally a host. Once started,
1135
- * logs the application URL for easy access. The startup process resolves
1136
- * once the application is successfully running.
1137
- *
1138
- * @param {number} [port=3000] - Port number to listen on.
1139
- * @param {string} [host] - Optional host or IP address to bind to.
1140
- * @param {boolean} [log=true] - Whether to log the application URL upon startup.
1141
- * @return {Promise<void>} Resolves once the application starts successfully.
1142
- */
1143
- static async start(port = Number(process.env.PORT) || 3000, host = undefined, log = true) {
1144
- this.app.listen(port, host).then(async () => {
1145
- if (log) {
1146
- const url = await this.app.getUrl();
1147
- this.logger.log(`🚀 Application is running at: ${url}`);
1148
- }
1149
- });
1150
- }
1151
- }
1152
-
1153
- /**
1154
- * @module for-nest
1155
- * @description This module serves as the main entry point for the ts-workspace library. It aggregates and exports
1156
- * functionality from various submodules and utilities within the project.
1157
- *
1158
- * The module includes:
1159
- * 1. Utility functions and types from the "./utils" directory:
1160
- * - These likely contain helper functions, common types, and shared functionality used throughout the project.
1161
- * - May include operations for data manipulation, type checking, or other general-purpose utilities.
1162
- *
1163
- * 2. A namespace and related types from the "./namespace" directory:
1164
- * - This could contain domain-specific code or a collection of related functionality.
1165
- * - Might include interfaces, types, or classes that represent core concepts in the library.
1166
- *
1167
- * 3. A VERSION constant:
1168
- * - Represents the current version of the module.
1169
- * - Useful for version checking and compatibility purposes.
1170
- *
1171
- * This structure provides a clean and organized export of the module's functionality, allowing consumers
1172
- * to easily import and use specific parts of the library as needed.
1173
- */
1174
- /**
1175
- * Represents the current version of the ts-workspace module.
1176
- * The actual version number is replaced during the build process.
1177
- * @constant
1178
- * @type {string}
1179
- */
1180
- const VERSION = "0.0.5";
1181
- const PACKAGE_NAME = "##PACKAGE_NAME##";
1182
- Metadata.registerLibrary(PACKAGE_NAME, VERSION);
1183
-
1184
- export { ApiProperty, ApiPropertyOptional, ApiResponseProperty, AuthorizationError, AuthorizationExceptionFilter, ConflictError, ConflictExceptionFilter, CorsError, DECAF_ADAPTER_ID, DECAF_MODULE_OPTIONS, DecafModule, GlobalExceptionFilter, HttpExceptionFilter, NestBootstraper, NotFoundError, NotFoundExceptionFilter, PACKAGE_NAME, RepoFactory, SwaggerBuilder, VERSION, ValidationError, ValidationExceptionFilter, createApiPropertyDecorator, createClassDecorator, createMethodDecorator, createMixedDecorator, createParamDecorator, createPropertyDecorator, getTypeIsArrayTuple, repoForModel };
1185
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yLW5lc3QuZXNtLmNqcyIsInNvdXJjZXMiOlsiLi4vc3JjL2RlY29yYXRvcnMvaGVscGVycy50cyIsIi4uL3NyYy9kZWNvcmF0b3JzL0FwaVByb3BlcnR5LnRzIiwiLi4vc3JjL2RlY29yYXRpb24udHMiLCIuLi9zcmMvY29uc3RhbnRzLnRzIiwiLi4vc3JjL2NvcmUtbW9kdWxlLnRzIiwiLi4vc3JjL1JlcG9GYWN0b3J5LnRzIiwiLi4vc3JjL21vZGVsLW1vZHVsZS50cyIsIi4uL3NyYy9tb2R1bGUudHMiLCIuLi9zcmMvdXRpbHMudHMiLCIuLi9zcmMvZmFjdG9yeS9lcnJvcnMvY29ycy50cyIsIi4uL3NyYy9mYWN0b3J5L2V4Y2VwdGlvbnMvSHR0cFJlc3BvbnNlRXJyb3IudHMiLCIuLi9zcmMvZmFjdG9yeS9leGNlcHRpb25zL0F1dGhvcml6YXRpb25FeGNlcHRpb25GaWx0ZXIudHMiLCIuLi9zcmMvZmFjdG9yeS9leGNlcHRpb25zL0NvbmZsaWN0RXhjZXB0aW9uRmlsdGVyLnRzIiwiLi4vc3JjL2ZhY3RvcnkvZXhjZXB0aW9ucy9HbG9iYWxFeGNlcHRpb25GaWx0ZXIudHMiLCIuLi9zcmMvZmFjdG9yeS9leGNlcHRpb25zL0h0dHBFeGNlcHRpb25GaWx0ZXIudHMiLCIuLi9zcmMvZmFjdG9yeS9leGNlcHRpb25zL05vdEZvdW5kRXhjZXB0aW9uRmlsdGVyLnRzIiwiLi4vc3JjL2ZhY3RvcnkvZXhjZXB0aW9ucy9WYWxpZGF0aW9uRXhjZXB0aW9uRmlsdGVyLnRzIiwiLi4vc3JjL2ZhY3Rvcnkvb3BlbmFwaS9jb25zdGFudHMudHMiLCIuLi9zcmMvZmFjdG9yeS9vcGVuYXBpL1N3YWdnZXJDdXN0b21VSS50cyIsIi4uL3NyYy9mYWN0b3J5L29wZW5hcGkvU3dhZ2dlckJ1aWxkZXIudHMiLCIuLi9zcmMvZmFjdG9yeS9OZXN0Qm9vdHN0cmFwZXIudHMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1mdW5jdGlvbi10eXBlICovXG5cbmltcG9ydCB7IE1FVEhPRF9NRVRBREFUQSB9IGZyb20gXCJAbmVzdGpzL2NvbW1vbi9jb25zdGFudHNcIjtcbmltcG9ydCB7IGlzQ29uc3RydWN0b3IgfSBmcm9tIFwiQG5lc3Rqcy9jb21tb24vdXRpbHMvc2hhcmVkLnV0aWxzXCI7XG5pbXBvcnQgeyBpc0FycmF5LCBpc1VuZGVmaW5lZCwgbmVnYXRlLCBwaWNrQnkgfSBmcm9tIFwibG9kYXNoXCI7XG5pbXBvcnQgeyBNRVRBREFUQV9GQUNUT1JZX05BTUUgfSBmcm9tIFwiQG5lc3Rqcy9zd2FnZ2VyL2Rpc3QvcGx1Z2luL3BsdWdpbi1jb25zdGFudHNcIjtcbmltcG9ydCB7IERFQ09SQVRPUlMgfSBmcm9tIFwiQG5lc3Rqcy9zd2FnZ2VyL2Rpc3QvY29uc3RhbnRzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNZXRob2REZWNvcmF0b3I8VCA9IGFueT4oXG4gIG1ldGFrZXk6IHN0cmluZyxcbiAgbWV0YWRhdGE6IFQsXG4gIHsgb3ZlcnJpZGVFeGlzdGluZyB9ID0geyBvdmVycmlkZUV4aXN0aW5nOiB0cnVlIH1cbik6IE1ldGhvZERlY29yYXRvciB7XG4gIHJldHVybiAoXG4gICAgdGFyZ2V0OiBvYmplY3QsXG4gICAga2V5OiBzdHJpbmcgfCBzeW1ib2wsXG4gICAgZGVzY3JpcHRvcjogUHJvcGVydHlEZXNjcmlwdG9yXG4gICkgPT4ge1xuICAgIGlmICh0eXBlb2YgbWV0YWRhdGEgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIGNvbnN0IHByZXZWYWx1ZSA9IFJlZmxlY3QuZ2V0TWV0YWRhdGEobWV0YWtleSwgZGVzY3JpcHRvci52YWx1ZSk7XG4gICAgICBpZiAocHJldlZhbHVlICYmICFvdmVycmlkZUV4aXN0aW5nKSB7XG4gICAgICAgIHJldHVybiBkZXNjcmlwdG9yO1xuICAgICAgfVxuICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcbiAgICAgICAgbWV0YWtleSxcbiAgICAgICAgeyAuLi5wcmV2VmFsdWUsIC4uLm1ldGFkYXRhIH0sXG4gICAgICAgIGRlc2NyaXB0b3IudmFsdWVcbiAgICAgICk7XG4gICAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgICB9XG4gICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShtZXRha2V5LCBtZXRhZGF0YSwgZGVzY3JpcHRvci52YWx1ZSk7XG4gICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDbGFzc0RlY29yYXRvcjxUIGV4dGVuZHMgQXJyYXk8YW55PiA9IGFueT4oXG4gIG1ldGFrZXk6IHN0cmluZyxcbiAgbWV0YWRhdGE6IFQgPSBbXSBhcyB1bmtub3duIGFzIFRcbik6IENsYXNzRGVjb3JhdG9yIHtcbiAgcmV0dXJuICh0YXJnZXQpID0+IHtcbiAgICBjb25zdCBwcmV2VmFsdWUgPSBSZWZsZWN0LmdldE1ldGFkYXRhKG1ldGFrZXksIHRhcmdldCkgfHwgW107XG4gICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShtZXRha2V5LCBbLi4ucHJldlZhbHVlLCAuLi5tZXRhZGF0YV0sIHRhcmdldCk7XG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVByb3BlcnR5RGVjb3JhdG9yPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gYW55PihcbiAgbWV0YWtleTogc3RyaW5nLFxuICBtZXRhZGF0YTogVCxcbiAgb3ZlcnJpZGVFeGlzdGluZyA9IHRydWVcbik6IFByb3BlcnR5RGVjb3JhdG9yIHtcbiAgcmV0dXJuICh0YXJnZXQ6IG9iamVjdCwgcHJvcGVydHlLZXk/OiBhbnkpID0+IHtcbiAgICBjb25zdCBwcm9wZXJ0aWVzID1cbiAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoREVDT1JBVE9SUy5BUElfTU9ERUxfUFJPUEVSVElFU19BUlJBWSwgdGFyZ2V0KSB8fCBbXTtcblxuICAgIGNvbnN0IGtleSA9IGA6JHtwcm9wZXJ0eUtleX1gO1xuICAgIGlmICghcHJvcGVydGllcy5pbmNsdWRlcyhrZXkpKSB7XG4gICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKFxuICAgICAgICBERUNPUkFUT1JTLkFQSV9NT0RFTF9QUk9QRVJUSUVTX0FSUkFZLFxuICAgICAgICBbLi4ucHJvcGVydGllcywgYDoke3Byb3BlcnR5S2V5fWBdLFxuICAgICAgICB0YXJnZXRcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IGV4aXN0aW5nTWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKG1ldGFrZXksIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICAgIGlmIChleGlzdGluZ01ldGFkYXRhKSB7XG4gICAgICBjb25zdCBuZXdNZXRhZGF0YSA9IHBpY2tCeShtZXRhZGF0YSwgbmVnYXRlKGlzVW5kZWZpbmVkKSk7XG4gICAgICBjb25zdCBtZXRhZGF0YVRvU2F2ZSA9IG92ZXJyaWRlRXhpc3RpbmdcbiAgICAgICAgPyB7XG4gICAgICAgICAgICAuLi5leGlzdGluZ01ldGFkYXRhLFxuICAgICAgICAgICAgLi4ubmV3TWV0YWRhdGEsXG4gICAgICAgICAgfVxuICAgICAgICA6IHtcbiAgICAgICAgICAgIC4uLm5ld01ldGFkYXRhLFxuICAgICAgICAgICAgLi4uZXhpc3RpbmdNZXRhZGF0YSxcbiAgICAgICAgICB9O1xuXG4gICAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKG1ldGFrZXksIG1ldGFkYXRhVG9TYXZlLCB0YXJnZXQsIHByb3BlcnR5S2V5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdHlwZSA9XG4gICAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgbmVzdCBqcyBvdmVycmlkZVxuICAgICAgICB0YXJnZXQ/LmNvbnN0cnVjdG9yPy5bTUVUQURBVEFfRkFDVE9SWV9OQU1FXT8uKClbcHJvcGVydHlLZXldPy50eXBlID8/XG4gICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoXCJkZXNpZ246dHlwZVwiLCB0YXJnZXQsIHByb3BlcnR5S2V5KTtcblxuICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcbiAgICAgICAgbWV0YWtleSxcbiAgICAgICAge1xuICAgICAgICAgIHR5cGUsXG4gICAgICAgICAgLi4ucGlja0J5KG1ldGFkYXRhLCBuZWdhdGUoaXNVbmRlZmluZWQpKSxcbiAgICAgICAgfSxcbiAgICAgICAgdGFyZ2V0LFxuICAgICAgICBwcm9wZXJ0eUtleVxuICAgICAgKTtcbiAgICB9XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNaXhlZERlY29yYXRvcjxUID0gYW55PihcbiAgbWV0YWtleTogc3RyaW5nLFxuICBtZXRhZGF0YTogVFxuKTogTWV0aG9kRGVjb3JhdG9yICYgQ2xhc3NEZWNvcmF0b3Ige1xuICByZXR1cm4gKFxuICAgIHRhcmdldDogb2JqZWN0LFxuICAgIGtleT86IHN0cmluZyB8IHN5bWJvbCxcbiAgICBkZXNjcmlwdG9yPzogVHlwZWRQcm9wZXJ0eURlc2NyaXB0b3I8YW55PlxuICApOiBhbnkgPT4ge1xuICAgIGlmIChkZXNjcmlwdG9yKSB7XG4gICAgICBsZXQgbWV0YWRhdGFzOiBhbnk7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShtZXRhZGF0YSkpIHtcbiAgICAgICAgY29uc3QgcHJldmlvdXNNZXRhZGF0YSA9XG4gICAgICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShtZXRha2V5LCBkZXNjcmlwdG9yLnZhbHVlKSB8fCBbXTtcbiAgICAgICAgbWV0YWRhdGFzID0gWy4uLnByZXZpb3VzTWV0YWRhdGEsIC4uLm1ldGFkYXRhXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzTWV0YWRhdGEgPVxuICAgICAgICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEobWV0YWtleSwgZGVzY3JpcHRvci52YWx1ZSkgfHwge307XG4gICAgICAgIG1ldGFkYXRhcyA9IHsgLi4ucHJldmlvdXNNZXRhZGF0YSwgLi4ubWV0YWRhdGEgfTtcbiAgICAgIH1cbiAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEobWV0YWtleSwgbWV0YWRhdGFzLCBkZXNjcmlwdG9yLnZhbHVlKTtcbiAgICAgIHJldHVybiBkZXNjcmlwdG9yO1xuICAgIH1cblxuICAgIGxldCBtZXRhZGF0YXM6IGFueTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShtZXRhZGF0YSkpIHtcbiAgICAgIGNvbnN0IHByZXZpb3VzTWV0YWRhdGEgPSBSZWZsZWN0LmdldE1ldGFkYXRhKG1ldGFrZXksIHRhcmdldCkgfHwgW107XG4gICAgICBtZXRhZGF0YXMgPSBbLi4ucHJldmlvdXNNZXRhZGF0YSwgLi4ubWV0YWRhdGFdO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBwcmV2aW91c01ldGFkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShtZXRha2V5LCB0YXJnZXQpIHx8IHt9O1xuICAgICAgbWV0YWRhdGFzID0gT2JqZWN0LmFzc2lnbihPYmplY3QuYXNzaWduKHt9LCBwcmV2aW91c01ldGFkYXRhKSwgbWV0YWRhdGEpO1xuICAgIH1cbiAgICBSZWZsZWN0LmRlZmluZU1ldGFkYXRhKG1ldGFrZXksIG1ldGFkYXRhcywgdGFyZ2V0KTtcbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUGFyYW1EZWNvcmF0b3I8VCBleHRlbmRzIFJlY29yZDxzdHJpbmcsIGFueT4gPSBhbnk+KFxuICBtZXRhZGF0YTogVCxcbiAgaW5pdGlhbDogUGFydGlhbDxUPlxuKTogTWV0aG9kRGVjb3JhdG9yICYgQ2xhc3NEZWNvcmF0b3Ige1xuICByZXR1cm4gKFxuICAgIHRhcmdldDogb2JqZWN0IHwgRnVuY3Rpb24sXG4gICAga2V5Pzogc3RyaW5nIHwgc3ltYm9sLFxuICAgIGRlc2NyaXB0b3I/OiBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcjxhbnk+XG4gICk6IGFueSA9PiB7XG4gICAgY29uc3QgcGFyYW1PcHRpb25zID0ge1xuICAgICAgLi4uaW5pdGlhbCxcbiAgICAgIC4uLnBpY2tCeShtZXRhZGF0YSwgbmVnYXRlKGlzVW5kZWZpbmVkKSksXG4gICAgfTtcblxuICAgIGlmIChkZXNjcmlwdG9yKSB7XG4gICAgICBjb25zdCBwYXJhbWV0ZXJzID1cbiAgICAgICAgUmVmbGVjdC5nZXRNZXRhZGF0YShERUNPUkFUT1JTLkFQSV9QQVJBTUVURVJTLCBkZXNjcmlwdG9yLnZhbHVlKSB8fCBbXTtcbiAgICAgIFJlZmxlY3QuZGVmaW5lTWV0YWRhdGEoXG4gICAgICAgIERFQ09SQVRPUlMuQVBJX1BBUkFNRVRFUlMsXG4gICAgICAgIFsuLi5wYXJhbWV0ZXJzLCBwYXJhbU9wdGlvbnNdLFxuICAgICAgICBkZXNjcmlwdG9yLnZhbHVlXG4gICAgICApO1xuICAgICAgcmV0dXJuIGRlc2NyaXB0b3I7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiB0YXJnZXQgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHJldHVybiB0YXJnZXQ7XG4gICAgfVxuXG4gICAgY29uc3QgcHJvcGVydHlLZXlzID0gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGFyZ2V0LnByb3RvdHlwZSk7XG5cbiAgICBmb3IgKGNvbnN0IHByb3BlcnR5S2V5IG9mIHByb3BlcnR5S2V5cykge1xuICAgICAgaWYgKGlzQ29uc3RydWN0b3IocHJvcGVydHlLZXkpKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBtZXRob2REZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihcbiAgICAgICAgdGFyZ2V0LnByb3RvdHlwZSxcbiAgICAgICAgcHJvcGVydHlLZXlcbiAgICAgICk7XG5cbiAgICAgIGlmICghbWV0aG9kRGVzY3JpcHRvcikge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaXNBcGlNZXRob2QgPSBSZWZsZWN0Lmhhc01ldGFkYXRhKFxuICAgICAgICBNRVRIT0RfTUVUQURBVEEsXG4gICAgICAgIG1ldGhvZERlc2NyaXB0b3IudmFsdWVcbiAgICAgICk7XG5cbiAgICAgIGlmICghaXNBcGlNZXRob2QpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPVxuICAgICAgICBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgICAgIERFQ09SQVRPUlMuQVBJX1BBUkFNRVRFUlMsXG4gICAgICAgICAgbWV0aG9kRGVzY3JpcHRvci52YWx1ZVxuICAgICAgICApIHx8IFtdO1xuICAgICAgUmVmbGVjdC5kZWZpbmVNZXRhZGF0YShcbiAgICAgICAgREVDT1JBVE9SUy5BUElfUEFSQU1FVEVSUyxcbiAgICAgICAgWy4uLnBhcmFtZXRlcnMsIHBhcmFtT3B0aW9uc10sXG4gICAgICAgIG1ldGhvZERlc2NyaXB0b3IudmFsdWVcbiAgICAgICk7XG4gICAgfVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VHlwZUlzQXJyYXlUdXBsZShcbiAgaW5wdXQ6IEZ1bmN0aW9uIHwgW0Z1bmN0aW9uXSB8IHVuZGVmaW5lZCB8IHN0cmluZyB8IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gIGlzQXJyYXlGbGFnOiBib29sZWFuXG4pOiBbRnVuY3Rpb24gfCB1bmRlZmluZWQsIGJvb2xlYW5dIHtcbiAgaWYgKCFpbnB1dCkge1xuICAgIHJldHVybiBbaW5wdXQgYXMgdW5kZWZpbmVkLCBpc0FycmF5RmxhZ107XG4gIH1cbiAgaWYgKGlzQXJyYXlGbGFnKSB7XG4gICAgcmV0dXJuIFtpbnB1dCBhcyBGdW5jdGlvbiwgaXNBcnJheUZsYWddO1xuICB9XG4gIGNvbnN0IGlzSW5wdXRBcnJheSA9IGlzQXJyYXkoaW5wdXQpO1xuICBjb25zdCB0eXBlID0gaXNJbnB1dEFycmF5ID8gaW5wdXRbMF0gOiBpbnB1dDtcbiAgcmV0dXJuIFt0eXBlIGFzIEZ1bmN0aW9uLCBpc0lucHV0QXJyYXldO1xufVxuIiwiaW1wb3J0IHsgVHlwZSB9IGZyb20gXCJAbmVzdGpzL2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgRW51bUFsbG93ZWRUeXBlcyxcbiAgU2NoZW1hT2JqZWN0TWV0YWRhdGEsXG59IGZyb20gXCJAbmVzdGpzL3N3YWdnZXIvZGlzdC9pbnRlcmZhY2VzL3NjaGVtYS1vYmplY3QtbWV0YWRhdGEuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBFbnVtU2NoZW1hQXR0cmlidXRlcyB9IGZyb20gXCJAbmVzdGpzL3N3YWdnZXIvZGlzdC9pbnRlcmZhY2VzL2VudW0tc2NoZW1hLWF0dHJpYnV0ZXMuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBnZXRUeXBlSXNBcnJheVR1cGxlIH0gZnJvbSBcIkBuZXN0anMvc3dhZ2dlci9kaXN0L2RlY29yYXRvcnMvaGVscGVyc1wiO1xuaW1wb3J0IHtcbiAgZ2V0RW51bVR5cGUsXG4gIGdldEVudW1WYWx1ZXMsXG59IGZyb20gXCJAbmVzdGpzL3N3YWdnZXIvZGlzdC91dGlscy9lbnVtLnV0aWxzXCI7XG5pbXBvcnQgeyBERUNPUkFUT1JTIH0gZnJvbSBcIkBuZXN0anMvc3dhZ2dlci9kaXN0L2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgY3JlYXRlUHJvcGVydHlEZWNvcmF0b3IgfSBmcm9tIFwiLi9oZWxwZXJzXCI7XG5cbmV4cG9ydCB0eXBlIEFwaVByb3BlcnR5Q29tbW9uT3B0aW9ucyA9IFNjaGVtYU9iamVjdE1ldGFkYXRhICYge1xuICBcIngtZW51bU5hbWVzXCI/OiBzdHJpbmdbXTtcbiAgLyoqXG4gICAqIExhenkgZnVuY3Rpb24gcmV0dXJuaW5nIHRoZSB0eXBlIGZvciB3aGljaCB0aGUgZGVjb3JhdGVkIHByb3BlcnR5XG4gICAqIGNhbiBiZSB1c2VkIGFzIGFuIGlkXG4gICAqXG4gICAqIFVzZSB0b2dldGhlciB3aXRoIEBBcGlEZWZhdWx0R2V0dGVyIG9uIHRoZSBnZXR0ZXIgcm91dGUgb2YgdGhlIHR5cGVcbiAgICogdG8gZ2VuZXJhdGUgT3BlbkFQSSBsaW5rIG9iamVjdHNcbiAgICpcbiAgICogQHNlZSBbU3dhZ2dlciBsaW5rIG9iamVjdHNdKGh0dHBzOi8vc3dhZ2dlci5pby9kb2NzL3NwZWNpZmljYXRpb24vbGlua3MvKVxuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtZnVuY3Rpb24tdHlwZVxuICBsaW5rPzogKCkgPT4gVHlwZTx1bmtub3duPiB8IEZ1bmN0aW9uO1xufTtcblxuZXhwb3J0IHR5cGUgQXBpUHJvcGVydHlPcHRpb25zID1cbiAgfCBBcGlQcm9wZXJ0eUNvbW1vbk9wdGlvbnNcbiAgfCAoQXBpUHJvcGVydHlDb21tb25PcHRpb25zICYge1xuICAgICAgZW51bU5hbWU6IHN0cmluZztcbiAgICAgIGVudW1TY2hlbWE/OiBFbnVtU2NoZW1hQXR0cmlidXRlcztcbiAgICB9KTtcblxuY29uc3QgaXNFbnVtQXJyYXkgPSAoXG4gIG9wdHM6IEFwaVByb3BlcnR5T3B0aW9uc1xuKTogb3B0cyBpcyB7XG4gIGlzQXJyYXk6IHRydWU7XG4gIGVudW06IEVudW1BbGxvd2VkVHlwZXM7XG4gIHR5cGU6IGFueTtcbiAgaXRlbXM6IGFueTtcbn0gPT4gKG9wdHMuaXNBcnJheSAmJiBcImVudW1cIiBpbiBvcHRzICYmIG9wdHMuZW51bSAhPT0gdW5kZWZpbmVkKSBhcyBib29sZWFuO1xuXG4vKipcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEFwaVByb3BlcnR5KFxuICBvcHRpb25zOiBBcGlQcm9wZXJ0eU9wdGlvbnMgPSB7fVxuKTogUHJvcGVydHlEZWNvcmF0b3Ige1xuICByZXR1cm4gY3JlYXRlQXBpUHJvcGVydHlEZWNvcmF0b3Iob3B0aW9ucyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVBcGlQcm9wZXJ0eURlY29yYXRvcihcbiAgb3B0aW9uczogQXBpUHJvcGVydHlPcHRpb25zID0ge30sXG4gIG92ZXJyaWRlRXhpc3RpbmcgPSB0cnVlXG4pOiBQcm9wZXJ0eURlY29yYXRvciB7XG4gIGNvbnN0IFt0eXBlLCBpc0FycmF5XSA9IGdldFR5cGVJc0FycmF5VHVwbGUoXG4gICAgb3B0aW9ucy50eXBlLFxuICAgIG9wdGlvbnMuaXNBcnJheSBhcyBib29sZWFuXG4gICk7XG4gIG9wdGlvbnMgPSB7XG4gICAgLi4ub3B0aW9ucyxcbiAgICB0eXBlLFxuICAgIGlzQXJyYXksXG4gIH0gYXMgQXBpUHJvcGVydHlPcHRpb25zO1xuXG4gIGlmIChpc0VudW1BcnJheShvcHRpb25zKSkge1xuICAgIG9wdGlvbnMudHlwZSA9IFwiYXJyYXlcIjtcblxuICAgIGNvbnN0IGVudW1WYWx1ZXMgPSBnZXRFbnVtVmFsdWVzKG9wdGlvbnMuZW51bSk7XG4gICAgb3B0aW9ucy5pdGVtcyA9IHtcbiAgICAgIHR5cGU6IGdldEVudW1UeXBlKGVudW1WYWx1ZXMpLFxuICAgICAgZW51bTogZW51bVZhbHVlcyxcbiAgICB9O1xuICAgIC8vIEB0cy1leHBlY3QtZXJyb3IgbmVzdCBzd2FnZ2VyIG92ZXJyaWRlXG4gICAgZGVsZXRlIG9wdGlvbnMuZW51bTtcbiAgfSBlbHNlIGlmIChcImVudW1cIiBpbiBvcHRpb25zICYmIG9wdGlvbnMuZW51bSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgZW51bVZhbHVlcyA9IGdldEVudW1WYWx1ZXMob3B0aW9ucy5lbnVtKTtcblxuICAgIG9wdGlvbnMuZW51bSA9IGVudW1WYWx1ZXM7XG4gICAgb3B0aW9ucy50eXBlID0gZ2V0RW51bVR5cGUoZW51bVZhbHVlcyk7XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheShvcHRpb25zLnR5cGUpKSB7XG4gICAgb3B0aW9ucy50eXBlID0gXCJhcnJheVwiO1xuICAgIG9wdGlvbnMuaXRlbXMgPSB7XG4gICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICBpdGVtczoge1xuICAgICAgICB0eXBlOiBvcHRpb25zLnR5cGVbMF0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gY3JlYXRlUHJvcGVydHlEZWNvcmF0b3IoXG4gICAgREVDT1JBVE9SUy5BUElfTU9ERUxfUFJPUEVSVElFUyxcbiAgICBvcHRpb25zLFxuICAgIG92ZXJyaWRlRXhpc3RpbmdcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIEFwaVByb3BlcnR5T3B0aW9uYWwoXG4gIG9wdGlvbnM6IEFwaVByb3BlcnR5T3B0aW9ucyA9IHt9XG4pOiBQcm9wZXJ0eURlY29yYXRvciB7XG4gIHJldHVybiBBcGlQcm9wZXJ0eSh7XG4gICAgLi4ub3B0aW9ucyxcbiAgICByZXF1aXJlZDogZmFsc2UsXG4gIH0gYXMgQXBpUHJvcGVydHlPcHRpb25zKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIEFwaVJlc3BvbnNlUHJvcGVydHkoXG4gIG9wdGlvbnM6IFBpY2s8XG4gICAgQXBpUHJvcGVydHlPcHRpb25zLFxuICAgIFwidHlwZVwiIHwgXCJleGFtcGxlXCIgfCBcImZvcm1hdFwiIHwgXCJkZXByZWNhdGVkXCIgfCBcImVudW1cIlxuICA+ID0ge31cbik6IFByb3BlcnR5RGVjb3JhdG9yIHtcbiAgcmV0dXJuIEFwaVByb3BlcnR5KHtcbiAgICByZWFkT25seTogdHJ1ZSxcbiAgICAuLi5vcHRpb25zLFxuICB9IGFzIEFwaVByb3BlcnR5T3B0aW9ucyk7XG59XG4iLCJpbXBvcnQge1xuICBJbmplY3RhYmxlQ29uZmlnLFxuICBJbmplY3RhYmxlc0tleXMsXG4gIEluamVjdE9wdGlvbnMsXG59IGZyb20gXCJAZGVjYWYtdHMvaW5qZWN0YWJsZS1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIFNjb3BlIH0gZnJvbSBcIkBuZXN0anMvY29tbW9uXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgRGVjb3JhdGlvbiwgRGVjb3JhdGlvbktleXMgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRpb25cIjtcbmltcG9ydCB7IFZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgQXBpUHJvcGVydHkgfSBmcm9tIFwiLi9kZWNvcmF0b3JzL0FwaVByb3BlcnR5XCI7XG5pbXBvcnQgeyBQZXJzaXN0ZW5jZUtleXMgfSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcblxuRGVjb3JhdGlvbi5mb3IoSW5qZWN0YWJsZXNLZXlzLklOSkVDVEFCTEUpXG4gIC5leHRlbmQoe1xuICAgIGRlY29yYXRvcjogZnVuY3Rpb24gbmVzdEluamVjdGFibGUoXG4gICAgICBjYXRlZ29yeTogc3RyaW5nIHwgQ29uc3RydWN0b3IsXG4gICAgICBjZmc6IEluamVjdGFibGVDb25maWdcbiAgICApIHtcbiAgICAgIHJldHVybiBJbmplY3RhYmxlKHtcbiAgICAgICAgc2NvcGU6IGNmZy5zaW5nbGV0b24gPyBTY29wZS5ERUZBVUxUIDogU2NvcGUuUkVRVUVTVCxcbiAgICAgICAgZHVyYWJsZTogY2ZnLnNpbmdsZXRvbiA/IHVuZGVmaW5lZCA6IHRydWUsXG4gICAgICB9KTtcbiAgICB9LFxuICB9KVxuICAuYXBwbHkoKTtcblxuRGVjb3JhdGlvbi5mb3IoSW5qZWN0YWJsZXNLZXlzLklOSkVDVClcbiAgLmV4dGVuZCh7XG4gICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBuZXN0SW5qZWN0KFxuICAgICAgY2F0ZWdvcnk6IHN5bWJvbCB8IHN0cmluZyB8IENvbnN0cnVjdG9yLFxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICAgICAgY2ZnOiBJbmplY3RPcHRpb25zXG4gICAgKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24gaW5uZXJOZXN0SW5qZWN0KFxuICAgICAgICB0YXJnZXQ6IG9iamVjdCxcbiAgICAgICAgcHJvcGVydHlLZXk/OiBhbnksXG4gICAgICAgIGRlc2NyaXB0b3I/OiBhbnlcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gSW5qZWN0KGNhdGVnb3J5IHx8ICh0YXJnZXQgYXMgQ29uc3RydWN0b3IpKShcbiAgICAgICAgICB0YXJnZXQsXG4gICAgICAgICAgcHJvcGVydHlLZXksXG4gICAgICAgICAgZGVzY3JpcHRvclxuICAgICAgICApO1xuICAgICAgfTtcbiAgICB9LFxuICB9KVxuICAuYXBwbHkoKTtcblxuRGVjb3JhdGlvbi5mb3IoVmFsaWRhdGlvbktleXMuUkVRVUlSRUQpXG4gIC5leHRlbmQoXG4gICAgQXBpUHJvcGVydHkoe1xuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgfSlcbiAgKVxuICAuYXBwbHkoKTtcblxuRGVjb3JhdGlvbi5mb3IoVmFsaWRhdGlvbktleXMuTUFYKVxuICAuZXh0ZW5kKHtcbiAgICBkZWNvcmF0b3I6IGZ1bmN0aW9uIG1heERlYyhtYXg6IG51bWJlcikge1xuICAgICAgcmV0dXJuIEFwaVByb3BlcnR5KHsgbWF4aW11bTogbWF4IH0pO1xuICAgIH0sXG4gIH0pXG4gIC5hcHBseSgpO1xuXG5EZWNvcmF0aW9uLmZvcihWYWxpZGF0aW9uS2V5cy5NSU4pXG4gIC5leHRlbmQoe1xuICAgIGRlY29yYXRvcjogZnVuY3Rpb24gbWluRGVjKG1pbjogbnVtYmVyKSB7XG4gICAgICByZXR1cm4gQXBpUHJvcGVydHkoeyBtaW5pbXVtOiBtaW4gfSk7XG4gICAgfSxcbiAgfSlcbiAgLmFwcGx5KCk7XG5cbkRlY29yYXRpb24uZm9yKFZhbGlkYXRpb25LZXlzLk1BWF9MRU5HVEgpXG4gIC5leHRlbmQoe1xuICAgIGRlY29yYXRvcjogZnVuY3Rpb24gbWF4TGVuZ3RoRGVjKG1heDogbnVtYmVyKSB7XG4gICAgICByZXR1cm4gQXBpUHJvcGVydHkoeyBtYXhMZW5ndGg6IG1heCB9KTtcbiAgICB9LFxuICB9KVxuICAuYXBwbHkoKTtcblxuRGVjb3JhdGlvbi5mb3IoVmFsaWRhdGlvbktleXMuTUlOX0xFTkdUSClcbiAgLmV4dGVuZCh7XG4gICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBtaW5MZW5ndGhEZWMobWluOiBudW1iZXIpIHtcbiAgICAgIHJldHVybiBBcGlQcm9wZXJ0eSh7IG1pbkxlbmd0aDogbWluIH0pO1xuICAgIH0sXG4gIH0pXG4gIC5hcHBseSgpO1xuLy9cbi8vIERlY29yYXRpb24uZm9yKFZhbGlkYXRpb25LZXlzLlRZUEUpXG4vLyAgIC5leHRlbmQoe1xuLy8gICAgIGRlY29yYXRvcjogZnVuY3Rpb24gdHlwZURlYyh0eXBlOiAoc3RyaW5nIHwgKCgpID0+IHN0cmluZykpW10gfCBzdHJpbmcgfCAoKCkgPT4gc3RyaW5nKSkge1xuLy8gICAgICAgcmV0dXJuIEFwaVByb3BlcnR5KHsgdHlwZTogdHlwZSBhcyBhbnkgfSk7XG4vLyAgICAgfSxcbi8vICAgfSlcbi8vICAgLmFwcGx5KCk7XG4vL1xuLy8gRGVjb3JhdGlvbi5mb3IoVmFsaWRhdGlvbktleXMuREFURSlcbi8vICAgLmV4dGVuZCh7XG4vLyAgICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBkYXRlRGVjKCkge1xuLy8gICAgICAgcmV0dXJuIEFwaVByb3BlcnR5KHsgdHlwZTogRGF0ZSB9KTtcbi8vICAgICB9LFxuLy8gICB9KVxuLy8gICAuYXBwbHkoKTtcblxuRGVjb3JhdGlvbi5mb3IoVmFsaWRhdGlvbktleXMuTElTVClcbiAgLmV4dGVuZCh7XG4gICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBsaXN0RGVjKFxuICAgICAgY2xheno6XG4gICAgICAgIHwgQ29uc3RydWN0b3I8YW55PlxuICAgICAgICB8ICgoKSA9PiBDb25zdHJ1Y3Rvcjxhbnk+KVxuICAgICAgICB8IChDb25zdHJ1Y3Rvcjxhbnk+IHwgKCgpID0+IENvbnN0cnVjdG9yPGFueT4pKVtdXG4gICAgKSB7XG4gICAgICBjb25zdCBjID0gQXJyYXkuaXNBcnJheShjbGF6eikgPyBjbGF6elswXSA6IGNsYXp6O1xuICAgICAgcmV0dXJuIEFwaVByb3BlcnR5KHsgdHlwZTogW2NdIH0pO1xuICAgIH0sXG4gIH0pXG4gIC5hcHBseSgpO1xuXG4vL1xuLy8gRGVjb3JhdGlvbi5mb3IoVmFsaWRhdGlvbktleXMuT1BUSU9OKVxuLy8gICAuZXh0ZW5kKHtcbi8vICAgICBkZWNvcmF0b3I6IGZ1bmN0aW9uIG9wdGlvbkRlYyhvcHRpb25zOiBzdHJpbmdbXSB8IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcbi8vICAgICAgIGNvbnN0IG9wdHMgPSBBcnJheS5pc0FycmF5KG9wdGlvbnMpID8gb3B0aW9ucyA6IE9iamVjdC52YWx1ZXMob3B0aW9ucyk7XG4vLyAgICAgICByZXR1cm4gQXBpUHJvcGVydHkoeyBlbnVtOiBvcHRzIH0pO1xuLy8gICAgIH0sXG4vLyAgIH0pXG4vLyAgIC5hcHBseSgpO1xuXG5EZWNvcmF0aW9uLmZvcihWYWxpZGF0aW9uS2V5cy5QQVRURVJOKVxuICAuZXh0ZW5kKHtcbiAgICBkZWNvcmF0b3I6IGZ1bmN0aW9uIHBhdHRlcm5EZWMocGF0OiBSZWdFeHAgfCBzdHJpbmcpIHtcbiAgICAgIHJldHVybiBBcGlQcm9wZXJ0eSh7XG4gICAgICAgIHBhdHRlcm46IHR5cGVvZiBwYXQgPT09IFwic3RyaW5nXCIgPyBwYXQgOiBwYXQuc291cmNlLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSlcbiAgLmFwcGx5KCk7XG5cbkRlY29yYXRpb24uZm9yKFBlcnNpc3RlbmNlS2V5cy5DT0xVTU4pXG4gIC5leHRlbmQoe1xuICAgIGRlY29yYXRvcjogZnVuY3Rpb24gY29sdW1uRGVjKG5hbWU6IHN0cmluZykge1xuICAgICAgcmV0dXJuIEFwaVByb3BlcnR5KHtcbiAgICAgICAgbmFtZTogbmFtZSxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0pXG4gIC5hcHBseSgpO1xuXG5EZWNvcmF0aW9uLmZvcihEZWNvcmF0aW9uS2V5cy5ERVNDUklQVElPTilcbiAgLmV4dGVuZCh7XG4gICAgZGVjb3JhdG9yOiBmdW5jdGlvbiBkZXNjcmlwdGlvbkRlYyhkZXNjcmlwdGlvbjogc3RyaW5nKSB7XG4gICAgICByZXR1cm4gQXBpUHJvcGVydHkoe1xuICAgICAgICBkZXNjcmlwdGlvbjogZGVzY3JpcHRpb24sXG4gICAgICB9KTtcbiAgICB9LFxuICB9KVxuICAuYXBwbHkoKTtcbiIsImV4cG9ydCBjb25zdCBERUNBRl9NT0RVTEVfT1BUSU9OUyA9IFwiRGVjYWZNb2R1bGVPcHRpb25zXCI7XG5leHBvcnQgY29uc3QgREVDQUZfQURBUFRFUl9JRCA9IFwiRGVjYWZBZGFwdGVyXCI7XG4iLCJpbXBvcnQge1xuICBEeW5hbWljTW9kdWxlLFxuICBHbG9iYWwsXG4gIEluamVjdCxcbiAgTW9kdWxlLFxuICBPbkFwcGxpY2F0aW9uU2h1dGRvd24sXG4gIFNjb3BlLFxufSBmcm9tIFwiQG5lc3Rqcy9jb21tb25cIjtcbmltcG9ydCB7IE1vZHVsZVJlZiB9IGZyb20gXCJAbmVzdGpzL2NvcmVcIjtcbmltcG9ydCB0eXBlIHsgRGVjYWZNb2R1bGVPcHRpb25zIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IERFQ0FGX0FEQVBURVJfSUQsIERFQ0FGX01PRFVMRV9PUFRJT05TIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBGYWN0b3J5UHJvdmlkZXIgfSBmcm9tIFwiQG5lc3Rqcy9jb21tb24vaW50ZXJmYWNlcy9tb2R1bGVzL3Byb3ZpZGVyLmludGVyZmFjZVwiO1xuaW1wb3J0IHsgQWRhcHRlciB9IGZyb20gXCJAZGVjYWYtdHMvY29yZVwiO1xuaW1wb3J0IHsgTG9nZ2VyLCBMb2dnaW5nIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5cbkBHbG9iYWwoKVxuQE1vZHVsZSh7fSlcbmV4cG9ydCBjbGFzcyBEZWNhZkNvcmVNb2R1bGU8XG4gIENPTkYsXG4gIEFEQVBURVIgZXh0ZW5kcyBBZGFwdGVyPENPTkYsIGFueSwgYW55LCBhbnksIGFueT4sXG4+IGltcGxlbWVudHMgT25BcHBsaWNhdGlvblNodXRkb3duXG57XG4gIHByaXZhdGUgc3RhdGljIF9sb2dnZXI6IExvZ2dlcjtcbiAgcHJpdmF0ZSBzdGF0aWMgX2FkYXB0ZXJJbnN0YW5jZTogQWRhcHRlcjxhbnksIGFueSwgYW55LCBhbnksIGFueT4gfCBudWxsID1cbiAgICBudWxsO1xuXG4gIHByb3RlY3RlZCBzdGF0aWMgZ2V0IGxvZygpOiBMb2dnZXIge1xuICAgIGlmICghdGhpcy5fbG9nZ2VyKSB0aGlzLl9sb2dnZXIgPSBMb2dnaW5nLmZvcihEZWNhZkNvcmVNb2R1bGUpO1xuICAgIHJldHVybiB0aGlzLl9sb2dnZXI7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KERFQ0FGX01PRFVMRV9PUFRJT05TKVxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogRGVjYWZNb2R1bGVPcHRpb25zPENPTkYsIEFEQVBURVI+LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbW9kdWxlUmVmOiBNb2R1bGVSZWZcbiAgKSB7fVxuXG4gIHN0YXRpYyBhc3luYyBjcmVhdGVBZGFwdGVyKFxuICAgIG9wdGlvbnM6IERlY2FmTW9kdWxlT3B0aW9uc1xuICApOiBQcm9taXNlPEFkYXB0ZXI8YW55LCBhbnksIGFueSwgYW55LCBhbnk+PiB7XG4gICAgaWYgKCF0aGlzLl9hZGFwdGVySW5zdGFuY2UpIHtcbiAgICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLmNyZWF0ZUFkYXB0ZXIpO1xuICAgICAgbG9nLmluZm8oXCJDcmVhdGluZyBhZGFwdGVyIGluc3RhbmNlLi4uXCIpO1xuICAgICAgdGhpcy5fYWRhcHRlckluc3RhbmNlID0gbmV3IG9wdGlvbnMuYWRhcHRlcihvcHRpb25zLmNvbmYsIG9wdGlvbnMuYWxpYXMpO1xuICAgICAgbG9nLmluZm8oXCJBZGFwdGVyIGluc3RhbmNlIGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5IVwiKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX2FkYXB0ZXJJbnN0YW5jZTtcbiAgfVxuXG4gIHN0YXRpYyBnZXRBZGFwdGVySW5zdGFuY2UoKTogQWRhcHRlcjxhbnksIGFueSwgYW55LCBhbnksIGFueT4gfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fYWRhcHRlckluc3RhbmNlO1xuICB9XG5cbiAgc3RhdGljIGZvclJvb3Qob3B0aW9uczogRGVjYWZNb2R1bGVPcHRpb25zKTogRHluYW1pY01vZHVsZSB7XG4gICAgY29uc3QgdHlwZU9ybU1vZHVsZU9wdGlvbnMgPSB7XG4gICAgICBwcm92aWRlOiBERUNBRl9NT0RVTEVfT1BUSU9OUyxcbiAgICAgIHVzZVZhbHVlOiBvcHRpb25zLFxuICAgIH07XG5cbiAgICBjb25zdCBhZGFwdGVyOiBGYWN0b3J5UHJvdmlkZXI8YW55PiA9IHtcbiAgICAgIHVzZUZhY3Rvcnk6IGFzeW5jIChvcHRzOiBEZWNhZk1vZHVsZU9wdGlvbnMpID0+IHtcbiAgICAgICAgcmV0dXJuIERlY2FmQ29yZU1vZHVsZS5jcmVhdGVBZGFwdGVyKG9wdHMpO1xuICAgICAgfSxcbiAgICAgIHByb3ZpZGU6IERFQ0FGX0FEQVBURVJfSUQsXG4gICAgICBkdXJhYmxlOiB0cnVlLFxuICAgICAgc2NvcGU6IFNjb3BlLkRFRkFVTFQsXG4gICAgICBpbmplY3Q6IFtERUNBRl9NT0RVTEVfT1BUSU9OU10sXG4gICAgfTtcblxuICAgIGNvbnN0IHByb3ZpZGVycyA9IFthZGFwdGVyLCB0eXBlT3JtTW9kdWxlT3B0aW9uc107XG4gICAgY29uc3QgZXhwb3J0cyA9IFthZGFwdGVyXTtcblxuICAgIHJldHVybiB7XG4gICAgICBtb2R1bGU6IERlY2FmQ29yZU1vZHVsZSxcbiAgICAgIHByb3ZpZGVycyxcbiAgICAgIGV4cG9ydHMsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIG9uQXBwbGljYXRpb25TaHV0ZG93bigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBsb2cgPSBEZWNhZkNvcmVNb2R1bGUubG9nLmZvcih0aGlzLm9uQXBwbGljYXRpb25TaHV0ZG93bik7XG4gICAgY29uc3QgYWRhcHRlciA9IHRoaXMubW9kdWxlUmVmLmdldDxBREFQVEVSPihERUNBRl9BREFQVEVSX0lEKTtcbiAgICB0cnkge1xuICAgICAgaWYgKGFkYXB0ZXIpIHtcbiAgICAgICAgbG9nLmluZm8oXCJTaHV0dGluZyBkb3duXCIpO1xuICAgICAgICBhd2FpdCBhZGFwdGVyLnNodXRkb3duKCk7XG4gICAgICAgIERlY2FmQ29yZU1vZHVsZS5fYWRhcHRlckluc3RhbmNlID0gbnVsbDtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICBsb2cuZXJyb3IoYEZhaWxlZCB0byBzaHV0ZG93biBhcHBsaWNhdGlvbmAsIGUgYXMgRXJyb3IpO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIkBkZWNhZi10cy9kYi1kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBSZXBvLCBSZXBvc2l0b3J5IH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdGlvblwiO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gXCJAbmVzdGpzL2NvbW1vblwiO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUmVwb0ZhY3Rvcnkge1xuICBmb3I8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogc3RyaW5nIHwgQ29uc3RydWN0b3I8TT4pOiBSZXBvPE0+IHtcbiAgICBtb2RlbCA9IHR5cGVvZiBtb2RlbCA9PT0gXCJzdHJpbmdcIiA/IChNb2RlbC5nZXQobW9kZWwpIGFzIGFueSkgOiBtb2RlbDtcbiAgICBpZiAoIW1vZGVsKSB7XG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgRmFpbGVkIHRvIGZpbmQgcmVwb3NpdG9yeSBmb3IgJHttb2RlbH1gKTtcbiAgICB9XG4gICAgcmV0dXJuIFJlcG9zaXRvcnkuZm9yTW9kZWwobW9kZWwgYXMgQ29uc3RydWN0b3I8TT4pO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBCb2R5LFxuICBDb250cm9sbGVyLFxuICBEZWxldGUsXG4gIER5bmFtaWNNb2R1bGUsXG4gIEdldCxcbiAgTW9kdWxlLFxuICBQYXJhbSxcbiAgUG9zdCxcbiAgUHV0LFxufSBmcm9tIFwiQG5lc3Rqcy9jb21tb25cIjtcbmltcG9ydCB7XG4gIEFwaUJhZFJlcXVlc3RSZXNwb25zZSxcbiAgQXBpQm9keSxcbiAgQXBpQ3JlYXRlZFJlc3BvbnNlLFxuICBBcGlFeHRyYU1vZGVscyxcbiAgQXBpTm90Rm91bmRSZXNwb25zZSxcbiAgQXBpT2tSZXNwb25zZSxcbiAgQXBpT3BlcmF0aW9uLFxuICBBcGlQYXJhbSxcbiAgQXBpVGFncyxcbiAgQXBpVW5wcm9jZXNzYWJsZUVudGl0eVJlc3BvbnNlLFxuICBnZXRTY2hlbWFQYXRoLFxufSBmcm9tIFwiQG5lc3Rqcy9zd2FnZ2VyXCI7XG5pbXBvcnQgeyBBZGFwdGVyLCBSZXBvLCBSZXBvc2l0b3J5IH0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5pbXBvcnQgeyBNb2RlbCwgTW9kZWxDb25zdHJ1Y3RvciB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IExvZ2dlZENsYXNzLCBMb2dnZXIsIExvZ2dpbmcsIHRvS2ViYWJDYXNlIH0gZnJvbSBcIkBkZWNhZi10cy9sb2dnaW5nXCI7XG5pbXBvcnQgeyBSZXBvRmFjdG9yeSB9IGZyb20gXCIuL1JlcG9GYWN0b3J5XCI7XG5cbkBNb2R1bGUoe30pXG5leHBvcnQgY2xhc3MgRGVjYWZNb2RlbE1vZHVsZSB7XG4gIHByaXZhdGUgc3RhdGljIF9sb2dnZXI6IExvZ2dlcjtcblxuICBwcm90ZWN0ZWQgc3RhdGljIGdldCBsb2coKTogTG9nZ2VyIHtcbiAgICBpZiAoIXRoaXMuX2xvZ2dlcikgdGhpcy5fbG9nZ2VyID0gTG9nZ2luZy5mb3IoRGVjYWZNb2RlbE1vZHVsZSk7XG4gICAgcmV0dXJuIHRoaXMuX2xvZ2dlcjtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIHRvTW9kZWxDb250cm9sbGVyPFQgZXh0ZW5kcyBNb2RlbDxhbnk+PihcbiAgICBNb2RlbENsYXp6OiBNb2RlbENvbnN0cnVjdG9yPGFueT5cbiAgKSB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMudG9Nb2RlbENvbnRyb2xsZXIpO1xuICAgIGNvbnN0IHRhYmxlTmFtZSA9IFJlcG9zaXRvcnkudGFibGUoTW9kZWxDbGF6eik7XG4gICAgY29uc3Qgcm91dGVQYXRoID0gdG9LZWJhYkNhc2UodGFibGVOYW1lKTtcbiAgICBjb25zdCBtb2RlbENsYXp6TmFtZSA9IE1vZGVsQ2xhenoubmFtZTtcblxuICAgIGxvZy5kZWJ1ZyhgQ3JlYXRpbmcgY29udHJvbGxlciBmb3IgbW9kZWw6ICR7bW9kZWxDbGF6ek5hbWV9YCk7XG5cbiAgICBAQ29udHJvbGxlcihyb3V0ZVBhdGgpXG4gICAgQEFwaVRhZ3MobW9kZWxDbGF6ek5hbWUpXG4gICAgQEFwaUV4dHJhTW9kZWxzKE1vZGVsQ2xhenopXG4gICAgY2xhc3MgRHluYW1pY01vZGVsQ29udHJvbGxlciBleHRlbmRzIExvZ2dlZENsYXNzIHtcbiAgICAgIC8vIHByaXZhdGUgcmVhZG9ubHkgcmVwbyA9IHRoaXMucmVwb0ZhY3RvcnkuZm9yKE1vZGVsQ2xhenopO1xuICAgICAgcHJpdmF0ZSByZWFkb25seSBwayE6IHN0cmluZztcbiAgICAgIHByaXZhdGUgcmVhZG9ubHkgcmVwbyE6IFJlcG88VD47IC8vUmVwb3NpdG9yeTxNb2RlbDxhbnk+LCBhbnksIGFueSwgYW55LCBhbnk+O1xuXG4gICAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHJlcG9GYWN0b3J5OiBSZXBvRmFjdG9yeSkge1xuICAgICAgICBzdXBlcigpO1xuICAgICAgICBsb2cuaW5mbyhcbiAgICAgICAgICBgUmVnaXN0ZXJpbmcgZHluYW1pYyBjb250cm9sbGVyIGZvciBtb2RlbDogJHttb2RlbENsYXp6TmFtZX0gcm91dGU6IC8ke3JvdXRlUGF0aH1gXG4gICAgICAgICk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLnJlcG8gPSB0aGlzLnJlcG9GYWN0b3J5LmZvcihNb2RlbENsYXp6Lm5hbWUpO1xuICAgICAgICAgIHRoaXMucGsgPSB0aGlzLnJlcG8ucGsgYXMgc3RyaW5nO1xuICAgICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgICB0aGlzLmxvZy5lcnJvcihcbiAgICAgICAgICAgIGBGYWlsZWQgdG8gaW5pdGlhbGl6ZSByZXBvc2l0b3J5IGZvciBtb2RlbCBcIiR7TW9kZWxDbGF6ei5uYW1lfVwiLmAsXG4gICAgICAgICAgICBlXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBAUG9zdCgpXG4gICAgICBAQXBpT3BlcmF0aW9uKHsgc3VtbWFyeTogYENyZWF0ZSBhIG5ldyAke21vZGVsQ2xhenpOYW1lfS5gIH0pXG4gICAgICBAQXBpQm9keSh7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBgUGF5bG9hZCBmb3IgJHttb2RlbENsYXp6TmFtZX1gLFxuICAgICAgICBzY2hlbWE6IHsgJHJlZjogZ2V0U2NoZW1hUGF0aChNb2RlbENsYXp6KSB9LFxuICAgICAgfSlcbiAgICAgIEBBcGlDcmVhdGVkUmVzcG9uc2Uoe1xuICAgICAgICBkZXNjcmlwdGlvbjogYCR7bW9kZWxDbGF6ek5hbWV9IGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5LmAsXG4gICAgICB9KVxuICAgICAgQEFwaUJhZFJlcXVlc3RSZXNwb25zZSh7IGRlc2NyaXB0aW9uOiBcIlBheWxvYWQgdmFsaWRhdGlvbiBmYWlsZWQuXCIgfSlcbiAgICAgIEBBcGlVbnByb2Nlc3NhYmxlRW50aXR5UmVzcG9uc2Uoe1xuICAgICAgICBkZXNjcmlwdGlvbjogXCJSZXBvc2l0b3J5IHJlamVjdGVkIHRoZSBwcm92aWRlZCBwYXlsb2FkLlwiLFxuICAgICAgfSlcbiAgICAgIGFzeW5jIGNyZWF0ZShAQm9keSgpIGRhdGE6IFQpOiBQcm9taXNlPE1vZGVsPGFueT4+IHtcbiAgICAgICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMuY3JlYXRlKTtcbiAgICAgICAgbG9nLnZlcmJvc2UoYGNyZWF0aW5nIG5ldyAke21vZGVsQ2xhenpOYW1lfWApO1xuICAgICAgICBsZXQgY3JlYXRlZDogTW9kZWw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY3JlYXRlZCA9IGF3YWl0IHRoaXMucmVwby5jcmVhdGUoZGF0YSk7XG4gICAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgICBsb2cuZXJyb3IoYEZhaWxlZCB0byBjcmVhdGUgbmV3ICR7bW9kZWxDbGF6ek5hbWV9YCwgZSBhcyBFcnJvcik7XG4gICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgfVxuICAgICAgICBsb2cuaW5mbyhgY3JlYXRlZCBuZXcgJHttb2RlbENsYXp6TmFtZX0gd2l0aCBpZCAke2NyZWF0ZWRbdGhpcy5wa119YCk7XG4gICAgICAgIHJldHVybiBjcmVhdGVkO1xuICAgICAgfVxuXG4gICAgICBAR2V0KFwiOmlkXCIpXG4gICAgICBAQXBpT3BlcmF0aW9uKHsgc3VtbWFyeTogYFJldHJpZXZlIGEgJHttb2RlbENsYXp6TmFtZX0gcmVjb3JkIGJ5IGlkLmAgfSlcbiAgICAgIEBBcGlQYXJhbSh7IG5hbWU6IFwiaWRcIiwgZGVzY3JpcHRpb246IFwiUHJpbWFyeSBrZXlcIiB9KVxuICAgICAgQEFwaU9rUmVzcG9uc2Uoe1xuICAgICAgICBkZXNjcmlwdGlvbjogYCR7bW9kZWxDbGF6ek5hbWV9IHJldHJpZXZlZCBzdWNjZXNzZnVsbHkuYCxcbiAgICAgIH0pXG4gICAgICBAQXBpTm90Rm91bmRSZXNwb25zZSh7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBgTm8gJHttb2RlbENsYXp6TmFtZX0gcmVjb3JkIG1hdGNoZXMgdGhlIHByb3ZpZGVkIGlkZW50aWZpZXIuYCxcbiAgICAgIH0pXG4gICAgICBhc3luYyByZWFkKEBQYXJhbShcImlkXCIpIGlkOiBzdHJpbmcpIHtcbiAgICAgICAgY29uc3QgbG9nID0gdGhpcy5sb2cuZm9yKHRoaXMucmVhZCk7XG4gICAgICAgIGxldCByZWFkOiBNb2RlbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBsb2cuZGVidWcoYHJlYWRpbmcgJHttb2RlbENsYXp6TmFtZX0gd2l0aCAke3RoaXMucGt9ICR7aWR9YCk7XG4gICAgICAgICAgcmVhZCA9IGF3YWl0IHRoaXMucmVwby5yZWFkKGlkKTtcbiAgICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICAgIGxvZy5lcnJvcihcbiAgICAgICAgICAgIGBGYWlsZWQgdG8gcmVhZCAke21vZGVsQ2xhenpOYW1lfSB3aXRoIGlkICR7aWR9YCxcbiAgICAgICAgICAgIGUgYXMgRXJyb3JcbiAgICAgICAgICApO1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cblxuICAgICAgICBsb2cuaW5mbyhgcmVhZCAke21vZGVsQ2xhenpOYW1lfSB3aXRoIGlkICR7cmVhZFt0aGlzLnBrXX1gKTtcbiAgICAgICAgcmV0dXJuIHJlYWQ7XG4gICAgICB9XG5cbiAgICAgIEBQdXQoXCI6aWRcIilcbiAgICAgIEBBcGlPcGVyYXRpb24oe1xuICAgICAgICBzdW1tYXJ5OiBgUmVwbGFjZSBhbiBleGlzdGluZyAke21vZGVsQ2xhenpOYW1lfSByZWNvcmQgd2l0aCBhIG5ldyBwYXlsb2FkLmAsXG4gICAgICB9KVxuICAgICAgQEFwaUJvZHkoe1xuICAgICAgICBkZXNjcmlwdGlvbjogYFBheWxvYWQgZm9yIHJlcGxhY2UgYSBleGlzdGluZyByZWNvcmQgb2YgJHttb2RlbENsYXp6TmFtZX1gLFxuICAgICAgICBzY2hlbWE6IHsgJHJlZjogZ2V0U2NoZW1hUGF0aChNb2RlbENsYXp6KSB9LFxuICAgICAgfSlcbiAgICAgIEBBcGlPa1Jlc3BvbnNlKHtcbiAgICAgICAgZGVzY3JpcHRpb246IGAke01vZGVsQ2xhenp9IHJlY29yZCByZXBsYWNlZCBzdWNjZXNzZnVsbHkuYCxcbiAgICAgIH0pXG4gICAgICBAQXBpTm90Rm91bmRSZXNwb25zZSh7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBgTm8gJHttb2RlbENsYXp6TmFtZX0gcmVjb3JkIG1hdGNoZXMgdGhlIHByb3ZpZGVkIGlkZW50aWZpZXIuYCxcbiAgICAgIH0pXG4gICAgICBAQXBpQmFkUmVxdWVzdFJlc3BvbnNlKHsgZGVzY3JpcHRpb246IFwiUGF5bG9hZCB2YWxpZGF0aW9uIGZhaWxlZC5cIiB9KVxuICAgICAgYXN5bmMgdXBkYXRlKEBCb2R5KCkgZGF0YTogTW9kZWw8YW55Pikge1xuICAgICAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy51cGRhdGUpO1xuICAgICAgICBsZXQgdXBkYXRlZDogTW9kZWw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbG9nLmluZm8oXG4gICAgICAgICAgICBgdXBkYXRpbmcgJHttb2RlbENsYXp6TmFtZX0gd2l0aCAke3RoaXMucGt9ICR7ZGF0YVt0aGlzLnBrXX1gXG4gICAgICAgICAgKTtcbiAgICAgICAgICB1cGRhdGVkID0gYXdhaXQgdGhpcy5yZXBvLmNyZWF0ZShkYXRhKTtcbiAgICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHVwZGF0ZWQ7XG4gICAgICB9XG5cbiAgICAgIEBEZWxldGUoXCI6aWRcIilcbiAgICAgIEBBcGlPcGVyYXRpb24oeyBzdW1tYXJ5OiBgRGVsZXRlIGEgJHttb2RlbENsYXp6TmFtZX0gcmVjb3JkIGJ5IGlkLmAgfSlcbiAgICAgIEBBcGlQYXJhbSh7XG4gICAgICAgIG5hbWU6IFwiaWRcIixcbiAgICAgICAgZGVzY3JpcHRpb246IGBQcmltYXJ5IGtleSB2YWx1ZSBvZiB0aGUgJHttb2RlbENsYXp6TmFtZX0gcmVjb3JkIHRvIGRlbGV0ZS5gLFxuICAgICAgfSlcbiAgICAgIEBBcGlPa1Jlc3BvbnNlKHtcbiAgICAgICAgZGVzY3JpcHRpb246IGAke21vZGVsQ2xhenpOYW1lfSByZWNvcmQgZGVsZXRlZCBzdWNjZXNzZnVsbHkuYCxcbiAgICAgIH0pXG4gICAgICBAQXBpTm90Rm91bmRSZXNwb25zZSh7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBgTm8gJHttb2RlbENsYXp6TmFtZX0gcmVjb3JkIG1hdGNoZXMgdGhlIHByb3ZpZGVkIGlkZW50aWZpZXIuYCxcbiAgICAgIH0pXG4gICAgICBhc3luYyBkZWxldGUoQFBhcmFtKFwiaWRcIikgaWQ6IHN0cmluZykge1xuICAgICAgICBjb25zdCBsb2cgPSB0aGlzLmxvZy5mb3IodGhpcy5kZWxldGUpO1xuICAgICAgICBsZXQgcmVhZDogTW9kZWw7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgbG9nLmRlYnVnKFxuICAgICAgICAgICAgYGRlbGV0aW5nICR7bW9kZWxDbGF6ek5hbWV9IHdpdGggJHt0aGlzLnBrIGFzIHN0cmluZ30gJHtpZH1gXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZWFkID0gYXdhaXQgdGhpcy5yZXBvLnJlYWQoaWQpO1xuICAgICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgICAgbG9nLmVycm9yKFxuICAgICAgICAgICAgYEZhaWxlZCB0byBkZWxldGUgJHttb2RlbENsYXp6TmFtZX0gd2l0aCBpZCAke2lkfWAsXG4gICAgICAgICAgICBlIGFzIEVycm9yXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGxvZy5pbmZvKGBkZWxldGVkICR7bW9kZWxDbGF6ek5hbWV9IHdpdGggaWQgJHtyZWFkW3RoaXMucGtdfWApO1xuICAgICAgICByZXR1cm4gcmVhZDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gRHluYW1pY01vZGVsQ29udHJvbGxlcjtcbiAgfVxuXG4gIHN0YXRpYyBmb3JSb290KGZsYXZvdXI6IHN0cmluZyk6IER5bmFtaWNNb2R1bGUge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nLmZvcih0aGlzLmZvclJvb3QpO1xuICAgIGxvZy5pbmZvKGBHZW5lcmF0aW5nIGNvbnRyb2xsZXJzIGZvciBmbGF2b3VyLi4uYCk7XG5cbiAgICBjb25zdCB0cmFja2VkTW9kZWxzID0gQWRhcHRlci5tb2RlbHMoZmxhdm91cik7XG4gICAgY29uc3QgY29udHJvbGxlcnMgPSB0cmFja2VkTW9kZWxzLm1hcCh0aGlzLnRvTW9kZWxDb250cm9sbGVyLmJpbmQodGhpcykpO1xuXG4gICAgbG9nLmluZm8oYEdlbmVyYXRlZCAke2NvbnRyb2xsZXJzLmxlbmd0aH0gY29udHJvbGxlcnNgKTtcblxuICAgIHJldHVybiB7XG4gICAgICBtb2R1bGU6IERlY2FmTW9kZWxNb2R1bGUsXG4gICAgICBjb250cm9sbGVycyxcbiAgICAgIHByb3ZpZGVyczogW1JlcG9GYWN0b3J5XSxcbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQgeyBEeW5hbWljTW9kdWxlLCBGb3J3YXJkUmVmZXJlbmNlLCBNb2R1bGUsIFR5cGUgfSBmcm9tIFwiQG5lc3Rqcy9jb21tb25cIjtcbmltcG9ydCB7IERlY2FmTW9kdWxlT3B0aW9ucyB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBEZWNhZkNvcmVNb2R1bGUgfSBmcm9tIFwiLi9jb3JlLW1vZHVsZVwiO1xuaW1wb3J0IHsgRGVjYWZNb2RlbE1vZHVsZSB9IGZyb20gXCIuL21vZGVsLW1vZHVsZVwiO1xuXG4vKipcbiAqIEBwdWJsaWNBcGlcbiAqL1xuQE1vZHVsZSh7fSlcbmV4cG9ydCBjbGFzcyBEZWNhZk1vZHVsZSB7XG4gIHN0YXRpYyBhc3luYyBmb3JSb290QXN5bmMoXG4gICAgb3B0aW9uczogRGVjYWZNb2R1bGVPcHRpb25zXG4gICk6IFByb21pc2U8RHluYW1pY01vZHVsZT4ge1xuICAgIGNvbnN0IHsgYXV0b0NvbnRyb2xsZXJzIH0gPSBvcHRpb25zO1xuXG4gICAgY29uc3QgYWRhcHRlciA9IGF3YWl0IERlY2FmQ29yZU1vZHVsZS5jcmVhdGVBZGFwdGVyKG9wdGlvbnMpO1xuICAgIGNvbnN0IGZsYXZvdXIgPSBhZGFwdGVyLmZsYXZvdXI7XG5cbiAgICBjb25zdCBpbXBvcnRzOlxuICAgICAgfCAoXG4gICAgICAgICAgfCBEeW5hbWljTW9kdWxlXG4gICAgICAgICAgfCBUeXBlPGFueT5cbiAgICAgICAgICB8IFByb21pc2U8RHluYW1pY01vZHVsZT5cbiAgICAgICAgICB8IEZvcndhcmRSZWZlcmVuY2U8YW55PlxuICAgICAgICApW11cbiAgICAgIHwgdW5kZWZpbmVkID0gW0RlY2FmQ29yZU1vZHVsZS5mb3JSb290KG9wdGlvbnMpXTtcblxuICAgIGlmIChhdXRvQ29udHJvbGxlcnMpIHtcbiAgICAgIGltcG9ydHMucHVzaChEZWNhZk1vZGVsTW9kdWxlLmZvclJvb3QoZmxhdm91cikpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBtb2R1bGU6IERlY2FmTW9kdWxlLFxuICAgICAgaW1wb3J0czogaW1wb3J0cyxcbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQge01vZGVsfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQge0ludGVybmFsRXJyb3J9IGZyb20gXCJAZGVjYWYtdHMvZGItZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHtSZXBvc2l0b3J5fSBmcm9tIFwiQGRlY2FmLXRzL2NvcmVcIjtcblxuZXhwb3J0IGZ1bmN0aW9uIHJlcG9Gb3JNb2RlbChtb2RlbDogc3RyaW5nKSB7XG5cdGNvbnN0IG0gPSBNb2RlbC5nZXQobW9kZWwpO1xuXHRpZiAoIW0pXG5cdFx0dGhyb3cgbmV3IEludGVybmFsRXJyb3IoYEZhaWxlZCB0byBmaW5kIHJlcG9zaXRvcnkgZm9yICR7bW9kZWx9YClcblx0Y29uc3QgcmVwbyA9IFJlcG9zaXRvcnkuZm9yTW9kZWwobSk7XG5cdHJldHVybiByZXBvO1xufSIsImltcG9ydCB7Q29ubmVjdGlvbkVycm9yLCBGb3JiaWRkZW5FcnJvcn0gZnJvbSBcIkBkZWNhZi10cy9jb3JlXCI7XG5cbmV4cG9ydCBjbGFzcyBDb3JzRXJyb3IgZXh0ZW5kcyBGb3JiaWRkZW5FcnJvciB7XG5cdGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcblx0XHRzdXBlcihtc2csIENvcnNFcnJvci5uYW1lKTtcblx0fVxufSIsImltcG9ydCB7IFJlcXVlc3QgfSBmcm9tIFwiZXhwcmVzc1wiO1xuaW1wb3J0IHsgSHR0cFN0YXR1cyB9IGZyb20gXCJAbmVzdGpzL2NvbW1vblwiO1xuXG5leHBvcnQgY2xhc3MgSHR0cFJlc3BvbnNlRXJyb3Ige1xuXHRzdGF0dXMhOiBudW1iZXI7XG5cdGVycm9yITogc3RyaW5nO1xuXHRtZXNzYWdlITogc3RyaW5nO1xuXHR0aW1lc3RhbXAhOiBzdHJpbmc7XG5cdHBhdGghOiBzdHJpbmc7XG5cdG1ldGhvZCE6IHN0cmluZztcblxuXHRjb25zdHJ1Y3Rvcihcblx0XHRyZXF1ZXN0OiBSZXF1ZXN0LFxuXHRcdHJlc3BvbnNlRXJyb3I/OiB7IHN0YXR1cz86IG51bWJlcjsgbWVzc2FnZT86IHN0cmluZzsgZXJyb3I/OiBzdHJpbmcgfVxuXHQpIHtcblx0XHRjb25zdCBzdGF0dXMgPSByZXNwb25zZUVycm9yPy5zdGF0dXMgPz8gSHR0cFN0YXR1cy5JTlRFUk5BTF9TRVJWRVJfRVJST1I7XG5cdFx0Y29uc3QgbWVzc2FnZSA9IHJlc3BvbnNlRXJyb3I/Lm1lc3NhZ2UgPz8gXCJJbnRlcm5hbCBTZXJ2ZXIgRXJyb3JcIjtcblx0XHRjb25zdCBlcnJvciA9IChyZXNwb25zZUVycm9yPy5lcnJvciA/PyBIdHRwU3RhdHVzW3N0YXR1c10gPz8gXCJIVFRQX0VYQ0VQVElPTlwiKVxuXHRcdFx0LnRvU3RyaW5nKClcblx0XHRcdC50b1VwcGVyQ2FzZSgpO1xuXG5cdFx0T2JqZWN0LmFzc2lnbih0aGlzLCB7XG5cdFx0XHRzdGF0dXMsXG5cdFx0XHRtZXNzYWdlLFxuXHRcdFx0ZXJyb3IsXG5cdFx0XHR0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcblx0XHRcdHBhdGg6IHJlcXVlc3QudXJsLFxuXHRcdFx0bWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcblx0XHR9KTtcblx0fVxufVxuIiwiaW1wb3J0IHtBcmd1bWVudHNIb3N0LCBDYXRjaCwgRXhjZXB0aW9uRmlsdGVyLCBIdHRwU3RhdHVzfSBmcm9tIFwiQG5lc3Rqcy9jb21tb25cIjtcbmltcG9ydCB7UmVxdWVzdCwgUmVzcG9uc2V9IGZyb20gXCJleHByZXNzXCI7XG5pbXBvcnQge0h0dHBSZXNwb25zZUVycm9yfSBmcm9tIFwiLi9IdHRwUmVzcG9uc2VFcnJvclwiO1xuXG5leHBvcnQgY2xhc3MgQXV0aG9yaXphdGlvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIHJlYWRvbmx5IHN0YXR1czogbnVtYmVyO1xuICAgIHJlYWRvbmx5IGNvZGU6IHN0cmluZztcblxuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSBcIlVuYXV0aG9yaXplZFwiKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkF1dGhvcml6YXRpb25FcnJvclwiO1xuICAgICAgICB0aGlzLnN0YXR1cyA9IDQwMTtcbiAgICAgICAgdGhpcy5jb2RlID0gXCJVTkFVVEhPUklaRURcIjtcbiAgICAgICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIEF1dGhvcml6YXRpb25FcnJvci5wcm90b3R5cGUpO1xuICAgIH1cbn1cblxuQENhdGNoKEF1dGhvcml6YXRpb25FcnJvcilcbmV4cG9ydCBjbGFzcyBBdXRob3JpemF0aW9uRXhjZXB0aW9uRmlsdGVyIGltcGxlbWVudHMgRXhjZXB0aW9uRmlsdGVyIHtcbiAgICBjYXRjaChleGNlcHRpb246IEF1dGhvcml6YXRpb25FcnJvciwgaG9zdDogQXJndW1lbnRzSG9zdCkge1xuICAgICAgICBjb25zdCBjdHggPSBob3N0LnN3aXRjaFRvSHR0cCgpO1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gY3R4LmdldFJlcXVlc3Q8UmVxdWVzdD4oKTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBjdHguZ2V0UmVzcG9uc2U8UmVzcG9uc2U+KCk7XG5cbiAgICAgICAgY29uc3QgaHR0cFJlc3BvbnNlRXJyb3IgPSBuZXcgSHR0cFJlc3BvbnNlRXJyb3IocmVxdWVzdCwge1xuICAgICAgICAgICAgZXJyb3I6IFwiVU5BVVRIT1JJWkVEXCIsXG4gICAgICAgICAgICBzdGF0dXM6IEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELFxuICAgICAgICAgICAgbWVzc2FnZTogZXhjZXB0aW9uLm1lc3NhZ2UsXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJlc3BvbnNlLnN0YXR1cyhIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCkuanNvbihodHRwUmVzcG9uc2VFcnJvcik7XG4gICAgfVxufVxuIiwiaW1wb3J0IHtBcmd1bWVudHNIb3N0LCBDYXRjaCwgRXhjZXB0aW9uRmlsdGVyLCBIdHRwU3RhdHVzfSBmcm9tIFwiQG5lc3Rqcy9jb21tb25cIjtcbmltcG9ydCB7UmVxdWVzdCwgUmVzcG9uc2V9IGZyb20gXCJleHByZXNzXCI7XG5pbXBvcnQge0h0dHBSZXNwb25zZUVycm9yfSBmcm9tIFwiLi9IdHRwUmVzcG9uc2VFcnJvclwiO1xuXG5leHBvcnQgY2xhc3MgQ29uZmxpY3RFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgICByZWFkb25seSBzdGF0dXM6IG51bWJlcjtcbiAgICByZWFkb25seSBjb2RlOiBzdHJpbmc7XG5cbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlID0gXCJDb25mbGljdFwiKSB7XG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgICB0aGlzLm5hbWUgPSBcIkNvbmZsaWN0RXJyb3JcIjtcbiAgICAgICAgdGhpcy5zdGF0dXMgPSA0MDk7XG4gICAgICAgIHRoaXMuY29kZSA9IFwiQ09ORkxJQ1RcIjtcblxuICAgICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgQ29uZmxpY3RFcnJvci5wcm90b3R5cGUpO1xuICAgIH1cbn1cblxuQENhdGNoKENvbmZsaWN0RXJyb3IpXG5leHBvcnQgY2xhc3MgQ29uZmxpY3RFeGNlcHRpb25GaWx0ZXIgaW1wbGVtZW50cyBFeGNlcHRpb25GaWx0ZXIge1xuICAgIGNhdGNoKGV4Y2VwdGlvbjogQ29uZmxpY3RFcnJvciwgaG9zdDogQXJndW1lbnRzSG9zdCkge1xuICAgICAgICBjb25zdCBjdHggPSBob3N0LnN3aXRjaFRvSHR0cCgpO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGN0eC5nZXRSZXNwb25zZTxSZXNwb25zZT4oKTtcbiAgICAgICAgY29uc3QgcmVxdWVzdCA9IGN0eC5nZXRSZXF1ZXN0PFJlcXVlc3Q+KCk7XG5cbiAgICAgICAgY29uc3QgaHR0cFJlc3BvbnNlRXJyb3IgPSBuZXcgSHR0cFJlc3BvbnNlRXJyb3IocmVxdWVzdCwge1xuICAgICAgICAgICAgc3RhdHVzOiBIdHRwU3RhdHVzLkNPTkZMSUNULFxuICAgICAgICAgICAgbWVzc2FnZTogZXhjZXB0aW9uLm1lc3NhZ2UsXG4gICAgICAgICAgICBlcnJvcjogXCJDT05GTElDVFwiXG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJlc3BvbnNlLnN0YXR1cyhodHRwUmVzcG9uc2VFcnJvci5zdGF0dXMpLmpzb24oaHR0cFJlc3BvbnNlRXJyb3IpO1xuICAgIH1cbn1cbiIsImltcG9ydCB7QXJndW1lbnRzSG9zdCwgQ2F0Y2gsIEV4Y2VwdGlvbkZpbHRlciwgSHR0cEV4Y2VwdGlvbiwgSHR0cFN0YXR1c30gZnJvbSBcIkBuZXN0anMvY29tbW9uXCI7XG5pbXBvcnQge1JlcXVlc3QsIFJlc3BvbnNlfSBmcm9tIFwiZXhwcmVzc1wiO1xuaW1wb3J0IHtIdHRwUmVzcG9uc2VFcnJvcn0gZnJvbSBcIi4vSHR0cFJlc3BvbnNlRXJyb3JcIjtcblxuQENhdGNoKClcbmV4cG9ydCBjbGFzcyBHbG9iYWxFeGNlcHRpb25GaWx0ZXIgaW1wbGVtZW50cyBFeGNlcHRpb25GaWx0ZXIge1xuICAgIGNhdGNoKGV4Y2VwdGlvbjogdW5rbm93biwgaG9zdDogQXJndW1lbnRzSG9zdCkge1xuICAgICAgICBjb25zdCBjdHggPSBob3N0LnN3aXRjaFRvSHR0cCgpO1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gY3R4LmdldFJlcXVlc3Q8UmVxdWVzdD4oKTtcbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSBjdHguZ2V0UmVzcG9uc2U8UmVzcG9uc2U+KCk7XG5cbiAgICAgICAgbGV0IHN0YXR1cyA9IEh0dHBTdGF0dXMuSU5URVJOQUxfU0VSVkVSX0VSUk9SO1xuICAgICAgICBsZXQgbWVzc2FnZSA9IFwiSW50ZXJuYWwgU2VydmVyIEVycm9yXCI7XG4gICAgICAgIGxldCBlcnJvcjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgICAgIGlmIChleGNlcHRpb24gaW5zdGFuY2VvZiBIdHRwRXhjZXB0aW9uKSB7XG4gICAgICAgICAgICBjb25zdCByZXM6IGFueSA9IGV4Y2VwdGlvbi5nZXRSZXNwb25zZSgpO1xuICAgICAgICAgICAgc3RhdHVzID0gZXhjZXB0aW9uLmdldFN0YXR1cygpO1xuICAgICAgICAgICAgbWVzc2FnZSA9IChyZXM/Lm1lc3NhZ2UgfHwgZXhjZXB0aW9uLm1lc3NhZ2UpID8/IG1lc3NhZ2U7XG4gICAgICAgICAgICBlcnJvciA9IHJlcz8uZXJyb3IgPz8gZXhjZXB0aW9uLm5hbWU7XG4gICAgICAgIH0gZWxzZSBpZiAoZXhjZXB0aW9uIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgICAgICAgIG1lc3NhZ2UgPSBleGNlcHRpb24ubWVzc2FnZTtcbiAgICAgICAgICAgIGVycm9yID0gZXhjZXB0aW9uLm5hbWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBodHRwUmVzcG9uc2VFcnJvciA9IG5ldyBIdHRwUmVzcG9uc2VFcnJvcihyZXF1ZXN0LCB7c3RhdHVzLCBtZXNzYWdlLCBlcnJvcn0pO1xuICAgICAgICByZXNwb25zZS5zdGF0dXMoaHR0cFJlc3BvbnNlRXJyb3Iuc3RhdHVzKS5qc29uKGh0dHBSZXNwb25zZUVycm9yKTtcbiAgICB9XG59XG4iLCJpbXBvcnQge0FyZ3VtZW50c0hvc3QsIENhdGNoLCBFeGNlcHRpb25GaWx0ZXIsIEh0dHBFeGNlcHRpb259IGZyb20gXCJAbmVzdGpzL2NvbW1vblwiO1xuaW1wb3J0IHtSZXF1ZXN0LCBSZXNwb25zZX0gZnJvbSBcImV4cHJlc3NcIjtcbmltcG9ydCB7SHR0cFJlc3BvbnNlRXJyb3J9IGZyb20gXCIuL0h0dHBSZXNwb25zZUVycm9yXCI7XG5cbkBDYXRjaChIdHRwRXhjZXB0aW9uKVxuZXhwb3J0IGNsYXNzIEh0dHBFeGNlcHRpb25GaWx0ZXIgaW1wbGVtZW50cyBFeGNlcHRpb25GaWx0ZXIge1xuICAgIGNhdGNoKGV4Y2VwdGlvbjogSHR0cEV4Y2VwdGlvbiwgaG9zdDogQXJndW1lbnRzSG9zdCkge1xuICAgICAgICBjb25zdCBjdHggPSBob3N0LnN3aXRjaFRvSHR0cCgpO1xuICAgICAgICBjb25zdCByZXNwb25zZSA9IGN0eC5nZXRSZXNwb25zZTxSZXNwb25zZT4oKTtcbiAgICAgICAgY29uc3QgcmVxdWVzdCA9IGN0eC5nZXRSZXF1ZXN0PFJlcXVlc3Q+KCk7XG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IGV4Y2VwdGlvbi5nZXRTdGF0dXMoKTtcblxuICAgICAgICBjb25zdCBodHRwUmVzcG9uc2VFcnJvciA9IG5ldyBIdHRwUmVzcG9uc2VFcnJvcihyZXF1ZXN0LCB7XG4gICAgICAgICAgICBzdGF0dXMsXG4gICAgICAgICAgICBtZXNzYWdlOiBleGNlcHRpb24ubWVzc2FnZSxcbiAgICAgICAgICAgIGVycm9yOiBleGNlcHRpb24ubmFtZVxuICAgICAgICB9KTtcblxuICAgICAgICByZXNwb25zZS5zdGF0dXMoaHR0cFJlc3BvbnNlRXJyb3Iuc3RhdHVzKS5qc29uKGh0dHBSZXNwb25zZUVycm9yKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBBcmd1bWVudHNIb3N0LCBDYXRjaCwgRXhjZXB0aW9uRmlsdGVyLCBIdHRwU3RhdHVzIH0gZnJvbSBcIkBuZXN0anMvY29tbW9uXCI7XG5pbXBvcnQgeyBSZXF1ZXN0LCBSZXNwb25zZSB9IGZyb20gXCJleHByZXNzXCI7XG5pbXBvcnQgeyBIdHRwUmVzcG9uc2VFcnJvciB9IGZyb20gXCIuL0h0dHBSZXNwb25zZUVycm9yXCI7XG5cbmV4cG9ydCBjbGFzcyBOb3RGb3VuZEVycm9yIGV4dGVuZHMgRXJyb3Ige1xuXHRyZWFkb25seSBzdGF0dXM6IG51bWJlcjtcblx0cmVhZG9ubHkgY29kZTogc3RyaW5nO1xuXG5cdGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSBcIlJlc291cmNlIG5vdCBmb3VuZFwiKSB7XG5cdFx0c3VwZXIobWVzc2FnZSk7XG5cdFx0dGhpcy5uYW1lID0gXCJOb3RGb3VuZEVycm9yXCI7XG5cdFx0dGhpcy5zdGF0dXMgPSA0MDQ7XG5cdFx0dGhpcy5jb2RlID0gXCJOT1RfRk9VTkRcIjtcblxuXHRcdE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBOb3RGb3VuZEVycm9yLnByb3RvdHlwZSk7XG5cdH1cbn1cblxuQENhdGNoKE5vdEZvdW5kRXJyb3IpXG5leHBvcnQgY2xhc3MgTm90Rm91bmRFeGNlcHRpb25GaWx0ZXIgaW1wbGVtZW50cyBFeGNlcHRpb25GaWx0ZXIge1xuXHRjYXRjaChleGNlcHRpb246IE5vdEZvdW5kRXJyb3IsIGhvc3Q6IEFyZ3VtZW50c0hvc3QpIHtcblx0XHRjb25zdCBjdHggPSBob3N0LnN3aXRjaFRvSHR0cCgpO1xuXHRcdGNvbnN0IHJlc3BvbnNlID0gY3R4LmdldFJlc3BvbnNlPFJlc3BvbnNlPigpO1xuXHRcdGNvbnN0IHJlcXVlc3QgPSBjdHguZ2V0UmVxdWVzdDxSZXF1ZXN0PigpO1xuXG5cdFx0Y29uc3QgaHR0cFJlc3BvbnNlRXJyb3IgPSBuZXcgSHR0cFJlc3BvbnNlRXJyb3IocmVxdWVzdCwge1xuXHRcdFx0c3RhdHVzOiBIdHRwU3RhdHVzLk5PVF9GT1VORCxcblx0XHRcdG1lc3NhZ2U6IGV4Y2VwdGlvbi5tZXNzYWdlLFxuXHRcdFx0ZXJyb3I6IFwiTk9UX0ZPVU5EXCIsXG5cdFx0fSk7XG5cblx0XHRyZXNwb25zZS5zdGF0dXMoaHR0cFJlc3BvbnNlRXJyb3Iuc3RhdHVzKS5qc29uKGh0dHBSZXNwb25zZUVycm9yKTtcblx0fVxufVxuIiwiaW1wb3J0IHtBcmd1bWVudHNIb3N0LCBDYXRjaCwgRXhjZXB0aW9uRmlsdGVyLCBIdHRwU3RhdHVzfSBmcm9tIFwiQG5lc3Rqcy9jb21tb25cIjtcbmltcG9ydCB7UmVxdWVzdCwgUmVzcG9uc2V9IGZyb20gXCJleHByZXNzXCI7XG5pbXBvcnQge0h0dHBSZXNwb25zZUVycm9yfSBmcm9tIFwiLi9IdHRwUmVzcG9uc2VFcnJvclwiO1xuXG5leHBvcnQgY2xhc3MgVmFsaWRhdGlvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICAgIHJlYWRvbmx5IHN0YXR1czogbnVtYmVyO1xuICAgIHJlYWRvbmx5IGNvZGU6IHN0cmluZztcblxuICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UgPSBcIlZhbGlkYXRpb24gZmFpbGVkXCIpIHtcbiAgICAgICAgc3VwZXIobWVzc2FnZSk7XG4gICAgICAgIHRoaXMubmFtZSA9IFwiVmFsaWRhdGlvbkVycm9yXCI7XG4gICAgICAgIHRoaXMuc3RhdHVzID0gNDIyO1xuICAgICAgICB0aGlzLmNvZGUgPSBcIlZBTElEQVRJT05fRVJST1JcIjtcblxuICAgICAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgVmFsaWRhdGlvbkVycm9yLnByb3RvdHlwZSk7XG4gICAgfVxufVxuXG5AQ2F0Y2goVmFsaWRhdGlvbkVycm9yKVxuZXhwb3J0IGNsYXNzIFZhbGlkYXRpb25FeGNlcHRpb25GaWx0ZXIgaW1wbGVtZW50cyBFeGNlcHRpb25GaWx0ZXIge1xuICAgIGNhdGNoKGV4Y2VwdGlvbjogVmFsaWRhdGlvbkVycm9yLCBob3N0OiBBcmd1bWVudHNIb3N0KSB7XG4gICAgICAgIGNvbnN0IGN0eCA9IGhvc3Quc3dpdGNoVG9IdHRwKCk7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gY3R4LmdldFJlc3BvbnNlPFJlc3BvbnNlPigpO1xuICAgICAgICBjb25zdCByZXF1ZXN0ID0gY3R4LmdldFJlcXVlc3Q8UmVxdWVzdD4oKTtcblxuICAgICAgICBjb25zdCBodHRwUmVzcG9uc2VFcnJvciA9IG5ldyBIdHRwUmVzcG9uc2VFcnJvcihyZXF1ZXN0LCB7XG4gICAgICAgICAgICBzdGF0dXM6IEh0dHBTdGF0dXMuVU5QUk9DRVNTQUJMRV9FTlRJVFksXG4gICAgICAgICAgICBtZXNzYWdlOiBleGNlcHRpb24ubWVzc2FnZSxcbiAgICAgICAgICAgIGVycm9yOiBcIlZBTElEQVRJT05fRVJST1JcIlxuICAgICAgICB9KTtcblxuICAgICAgICByZXNwb25zZS5zdGF0dXMoaHR0cFJlc3BvbnNlRXJyb3Iuc3RhdHVzKS5qc29uKGh0dHBSZXNwb25zZUVycm9yKTtcbiAgICB9XG59XG4iLCJpbXBvcnQgeyBTZWN1cml0eVNjaGVtZU9iamVjdCB9IGZyb20gXCJAbmVzdGpzL3N3YWdnZXIvZGlzdC9pbnRlcmZhY2VzL29wZW4tYXBpLXNwZWMuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdGlvblwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN3YWdnZXJPcHRpb25zIHtcbiAgdGl0bGU6IHN0cmluZztcbiAgZGVzY3JpcHRpb246IHN0cmluZztcbiAgdmVyc2lvbj86IHN0cmluZztcbiAgYXNzZXRzUGF0aD86IHN0cmluZztcbiAgZmF2aWNvbkZpbGVQYXRoPzogc3RyaW5nO1xuICB0b3BiYXJJY29uRmlsZVBhdGg/OiBzdHJpbmc7XG4gIHBlcnNpc3RBdXRob3JpemF0aW9uPzogYm9vbGVhbjtcbiAgcGF0aDogc3RyaW5nO1xuICBhdXRoPzogU2VjdXJpdHlTY2hlbWVPYmplY3Q7XG4gIHRvcGJhckJnQ29sb3I/OiBzdHJpbmc7XG4gIGV4dHJhTW9kZWxzPzogQ29uc3RydWN0b3JbXTtcbn1cblxuZXhwb3J0IGNvbnN0IFNXQUdHRVJfVUlfQ09OU1RBTlRTOiBTd2FnZ2VyT3B0aW9ucyA9IHtcbiAgdGl0bGU6IFwiU3dhZ2dlciB8IE9wZW5BUEkgU3BlY2lmaWNhdGlvbiAoT0FTKVwiLFxuICBkZXNjcmlwdGlvbjogXCJTdGFuZGFyZGl6ZWQgZm9ybWF0IGZvciBkZXNjcmliaW5nIFJFU1RmdWwgQVBJc1wiLFxuICB2ZXJzaW9uOiBcIjAuMC4xXCIsXG4gIHBhdGg6IFwiZG9jc1wiLFxuICBmYXZpY29uRmlsZVBhdGg6IFwiXCIsXG4gIHRvcGJhckljb25GaWxlUGF0aDogXCJcIixcbiAgYXV0aDoge1xuICAgIHR5cGU6IFwiaHR0cFwiLFxuICAgIHNjaGVtZTogXCJiZWFyZXJcIixcbiAgICBiZWFyZXJGb3JtYXQ6IFwiSldUXCIsXG4gICAgbmFtZTogXCJBdXRob3JpemF0aW9uXCIsXG4gICAgZGVzY3JpcHRpb246IFwiRW50ZXIgSldUIHRva2VuXCIsXG4gICAgaW46IFwiaGVhZGVyXCIsXG4gIH0sXG4gIHBlcnNpc3RBdXRob3JpemF0aW9uOiB0cnVlLFxuICB0b3BiYXJCZ0NvbG9yOiBcIiMwMDAwMDBcIixcbn07XG4iLCJpbXBvcnQgeyBTV0FHR0VSX1VJX0NPTlNUQU5UUyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgcmVhZEZpbGVTeW5jIH0gZnJvbSBcImZzXCI7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3dhZ2dlclVJT3B0aW9ucyB7XG4gIHRpdGxlPzogc3RyaW5nO1xuICBwYXRoPzogc3RyaW5nO1xuICBwZXJzaXN0QXV0aG9yaXphdGlvbjogYm9vbGVhbjtcbiAgYXNzZXRzUGF0aD86IHN0cmluZztcbiAgZmF2aWNvblBhdGg/OiBzdHJpbmc7XG4gIHRvcGJhckljb25QYXRoPzogc3RyaW5nO1xuICB0b3BiYXJCZ0NvbG9yPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgU3dhZ2dlckN1c3RvbVVJIHtcbiAgcmVhZG9ubHkgb3B0aW9uczogU3dhZ2dlclVJT3B0aW9ucztcbiAgLy8gcHJpdmF0ZSByZWFkb25seSBhc3NldHNQYXRoOiBzdHJpbmcgPSBwYXRoLmpvaW4oXG4gIC8vICAgX19kaXJuYW1lLFxuICAvLyAgIFwiLi5cIixcbiAgLy8gICBcIi4uXCIsXG4gIC8vICAgXCJ3b3JrZG9jc1wiLFxuICAvLyAgIFwiYXNzZXRzXCJcbiAgLy8gKTtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBTd2FnZ2VyVUlPcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBjdXN0b21DU1MoKSB7XG4gICAgbGV0IGNzcyA9IFwiXCI7XG4gICAgaWYgKHRoaXMub3B0aW9ucy50b3BiYXJJY29uUGF0aCkge1xuICAgICAgY29uc3QgaW1nID0gdGhpcy5iNjQodGhpcy5vcHRpb25zLnRvcGJhckljb25QYXRoKTtcbiAgICAgIGNzcyArPSBgLnRvcGJhci13cmFwcGVyIHsgY29udGVudDogdXJsKCdkYXRhOmltYWdlL3BuZztiYXNlNjQsJHtpbWd9Jyk7IHdpZHRoOiAyMDBweDsgaGVpZ2h0OiBhdXRvOyB9XFxuYDtcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIGNzcyArXG4gICAgICBgXG4gICAgICAgIC50b3BiYXItd3JhcHBlciBzdmcgeyB2aXNpYmlsaXR5OiBoaWRkZW47IH1cbiAgICAgICAgLnN3YWdnZXItdWkgLnRvcGJhciB7IGJhY2tncm91bmQtY29sb3I6ICR7dGhpcy5vcHRpb25zLnRvcGJhckJnQ29sb3IgfHwgU1dBR0dFUl9VSV9DT05TVEFOVFMudG9wYmFyQmdDb2xvcn07IH1cbiAgICAgIGBcbiAgICApO1xuICB9XG5cbiAgZ2V0Q3VzdG9tT3B0aW9ucygpIHtcbiAgICBjb25zdCBmYXZpY29uOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgaWYgKHRoaXMub3B0aW9ucy5mYXZpY29uUGF0aCkge1xuICAgICAgZmF2aWNvbltcImN1c3RvbWZhdkljb25cIl0gPSB0aGlzLmI2NCh0aGlzLm9wdGlvbnMuZmF2aWNvblBhdGgsIHRydWUpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBjdXN0b21TaXRlVGl0bGU6IHRoaXMub3B0aW9ucy50aXRsZSxcbiAgICAgIC4uLmZhdmljb24sXG4gICAgICBjdXN0b21Dc3M6IHRoaXMuY3VzdG9tQ1NTKCksXG4gICAgICBzd2FnZ2VyT3B0aW9uczoge1xuICAgICAgICBwZXJzaXN0QXV0aG9yaXphdGlvbjogdGhpcy5vcHRpb25zLnBlcnNpc3RBdXRob3JpemF0aW9uLFxuICAgICAgfSxcbiAgICAgIGpzb25Eb2N1bWVudFVybDogdGhpcy5vcHRpb25zLnBhdGhcbiAgICAgICAgPyBgJHt0aGlzLm9wdGlvbnMucGF0aH0vc3BlYy5qc29uYFxuICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICAgIHlhbWxEb2N1bWVudFVybDogdGhpcy5vcHRpb25zLnBhdGhcbiAgICAgICAgPyBgJHt0aGlzLm9wdGlvbnMucGF0aH0vc3BlYy55YW1sYFxuICAgICAgICA6IHVuZGVmaW5lZCxcbiAgICB9O1xuICB9XG5cbiAgYjY0KGZpbGU6IHN0cmluZywgaW1nOiBib29sZWFuID0gZmFsc2UpIHtcbiAgICBjb25zdCBmaWxlUGF0aCA9IHBhdGguam9pbih0aGlzLm9wdGlvbnMuYXNzZXRzUGF0aCB8fCBcIlwiLCBmaWxlKTtcbiAgICBjb25zdCBiNjQgPSByZWFkRmlsZVN5bmMoZmlsZVBhdGgsIHsgZW5jb2Rpbmc6IFwiYmFzZTY0XCIgfSk7XG4gICAgcmV0dXJuIGltZyA/IFwiZGF0YTppbWFnZS9wbmc7YmFzZTY0LFwiICsgYjY0IDogYjY0O1xuICB9XG59XG4iLCJpbXBvcnQgeyBJTmVzdEFwcGxpY2F0aW9uIH0gZnJvbSBcIkBuZXN0anMvY29tbW9uXCI7XG5pbXBvcnQgeyBEb2N1bWVudEJ1aWxkZXIsIFN3YWdnZXJNb2R1bGUgfSBmcm9tIFwiQG5lc3Rqcy9zd2FnZ2VyXCI7XG5pbXBvcnQgeyBTd2FnZ2VyQ3VzdG9tVUkgfSBmcm9tIFwiLi9Td2FnZ2VyQ3VzdG9tVUlcIjtcbmltcG9ydCB7IFNXQUdHRVJfVUlfQ09OU1RBTlRTLCBTd2FnZ2VyT3B0aW9ucyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG5leHBvcnQgY2xhc3MgU3dhZ2dlckJ1aWxkZXIge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGFwcDogSU5lc3RBcHBsaWNhdGlvbixcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IFN3YWdnZXJPcHRpb25zXG4gICkge31cblxuICBwcml2YXRlIGNyZWF0ZURvY3VtZW50KCkge1xuICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gdGhpcy5vcHRpb25zLnBhdGhcbiAgICAgID8gdGhpcy5vcHRpb25zLmRlc2NyaXB0aW9uICtcbiAgICAgICAgXCJcIiArXG4gICAgICAgIGA8YnI+PGJyPjxhIGhyZWY9XCIke3RoaXMub3B0aW9ucy5wYXRofS9zcGVjLmpzb25cIj5PcGVuQVBJIEpTT04gU3BlYzwvYT4gfCBgICtcbiAgICAgICAgYDxhIGhyZWY9XCIke3RoaXMub3B0aW9ucy5wYXRofS9zcGVjLnlhbWxcIj5PcGVuQVBJIFlBTUwgU3BlYzwvYT5gXG4gICAgICA6IHRoaXMub3B0aW9ucy5kZXNjcmlwdGlvbjtcblxuICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBEb2N1bWVudEJ1aWxkZXIoKVxuICAgICAgLnNldFRpdGxlKHRoaXMub3B0aW9ucy50aXRsZSlcbiAgICAgIC5zZXREZXNjcmlwdGlvbihkZXNjcmlwdGlvbilcbiAgICAgIC5zZXRWZXJzaW9uKHRoaXMub3B0aW9ucy52ZXJzaW9uIHx8IFwiMC4wLjFcIilcbiAgICAgIC5hZGRCZWFyZXJBdXRoKHRoaXMub3B0aW9ucy5hdXRoIHx8IFNXQUdHRVJfVUlfQ09OU1RBTlRTLmF1dGgpXG4gICAgICAuYnVpbGQoKTtcblxuICAgIHJldHVybiBTd2FnZ2VyTW9kdWxlLmNyZWF0ZURvY3VtZW50KHRoaXMuYXBwLCBjb25maWcsIHtcbiAgICAgIGV4dHJhTW9kZWxzOiB0aGlzLm9wdGlvbnMuZXh0cmFNb2RlbHMgfHwgW10sXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc2V0dXBTd2FnZ2VyKCkge1xuICAgIGNvbnN0IGRvY3VtZW50ID0gdGhpcy5jcmVhdGVEb2N1bWVudCgpO1xuICAgIGNvbnN0IHN3YWdnZXJVSSA9IG5ldyBTd2FnZ2VyQ3VzdG9tVUkoe1xuICAgICAgdGl0bGU6IHRoaXMub3B0aW9ucy50aXRsZSxcbiAgICAgIHBhdGg6IHRoaXMub3B0aW9ucy5wYXRoIHx8IFNXQUdHRVJfVUlfQ09OU1RBTlRTLnBhdGgsXG4gICAgICBwZXJzaXN0QXV0aG9yaXphdGlvbjogdGhpcy5vcHRpb25zLnBlcnNpc3RBdXRob3JpemF0aW9uID8/IHRydWUsXG4gICAgICBhc3NldHNQYXRoOiB0aGlzLm9wdGlvbnMuYXNzZXRzUGF0aCxcbiAgICAgIGZhdmljb25QYXRoOiB0aGlzLm9wdGlvbnMuZmF2aWNvbkZpbGVQYXRoLFxuICAgICAgdG9wYmFySWNvblBhdGg6IHRoaXMub3B0aW9ucy50b3BiYXJJY29uRmlsZVBhdGgsXG4gICAgICB0b3BiYXJCZ0NvbG9yOiB0aGlzLm9wdGlvbnMudG9wYmFyQmdDb2xvcixcbiAgICB9KTtcbiAgICBTd2FnZ2VyTW9kdWxlLnNldHVwKFxuICAgICAgdGhpcy5vcHRpb25zLnBhdGggfHwgU1dBR0dFUl9VSV9DT05TVEFOVFMucGF0aCxcbiAgICAgIHRoaXMuYXBwLFxuICAgICAgZG9jdW1lbnQsXG4gICAgICB7XG4gICAgICAgIC4uLnN3YWdnZXJVSS5nZXRDdXN0b21PcHRpb25zKCksXG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8vIHByaXZhdGUgZ2V0VmVyc2lvbigpIHtcbiAgLy8gICAvLyBjb25zdCBwYWNrYWdlSnNvbiA9IHBhdGguam9pbihfX2Rpcm5hbWUsIFwiLi5cIiwgXCIuLlwiLCBcInBhY2thZ2UuanNvblwiKTtcbiAgLy8gICAvLyBjb25zdCB7dmVyc2lvbn0gPSByZXF1aXJlKHBhY2thZ2VKc29uKTtcbiAgLy8gICByZXR1cm4gXCJ2ZXJzaW9uXCI7XG4gIC8vIH1cbn1cbiIsImltcG9ydCB7XG4gIEV4Y2VwdGlvbkZpbHRlcixcbiAgSU5lc3RBcHBsaWNhdGlvbixcbiAgTG9nZ2VyLFxuICBOZXN0SW50ZXJjZXB0b3IsXG4gIFBpcGVUcmFuc2Zvcm0sXG59IGZyb20gXCJAbmVzdGpzL2NvbW1vblwiO1xuaW1wb3J0IHtcbiAgQXV0aG9yaXphdGlvbkV4Y2VwdGlvbkZpbHRlcixcbiAgQ29uZmxpY3RFeGNlcHRpb25GaWx0ZXIsXG4gIEdsb2JhbEV4Y2VwdGlvbkZpbHRlcixcbiAgSHR0cEV4Y2VwdGlvbkZpbHRlcixcbiAgTm90Rm91bmRFeGNlcHRpb25GaWx0ZXIsXG4gIFZhbGlkYXRpb25FeGNlcHRpb25GaWx0ZXIsXG59IGZyb20gXCIuL2V4Y2VwdGlvbnNcIjtcbmltcG9ydCB7IFN3YWdnZXJCdWlsZGVyIH0gZnJvbSBcIi4vb3BlbmFwaVwiO1xuaW1wb3J0IHsgQ29yc09wdGlvbnMgfSBmcm9tIFwiQG5lc3Rqcy9jb21tb24vaW50ZXJmYWNlcy9leHRlcm5hbC9jb3JzLW9wdGlvbnMuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBDb3JzRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb25cbiAqIERlZmluZXMgYWxsIGN1c3RvbWl6YWJsZSBwYXJhbWV0ZXJzIGZvciBTd2FnZ2VyIHNldHVwLlxuICpcbiAqIEBzdW1tYXJ5XG4gKiBUaGlzIGludGVyZmFjZSBhbGxvd3MgZGV2ZWxvcGVycyB0byBjdXN0b21pemUgaG93IFN3YWdnZXIgVUkgaXMgY29uZmlndXJlZFxuICogd2l0aGluIHRoZSBOZXN0SlMgYXBwbGljYXRpb24uIEl0IGluY2x1ZGVzIHBhcmFtZXRlcnMgZm9yIHRpdGxlcywgcGF0aHMsXG4gKiBjb2xvciBzY2hlbWVzLCBhbmQgYXNzZXQgcGF0aHMgdG8gdGFpbG9yIHRoZSBBUEkgZG9jdW1lbnRhdGlvbiBleHBlcmllbmNlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0aXRsZSAtIFRpdGxlIGRpc3BsYXllZCBpbiBTd2FnZ2VyIFVJLlxuICogQHBhcmFtIHtzdHJpbmd9IGRlc2NyaXB0aW9uIC0gRGVzY3JpcHRpb24gc2hvd24gYmVsb3cgdGhlIHRpdGxlLlxuICogQHBhcmFtIHtzdHJpbmd9IHZlcnNpb24gLSBBUEkgdmVyc2lvbiBkaXNwbGF5ZWQgaW4gdGhlIGRvY3VtZW50YXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gW3BhdGhdIC0gT3B0aW9uYWwgcGF0aCB3aGVyZSBTd2FnZ2VyIHdpbGwgYmUgYXZhaWxhYmxlLlxuICogQHBhcmFtIHtib29sZWFufSBbcGVyc2lzdEF1dGhvcml6YXRpb25dIC0gV2hldGhlciBhdXRob3JpemF0aW9uIHRva2VucyBwZXJzaXN0IGFjcm9zcyByZWxvYWRzLlxuICogQHBhcmFtIHtzdHJpbmd9IFthc3NldHNQYXRoXSAtIFBhdGggdG8gY3VzdG9tIGFzc2V0cyBmb3IgU3dhZ2dlciBVSS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbdG9wYmFyQmdDb2xvcl0gLSBDdXN0b20gYmFja2dyb3VuZCBjb2xvciBmb3IgdGhlIFN3YWdnZXIgdG9wIGJhci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbdG9wYmFySWNvblBhdGhdIC0gUGF0aCB0byBhIGN1c3RvbSBpY29uIGRpc3BsYXllZCBpbiB0aGUgdG9wIGJhci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbZmF2aWNvblBhdGhdIC0gUGF0aCB0byBhIGN1c3RvbSBmYXZpY29uLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN3YWdnZXJTZXR1cE9wdGlvbnMge1xuICB0aXRsZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICB2ZXJzaW9uOiBzdHJpbmc7XG4gIHBhdGg/OiBzdHJpbmc7XG4gIHBlcnNpc3RBdXRob3JpemF0aW9uPzogYm9vbGVhbjtcbiAgYXNzZXRzUGF0aD86IHN0cmluZztcbiAgdG9wYmFyQmdDb2xvcj86IHN0cmluZztcbiAgdG9wYmFySWNvblBhdGg/OiBzdHJpbmc7XG4gIGZhdmljb25QYXRoPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvblxuICogQSBmbHVlbnQsIHN0YXRpYyBib290c3RyYXAgY2xhc3MgZm9yIGluaXRpYWxpemluZyBhbmQgY29uZmlndXJpbmcgYSBOZXN0SlMgYXBwbGljYXRpb24uXG4gKlxuICogQHN1bW1hcnlcbiAqIFRoZSBgTmVzdEJvb3RzdHJhcGVyYCBjbGFzcyBwcm92aWRlcyBhIGNoYWluYWJsZSBBUEkgZm9yIGNvbmZpZ3VyaW5nXG4gKiBhIE5lc3RKUyBhcHBsaWNhdGlvbiBpbnN0YW5jZS4gSXQgaW5jbHVkZXMgYnVpbHQtaW4gbWV0aG9kcyBmb3IgZW5hYmxpbmdcbiAqIENPUlMsIEhlbG1ldCBzZWN1cml0eSwgU3dhZ2dlciBkb2N1bWVudGF0aW9uLCBnbG9iYWwgcGlwZXMsIGZpbHRlcnMsXG4gKiBpbnRlcmNlcHRvcnMsIGFuZCBzdGFydGluZyB0aGUgc2VydmVyLlxuICpcbiAqIFRoaXMgY2xhc3MgcHJvbW90ZXMgY29uc2lzdGVuY3kgYW5kIHJlZHVjZXMgcmVwZXRpdGl2ZSBzZXR1cCBjb2RlXG4gKiBhY3Jvc3MgbXVsdGlwbGUgTmVzdEpTIHByb2plY3RzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgTmVzdEZhY3RvcnkgfSBmcm9tIFwiQG5lc3Rqcy9jb3JlXCI7XG4gKiBpbXBvcnQgeyBBcHBNb2R1bGUgfSBmcm9tIFwiLi9hcHAubW9kdWxlXCI7XG4gKiBpbXBvcnQgeyBNeUxvZ2dlciB9IGZyb20gXCIuL015TG9nZ2VyXCI7XG4gKiBpbXBvcnQgeyBOZXN0Qm9vdHN0cmFwZXIgfSBmcm9tIFwiQGRlY2FmLXRzL2Zvci1uZXN0XCI7XG4gKlxuICogYXN5bmMgZnVuY3Rpb24gYm9vdHN0cmFwKCkge1xuICogICBjb25zdCBhcHAgPSBhd2FpdCBOZXN0RmFjdG9yeS5jcmVhdGUoQXBwTW9kdWxlKTtcbiAqXG4gKiAgIGF3YWl0IE5lc3RCb290c3RyYXBlclxuICogICAgIC5pbml0aWFsaXplKGFwcClcbiAqICAgICAuZW5hYmxlTG9nZ2VyKG5ldyBNeUxvZ2dlcigpKVxuICogICAgIC5lbmFibGVDb3JzKFtcImh0dHA6Ly9sb2NhbGhvc3Q6NDIwMFwiXSlcbiAqICAgICAudXNlSGVsbWV0KClcbiAqICAgICAuc2V0dXBTd2FnZ2VyKHtcbiAqICAgICAgIHRpdGxlOiBcIk9wZW5BUEkgYnkgVHJhZGVNYXJr4oSiXCIsXG4gKiAgICAgICBkZXNjcmlwdGlvbjogXCJUcmFkZU1hcmvihKIgQVBJIGRvY3VtZW50YXRpb25cIixcbiAqICAgICAgIHZlcnNpb246IFwiMS4wLjBcIixcbiAqICAgICAgIHBhdGg6IFwiYXBpXCIsXG4gKiAgICAgICBwZXJzaXN0QXV0aG9yaXphdGlvbjogdHJ1ZSxcbiAqICAgICAgIHRvcGJhckJnQ29sb3I6IFwiIzJDM0U1MFwiLFxuICogICAgICAgdG9wYmFySWNvblBhdGg6IFwiL2Fzc2V0cy9sb2dvLnN2Z1wiLFxuICogICAgICAgZmF2aWNvblBhdGg6IFwiL2Fzc2V0cy9mYXZpY29uLmljb1wiXG4gKiAgICAgfSlcbiAqICAgICAudXNlR2xvYmFsRmlsdGVycygpXG4gKiAgICAgLnVzZUdsb2JhbFBpcGVzKC4uLilcbiAqICAgICAudXNlR2xvYmFsSW50ZXJjZXB0b3JzKC4uLilcbiAqICAgICAuc3RhcnQoMzAwMCk7XG4gKiB9XG4gKlxuICogYm9vdHN0cmFwKCk7XG4gKiBgYGBcbiAqIEBjbGFzc1xuICovXG5leHBvcnQgY2xhc3MgTmVzdEJvb3RzdHJhcGVyIHtcbiAgcHJpdmF0ZSBzdGF0aWMgYXBwOiBJTmVzdEFwcGxpY2F0aW9uO1xuICBwcml2YXRlIHN0YXRpYyBfbG9nZ2VyOiBMb2dnZXI7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IGxvZ2dlciBpbnN0YW5jZSwgY3JlYXRpbmcgYSBkZWZhdWx0IG9uZSBpZiBub3Qgc2V0LlxuICAgKlxuICAgKiBAc3VtbWFyeVxuICAgKiBFbnN1cmVzIHRoYXQgYSB2YWxpZCBgTG9nZ2VyYCBpbnN0YW5jZSBpcyBhbHdheXMgYXZhaWxhYmxlXG4gICAqIGZvciBsb2dnaW5nIGJvb3RzdHJhcC1yZWxhdGVkIG1lc3NhZ2VzLlxuICAgKlxuICAgKiBAcmV0dXJuIHtMb2dnZXJ9IFRoZSBhY3RpdmUgbG9nZ2VyIGluc3RhbmNlLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0IGxvZ2dlcigpOiBMb2dnZXIge1xuICAgIGlmICghdGhpcy5fbG9nZ2VyKSB7XG4gICAgICAvLyBmYWxsYmFja1xuICAgICAgdGhpcy5fbG9nZ2VyID0gbmV3IExvZ2dlcihcIk5lc3RCb290c3RyYXBcIik7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9sb2dnZXI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIEluaXRpYWxpemVzIHRoZSBib290c3RyYXBwZXIgd2l0aCBhIGdpdmVuIE5lc3RKUyBhcHBsaWNhdGlvbi5cbiAgICpcbiAgICogQHN1bW1hcnlcbiAgICogQmluZHMgdGhlIHByb3ZpZGVkIE5lc3RKUyBhcHAgaW5zdGFuY2UgdG8gdGhlIGJvb3RzdHJhcHBlciwgZW5hYmxpbmdcbiAgICogY2hhaW5lZCBjb25maWd1cmF0aW9uIG1ldGhvZHMuXG4gICAqXG4gICAqIEBwYXJhbSB7SU5lc3RBcHBsaWNhdGlvbn0gYXBwIC0gVGhlIE5lc3RKUyBhcHBsaWNhdGlvbiBpbnN0YW5jZSB0byBpbml0aWFsaXplLlxuICAgKiBAcmV0dXJuIHt0eXBlb2YgTmVzdEJvb3RzdHJhcGVyfSBSZXR1cm5zIHRoZSBjbGFzcyBmb3IgY2hhaW5pbmcgY29uZmlndXJhdGlvbiBtZXRob2RzLlxuICAgKi9cbiAgc3RhdGljIGluaXRpYWxpemUoYXBwOiBJTmVzdEFwcGxpY2F0aW9uKSB7XG4gICAgdGhpcy5hcHAgPSBhcHA7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIEVuYWJsZXMgb3IgcmVwbGFjZXMgdGhlIGdsb2JhbCBsb2dnZXIgZm9yIHRoZSBOZXN0SlMgYXBwbGljYXRpb24uXG4gICAqXG4gICAqIEBzdW1tYXJ5XG4gICAqIElmIGEgY3VzdG9tIGxvZ2dlciBpcyBwcm92aWRlZCwgaXQgcmVwbGFjZXMgdGhlIGRlZmF1bHQgbG9nZ2VyLiBPdGhlcndpc2UsXG4gICAqIGEgbmV3IGxvZ2dlciBuYW1lZCBgXCJOZXN0Qm9vdHN0cmFwXCJgIGlzIHVzZWQuIFRoaXMgbG9nZ2VyIGlzIGFsc28gcmVnaXN0ZXJlZFxuICAgKiB3aXRoIHRoZSBOZXN0SlMgYXBwbGljYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSB7TG9nZ2VyfSBbY3VzdG9tTG9nZ2VyXSAtIE9wdGlvbmFsIGN1c3RvbSBsb2dnZXIgaW5zdGFuY2UuXG4gICAqIEByZXR1cm4ge3R5cGVvZiBOZXN0Qm9vdHN0cmFwZXJ9IFJldHVybnMgdGhlIGNsYXNzIGZvciBjaGFpbmluZy5cbiAgICovXG4gIHN0YXRpYyBlbmFibGVMb2dnZXIoY3VzdG9tTG9nZ2VyPzogTG9nZ2VyKSB7XG4gICAgdGhpcy5fbG9nZ2VyID0gY3VzdG9tTG9nZ2VyIHx8IG5ldyBMb2dnZXIoXCJOZXN0Qm9vdHN0cmFwXCIpO1xuICAgIHRoaXMuYXBwLnVzZUxvZ2dlcih0aGlzLl9sb2dnZXIpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBFbmFibGVzIENyb3NzLU9yaWdpbiBSZXNvdXJjZSBTaGFyaW5nIChDT1JTKSBmb3IgdGhlIGFwcGxpY2F0aW9uLlxuICAgKlxuICAgKiBAc3VtbWFyeVxuICAgKiBBbGxvd3MgZGVmaW5pbmcgZWl0aGVyIGEgd2lsZGNhcmQgb3JpZ2luIChgXCIqXCJgKSBvciBhIGxpc3Qgb2YgYWxsb3dlZCBvcmlnaW5zLlxuICAgKiBBdXRvbWF0aWNhbGx5IGFjY2VwdHMgbG9jYWwgZGV2ZWxvcG1lbnQgcmVxdWVzdHMgYW5kIHRob3NlIHdpdGhvdXQgb3JpZ2luIGhlYWRlcnMuXG4gICAqIFRocm93cyBhIGBDb3JzRXJyb3JgIGZvciB1bmF1dGhvcml6ZWQgb3JpZ2lucy5cbiAgICpcbiAgICogQHBhcmFtIHsnKicgfCBzdHJpbmdbXX0gW29yaWdpbnM9W11dIC0gTGlzdCBvZiBhbGxvd2VkIG9yaWdpbnMgb3IgYFwiKlwiYCB0byBhbGxvdyBhbGwuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IFthbGxvd01ldGhvZHM9WydHRVQnLCAnUE9TVCcsICdQVVQnLCAnREVMRVRFJ11dIC0gQWxsb3dlZCBIVFRQIG1ldGhvZHMuXG4gICAqIEByZXR1cm4ge3R5cGVvZiBOZXN0Qm9vdHN0cmFwZXJ9IFJldHVybnMgdGhlIGNsYXNzIGZvciBjaGFpbmluZyBjb25maWd1cmF0aW9uLlxuICAgKlxuICAgKi9cbiAgc3RhdGljIGVuYWJsZUNvcnMoXG4gICAgb3JpZ2luczogXCIqXCIgfCBzdHJpbmdbXSA9IFtdLFxuICAgIGFsbG93TWV0aG9kczogc3RyaW5nW10gPSBbXCJHRVRcIiwgXCJQT1NUXCIsIFwiUFVUXCIsIFwiREVMRVRFXCJdXG4gICkge1xuICAgIGNvbnN0IGFsbG93ZWRPcmlnaW5zID1cbiAgICAgIG9yaWdpbnMgPT09IFwiKlwiID8gXCIqXCIgOiBvcmlnaW5zLm1hcCgobykgPT4gby50cmltKCkudG9Mb3dlckNhc2UoKSk7XG5cbiAgICBjb25zdCBjb3JzT3B0aW9uczogQ29yc09wdGlvbnMgPSB7XG4gICAgICBvcmlnaW46IChvcmlnaW4sIGNhbGxiYWNrKSA9PiB7XG4gICAgICAgIC8vIEFsbG93IHJlcXVlc3Qgd2l0aG91dCBvcmlnaW4uLi5cbiAgICAgICAgaWYgKCFvcmlnaW4pIHJldHVybiBjYWxsYmFjayhudWxsLCB0cnVlKTtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgYWxsb3dlZE9yaWdpbnMgPT09IFwiKlwiIHx8XG4gICAgICAgICAgKEFycmF5LmlzQXJyYXkoYWxsb3dlZE9yaWdpbnMpICYmXG4gICAgICAgICAgICBhbGxvd2VkT3JpZ2lucy5pbmNsdWRlcyhvcmlnaW4udG9Mb3dlckNhc2UoKSkpXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNhbGxiYWNrKG5ldyBDb3JzRXJyb3IoYE9yaWdpbiAke29yaWdpbn0gbm90IGFsbG93ZWRgKSk7XG4gICAgICB9LFxuICAgICAgY3JlZGVudGlhbHM6IHRydWUsXG4gICAgICBtZXRob2RzOiBhbGxvd01ldGhvZHMuam9pbihcIixcIiksXG4gICAgfTtcblxuICAgIHRoaXMuYXBwLmVuYWJsZUNvcnMoY29yc09wdGlvbnMpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBBcHBsaWVzIHRoZSBIZWxtZXQgbWlkZGxld2FyZSBmb3IgZW5oYW5jZWQgc2VjdXJpdHkuXG4gICAqXG4gICAqIEBzdW1tYXJ5XG4gICAqIER5bmFtaWNhbGx5IGxvYWRzIHRoZSBgaGVsbWV0YCBwYWNrYWdlIGlmIGF2YWlsYWJsZSBhbmQgcmVnaXN0ZXJzIGl0XG4gICAqIGFzIG1pZGRsZXdhcmUgdG8gaW1wcm92ZSBIVFRQIGhlYWRlciBzZWN1cml0eS4gSWYgbm90IGluc3RhbGxlZCwgbG9ncyBhIHdhcm5pbmdcbiAgICogYW5kIGNvbnRpbnVlcyBleGVjdXRpb24gd2l0aG91dCB0aHJvd2luZyBlcnJvcnMuXG4gICAqXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gW29wdGlvbnNdIC0gT3B0aW9uYWwgY29uZmlndXJhdGlvbiBwYXNzZWQgdG8gSGVsbWV0LlxuICAgKiBAcmV0dXJuIHt0eXBlb2YgTmVzdEJvb3RzdHJhcGVyfSBSZXR1cm5zIHRoZSBjbGFzcyBmb3IgY2hhaW5pbmcgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIHN0YXRpYyB1c2VIZWxtZXQob3B0aW9ucz86IFJlY29yZDxzdHJpbmcsIGFueT4pIHtcbiAgICB0cnkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgICAgIGNvbnN0IGhlbG1ldCA9IHJlcXVpcmUoXCJoZWxtZXRcIik7IC8vIER5bmFtaWMgaW1wb3J0IHRvIGF2b2lkIGhhcmQgZGVwZW5kZW5jeVxuICAgICAgdGhpcy5hcHAudXNlKGhlbG1ldChvcHRpb25zKSk7XG4gICAgICB0aGlzLmxvZ2dlci5sb2coXCJIZWxtZXQgbWlkZGxld2FyZSBlbmFibGVkIHN1Y2Nlc3NmdWxseS5cIik7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICB0aGlzLmxvZ2dlci53YXJuKFwiSGVsbWV0IG5vdCBpbnN0YWxsZWQuIFNraXBwaW5nIG1pZGRsZXdhcmUuXCIpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBDb25maWd1cmVzIGFuZCBpbml0aWFsaXplcyBTd2FnZ2VyIFVJIGZvciBBUEkgZG9jdW1lbnRhdGlvbi5cbiAgICpcbiAgICogQHN1bW1hcnlcbiAgICogVXNlcyB0aGUgYFN3YWdnZXJCdWlsZGVyYCB1dGlsaXR5IHRvIGNvbmZpZ3VyZSBBUEkgZG9jdW1lbnRhdGlvblxuICAgKiB3aXRoIGRldGFpbGVkIGN1c3RvbWl6YXRpb24gZm9yIHRpdGxlLCB2ZXJzaW9uLCBwYXRocywgYW5kIGNvbG9ycy5cbiAgICogU3dhZ2dlciBpcyBhdXRvbWF0aWNhbGx5IGV4cG9zZWQgYXQgdGhlIGNvbmZpZ3VyZWQgcGF0aC5cbiAgICpcbiAgICogQHBhcmFtIHtTd2FnZ2VyU2V0dXBPcHRpb25zfSBvcHRpb25zIC0gU3dhZ2dlciBjb25maWd1cmF0aW9uIG9wdGlvbnMuXG4gICAqIEByZXR1cm4ge3R5cGVvZiBOZXN0Qm9vdHN0cmFwZXJ9IFJldHVybnMgdGhlIGNsYXNzIGZvciBjaGFpbmluZyBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgc3RhdGljIHNldHVwU3dhZ2dlcihvcHRpb25zOiBTd2FnZ2VyU2V0dXBPcHRpb25zKSB7XG4gICAgY29uc3Qgc3dhZ2dlciA9IG5ldyBTd2FnZ2VyQnVpbGRlcih0aGlzLmFwcCwge1xuICAgICAgdGl0bGU6IG9wdGlvbnMudGl0bGUsXG4gICAgICBkZXNjcmlwdGlvbjogb3B0aW9ucy5kZXNjcmlwdGlvbixcbiAgICAgIHZlcnNpb246IG9wdGlvbnMudmVyc2lvbixcbiAgICAgIHBhdGg6IG9wdGlvbnMucGF0aCB8fCBcImFwaVwiLFxuICAgICAgcGVyc2lzdEF1dGhvcml6YXRpb246IG9wdGlvbnMucGVyc2lzdEF1dGhvcml6YXRpb24gPz8gdHJ1ZSxcbiAgICAgIGFzc2V0c1BhdGg6IG9wdGlvbnMuYXNzZXRzUGF0aCxcbiAgICAgIGZhdmljb25GaWxlUGF0aDogb3B0aW9ucy5mYXZpY29uUGF0aCxcbiAgICAgIHRvcGJhckljb25GaWxlUGF0aDogb3B0aW9ucy50b3BiYXJJY29uUGF0aCxcbiAgICAgIHRvcGJhckJnQ29sb3I6IG9wdGlvbnMudG9wYmFyQmdDb2xvcixcbiAgICB9KTtcbiAgICBzd2FnZ2VyLnNldHVwU3dhZ2dlcigpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvblxuICAgKiBSZWdpc3RlcnMgb25lIG9yIG1vcmUgZ2xvYmFsIHZhbGlkYXRpb24gcGlwZXMuXG4gICAqXG4gICAqIEBzdW1tYXJ5XG4gICAqIEVuYWJsZXMgcmVxdWVzdCBwYXlsb2FkIHZhbGlkYXRpb24gYW5kIHRyYW5zZm9ybWF0aW9uIGdsb2JhbGx5IGFjcm9zc1xuICAgKiB0aGUgZW50aXJlIE5lc3RKUyBhcHBsaWNhdGlvbi4gTXVsdGlwbGUgcGlwZXMgY2FuIGJlIGNoYWluZWQgdG9nZXRoZXJcbiAgICogZm9yIG1vZHVsYXIgaW5wdXQgdmFsaWRhdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHsuLi5QaXBlVHJhbnNmb3JtW119IHBpcGVzIC0gUGlwZSBpbnN0YW5jZXMgdG8gcmVnaXN0ZXIgZ2xvYmFsbHkuXG4gICAqIEByZXR1cm4ge3R5cGVvZiBOZXN0Qm9vdHN0cmFwZXJ9IFJldHVybnMgdGhlIGNsYXNzIGZvciBjaGFpbmluZy5cbiAgICovXG4gIHN0YXRpYyB1c2VHbG9iYWxQaXBlcyguLi5waXBlczogUGlwZVRyYW5zZm9ybVtdKSB7XG4gICAgaWYgKHBpcGVzLmxlbmd0aCA+IDApIHRoaXMuYXBwLnVzZUdsb2JhbFBpcGVzKC4uLnBpcGVzKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogUmVnaXN0ZXJzIG9uZSBvciBtb3JlIGdsb2JhbCBleGNlcHRpb24gZmlsdGVycy5cbiAgICpcbiAgICogQHN1bW1hcnlcbiAgICogSWYgbm8gZmlsdGVycyBhcmUgcHJvdmlkZWQsIGl0IGF1dG9tYXRpY2FsbHkgcmVnaXN0ZXJzIGEgZGVmYXVsdFxuICAgKiBzZXQgb2Ygc3RhbmRhcmQgZXhjZXB0aW9uIGZpbHRlcnMgZm9yIGNvbW1vbiBlcnJvciB0eXBlcyBsaWtlXG4gICAqIGBIdHRwRXhjZXB0aW9uYCwgYFZhbGlkYXRpb25FeGNlcHRpb25gLCBgQ29uZmxpY3RFeGNlcHRpb25gLCBhbmQgb3RoZXJzLlxuICAgKlxuICAgKiBAcGFyYW0gey4uLkV4Y2VwdGlvbkZpbHRlcltdfSBmaWx0ZXJzIC0gT3B0aW9uYWwgZmlsdGVycyB0byBhcHBseSBnbG9iYWxseS5cbiAgICogQHJldHVybiB7dHlwZW9mIE5lc3RCb290c3RyYXBlcn0gUmV0dXJucyB0aGUgY2xhc3MgZm9yIGNoYWluaW5nIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBzdGF0aWMgdXNlR2xvYmFsRmlsdGVycyguLi5maWx0ZXJzOiBhbnlbXSkge1xuICAgIGNvbnN0IGRlZmF1bHRGaWx0ZXJzID0gW1xuICAgICAgbmV3IEh0dHBFeGNlcHRpb25GaWx0ZXIoKSxcbiAgICAgIG5ldyBWYWxpZGF0aW9uRXhjZXB0aW9uRmlsdGVyKCksXG4gICAgICBuZXcgTm90Rm91bmRFeGNlcHRpb25GaWx0ZXIoKSxcbiAgICAgIG5ldyBDb25mbGljdEV4Y2VwdGlvbkZpbHRlcigpLFxuICAgICAgbmV3IEF1dGhvcml6YXRpb25FeGNlcHRpb25GaWx0ZXIoKSxcbiAgICAgIG5ldyBHbG9iYWxFeGNlcHRpb25GaWx0ZXIoKSxcbiAgICBdO1xuXG4gICAgdGhpcy5hcHAudXNlR2xvYmFsRmlsdGVycyhcbiAgICAgIC4uLihmaWx0ZXJzLmxlbmd0aCA+IDAgPyBmaWx0ZXJzIDogZGVmYXVsdEZpbHRlcnMpXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb25cbiAgICogUmVnaXN0ZXJzIGdsb2JhbCBpbnRlcmNlcHRvcnMgZm9yIHJlcXVlc3QgYW5kIHJlc3BvbnNlIHRyYW5zZm9ybWF0aW9uLlxuICAgKlxuICAgKiBAc3VtbWFyeVxuICAgKiBJbnRlcmNlcHRvcnMgYWxsb3cgYWR2YW5jZWQgcmVxdWVzdC9yZXNwb25zZSBtYW5pcHVsYXRpb24gc3VjaCBhc1xuICAgKiBzZXJpYWxpemF0aW9uLCBsb2dnaW5nLCBvciB0cmFuc2Zvcm1hdGlvbi4gTXVsdGlwbGUgaW50ZXJjZXB0b3JzXG4gICAqIGNhbiBiZSBhZGRlZCBmb3IgbW9kdWxhciBjb25maWd1cmF0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gey4uLk5lc3RJbnRlcmNlcHRvcltdfSBpbnRlcmNlcHRvcnMgLSBJbnRlcmNlcHRvciBpbnN0YW5jZXMgdG8gcmVnaXN0ZXIuXG4gICAqIEByZXR1cm4ge3R5cGVvZiBOZXN0Qm9vdHN0cmFwZXJ9IFJldHVybnMgdGhlIGNsYXNzIGZvciBjaGFpbmluZyBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgc3RhdGljIHVzZUdsb2JhbEludGVyY2VwdG9ycyguLi5pbnRlcmNlcHRvcnM6IE5lc3RJbnRlcmNlcHRvcltdKSB7XG4gICAgaWYgKGludGVyY2VwdG9ycy5sZW5ndGggPiAwKVxuICAgICAgdGhpcy5hcHAudXNlR2xvYmFsSW50ZXJjZXB0b3JzKC4uLmludGVyY2VwdG9ycyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uXG4gICAqIFN0YXJ0cyB0aGUgTmVzdEpTIGFwcGxpY2F0aW9uIGFuZCBiaW5kcyBpdCB0byB0aGUgZ2l2ZW4gcG9ydCBhbmQgaG9zdC5cbiAgICpcbiAgICogQHN1bW1hcnlcbiAgICogTGlzdGVucyBvbiB0aGUgc3BlY2lmaWVkIHBvcnQgYW5kIG9wdGlvbmFsbHkgYSBob3N0LiBPbmNlIHN0YXJ0ZWQsXG4gICAqIGxvZ3MgdGhlIGFwcGxpY2F0aW9uIFVSTCBmb3IgZWFzeSBhY2Nlc3MuIFRoZSBzdGFydHVwIHByb2Nlc3MgcmVzb2x2ZXNcbiAgICogb25jZSB0aGUgYXBwbGljYXRpb24gaXMgc3VjY2Vzc2Z1bGx5IHJ1bm5pbmcuXG4gICAqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbcG9ydD0zMDAwXSAtIFBvcnQgbnVtYmVyIHRvIGxpc3RlbiBvbi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFtob3N0XSAtIE9wdGlvbmFsIGhvc3Qgb3IgSVAgYWRkcmVzcyB0byBiaW5kIHRvLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtsb2c9dHJ1ZV0gLSBXaGV0aGVyIHRvIGxvZyB0aGUgYXBwbGljYXRpb24gVVJMIHVwb24gc3RhcnR1cC5cbiAgICogQHJldHVybiB7UHJvbWlzZTx2b2lkPn0gUmVzb2x2ZXMgb25jZSB0aGUgYXBwbGljYXRpb24gc3RhcnRzIHN1Y2Nlc3NmdWxseS5cbiAgICovXG4gIHN0YXRpYyBhc3luYyBzdGFydChcbiAgICBwb3J0OiBudW1iZXIgPSBOdW1iZXIocHJvY2Vzcy5lbnYuUE9SVCkgfHwgMzAwMCxcbiAgICBob3N0OiBzdHJpbmcgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQsXG4gICAgbG9nOiBib29sZWFuID0gdHJ1ZVxuICApIHtcbiAgICB0aGlzLmFwcC5saXN0ZW4ocG9ydCwgaG9zdCBhcyBhbnkpLnRoZW4oYXN5bmMgKCkgPT4ge1xuICAgICAgaWYgKGxvZykge1xuICAgICAgICBjb25zdCB1cmwgPSBhd2FpdCB0aGlzLmFwcC5nZXRVcmwoKTtcbiAgICAgICAgdGhpcy5sb2dnZXIubG9nKGDwn5qAIEFwcGxpY2F0aW9uIGlzIHJ1bm5pbmcgYXQ6ICR7dXJsfWApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG4iLCIvKipcbiAqIEBtb2R1bGUgZm9yLW5lc3RcbiAqIEBkZXNjcmlwdGlvbiBUaGlzIG1vZHVsZSBzZXJ2ZXMgYXMgdGhlIG1haW4gZW50cnkgcG9pbnQgZm9yIHRoZSB0cy13b3Jrc3BhY2UgbGlicmFyeS4gSXQgYWdncmVnYXRlcyBhbmQgZXhwb3J0c1xuICogZnVuY3Rpb25hbGl0eSBmcm9tIHZhcmlvdXMgc3VibW9kdWxlcyBhbmQgdXRpbGl0aWVzIHdpdGhpbiB0aGUgcHJvamVjdC5cbiAqXG4gKiBUaGUgbW9kdWxlIGluY2x1ZGVzOlxuICogMS4gVXRpbGl0eSBmdW5jdGlvbnMgYW5kIHR5cGVzIGZyb20gdGhlIFwiLi91dGlsc1wiIGRpcmVjdG9yeTpcbiAqICAgIC0gVGhlc2UgbGlrZWx5IGNvbnRhaW4gaGVscGVyIGZ1bmN0aW9ucywgY29tbW9uIHR5cGVzLCBhbmQgc2hhcmVkIGZ1bmN0aW9uYWxpdHkgdXNlZCB0aHJvdWdob3V0IHRoZSBwcm9qZWN0LlxuICogICAgLSBNYXkgaW5jbHVkZSBvcGVyYXRpb25zIGZvciBkYXRhIG1hbmlwdWxhdGlvbiwgdHlwZSBjaGVja2luZywgb3Igb3RoZXIgZ2VuZXJhbC1wdXJwb3NlIHV0aWxpdGllcy5cbiAqXG4gKiAyLiBBIG5hbWVzcGFjZSBhbmQgcmVsYXRlZCB0eXBlcyBmcm9tIHRoZSBcIi4vbmFtZXNwYWNlXCIgZGlyZWN0b3J5OlxuICogICAgLSBUaGlzIGNvdWxkIGNvbnRhaW4gZG9tYWluLXNwZWNpZmljIGNvZGUgb3IgYSBjb2xsZWN0aW9uIG9mIHJlbGF0ZWQgZnVuY3Rpb25hbGl0eS5cbiAqICAgIC0gTWlnaHQgaW5jbHVkZSBpbnRlcmZhY2VzLCB0eXBlcywgb3IgY2xhc3NlcyB0aGF0IHJlcHJlc2VudCBjb3JlIGNvbmNlcHRzIGluIHRoZSBsaWJyYXJ5LlxuICpcbiAqIDMuIEEgVkVSU0lPTiBjb25zdGFudDpcbiAqICAgIC0gUmVwcmVzZW50cyB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIHRoZSBtb2R1bGUuXG4gKiAgICAtIFVzZWZ1bCBmb3IgdmVyc2lvbiBjaGVja2luZyBhbmQgY29tcGF0aWJpbGl0eSBwdXJwb3Nlcy5cbiAqXG4gKiBUaGlzIHN0cnVjdHVyZSBwcm92aWRlcyBhIGNsZWFuIGFuZCBvcmdhbml6ZWQgZXhwb3J0IG9mIHRoZSBtb2R1bGUncyBmdW5jdGlvbmFsaXR5LCBhbGxvd2luZyBjb25zdW1lcnNcbiAqIHRvIGVhc2lseSBpbXBvcnQgYW5kIHVzZSBzcGVjaWZpYyBwYXJ0cyBvZiB0aGUgbGlicmFyeSBhcyBuZWVkZWQuXG4gKi9cblxuaW1wb3J0IHsgTWV0YWRhdGEgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRpb25cIjtcbmltcG9ydCBcIi4vZGVjb3JhdGlvblwiO1xuXG5leHBvcnQgKiBmcm9tIFwiLi9kZWNvcmF0b3JzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2RlY29yYXRpb25cIjtcbmV4cG9ydCAqIGZyb20gXCIuL21vZHVsZVwiO1xuZXhwb3J0ICogZnJvbSBcIi4vUmVwb0ZhY3RvcnlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL3R5cGVzXCI7XG5leHBvcnQgKiBmcm9tIFwiLi91dGlsc1wiO1xuZXhwb3J0ICogZnJvbSBcIi4vZmFjdG9yeVwiO1xuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlIGN1cnJlbnQgdmVyc2lvbiBvZiB0aGUgdHMtd29ya3NwYWNlIG1vZHVsZS5cbiAqIFRoZSBhY3R1YWwgdmVyc2lvbiBudW1iZXIgaXMgcmVwbGFjZWQgZHVyaW5nIHRoZSBidWlsZCBwcm9jZXNzLlxuICogQGNvbnN0YW50XG4gKiBAdHlwZSB7c3RyaW5nfVxuICovXG5leHBvcnQgY29uc3QgVkVSU0lPTiA9IFwiIyNWRVJTSU9OIyNcIjtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX05BTUUgPSBcIiMjUEFDS0FHRV9OQU1FIyNcIjtcblxuTWV0YWRhdGEucmVnaXN0ZXJMaWJyYXJ5KFBBQ0tBR0VfTkFNRSwgVkVSU0lPTik7XG4iXSwibmFtZXMiOlsiZ2V0VHlwZUlzQXJyYXlUdXBsZSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQVFnQixTQUFBLHFCQUFxQixDQUNuQyxPQUFlLEVBQ2YsUUFBVyxFQUNYLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFLGdCQUFnQixFQUFFLElBQUksRUFBRSxFQUFBO0FBRWpELElBQUEsT0FBTyxDQUNMLE1BQWMsRUFDZCxHQUFvQixFQUNwQixVQUE4QixLQUM1QjtBQUNGLFFBQUEsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLEVBQUU7QUFDaEMsWUFBQSxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxVQUFVLENBQUMsS0FBSyxDQUFDO0FBQ2hFLFlBQUEsSUFBSSxTQUFTLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtBQUNsQyxnQkFBQSxPQUFPLFVBQVU7O0FBRW5CLFlBQUEsT0FBTyxDQUFDLGNBQWMsQ0FDcEIsT0FBTyxFQUNQLEVBQUUsR0FBRyxTQUFTLEVBQUUsR0FBRyxRQUFRLEVBQUUsRUFDN0IsVUFBVSxDQUFDLEtBQUssQ0FDakI7QUFDRCxZQUFBLE9BQU8sVUFBVTs7UUFFbkIsT0FBTyxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxLQUFLLENBQUM7QUFDM0QsUUFBQSxPQUFPLFVBQVU7QUFDbkIsS0FBQztBQUNIO1NBRWdCLG9CQUFvQixDQUNsQyxPQUFlLEVBQ2YsV0FBYyxFQUFrQixFQUFBO0lBRWhDLE9BQU8sQ0FBQyxNQUFNLEtBQUk7QUFDaEIsUUFBQSxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSSxFQUFFO0FBQzVELFFBQUEsT0FBTyxDQUFD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