every-plugin 0.4.9 → 0.4.11

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 (58) hide show
  1. package/dist/build/rspack/index.cjs +45 -7
  2. package/dist/build/rspack/index.mjs +45 -7
  3. package/dist/{errors-CVnoPl9v.cjs → errors-BEsEPXKG.cjs} +2 -2
  4. package/dist/errors-CpYzD_-M.d.cts +38 -0
  5. package/dist/errors-D2-thHKG.d.mts +38 -0
  6. package/dist/{errors-D7keKf7a.mjs → errors-DnigICIv.mjs} +2 -2
  7. package/dist/errors.cjs +2 -2
  8. package/dist/errors.d.cts +1 -2
  9. package/dist/errors.d.mts +1 -2
  10. package/dist/errors.mjs +2 -2
  11. package/dist/{fetch-Cc95-7kM.cjs → fetch-CGzn1Uf7.cjs} +2 -2
  12. package/dist/{fetch-KLktuWuM.mjs → fetch-ycs0raYN.mjs} +2 -2
  13. package/dist/{index-matrPV4m.d.cts → index-BXfi8DqC.d.cts} +1 -1
  14. package/dist/{index-bwAhA9ca.d.mts → index-DvIxKA8K.d.mts} +2 -2
  15. package/dist/index.cjs +4 -4
  16. package/dist/index.d.cts +3 -4
  17. package/dist/index.d.mts +3 -4
  18. package/dist/index.mjs +4 -4
  19. package/dist/{normalize-BLTyqFww.d.mts → normalize-BCE_FLe8.d.mts} +1 -1
  20. package/dist/{normalize-BW7kk8Lk.d.cts → normalize-Tt7I_RdD.d.cts} +1 -1
  21. package/dist/package-C2Mp8qeD.cjs +155 -0
  22. package/dist/package-uEsV9Z-2.mjs +150 -0
  23. package/dist/plugins-Cmsm3gW1.cjs +791 -0
  24. package/dist/plugins-hpi2GlaX.mjs +790 -0
  25. package/dist/runtime/index.cjs +2 -2
  26. package/dist/runtime/index.d.cts +3 -4
  27. package/dist/runtime/index.d.mts +3 -4
  28. package/dist/runtime/index.mjs +2 -2
  29. package/dist/runtime/services/normalize.d.cts +1 -1
  30. package/dist/runtime/services/normalize.d.mts +1 -1
  31. package/dist/{runtime-Daw9Tlz6.mjs → runtime-BUQ0hy1J.mjs} +3 -3
  32. package/dist/{runtime-CWCl3EIz.cjs → runtime-LlP2xpdB.cjs} +3 -3
  33. package/dist/{standard-eUgUkWaf.cjs → standard-0wBehDUp.cjs} +1 -18
  34. package/dist/{standard-DaxKTFui.mjs → standard-CYaRay89.mjs} +2 -13
  35. package/dist/testing/index.cjs +2 -2
  36. package/dist/testing/index.d.cts +4 -5
  37. package/dist/testing/index.d.mts +4 -5
  38. package/dist/testing/index.mjs +2 -2
  39. package/dist/zod-BDDjyyHQ.mjs +10 -0
  40. package/dist/{zod-DYghWCz1.cjs → zod-CJY4vNLR.cjs} +2 -2
  41. package/dist/zod.cjs +4 -4
  42. package/dist/zod.d.cts +1 -2
  43. package/dist/zod.d.mts +1 -2
  44. package/dist/zod.mjs +2 -2
  45. package/package.json +3 -2
  46. package/dist/errors-Car4tFVP.d.mts +0 -75
  47. package/dist/errors-DKPPPYYT.d.cts +0 -75
  48. package/dist/openapi.DrTcell5-C6kyDyUK.mjs +0 -669
  49. package/dist/openapi.DrTcell5-DDf4D5V3.cjs +0 -687
  50. package/dist/package-BwFfsvZZ.mjs +0 -149
  51. package/dist/package-CSi-6ikY.cjs +0 -154
  52. package/dist/plugins-C-7lh5gK.cjs +0 -128
  53. package/dist/plugins-Ps5Xxpk2.mjs +0 -128
  54. package/dist/zod-A7Pti5IV.d.cts +0 -4
  55. package/dist/zod-BVo51kgJ.mjs +0 -10
  56. package/dist/zod-D4CFw8d9.d.mts +0 -4
  57. package/dist/zod4-BXTBR1od.cjs +0 -318
  58. package/dist/zod4-VpXuwRO7.mjs +0 -317
@@ -1,669 +0,0 @@
1
- import { a as toHttpPath, c as fallbackORPCErrorStatus, d as findDeepMatches, g as toArray, h as stringifyJSON, i as standardizeHTTPPath, l as isORPCErrorStatus, p as isObject, r as getDynamicParams, s as fallbackORPCErrorMessage, t as StandardOpenAPIJsonSerializer, u as clone, v as value } from "./standard-DaxKTFui.mjs";
2
- import { isProcedure, resolveContractProcedures } from "@orpc/server";
3
- import { fallbackContractConfig, getEventIteratorSchemaDetails } from "@orpc/contract";
4
-
5
- //#region ../../node_modules/.bun/@orpc+interop@1.10.4/node_modules/@orpc/interop/dist/json-schema-typed/index.mjs
6
- var ContentEncoding;
7
- (function(ContentEncoding1) {
8
- ContentEncoding1["7bit"] = "7bit";
9
- ContentEncoding1["8bit"] = "8bit";
10
- ContentEncoding1["Base64"] = "base64";
11
- ContentEncoding1["Binary"] = "binary";
12
- ContentEncoding1["IETFToken"] = "ietf-token";
13
- ContentEncoding1["QuotedPrintable"] = "quoted-printable";
14
- ContentEncoding1["XToken"] = "x-token";
15
- })(ContentEncoding || (ContentEncoding = {}));
16
- var Format;
17
- (function(Format1) {
18
- Format1["Date"] = "date";
19
- Format1["DateTime"] = "date-time";
20
- Format1["Duration"] = "duration";
21
- Format1["Email"] = "email";
22
- Format1["Hostname"] = "hostname";
23
- Format1["IDNEmail"] = "idn-email";
24
- Format1["IDNHostname"] = "idn-hostname";
25
- Format1["IPv4"] = "ipv4";
26
- Format1["IPv6"] = "ipv6";
27
- Format1["IRI"] = "iri";
28
- Format1["IRIReference"] = "iri-reference";
29
- Format1["JSONPointer"] = "json-pointer";
30
- Format1["JSONPointerURIFragment"] = "json-pointer-uri-fragment";
31
- Format1["RegEx"] = "regex";
32
- Format1["RelativeJSONPointer"] = "relative-json-pointer";
33
- Format1["Time"] = "time";
34
- Format1["URI"] = "uri";
35
- Format1["URIReference"] = "uri-reference";
36
- Format1["URITemplate"] = "uri-template";
37
- Format1["UUID"] = "uuid";
38
- })(Format || (Format = {}));
39
- var TypeName;
40
- (function(TypeName1) {
41
- TypeName1["Array"] = "array";
42
- TypeName1["Boolean"] = "boolean";
43
- TypeName1["Integer"] = "integer";
44
- TypeName1["Null"] = "null";
45
- TypeName1["Number"] = "number";
46
- TypeName1["Object"] = "object";
47
- TypeName1["String"] = "string";
48
- })(TypeName || (TypeName = {}));
49
-
50
- //#endregion
51
- //#region ../../node_modules/.bun/@orpc+openapi@1.10.4/node_modules/@orpc/openapi/dist/shared/openapi.DrTcell5.mjs
52
- const OPERATION_EXTENDER_SYMBOL = Symbol("ORPC_OPERATION_EXTENDER");
53
- function getCustomOpenAPIOperation(o) {
54
- return o[OPERATION_EXTENDER_SYMBOL];
55
- }
56
- function applyCustomOpenAPIOperation(operation, contract) {
57
- const operationCustoms = [];
58
- for (const errorItem of Object.values(contract["~orpc"].errorMap)) {
59
- const maybeExtender = errorItem ? getCustomOpenAPIOperation(errorItem) : void 0;
60
- if (maybeExtender) operationCustoms.push(maybeExtender);
61
- }
62
- if (isProcedure(contract)) for (const middleware of contract["~orpc"].middlewares) {
63
- const maybeExtender = getCustomOpenAPIOperation(middleware);
64
- if (maybeExtender) operationCustoms.push(maybeExtender);
65
- }
66
- let currentOperation = operation;
67
- for (const custom of operationCustoms) if (typeof custom === "function") currentOperation = custom(currentOperation, contract);
68
- else currentOperation = {
69
- ...currentOperation,
70
- ...custom
71
- };
72
- return currentOperation;
73
- }
74
- const LOGIC_KEYWORDS = [
75
- "$dynamicRef",
76
- "$ref",
77
- "additionalItems",
78
- "additionalProperties",
79
- "allOf",
80
- "anyOf",
81
- "const",
82
- "contains",
83
- "contentEncoding",
84
- "contentMediaType",
85
- "contentSchema",
86
- "dependencies",
87
- "dependentRequired",
88
- "dependentSchemas",
89
- "else",
90
- "enum",
91
- "exclusiveMaximum",
92
- "exclusiveMinimum",
93
- "format",
94
- "if",
95
- "items",
96
- "maxContains",
97
- "maximum",
98
- "maxItems",
99
- "maxLength",
100
- "maxProperties",
101
- "minContains",
102
- "minimum",
103
- "minItems",
104
- "minLength",
105
- "minProperties",
106
- "multipleOf",
107
- "not",
108
- "oneOf",
109
- "pattern",
110
- "patternProperties",
111
- "prefixItems",
112
- "properties",
113
- "propertyNames",
114
- "required",
115
- "then",
116
- "type",
117
- "unevaluatedItems",
118
- "unevaluatedProperties",
119
- "uniqueItems"
120
- ];
121
- function isFileSchema(schema) {
122
- return isObject(schema) && schema.type === "string" && typeof schema.contentMediaType === "string";
123
- }
124
- function isObjectSchema(schema) {
125
- return isObject(schema) && schema.type === "object";
126
- }
127
- function isAnySchema(schema) {
128
- if (schema === true) return true;
129
- if (Object.keys(schema).every((k) => !LOGIC_KEYWORDS.includes(k))) return true;
130
- return false;
131
- }
132
- function separateObjectSchema(schema, separatedProperties) {
133
- if (Object.keys(schema).some((k) => ![
134
- "type",
135
- "properties",
136
- "required",
137
- "additionalProperties"
138
- ].includes(k) && LOGIC_KEYWORDS.includes(k) && schema[k] !== void 0)) return [{ type: "object" }, schema];
139
- const matched = { ...schema };
140
- const rest = { ...schema };
141
- matched.properties = separatedProperties.reduce((acc, key) => {
142
- const keySchema = schema.properties?.[key] ?? schema.additionalProperties;
143
- if (keySchema !== void 0) acc[key] = keySchema;
144
- return acc;
145
- }, {});
146
- matched.required = schema.required?.filter((key) => separatedProperties.includes(key));
147
- matched.examples = schema.examples?.map((example) => {
148
- if (!isObject(example)) return example;
149
- return Object.entries(example).reduce((acc, [key, value$1]) => {
150
- if (separatedProperties.includes(key)) acc[key] = value$1;
151
- return acc;
152
- }, {});
153
- });
154
- rest.properties = schema.properties && Object.entries(schema.properties).filter(([key]) => !separatedProperties.includes(key)).reduce((acc, [key, value$1]) => {
155
- acc[key] = value$1;
156
- return acc;
157
- }, {});
158
- rest.required = schema.required?.filter((key) => !separatedProperties.includes(key));
159
- rest.examples = schema.examples?.map((example) => {
160
- if (!isObject(example)) return example;
161
- return Object.entries(example).reduce((acc, [key, value$1]) => {
162
- if (!separatedProperties.includes(key)) acc[key] = value$1;
163
- return acc;
164
- }, {});
165
- });
166
- return [matched, rest];
167
- }
168
- function filterSchemaBranches(schema, check, matches = []) {
169
- if (check(schema)) {
170
- matches.push(schema);
171
- return [matches, void 0];
172
- }
173
- if (isObject(schema)) {
174
- for (const keyword of ["anyOf", "oneOf"]) if (schema[keyword] && Object.keys(schema).every((k) => k === keyword || !LOGIC_KEYWORDS.includes(k))) {
175
- const rest = schema[keyword].map((s) => filterSchemaBranches(s, check, matches)[1]).filter((v) => !!v);
176
- if (rest.length === 1 && typeof rest[0] === "object") return [matches, {
177
- ...schema,
178
- [keyword]: void 0,
179
- ...rest[0]
180
- }];
181
- return [matches, {
182
- ...schema,
183
- [keyword]: rest
184
- }];
185
- }
186
- }
187
- return [matches, schema];
188
- }
189
- function applySchemaOptionality(required, schema) {
190
- if (required) return schema;
191
- return { anyOf: [schema, { not: {} }] };
192
- }
193
- function expandUnionSchema(schema) {
194
- if (typeof schema === "object") {
195
- for (const keyword of ["anyOf", "oneOf"]) if (schema[keyword] && Object.keys(schema).every((k) => k === keyword || !LOGIC_KEYWORDS.includes(k))) return schema[keyword].flatMap((s) => expandUnionSchema(s));
196
- }
197
- return [schema];
198
- }
199
- function expandArrayableSchema(schema) {
200
- const schemas = expandUnionSchema(schema);
201
- if (schemas.length !== 2) return;
202
- const arraySchema = schemas.find((s) => typeof s === "object" && s.type === "array" && Object.keys(s).filter((k) => LOGIC_KEYWORDS.includes(k)).every((k) => k === "type" || k === "items"));
203
- if (arraySchema === void 0) return;
204
- const items1 = arraySchema.items;
205
- const items2 = schemas.find((s) => s !== arraySchema);
206
- if (stringifyJSON(items1) !== stringifyJSON(items2)) return;
207
- return [items2, arraySchema];
208
- }
209
- const PRIMITIVE_SCHEMA_TYPES = /* @__PURE__ */ new Set([
210
- TypeName.String,
211
- TypeName.Number,
212
- TypeName.Integer,
213
- TypeName.Boolean,
214
- TypeName.Null
215
- ]);
216
- function isPrimitiveSchema(schema) {
217
- return expandUnionSchema(schema).every((s) => {
218
- if (typeof s === "boolean") return false;
219
- if (typeof s.type === "string" && PRIMITIVE_SCHEMA_TYPES.has(s.type)) return true;
220
- if (s.const !== void 0) return true;
221
- return false;
222
- });
223
- }
224
- function toOpenAPIPath(path) {
225
- return standardizeHTTPPath(path).replace(/\/\{\+([^}]+)\}/g, "/{$1}");
226
- }
227
- function toOpenAPIMethod(method) {
228
- return method.toLocaleLowerCase();
229
- }
230
- function toOpenAPIContent(schema) {
231
- const content = {};
232
- const [matches, restSchema] = filterSchemaBranches(schema, isFileSchema);
233
- for (const file of matches) content[file.contentMediaType] = { schema: toOpenAPISchema(file) };
234
- if (restSchema !== void 0) {
235
- content["application/json"] = { schema: toOpenAPISchema(restSchema) };
236
- if (findDeepMatches((v) => isObject(v) && isFileSchema(v), restSchema).values.length > 0) content["multipart/form-data"] = { schema: toOpenAPISchema(restSchema) };
237
- }
238
- return content;
239
- }
240
- function toOpenAPIEventIteratorContent([yieldsRequired, yieldsSchema], [returnsRequired, returnsSchema]) {
241
- return { "text/event-stream": { schema: toOpenAPISchema({ oneOf: [
242
- {
243
- type: "object",
244
- properties: {
245
- event: { const: "message" },
246
- data: yieldsSchema,
247
- id: { type: "string" },
248
- retry: { type: "number" }
249
- },
250
- required: yieldsRequired ? ["event", "data"] : ["event"]
251
- },
252
- {
253
- type: "object",
254
- properties: {
255
- event: { const: "done" },
256
- data: returnsSchema,
257
- id: { type: "string" },
258
- retry: { type: "number" }
259
- },
260
- required: returnsRequired ? ["event", "data"] : ["event"]
261
- },
262
- {
263
- type: "object",
264
- properties: {
265
- event: { const: "error" },
266
- data: {},
267
- id: { type: "string" },
268
- retry: { type: "number" }
269
- },
270
- required: ["event"]
271
- }
272
- ] }) } };
273
- }
274
- function toOpenAPIParameters(schema, parameterIn) {
275
- const parameters = [];
276
- for (const key in schema.properties) {
277
- const keySchema = schema.properties[key];
278
- let isDeepObjectStyle = true;
279
- if (parameterIn !== "query") isDeepObjectStyle = false;
280
- else if (isPrimitiveSchema(keySchema)) isDeepObjectStyle = false;
281
- else {
282
- const [item] = expandArrayableSchema(keySchema) ?? [];
283
- if (item !== void 0 && isPrimitiveSchema(item)) isDeepObjectStyle = false;
284
- }
285
- parameters.push({
286
- name: key,
287
- in: parameterIn,
288
- required: schema.required?.includes(key),
289
- schema: toOpenAPISchema(keySchema),
290
- style: isDeepObjectStyle ? "deepObject" : void 0,
291
- explode: isDeepObjectStyle ? true : void 0,
292
- allowEmptyValue: parameterIn === "query" ? true : void 0,
293
- allowReserved: parameterIn === "query" ? true : void 0
294
- });
295
- }
296
- return parameters;
297
- }
298
- function checkParamsSchema(schema, params) {
299
- const properties = Object.keys(schema.properties ?? {});
300
- const required = schema.required ?? [];
301
- if (properties.length !== params.length || properties.some((v) => !params.includes(v))) return false;
302
- if (required.length !== params.length || required.some((v) => !params.includes(v))) return false;
303
- return true;
304
- }
305
- function toOpenAPISchema(schema) {
306
- return schema === true ? {} : schema === false ? { not: {} } : schema;
307
- }
308
- const OPENAPI_JSON_SCHEMA_REF_PREFIX = "#/components/schemas/";
309
- function resolveOpenAPIJsonSchemaRef(doc, schema) {
310
- if (typeof schema !== "object" || !schema.$ref?.startsWith(OPENAPI_JSON_SCHEMA_REF_PREFIX)) return schema;
311
- const name = schema.$ref.slice(21);
312
- return doc.components?.schemas?.[name] ?? schema;
313
- }
314
- var CompositeSchemaConverter = class {
315
- converters;
316
- constructor(converters) {
317
- this.converters = converters;
318
- }
319
- async convert(schema, options) {
320
- for (const converter of this.converters) if (await converter.condition(schema, options)) return converter.convert(schema, options);
321
- return [false, {}];
322
- }
323
- };
324
- var OpenAPIGeneratorError = class extends Error {};
325
- var OpenAPIGenerator = class {
326
- serializer;
327
- converter;
328
- constructor(options = {}) {
329
- this.serializer = new StandardOpenAPIJsonSerializer(options);
330
- this.converter = new CompositeSchemaConverter(toArray(options.schemaConverters));
331
- }
332
- /**
333
- * Generates OpenAPI specifications from oRPC routers/contracts.
334
- *
335
- * @see {@link https://orpc.unnoq.com/docs/openapi/openapi-specification OpenAPI Specification Docs}
336
- */
337
- async generate(router, { customErrorResponseBodySchema, commonSchemas, filter: baseFilter, exclude,...baseDoc } = {}) {
338
- const filter = baseFilter ?? (({ contract, path }) => {
339
- return !(exclude?.(contract, path) ?? false);
340
- });
341
- const doc = {
342
- ...clone(baseDoc),
343
- info: baseDoc.info ?? {
344
- title: "API Reference",
345
- version: "0.0.0"
346
- },
347
- openapi: "3.1.1"
348
- };
349
- const { baseSchemaConvertOptions, undefinedErrorJsonSchema } = await this.#resolveCommonSchemas(doc, commonSchemas);
350
- const contracts = [];
351
- await resolveContractProcedures({
352
- path: [],
353
- router
354
- }, (traverseOptions) => {
355
- if (!value(filter, traverseOptions)) return;
356
- contracts.push(traverseOptions);
357
- });
358
- const errors = [];
359
- for (const { contract, path } of contracts) {
360
- const stringPath = path.join(".");
361
- try {
362
- const def = contract["~orpc"];
363
- const method = toOpenAPIMethod(fallbackContractConfig("defaultMethod", def.route.method));
364
- const httpPath = toOpenAPIPath(def.route.path ?? toHttpPath(path));
365
- let operationObjectRef;
366
- if (def.route.spec !== void 0 && typeof def.route.spec !== "function") operationObjectRef = def.route.spec;
367
- else {
368
- operationObjectRef = {
369
- operationId: def.route.operationId ?? stringPath,
370
- summary: def.route.summary,
371
- description: def.route.description,
372
- deprecated: def.route.deprecated,
373
- tags: def.route.tags?.map((tag) => tag)
374
- };
375
- await this.#request(doc, operationObjectRef, def, baseSchemaConvertOptions);
376
- await this.#successResponse(doc, operationObjectRef, def, baseSchemaConvertOptions);
377
- await this.#errorResponse(operationObjectRef, def, baseSchemaConvertOptions, undefinedErrorJsonSchema, customErrorResponseBodySchema);
378
- }
379
- if (typeof def.route.spec === "function") operationObjectRef = def.route.spec(operationObjectRef);
380
- doc.paths ??= {};
381
- doc.paths[httpPath] ??= {};
382
- doc.paths[httpPath][method] = applyCustomOpenAPIOperation(operationObjectRef, contract);
383
- } catch (e) {
384
- if (!(e instanceof OpenAPIGeneratorError)) throw e;
385
- errors.push(`[OpenAPIGenerator] Error occurred while generating OpenAPI for procedure at path: ${stringPath}
386
- ${e.message}`);
387
- }
388
- }
389
- if (errors.length) throw new OpenAPIGeneratorError(`Some error occurred during OpenAPI generation:
390
-
391
- ${errors.join("\n\n")}`);
392
- return this.serializer.serialize(doc)[0];
393
- }
394
- async #resolveCommonSchemas(doc, commonSchemas) {
395
- let undefinedErrorJsonSchema = {
396
- type: "object",
397
- properties: {
398
- defined: { const: false },
399
- code: { type: "string" },
400
- status: { type: "number" },
401
- message: { type: "string" },
402
- data: {}
403
- },
404
- required: [
405
- "defined",
406
- "code",
407
- "status",
408
- "message"
409
- ]
410
- };
411
- const baseSchemaConvertOptions = {};
412
- if (commonSchemas) {
413
- baseSchemaConvertOptions.components = [];
414
- for (const key in commonSchemas) {
415
- const options = commonSchemas[key];
416
- if (options.schema === void 0) continue;
417
- const { schema, strategy = "input" } = options;
418
- const [required, json] = await this.converter.convert(schema, { strategy });
419
- const allowedStrategies = [strategy];
420
- if (strategy === "input") {
421
- const [outputRequired, outputJson] = await this.converter.convert(schema, { strategy: "output" });
422
- if (outputRequired === required && stringifyJSON(outputJson) === stringifyJSON(json)) allowedStrategies.push("output");
423
- } else if (strategy === "output") {
424
- const [inputRequired, inputJson] = await this.converter.convert(schema, { strategy: "input" });
425
- if (inputRequired === required && stringifyJSON(inputJson) === stringifyJSON(json)) allowedStrategies.push("input");
426
- }
427
- baseSchemaConvertOptions.components.push({
428
- schema,
429
- required,
430
- ref: `#/components/schemas/${key}`,
431
- allowedStrategies
432
- });
433
- }
434
- doc.components ??= {};
435
- doc.components.schemas ??= {};
436
- for (const key in commonSchemas) {
437
- const options = commonSchemas[key];
438
- if (options.schema === void 0) {
439
- if (options.error === "UndefinedError") {
440
- doc.components.schemas[key] = toOpenAPISchema(undefinedErrorJsonSchema);
441
- undefinedErrorJsonSchema = { $ref: `#/components/schemas/${key}` };
442
- }
443
- continue;
444
- }
445
- const { schema, strategy = "input" } = options;
446
- const [, json] = await this.converter.convert(schema, {
447
- ...baseSchemaConvertOptions,
448
- strategy,
449
- minStructureDepthForRef: 1
450
- });
451
- doc.components.schemas[key] = toOpenAPISchema(json);
452
- }
453
- }
454
- return {
455
- baseSchemaConvertOptions,
456
- undefinedErrorJsonSchema
457
- };
458
- }
459
- async #request(doc, ref, def, baseSchemaConvertOptions) {
460
- const method = fallbackContractConfig("defaultMethod", def.route.method);
461
- const details = getEventIteratorSchemaDetails(def.inputSchema);
462
- if (details) {
463
- ref.requestBody = {
464
- required: true,
465
- content: toOpenAPIEventIteratorContent(await this.converter.convert(details.yields, {
466
- ...baseSchemaConvertOptions,
467
- strategy: "input"
468
- }), await this.converter.convert(details.returns, {
469
- ...baseSchemaConvertOptions,
470
- strategy: "input"
471
- }))
472
- };
473
- return;
474
- }
475
- const dynamicParams = getDynamicParams(def.route.path)?.map((v) => v.name);
476
- const inputStructure = fallbackContractConfig("defaultInputStructure", def.route.inputStructure);
477
- let [required, schema] = await this.converter.convert(def.inputSchema, {
478
- ...baseSchemaConvertOptions,
479
- strategy: "input",
480
- minStructureDepthForRef: dynamicParams?.length || inputStructure === "detailed" ? 1 : 0
481
- });
482
- if (isAnySchema(schema) && !dynamicParams?.length) return;
483
- if (inputStructure === "compact") {
484
- if (dynamicParams?.length) {
485
- const error2 = new OpenAPIGeneratorError("When input structure is \"compact\", and path has dynamic params, input schema must be an object with all dynamic params as required.");
486
- if (!isObjectSchema(schema)) throw error2;
487
- const [paramsSchema, rest] = separateObjectSchema(schema, dynamicParams);
488
- schema = rest;
489
- required = rest.required ? rest.required.length !== 0 : false;
490
- if (!checkParamsSchema(paramsSchema, dynamicParams)) throw error2;
491
- ref.parameters ??= [];
492
- ref.parameters.push(...toOpenAPIParameters(paramsSchema, "path"));
493
- }
494
- if (method === "GET") {
495
- const resolvedSchema = resolveOpenAPIJsonSchemaRef(doc, schema);
496
- if (!isObjectSchema(resolvedSchema)) throw new OpenAPIGeneratorError("When method is \"GET\", input schema must satisfy: object | any | unknown");
497
- ref.parameters ??= [];
498
- ref.parameters.push(...toOpenAPIParameters(resolvedSchema, "query"));
499
- } else ref.requestBody = {
500
- required,
501
- content: toOpenAPIContent(schema)
502
- };
503
- return;
504
- }
505
- const error = new OpenAPIGeneratorError("When input structure is \"detailed\", input schema must satisfy: { params?: Record<string, unknown>, query?: Record<string, unknown>, headers?: Record<string, unknown>, body?: unknown }");
506
- if (!isObjectSchema(schema)) throw error;
507
- const resolvedParamSchema = schema.properties?.params !== void 0 ? resolveOpenAPIJsonSchemaRef(doc, schema.properties.params) : void 0;
508
- if (dynamicParams?.length && (resolvedParamSchema === void 0 || !isObjectSchema(resolvedParamSchema) || !checkParamsSchema(resolvedParamSchema, dynamicParams))) throw new OpenAPIGeneratorError("When input structure is \"detailed\" and path has dynamic params, the \"params\" schema must be an object with all dynamic params as required.");
509
- for (const from of [
510
- "params",
511
- "query",
512
- "headers"
513
- ]) {
514
- const fromSchema = schema.properties?.[from];
515
- if (fromSchema !== void 0) {
516
- const resolvedSchema = resolveOpenAPIJsonSchemaRef(doc, fromSchema);
517
- if (!isObjectSchema(resolvedSchema)) throw error;
518
- const parameterIn = from === "params" ? "path" : from === "headers" ? "header" : "query";
519
- ref.parameters ??= [];
520
- ref.parameters.push(...toOpenAPIParameters(resolvedSchema, parameterIn));
521
- }
522
- }
523
- if (schema.properties?.body !== void 0) ref.requestBody = {
524
- required: schema.required?.includes("body"),
525
- content: toOpenAPIContent(schema.properties.body)
526
- };
527
- }
528
- async #successResponse(doc, ref, def, baseSchemaConvertOptions) {
529
- const outputSchema = def.outputSchema;
530
- const status = fallbackContractConfig("defaultSuccessStatus", def.route.successStatus);
531
- const description = fallbackContractConfig("defaultSuccessDescription", def.route?.successDescription);
532
- const eventIteratorSchemaDetails = getEventIteratorSchemaDetails(outputSchema);
533
- const outputStructure = fallbackContractConfig("defaultOutputStructure", def.route.outputStructure);
534
- if (eventIteratorSchemaDetails) {
535
- ref.responses ??= {};
536
- ref.responses[status] = {
537
- description,
538
- content: toOpenAPIEventIteratorContent(await this.converter.convert(eventIteratorSchemaDetails.yields, {
539
- ...baseSchemaConvertOptions,
540
- strategy: "output"
541
- }), await this.converter.convert(eventIteratorSchemaDetails.returns, {
542
- ...baseSchemaConvertOptions,
543
- strategy: "output"
544
- }))
545
- };
546
- return;
547
- }
548
- const [required, json] = await this.converter.convert(outputSchema, {
549
- ...baseSchemaConvertOptions,
550
- strategy: "output",
551
- minStructureDepthForRef: outputStructure === "detailed" ? 1 : 0
552
- });
553
- if (outputStructure === "compact") {
554
- ref.responses ??= {};
555
- ref.responses[status] = { description };
556
- ref.responses[status].content = toOpenAPIContent(applySchemaOptionality(required, json));
557
- return;
558
- }
559
- const handledStatuses = /* @__PURE__ */ new Set();
560
- for (const item of expandUnionSchema(json)) {
561
- const error = new OpenAPIGeneratorError(`
562
- When output structure is "detailed", output schema must satisfy:
563
- {
564
- status?: number, // must be a literal number and in the range of 200-399
565
- headers?: Record<string, unknown>,
566
- body?: unknown
567
- }
568
-
569
- But got: ${stringifyJSON(item)}
570
- `);
571
- if (!isObjectSchema(item)) throw error;
572
- let schemaStatus;
573
- let schemaDescription;
574
- if (item.properties?.status !== void 0) {
575
- const statusSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.status);
576
- if (typeof statusSchema !== "object" || statusSchema.const === void 0 || typeof statusSchema.const !== "number" || !Number.isInteger(statusSchema.const) || isORPCErrorStatus(statusSchema.const)) throw error;
577
- schemaStatus = statusSchema.const;
578
- schemaDescription = statusSchema.description;
579
- }
580
- const itemStatus = schemaStatus ?? status;
581
- const itemDescription = schemaDescription ?? description;
582
- if (handledStatuses.has(itemStatus)) throw new OpenAPIGeneratorError(`
583
- When output structure is "detailed", each success status must be unique.
584
- But got status: ${itemStatus} used more than once.
585
- `);
586
- handledStatuses.add(itemStatus);
587
- ref.responses ??= {};
588
- ref.responses[itemStatus] = { description: itemDescription };
589
- if (item.properties?.headers !== void 0) {
590
- const headersSchema = resolveOpenAPIJsonSchemaRef(doc, item.properties.headers);
591
- if (!isObjectSchema(headersSchema)) throw error;
592
- for (const key in headersSchema.properties) {
593
- const headerSchema = headersSchema.properties[key];
594
- if (headerSchema !== void 0) {
595
- ref.responses[itemStatus].headers ??= {};
596
- ref.responses[itemStatus].headers[key] = {
597
- schema: toOpenAPISchema(headerSchema),
598
- required: item.required?.includes("headers") && headersSchema.required?.includes(key)
599
- };
600
- }
601
- }
602
- }
603
- if (item.properties?.body !== void 0) ref.responses[itemStatus].content = toOpenAPIContent(applySchemaOptionality(item.required?.includes("body") ?? false, item.properties.body));
604
- }
605
- }
606
- async #errorResponse(ref, def, baseSchemaConvertOptions, undefinedErrorSchema, customErrorResponseBodySchema) {
607
- const errorMap = def.errorMap;
608
- const errorResponsesByStatus = {};
609
- for (const code in errorMap) {
610
- const config = errorMap[code];
611
- if (!config) continue;
612
- const status = fallbackORPCErrorStatus(code, config.status);
613
- const defaultMessage = fallbackORPCErrorMessage(code, config.message);
614
- errorResponsesByStatus[status] ??= {
615
- status,
616
- definedErrorDefinitions: [],
617
- errorSchemaVariants: []
618
- };
619
- const [dataRequired, dataSchema] = await this.converter.convert(config.data, {
620
- ...baseSchemaConvertOptions,
621
- strategy: "output"
622
- });
623
- errorResponsesByStatus[status].definedErrorDefinitions.push([
624
- code,
625
- defaultMessage,
626
- dataRequired,
627
- dataSchema
628
- ]);
629
- errorResponsesByStatus[status].errorSchemaVariants.push({
630
- type: "object",
631
- properties: {
632
- defined: { const: true },
633
- code: { const: code },
634
- status: { const: status },
635
- message: {
636
- type: "string",
637
- default: defaultMessage
638
- },
639
- data: dataSchema
640
- },
641
- required: dataRequired ? [
642
- "defined",
643
- "code",
644
- "status",
645
- "message",
646
- "data"
647
- ] : [
648
- "defined",
649
- "code",
650
- "status",
651
- "message"
652
- ]
653
- });
654
- }
655
- ref.responses ??= {};
656
- for (const statusString in errorResponsesByStatus) {
657
- const errorResponse = errorResponsesByStatus[statusString];
658
- const customBodySchema = value(customErrorResponseBodySchema, errorResponse.definedErrorDefinitions, errorResponse.status);
659
- ref.responses[statusString] = {
660
- description: statusString,
661
- content: toOpenAPIContent(customBodySchema ?? { oneOf: [...errorResponse.errorSchemaVariants, undefinedErrorSchema] })
662
- };
663
- }
664
- }
665
- };
666
-
667
- //#endregion
668
- export { ContentEncoding as n, Format as r, OpenAPIGenerator as t };
669
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFwaS5EclRjZWxsNS1DNmt5RHlVSy5tanMiLCJuYW1lcyI6WyJ2YWx1ZSIsIiNyZXNvbHZlQ29tbW9uU2NoZW1hcyIsIiNyZXF1ZXN0IiwiI3N1Y2Nlc3NSZXNwb25zZSIsIiNlcnJvclJlc3BvbnNlIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vbm9kZV9tb2R1bGVzLy5idW4vQG9ycGMraW50ZXJvcEAxLjEwLjQvbm9kZV9tb2R1bGVzL0BvcnBjL2ludGVyb3AvZGlzdC9qc29uLXNjaGVtYS10eXBlZC9pbmRleC5tanMiLCIuLi8uLi8uLi9ub2RlX21vZHVsZXMvLmJ1bi9Ab3JwYytvcGVuYXBpQDEuMTAuNC9ub2RlX21vZHVsZXMvQG9ycGMvb3BlbmFwaS9kaXN0L3NoYXJlZC9vcGVuYXBpLkRyVGNlbGw1Lm1qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLy8gPHJlZmVyZW5jZSB0eXBlcz1cIi4vZHJhZnQtMjAyMC0xMi50c1wiIC8+XG4vLyBAZ2VuZXJhdGVkXG4vLyBkZW5vLWZtdC1pZ25vcmUtZmlsZVxuLy8gZGVuby1saW50LWlnbm9yZS1maWxlXG4vLyBUaGlzIGNvZGUgd2FzIGJ1bmRsZWQgdXNpbmcgYGRlbm8gYnVuZGxlYCBhbmQgaXQncyBub3QgcmVjb21tZW5kZWQgdG8gZWRpdCBpdCBtYW51YWxseVxuXG5jb25zdCBkcmFmdCA9IFwiMjAyMC0xMlwiO1xuY29uc3QgJHNjaGVtYSA9IFwiaHR0cHM6Ly9qc29uLXNjaGVtYS5vcmcvZHJhZnQvMjAyMC0xMi9zY2hlbWFcIjtcbnZhciBDb250ZW50RW5jb2Rpbmc7XG4oZnVuY3Rpb24oQ29udGVudEVuY29kaW5nMSkge1xuICAgIENvbnRlbnRFbmNvZGluZzFbXCI3Yml0XCJdID0gXCI3Yml0XCI7XG4gICAgQ29udGVudEVuY29kaW5nMVtcIjhiaXRcIl0gPSBcIjhiaXRcIjtcbiAgICBDb250ZW50RW5jb2RpbmcxW1wiQmFzZTY0XCJdID0gXCJiYXNlNjRcIjtcbiAgICBDb250ZW50RW5jb2RpbmcxW1wiQmluYXJ5XCJdID0gXCJiaW5hcnlcIjtcbiAgICBDb250ZW50RW5jb2RpbmcxW1wiSUVURlRva2VuXCJdID0gXCJpZXRmLXRva2VuXCI7XG4gICAgQ29udGVudEVuY29kaW5nMVtcIlF1b3RlZFByaW50YWJsZVwiXSA9IFwicXVvdGVkLXByaW50YWJsZVwiO1xuICAgIENvbnRlbnRFbmNvZGluZzFbXCJYVG9rZW5cIl0gPSBcIngtdG9rZW5cIjtcbn0pKENvbnRlbnRFbmNvZGluZyB8fCAoQ29udGVudEVuY29kaW5nID0ge30pKTtcbnZhciBGb3JtYXQ7XG4oZnVuY3Rpb24oRm9ybWF0MSkge1xuICAgIEZvcm1hdDFbXCJEYXRlXCJdID0gXCJkYXRlXCI7XG4gICAgRm9ybWF0MVtcIkRhdGVUaW1lXCJdID0gXCJkYXRlLXRpbWVcIjtcbiAgICBGb3JtYXQxW1wiRHVyYXRpb25cIl0gPSBcImR1cmF0aW9uXCI7XG4gICAgRm9ybWF0MVtcIkVtYWlsXCJdID0gXCJlbWFpbFwiO1xuICAgIEZvcm1hdDFbXCJIb3N0bmFtZVwiXSA9IFwiaG9zdG5hbWVcIjtcbiAgICBGb3JtYXQxW1wiSURORW1haWxcIl0gPSBcImlkbi1lbWFpbFwiO1xuICAgIEZvcm1hdDFbXCJJRE5Ib3N0bmFtZVwiXSA9IFwiaWRuLWhvc3RuYW1lXCI7XG4gICAgRm9ybWF0MVtcIklQdjRcIl0gPSBcImlwdjRcIjtcbiAgICBGb3JtYXQxW1wiSVB2NlwiXSA9IFwiaXB2NlwiO1xuICAgIEZvcm1hdDFbXCJJUklcIl0gPSBcImlyaVwiO1xuICAgIEZvcm1hdDFbXCJJUklSZWZlcmVuY2VcIl0gPSBcImlyaS1yZWZlcmVuY2VcIjtcbiAgICBGb3JtYXQxW1wiSlNPTlBvaW50ZXJcIl0gPSBcImpzb24tcG9pbnRlclwiO1xuICAgIEZvcm1hdDFbXCJKU09OUG9pbnRlclVSSUZyYWdtZW50XCJdID0gXCJqc29uLXBvaW50ZXItdXJpLWZyYWdtZW50XCI7XG4gICAgRm9ybWF0MVtcIlJlZ0V4XCJdID0gXCJyZWdleFwiO1xuICAgIEZvcm1hdDFbXCJSZWxhdGl2ZUpTT05Qb2ludGVyXCJdID0gXCJyZWxhdGl2ZS1qc29uLXBvaW50ZXJcIjtcbiAgICBGb3JtYXQxW1wiVGltZVwiXSA9IFwidGltZVwiO1xuICAgIEZvcm1hdDFbXCJVUklcIl0gPSBcInVyaVwiO1xuICAgIEZvcm1hdDFbXCJVUklSZWZlcmVuY2VcIl0gPSBcInVyaS1yZWZlcmVuY2VcIjtcbiAgICBGb3JtYXQxW1wiVVJJVGVtcGxhdGVcIl0gPSBcInVyaS10ZW1wbGF0ZVwiO1xuICAgIEZvcm1hdDFbXCJVVUlEXCJdID0gXCJ1dWlkXCI7XG59KShGb3JtYXQgfHwgKEZvcm1hdCA9IHt9KSk7XG52YXIgVHlwZU5hbWU7XG4oZnVuY3Rpb24oVHlwZU5hbWUxKSB7XG4gICAgVHlwZU5hbWUxW1wiQXJyYXlcIl0gPSBcImFycmF5XCI7XG4gICAgVHlwZU5hbWUxW1wiQm9vbGVhblwiXSA9IFwiYm9vbGVhblwiO1xuICAgIFR5cGVOYW1lMVtcIkludGVnZXJcIl0gPSBcImludGVnZXJcIjtcbiAgICBUeXBlTmFtZTFbXCJOdWxsXCJdID0gXCJudWxsXCI7XG4gICAgVHlwZU5hbWUxW1wiTnVtYmVyXCJdID0gXCJudW1iZXJcIjtcbiAgICBUeXBlTmFtZTFbXCJPYmplY3RcIl0gPSBcIm9iamVjdFwiO1xuICAgIFR5cGVOYW1lMVtcIlN0cmluZ1wiXSA9IFwic3RyaW5nXCI7XG59KShUeXBlTmFtZSB8fCAoVHlwZU5hbWUgPSB7fSkpO1xuY29uc3Qga2V5d29yZHMgPSBbXG4gICAgXCIkYW5jaG9yXCIsXG4gICAgXCIkY29tbWVudFwiLFxuICAgIFwiJGRlZnNcIixcbiAgICBcIiRkeW5hbWljQW5jaG9yXCIsXG4gICAgXCIkZHluYW1pY1JlZlwiLFxuICAgIFwiJGlkXCIsXG4gICAgXCIkcmVmXCIsXG4gICAgXCIkc2NoZW1hXCIsXG4gICAgXCIkdm9jYWJ1bGFyeVwiLFxuICAgIFwiYWRkaXRpb25hbEl0ZW1zXCIsXG4gICAgXCJhZGRpdGlvbmFsUHJvcGVydGllc1wiLFxuICAgIFwiYWxsT2ZcIixcbiAgICBcImFueU9mXCIsXG4gICAgXCJjb25zdFwiLFxuICAgIFwiY29udGFpbnNcIixcbiAgICBcImNvbnRlbnRFbmNvZGluZ1wiLFxuICAgIFwiY29udGVudE1lZGlhVHlwZVwiLFxuICAgIFwiY29udGVudFNjaGVtYVwiLFxuICAgIFwiZGVmYXVsdFwiLFxuICAgIFwiZGVmaW5pdGlvbnNcIixcbiAgICBcImRlcGVuZGVuY2llc1wiLFxuICAgIFwiZGVwZW5kZW50UmVxdWlyZWRcIixcbiAgICBcImRlcGVuZGVudFNjaGVtYXNcIixcbiAgICBcImRlcHJlY2F0ZWRcIixcbiAgICBcImRlc2NyaXB0aW9uXCIsXG4gICAgXCJlbHNlXCIsXG4gICAgXCJlbnVtXCIsXG4gICAgXCJleGFtcGxlc1wiLFxuICAgIFwiZXhjbHVzaXZlTWF4aW11bVwiLFxuICAgIFwiZXhjbHVzaXZlTWluaW11bVwiLFxuICAgIFwiZm9ybWF0XCIsXG4gICAgXCJpZlwiLFxuICAgIFwiaXRlbXNcIixcbiAgICBcIm1heENvbnRhaW5zXCIsXG4gICAgXCJtYXhpbXVtXCIsXG4gICAgXCJtYXhJdGVtc1wiLFxuICAgIFwibWF4TGVuZ3RoXCIsXG4gICAgXCJtYXhQcm9wZXJ0aWVzXCIsXG4gICAgXCJtaW5Db250YWluc1wiLFxuICAgIFwibWluaW11bVwiLFxuICAgIFwibWluSXRlbXNcIixcbiAgICBcIm1pbkxlbmd0aFwiLFxuICAgIFwibWluUHJvcGVydGllc1wiLFxuICAgIFwibXVsdGlwbGVPZlwiLFxuICAgIFwibm90XCIsXG4gICAgXCJvbmVPZlwiLFxuICAgIFwicGF0dGVyblwiLFxuICAgIFwicGF0dGVyblByb3BlcnRpZXNcIixcbiAgICBcInByZWZpeEl0ZW1zXCIsXG4gICAgXCJwcm9wZXJ0aWVzXCIsXG4gICAgXCJwcm9wZXJ0eU5hbWVzXCIsXG4gICAgXCJyZWFkT25seVwiLFxuICAgIFwicmVxdWlyZWRcIixcbiAgICBcInRoZW5cIixcbiAgICBcInRpdGxlXCIsXG4gICAgXCJ0eXBlXCIsXG4gICAgXCJ1bmV2YWx1YXRlZEl0ZW1zXCIsXG4gICAgXCJ1bmV2YWx1YXRlZFByb3BlcnRpZXNcIixcbiAgICBcInVuaXF1ZUl0ZW1zXCIsXG4gICAgXCJ3cml0ZU9ubHlcIiwgXG5dO1xuXG5leHBvcnQgeyAkc2NoZW1hLCBDb250ZW50RW5jb2RpbmcsIEZvcm1hdCwgVHlwZU5hbWUsIGRyYWZ0LCBrZXl3b3JkcyB9O1xuIiwiaW1wb3J0IHsgaXNPUlBDRXJyb3JTdGF0dXMsIGZhbGxiYWNrT1JQQ0Vycm9yU3RhdHVzLCBmYWxsYmFja09SUENFcnJvck1lc3NhZ2UgfSBmcm9tICdAb3JwYy9jbGllbnQnO1xuaW1wb3J0IHsgdG9IdHRwUGF0aCB9IGZyb20gJ0BvcnBjL2NsaWVudC9zdGFuZGFyZCc7XG5pbXBvcnQgeyBmYWxsYmFja0NvbnRyYWN0Q29uZmlnLCBnZXRFdmVudEl0ZXJhdG9yU2NoZW1hRGV0YWlscyB9IGZyb20gJ0BvcnBjL2NvbnRyYWN0JztcbmltcG9ydCB7IHN0YW5kYXJkaXplSFRUUFBhdGgsIFN0YW5kYXJkT3BlbkFQSUpzb25TZXJpYWxpemVyLCBnZXREeW5hbWljUGFyYW1zIH0gZnJvbSAnQG9ycGMvb3BlbmFwaS1jbGllbnQvc3RhbmRhcmQnO1xuaW1wb3J0IHsgaXNQcm9jZWR1cmUsIHJlc29sdmVDb250cmFjdFByb2NlZHVyZXMgfSBmcm9tICdAb3JwYy9zZXJ2ZXInO1xuaW1wb3J0IHsgaXNPYmplY3QsIHN0cmluZ2lmeUpTT04sIGZpbmREZWVwTWF0Y2hlcywgdG9BcnJheSwgY2xvbmUsIHZhbHVlIH0gZnJvbSAnQG9ycGMvc2hhcmVkJztcbmltcG9ydCB7IFR5cGVOYW1lIH0gZnJvbSAnQG9ycGMvaW50ZXJvcC9qc29uLXNjaGVtYS10eXBlZC9kcmFmdC0yMDIwLTEyJztcblxuY29uc3QgT1BFUkFUSU9OX0VYVEVOREVSX1NZTUJPTCA9IFN5bWJvbChcIk9SUENfT1BFUkFUSU9OX0VYVEVOREVSXCIpO1xuZnVuY3Rpb24gY3VzdG9tT3BlbkFQSU9wZXJhdGlvbihvLCBleHRlbmQpIHtcbiAgcmV0dXJuIG5ldyBQcm94eShvLCB7XG4gICAgZ2V0KHRhcmdldCwgcHJvcCwgcmVjZWl2ZXIpIHtcbiAgICAgIGlmIChwcm9wID09PSBPUEVSQVRJT05fRVhURU5ERVJfU1lNQk9MKSB7XG4gICAgICAgIHJldHVybiBleHRlbmQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gUmVmbGVjdC5nZXQodGFyZ2V0LCBwcm9wLCByZWNlaXZlcik7XG4gICAgfVxuICB9KTtcbn1cbmZ1bmN0aW9uIGdldEN1c3RvbU9wZW5BUElPcGVyYXRpb24obykge1xuICByZXR1cm4gb1tPUEVSQVRJT05fRVhURU5ERVJfU1lNQk9MXTtcbn1cbmZ1bmN0aW9uIGFwcGx5Q3VzdG9tT3BlbkFQSU9wZXJhdGlvbihvcGVyYXRpb24sIGNvbnRyYWN0KSB7XG4gIGNvbnN0IG9wZXJhdGlvbkN1c3RvbXMgPSBbXTtcbiAgZm9yIChjb25zdCBlcnJvckl0ZW0gb2YgT2JqZWN0LnZhbHVlcyhjb250cmFjdFtcIn5vcnBjXCJdLmVycm9yTWFwKSkge1xuICAgIGNvbnN0IG1heWJlRXh0ZW5kZXIgPSBlcnJvckl0ZW0gPyBnZXRDdXN0b21PcGVuQVBJT3BlcmF0aW9uKGVycm9ySXRlbSkgOiB2b2lkIDA7XG4gICAgaWYgKG1heWJlRXh0ZW5kZXIpIHtcbiAgICAgIG9wZXJhdGlvbkN1c3RvbXMucHVzaChtYXliZUV4dGVuZGVyKTtcbiAgICB9XG4gIH1cbiAgaWYgKGlzUHJvY2VkdXJlKGNvbnRyYWN0KSkge1xuICAgIGZvciAoY29uc3QgbWlkZGxld2FyZSBvZiBjb250cmFjdFtcIn5vcnBjXCJdLm1pZGRsZXdhcmVzKSB7XG4gICAgICBjb25zdCBtYXliZUV4dGVuZGVyID0gZ2V0Q3VzdG9tT3BlbkFQSU9wZXJhdGlvbihtaWRkbGV3YXJlKTtcbiAgICAgIGlmIChtYXliZUV4dGVuZGVyKSB7XG4gICAgICAgIG9wZXJhdGlvbkN1c3RvbXMucHVzaChtYXliZUV4dGVuZGVyKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgbGV0IGN1cnJlbnRPcGVyYXRpb24gPSBvcGVyYXRpb247XG4gIGZvciAoY29uc3QgY3VzdG9tIG9mIG9wZXJhdGlvbkN1c3RvbXMpIHtcbiAgICBpZiAodHlwZW9mIGN1c3RvbSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICBjdXJyZW50T3BlcmF0aW9uID0gY3VzdG9tKGN1cnJlbnRPcGVyYXRpb24sIGNvbnRyYWN0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY3VycmVudE9wZXJhdGlvbiA9IHtcbiAgICAgICAgLi4uY3VycmVudE9wZXJhdGlvbixcbiAgICAgICAgLi4uY3VzdG9tXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICByZXR1cm4gY3VycmVudE9wZXJhdGlvbjtcbn1cblxuY29uc3QgTE9HSUNfS0VZV09SRFMgPSBbXG4gIFwiJGR5bmFtaWNSZWZcIixcbiAgXCIkcmVmXCIsXG4gIFwiYWRkaXRpb25hbEl0ZW1zXCIsXG4gIFwiYWRkaXRpb25hbFByb3BlcnRpZXNcIixcbiAgXCJhbGxPZlwiLFxuICBcImFueU9mXCIsXG4gIFwiY29uc3RcIixcbiAgXCJjb250YWluc1wiLFxuICBcImNvbnRlbnRFbmNvZGluZ1wiLFxuICBcImNvbnRlbnRNZWRpYVR5cGVcIixcbiAgXCJjb250ZW50U2NoZW1hXCIsXG4gIFwiZGVwZW5kZW5jaWVzXCIsXG4gIFwiZGVwZW5kZW50UmVxdWlyZWRcIixcbiAgXCJkZXBlbmRlbnRTY2hlbWFzXCIsXG4gIFwiZWxzZVwiLFxuICBcImVudW1cIixcbiAgXCJleGNsdXNpdmVNYXhpbXVtXCIsXG4gIFwiZXhjbHVzaXZlTWluaW11bVwiLFxuICBcImZvcm1hdFwiLFxuICBcImlmXCIsXG4gIFwiaXRlbXNcIixcbiAgXCJtYXhDb250YWluc1wiLFxuICBcIm1heGltdW1cIixcbiAgXCJtYXhJdGVtc1wiLFxuICBcIm1heExlbmd0aFwiLFxuICBcIm1heFByb3BlcnRpZXNcIixcbiAgXCJtaW5Db250YWluc1wiLFxuICBcIm1pbmltdW1cIixcbiAgXCJtaW5JdGVtc1wiLFxuICBcIm1pbkxlbmd0aFwiLFxuICBcIm1pblByb3BlcnRpZXNcIixcbiAgXCJtdWx0aXBsZU9mXCIsXG4gIFwibm90XCIsXG4gIFwib25lT2ZcIixcbiAgXCJwYXR0ZXJuXCIsXG4gIFwicGF0dGVyblByb3BlcnRpZXNcIixcbiAgXCJwcmVmaXhJdGVtc1wiLFxuICBcInByb3BlcnRpZXNcIixcbiAgXCJwcm9wZXJ0eU5hbWVzXCIsXG4gIFwicmVxdWlyZWRcIixcbiAgXCJ0aGVuXCIsXG4gIFwidHlwZVwiLFxuICBcInVuZXZhbHVhdGVkSXRlbXNcIixcbiAgXCJ1bmV2YWx1YXRlZFByb3BlcnRpZXNcIixcbiAgXCJ1bmlxdWVJdGVtc1wiXG5dO1xuXG5mdW5jdGlvbiBpc0ZpbGVTY2hlbWEoc2NoZW1hKSB7XG4gIHJldHVybiBpc09iamVjdChzY2hlbWEpICYmIHNjaGVtYS50eXBlID09PSBcInN0cmluZ1wiICYmIHR5cGVvZiBzY2hlbWEuY29udGVudE1lZGlhVHlwZSA9PT0gXCJzdHJpbmdcIjtcbn1cbmZ1bmN0aW9uIGlzT2JqZWN0U2NoZW1hKHNjaGVtYSkge1xuICByZXR1cm4gaXNPYmplY3Qoc2NoZW1hKSAmJiBzY2hlbWEudHlwZSA9PT0gXCJvYmplY3RcIjtcbn1cbmZ1bmN0aW9uIGlzQW55U2NoZW1hKHNjaGVtYSkge1xuICBpZiAoc2NoZW1hID09PSB0cnVlKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKE9iamVjdC5rZXlzKHNjaGVtYSkuZXZlcnkoKGspID0+ICFMT0dJQ19LRVlXT1JEUy5pbmNsdWRlcyhrKSkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5mdW5jdGlvbiBzZXBhcmF0ZU9iamVjdFNjaGVtYShzY2hlbWEsIHNlcGFyYXRlZFByb3BlcnRpZXMpIHtcbiAgaWYgKE9iamVjdC5rZXlzKHNjaGVtYSkuc29tZShcbiAgICAoaykgPT4gIVtcInR5cGVcIiwgXCJwcm9wZXJ0aWVzXCIsIFwicmVxdWlyZWRcIiwgXCJhZGRpdGlvbmFsUHJvcGVydGllc1wiXS5pbmNsdWRlcyhrKSAmJiBMT0dJQ19LRVlXT1JEUy5pbmNsdWRlcyhrKSAmJiBzY2hlbWFba10gIT09IHZvaWQgMFxuICApKSB7XG4gICAgcmV0dXJuIFt7IHR5cGU6IFwib2JqZWN0XCIgfSwgc2NoZW1hXTtcbiAgfVxuICBjb25zdCBtYXRjaGVkID0geyAuLi5zY2hlbWEgfTtcbiAgY29uc3QgcmVzdCA9IHsgLi4uc2NoZW1hIH07XG4gIG1hdGNoZWQucHJvcGVydGllcyA9IHNlcGFyYXRlZFByb3BlcnRpZXMucmVkdWNlKChhY2MsIGtleSkgPT4ge1xuICAgIGNvbnN0IGtleVNjaGVtYSA9IHNjaGVtYS5wcm9wZXJ0aWVzPy5ba2V5XSA/PyBzY2hlbWEuYWRkaXRpb25hbFByb3BlcnRpZXM7XG4gICAgaWYgKGtleVNjaGVtYSAhPT0gdm9pZCAwKSB7XG4gICAgICBhY2Nba2V5XSA9IGtleVNjaGVtYTtcbiAgICB9XG4gICAgcmV0dXJuIGFjYztcbiAgfSwge30pO1xuICBtYXRjaGVkLnJlcXVpcmVkID0gc2NoZW1hLnJlcXVpcmVkPy5maWx0ZXIoKGtleSkgPT4gc2VwYXJhdGVkUHJvcGVydGllcy5pbmNsdWRlcyhrZXkpKTtcbiAgbWF0Y2hlZC5leGFtcGxlcyA9IHNjaGVtYS5leGFtcGxlcz8ubWFwKChleGFtcGxlKSA9PiB7XG4gICAgaWYgKCFpc09iamVjdChleGFtcGxlKSkge1xuICAgICAgcmV0dXJuIGV4YW1wbGU7XG4gICAgfVxuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhleGFtcGxlKS5yZWR1Y2UoKGFjYywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBpZiAoc2VwYXJhdGVkUHJvcGVydGllcy5pbmNsdWRlcyhrZXkpKSB7XG4gICAgICAgIGFjY1trZXldID0gdmFsdWU7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9KTtcbiAgfSk7XG4gIHJlc3QucHJvcGVydGllcyA9IHNjaGVtYS5wcm9wZXJ0aWVzICYmIE9iamVjdC5lbnRyaWVzKHNjaGVtYS5wcm9wZXJ0aWVzKS5maWx0ZXIoKFtrZXldKSA9PiAhc2VwYXJhdGVkUHJvcGVydGllcy5pbmNsdWRlcyhrZXkpKS5yZWR1Y2UoKGFjYywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgYWNjW2tleV0gPSB2YWx1ZTtcbiAgICByZXR1cm4gYWNjO1xuICB9LCB7fSk7XG4gIHJlc3QucmVxdWlyZWQgPSBzY2hlbWEucmVxdWlyZWQ/LmZpbHRlcigoa2V5KSA9PiAhc2VwYXJhdGVkUHJvcGVydGllcy5pbmNsdWRlcyhrZXkpKTtcbiAgcmVzdC5leGFtcGxlcyA9IHNjaGVtYS5leGFtcGxlcz8ubWFwKChleGFtcGxlKSA9PiB7XG4gICAgaWYgKCFpc09iamVjdChleGFtcGxlKSkge1xuICAgICAgcmV0dXJuIGV4YW1wbGU7XG4gICAgfVxuICAgIHJldHVybiBPYmplY3QuZW50cmllcyhleGFtcGxlKS5yZWR1Y2UoKGFjYywgW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBpZiAoIXNlcGFyYXRlZFByb3BlcnRpZXMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICBhY2Nba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG4gIH0pO1xuICByZXR1cm4gW21hdGNoZWQsIHJlc3RdO1xufVxuZnVuY3Rpb24gZmlsdGVyU2NoZW1hQnJhbmNoZXMoc2NoZW1hLCBjaGVjaywgbWF0Y2hlcyA9IFtdKSB7XG4gIGlmIChjaGVjayhzY2hlbWEpKSB7XG4gICAgbWF0Y2hlcy5wdXNoKHNjaGVtYSk7XG4gICAgcmV0dXJuIFttYXRjaGVzLCB2b2lkIDBdO1xuICB9XG4gIGlmIChpc09iamVjdChzY2hlbWEpKSB7XG4gICAgZm9yIChjb25zdCBrZXl3b3JkIG9mIFtcImFueU9mXCIsIFwib25lT2ZcIl0pIHtcbiAgICAgIGlmIChzY2hlbWFba2V5d29yZF0gJiYgT2JqZWN0LmtleXMoc2NoZW1hKS5ldmVyeShcbiAgICAgICAgKGspID0+IGsgPT09IGtleXdvcmQgfHwgIUxPR0lDX0tFWVdPUkRTLmluY2x1ZGVzKGspXG4gICAgICApKSB7XG4gICAgICAgIGNvbnN0IHJlc3QgPSBzY2hlbWFba2V5d29yZF0ubWFwKChzKSA9PiBmaWx0ZXJTY2hlbWFCcmFuY2hlcyhzLCBjaGVjaywgbWF0Y2hlcylbMV0pLmZpbHRlcigodikgPT4gISF2KTtcbiAgICAgICAgaWYgKHJlc3QubGVuZ3RoID09PSAxICYmIHR5cGVvZiByZXN0WzBdID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgcmV0dXJuIFttYXRjaGVzLCB7IC4uLnNjaGVtYSwgW2tleXdvcmRdOiB2b2lkIDAsIC4uLnJlc3RbMF0gfV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFttYXRjaGVzLCB7IC4uLnNjaGVtYSwgW2tleXdvcmRdOiByZXN0IH1dO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gW21hdGNoZXMsIHNjaGVtYV07XG59XG5mdW5jdGlvbiBhcHBseVNjaGVtYU9wdGlvbmFsaXR5KHJlcXVpcmVkLCBzY2hlbWEpIHtcbiAgaWYgKHJlcXVpcmVkKSB7XG4gICAgcmV0dXJuIHNjaGVtYTtcbiAgfVxuICByZXR1cm4ge1xuICAgIGFueU9mOiBbXG4gICAgICBzY2hlbWEsXG4gICAgICB7IG5vdDoge30gfVxuICAgIF1cbiAgfTtcbn1cbmZ1bmN0aW9uIGV4cGFuZFVuaW9uU2NoZW1hKHNjaGVtYSkge1xuICBpZiAodHlwZW9mIHNjaGVtYSA9PT0gXCJvYmplY3RcIikge1xuICAgIGZvciAoY29uc3Qga2V5d29yZCBvZiBbXCJhbnlPZlwiLCBcIm9uZU9mXCJdKSB7XG4gICAgICBpZiAoc2NoZW1hW2tleXdvcmRdICYmIE9iamVjdC5rZXlzKHNjaGVtYSkuZXZlcnkoXG4gICAgICAgIChrKSA9PiBrID09PSBrZXl3b3JkIHx8ICFMT0dJQ19LRVlXT1JEUy5pbmNsdWRlcyhrKVxuICAgICAgKSkge1xuICAgICAgICByZXR1cm4gc2NoZW1hW2tleXdvcmRdLmZsYXRNYXAoKHMpID0+IGV4cGFuZFVuaW9uU2NoZW1hKHMpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIFtzY2hlbWFdO1xufVxuZnVuY3Rpb24gZXhwYW5kQXJyYXlhYmxlU2NoZW1hKHNjaGVtYSkge1xuICBjb25zdCBzY2hlbWFzID0gZXhwYW5kVW5pb25TY2hlbWEoc2NoZW1hKTtcbiAgaWYgKHNjaGVtYXMubGVuZ3RoICE9PSAyKSB7XG4gICAgcmV0dXJuIHZvaWQgMDtcbiAgfVxuICBjb25zdCBhcnJheVNjaGVtYSA9IHNjaGVtYXMuZmluZChcbiAgICAocykgPT4gdHlwZW9mIHMgPT09IFwib2JqZWN0XCIgJiYgcy50eXBlID09PSBcImFycmF5XCIgJiYgT2JqZWN0LmtleXMocykuZmlsdGVyKChrKSA9PiBMT0dJQ19LRVlXT1JEUy5pbmNsdWRlcyhrKSkuZXZlcnkoKGspID0+IGsgPT09IFwidHlwZVwiIHx8IGsgPT09IFwiaXRlbXNcIilcbiAgKTtcbiAgaWYgKGFycmF5U2NoZW1hID09PSB2b2lkIDApIHtcbiAgICByZXR1cm4gdm9pZCAwO1xuICB9XG4gIGNvbnN0IGl0ZW1zMSA9IGFycmF5U2NoZW1hLml0ZW1zO1xuICBjb25zdCBpdGVtczIgPSBzY2hlbWFzLmZpbmQoKHMpID0+IHMgIT09IGFycmF5U2NoZW1hKTtcbiAgaWYgKHN0cmluZ2lmeUpTT04oaXRlbXMxKSAhPT0gc3RyaW5naWZ5SlNPTihpdGVtczIpKSB7XG4gICAgcmV0dXJuIHZvaWQgMDtcbiAgfVxuICByZXR1cm4gW2l0ZW1zMiwgYXJyYXlTY2hlbWFdO1xufVxuY29uc3QgUFJJTUlUSVZFX1NDSEVNQV9UWVBFUyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KFtcbiAgVHlwZU5hbWUuU3RyaW5nLFxuICBUeXBlTmFtZS5OdW1iZXIsXG4gIFR5cGVOYW1lLkludGVnZXIsXG4gIFR5cGVOYW1lLkJvb2xlYW4sXG4gIFR5cGVOYW1lLk51bGxcbl0pO1xuZnVuY3Rpb24gaXNQcmltaXRpdmVTY2hlbWEoc2NoZW1hKSB7XG4gIHJldHVybiBleHBhbmRVbmlvblNjaGVtYShzY2hlbWEpLmV2ZXJ5KChzKSA9PiB7XG4gICAgaWYgKHR5cGVvZiBzID09PSBcImJvb2xlYW5cIikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHMudHlwZSA9PT0gXCJzdHJpbmdcIiAmJiBQUklNSVRJVkVfU0NIRU1BX1RZUEVTLmhhcyhzLnR5cGUpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHMuY29uc3QgIT09IHZvaWQgMCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHRvT3BlbkFQSVBhdGgocGF0aCkge1xuICByZXR1cm4gc3RhbmRhcmRpemVIVFRQUGF0aChwYXRoKS5yZXBsYWNlKC9cXC9cXHtcXCsoW159XSspXFx9L2csIFwiL3skMX1cIik7XG59XG5mdW5jdGlvbiB0b09wZW5BUElNZXRob2QobWV0aG9kKSB7XG4gIHJldHVybiBtZXRob2QudG9Mb2NhbGVMb3dlckNhc2UoKTtcbn1cbmZ1bmN0aW9uIHRvT3BlbkFQSUNvbnRlbnQoc2NoZW1hKSB7XG4gIGNvbnN0IGNvbnRlbnQgPSB7fTtcbiAgY29uc3QgW21hdGNoZXMsIHJlc3RTY2hlbWFdID0gZmlsdGVyU2NoZW1hQnJhbmNoZXMoc2NoZW1hLCBpc0ZpbGVTY2hlbWEpO1xuICBmb3IgKGNvbnN0IGZpbGUgb2YgbWF0Y2hlcykge1xuICAgIGNvbnRlbnRbZmlsZS5jb250ZW50TWVkaWFUeXBlXSA9IHtcbiAgICAgIHNjaGVtYTogdG9PcGVuQVBJU2NoZW1hKGZpbGUpXG4gICAgfTtcbiAgfVxuICBpZiAocmVzdFNjaGVtYSAhPT0gdm9pZCAwKSB7XG4gICAgY29udGVudFtcImFwcGxpY2F0aW9uL2pzb25cIl0gPSB7XG4gICAgICBzY2hlbWE6IHRvT3BlbkFQSVNjaGVtYShyZXN0U2NoZW1hKVxuICAgIH07XG4gICAgY29uc3QgaXNTdGlsbEhhc0ZpbGVTY2hlbWEgPSBmaW5kRGVlcE1hdGNoZXMoKHYpID0+IGlzT2JqZWN0KHYpICYmIGlzRmlsZVNjaGVtYSh2KSwgcmVzdFNjaGVtYSkudmFsdWVzLmxlbmd0aCA+IDA7XG4gICAgaWYgKGlzU3RpbGxIYXNGaWxlU2NoZW1hKSB7XG4gICAgICBjb250ZW50W1wibXVsdGlwYXJ0L2Zvcm0tZGF0YVwiXSA9IHtcbiAgICAgICAgc2NoZW1hOiB0b09wZW5BUElTY2hlbWEocmVzdFNjaGVtYSlcbiAgICAgIH07XG4gICAgfVxuICB9XG4gIHJldHVybiBjb250ZW50O1xufVxuZnVuY3Rpb24gdG9PcGVuQVBJRXZlbnRJdGVyYXRvckNvbnRlbnQoW3lpZWxkc1JlcXVpcmVkLCB5aWVsZHNTY2hlbWFdLCBbcmV0dXJuc1JlcXVpcmVkLCByZXR1cm5zU2NoZW1hXSkge1xuICByZXR1cm4ge1xuICAgIFwidGV4dC9ldmVudC1zdHJlYW1cIjoge1xuICAgICAgc2NoZW1hOiB0b09wZW5BUElTY2hlbWEoe1xuICAgICAgICBvbmVPZjogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgIGV2ZW50OiB7IGNvbnN0OiBcIm1lc3NhZ2VcIiB9LFxuICAgICAgICAgICAgICBkYXRhOiB5aWVsZHNTY2hlbWEsXG4gICAgICAgICAgICAgIGlkOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICAgICAgcmV0cnk6IHsgdHlwZTogXCJudW1iZXJcIiB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVxdWlyZWQ6IHlpZWxkc1JlcXVpcmVkID8gW1wiZXZlbnRcIiwgXCJkYXRhXCJdIDogW1wiZXZlbnRcIl1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgIGV2ZW50OiB7IGNvbnN0OiBcImRvbmVcIiB9LFxuICAgICAgICAgICAgICBkYXRhOiByZXR1cm5zU2NoZW1hLFxuICAgICAgICAgICAgICBpZDogeyB0eXBlOiBcInN0cmluZ1wiIH0sXG4gICAgICAgICAgICAgIHJldHJ5OiB7IHR5cGU6IFwibnVtYmVyXCIgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlcXVpcmVkOiByZXR1cm5zUmVxdWlyZWQgPyBbXCJldmVudFwiLCBcImRhdGFcIl0gOiBbXCJldmVudFwiXVxuICAgICAgICAgIH0sXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJvYmplY3RcIixcbiAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgZXZlbnQ6IHsgY29uc3Q6IFwiZXJyb3JcIiB9LFxuICAgICAgICAgICAgICBkYXRhOiB7fSxcbiAgICAgICAgICAgICAgaWQ6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgICAgICAgICByZXRyeTogeyB0eXBlOiBcIm51bWJlclwiIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZXF1aXJlZDogW1wiZXZlbnRcIl1cbiAgICAgICAgICB9XG4gICAgICAgIF1cbiAgICAgIH0pXG4gICAgfVxuICB9O1xufVxuZnVuY3Rpb24gdG9PcGVuQVBJUGFyYW1ldGVycyhzY2hlbWEsIHBhcmFtZXRlckluKSB7XG4gIGNvbnN0IHBhcmFtZXRlcnMgPSBbXTtcbiAgZm9yIChjb25zdCBrZXkgaW4gc2NoZW1hLnByb3BlcnRpZXMpIHtcbiAgICBjb25zdCBrZXlTY2hlbWEgPSBzY2hlbWEucHJvcGVydGllc1trZXldO1xuICAgIGxldCBpc0RlZXBPYmplY3RTdHlsZSA9IHRydWU7XG4gICAgaWYgKHBhcmFtZXRlckluICE9PSBcInF1ZXJ5XCIpIHtcbiAgICAgIGlzRGVlcE9iamVjdFN0eWxlID0gZmFsc2U7XG4gICAgfSBlbHNlIGlmIChpc1ByaW1pdGl2ZVNjaGVtYShrZXlTY2hlbWEpKSB7XG4gICAgICBpc0RlZXBPYmplY3RTdHlsZSA9IGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBbaXRlbV0gPSBleHBhbmRBcnJheWFibGVTY2hlbWEoa2V5U2NoZW1hKSA/PyBbXTtcbiAgICAgIGlmIChpdGVtICE9PSB2b2lkIDAgJiYgaXNQcmltaXRpdmVTY2hlbWEoaXRlbSkpIHtcbiAgICAgICAgaXNEZWVwT2JqZWN0U3R5bGUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcGFyYW1ldGVycy5wdXNoKHtcbiAgICAgIG5hbWU6IGtleSxcbiAgICAgIGluOiBwYXJhbWV0ZXJJbixcbiAgICAgIHJlcXVpcmVkOiBzY2hlbWEucmVxdWlyZWQ/LmluY2x1ZGVzKGtleSksXG4gICAgICBzY2hlbWE6IHRvT3BlbkFQSVNjaGVtYShrZXlTY2hlbWEpLFxuICAgICAgc3R5bGU6IGlzRGVlcE9iamVjdFN0eWxlID8gXCJkZWVwT2JqZWN0XCIgOiB2b2lkIDAsXG4gICAgICBleHBsb2RlOiBpc0RlZXBPYmplY3RTdHlsZSA/IHRydWUgOiB2b2lkIDAsXG4gICAgICBhbGxvd0VtcHR5VmFsdWU6IHBhcmFtZXRlckluID09PSBcInF1ZXJ5XCIgPyB0cnVlIDogdm9pZCAwLFxuICAgICAgYWxsb3dSZXNlcnZlZDogcGFyYW1ldGVySW4gPT09IFwicXVlcnlcIiA/IHRydWUgOiB2b2lkIDBcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gcGFyYW1ldGVycztcbn1cbmZ1bmN0aW9uIGNoZWNrUGFyYW1zU2NoZW1hKHNjaGVtYSwgcGFyYW1zKSB7XG4gIGNvbnN0IHByb3BlcnRpZXMgPSBPYmplY3Qua2V5cyhzY2hlbWEucHJvcGVydGllcyA/PyB7fSk7XG4gIGNvbnN0IHJlcXVpcmVkID0gc2NoZW1hLnJlcXVpcmVkID8/IFtdO1xuICBpZiAocHJvcGVydGllcy5sZW5ndGggIT09IHBhcmFtcy5sZW5ndGggfHwgcHJvcGVydGllcy5zb21lKCh2KSA9PiAhcGFyYW1zLmluY2x1ZGVzKHYpKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpZiAocmVxdWlyZWQubGVuZ3RoICE9PSBwYXJhbXMubGVuZ3RoIHx8IHJlcXVpcmVkLnNvbWUoKHYpID0+ICFwYXJhbXMuaW5jbHVkZXModikpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gdG9PcGVuQVBJU2NoZW1hKHNjaGVtYSkge1xuICByZXR1cm4gc2NoZW1hID09PSB0cnVlID8ge30gOiBzY2hlbWEgPT09IGZhbHNlID8geyBub3Q6IHt9IH0gOiBzY2hlbWE7XG59XG5jb25zdCBPUEVOQVBJX0pTT05fU0NIRU1BX1JFRl9QUkVGSVggPSBcIiMvY29tcG9uZW50cy9zY2hlbWFzL1wiO1xuZnVuY3Rpb24gcmVzb2x2ZU9wZW5BUElKc29uU2NoZW1hUmVmKGRvYywgc2NoZW1hKSB7XG4gIGlmICh0eXBlb2Ygc2NoZW1hICE9PSBcIm9iamVjdFwiIHx8ICFzY2hlbWEuJHJlZj8uc3RhcnRzV2l0aChPUEVOQVBJX0pTT05fU0NIRU1BX1JFRl9QUkVGSVgpKSB7XG4gICAgcmV0dXJuIHNjaGVtYTtcbiAgfVxuICBjb25zdCBuYW1lID0gc2NoZW1hLiRyZWYuc2xpY2UoT1BFTkFQSV9KU09OX1NDSEVNQV9SRUZfUFJFRklYLmxlbmd0aCk7XG4gIGNvbnN0IHJlc29sdmVkID0gZG9jLmNvbXBvbmVudHM/LnNjaGVtYXM/LltuYW1lXTtcbiAgcmV0dXJuIHJlc29sdmVkID8/IHNjaGVtYTtcbn1cblxuY2xhc3MgQ29tcG9zaXRlU2NoZW1hQ29udmVydGVyIHtcbiAgY29udmVydGVycztcbiAgY29uc3RydWN0b3IoY29udmVydGVycykge1xuICAgIHRoaXMuY29udmVydGVycyA9IGNvbnZlcnRlcnM7XG4gIH1cbiAgYXN5bmMgY29udmVydChzY2hlbWEsIG9wdGlvbnMpIHtcbiAgICBmb3IgKGNvbnN0IGNvbnZlcnRlciBvZiB0aGlzLmNvbnZlcnRlcnMpIHtcbiAgICAgIGlmIChhd2FpdCBjb252ZXJ0ZXIuY29uZGl0aW9uKHNjaGVtYSwgb3B0aW9ucykpIHtcbiAgICAgICAgcmV0dXJuIGNvbnZlcnRlci5jb252ZXJ0KHNjaGVtYSwgb3B0aW9ucyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBbZmFsc2UsIHt9XTtcbiAgfVxufVxuXG5jbGFzcyBPcGVuQVBJR2VuZXJhdG9yRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG59XG5jbGFzcyBPcGVuQVBJR2VuZXJhdG9yIHtcbiAgc2VyaWFsaXplcjtcbiAgY29udmVydGVyO1xuICBjb25zdHJ1Y3RvcihvcHRpb25zID0ge30pIHtcbiAgICB0aGlzLnNlcmlhbGl6ZXIgPSBuZXcgU3RhbmRhcmRPcGVuQVBJSnNvblNlcmlhbGl6ZXIob3B0aW9ucyk7XG4gICAgdGhpcy5jb252ZXJ0ZXIgPSBuZXcgQ29tcG9zaXRlU2NoZW1hQ29udmVydGVyKHRvQXJyYXkob3B0aW9ucy5zY2hlbWFDb252ZXJ0ZXJzKSk7XG4gIH1cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBPcGVuQVBJIHNwZWNpZmljYXRpb25zIGZyb20gb1JQQyByb3V0ZXJzL2NvbnRyYWN0cy5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgaHR0cHM6Ly9vcnBjLnVubm9xLmNvbS9kb2NzL29wZW5hcGkvb3BlbmFwaS1zcGVjaWZpY2F0aW9uIE9wZW5BUEkgU3BlY2lmaWNhdGlvbiBEb2NzfVxuICAgKi9cbiAgYXN5bmMgZ2VuZXJhdGUocm91dGVyLCB7IGN1c3RvbUVycm9yUmVzcG9uc2VCb2R5U2NoZW1hLCBjb21tb25TY2hlbWFzLCBmaWx0ZXI6IGJhc2VGaWx0ZXIsIGV4Y2x1ZGUsIC4uLmJhc2VEb2MgfSA9IHt9KSB7XG4gICAgY29uc3QgZmlsdGVyID0gYmFzZUZpbHRlciA/PyAoKHsgY29udHJhY3QsIHBhdGggfSkgPT4ge1xuICAgICAgcmV0dXJuICEoZXhjbHVkZT8uKGNvbnRyYWN0LCBwYXRoKSA/PyBmYWxzZSk7XG4gICAgfSk7XG4gICAgY29uc3QgZG9jID0ge1xuICAgICAgLi4uY2xvbmUoYmFzZURvYyksXG4gICAgICBpbmZvOiBiYXNlRG9jLmluZm8gPz8geyB0aXRsZTogXCJBUEkgUmVmZXJlbmNlXCIsIHZlcnNpb246IFwiMC4wLjBcIiB9LFxuICAgICAgb3BlbmFwaTogXCIzLjEuMVwiXG4gICAgfTtcbiAgICBjb25zdCB7IGJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucywgdW5kZWZpbmVkRXJyb3JKc29uU2NoZW1hIH0gPSBhd2FpdCB0aGlzLiNyZXNvbHZlQ29tbW9uU2NoZW1hcyhkb2MsIGNvbW1vblNjaGVtYXMpO1xuICAgIGNvbnN0IGNvbnRyYWN0cyA9IFtdO1xuICAgIGF3YWl0IHJlc29sdmVDb250cmFjdFByb2NlZHVyZXMoeyBwYXRoOiBbXSwgcm91dGVyIH0sICh0cmF2ZXJzZU9wdGlvbnMpID0+IHtcbiAgICAgIGlmICghdmFsdWUoZmlsdGVyLCB0cmF2ZXJzZU9wdGlvbnMpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnRyYWN0cy5wdXNoKHRyYXZlcnNlT3B0aW9ucyk7XG4gICAgfSk7XG4gICAgY29uc3QgZXJyb3JzID0gW107XG4gICAgZm9yIChjb25zdCB7IGNvbnRyYWN0LCBwYXRoIH0gb2YgY29udHJhY3RzKSB7XG4gICAgICBjb25zdCBzdHJpbmdQYXRoID0gcGF0aC5qb2luKFwiLlwiKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGRlZiA9IGNvbnRyYWN0W1wifm9ycGNcIl07XG4gICAgICAgIGNvbnN0IG1ldGhvZCA9IHRvT3BlbkFQSU1ldGhvZChmYWxsYmFja0NvbnRyYWN0Q29uZmlnKFwiZGVmYXVsdE1ldGhvZFwiLCBkZWYucm91dGUubWV0aG9kKSk7XG4gICAgICAgIGNvbnN0IGh0dHBQYXRoID0gdG9PcGVuQVBJUGF0aChkZWYucm91dGUucGF0aCA/PyB0b0h0dHBQYXRoKHBhdGgpKTtcbiAgICAgICAgbGV0IG9wZXJhdGlvbk9iamVjdFJlZjtcbiAgICAgICAgaWYgKGRlZi5yb3V0ZS5zcGVjICE9PSB2b2lkIDAgJiYgdHlwZW9mIGRlZi5yb3V0ZS5zcGVjICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgICBvcGVyYXRpb25PYmplY3RSZWYgPSBkZWYucm91dGUuc3BlYztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvcGVyYXRpb25PYmplY3RSZWYgPSB7XG4gICAgICAgICAgICBvcGVyYXRpb25JZDogZGVmLnJvdXRlLm9wZXJhdGlvbklkID8/IHN0cmluZ1BhdGgsXG4gICAgICAgICAgICBzdW1tYXJ5OiBkZWYucm91dGUuc3VtbWFyeSxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBkZWYucm91dGUuZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBkZXByZWNhdGVkOiBkZWYucm91dGUuZGVwcmVjYXRlZCxcbiAgICAgICAgICAgIHRhZ3M6IGRlZi5yb3V0ZS50YWdzPy5tYXAoKHRhZykgPT4gdGFnKVxuICAgICAgICAgIH07XG4gICAgICAgICAgYXdhaXQgdGhpcy4jcmVxdWVzdChkb2MsIG9wZXJhdGlvbk9iamVjdFJlZiwgZGVmLCBiYXNlU2NoZW1hQ29udmVydE9wdGlvbnMpO1xuICAgICAgICAgIGF3YWl0IHRoaXMuI3N1Y2Nlc3NSZXNwb25zZShkb2MsIG9wZXJhdGlvbk9iamVjdFJlZiwgZGVmLCBiYXNlU2NoZW1hQ29udmVydE9wdGlvbnMpO1xuICAgICAgICAgIGF3YWl0IHRoaXMuI2Vycm9yUmVzcG9uc2Uob3BlcmF0aW9uT2JqZWN0UmVmLCBkZWYsIGJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucywgdW5kZWZpbmVkRXJyb3JKc29uU2NoZW1hLCBjdXN0b21FcnJvclJlc3BvbnNlQm9keVNjaGVtYSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHR5cGVvZiBkZWYucm91dGUuc3BlYyA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgb3BlcmF0aW9uT2JqZWN0UmVmID0gZGVmLnJvdXRlLnNwZWMob3BlcmF0aW9uT2JqZWN0UmVmKTtcbiAgICAgICAgfVxuICAgICAgICBkb2MucGF0aHMgPz89IHt9O1xuICAgICAgICBkb2MucGF0aHNbaHR0cFBhdGhdID8/PSB7fTtcbiAgICAgICAgZG9jLnBhdGhzW2h0dHBQYXRoXVttZXRob2RdID0gYXBwbHlDdXN0b21PcGVuQVBJT3BlcmF0aW9uKG9wZXJhdGlvbk9iamVjdFJlZiwgY29udHJhY3QpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBpZiAoIShlIGluc3RhbmNlb2YgT3BlbkFQSUdlbmVyYXRvckVycm9yKSkge1xuICAgICAgICAgIHRocm93IGU7XG4gICAgICAgIH1cbiAgICAgICAgZXJyb3JzLnB1c2goXG4gICAgICAgICAgYFtPcGVuQVBJR2VuZXJhdG9yXSBFcnJvciBvY2N1cnJlZCB3aGlsZSBnZW5lcmF0aW5nIE9wZW5BUEkgZm9yIHByb2NlZHVyZSBhdCBwYXRoOiAke3N0cmluZ1BhdGh9XG4ke2UubWVzc2FnZX1gXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChlcnJvcnMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgT3BlbkFQSUdlbmVyYXRvckVycm9yKFxuICAgICAgICBgU29tZSBlcnJvciBvY2N1cnJlZCBkdXJpbmcgT3BlbkFQSSBnZW5lcmF0aW9uOlxuXG4ke2Vycm9ycy5qb2luKFwiXFxuXFxuXCIpfWBcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNlcmlhbGl6ZXIuc2VyaWFsaXplKGRvYylbMF07XG4gIH1cbiAgYXN5bmMgI3Jlc29sdmVDb21tb25TY2hlbWFzKGRvYywgY29tbW9uU2NoZW1hcykge1xuICAgIGxldCB1bmRlZmluZWRFcnJvckpzb25TY2hlbWEgPSB7XG4gICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICBkZWZpbmVkOiB7IGNvbnN0OiBmYWxzZSB9LFxuICAgICAgICBjb2RlOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgc3RhdHVzOiB7IHR5cGU6IFwibnVtYmVyXCIgfSxcbiAgICAgICAgbWVzc2FnZTogeyB0eXBlOiBcInN0cmluZ1wiIH0sXG4gICAgICAgIGRhdGE6IHt9XG4gICAgICB9LFxuICAgICAgcmVxdWlyZWQ6IFtcImRlZmluZWRcIiwgXCJjb2RlXCIsIFwic3RhdHVzXCIsIFwibWVzc2FnZVwiXVxuICAgIH07XG4gICAgY29uc3QgYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zID0ge307XG4gICAgaWYgKGNvbW1vblNjaGVtYXMpIHtcbiAgICAgIGJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucy5jb21wb25lbnRzID0gW107XG4gICAgICBmb3IgKGNvbnN0IGtleSBpbiBjb21tb25TY2hlbWFzKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBjb21tb25TY2hlbWFzW2tleV07XG4gICAgICAgIGlmIChvcHRpb25zLnNjaGVtYSA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgeyBzY2hlbWEsIHN0cmF0ZWd5ID0gXCJpbnB1dFwiIH0gPSBvcHRpb25zO1xuICAgICAgICBjb25zdCBbcmVxdWlyZWQsIGpzb25dID0gYXdhaXQgdGhpcy5jb252ZXJ0ZXIuY29udmVydChzY2hlbWEsIHsgc3RyYXRlZ3kgfSk7XG4gICAgICAgIGNvbnN0IGFsbG93ZWRTdHJhdGVnaWVzID0gW3N0cmF0ZWd5XTtcbiAgICAgICAgaWYgKHN0cmF0ZWd5ID09PSBcImlucHV0XCIpIHtcbiAgICAgICAgICBjb25zdCBbb3V0cHV0UmVxdWlyZWQsIG91dHB1dEpzb25dID0gYXdhaXQgdGhpcy5jb252ZXJ0ZXIuY29udmVydChzY2hlbWEsIHsgc3RyYXRlZ3k6IFwib3V0cHV0XCIgfSk7XG4gICAgICAgICAgaWYgKG91dHB1dFJlcXVpcmVkID09PSByZXF1aXJlZCAmJiBzdHJpbmdpZnlKU09OKG91dHB1dEpzb24pID09PSBzdHJpbmdpZnlKU09OKGpzb24pKSB7XG4gICAgICAgICAgICBhbGxvd2VkU3RyYXRlZ2llcy5wdXNoKFwib3V0cHV0XCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChzdHJhdGVneSA9PT0gXCJvdXRwdXRcIikge1xuICAgICAgICAgIGNvbnN0IFtpbnB1dFJlcXVpcmVkLCBpbnB1dEpzb25dID0gYXdhaXQgdGhpcy5jb252ZXJ0ZXIuY29udmVydChzY2hlbWEsIHsgc3RyYXRlZ3k6IFwiaW5wdXRcIiB9KTtcbiAgICAgICAgICBpZiAoaW5wdXRSZXF1aXJlZCA9PT0gcmVxdWlyZWQgJiYgc3RyaW5naWZ5SlNPTihpbnB1dEpzb24pID09PSBzdHJpbmdpZnlKU09OKGpzb24pKSB7XG4gICAgICAgICAgICBhbGxvd2VkU3RyYXRlZ2llcy5wdXNoKFwiaW5wdXRcIik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucy5jb21wb25lbnRzLnB1c2goe1xuICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICByZXF1aXJlZCxcbiAgICAgICAgICByZWY6IGAjL2NvbXBvbmVudHMvc2NoZW1hcy8ke2tleX1gLFxuICAgICAgICAgIGFsbG93ZWRTdHJhdGVnaWVzXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgZG9jLmNvbXBvbmVudHMgPz89IHt9O1xuICAgICAgZG9jLmNvbXBvbmVudHMuc2NoZW1hcyA/Pz0ge307XG4gICAgICBmb3IgKGNvbnN0IGtleSBpbiBjb21tb25TY2hlbWFzKSB7XG4gICAgICAgIGNvbnN0IG9wdGlvbnMgPSBjb21tb25TY2hlbWFzW2tleV07XG4gICAgICAgIGlmIChvcHRpb25zLnNjaGVtYSA9PT0gdm9pZCAwKSB7XG4gICAgICAgICAgaWYgKG9wdGlvbnMuZXJyb3IgPT09IFwiVW5kZWZpbmVkRXJyb3JcIikge1xuICAgICAgICAgICAgZG9jLmNvbXBvbmVudHMuc2NoZW1hc1trZXldID0gdG9PcGVuQVBJU2NoZW1hKHVuZGVmaW5lZEVycm9ySnNvblNjaGVtYSk7XG4gICAgICAgICAgICB1bmRlZmluZWRFcnJvckpzb25TY2hlbWEgPSB7ICRyZWY6IGAjL2NvbXBvbmVudHMvc2NoZW1hcy8ke2tleX1gIH07XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgc2NoZW1hLCBzdHJhdGVneSA9IFwiaW5wdXRcIiB9ID0gb3B0aW9ucztcbiAgICAgICAgY29uc3QgWywganNvbl0gPSBhd2FpdCB0aGlzLmNvbnZlcnRlci5jb252ZXJ0KFxuICAgICAgICAgIHNjaGVtYSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICAuLi5iYXNlU2NoZW1hQ29udmVydE9wdGlvbnMsXG4gICAgICAgICAgICBzdHJhdGVneSxcbiAgICAgICAgICAgIG1pblN0cnVjdHVyZURlcHRoRm9yUmVmOiAxXG4gICAgICAgICAgICAvLyBub3QgYWxsb3cgdXNlICRyZWYgZm9yIHJvb3Qgc2NoZW1hc1xuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgICAgZG9jLmNvbXBvbmVudHMuc2NoZW1hc1trZXldID0gdG9PcGVuQVBJU2NoZW1hKGpzb24pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geyBiYXNlU2NoZW1hQ29udmVydE9wdGlvbnMsIHVuZGVmaW5lZEVycm9ySnNvblNjaGVtYSB9O1xuICB9XG4gIGFzeW5jICNyZXF1ZXN0KGRvYywgcmVmLCBkZWYsIGJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucykge1xuICAgIGNvbnN0IG1ldGhvZCA9IGZhbGxiYWNrQ29udHJhY3RDb25maWcoXCJkZWZhdWx0TWV0aG9kXCIsIGRlZi5yb3V0ZS5tZXRob2QpO1xuICAgIGNvbnN0IGRldGFpbHMgPSBnZXRFdmVudEl0ZXJhdG9yU2NoZW1hRGV0YWlscyhkZWYuaW5wdXRTY2hlbWEpO1xuICAgIGlmIChkZXRhaWxzKSB7XG4gICAgICByZWYucmVxdWVzdEJvZHkgPSB7XG4gICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICBjb250ZW50OiB0b09wZW5BUElFdmVudEl0ZXJhdG9yQ29udGVudChcbiAgICAgICAgICBhd2FpdCB0aGlzLmNvbnZlcnRlci5jb252ZXJ0KGRldGFpbHMueWllbGRzLCB7IC4uLmJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucywgc3RyYXRlZ3k6IFwiaW5wdXRcIiB9KSxcbiAgICAgICAgICBhd2FpdCB0aGlzLmNvbnZlcnRlci5jb252ZXJ0KGRldGFpbHMucmV0dXJucywgeyAuLi5iYXNlU2NoZW1hQ29udmVydE9wdGlvbnMsIHN0cmF0ZWd5OiBcImlucHV0XCIgfSlcbiAgICAgICAgKVxuICAgICAgfTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZHluYW1pY1BhcmFtcyA9IGdldER5bmFtaWNQYXJhbXMoZGVmLnJvdXRlLnBhdGgpPy5tYXAoKHYpID0+IHYubmFtZSk7XG4gICAgY29uc3QgaW5wdXRTdHJ1Y3R1cmUgPSBmYWxsYmFja0NvbnRyYWN0Q29uZmlnKFwiZGVmYXVsdElucHV0U3RydWN0dXJlXCIsIGRlZi5yb3V0ZS5pbnB1dFN0cnVjdHVyZSk7XG4gICAgbGV0IFtyZXF1aXJlZCwgc2NoZW1hXSA9IGF3YWl0IHRoaXMuY29udmVydGVyLmNvbnZlcnQoXG4gICAgICBkZWYuaW5wdXRTY2hlbWEsXG4gICAgICB7XG4gICAgICAgIC4uLmJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucyxcbiAgICAgICAgc3RyYXRlZ3k6IFwiaW5wdXRcIixcbiAgICAgICAgbWluU3RydWN0dXJlRGVwdGhGb3JSZWY6IGR5bmFtaWNQYXJhbXM/Lmxlbmd0aCB8fCBpbnB1dFN0cnVjdHVyZSA9PT0gXCJkZXRhaWxlZFwiID8gMSA6IDBcbiAgICAgIH1cbiAgICApO1xuICAgIGlmIChpc0FueVNjaGVtYShzY2hlbWEpICYmICFkeW5hbWljUGFyYW1zPy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKGlucHV0U3RydWN0dXJlID09PSBcImNvbXBhY3RcIikge1xuICAgICAgaWYgKGR5bmFtaWNQYXJhbXM/Lmxlbmd0aCkge1xuICAgICAgICBjb25zdCBlcnJvcjIgPSBuZXcgT3BlbkFQSUdlbmVyYXRvckVycm9yKFxuICAgICAgICAgICdXaGVuIGlucHV0IHN0cnVjdHVyZSBpcyBcImNvbXBhY3RcIiwgYW5kIHBhdGggaGFzIGR5bmFtaWMgcGFyYW1zLCBpbnB1dCBzY2hlbWEgbXVzdCBiZSBhbiBvYmplY3Qgd2l0aCBhbGwgZHluYW1pYyBwYXJhbXMgYXMgcmVxdWlyZWQuJ1xuICAgICAgICApO1xuICAgICAgICBpZiAoIWlzT2JqZWN0U2NoZW1hKHNjaGVtYSkpIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjI7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgW3BhcmFtc1NjaGVtYSwgcmVzdF0gPSBzZXBhcmF0ZU9iamVjdFNjaGVtYShzY2hlbWEsIGR5bmFtaWNQYXJhbXMpO1xuICAgICAgICBzY2hlbWEgPSByZXN0O1xuICAgICAgICByZXF1aXJlZCA9IHJlc3QucmVxdWlyZWQgPyByZXN0LnJlcXVpcmVkLmxlbmd0aCAhPT0gMCA6IGZhbHNlO1xuICAgICAgICBpZiAoIWNoZWNrUGFyYW1zU2NoZW1hKHBhcmFtc1NjaGVtYSwgZHluYW1pY1BhcmFtcykpIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjI7XG4gICAgICAgIH1cbiAgICAgICAgcmVmLnBhcmFtZXRlcnMgPz89IFtdO1xuICAgICAgICByZWYucGFyYW1ldGVycy5wdXNoKC4uLnRvT3BlbkFQSVBhcmFtZXRlcnMocGFyYW1zU2NoZW1hLCBcInBhdGhcIikpO1xuICAgICAgfVxuICAgICAgaWYgKG1ldGhvZCA9PT0gXCJHRVRcIikge1xuICAgICAgICBjb25zdCByZXNvbHZlZFNjaGVtYSA9IHJlc29sdmVPcGVuQVBJSnNvblNjaGVtYVJlZihkb2MsIHNjaGVtYSk7XG4gICAgICAgIGlmICghaXNPYmplY3RTY2hlbWEocmVzb2x2ZWRTY2hlbWEpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE9wZW5BUElHZW5lcmF0b3JFcnJvcihcbiAgICAgICAgICAgICdXaGVuIG1ldGhvZCBpcyBcIkdFVFwiLCBpbnB1dCBzY2hlbWEgbXVzdCBzYXRpc2Z5OiBvYmplY3QgfCBhbnkgfCB1bmtub3duJ1xuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmVmLnBhcmFtZXRlcnMgPz89IFtdO1xuICAgICAgICByZWYucGFyYW1ldGVycy5wdXNoKC4uLnRvT3BlbkFQSVBhcmFtZXRlcnMocmVzb2x2ZWRTY2hlbWEsIFwicXVlcnlcIikpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVmLnJlcXVlc3RCb2R5ID0ge1xuICAgICAgICAgIHJlcXVpcmVkLFxuICAgICAgICAgIGNvbnRlbnQ6IHRvT3BlbkFQSUNvbnRlbnQoc2NoZW1hKVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBlcnJvciA9IG5ldyBPcGVuQVBJR2VuZXJhdG9yRXJyb3IoXG4gICAgICAnV2hlbiBpbnB1dCBzdHJ1Y3R1cmUgaXMgXCJkZXRhaWxlZFwiLCBpbnB1dCBzY2hlbWEgbXVzdCBzYXRpc2Z5OiB7IHBhcmFtcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBxdWVyeT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBoZWFkZXJzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIGJvZHk/OiB1bmtub3duIH0nXG4gICAgKTtcbiAgICBpZiAoIWlzT2JqZWN0U2NoZW1hKHNjaGVtYSkpIHtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgICBjb25zdCByZXNvbHZlZFBhcmFtU2NoZW1hID0gc2NoZW1hLnByb3BlcnRpZXM/LnBhcmFtcyAhPT0gdm9pZCAwID8gcmVzb2x2ZU9wZW5BUElKc29uU2NoZW1hUmVmKGRvYywgc2NoZW1hLnByb3BlcnRpZXMucGFyYW1zKSA6IHZvaWQgMDtcbiAgICBpZiAoZHluYW1pY1BhcmFtcz8ubGVuZ3RoICYmIChyZXNvbHZlZFBhcmFtU2NoZW1hID09PSB2b2lkIDAgfHwgIWlzT2JqZWN0U2NoZW1hKHJlc29sdmVkUGFyYW1TY2hlbWEpIHx8ICFjaGVja1BhcmFtc1NjaGVtYShyZXNvbHZlZFBhcmFtU2NoZW1hLCBkeW5hbWljUGFyYW1zKSkpIHtcbiAgICAgIHRocm93IG5ldyBPcGVuQVBJR2VuZXJhdG9yRXJyb3IoXG4gICAgICAgICdXaGVuIGlucHV0IHN0cnVjdHVyZSBpcyBcImRldGFpbGVkXCIgYW5kIHBhdGggaGFzIGR5bmFtaWMgcGFyYW1zLCB0aGUgXCJwYXJhbXNcIiBzY2hlbWEgbXVzdCBiZSBhbiBvYmplY3Qgd2l0aCBhbGwgZHluYW1pYyBwYXJhbXMgYXMgcmVxdWlyZWQuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBmcm9tIG9mIFtcInBhcmFtc1wiLCBcInF1ZXJ5XCIsIFwiaGVhZGVyc1wiXSkge1xuICAgICAgY29uc3QgZnJvbVNjaGVtYSA9IHNjaGVtYS5wcm9wZXJ0aWVzPy5bZnJvbV07XG4gICAgICBpZiAoZnJvbVNjaGVtYSAhPT0gdm9pZCAwKSB7XG4gICAgICAgIGNvbnN0IHJlc29sdmVkU2NoZW1hID0gcmVzb2x2ZU9wZW5BUElKc29uU2NoZW1hUmVmKGRvYywgZnJvbVNjaGVtYSk7XG4gICAgICAgIGlmICghaXNPYmplY3RTY2hlbWEocmVzb2x2ZWRTY2hlbWEpKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFyYW1ldGVySW4gPSBmcm9tID09PSBcInBhcmFtc1wiID8gXCJwYXRoXCIgOiBmcm9tID09PSBcImhlYWRlcnNcIiA/IFwiaGVhZGVyXCIgOiBcInF1ZXJ5XCI7XG4gICAgICAgIHJlZi5wYXJhbWV0ZXJzID8/PSBbXTtcbiAgICAgICAgcmVmLnBhcmFtZXRlcnMucHVzaCguLi50b09wZW5BUElQYXJhbWV0ZXJzKHJlc29sdmVkU2NoZW1hLCBwYXJhbWV0ZXJJbikpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoc2NoZW1hLnByb3BlcnRpZXM/LmJvZHkgIT09IHZvaWQgMCkge1xuICAgICAgcmVmLnJlcXVlc3RCb2R5ID0ge1xuICAgICAgICByZXF1aXJlZDogc2NoZW1hLnJlcXVpcmVkPy5pbmNsdWRlcyhcImJvZHlcIiksXG4gICAgICAgIGNvbnRlbnQ6IHRvT3BlbkFQSUNvbnRlbnQoc2NoZW1hLnByb3BlcnRpZXMuYm9keSlcbiAgICAgIH07XG4gICAgfVxuICB9XG4gIGFzeW5jICNzdWNjZXNzUmVzcG9uc2UoZG9jLCByZWYsIGRlZiwgYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zKSB7XG4gICAgY29uc3Qgb3V0cHV0U2NoZW1hID0gZGVmLm91dHB1dFNjaGVtYTtcbiAgICBjb25zdCBzdGF0dXMgPSBmYWxsYmFja0NvbnRyYWN0Q29uZmlnKFwiZGVmYXVsdFN1Y2Nlc3NTdGF0dXNcIiwgZGVmLnJvdXRlLnN1Y2Nlc3NTdGF0dXMpO1xuICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gZmFsbGJhY2tDb250cmFjdENvbmZpZyhcImRlZmF1bHRTdWNjZXNzRGVzY3JpcHRpb25cIiwgZGVmLnJvdXRlPy5zdWNjZXNzRGVzY3JpcHRpb24pO1xuICAgIGNvbnN0IGV2ZW50SXRlcmF0b3JTY2hlbWFEZXRhaWxzID0gZ2V0RXZlbnRJdGVyYXRvclNjaGVtYURldGFpbHMob3V0cHV0U2NoZW1hKTtcbiAgICBjb25zdCBvdXRwdXRTdHJ1Y3R1cmUgPSBmYWxsYmFja0NvbnRyYWN0Q29uZmlnKFwiZGVmYXVsdE91dHB1dFN0cnVjdHVyZVwiLCBkZWYucm91dGUub3V0cHV0U3RydWN0dXJlKTtcbiAgICBpZiAoZXZlbnRJdGVyYXRvclNjaGVtYURldGFpbHMpIHtcbiAgICAgIHJlZi5yZXNwb25zZXMgPz89IHt9O1xuICAgICAgcmVmLnJlc3BvbnNlc1tzdGF0dXNdID0ge1xuICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgY29udGVudDogdG9PcGVuQVBJRXZlbnRJdGVyYXRvckNvbnRlbnQoXG4gICAgICAgICAgYXdhaXQgdGhpcy5jb252ZXJ0ZXIuY29udmVydChldmVudEl0ZXJhdG9yU2NoZW1hRGV0YWlscy55aWVsZHMsIHsgLi4uYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zLCBzdHJhdGVneTogXCJvdXRwdXRcIiB9KSxcbiAgICAgICAgICBhd2FpdCB0aGlzLmNvbnZlcnRlci5jb252ZXJ0KGV2ZW50SXRlcmF0b3JTY2hlbWFEZXRhaWxzLnJldHVybnMsIHsgLi4uYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zLCBzdHJhdGVneTogXCJvdXRwdXRcIiB9KVxuICAgICAgICApXG4gICAgICB9O1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBbcmVxdWlyZWQsIGpzb25dID0gYXdhaXQgdGhpcy5jb252ZXJ0ZXIuY29udmVydChcbiAgICAgIG91dHB1dFNjaGVtYSxcbiAgICAgIHtcbiAgICAgICAgLi4uYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zLFxuICAgICAgICBzdHJhdGVneTogXCJvdXRwdXRcIixcbiAgICAgICAgbWluU3RydWN0dXJlRGVwdGhGb3JSZWY6IG91dHB1dFN0cnVjdHVyZSA9PT0gXCJkZXRhaWxlZFwiID8gMSA6IDBcbiAgICAgIH1cbiAgICApO1xuICAgIGlmIChvdXRwdXRTdHJ1Y3R1cmUgPT09IFwiY29tcGFjdFwiKSB7XG4gICAgICByZWYucmVzcG9uc2VzID8/PSB7fTtcbiAgICAgIHJlZi5yZXNwb25zZXNbc3RhdHVzXSA9IHtcbiAgICAgICAgZGVzY3JpcHRpb25cbiAgICAgIH07XG4gICAgICByZWYucmVzcG9uc2VzW3N0YXR1c10uY29udGVudCA9IHRvT3BlbkFQSUNvbnRlbnQoYXBwbHlTY2hlbWFPcHRpb25hbGl0eShyZXF1aXJlZCwganNvbikpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBoYW5kbGVkU3RhdHVzZXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpO1xuICAgIGZvciAoY29uc3QgaXRlbSBvZiBleHBhbmRVbmlvblNjaGVtYShqc29uKSkge1xuICAgICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlbkFQSUdlbmVyYXRvckVycm9yKGBcbiAgICAgICAgV2hlbiBvdXRwdXQgc3RydWN0dXJlIGlzIFwiZGV0YWlsZWRcIiwgb3V0cHV0IHNjaGVtYSBtdXN0IHNhdGlzZnk6XG4gICAgICAgIHsgXG4gICAgICAgICAgc3RhdHVzPzogbnVtYmVyLCAvLyBtdXN0IGJlIGEgbGl0ZXJhbCBudW1iZXIgYW5kIGluIHRoZSByYW5nZSBvZiAyMDAtMzk5XG4gICAgICAgICAgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBcbiAgICAgICAgICBib2R5PzogdW5rbm93biBcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgQnV0IGdvdDogJHtzdHJpbmdpZnlKU09OKGl0ZW0pfVxuICAgICAgYCk7XG4gICAgICBpZiAoIWlzT2JqZWN0U2NoZW1hKGl0ZW0pKSB7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgbGV0IHNjaGVtYVN0YXR1cztcbiAgICAgIGxldCBzY2hlbWFEZXNjcmlwdGlvbjtcbiAgICAgIGlmIChpdGVtLnByb3BlcnRpZXM/LnN0YXR1cyAhPT0gdm9pZCAwKSB7XG4gICAgICAgIGNvbnN0IHN0YXR1c1NjaGVtYSA9IHJlc29sdmVPcGVuQVBJSnNvblNjaGVtYVJlZihkb2MsIGl0ZW0ucHJvcGVydGllcy5zdGF0dXMpO1xuICAgICAgICBpZiAodHlwZW9mIHN0YXR1c1NjaGVtYSAhPT0gXCJvYmplY3RcIiB8fCBzdGF0dXNTY2hlbWEuY29uc3QgPT09IHZvaWQgMCB8fCB0eXBlb2Ygc3RhdHVzU2NoZW1hLmNvbnN0ICE9PSBcIm51bWJlclwiIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKHN0YXR1c1NjaGVtYS5jb25zdCkgfHwgaXNPUlBDRXJyb3JTdGF0dXMoc3RhdHVzU2NoZW1hLmNvbnN0KSkge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHNjaGVtYVN0YXR1cyA9IHN0YXR1c1NjaGVtYS5jb25zdDtcbiAgICAgICAgc2NoZW1hRGVzY3JpcHRpb24gPSBzdGF0dXNTY2hlbWEuZGVzY3JpcHRpb247XG4gICAgICB9XG4gICAgICBjb25zdCBpdGVtU3RhdHVzID0gc2NoZW1hU3RhdHVzID8/IHN0YXR1cztcbiAgICAgIGNvbnN0IGl0ZW1EZXNjcmlwdGlvbiA9IHNjaGVtYURlc2NyaXB0aW9uID8/IGRlc2NyaXB0aW9uO1xuICAgICAgaWYgKGhhbmRsZWRTdGF0dXNlcy5oYXMoaXRlbVN0YXR1cykpIHtcbiAgICAgICAgdGhyb3cgbmV3IE9wZW5BUElHZW5lcmF0b3JFcnJvcihgXG4gICAgICAgICAgV2hlbiBvdXRwdXQgc3RydWN0dXJlIGlzIFwiZGV0YWlsZWRcIiwgZWFjaCBzdWNjZXNzIHN0YXR1cyBtdXN0IGJlIHVuaXF1ZS5cbiAgICAgICAgICBCdXQgZ290IHN0YXR1czogJHtpdGVtU3RhdHVzfSB1c2VkIG1vcmUgdGhhbiBvbmNlLlxuICAgICAgICBgKTtcbiAgICAgIH1cbiAgICAgIGhhbmRsZWRTdGF0dXNlcy5hZGQoaXRlbVN0YXR1cyk7XG4gICAgICByZWYucmVzcG9uc2VzID8/PSB7fTtcbiAgICAgIHJlZi5yZXNwb25zZXNbaXRlbVN0YXR1c10gPSB7XG4gICAgICAgIGRlc2NyaXB0aW9uOiBpdGVtRGVzY3JpcHRpb25cbiAgICAgIH07XG4gICAgICBpZiAoaXRlbS5wcm9wZXJ0aWVzPy5oZWFkZXJzICE9PSB2b2lkIDApIHtcbiAgICAgICAgY29uc3QgaGVhZGVyc1NjaGVtYSA9IHJlc29sdmVPcGVuQVBJSnNvblNjaGVtYVJlZihkb2MsIGl0ZW0ucHJvcGVydGllcy5oZWFkZXJzKTtcbiAgICAgICAgaWYgKCFpc09iamVjdFNjaGVtYShoZWFkZXJzU2NoZW1hKSkge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGZvciAoY29uc3Qga2V5IGluIGhlYWRlcnNTY2hlbWEucHJvcGVydGllcykge1xuICAgICAgICAgIGNvbnN0IGhlYWRlclNjaGVtYSA9IGhlYWRlcnNTY2hlbWEucHJvcGVydGllc1trZXldO1xuICAgICAgICAgIGlmIChoZWFkZXJTY2hlbWEgIT09IHZvaWQgMCkge1xuICAgICAgICAgICAgcmVmLnJlc3BvbnNlc1tpdGVtU3RhdHVzXS5oZWFkZXJzID8/PSB7fTtcbiAgICAgICAgICAgIHJlZi5yZXNwb25zZXNbaXRlbVN0YXR1c10uaGVhZGVyc1trZXldID0ge1xuICAgICAgICAgICAgICBzY2hlbWE6IHRvT3BlbkFQSVNjaGVtYShoZWFkZXJTY2hlbWEpLFxuICAgICAgICAgICAgICByZXF1aXJlZDogaXRlbS5yZXF1aXJlZD8uaW5jbHVkZXMoXCJoZWFkZXJzXCIpICYmIGhlYWRlcnNTY2hlbWEucmVxdWlyZWQ/LmluY2x1ZGVzKGtleSlcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaXRlbS5wcm9wZXJ0aWVzPy5ib2R5ICE9PSB2b2lkIDApIHtcbiAgICAgICAgcmVmLnJlc3BvbnNlc1tpdGVtU3RhdHVzXS5jb250ZW50ID0gdG9PcGVuQVBJQ29udGVudChcbiAgICAgICAgICBhcHBseVNjaGVtYU9wdGlvbmFsaXR5KGl0ZW0ucmVxdWlyZWQ/LmluY2x1ZGVzKFwiYm9keVwiKSA/PyBmYWxzZSwgaXRlbS5wcm9wZXJ0aWVzLmJvZHkpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGFzeW5jICNlcnJvclJlc3BvbnNlKHJlZiwgZGVmLCBiYXNlU2NoZW1hQ29udmVydE9wdGlvbnMsIHVuZGVmaW5lZEVycm9yU2NoZW1hLCBjdXN0b21FcnJvclJlc3BvbnNlQm9keVNjaGVtYSkge1xuICAgIGNvbnN0IGVycm9yTWFwID0gZGVmLmVycm9yTWFwO1xuICAgIGNvbnN0IGVycm9yUmVzcG9uc2VzQnlTdGF0dXMgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGNvZGUgaW4gZXJyb3JNYXApIHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IGVycm9yTWFwW2NvZGVdO1xuICAgICAgaWYgKCFjb25maWcpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCBzdGF0dXMgPSBmYWxsYmFja09SUENFcnJvclN0YXR1cyhjb2RlLCBjb25maWcuc3RhdHVzKTtcbiAgICAgIGNvbnN0IGRlZmF1bHRNZXNzYWdlID0gZmFsbGJhY2tPUlBDRXJyb3JNZXNzYWdlKGNvZGUsIGNvbmZpZy5tZXNzYWdlKTtcbiAgICAgIGVycm9yUmVzcG9uc2VzQnlTdGF0dXNbc3RhdHVzXSA/Pz0geyBzdGF0dXMsIGRlZmluZWRFcnJvckRlZmluaXRpb25zOiBbXSwgZXJyb3JTY2hlbWFWYXJpYW50czogW10gfTtcbiAgICAgIGNvbnN0IFtkYXRhUmVxdWlyZWQsIGRhdGFTY2hlbWFdID0gYXdhaXQgdGhpcy5jb252ZXJ0ZXIuY29udmVydChjb25maWcuZGF0YSwgeyAuLi5iYXNlU2NoZW1hQ29udmVydE9wdGlvbnMsIHN0cmF0ZWd5OiBcIm91dHB1dFwiIH0pO1xuICAgICAgZXJyb3JSZXNwb25zZXNCeVN0YXR1c1tzdGF0dXNdLmRlZmluZWRFcnJvckRlZmluaXRpb25zLnB1c2goW2NvZGUsIGRlZmF1bHRNZXNzYWdlLCBkYXRhUmVxdWlyZWQsIGRhdGFTY2hlbWFdKTtcbiAgICAgIGVycm9yUmVzcG9uc2VzQnlTdGF0dXNbc3RhdHVzXS5lcnJvclNjaGVtYVZhcmlhbnRzLnB1c2goe1xuICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgZGVmaW5lZDogeyBjb25zdDogdHJ1ZSB9LFxuICAgICAgICAgIGNvZGU6IHsgY29uc3Q6IGNvZGUgfSxcbiAgICAgICAgICBzdGF0dXM6IHsgY29uc3Q6IHN0YXR1cyB9LFxuICAgICAgICAgIG1lc3NhZ2U6IHsgdHlwZTogXCJzdHJpbmdcIiwgZGVmYXVsdDogZGVmYXVsdE1lc3NhZ2UgfSxcbiAgICAgICAgICBkYXRhOiBkYXRhU2NoZW1hXG4gICAgICAgIH0sXG4gICAgICAgIHJlcXVpcmVkOiBkYXRhUmVxdWlyZWQgPyBbXCJkZWZpbmVkXCIsIFwiY29kZVwiLCBcInN0YXR1c1wiLCBcIm1lc3NhZ2VcIiwgXCJkYXRhXCJdIDogW1wiZGVmaW5lZFwiLCBcImNvZGVcIiwgXCJzdGF0dXNcIiwgXCJtZXNzYWdlXCJdXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmVmLnJlc3BvbnNlcyA/Pz0ge307XG4gICAgZm9yIChjb25zdCBzdGF0dXNTdHJpbmcgaW4gZXJyb3JSZXNwb25zZXNCeVN0YXR1cykge1xuICAgICAgY29uc3QgZXJyb3JSZXNwb25zZSA9IGVycm9yUmVzcG9uc2VzQnlTdGF0dXNbc3RhdHVzU3RyaW5nXTtcbiAgICAgIGNvbnN0IGN1c3RvbUJvZHlTY2hlbWEgPSB2YWx1ZShjdXN0b21FcnJvclJlc3BvbnNlQm9keVNjaGVtYSwgZXJyb3JSZXNwb25zZS5kZWZpbmVkRXJyb3JEZWZpbml0aW9ucywgZXJyb3JSZXNwb25zZS5zdGF0dXMpO1xuICAgICAgcmVmLnJlc3BvbnNlc1tzdGF0dXNTdHJpbmddID0ge1xuICAgICAgICBkZXNjcmlwdGlvbjogc3RhdHVzU3RyaW5nLFxuICAgICAgICBjb250ZW50OiB0b09wZW5BUElDb250ZW50KGN1c3RvbUJvZHlTY2hlbWEgPz8ge1xuICAgICAgICAgIG9uZU9mOiBbXG4gICAgICAgICAgICAuLi5lcnJvclJlc3BvbnNlLmVycm9yU2NoZW1hVmFyaWFudHMsXG4gICAgICAgICAgICB1bmRlZmluZWRFcnJvclNjaGVtYVxuICAgICAgICAgIF1cbiAgICAgICAgfSlcbiAgICAgIH07XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCB7IENvbXBvc2l0ZVNjaGVtYUNvbnZlcnRlciBhcyBDLCBMT0dJQ19LRVlXT1JEUyBhcyBMLCBPcGVuQVBJR2VuZXJhdG9yIGFzIE8sIGFwcGx5Q3VzdG9tT3BlbkFQSU9wZXJhdGlvbiBhcyBhLCB0b09wZW5BUElNZXRob2QgYXMgYiwgY3VzdG9tT3BlbkFQSU9wZXJhdGlvbiBhcyBjLCB0b09wZW5BUElDb250ZW50IGFzIGQsIHRvT3BlbkFQSUV2ZW50SXRlcmF0b3JDb250ZW50IGFzIGUsIHRvT3BlbkFQSVBhcmFtZXRlcnMgYXMgZiwgZ2V0Q3VzdG9tT3BlbkFQSU9wZXJhdGlvbiBhcyBnLCBjaGVja1BhcmFtc1NjaGVtYSBhcyBoLCB0b09wZW5BUElTY2hlbWEgYXMgaSwgaXNGaWxlU2NoZW1hIGFzIGosIGlzT2JqZWN0U2NoZW1hIGFzIGssIGlzQW55U2NoZW1hIGFzIGwsIGZpbHRlclNjaGVtYUJyYW5jaGVzIGFzIG0sIGFwcGx5U2NoZW1hT3B0aW9uYWxpdHkgYXMgbiwgZXhwYW5kVW5pb25TY2hlbWEgYXMgbywgZXhwYW5kQXJyYXlhYmxlU2NoZW1hIGFzIHAsIGlzUHJpbWl0aXZlU2NoZW1hIGFzIHEsIHJlc29sdmVPcGVuQVBJSnNvblNjaGVtYVJlZiBhcyByLCBzZXBhcmF0ZU9iamVjdFNjaGVtYSBhcyBzLCB0b09wZW5BUElQYXRoIGFzIHQgfTtcbiJdLCJ4X2dvb2dsZV9pZ25vcmVMaXN0IjpbMCwxXSwibWFwcGluZ3MiOiI7Ozs7O0FBUUEsSUFBSTtDQUNILFNBQVMsa0JBQWtCO0FBQ3hCLGtCQUFpQixVQUFVO0FBQzNCLGtCQUFpQixVQUFVO0FBQzNCLGtCQUFpQixZQUFZO0FBQzdCLGtCQUFpQixZQUFZO0FBQzdCLGtCQUFpQixlQUFlO0FBQ2hDLGtCQUFpQixxQkFBcUI7QUFDdEMsa0JBQWlCLFlBQVk7R0FDOUIsb0JBQW9CLGtCQUFrQixFQUFFLEVBQUU7QUFDN0MsSUFBSTtDQUNILFNBQVMsU0FBUztBQUNmLFNBQVEsVUFBVTtBQUNsQixTQUFRLGNBQWM7QUFDdEIsU0FBUSxjQUFjO0FBQ3RCLFNBQVEsV0FBVztBQUNuQixTQUFRLGNBQWM7QUFDdEIsU0FBUSxjQUFjO0FBQ3RCLFNBQVEsaUJBQWlCO0FBQ3pCLFNBQVEsVUFBVTtBQUNsQixTQUFRLFVBQVU7QUFDbEIsU0FBUSxTQUFTO0FBQ2pCLFNBQVEsa0JBQWtCO0FBQzFCLFNBQVEsaUJBQWlCO0FBQ3pCLFNBQVEsNEJBQTRCO0FBQ3BDLFNBQVEsV0FBVztBQUNuQixTQUFRLHlCQUF5QjtBQUNqQyxTQUFRLFVBQVU7QUFDbEIsU0FBUSxTQUFTO0FBQ2pCLFNBQVEsa0JBQWtCO0FBQzFCLFNBQVEsaUJBQWlCO0FBQ3pCLFNBQVEsVUFBVTtHQUNuQixXQUFXLFNBQVMsRUFBRSxFQUFFO0FBQzNCLElBQUk7Q0FDSCxTQUFTLFdBQVc7QUFDakIsV0FBVSxXQUFXO0FBQ3JCLFdBQVUsYUFBYTtBQUN2QixXQUFVLGFBQWE7QUFDdkIsV0FBVSxVQUFVO0FBQ3BCLFdBQVUsWUFBWTtBQUN0QixXQUFVLFlBQVk7QUFDdEIsV0FBVSxZQUFZO0dBQ3ZCLGFBQWEsV0FBVyxFQUFFLEVBQUU7Ozs7QUMxQy9CLE1BQU0sNEJBQTRCLE9BQU8sMEJBQTBCO0FBV25FLFNBQVMsMEJBQTBCLEdBQUc7QUFDcEMsUUFBTyxFQUFFOztBQUVYLFNBQVMsNEJBQTRCLFdBQVcsVUFBVTtDQUN4RCxNQUFNLG1CQUFtQixFQUFFO0FBQzNCLE1BQUssTUFBTSxhQUFhLE9BQU8sT0FBTyxTQUFTLFNBQVMsU0FBUyxFQUFFO0VBQ2pFLE1BQU0sZ0JBQWdCLFlBQVksMEJBQTBCLFVBQVUsR0FBRyxLQUFLO0FBQzlFLE1BQUksY0FDRixrQkFBaUIsS0FBSyxjQUFjOztBQUd4QyxLQUFJLFlBQVksU0FBUyxDQUN2QixNQUFLLE1BQU0sY0FBYyxTQUFTLFNBQVMsYUFBYTtFQUN0RCxNQUFNLGdCQUFnQiwwQkFBMEIsV0FBVztBQUMzRCxNQUFJLGNBQ0Ysa0JBQWlCLEtBQUssY0FBYzs7Q0FJMUMsSUFBSSxtQkFBbUI7QUFDdkIsTUFBSyxNQUFNLFVBQVUsaUJBQ25CLEtBQUksT0FBTyxXQUFXLFdBQ3BCLG9CQUFtQixPQUFPLGtCQUFrQixTQUFTO0tBRXJELG9CQUFtQjtFQUNqQixHQUFHO0VBQ0gsR0FBRztFQUNKO0FBR0wsUUFBTzs7QUFHVCxNQUFNLGlCQUFpQjtDQUNyQjtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7Q0FDRDtBQUVELFNBQVMsYUFBYSxRQUFRO0FBQzVCLFFBQU8sU0FBUyxPQUFPLElBQUksT0FBTyxTQUFTLFlBQVksT0FBTyxPQUFPLHFCQUFxQjs7QUFFNUYsU0FBUyxlQUFlLFFBQVE7QUFDOUIsUUFBTyxTQUFTLE9BQU8sSUFBSSxPQUFPLFNBQVM7O0FBRTdDLFNBQVMsWUFBWSxRQUFRO0FBQzNCLEtBQUksV0FBVyxLQUNiLFFBQU87QUFFVCxLQUFJLE9BQU8sS0FBSyxPQUFPLENBQUMsT0FBTyxNQUFNLENBQUMsZUFBZSxTQUFTLEVBQUUsQ0FBQyxDQUMvRCxRQUFPO0FBRVQsUUFBTzs7QUFFVCxTQUFTLHFCQUFxQixRQUFRLHFCQUFxQjtBQUN6RCxLQUFJLE9BQU8sS0FBSyxPQUFPLENBQUMsTUFDckIsTUFBTSxDQUFDO0VBQUM7RUFBUTtFQUFjO0VBQVk7RUFBdUIsQ0FBQyxTQUFTLEVBQUUsSUFBSSxlQUFlLFNBQVMsRUFBRSxJQUFJLE9BQU8sT0FBTyxLQUFLLEVBQ3BJLENBQ0MsUUFBTyxDQUFDLEVBQUUsTUFBTSxVQUFVLEVBQUUsT0FBTztDQUVyQyxNQUFNLFVBQVUsRUFBRSxHQUFHLFFBQVE7Q0FDN0IsTUFBTSxPQUFPLEVBQUUsR0FBRyxRQUFRO0FBQzFCLFNBQVEsYUFBYSxvQkFBb0IsUUFBUSxLQUFLLFFBQVE7RUFDNUQsTUFBTSxZQUFZLE9BQU8sYUFBYSxRQUFRLE9BQU87QUFDckQsTUFBSSxjQUFjLEtBQUssRUFDckIsS0FBSSxPQUFPO0FBRWIsU0FBTztJQUNOLEVBQUUsQ0FBQztBQUNOLFNBQVEsV0FBVyxPQUFPLFVBQVUsUUFBUSxRQUFRLG9CQUFvQixTQUFTLElBQUksQ0FBQztBQUN0RixTQUFRLFdBQVcsT0FBTyxVQUFVLEtBQUssWUFBWTtBQUNuRCxNQUFJLENBQUMsU0FBUyxRQUFRLENBQ3BCLFFBQU87QUFFVCxTQUFPLE9BQU8sUUFBUSxRQUFRLENBQUMsUUFBUSxLQUFLLENBQUMsS0FBS0EsYUFBVztBQUMzRCxPQUFJLG9CQUFvQixTQUFTLElBQUksQ0FDbkMsS0FBSSxPQUFPQTtBQUViLFVBQU87S0FDTixFQUFFLENBQUM7R0FDTjtBQUNGLE1BQUssYUFBYSxPQUFPLGNBQWMsT0FBTyxRQUFRLE9BQU8sV0FBVyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsb0JBQW9CLFNBQVMsSUFBSSxDQUFDLENBQUMsUUFBUSxLQUFLLENBQUMsS0FBS0EsYUFBVztBQUMzSixNQUFJLE9BQU9BO0FBQ1gsU0FBTztJQUNOLEVBQUUsQ0FBQztBQUNOLE1BQUssV0FBVyxPQUFPLFVBQVUsUUFBUSxRQUFRLENBQUMsb0JBQW9CLFNBQVMsSUFBSSxDQUFDO0FBQ3BGLE1BQUssV0FBVyxPQUFPLFVBQVUsS0FBSyxZQUFZO0FBQ2hELE1BQUksQ0FBQyxTQUFTLFFBQVEsQ0FDcEIsUUFBTztBQUVULFNBQU8sT0FBTyxRQUFRLFFBQVEsQ0FBQyxRQUFRLEtBQUssQ0FBQyxLQUFLQSxhQUFXO0FBQzNELE9BQUksQ0FBQyxvQkFBb0IsU0FBUyxJQUFJLENBQ3BDLEtBQUksT0FBT0E7QUFFYixVQUFPO0tBQ04sRUFBRSxDQUFDO0dBQ047QUFDRixRQUFPLENBQUMsU0FBUyxLQUFLOztBQUV4QixTQUFTLHFCQUFxQixRQUFRLE9BQU8sVUFBVSxFQUFFLEVBQUU7QUFDekQsS0FBSSxNQUFNLE9BQU8sRUFBRTtBQUNqQixVQUFRLEtBQUssT0FBTztBQUNwQixTQUFPLENBQUMsU0FBUyxLQUFLLEVBQUU7O0FBRTFCLEtBQUksU0FBUyxPQUFPLEVBQ2xCO09BQUssTUFBTSxXQUFXLENBQUMsU0FBUyxRQUFRLENBQ3RDLEtBQUksT0FBTyxZQUFZLE9BQU8sS0FBSyxPQUFPLENBQUMsT0FDeEMsTUFBTSxNQUFNLFdBQVcsQ0FBQyxlQUFlLFNBQVMsRUFBRSxDQUNwRCxFQUFFO0dBQ0QsTUFBTSxPQUFPLE9BQU8sU0FBUyxLQUFLLE1BQU0scUJBQXFCLEdBQUcsT0FBTyxRQUFRLENBQUMsR0FBRyxDQUFDLFFBQVEsTUFBTSxDQUFDLENBQUMsRUFBRTtBQUN0RyxPQUFJLEtBQUssV0FBVyxLQUFLLE9BQU8sS0FBSyxPQUFPLFNBQzFDLFFBQU8sQ0FBQyxTQUFTO0lBQUUsR0FBRztLQUFTLFVBQVUsS0FBSztJQUFHLEdBQUcsS0FBSztJQUFJLENBQUM7QUFFaEUsVUFBTyxDQUFDLFNBQVM7SUFBRSxHQUFHO0tBQVMsVUFBVTtJQUFNLENBQUM7OztBQUl0RCxRQUFPLENBQUMsU0FBUyxPQUFPOztBQUUxQixTQUFTLHVCQUF1QixVQUFVLFFBQVE7QUFDaEQsS0FBSSxTQUNGLFFBQU87QUFFVCxRQUFPLEVBQ0wsT0FBTyxDQUNMLFFBQ0EsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUNaLEVBQ0Y7O0FBRUgsU0FBUyxrQkFBa0IsUUFBUTtBQUNqQyxLQUFJLE9BQU8sV0FBVyxVQUNwQjtPQUFLLE1BQU0sV0FBVyxDQUFDLFNBQVMsUUFBUSxDQUN0QyxLQUFJLE9BQU8sWUFBWSxPQUFPLEtBQUssT0FBTyxDQUFDLE9BQ3hDLE1BQU0sTUFBTSxXQUFXLENBQUMsZUFBZSxTQUFTLEVBQUUsQ0FDcEQsQ0FDQyxRQUFPLE9BQU8sU0FBUyxTQUFTLE1BQU0sa0JBQWtCLEVBQUUsQ0FBQzs7QUFJakUsUUFBTyxDQUFDLE9BQU87O0FBRWpCLFNBQVMsc0JBQXNCLFFBQVE7Q0FDckMsTUFBTSxVQUFVLGtCQUFrQixPQUFPO0FBQ3pDLEtBQUksUUFBUSxXQUFXLEVBQ3JCO0NBRUYsTUFBTSxjQUFjLFFBQVEsTUFDekIsTUFBTSxPQUFPLE1BQU0sWUFBWSxFQUFFLFNBQVMsV0FBVyxPQUFPLEtBQUssRUFBRSxDQUFDLFFBQVEsTUFBTSxlQUFlLFNBQVMsRUFBRSxDQUFDLENBQUMsT0FBTyxNQUFNLE1BQU0sVUFBVSxNQUFNLFFBQVEsQ0FDM0o7QUFDRCxLQUFJLGdCQUFnQixLQUFLLEVBQ3ZCO0NBRUYsTUFBTSxTQUFTLFlBQVk7Q0FDM0IsTUFBTSxTQUFTLFFBQVEsTUFBTSxNQUFNLE1BQU0sWUFBWTtBQUNyRCxLQUFJLGNBQWMsT0FBTyxLQUFLLGNBQWMsT0FBTyxDQUNqRDtBQUVGLFFBQU8sQ0FBQyxRQUFRLFlBQVk7O0FBRTlCLE1BQU0seUNBQXlDLElBQUksSUFBSTtDQUNyRCxTQUFTO0NBQ1QsU0FBUztDQUNULFNBQVM7Q0FDVCxTQUFTO0NBQ1QsU0FBUztDQUNWLENBQUM7QUFDRixTQUFTLGtCQUFrQixRQUFRO0FBQ2pDLFFBQU8sa0JBQWtCLE9BQU8sQ0FBQyxPQUFPLE1BQU07QUFDNUMsTUFBSSxPQUFPLE1BQU0sVUFDZixRQUFPO0FBRVQsTUFBSSxPQUFPLEVBQUUsU0FBUyxZQUFZLHVCQUF1QixJQUFJLEVBQUUsS0FBSyxDQUNsRSxRQUFPO0FBRVQsTUFBSSxFQUFFLFVBQVUsS0FBSyxFQUNuQixRQUFPO0FBRVQsU0FBTztHQUNQOztBQUdKLFNBQVMsY0FBYyxNQUFNO0FBQzNCLFFBQU8sb0JBQW9CLEtBQUssQ0FBQyxRQUFRLG9CQUFvQixRQUFROztBQUV2RSxTQUFTLGdCQUFnQixRQUFRO0FBQy9CLFFBQU8sT0FBTyxtQkFBbUI7O0FBRW5DLFNBQVMsaUJBQWlCLFFBQVE7Q0FDaEMsTUFBTSxVQUFVLEVBQUU7Q0FDbEIsTUFBTSxDQUFDLFNBQVMsY0FBYyxxQkFBcUIsUUFBUSxhQUFhO0FBQ3hFLE1BQUssTUFBTSxRQUFRLFFBQ2pCLFNBQVEsS0FBSyxvQkFBb0IsRUFDL0IsUUFBUSxnQkFBZ0IsS0FBSyxFQUM5QjtBQUVILEtBQUksZUFBZSxLQUFLLEdBQUc7QUFDekIsVUFBUSxzQkFBc0IsRUFDNUIsUUFBUSxnQkFBZ0IsV0FBVyxFQUNwQztBQUVELE1BRDZCLGlCQUFpQixNQUFNLFNBQVMsRUFBRSxJQUFJLGFBQWEsRUFBRSxFQUFFLFdBQVcsQ0FBQyxPQUFPLFNBQVMsRUFFOUcsU0FBUSx5QkFBeUIsRUFDL0IsUUFBUSxnQkFBZ0IsV0FBVyxFQUNwQzs7QUFHTCxRQUFPOztBQUVULFNBQVMsOEJBQThCLENBQUMsZ0JBQWdCLGVBQWUsQ0FBQyxpQkFBaUIsZ0JBQWdCO0FBQ3ZHLFFBQU8sRUFDTCxxQkFBcUIsRUFDbkIsUUFBUSxnQkFBZ0IsRUFDdEIsT0FBTztFQUNMO0dBQ0UsTUFBTTtHQUNOLFlBQVk7SUFDVixPQUFPLEVBQUUsT0FBTyxXQUFXO0lBQzNCLE1BQU07SUFDTixJQUFJLEVBQUUsTUFBTSxVQUFVO0lBQ3RCLE9BQU8sRUFBRSxNQUFNLFVBQVU7SUFDMUI7R0FDRCxVQUFVLGlCQUFpQixDQUFDLFNBQVMsT0FBTyxHQUFHLENBQUMsUUFBUTtHQUN6RDtFQUNEO0dBQ0UsTUFBTTtHQUNOLFlBQVk7SUFDVixPQUFPLEVBQUUsT0FBTyxRQUFRO0lBQ3hCLE1BQU07SUFDTixJQUFJLEVBQUUsTUFBTSxVQUFVO0lBQ3RCLE9BQU8sRUFBRSxNQUFNLFVBQVU7SUFDMUI7R0FDRCxVQUFVLGtCQUFrQixDQUFDLFNBQVMsT0FBTyxHQUFHLENBQUMsUUFBUTtHQUMxRDtFQUNEO0dBQ0UsTUFBTTtHQUNOLFlBQVk7SUFDVixPQUFPLEVBQUUsT0FBTyxTQUFTO0lBQ3pCLE1BQU0sRUFBRTtJQUNSLElBQUksRUFBRSxNQUFNLFVBQVU7SUFDdEIsT0FBTyxFQUFFLE1BQU0sVUFBVTtJQUMxQjtHQUNELFVBQVUsQ0FBQyxRQUFRO0dBQ3BCO0VBQ0YsRUFDRixDQUFDLEVBQ0gsRUFDRjs7QUFFSCxTQUFTLG9CQUFvQixRQUFRLGFBQWE7Q0FDaEQsTUFBTSxhQUFhLEVBQUU7QUFDckIsTUFBSyxNQUFNLE9BQU8sT0FBTyxZQUFZO0VBQ25DLE1BQU0sWUFBWSxPQUFPLFdBQVc7RUFDcEMsSUFBSSxvQkFBb0I7QUFDeEIsTUFBSSxnQkFBZ0IsUUFDbEIscUJBQW9CO1dBQ1gsa0JBQWtCLFVBQVUsQ0FDckMscUJBQW9CO09BQ2Y7R0FDTCxNQUFNLENBQUMsUUFBUSxzQkFBc0IsVUFBVSxJQUFJLEVBQUU7QUFDckQsT0FBSSxTQUFTLEtBQUssS0FBSyxrQkFBa0IsS0FBSyxDQUM1QyxxQkFBb0I7O0FBR3hCLGFBQVcsS0FBSztHQUNkLE1BQU07R0FDTixJQUFJO0dBQ0osVUFBVSxPQUFPLFVBQVUsU0FBUyxJQUFJO0dBQ3hDLFFBQVEsZ0JBQWdCLFVBQVU7R0FDbEMsT0FBTyxvQkFBb0IsZUFBZSxLQUFLO0dBQy9DLFNBQVMsb0JBQW9CLE9BQU8sS0FBSztHQUN6QyxpQkFBaUIsZ0JBQWdCLFVBQVUsT0FBTyxLQUFLO0dBQ3ZELGVBQWUsZ0JBQWdCLFVBQVUsT0FBTyxLQUFLO0dBQ3RELENBQUM7O0FBRUosUUFBTzs7QUFFVCxTQUFTLGtCQUFrQixRQUFRLFFBQVE7Q0FDekMsTUFBTSxhQUFhLE9BQU8sS0FBSyxPQUFPLGNBQWMsRUFBRSxDQUFDO0NBQ3ZELE1BQU0sV0FBVyxPQUFPLFlBQVksRUFBRTtBQUN0QyxLQUFJLFdBQVcsV0FBVyxPQUFPLFVBQVUsV0FBVyxNQUFNLE1BQU0sQ0FBQyxPQUFPLFNBQVMsRUFBRSxDQUFDLENBQ3BGLFFBQU87QUFFVCxLQUFJLFNBQVMsV0FBVyxPQUFPLFVBQVUsU0FBUyxNQUFNLE1BQU0sQ0FBQyxPQUFPLFNBQVMsRUFBRSxDQUFDLENBQ2hGLFFBQU87QUFFVCxRQUFPOztBQUVULFNBQVMsZ0JBQWdCLFFBQVE7QUFDL0IsUUFBTyxXQUFXLE9BQU8sRUFBRSxHQUFHLFdBQVcsUUFBUSxFQUFFLEtBQUssRUFBRSxFQUFFLEdBQUc7O0FBRWpFLE1BQU0saUNBQWlDO0FBQ3ZDLFNBQVMsNEJBQTRCLEtBQUssUUFBUTtBQUNoRCxLQUFJLE9BQU8sV0FBVyxZQUFZLENBQUMsT0FBTyxNQUFNLFdBQVcsK0JBQStCLENBQ3hGLFFBQU87Q0FFVCxNQUFNLE9BQU8sT0FBTyxLQUFLLE1BQU0sR0FBc0M7QUFFckUsUUFEaUIsSUFBSSxZQUFZLFVBQVUsU0FDeEI7O0FBR3JCLElBQU0sMkJBQU4sTUFBK0I7Q0FDN0I7Q0FDQSxZQUFZLFlBQVk7QUFDdEIsT0FBSyxhQUFhOztDQUVwQixNQUFNLFFBQVEsUUFBUSxTQUFTO0FBQzdCLE9BQUssTUFBTSxhQUFhLEtBQUssV0FDM0IsS0FBSSxNQUFNLFVBQVUsVUFBVSxRQUFRLFFBQVEsQ0FDNUMsUUFBTyxVQUFVLFFBQVEsUUFBUSxRQUFRO0FBRzdDLFNBQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQzs7O0FBSXRCLElBQU0sd0JBQU4sY0FBb0MsTUFBTTtBQUUxQyxJQUFNLG1CQUFOLE1BQXVCO0NBQ3JCO0NBQ0E7Q0FDQSxZQUFZLFVBQVUsRUFBRSxFQUFFO0FBQ3hCLE9BQUssYUFBYSxJQUFJLDhCQUE4QixRQUFRO0FBQzVELE9BQUssWUFBWSxJQUFJLHlCQUF5QixRQUFRLFFBQVEsaUJBQWlCLENBQUM7Ozs7Ozs7Q0FPbEYsTUFBTSxTQUFTLFFBQVEsRUFBRSwrQkFBK0IsZUFBZSxRQUFRLFlBQVksUUFBUyxHQUFHLFlBQVksRUFBRSxFQUFFO0VBQ3JILE1BQU0sU0FBUyxnQkFBZ0IsRUFBRSxVQUFVLFdBQVc7QUFDcEQsVUFBTyxFQUFFLFVBQVUsVUFBVSxLQUFLLElBQUk7O0VBRXhDLE1BQU0sTUFBTTtHQUNWLEdBQUcsTUFBTSxRQUFRO0dBQ2pCLE1BQU0sUUFBUSxRQUFRO0lBQUUsT0FBTztJQUFpQixTQUFTO0lBQVM7R0FDbEUsU0FBUztHQUNWO0VBQ0QsTUFBTSxFQUFFLDBCQUEwQiw2QkFBNkIsTUFBTSxNQUFLQyxxQkFBc0IsS0FBSyxjQUFjO0VBQ25ILE1BQU0sWUFBWSxFQUFFO0FBQ3BCLFFBQU0sMEJBQTBCO0dBQUUsTUFBTSxFQUFFO0dBQUU7R0FBUSxHQUFHLG9CQUFvQjtBQUN6RSxPQUFJLENBQUMsTUFBTSxRQUFRLGdCQUFnQixDQUNqQztBQUVGLGFBQVUsS0FBSyxnQkFBZ0I7SUFDL0I7RUFDRixNQUFNLFNBQVMsRUFBRTtBQUNqQixPQUFLLE1BQU0sRUFBRSxVQUFVLFVBQVUsV0FBVztHQUMxQyxNQUFNLGFBQWEsS0FBSyxLQUFLLElBQUk7QUFDakMsT0FBSTtJQUNGLE1BQU0sTUFBTSxTQUFTO0lBQ3JCLE1BQU0sU0FBUyxnQkFBZ0IsdUJBQXVCLGlCQUFpQixJQUFJLE1BQU0sT0FBTyxDQUFDO0lBQ3pGLE1BQU0sV0FBVyxjQUFjLElBQUksTUFBTSxRQUFRLFdBQVcsS0FBSyxDQUFDO0lBQ2xFLElBQUk7QUFDSixRQUFJLElBQUksTUFBTSxTQUFTLEtBQUssS0FBSyxPQUFPLElBQUksTUFBTSxTQUFTLFdBQ3pELHNCQUFxQixJQUFJLE1BQU07U0FDMUI7QUFDTCwwQkFBcUI7TUFDbkIsYUFBYSxJQUFJLE1BQU0sZUFBZTtNQUN0QyxTQUFTLElBQUksTUFBTTtNQUNuQixhQUFhLElBQUksTUFBTTtNQUN2QixZQUFZLElBQUksTUFBTTtNQUN0QixNQUFNLElBQUksTUFBTSxNQUFNLEtBQUssUUFBUSxJQUFJO01BQ3hDO0FBQ0QsV0FBTSxNQUFLQyxRQUFTLEtBQUssb0JBQW9CLEtBQUsseUJBQXlCO0FBQzNFLFdBQU0sTUFBS0MsZ0JBQWlCLEtBQUssb0JBQW9CLEtBQUsseUJBQXlCO0FBQ25GLFdBQU0sTUFBS0MsY0FBZSxvQkFBb0IsS0FBSywwQkFBMEIsMEJBQTBCLDhCQUE4Qjs7QUFFdkksUUFBSSxPQUFPLElBQUksTUFBTSxTQUFTLFdBQzVCLHNCQUFxQixJQUFJLE1BQU0sS0FBSyxtQkFBbUI7QUFFekQsUUFBSSxVQUFVLEVBQUU7QUFDaEIsUUFBSSxNQUFNLGNBQWMsRUFBRTtBQUMxQixRQUFJLE1BQU0sVUFBVSxVQUFVLDRCQUE0QixvQkFBb0IsU0FBUztZQUNoRixHQUFHO0FBQ1YsUUFBSSxFQUFFLGFBQWEsdUJBQ2pCLE9BQU07QUFFUixXQUFPLEtBQ0wscUZBQXFGLFdBQVc7RUFDeEcsRUFBRSxVQUNLOzs7QUFHTCxNQUFJLE9BQU8sT0FDVCxPQUFNLElBQUksc0JBQ1I7O0VBRU4sT0FBTyxLQUFLLE9BQU8sR0FDZDtBQUVILFNBQU8sS0FBSyxXQUFXLFVBQVUsSUFBSSxDQUFDOztDQUV4QyxPQUFNSCxxQkFBc0IsS0FBSyxlQUFlO0VBQzlDLElBQUksMkJBQTJCO0dBQzdCLE1BQU07R0FDTixZQUFZO0lBQ1YsU0FBUyxFQUFFLE9BQU8sT0FBTztJQUN6QixNQUFNLEVBQUUsTUFBTSxVQUFVO0lBQ3hCLFFBQVEsRUFBRSxNQUFNLFVBQVU7SUFDMUIsU0FBUyxFQUFFLE1BQU0sVUFBVTtJQUMzQixNQUFNLEVBQUU7SUFDVDtHQUNELFVBQVU7SUFBQztJQUFXO0lBQVE7SUFBVTtJQUFVO0dBQ25EO0VBQ0QsTUFBTSwyQkFBMkIsRUFBRTtBQUNuQyxNQUFJLGVBQWU7QUFDakIsNEJBQXlCLGFBQWEsRUFBRTtBQUN4QyxRQUFLLE1BQU0sT0FBTyxlQUFlO0lBQy9CLE1BQU0sVUFBVSxjQUFjO0FBQzlCLFFBQUksUUFBUSxXQUFXLEtBQUssRUFDMUI7SUFFRixNQUFNLEVBQUUsUUFBUSxXQUFXLFlBQVk7SUFDdkMsTUFBTSxDQUFDLFVBQVUsUUFBUSxNQUFNLEtBQUssVUFBVSxRQUFRLFFBQVEsRUFBRSxVQUFVLENBQUM7SUFDM0UsTUFBTSxvQkFBb0IsQ0FBQyxTQUFTO0FBQ3BDLFFBQUksYUFBYSxTQUFTO0tBQ3hCLE1BQU0sQ0FBQyxnQkFBZ0IsY0FBYyxNQUFNLEtBQUssVUFBVSxRQUFRLFFBQVEsRUFBRSxVQUFVLFVBQVUsQ0FBQztBQUNqRyxTQUFJLG1CQUFtQixZQUFZLGNBQWMsV0FBVyxLQUFLLGNBQWMsS0FBSyxDQUNsRixtQkFBa0IsS0FBSyxTQUFTO2VBRXpCLGFBQWEsVUFBVTtLQUNoQyxNQUFNLENBQUMsZUFBZSxhQUFhLE1BQU0sS0FBSyxVQUFVLFFBQVEsUUFBUSxFQUFFLFVBQVUsU0FBUyxDQUFDO0FBQzlGLFNBQUksa0JBQWtCLFlBQVksY0FBYyxVQUFVLEtBQUssY0FBYyxLQUFLLENBQ2hGLG1CQUFrQixLQUFLLFFBQVE7O0FBR25DLDZCQUF5QixXQUFXLEtBQUs7S0FDdkM7S0FDQTtLQUNBLEtBQUssd0JBQXdCO0tBQzdCO0tBQ0QsQ0FBQzs7QUFFSixPQUFJLGVBQWUsRUFBRTtBQUNyQixPQUFJLFdBQVcsWUFBWSxFQUFFO0FBQzdCLFFBQUssTUFBTSxPQUFPLGVBQWU7SUFDL0IsTUFBTSxVQUFVLGNBQWM7QUFDOUIsUUFBSSxRQUFRLFdBQVcsS0FBSyxHQUFHO0FBQzdCLFNBQUksUUFBUSxVQUFVLGtCQUFrQjtBQUN0QyxVQUFJLFdBQVcsUUFBUSxPQUFPLGdCQUFnQix5QkFBeUI7QUFDdkUsaUNBQTJCLEVBQUUsTUFBTSx3QkFBd0IsT0FBTzs7QUFFcEU7O0lBRUYsTUFBTSxFQUFFLFFBQVEsV0FBVyxZQUFZO0lBQ3ZDLE1BQU0sR0FBRyxRQUFRLE1BQU0sS0FBSyxVQUFVLFFBQ3BDLFFBQ0E7S0FDRSxHQUFHO0tBQ0g7S0FDQSx5QkFBeUI7S0FFMUIsQ0FDRjtBQUNELFFBQUksV0FBVyxRQUFRLE9BQU8sZ0JBQWdCLEtBQUs7OztBQUd2RCxTQUFPO0dBQUU7R0FBMEI7R0FBMEI7O0NBRS9ELE9BQU1DLFFBQVMsS0FBSyxLQUFLLEtBQUssMEJBQTBCO0VBQ3RELE1BQU0sU0FBUyx1QkFBdUIsaUJBQWlCLElBQUksTUFBTSxPQUFPO0VBQ3hFLE1BQU0sVUFBVSw4QkFBOEIsSUFBSSxZQUFZO0FBQzlELE1BQUksU0FBUztBQUNYLE9BQUksY0FBYztJQUNoQixVQUFVO0lBQ1YsU0FBUyw4QkFDUCxNQUFNLEtBQUssVUFBVSxRQUFRLFFBQVEsUUFBUTtLQUFFLEdBQUc7S0FBMEIsVUFBVTtLQUFTLENBQUMsRUFDaEcsTUFBTSxLQUFLLFVBQVUsUUFBUSxRQUFRLFNBQVM7S0FBRSxHQUFHO0tBQTBCLFVBQVU7S0FBUyxDQUFDLENBQ2xHO0lBQ0Y7QUFDRDs7RUFFRixNQUFNLGdCQUFnQixpQkFBaUIsSUFBSSxNQUFNLEtBQUssRUFBRSxLQUFLLE1BQU0sRUFBRSxLQUFLO0VBQzFFLE1BQU0saUJBQWlCLHVCQUF1Qix5QkFBeUIsSUFBSSxNQUFNLGVBQWU7RUFDaEcsSUFBSSxDQUFDLFVBQVUsVUFBVSxNQUFNLEtBQUssVUFBVSxRQUM1QyxJQUFJLGFBQ0o7R0FDRSxHQUFHO0dBQ0gsVUFBVTtHQUNWLHlCQUF5QixlQUFlLFVBQVUsbUJBQW1CLGFBQWEsSUFBSTtHQUN2RixDQUNGO0FBQ0QsTUFBSSxZQUFZLE9BQU8sSUFBSSxDQUFDLGVBQWUsT0FDekM7QUFFRixNQUFJLG1CQUFtQixXQUFXO0FBQ2hDLE9BQUksZUFBZSxRQUFRO0lBQ3pCLE1BQU0sU0FBUyxJQUFJLHNCQUNqQix3SUFDRDtBQUNELFFBQUksQ0FBQyxlQUFlLE9BQU8sQ0FDekIsT0FBTTtJQUVSLE1BQU0sQ0FBQyxjQUFjLFFBQVEscUJBQXFCLFFBQVEsY0FBYztBQUN4RSxhQUFTO0FBQ1QsZUFBVyxLQUFLLFdBQVcsS0FBSyxTQUFTLFdBQVcsSUFBSTtBQUN4RCxRQUFJLENBQUMsa0JBQWtCLGNBQWMsY0FBYyxDQUNqRCxPQUFNO0FBRVIsUUFBSSxlQUFlLEVBQUU7QUFDckIsUUFBSSxXQUFXLEtBQUssR0FBRyxvQkFBb0IsY0FBYyxPQUFPLENBQUM7O0FBRW5FLE9BQUksV0FBVyxPQUFPO0lBQ3BCLE1BQU0saUJBQWlCLDRCQUE0QixLQUFLLE9BQU87QUFDL0QsUUFBSSxDQUFDLGVBQWUsZUFBZSxDQUNqQyxPQUFNLElBQUksc0JBQ1IsNEVBQ0Q7QUFFSCxRQUFJLGVBQWUsRUFBRTtBQUNyQixRQUFJLFdBQVcsS0FBSyxHQUFHLG9CQUFvQixnQkFBZ0IsUUFBUSxDQUFDO1NBRXBFLEtBQUksY0FBYztJQUNoQjtJQUNBLFNBQVMsaUJBQWlCLE9BQU87SUFDbEM7QUFFSDs7RUFFRixNQUFNLFFBQVEsSUFBSSxzQkFDaEIsNExBQ0Q7QUFDRCxNQUFJLENBQUMsZUFBZSxPQUFPLENBQ3pCLE9BQU07RUFFUixNQUFNLHNCQUFzQixPQUFPLFlBQVksV0FBVyxLQUFLLElBQUksNEJBQTRCLEtBQUssT0FBTyxXQUFXLE9BQU8sR0FBRyxLQUFLO0FBQ3JJLE1BQUksZUFBZSxXQUFXLHdCQUF3QixLQUFLLEtBQUssQ0FBQyxlQUFlLG9CQUFvQixJQUFJLENBQUMsa0JBQWtCLHFCQUFxQixjQUFjLEVBQzVKLE9BQU0sSUFBSSxzQkFDUixpSkFDRDtBQUVILE9BQUssTUFBTSxRQUFRO0dBQUM7R0FBVTtHQUFTO0dBQVUsRUFBRTtHQUNqRCxNQUFNLGFBQWEsT0FBTyxhQUFhO0FBQ3ZDLE9BQUksZUFBZSxLQUFLLEdBQUc7SUFDekIsTUFBTSxpQkFBaUIsNEJBQTRCLEtBQUssV0FBVztBQUNuRSxRQUFJLENBQUMsZUFBZSxlQUFlLENBQ2pDLE9BQU07SUFFUixNQUFNLGNBQWMsU0FBUyxXQUFXLFNBQVMsU0FBUyxZQUFZLFdBQVc7QUFDakYsUUFBSSxlQUFlLEVBQUU7QUFDckIsUUFBSSxXQUFXLEtBQUssR0FBRyxvQkFBb0IsZ0JBQWdCLFlBQVksQ0FBQzs7O0FBRzVFLE1BQUksT0FBTyxZQUFZLFNBQVMsS0FBSyxFQUNuQyxLQUFJLGNBQWM7R0FDaEIsVUFBVSxPQUFPLFVBQVUsU0FBUyxPQUFPO0dBQzNDLFNBQVMsaUJBQWlCLE9BQU8sV0FBVyxLQUFLO0dBQ2xEOztDQUdMLE9BQU1DLGdCQUFpQixLQUFLLEtBQUssS0FBSywwQkFBMEI7RUFDOUQsTUFBTSxlQUFlLElBQUk7RUFDekIsTUFBTSxTQUFTLHVCQUF1Qix3QkFBd0IsSUFBSSxNQUFNLGNBQWM7RUFDdEYsTUFBTSxjQUFjLHVCQUF1Qiw2QkFBNkIsSUFBSSxPQUFPLG1CQUFtQjtFQUN0RyxNQUFNLDZCQUE2Qiw4QkFBOEIsYUFBYTtFQUM5RSxNQUFNLGtCQUFrQix1QkFBdUIsMEJBQTBCLElBQUksTUFBTSxnQkFBZ0I7QUFDbkcsTUFBSSw0QkFBNEI7QUFDOUIsT0FBSSxjQUFjLEVBQUU7QUFDcEIsT0FBSSxVQUFVLFVBQVU7SUFDdEI7SUFDQSxTQUFTLDhCQUNQLE1BQU0sS0FBSyxVQUFVLFFBQVEsMkJBQTJCLFFBQVE7S0FBRSxHQUFHO0tBQTBCLFVBQVU7S0FBVSxDQUFDLEVBQ3BILE1BQU0sS0FBSyxVQUFVLFFBQVEsMkJBQTJCLFNBQVM7S0FBRSxHQUFHO0tBQTBCLFVBQVU7S0FBVSxDQUFDLENBQ3RIO0lBQ0Y7QUFDRDs7RUFFRixNQUFNLENBQUMsVUFBVSxRQUFRLE1BQU0sS0FBSyxVQUFVLFFBQzVDLGNBQ0E7R0FDRSxHQUFHO0dBQ0gsVUFBVTtHQUNWLHlCQUF5QixvQkFBb0IsYUFBYSxJQUFJO0dBQy9ELENBQ0Y7QUFDRCxNQUFJLG9CQUFvQixXQUFXO0FBQ2pDLE9BQUksY0FBYyxFQUFFO0FBQ3BCLE9BQUksVUFBVSxVQUFVLEVBQ3RCLGFBQ0Q7QUFDRCxPQUFJLFVBQVUsUUFBUSxVQUFVLGlCQUFpQix1QkFBdUIsVUFBVSxLQUFLLENBQUM7QUFDeEY7O0VBRUYsTUFBTSxrQ0FBa0MsSUFBSSxLQUFLO0FBQ2pELE9BQUssTUFBTSxRQUFRLGtCQUFrQixLQUFLLEVBQUU7R0FDMUMsTUFBTSxRQUFRLElBQUksc0JBQXNCOzs7Ozs7OzttQkFRM0IsY0FBYyxLQUFLLENBQUM7UUFDL0I7QUFDRixPQUFJLENBQUMsZUFBZSxLQUFLLENBQ3ZCLE9BQU07R0FFUixJQUFJO0dBQ0osSUFBSTtBQUNKLE9BQUksS0FBSyxZQUFZLFdBQVcsS0FBSyxHQUFHO0lBQ3RDLE1BQU0sZUFBZSw0QkFBNEIsS0FBSyxLQUFLLFdBQVcsT0FBTztBQUM3RSxRQUFJLE9BQU8saUJBQWlCLFlBQVksYUFBYSxVQUFVLEtBQUssS0FBSyxPQUFPLGFBQWEsVUFBVSxZQUFZLENBQUMsT0FBTyxVQUFVLGFBQWEsTUFBTSxJQUFJLGtCQUFrQixhQUFhLE1BQU0sQ0FDL0wsT0FBTTtBQUVSLG1CQUFlLGFBQWE7QUFDNUIsd0JBQW9CLGFBQWE7O0dBRW5DLE1BQU0sYUFBYSxnQkFBZ0I7R0FDbkMsTUFBTSxrQkFBa0IscUJBQXFCO0FBQzdDLE9BQUksZ0JBQWdCLElBQUksV0FBVyxDQUNqQyxPQUFNLElBQUksc0JBQXNCOzs0QkFFWixXQUFXO1VBQzdCO0FBRUosbUJBQWdCLElBQUksV0FBVztBQUMvQixPQUFJLGNBQWMsRUFBRTtBQUNwQixPQUFJLFVBQVUsY0FBYyxFQUMxQixhQUFhLGlCQUNkO0FBQ0QsT0FBSSxLQUFLLFlBQVksWUFBWSxLQUFLLEdBQUc7SUFDdkMsTUFBTSxnQkFBZ0IsNEJBQTRCLEtBQUssS0FBSyxXQUFXLFFBQVE7QUFDL0UsUUFBSSxDQUFDLGVBQWUsY0FBYyxDQUNoQyxPQUFNO0FBRVIsU0FBSyxNQUFNLE9BQU8sY0FBYyxZQUFZO0tBQzFDLE1BQU0sZUFBZSxjQUFjLFdBQVc7QUFDOUMsU0FBSSxpQkFBaUIsS0FBSyxHQUFHO0FBQzNCLFVBQUksVUFBVSxZQUFZLFlBQVksRUFBRTtBQUN4QyxVQUFJLFVBQVUsWUFBWSxRQUFRLE9BQU87T0FDdkMsUUFBUSxnQkFBZ0IsYUFBYTtPQUNyQyxVQUFVLEtBQUssVUFBVSxTQUFTLFVBQVUsSUFBSSxjQUFjLFVBQVUsU0FBUyxJQUFJO09BQ3RGOzs7O0FBSVAsT0FBSSxLQUFLLFlBQVksU0FBUyxLQUFLLEVBQ2pDLEtBQUksVUFBVSxZQUFZLFVBQVUsaUJBQ2xDLHVCQUF1QixLQUFLLFVBQVUsU0FBUyxPQUFPLElBQUksT0FBTyxLQUFLLFdBQVcsS0FBSyxDQUN2Rjs7O0NBSVAsT0FBTUMsY0FBZSxLQUFLLEtBQUssMEJBQTBCLHNCQUFzQiwrQkFBK0I7RUFDNUcsTUFBTSxXQUFXLElBQUk7RUFDckIsTUFBTSx5QkFBeUIsRUFBRTtBQUNqQyxPQUFLLE1BQU0sUUFBUSxVQUFVO0dBQzNCLE1BQU0sU0FBUyxTQUFTO0FBQ3hCLE9BQUksQ0FBQyxPQUNIO0dBRUYsTUFBTSxTQUFTLHdCQUF3QixNQUFNLE9BQU8sT0FBTztHQUMzRCxNQUFNLGlCQUFpQix5QkFBeUIsTUFBTSxPQUFPLFFBQVE7QUFDckUsMEJBQXVCLFlBQVk7SUFBRTtJQUFRLHlCQUF5QixFQUFFO0lBQUUscUJBQXFCLEVBQUU7SUFBRTtHQUNuRyxNQUFNLENBQUMsY0FBYyxjQUFjLE1BQU0sS0FBSyxVQUFVLFFBQVEsT0FBTyxNQUFNO0lBQUUsR0FBRztJQUEwQixVQUFVO0lBQVUsQ0FBQztBQUNqSSwwQkFBdUIsUUFBUSx3QkFBd0IsS0FBSztJQUFDO0lBQU07SUFBZ0I7SUFBYztJQUFXLENBQUM7QUFDN0csMEJBQXVCLFFBQVEsb0JBQW9CLEtBQUs7SUFDdEQsTUFBTTtJQUNOLFlBQVk7S0FDVixTQUFTLEVBQUUsT0FBTyxNQUFNO0tBQ3hCLE1BQU0sRUFBRSxPQUFPLE1BQU07S0FDckIsUUFBUSxFQUFFLE9BQU8sUUFBUTtLQUN6QixTQUFTO01BQUUsTUFBTTtNQUFVLFNBQVM7TUFBZ0I7S0FDcEQsTUFBTTtLQUNQO0lBQ0QsVUFBVSxlQUFlO0tBQUM7S0FBVztLQUFRO0tBQVU7S0FBVztLQUFPLEdBQUc7S0FBQztLQUFXO0tBQVE7S0FBVTtLQUFVO0lBQ3JILENBQUM7O0FBRUosTUFBSSxjQUFjLEVBQUU7QUFDcEIsT0FBSyxNQUFNLGdCQUFnQix3QkFBd0I7R0FDakQsTUFBTSxnQkFBZ0IsdUJBQXVCO0dBQzdDLE1BQU0sbUJBQW1CLE1BQU0sK0JBQStCLGNBQWMseUJBQXlCLGNBQWMsT0FBTztBQUMxSCxPQUFJLFVBQVUsZ0JBQWdCO0lBQzVCLGFBQWE7SUFDYixTQUFTLGlCQUFpQixvQkFBb0IsRUFDNUMsT0FBTyxDQUNMLEdBQUcsY0FBYyxxQkFDakIscUJBQ0QsRUFDRixDQUFDO0lBQ0gifQ==