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.
- package/dist/build/rspack/index.cjs +45 -7
- package/dist/build/rspack/index.mjs +45 -7
- package/dist/{errors-CVnoPl9v.cjs → errors-BEsEPXKG.cjs} +2 -2
- package/dist/errors-CpYzD_-M.d.cts +38 -0
- package/dist/errors-D2-thHKG.d.mts +38 -0
- package/dist/{errors-D7keKf7a.mjs → errors-DnigICIv.mjs} +2 -2
- package/dist/errors.cjs +2 -2
- package/dist/errors.d.cts +1 -2
- package/dist/errors.d.mts +1 -2
- package/dist/errors.mjs +2 -2
- package/dist/{fetch-Cc95-7kM.cjs → fetch-CGzn1Uf7.cjs} +2 -2
- package/dist/{fetch-KLktuWuM.mjs → fetch-ycs0raYN.mjs} +2 -2
- package/dist/{index-matrPV4m.d.cts → index-BXfi8DqC.d.cts} +1 -1
- package/dist/{index-bwAhA9ca.d.mts → index-DvIxKA8K.d.mts} +2 -2
- package/dist/index.cjs +4 -4
- package/dist/index.d.cts +3 -4
- package/dist/index.d.mts +3 -4
- package/dist/index.mjs +4 -4
- package/dist/{normalize-BLTyqFww.d.mts → normalize-BCE_FLe8.d.mts} +1 -1
- package/dist/{normalize-BW7kk8Lk.d.cts → normalize-Tt7I_RdD.d.cts} +1 -1
- package/dist/package-C2Mp8qeD.cjs +155 -0
- package/dist/package-uEsV9Z-2.mjs +150 -0
- package/dist/plugins-Cmsm3gW1.cjs +791 -0
- package/dist/plugins-hpi2GlaX.mjs +790 -0
- package/dist/runtime/index.cjs +2 -2
- package/dist/runtime/index.d.cts +3 -4
- package/dist/runtime/index.d.mts +3 -4
- package/dist/runtime/index.mjs +2 -2
- package/dist/runtime/services/normalize.d.cts +1 -1
- package/dist/runtime/services/normalize.d.mts +1 -1
- package/dist/{runtime-Daw9Tlz6.mjs → runtime-BUQ0hy1J.mjs} +3 -3
- package/dist/{runtime-CWCl3EIz.cjs → runtime-LlP2xpdB.cjs} +3 -3
- package/dist/{standard-eUgUkWaf.cjs → standard-0wBehDUp.cjs} +1 -18
- package/dist/{standard-DaxKTFui.mjs → standard-CYaRay89.mjs} +2 -13
- package/dist/testing/index.cjs +2 -2
- package/dist/testing/index.d.cts +4 -5
- package/dist/testing/index.d.mts +4 -5
- package/dist/testing/index.mjs +2 -2
- package/dist/zod-BDDjyyHQ.mjs +10 -0
- package/dist/{zod-DYghWCz1.cjs → zod-CJY4vNLR.cjs} +2 -2
- package/dist/zod.cjs +4 -4
- package/dist/zod.d.cts +1 -2
- package/dist/zod.d.mts +1 -2
- package/dist/zod.mjs +2 -2
- package/package.json +3 -2
- package/dist/errors-Car4tFVP.d.mts +0 -75
- package/dist/errors-DKPPPYYT.d.cts +0 -75
- package/dist/openapi.DrTcell5-C6kyDyUK.mjs +0 -669
- package/dist/openapi.DrTcell5-DDf4D5V3.cjs +0 -687
- package/dist/package-BwFfsvZZ.mjs +0 -149
- package/dist/package-CSi-6ikY.cjs +0 -154
- package/dist/plugins-C-7lh5gK.cjs +0 -128
- package/dist/plugins-Ps5Xxpk2.mjs +0 -128
- package/dist/zod-A7Pti5IV.d.cts +0 -4
- package/dist/zod-BVo51kgJ.mjs +0 -10
- package/dist/zod-D4CFw8d9.d.mts +0 -4
- package/dist/zod4-BXTBR1od.cjs +0 -318
- package/dist/zod4-VpXuwRO7.mjs +0 -317
|
@@ -0,0 +1,790 @@
|
|
|
1
|
+
import { _ as value, a as toHttpPath, c as fallbackORPCErrorStatus, d as findDeepMatches, f as isObject, h as toArray, i as standardizeHTTPPath, l as isORPCErrorStatus, m as stringifyJSON, p as once, r as getDynamicParams, s as fallbackORPCErrorMessage, t as StandardOpenAPIJsonSerializer, u as clone } from "./standard-CYaRay89.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
|
+
//#region ../../node_modules/.bun/@orpc+openapi@1.10.4/node_modules/@orpc/openapi/dist/plugins/index.mjs
|
|
669
|
+
var OpenAPIReferencePlugin = class {
|
|
670
|
+
generator;
|
|
671
|
+
specGenerateOptions;
|
|
672
|
+
specPath;
|
|
673
|
+
docsPath;
|
|
674
|
+
docsTitle;
|
|
675
|
+
docsHead;
|
|
676
|
+
docsProvider;
|
|
677
|
+
docsScriptUrl;
|
|
678
|
+
docsCssUrl;
|
|
679
|
+
docsConfig;
|
|
680
|
+
renderDocsHtml;
|
|
681
|
+
constructor(options = {}) {
|
|
682
|
+
this.specGenerateOptions = options.specGenerateOptions;
|
|
683
|
+
this.docsPath = options.docsPath ?? "/";
|
|
684
|
+
this.docsTitle = options.docsTitle ?? "API Reference";
|
|
685
|
+
this.docsConfig = options.docsConfig ?? void 0;
|
|
686
|
+
this.docsProvider = options.docsProvider ?? "scalar";
|
|
687
|
+
this.docsScriptUrl = options.docsScriptUrl ?? (this.docsProvider === "swagger" ? "https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js" : "https://cdn.jsdelivr.net/npm/@scalar/api-reference");
|
|
688
|
+
this.docsCssUrl = options.docsCssUrl ?? (this.docsProvider === "swagger" ? "https://unpkg.com/swagger-ui-dist/swagger-ui.css" : void 0);
|
|
689
|
+
this.docsHead = options.docsHead ?? "";
|
|
690
|
+
this.specPath = options.specPath ?? "/spec.json";
|
|
691
|
+
this.generator = new OpenAPIGenerator(options);
|
|
692
|
+
const esc = (s) => s.replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
693
|
+
this.renderDocsHtml = options.renderDocsHtml ?? ((specUrl, title, head, scriptUrl, config, spec, docsProvider, cssUrl) => {
|
|
694
|
+
let body;
|
|
695
|
+
if (docsProvider === "swagger") {
|
|
696
|
+
const swaggerConfig = {
|
|
697
|
+
dom_id: "#app",
|
|
698
|
+
spec,
|
|
699
|
+
deepLinking: true,
|
|
700
|
+
presets: ["SwaggerUIBundle.presets.apis", "SwaggerUIBundle.presets.standalone"],
|
|
701
|
+
plugins: ["SwaggerUIBundle.plugins.DownloadUrl"],
|
|
702
|
+
...config
|
|
703
|
+
};
|
|
704
|
+
body = `
|
|
705
|
+
<body>
|
|
706
|
+
<div id="app"></div>
|
|
707
|
+
|
|
708
|
+
<script src="${esc(scriptUrl)}"><\/script>
|
|
709
|
+
|
|
710
|
+
<script>
|
|
711
|
+
window.onload = () => {
|
|
712
|
+
window.ui = SwaggerUIBundle(${stringifyJSON(swaggerConfig).replace(/"(SwaggerUIBundle\.[^"]+)"/g, "$1")})
|
|
713
|
+
}
|
|
714
|
+
<\/script>
|
|
715
|
+
</body>
|
|
716
|
+
`;
|
|
717
|
+
} else body = `
|
|
718
|
+
<body>
|
|
719
|
+
<div id="app" data-config="${esc(stringifyJSON({
|
|
720
|
+
content: stringifyJSON(spec),
|
|
721
|
+
...config
|
|
722
|
+
}))}"></div>
|
|
723
|
+
|
|
724
|
+
<script src="${esc(scriptUrl)}"><\/script>
|
|
725
|
+
|
|
726
|
+
<script>
|
|
727
|
+
Scalar.createApiReference('#app', JSON.parse(document.getElementById('app').dataset.config))
|
|
728
|
+
<\/script>
|
|
729
|
+
</body>
|
|
730
|
+
`;
|
|
731
|
+
return `
|
|
732
|
+
<!doctype html>
|
|
733
|
+
<html>
|
|
734
|
+
<head>
|
|
735
|
+
<meta charset="utf-8" />
|
|
736
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
737
|
+
<title>${esc(title)}</title>
|
|
738
|
+
${cssUrl ? `<link rel="stylesheet" type="text/css" href="${esc(cssUrl)}" />` : ""}
|
|
739
|
+
${head}
|
|
740
|
+
</head>
|
|
741
|
+
${body}
|
|
742
|
+
</html>
|
|
743
|
+
`;
|
|
744
|
+
});
|
|
745
|
+
}
|
|
746
|
+
init(options, router) {
|
|
747
|
+
options.interceptors ??= [];
|
|
748
|
+
options.interceptors.push(async (options2) => {
|
|
749
|
+
const res = await options2.next();
|
|
750
|
+
if (res.matched || options2.request.method !== "GET") return res;
|
|
751
|
+
const prefix = options2.prefix ?? "";
|
|
752
|
+
const requestPathname = options2.request.url.pathname.replace(/\/$/, "") || "/";
|
|
753
|
+
const docsUrl = new URL(`${prefix}${this.docsPath}`.replace(/\/$/, ""), options2.request.url.origin);
|
|
754
|
+
const specUrl = new URL(`${prefix}${this.specPath}`.replace(/\/$/, ""), options2.request.url.origin);
|
|
755
|
+
const generateSpec = once(async () => {
|
|
756
|
+
return await this.generator.generate(router, {
|
|
757
|
+
servers: [{ url: new URL(prefix, options2.request.url.origin).toString() }],
|
|
758
|
+
...await value(this.specGenerateOptions, options2)
|
|
759
|
+
});
|
|
760
|
+
});
|
|
761
|
+
if (requestPathname === specUrl.pathname) {
|
|
762
|
+
const spec = await generateSpec();
|
|
763
|
+
return {
|
|
764
|
+
matched: true,
|
|
765
|
+
response: {
|
|
766
|
+
status: 200,
|
|
767
|
+
headers: {},
|
|
768
|
+
body: new File([stringifyJSON(spec)], "spec.json", { type: "application/json" })
|
|
769
|
+
}
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
if (requestPathname === docsUrl.pathname) {
|
|
773
|
+
const html = this.renderDocsHtml(specUrl.toString(), await value(this.docsTitle, options2), await value(this.docsHead, options2), await value(this.docsScriptUrl, options2), await value(this.docsConfig, options2), await generateSpec(), this.docsProvider, await value(this.docsCssUrl, options2));
|
|
774
|
+
return {
|
|
775
|
+
matched: true,
|
|
776
|
+
response: {
|
|
777
|
+
status: 200,
|
|
778
|
+
headers: {},
|
|
779
|
+
body: new File([html], "api-reference.html", { type: "text/html" })
|
|
780
|
+
}
|
|
781
|
+
};
|
|
782
|
+
}
|
|
783
|
+
return res;
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
};
|
|
787
|
+
|
|
788
|
+
//#endregion
|
|
789
|
+
export { OpenAPIReferencePlugin };
|
|
790
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy1ocGkyR2xhWC5tanMiLCJuYW1lcyI6WyJ2YWx1ZSIsIiNyZXNvbHZlQ29tbW9uU2NoZW1hcyIsIiNyZXF1ZXN0IiwiI3N1Y2Nlc3NSZXNwb25zZSIsIiNlcnJvclJlc3BvbnNlIl0sInNvdXJjZXMiOlsiLi4vLi4vLi4vbm9kZV9tb2R1bGVzLy5idW4vQG9ycGMraW50ZXJvcEAxLjEwLjQvbm9kZV9tb2R1bGVzL0BvcnBjL2ludGVyb3AvZGlzdC9qc29uLXNjaGVtYS10eXBlZC9pbmRleC5tanMiLCIuLi8uLi8uLi9ub2RlX21vZHVsZXMvLmJ1bi9Ab3JwYytvcGVuYXBpQDEuMTAuNC9ub2RlX21vZHVsZXMvQG9ycGMvb3BlbmFwaS9kaXN0L3NoYXJlZC9vcGVuYXBpLkRyVGNlbGw1Lm1qcyIsIi4uLy4uLy4uL25vZGVfbW9kdWxlcy8uYnVuL0BvcnBjK29wZW5hcGlAMS4xMC40L25vZGVfbW9kdWxlcy9Ab3JwYy9vcGVuYXBpL2Rpc3QvcGx1Z2lucy9pbmRleC5tanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8vIDxyZWZlcmVuY2UgdHlwZXM9XCIuL2RyYWZ0LTIwMjAtMTIudHNcIiAvPlxuLy8gQGdlbmVyYXRlZFxuLy8gZGVuby1mbXQtaWdub3JlLWZpbGVcbi8vIGRlbm8tbGludC1pZ25vcmUtZmlsZVxuLy8gVGhpcyBjb2RlIHdhcyBidW5kbGVkIHVzaW5nIGBkZW5vIGJ1bmRsZWAgYW5kIGl0J3Mgbm90IHJlY29tbWVuZGVkIHRvIGVkaXQgaXQgbWFudWFsbHlcblxuY29uc3QgZHJhZnQgPSBcIjIwMjAtMTJcIjtcbmNvbnN0ICRzY2hlbWEgPSBcImh0dHBzOi8vanNvbi1zY2hlbWEub3JnL2RyYWZ0LzIwMjAtMTIvc2NoZW1hXCI7XG52YXIgQ29udGVudEVuY29kaW5nO1xuKGZ1bmN0aW9uKENvbnRlbnRFbmNvZGluZzEpIHtcbiAgICBDb250ZW50RW5jb2RpbmcxW1wiN2JpdFwiXSA9IFwiN2JpdFwiO1xuICAgIENvbnRlbnRFbmNvZGluZzFbXCI4Yml0XCJdID0gXCI4Yml0XCI7XG4gICAgQ29udGVudEVuY29kaW5nMVtcIkJhc2U2NFwiXSA9IFwiYmFzZTY0XCI7XG4gICAgQ29udGVudEVuY29kaW5nMVtcIkJpbmFyeVwiXSA9IFwiYmluYXJ5XCI7XG4gICAgQ29udGVudEVuY29kaW5nMVtcIklFVEZUb2tlblwiXSA9IFwiaWV0Zi10b2tlblwiO1xuICAgIENvbnRlbnRFbmNvZGluZzFbXCJRdW90ZWRQcmludGFibGVcIl0gPSBcInF1b3RlZC1wcmludGFibGVcIjtcbiAgICBDb250ZW50RW5jb2RpbmcxW1wiWFRva2VuXCJdID0gXCJ4LXRva2VuXCI7XG59KShDb250ZW50RW5jb2RpbmcgfHwgKENvbnRlbnRFbmNvZGluZyA9IHt9KSk7XG52YXIgRm9ybWF0O1xuKGZ1bmN0aW9uKEZvcm1hdDEpIHtcbiAgICBGb3JtYXQxW1wiRGF0ZVwiXSA9IFwiZGF0ZVwiO1xuICAgIEZvcm1hdDFbXCJEYXRlVGltZVwiXSA9IFwiZGF0ZS10aW1lXCI7XG4gICAgRm9ybWF0MVtcIkR1cmF0aW9uXCJdID0gXCJkdXJhdGlvblwiO1xuICAgIEZvcm1hdDFbXCJFbWFpbFwiXSA9IFwiZW1haWxcIjtcbiAgICBGb3JtYXQxW1wiSG9zdG5hbWVcIl0gPSBcImhvc3RuYW1lXCI7XG4gICAgRm9ybWF0MVtcIklETkVtYWlsXCJdID0gXCJpZG4tZW1haWxcIjtcbiAgICBGb3JtYXQxW1wiSUROSG9zdG5hbWVcIl0gPSBcImlkbi1ob3N0bmFtZVwiO1xuICAgIEZvcm1hdDFbXCJJUHY0XCJdID0gXCJpcHY0XCI7XG4gICAgRm9ybWF0MVtcIklQdjZcIl0gPSBcImlwdjZcIjtcbiAgICBGb3JtYXQxW1wiSVJJXCJdID0gXCJpcmlcIjtcbiAgICBGb3JtYXQxW1wiSVJJUmVmZXJlbmNlXCJdID0gXCJpcmktcmVmZXJlbmNlXCI7XG4gICAgRm9ybWF0MVtcIkpTT05Qb2ludGVyXCJdID0gXCJqc29uLXBvaW50ZXJcIjtcbiAgICBGb3JtYXQxW1wiSlNPTlBvaW50ZXJVUklGcmFnbWVudFwiXSA9IFwianNvbi1wb2ludGVyLXVyaS1mcmFnbWVudFwiO1xuICAgIEZvcm1hdDFbXCJSZWdFeFwiXSA9IFwicmVnZXhcIjtcbiAgICBGb3JtYXQxW1wiUmVsYXRpdmVKU09OUG9pbnRlclwiXSA9IFwicmVsYXRpdmUtanNvbi1wb2ludGVyXCI7XG4gICAgRm9ybWF0MVtcIlRpbWVcIl0gPSBcInRpbWVcIjtcbiAgICBGb3JtYXQxW1wiVVJJXCJdID0gXCJ1cmlcIjtcbiAgICBGb3JtYXQxW1wiVVJJUmVmZXJlbmNlXCJdID0gXCJ1cmktcmVmZXJlbmNlXCI7XG4gICAgRm9ybWF0MVtcIlVSSVRlbXBsYXRlXCJdID0gXCJ1cmktdGVtcGxhdGVcIjtcbiAgICBGb3JtYXQxW1wiVVVJRFwiXSA9IFwidXVpZFwiO1xufSkoRm9ybWF0IHx8IChGb3JtYXQgPSB7fSkpO1xudmFyIFR5cGVOYW1lO1xuKGZ1bmN0aW9uKFR5cGVOYW1lMSkge1xuICAgIFR5cGVOYW1lMVtcIkFycmF5XCJdID0gXCJhcnJheVwiO1xuICAgIFR5cGVOYW1lMVtcIkJvb2xlYW5cIl0gPSBcImJvb2xlYW5cIjtcbiAgICBUeXBlTmFtZTFbXCJJbnRlZ2VyXCJdID0gXCJpbnRlZ2VyXCI7XG4gICAgVHlwZU5hbWUxW1wiTnVsbFwiXSA9IFwibnVsbFwiO1xuICAgIFR5cGVOYW1lMVtcIk51bWJlclwiXSA9IFwibnVtYmVyXCI7XG4gICAgVHlwZU5hbWUxW1wiT2JqZWN0XCJdID0gXCJvYmplY3RcIjtcbiAgICBUeXBlTmFtZTFbXCJTdHJpbmdcIl0gPSBcInN0cmluZ1wiO1xufSkoVHlwZU5hbWUgfHwgKFR5cGVOYW1lID0ge30pKTtcbmNvbnN0IGtleXdvcmRzID0gW1xuICAgIFwiJGFuY2hvclwiLFxuICAgIFwiJGNvbW1lbnRcIixcbiAgICBcIiRkZWZzXCIsXG4gICAgXCIkZHluYW1pY0FuY2hvclwiLFxuICAgIFwiJGR5bmFtaWNSZWZcIixcbiAgICBcIiRpZFwiLFxuICAgIFwiJHJlZlwiLFxuICAgIFwiJHNjaGVtYVwiLFxuICAgIFwiJHZvY2FidWxhcnlcIixcbiAgICBcImFkZGl0aW9uYWxJdGVtc1wiLFxuICAgIFwiYWRkaXRpb25hbFByb3BlcnRpZXNcIixcbiAgICBcImFsbE9mXCIsXG4gICAgXCJhbnlPZlwiLFxuICAgIFwiY29uc3RcIixcbiAgICBcImNvbnRhaW5zXCIsXG4gICAgXCJjb250ZW50RW5jb2RpbmdcIixcbiAgICBcImNvbnRlbnRNZWRpYVR5cGVcIixcbiAgICBcImNvbnRlbnRTY2hlbWFcIixcbiAgICBcImRlZmF1bHRcIixcbiAgICBcImRlZmluaXRpb25zXCIsXG4gICAgXCJkZXBlbmRlbmNpZXNcIixcbiAgICBcImRlcGVuZGVudFJlcXVpcmVkXCIsXG4gICAgXCJkZXBlbmRlbnRTY2hlbWFzXCIsXG4gICAgXCJkZXByZWNhdGVkXCIsXG4gICAgXCJkZXNjcmlwdGlvblwiLFxuICAgIFwiZWxzZVwiLFxuICAgIFwiZW51bVwiLFxuICAgIFwiZXhhbXBsZXNcIixcbiAgICBcImV4Y2x1c2l2ZU1heGltdW1cIixcbiAgICBcImV4Y2x1c2l2ZU1pbmltdW1cIixcbiAgICBcImZvcm1hdFwiLFxuICAgIFwiaWZcIixcbiAgICBcIml0ZW1zXCIsXG4gICAgXCJtYXhDb250YWluc1wiLFxuICAgIFwibWF4aW11bVwiLFxuICAgIFwibWF4SXRlbXNcIixcbiAgICBcIm1heExlbmd0aFwiLFxuICAgIFwibWF4UHJvcGVydGllc1wiLFxuICAgIFwibWluQ29udGFpbnNcIixcbiAgICBcIm1pbmltdW1cIixcbiAgICBcIm1pbkl0ZW1zXCIsXG4gICAgXCJtaW5MZW5ndGhcIixcbiAgICBcIm1pblByb3BlcnRpZXNcIixcbiAgICBcIm11bHRpcGxlT2ZcIixcbiAgICBcIm5vdFwiLFxuICAgIFwib25lT2ZcIixcbiAgICBcInBhdHRlcm5cIixcbiAgICBcInBhdHRlcm5Qcm9wZXJ0aWVzXCIsXG4gICAgXCJwcmVmaXhJdGVtc1wiLFxuICAgIFwicHJvcGVydGllc1wiLFxuICAgIFwicHJvcGVydHlOYW1lc1wiLFxuICAgIFwicmVhZE9ubHlcIixcbiAgICBcInJlcXVpcmVkXCIsXG4gICAgXCJ0aGVuXCIsXG4gICAgXCJ0aXRsZVwiLFxuICAgIFwidHlwZVwiLFxuICAgIFwidW5ldmFsdWF0ZWRJdGVtc1wiLFxuICAgIFwidW5ldmFsdWF0ZWRQcm9wZXJ0aWVzXCIsXG4gICAgXCJ1bmlxdWVJdGVtc1wiLFxuICAgIFwid3JpdGVPbmx5XCIsIFxuXTtcblxuZXhwb3J0IHsgJHNjaGVtYSwgQ29udGVudEVuY29kaW5nLCBGb3JtYXQsIFR5cGVOYW1lLCBkcmFmdCwga2V5d29yZHMgfTtcbiIsImltcG9ydCB7IGlzT1JQQ0Vycm9yU3RhdHVzLCBmYWxsYmFja09SUENFcnJvclN0YXR1cywgZmFsbGJhY2tPUlBDRXJyb3JNZXNzYWdlIH0gZnJvbSAnQG9ycGMvY2xpZW50JztcbmltcG9ydCB7IHRvSHR0cFBhdGggfSBmcm9tICdAb3JwYy9jbGllbnQvc3RhbmRhcmQnO1xuaW1wb3J0IHsgZmFsbGJhY2tDb250cmFjdENvbmZpZywgZ2V0RXZlbnRJdGVyYXRvclNjaGVtYURldGFpbHMgfSBmcm9tICdAb3JwYy9jb250cmFjdCc7XG5pbXBvcnQgeyBzdGFuZGFyZGl6ZUhUVFBQYXRoLCBTdGFuZGFyZE9wZW5BUElKc29uU2VyaWFsaXplciwgZ2V0RHluYW1pY1BhcmFtcyB9IGZyb20gJ0BvcnBjL29wZW5hcGktY2xpZW50L3N0YW5kYXJkJztcbmltcG9ydCB7IGlzUHJvY2VkdXJlLCByZXNvbHZlQ29udHJhY3RQcm9jZWR1cmVzIH0gZnJvbSAnQG9ycGMvc2VydmVyJztcbmltcG9ydCB7IGlzT2JqZWN0LCBzdHJpbmdpZnlKU09OLCBmaW5kRGVlcE1hdGNoZXMsIHRvQXJyYXksIGNsb25lLCB2YWx1ZSB9IGZyb20gJ0BvcnBjL3NoYXJlZCc7XG5pbXBvcnQgeyBUeXBlTmFtZSB9IGZyb20gJ0BvcnBjL2ludGVyb3AvanNvbi1zY2hlbWEtdHlwZWQvZHJhZnQtMjAyMC0xMic7XG5cbmNvbnN0IE9QRVJBVElPTl9FWFRFTkRFUl9TWU1CT0wgPSBTeW1ib2woXCJPUlBDX09QRVJBVElPTl9FWFRFTkRFUlwiKTtcbmZ1bmN0aW9uIGN1c3RvbU9wZW5BUElPcGVyYXRpb24obywgZXh0ZW5kKSB7XG4gIHJldHVybiBuZXcgUHJveHkobywge1xuICAgIGdldCh0YXJnZXQsIHByb3AsIHJlY2VpdmVyKSB7XG4gICAgICBpZiAocHJvcCA9PT0gT1BFUkFUSU9OX0VYVEVOREVSX1NZTUJPTCkge1xuICAgICAgICByZXR1cm4gZXh0ZW5kO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHRhcmdldCwgcHJvcCwgcmVjZWl2ZXIpO1xuICAgIH1cbiAgfSk7XG59XG5mdW5jdGlvbiBnZXRDdXN0b21PcGVuQVBJT3BlcmF0aW9uKG8pIHtcbiAgcmV0dXJuIG9bT1BFUkFUSU9OX0VYVEVOREVSX1NZTUJPTF07XG59XG5mdW5jdGlvbiBhcHBseUN1c3RvbU9wZW5BUElPcGVyYXRpb24ob3BlcmF0aW9uLCBjb250cmFjdCkge1xuICBjb25zdCBvcGVyYXRpb25DdXN0b21zID0gW107XG4gIGZvciAoY29uc3QgZXJyb3JJdGVtIG9mIE9iamVjdC52YWx1ZXMoY29udHJhY3RbXCJ+b3JwY1wiXS5lcnJvck1hcCkpIHtcbiAgICBjb25zdCBtYXliZUV4dGVuZGVyID0gZXJyb3JJdGVtID8gZ2V0Q3VzdG9tT3BlbkFQSU9wZXJhdGlvbihlcnJvckl0ZW0pIDogdm9pZCAwO1xuICAgIGlmIChtYXliZUV4dGVuZGVyKSB7XG4gICAgICBvcGVyYXRpb25DdXN0b21zLnB1c2gobWF5YmVFeHRlbmRlcik7XG4gICAgfVxuICB9XG4gIGlmIChpc1Byb2NlZHVyZShjb250cmFjdCkpIHtcbiAgICBmb3IgKGNvbnN0IG1pZGRsZXdhcmUgb2YgY29udHJhY3RbXCJ+b3JwY1wiXS5taWRkbGV3YXJlcykge1xuICAgICAgY29uc3QgbWF5YmVFeHRlbmRlciA9IGdldEN1c3RvbU9wZW5BUElPcGVyYXRpb24obWlkZGxld2FyZSk7XG4gICAgICBpZiAobWF5YmVFeHRlbmRlcikge1xuICAgICAgICBvcGVyYXRpb25DdXN0b21zLnB1c2gobWF5YmVFeHRlbmRlcik7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGxldCBjdXJyZW50T3BlcmF0aW9uID0gb3BlcmF0aW9uO1xuICBmb3IgKGNvbnN0IGN1c3RvbSBvZiBvcGVyYXRpb25DdXN0b21zKSB7XG4gICAgaWYgKHR5cGVvZiBjdXN0b20gPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgY3VycmVudE9wZXJhdGlvbiA9IGN1c3RvbShjdXJyZW50T3BlcmF0aW9uLCBjb250cmFjdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGN1cnJlbnRPcGVyYXRpb24gPSB7XG4gICAgICAgIC4uLmN1cnJlbnRPcGVyYXRpb24sXG4gICAgICAgIC4uLmN1c3RvbVxuICAgICAgfTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGN1cnJlbnRPcGVyYXRpb247XG59XG5cbmNvbnN0IExPR0lDX0tFWVdPUkRTID0gW1xuICBcIiRkeW5hbWljUmVmXCIsXG4gIFwiJHJlZlwiLFxuICBcImFkZGl0aW9uYWxJdGVtc1wiLFxuICBcImFkZGl0aW9uYWxQcm9wZXJ0aWVzXCIsXG4gIFwiYWxsT2ZcIixcbiAgXCJhbnlPZlwiLFxuICBcImNvbnN0XCIsXG4gIFwiY29udGFpbnNcIixcbiAgXCJjb250ZW50RW5jb2RpbmdcIixcbiAgXCJjb250ZW50TWVkaWFUeXBlXCIsXG4gIFwiY29udGVudFNjaGVtYVwiLFxuICBcImRlcGVuZGVuY2llc1wiLFxuICBcImRlcGVuZGVudFJlcXVpcmVkXCIsXG4gIFwiZGVwZW5kZW50U2NoZW1hc1wiLFxuICBcImVsc2VcIixcbiAgXCJlbnVtXCIsXG4gIFwiZXhjbHVzaXZlTWF4aW11bVwiLFxuICBcImV4Y2x1c2l2ZU1pbmltdW1cIixcbiAgXCJmb3JtYXRcIixcbiAgXCJpZlwiLFxuICBcIml0ZW1zXCIsXG4gIFwibWF4Q29udGFpbnNcIixcbiAgXCJtYXhpbXVtXCIsXG4gIFwibWF4SXRlbXNcIixcbiAgXCJtYXhMZW5ndGhcIixcbiAgXCJtYXhQcm9wZXJ0aWVzXCIsXG4gIFwibWluQ29udGFpbnNcIixcbiAgXCJtaW5pbXVtXCIsXG4gIFwibWluSXRlbXNcIixcbiAgXCJtaW5MZW5ndGhcIixcbiAgXCJtaW5Qcm9wZXJ0aWVzXCIsXG4gIFwibXVsdGlwbGVPZlwiLFxuICBcIm5vdFwiLFxuICBcIm9uZU9mXCIsXG4gIFwicGF0dGVyblwiLFxuICBcInBhdHRlcm5Qcm9wZXJ0aWVzXCIsXG4gIFwicHJlZml4SXRlbXNcIixcbiAgXCJwcm9wZXJ0aWVzXCIsXG4gIFwicHJvcGVydHlOYW1lc1wiLFxuICBcInJlcXVpcmVkXCIsXG4gIFwidGhlblwiLFxuICBcInR5cGVcIixcbiAgXCJ1bmV2YWx1YXRlZEl0ZW1zXCIsXG4gIFwidW5ldmFsdWF0ZWRQcm9wZXJ0aWVzXCIsXG4gIFwidW5pcXVlSXRlbXNcIlxuXTtcblxuZnVuY3Rpb24gaXNGaWxlU2NoZW1hKHNjaGVtYSkge1xuICByZXR1cm4gaXNPYmplY3Qoc2NoZW1hKSAmJiBzY2hlbWEudHlwZSA9PT0gXCJzdHJpbmdcIiAmJiB0eXBlb2Ygc2NoZW1hLmNvbnRlbnRNZWRpYVR5cGUgPT09IFwic3RyaW5nXCI7XG59XG5mdW5jdGlvbiBpc09iamVjdFNjaGVtYShzY2hlbWEpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHNjaGVtYSkgJiYgc2NoZW1hLnR5cGUgPT09IFwib2JqZWN0XCI7XG59XG5mdW5jdGlvbiBpc0FueVNjaGVtYShzY2hlbWEpIHtcbiAgaWYgKHNjaGVtYSA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmIChPYmplY3Qua2V5cyhzY2hlbWEpLmV2ZXJ5KChrKSA9PiAhTE9HSUNfS0VZV09SRFMuaW5jbHVkZXMoaykpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuZnVuY3Rpb24gc2VwYXJhdGVPYmplY3RTY2hlbWEoc2NoZW1hLCBzZXBhcmF0ZWRQcm9wZXJ0aWVzKSB7XG4gIGlmIChPYmplY3Qua2V5cyhzY2hlbWEpLnNvbWUoXG4gICAgKGspID0+ICFbXCJ0eXBlXCIsIFwicHJvcGVydGllc1wiLCBcInJlcXVpcmVkXCIsIFwiYWRkaXRpb25hbFByb3BlcnRpZXNcIl0uaW5jbHVkZXMoaykgJiYgTE9HSUNfS0VZV09SRFMuaW5jbHVkZXMoaykgJiYgc2NoZW1hW2tdICE9PSB2b2lkIDBcbiAgKSkge1xuICAgIHJldHVybiBbeyB0eXBlOiBcIm9iamVjdFwiIH0sIHNjaGVtYV07XG4gIH1cbiAgY29uc3QgbWF0Y2hlZCA9IHsgLi4uc2NoZW1hIH07XG4gIGNvbnN0IHJlc3QgPSB7IC4uLnNjaGVtYSB9O1xuICBtYXRjaGVkLnByb3BlcnRpZXMgPSBzZXBhcmF0ZWRQcm9wZXJ0aWVzLnJlZHVjZSgoYWNjLCBrZXkpID0+IHtcbiAgICBjb25zdCBrZXlTY2hlbWEgPSBzY2hlbWEucHJvcGVydGllcz8uW2tleV0gPz8gc2NoZW1hLmFkZGl0aW9uYWxQcm9wZXJ0aWVzO1xuICAgIGlmIChrZXlTY2hlbWEgIT09IHZvaWQgMCkge1xuICAgICAgYWNjW2tleV0gPSBrZXlTY2hlbWE7XG4gICAgfVxuICAgIHJldHVybiBhY2M7XG4gIH0sIHt9KTtcbiAgbWF0Y2hlZC5yZXF1aXJlZCA9IHNjaGVtYS5yZXF1aXJlZD8uZmlsdGVyKChrZXkpID0+IHNlcGFyYXRlZFByb3BlcnRpZXMuaW5jbHVkZXMoa2V5KSk7XG4gIG1hdGNoZWQuZXhhbXBsZXMgPSBzY2hlbWEuZXhhbXBsZXM/Lm1hcCgoZXhhbXBsZSkgPT4ge1xuICAgIGlmICghaXNPYmplY3QoZXhhbXBsZSkpIHtcbiAgICAgIHJldHVybiBleGFtcGxlO1xuICAgIH1cbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMoZXhhbXBsZSkucmVkdWNlKChhY2MsIFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgaWYgKHNlcGFyYXRlZFByb3BlcnRpZXMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgICBhY2Nba2V5XSA9IHZhbHVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjYztcbiAgICB9LCB7fSk7XG4gIH0pO1xuICByZXN0LnByb3BlcnRpZXMgPSBzY2hlbWEucHJvcGVydGllcyAmJiBPYmplY3QuZW50cmllcyhzY2hlbWEucHJvcGVydGllcykuZmlsdGVyKChba2V5XSkgPT4gIXNlcGFyYXRlZFByb3BlcnRpZXMuaW5jbHVkZXMoa2V5KSkucmVkdWNlKChhY2MsIFtrZXksIHZhbHVlXSkgPT4ge1xuICAgIGFjY1trZXldID0gdmFsdWU7XG4gICAgcmV0dXJuIGFjYztcbiAgfSwge30pO1xuICByZXN0LnJlcXVpcmVkID0gc2NoZW1hLnJlcXVpcmVkPy5maWx0ZXIoKGtleSkgPT4gIXNlcGFyYXRlZFByb3BlcnRpZXMuaW5jbHVkZXMoa2V5KSk7XG4gIHJlc3QuZXhhbXBsZXMgPSBzY2hlbWEuZXhhbXBsZXM/Lm1hcCgoZXhhbXBsZSkgPT4ge1xuICAgIGlmICghaXNPYmplY3QoZXhhbXBsZSkpIHtcbiAgICAgIHJldHVybiBleGFtcGxlO1xuICAgIH1cbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMoZXhhbXBsZSkucmVkdWNlKChhY2MsIFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgaWYgKCFzZXBhcmF0ZWRQcm9wZXJ0aWVzLmluY2x1ZGVzKGtleSkpIHtcbiAgICAgICAgYWNjW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30pO1xuICB9KTtcbiAgcmV0dXJuIFttYXRjaGVkLCByZXN0XTtcbn1cbmZ1bmN0aW9uIGZpbHRlclNjaGVtYUJyYW5jaGVzKHNjaGVtYSwgY2hlY2ssIG1hdGNoZXMgPSBbXSkge1xuICBpZiAoY2hlY2soc2NoZW1hKSkge1xuICAgIG1hdGNoZXMucHVzaChzY2hlbWEpO1xuICAgIHJldHVybiBbbWF0Y2hlcywgdm9pZCAwXTtcbiAgfVxuICBpZiAoaXNPYmplY3Qoc2NoZW1hKSkge1xuICAgIGZvciAoY29uc3Qga2V5d29yZCBvZiBbXCJhbnlPZlwiLCBcIm9uZU9mXCJdKSB7XG4gICAgICBpZiAoc2NoZW1hW2tleXdvcmRdICYmIE9iamVjdC5rZXlzKHNjaGVtYSkuZXZlcnkoXG4gICAgICAgIChrKSA9PiBrID09PSBrZXl3b3JkIHx8ICFMT0dJQ19LRVlXT1JEUy5pbmNsdWRlcyhrKVxuICAgICAgKSkge1xuICAgICAgICBjb25zdCByZXN0ID0gc2NoZW1hW2tleXdvcmRdLm1hcCgocykgPT4gZmlsdGVyU2NoZW1hQnJhbmNoZXMocywgY2hlY2ssIG1hdGNoZXMpWzFdKS5maWx0ZXIoKHYpID0+ICEhdik7XG4gICAgICAgIGlmIChyZXN0Lmxlbmd0aCA9PT0gMSAmJiB0eXBlb2YgcmVzdFswXSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICAgIHJldHVybiBbbWF0Y2hlcywgeyAuLi5zY2hlbWEsIFtrZXl3b3JkXTogdm9pZCAwLCAuLi5yZXN0WzBdIH1dO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbbWF0Y2hlcywgeyAuLi5zY2hlbWEsIFtrZXl3b3JkXTogcmVzdCB9XTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIFttYXRjaGVzLCBzY2hlbWFdO1xufVxuZnVuY3Rpb24gYXBwbHlTY2hlbWFPcHRpb25hbGl0eShyZXF1aXJlZCwgc2NoZW1hKSB7XG4gIGlmIChyZXF1aXJlZCkge1xuICAgIHJldHVybiBzY2hlbWE7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBhbnlPZjogW1xuICAgICAgc2NoZW1hLFxuICAgICAgeyBub3Q6IHt9IH1cbiAgICBdXG4gIH07XG59XG5mdW5jdGlvbiBleHBhbmRVbmlvblNjaGVtYShzY2hlbWEpIHtcbiAgaWYgKHR5cGVvZiBzY2hlbWEgPT09IFwib2JqZWN0XCIpIHtcbiAgICBmb3IgKGNvbnN0IGtleXdvcmQgb2YgW1wiYW55T2ZcIiwgXCJvbmVPZlwiXSkge1xuICAgICAgaWYgKHNjaGVtYVtrZXl3b3JkXSAmJiBPYmplY3Qua2V5cyhzY2hlbWEpLmV2ZXJ5KFxuICAgICAgICAoaykgPT4gayA9PT0ga2V5d29yZCB8fCAhTE9HSUNfS0VZV09SRFMuaW5jbHVkZXMoaylcbiAgICAgICkpIHtcbiAgICAgICAgcmV0dXJuIHNjaGVtYVtrZXl3b3JkXS5mbGF0TWFwKChzKSA9PiBleHBhbmRVbmlvblNjaGVtYShzKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBbc2NoZW1hXTtcbn1cbmZ1bmN0aW9uIGV4cGFuZEFycmF5YWJsZVNjaGVtYShzY2hlbWEpIHtcbiAgY29uc3Qgc2NoZW1hcyA9IGV4cGFuZFVuaW9uU2NoZW1hKHNjaGVtYSk7XG4gIGlmIChzY2hlbWFzLmxlbmd0aCAhPT0gMikge1xuICAgIHJldHVybiB2b2lkIDA7XG4gIH1cbiAgY29uc3QgYXJyYXlTY2hlbWEgPSBzY2hlbWFzLmZpbmQoXG4gICAgKHMpID0+IHR5cGVvZiBzID09PSBcIm9iamVjdFwiICYmIHMudHlwZSA9PT0gXCJhcnJheVwiICYmIE9iamVjdC5rZXlzKHMpLmZpbHRlcigoaykgPT4gTE9HSUNfS0VZV09SRFMuaW5jbHVkZXMoaykpLmV2ZXJ5KChrKSA9PiBrID09PSBcInR5cGVcIiB8fCBrID09PSBcIml0ZW1zXCIpXG4gICk7XG4gIGlmIChhcnJheVNjaGVtYSA9PT0gdm9pZCAwKSB7XG4gICAgcmV0dXJuIHZvaWQgMDtcbiAgfVxuICBjb25zdCBpdGVtczEgPSBhcnJheVNjaGVtYS5pdGVtcztcbiAgY29uc3QgaXRlbXMyID0gc2NoZW1hcy5maW5kKChzKSA9PiBzICE9PSBhcnJheVNjaGVtYSk7XG4gIGlmIChzdHJpbmdpZnlKU09OKGl0ZW1zMSkgIT09IHN0cmluZ2lmeUpTT04oaXRlbXMyKSkge1xuICAgIHJldHVybiB2b2lkIDA7XG4gIH1cbiAgcmV0dXJuIFtpdGVtczIsIGFycmF5U2NoZW1hXTtcbn1cbmNvbnN0IFBSSU1JVElWRV9TQ0hFTUFfVFlQRVMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldChbXG4gIFR5cGVOYW1lLlN0cmluZyxcbiAgVHlwZU5hbWUuTnVtYmVyLFxuICBUeXBlTmFtZS5JbnRlZ2VyLFxuICBUeXBlTmFtZS5Cb29sZWFuLFxuICBUeXBlTmFtZS5OdWxsXG5dKTtcbmZ1bmN0aW9uIGlzUHJpbWl0aXZlU2NoZW1hKHNjaGVtYSkge1xuICByZXR1cm4gZXhwYW5kVW5pb25TY2hlbWEoc2NoZW1hKS5ldmVyeSgocykgPT4ge1xuICAgIGlmICh0eXBlb2YgcyA9PT0gXCJib29sZWFuXCIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBzLnR5cGUgPT09IFwic3RyaW5nXCIgJiYgUFJJTUlUSVZFX1NDSEVNQV9UWVBFUy5oYXMocy50eXBlKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChzLmNvbnN0ICE9PSB2b2lkIDApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiB0b09wZW5BUElQYXRoKHBhdGgpIHtcbiAgcmV0dXJuIHN0YW5kYXJkaXplSFRUUFBhdGgocGF0aCkucmVwbGFjZSgvXFwvXFx7XFwrKFtefV0rKVxcfS9nLCBcIi97JDF9XCIpO1xufVxuZnVuY3Rpb24gdG9PcGVuQVBJTWV0aG9kKG1ldGhvZCkge1xuICByZXR1cm4gbWV0aG9kLnRvTG9jYWxlTG93ZXJDYXNlKCk7XG59XG5mdW5jdGlvbiB0b09wZW5BUElDb250ZW50KHNjaGVtYSkge1xuICBjb25zdCBjb250ZW50ID0ge307XG4gIGNvbnN0IFttYXRjaGVzLCByZXN0U2NoZW1hXSA9IGZpbHRlclNjaGVtYUJyYW5jaGVzKHNjaGVtYSwgaXNGaWxlU2NoZW1hKTtcbiAgZm9yIChjb25zdCBmaWxlIG9mIG1hdGNoZXMpIHtcbiAgICBjb250ZW50W2ZpbGUuY29udGVudE1lZGlhVHlwZV0gPSB7XG4gICAgICBzY2hlbWE6IHRvT3BlbkFQSVNjaGVtYShmaWxlKVxuICAgIH07XG4gIH1cbiAgaWYgKHJlc3RTY2hlbWEgIT09IHZvaWQgMCkge1xuICAgIGNvbnRlbnRbXCJhcHBsaWNhdGlvbi9qc29uXCJdID0ge1xuICAgICAgc2NoZW1hOiB0b09wZW5BUElTY2hlbWEocmVzdFNjaGVtYSlcbiAgICB9O1xuICAgIGNvbnN0IGlzU3RpbGxIYXNGaWxlU2NoZW1hID0gZmluZERlZXBNYXRjaGVzKCh2KSA9PiBpc09iamVjdCh2KSAmJiBpc0ZpbGVTY2hlbWEodiksIHJlc3RTY2hlbWEpLnZhbHVlcy5sZW5ndGggPiAwO1xuICAgIGlmIChpc1N0aWxsSGFzRmlsZVNjaGVtYSkge1xuICAgICAgY29udGVudFtcIm11bHRpcGFydC9mb3JtLWRhdGFcIl0gPSB7XG4gICAgICAgIHNjaGVtYTogdG9PcGVuQVBJU2NoZW1hKHJlc3RTY2hlbWEpXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICByZXR1cm4gY29udGVudDtcbn1cbmZ1bmN0aW9uIHRvT3BlbkFQSUV2ZW50SXRlcmF0b3JDb250ZW50KFt5aWVsZHNSZXF1aXJlZCwgeWllbGRzU2NoZW1hXSwgW3JldHVybnNSZXF1aXJlZCwgcmV0dXJuc1NjaGVtYV0pIHtcbiAgcmV0dXJuIHtcbiAgICBcInRleHQvZXZlbnQtc3RyZWFtXCI6IHtcbiAgICAgIHNjaGVtYTogdG9PcGVuQVBJU2NoZW1hKHtcbiAgICAgICAgb25lT2Y6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICBldmVudDogeyBjb25zdDogXCJtZXNzYWdlXCIgfSxcbiAgICAgICAgICAgICAgZGF0YTogeWllbGRzU2NoZW1hLFxuICAgICAgICAgICAgICBpZDogeyB0eXBlOiBcInN0cmluZ1wiIH0sXG4gICAgICAgICAgICAgIHJldHJ5OiB7IHR5cGU6IFwibnVtYmVyXCIgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlcXVpcmVkOiB5aWVsZHNSZXF1aXJlZCA/IFtcImV2ZW50XCIsIFwiZGF0YVwiXSA6IFtcImV2ZW50XCJdXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICBldmVudDogeyBjb25zdDogXCJkb25lXCIgfSxcbiAgICAgICAgICAgICAgZGF0YTogcmV0dXJuc1NjaGVtYSxcbiAgICAgICAgICAgICAgaWQ6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgICAgICAgICByZXRyeTogeyB0eXBlOiBcIm51bWJlclwiIH1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICByZXF1aXJlZDogcmV0dXJuc1JlcXVpcmVkID8gW1wiZXZlbnRcIiwgXCJkYXRhXCJdIDogW1wiZXZlbnRcIl1cbiAgICAgICAgICB9LFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgIGV2ZW50OiB7IGNvbnN0OiBcImVycm9yXCIgfSxcbiAgICAgICAgICAgICAgZGF0YToge30sXG4gICAgICAgICAgICAgIGlkOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICAgICAgcmV0cnk6IHsgdHlwZTogXCJudW1iZXJcIiB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgcmVxdWlyZWQ6IFtcImV2ZW50XCJdXG4gICAgICAgICAgfVxuICAgICAgICBdXG4gICAgICB9KVxuICAgIH1cbiAgfTtcbn1cbmZ1bmN0aW9uIHRvT3BlbkFQSVBhcmFtZXRlcnMoc2NoZW1hLCBwYXJhbWV0ZXJJbikge1xuICBjb25zdCBwYXJhbWV0ZXJzID0gW107XG4gIGZvciAoY29uc3Qga2V5IGluIHNjaGVtYS5wcm9wZXJ0aWVzKSB7XG4gICAgY29uc3Qga2V5U2NoZW1hID0gc2NoZW1hLnByb3BlcnRpZXNba2V5XTtcbiAgICBsZXQgaXNEZWVwT2JqZWN0U3R5bGUgPSB0cnVlO1xuICAgIGlmIChwYXJhbWV0ZXJJbiAhPT0gXCJxdWVyeVwiKSB7XG4gICAgICBpc0RlZXBPYmplY3RTdHlsZSA9IGZhbHNlO1xuICAgIH0gZWxzZSBpZiAoaXNQcmltaXRpdmVTY2hlbWEoa2V5U2NoZW1hKSkge1xuICAgICAgaXNEZWVwT2JqZWN0U3R5bGUgPSBmYWxzZTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgW2l0ZW1dID0gZXhwYW5kQXJyYXlhYmxlU2NoZW1hKGtleVNjaGVtYSkgPz8gW107XG4gICAgICBpZiAoaXRlbSAhPT0gdm9pZCAwICYmIGlzUHJpbWl0aXZlU2NoZW1hKGl0ZW0pKSB7XG4gICAgICAgIGlzRGVlcE9iamVjdFN0eWxlID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIHBhcmFtZXRlcnMucHVzaCh7XG4gICAgICBuYW1lOiBrZXksXG4gICAgICBpbjogcGFyYW1ldGVySW4sXG4gICAgICByZXF1aXJlZDogc2NoZW1hLnJlcXVpcmVkPy5pbmNsdWRlcyhrZXkpLFxuICAgICAgc2NoZW1hOiB0b09wZW5BUElTY2hlbWEoa2V5U2NoZW1hKSxcbiAgICAgIHN0eWxlOiBpc0RlZXBPYmplY3RTdHlsZSA/IFwiZGVlcE9iamVjdFwiIDogdm9pZCAwLFxuICAgICAgZXhwbG9kZTogaXNEZWVwT2JqZWN0U3R5bGUgPyB0cnVlIDogdm9pZCAwLFxuICAgICAgYWxsb3dFbXB0eVZhbHVlOiBwYXJhbWV0ZXJJbiA9PT0gXCJxdWVyeVwiID8gdHJ1ZSA6IHZvaWQgMCxcbiAgICAgIGFsbG93UmVzZXJ2ZWQ6IHBhcmFtZXRlckluID09PSBcInF1ZXJ5XCIgPyB0cnVlIDogdm9pZCAwXG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIHBhcmFtZXRlcnM7XG59XG5mdW5jdGlvbiBjaGVja1BhcmFtc1NjaGVtYShzY2hlbWEsIHBhcmFtcykge1xuICBjb25zdCBwcm9wZXJ0aWVzID0gT2JqZWN0LmtleXMoc2NoZW1hLnByb3BlcnRpZXMgPz8ge30pO1xuICBjb25zdCByZXF1aXJlZCA9IHNjaGVtYS5yZXF1aXJlZCA/PyBbXTtcbiAgaWYgKHByb3BlcnRpZXMubGVuZ3RoICE9PSBwYXJhbXMubGVuZ3RoIHx8IHByb3BlcnRpZXMuc29tZSgodikgPT4gIXBhcmFtcy5pbmNsdWRlcyh2KSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKHJlcXVpcmVkLmxlbmd0aCAhPT0gcGFyYW1zLmxlbmd0aCB8fCByZXF1aXJlZC5zb21lKCh2KSA9PiAhcGFyYW1zLmluY2x1ZGVzKHYpKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbmZ1bmN0aW9uIHRvT3BlbkFQSVNjaGVtYShzY2hlbWEpIHtcbiAgcmV0dXJuIHNjaGVtYSA9PT0gdHJ1ZSA/IHt9IDogc2NoZW1hID09PSBmYWxzZSA/IHsgbm90OiB7fSB9IDogc2NoZW1hO1xufVxuY29uc3QgT1BFTkFQSV9KU09OX1NDSEVNQV9SRUZfUFJFRklYID0gXCIjL2NvbXBvbmVudHMvc2NoZW1hcy9cIjtcbmZ1bmN0aW9uIHJlc29sdmVPcGVuQVBJSnNvblNjaGVtYVJlZihkb2MsIHNjaGVtYSkge1xuICBpZiAodHlwZW9mIHNjaGVtYSAhPT0gXCJvYmplY3RcIiB8fCAhc2NoZW1hLiRyZWY/LnN0YXJ0c1dpdGgoT1BFTkFQSV9KU09OX1NDSEVNQV9SRUZfUFJFRklYKSkge1xuICAgIHJldHVybiBzY2hlbWE7XG4gIH1cbiAgY29uc3QgbmFtZSA9IHNjaGVtYS4kcmVmLnNsaWNlKE9QRU5BUElfSlNPTl9TQ0hFTUFfUkVGX1BSRUZJWC5sZW5ndGgpO1xuICBjb25zdCByZXNvbHZlZCA9IGRvYy5jb21wb25lbnRzPy5zY2hlbWFzPy5bbmFtZV07XG4gIHJldHVybiByZXNvbHZlZCA/PyBzY2hlbWE7XG59XG5cbmNsYXNzIENvbXBvc2l0ZVNjaGVtYUNvbnZlcnRlciB7XG4gIGNvbnZlcnRlcnM7XG4gIGNvbnN0cnVjdG9yKGNvbnZlcnRlcnMpIHtcbiAgICB0aGlzLmNvbnZlcnRlcnMgPSBjb252ZXJ0ZXJzO1xuICB9XG4gIGFzeW5jIGNvbnZlcnQoc2NoZW1hLCBvcHRpb25zKSB7XG4gICAgZm9yIChjb25zdCBjb252ZXJ0ZXIgb2YgdGhpcy5jb252ZXJ0ZXJzKSB7XG4gICAgICBpZiAoYXdhaXQgY29udmVydGVyLmNvbmRpdGlvbihzY2hlbWEsIG9wdGlvbnMpKSB7XG4gICAgICAgIHJldHVybiBjb252ZXJ0ZXIuY29udmVydChzY2hlbWEsIG9wdGlvbnMpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gW2ZhbHNlLCB7fV07XG4gIH1cbn1cblxuY2xhc3MgT3BlbkFQSUdlbmVyYXRvckVycm9yIGV4dGVuZHMgRXJyb3Ige1xufVxuY2xhc3MgT3BlbkFQSUdlbmVyYXRvciB7XG4gIHNlcmlhbGl6ZXI7XG4gIGNvbnZlcnRlcjtcbiAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgdGhpcy5zZXJpYWxpemVyID0gbmV3IFN0YW5kYXJkT3BlbkFQSUpzb25TZXJpYWxpemVyKG9wdGlvbnMpO1xuICAgIHRoaXMuY29udmVydGVyID0gbmV3IENvbXBvc2l0ZVNjaGVtYUNvbnZlcnRlcih0b0FycmF5KG9wdGlvbnMuc2NoZW1hQ29udmVydGVycykpO1xuICB9XG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgT3BlbkFQSSBzcGVjaWZpY2F0aW9ucyBmcm9tIG9SUEMgcm91dGVycy9jb250cmFjdHMuXG4gICAqXG4gICAqIEBzZWUge0BsaW5rIGh0dHBzOi8vb3JwYy51bm5vcS5jb20vZG9jcy9vcGVuYXBpL29wZW5hcGktc3BlY2lmaWNhdGlvbiBPcGVuQVBJIFNwZWNpZmljYXRpb24gRG9jc31cbiAgICovXG4gIGFzeW5jIGdlbmVyYXRlKHJvdXRlciwgeyBjdXN0b21FcnJvclJlc3BvbnNlQm9keVNjaGVtYSwgY29tbW9uU2NoZW1hcywgZmlsdGVyOiBiYXNlRmlsdGVyLCBleGNsdWRlLCAuLi5iYXNlRG9jIH0gPSB7fSkge1xuICAgIGNvbnN0IGZpbHRlciA9IGJhc2VGaWx0ZXIgPz8gKCh7IGNvbnRyYWN0LCBwYXRoIH0pID0+IHtcbiAgICAgIHJldHVybiAhKGV4Y2x1ZGU/Lihjb250cmFjdCwgcGF0aCkgPz8gZmFsc2UpO1xuICAgIH0pO1xuICAgIGNvbnN0IGRvYyA9IHtcbiAgICAgIC4uLmNsb25lKGJhc2VEb2MpLFxuICAgICAgaW5mbzogYmFzZURvYy5pbmZvID8/IHsgdGl0bGU6IFwiQVBJIFJlZmVyZW5jZVwiLCB2ZXJzaW9uOiBcIjAuMC4wXCIgfSxcbiAgICAgIG9wZW5hcGk6IFwiMy4xLjFcIlxuICAgIH07XG4gICAgY29uc3QgeyBiYXNlU2NoZW1hQ29udmVydE9wdGlvbnMsIHVuZGVmaW5lZEVycm9ySnNvblNjaGVtYSB9ID0gYXdhaXQgdGhpcy4jcmVzb2x2ZUNvbW1vblNjaGVtYXMoZG9jLCBjb21tb25TY2hlbWFzKTtcbiAgICBjb25zdCBjb250cmFjdHMgPSBbXTtcbiAgICBhd2FpdCByZXNvbHZlQ29udHJhY3RQcm9jZWR1cmVzKHsgcGF0aDogW10sIHJvdXRlciB9LCAodHJhdmVyc2VPcHRpb25zKSA9PiB7XG4gICAgICBpZiAoIXZhbHVlKGZpbHRlciwgdHJhdmVyc2VPcHRpb25zKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb250cmFjdHMucHVzaCh0cmF2ZXJzZU9wdGlvbnMpO1xuICAgIH0pO1xuICAgIGNvbnN0IGVycm9ycyA9IFtdO1xuICAgIGZvciAoY29uc3QgeyBjb250cmFjdCwgcGF0aCB9IG9mIGNvbnRyYWN0cykge1xuICAgICAgY29uc3Qgc3RyaW5nUGF0aCA9IHBhdGguam9pbihcIi5cIik7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBkZWYgPSBjb250cmFjdFtcIn5vcnBjXCJdO1xuICAgICAgICBjb25zdCBtZXRob2QgPSB0b09wZW5BUElNZXRob2QoZmFsbGJhY2tDb250cmFjdENvbmZpZyhcImRlZmF1bHRNZXRob2RcIiwgZGVmLnJvdXRlLm1ldGhvZCkpO1xuICAgICAgICBjb25zdCBodHRwUGF0aCA9IHRvT3BlbkFQSVBhdGgoZGVmLnJvdXRlLnBhdGggPz8gdG9IdHRwUGF0aChwYXRoKSk7XG4gICAgICAgIGxldCBvcGVyYXRpb25PYmplY3RSZWY7XG4gICAgICAgIGlmIChkZWYucm91dGUuc3BlYyAhPT0gdm9pZCAwICYmIHR5cGVvZiBkZWYucm91dGUuc3BlYyAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgb3BlcmF0aW9uT2JqZWN0UmVmID0gZGVmLnJvdXRlLnNwZWM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgb3BlcmF0aW9uT2JqZWN0UmVmID0ge1xuICAgICAgICAgICAgb3BlcmF0aW9uSWQ6IGRlZi5yb3V0ZS5vcGVyYXRpb25JZCA/PyBzdHJpbmdQYXRoLFxuICAgICAgICAgICAgc3VtbWFyeTogZGVmLnJvdXRlLnN1bW1hcnksXG4gICAgICAgICAgICBkZXNjcmlwdGlvbjogZGVmLnJvdXRlLmRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgZGVwcmVjYXRlZDogZGVmLnJvdXRlLmRlcHJlY2F0ZWQsXG4gICAgICAgICAgICB0YWdzOiBkZWYucm91dGUudGFncz8ubWFwKCh0YWcpID0+IHRhZylcbiAgICAgICAgICB9O1xuICAgICAgICAgIGF3YWl0IHRoaXMuI3JlcXVlc3QoZG9jLCBvcGVyYXRpb25PYmplY3RSZWYsIGRlZiwgYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zKTtcbiAgICAgICAgICBhd2FpdCB0aGlzLiNzdWNjZXNzUmVzcG9uc2UoZG9jLCBvcGVyYXRpb25PYmplY3RSZWYsIGRlZiwgYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zKTtcbiAgICAgICAgICBhd2FpdCB0aGlzLiNlcnJvclJlc3BvbnNlKG9wZXJhdGlvbk9iamVjdFJlZiwgZGVmLCBiYXNlU2NoZW1hQ29udmVydE9wdGlvbnMsIHVuZGVmaW5lZEVycm9ySnNvblNjaGVtYSwgY3VzdG9tRXJyb3JSZXNwb25zZUJvZHlTY2hlbWEpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0eXBlb2YgZGVmLnJvdXRlLnNwZWMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgIG9wZXJhdGlvbk9iamVjdFJlZiA9IGRlZi5yb3V0ZS5zcGVjKG9wZXJhdGlvbk9iamVjdFJlZik7XG4gICAgICAgIH1cbiAgICAgICAgZG9jLnBhdGhzID8/PSB7fTtcbiAgICAgICAgZG9jLnBhdGhzW2h0dHBQYXRoXSA/Pz0ge307XG4gICAgICAgIGRvYy5wYXRoc1todHRwUGF0aF1bbWV0aG9kXSA9IGFwcGx5Q3VzdG9tT3BlbkFQSU9wZXJhdGlvbihvcGVyYXRpb25PYmplY3RSZWYsIGNvbnRyYWN0KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKCEoZSBpbnN0YW5jZW9mIE9wZW5BUElHZW5lcmF0b3JFcnJvcikpIHtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICAgIGVycm9ycy5wdXNoKFxuICAgICAgICAgIGBbT3BlbkFQSUdlbmVyYXRvcl0gRXJyb3Igb2NjdXJyZWQgd2hpbGUgZ2VuZXJhdGluZyBPcGVuQVBJIGZvciBwcm9jZWR1cmUgYXQgcGF0aDogJHtzdHJpbmdQYXRofVxuJHtlLm1lc3NhZ2V9YFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoZXJyb3JzLmxlbmd0aCkge1xuICAgICAgdGhyb3cgbmV3IE9wZW5BUElHZW5lcmF0b3JFcnJvcihcbiAgICAgICAgYFNvbWUgZXJyb3Igb2NjdXJyZWQgZHVyaW5nIE9wZW5BUEkgZ2VuZXJhdGlvbjpcblxuJHtlcnJvcnMuam9pbihcIlxcblxcblwiKX1gXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zZXJpYWxpemVyLnNlcmlhbGl6ZShkb2MpWzBdO1xuICB9XG4gIGFzeW5jICNyZXNvbHZlQ29tbW9uU2NoZW1hcyhkb2MsIGNvbW1vblNjaGVtYXMpIHtcbiAgICBsZXQgdW5kZWZpbmVkRXJyb3JKc29uU2NoZW1hID0ge1xuICAgICAgdHlwZTogXCJvYmplY3RcIixcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgZGVmaW5lZDogeyBjb25zdDogZmFsc2UgfSxcbiAgICAgICAgY29kZTogeyB0eXBlOiBcInN0cmluZ1wiIH0sXG4gICAgICAgIHN0YXR1czogeyB0eXBlOiBcIm51bWJlclwiIH0sXG4gICAgICAgIG1lc3NhZ2U6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgICBkYXRhOiB7fVxuICAgICAgfSxcbiAgICAgIHJlcXVpcmVkOiBbXCJkZWZpbmVkXCIsIFwiY29kZVwiLCBcInN0YXR1c1wiLCBcIm1lc3NhZ2VcIl1cbiAgICB9O1xuICAgIGNvbnN0IGJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucyA9IHt9O1xuICAgIGlmIChjb21tb25TY2hlbWFzKSB7XG4gICAgICBiYXNlU2NoZW1hQ29udmVydE9wdGlvbnMuY29tcG9uZW50cyA9IFtdO1xuICAgICAgZm9yIChjb25zdCBrZXkgaW4gY29tbW9uU2NoZW1hcykge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gY29tbW9uU2NoZW1hc1trZXldO1xuICAgICAgICBpZiAob3B0aW9ucy5zY2hlbWEgPT09IHZvaWQgMCkge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgc2NoZW1hLCBzdHJhdGVneSA9IFwiaW5wdXRcIiB9ID0gb3B0aW9ucztcbiAgICAgICAgY29uc3QgW3JlcXVpcmVkLCBqc29uXSA9IGF3YWl0IHRoaXMuY29udmVydGVyLmNvbnZlcnQoc2NoZW1hLCB7IHN0cmF0ZWd5IH0pO1xuICAgICAgICBjb25zdCBhbGxvd2VkU3RyYXRlZ2llcyA9IFtzdHJhdGVneV07XG4gICAgICAgIGlmIChzdHJhdGVneSA9PT0gXCJpbnB1dFwiKSB7XG4gICAgICAgICAgY29uc3QgW291dHB1dFJlcXVpcmVkLCBvdXRwdXRKc29uXSA9IGF3YWl0IHRoaXMuY29udmVydGVyLmNvbnZlcnQoc2NoZW1hLCB7IHN0cmF0ZWd5OiBcIm91dHB1dFwiIH0pO1xuICAgICAgICAgIGlmIChvdXRwdXRSZXF1aXJlZCA9PT0gcmVxdWlyZWQgJiYgc3RyaW5naWZ5SlNPTihvdXRwdXRKc29uKSA9PT0gc3RyaW5naWZ5SlNPTihqc29uKSkge1xuICAgICAgICAgICAgYWxsb3dlZFN0cmF0ZWdpZXMucHVzaChcIm91dHB1dFwiKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoc3RyYXRlZ3kgPT09IFwib3V0cHV0XCIpIHtcbiAgICAgICAgICBjb25zdCBbaW5wdXRSZXF1aXJlZCwgaW5wdXRKc29uXSA9IGF3YWl0IHRoaXMuY29udmVydGVyLmNvbnZlcnQoc2NoZW1hLCB7IHN0cmF0ZWd5OiBcImlucHV0XCIgfSk7XG4gICAgICAgICAgaWYgKGlucHV0UmVxdWlyZWQgPT09IHJlcXVpcmVkICYmIHN0cmluZ2lmeUpTT04oaW5wdXRKc29uKSA9PT0gc3RyaW5naWZ5SlNPTihqc29uKSkge1xuICAgICAgICAgICAgYWxsb3dlZFN0cmF0ZWdpZXMucHVzaChcImlucHV0XCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBiYXNlU2NoZW1hQ29udmVydE9wdGlvbnMuY29tcG9uZW50cy5wdXNoKHtcbiAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgcmVxdWlyZWQsXG4gICAgICAgICAgcmVmOiBgIy9jb21wb25lbnRzL3NjaGVtYXMvJHtrZXl9YCxcbiAgICAgICAgICBhbGxvd2VkU3RyYXRlZ2llc1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGRvYy5jb21wb25lbnRzID8/PSB7fTtcbiAgICAgIGRvYy5jb21wb25lbnRzLnNjaGVtYXMgPz89IHt9O1xuICAgICAgZm9yIChjb25zdCBrZXkgaW4gY29tbW9uU2NoZW1hcykge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gY29tbW9uU2NoZW1hc1trZXldO1xuICAgICAgICBpZiAob3B0aW9ucy5zY2hlbWEgPT09IHZvaWQgMCkge1xuICAgICAgICAgIGlmIChvcHRpb25zLmVycm9yID09PSBcIlVuZGVmaW5lZEVycm9yXCIpIHtcbiAgICAgICAgICAgIGRvYy5jb21wb25lbnRzLnNjaGVtYXNba2V5XSA9IHRvT3BlbkFQSVNjaGVtYSh1bmRlZmluZWRFcnJvckpzb25TY2hlbWEpO1xuICAgICAgICAgICAgdW5kZWZpbmVkRXJyb3JKc29uU2NoZW1hID0geyAkcmVmOiBgIy9jb21wb25lbnRzL3NjaGVtYXMvJHtrZXl9YCB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IHNjaGVtYSwgc3RyYXRlZ3kgPSBcImlucHV0XCIgfSA9IG9wdGlvbnM7XG4gICAgICAgIGNvbnN0IFssIGpzb25dID0gYXdhaXQgdGhpcy5jb252ZXJ0ZXIuY29udmVydChcbiAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAge1xuICAgICAgICAgICAgLi4uYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zLFxuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBtaW5TdHJ1Y3R1cmVEZXB0aEZvclJlZjogMVxuICAgICAgICAgICAgLy8gbm90IGFsbG93IHVzZSAkcmVmIGZvciByb290IHNjaGVtYXNcbiAgICAgICAgICB9XG4gICAgICAgICk7XG4gICAgICAgIGRvYy5jb21wb25lbnRzLnNjaGVtYXNba2V5XSA9IHRvT3BlbkFQSVNjaGVtYShqc29uKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zLCB1bmRlZmluZWRFcnJvckpzb25TY2hlbWEgfTtcbiAgfVxuICBhc3luYyAjcmVxdWVzdChkb2MsIHJlZiwgZGVmLCBiYXNlU2NoZW1hQ29udmVydE9wdGlvbnMpIHtcbiAgICBjb25zdCBtZXRob2QgPSBmYWxsYmFja0NvbnRyYWN0Q29uZmlnKFwiZGVmYXVsdE1ldGhvZFwiLCBkZWYucm91dGUubWV0aG9kKTtcbiAgICBjb25zdCBkZXRhaWxzID0gZ2V0RXZlbnRJdGVyYXRvclNjaGVtYURldGFpbHMoZGVmLmlucHV0U2NoZW1hKTtcbiAgICBpZiAoZGV0YWlscykge1xuICAgICAgcmVmLnJlcXVlc3RCb2R5ID0ge1xuICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgY29udGVudDogdG9PcGVuQVBJRXZlbnRJdGVyYXRvckNvbnRlbnQoXG4gICAgICAgICAgYXdhaXQgdGhpcy5jb252ZXJ0ZXIuY29udmVydChkZXRhaWxzLnlpZWxkcywgeyAuLi5iYXNlU2NoZW1hQ29udmVydE9wdGlvbnMsIHN0cmF0ZWd5OiBcImlucHV0XCIgfSksXG4gICAgICAgICAgYXdhaXQgdGhpcy5jb252ZXJ0ZXIuY29udmVydChkZXRhaWxzLnJldHVybnMsIHsgLi4uYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zLCBzdHJhdGVneTogXCJpbnB1dFwiIH0pXG4gICAgICAgIClcbiAgICAgIH07XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGR5bmFtaWNQYXJhbXMgPSBnZXREeW5hbWljUGFyYW1zKGRlZi5yb3V0ZS5wYXRoKT8ubWFwKCh2KSA9PiB2Lm5hbWUpO1xuICAgIGNvbnN0IGlucHV0U3RydWN0dXJlID0gZmFsbGJhY2tDb250cmFjdENvbmZpZyhcImRlZmF1bHRJbnB1dFN0cnVjdHVyZVwiLCBkZWYucm91dGUuaW5wdXRTdHJ1Y3R1cmUpO1xuICAgIGxldCBbcmVxdWlyZWQsIHNjaGVtYV0gPSBhd2FpdCB0aGlzLmNvbnZlcnRlci5jb252ZXJ0KFxuICAgICAgZGVmLmlucHV0U2NoZW1hLFxuICAgICAge1xuICAgICAgICAuLi5iYXNlU2NoZW1hQ29udmVydE9wdGlvbnMsXG4gICAgICAgIHN0cmF0ZWd5OiBcImlucHV0XCIsXG4gICAgICAgIG1pblN0cnVjdHVyZURlcHRoRm9yUmVmOiBkeW5hbWljUGFyYW1zPy5sZW5ndGggfHwgaW5wdXRTdHJ1Y3R1cmUgPT09IFwiZGV0YWlsZWRcIiA/IDEgOiAwXG4gICAgICB9XG4gICAgKTtcbiAgICBpZiAoaXNBbnlTY2hlbWEoc2NoZW1hKSAmJiAhZHluYW1pY1BhcmFtcz8ubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChpbnB1dFN0cnVjdHVyZSA9PT0gXCJjb21wYWN0XCIpIHtcbiAgICAgIGlmIChkeW5hbWljUGFyYW1zPy5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgZXJyb3IyID0gbmV3IE9wZW5BUElHZW5lcmF0b3JFcnJvcihcbiAgICAgICAgICAnV2hlbiBpbnB1dCBzdHJ1Y3R1cmUgaXMgXCJjb21wYWN0XCIsIGFuZCBwYXRoIGhhcyBkeW5hbWljIHBhcmFtcywgaW5wdXQgc2NoZW1hIG11c3QgYmUgYW4gb2JqZWN0IHdpdGggYWxsIGR5bmFtaWMgcGFyYW1zIGFzIHJlcXVpcmVkLidcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCFpc09iamVjdFNjaGVtYShzY2hlbWEpKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3IyO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IFtwYXJhbXNTY2hlbWEsIHJlc3RdID0gc2VwYXJhdGVPYmplY3RTY2hlbWEoc2NoZW1hLCBkeW5hbWljUGFyYW1zKTtcbiAgICAgICAgc2NoZW1hID0gcmVzdDtcbiAgICAgICAgcmVxdWlyZWQgPSByZXN0LnJlcXVpcmVkID8gcmVzdC5yZXF1aXJlZC5sZW5ndGggIT09IDAgOiBmYWxzZTtcbiAgICAgICAgaWYgKCFjaGVja1BhcmFtc1NjaGVtYShwYXJhbXNTY2hlbWEsIGR5bmFtaWNQYXJhbXMpKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3IyO1xuICAgICAgICB9XG4gICAgICAgIHJlZi5wYXJhbWV0ZXJzID8/PSBbXTtcbiAgICAgICAgcmVmLnBhcmFtZXRlcnMucHVzaCguLi50b09wZW5BUElQYXJhbWV0ZXJzKHBhcmFtc1NjaGVtYSwgXCJwYXRoXCIpKTtcbiAgICAgIH1cbiAgICAgIGlmIChtZXRob2QgPT09IFwiR0VUXCIpIHtcbiAgICAgICAgY29uc3QgcmVzb2x2ZWRTY2hlbWEgPSByZXNvbHZlT3BlbkFQSUpzb25TY2hlbWFSZWYoZG9jLCBzY2hlbWEpO1xuICAgICAgICBpZiAoIWlzT2JqZWN0U2NoZW1hKHJlc29sdmVkU2NoZW1hKSkge1xuICAgICAgICAgIHRocm93IG5ldyBPcGVuQVBJR2VuZXJhdG9yRXJyb3IoXG4gICAgICAgICAgICAnV2hlbiBtZXRob2QgaXMgXCJHRVRcIiwgaW5wdXQgc2NoZW1hIG11c3Qgc2F0aXNmeTogb2JqZWN0IHwgYW55IHwgdW5rbm93bidcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHJlZi5wYXJhbWV0ZXJzID8/PSBbXTtcbiAgICAgICAgcmVmLnBhcmFtZXRlcnMucHVzaCguLi50b09wZW5BUElQYXJhbWV0ZXJzKHJlc29sdmVkU2NoZW1hLCBcInF1ZXJ5XCIpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlZi5yZXF1ZXN0Qm9keSA9IHtcbiAgICAgICAgICByZXF1aXJlZCxcbiAgICAgICAgICBjb250ZW50OiB0b09wZW5BUElDb250ZW50KHNjaGVtYSlcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZXJyb3IgPSBuZXcgT3BlbkFQSUdlbmVyYXRvckVycm9yKFxuICAgICAgJ1doZW4gaW5wdXQgc3RydWN0dXJlIGlzIFwiZGV0YWlsZWRcIiwgaW5wdXQgc2NoZW1hIG11c3Qgc2F0aXNmeTogeyBwYXJhbXM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgcXVlcnk/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgaGVhZGVycz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+LCBib2R5PzogdW5rbm93biB9J1xuICAgICk7XG4gICAgaWYgKCFpc09iamVjdFNjaGVtYShzY2hlbWEpKSB7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gICAgY29uc3QgcmVzb2x2ZWRQYXJhbVNjaGVtYSA9IHNjaGVtYS5wcm9wZXJ0aWVzPy5wYXJhbXMgIT09IHZvaWQgMCA/IHJlc29sdmVPcGVuQVBJSnNvblNjaGVtYVJlZihkb2MsIHNjaGVtYS5wcm9wZXJ0aWVzLnBhcmFtcykgOiB2b2lkIDA7XG4gICAgaWYgKGR5bmFtaWNQYXJhbXM/Lmxlbmd0aCAmJiAocmVzb2x2ZWRQYXJhbVNjaGVtYSA9PT0gdm9pZCAwIHx8ICFpc09iamVjdFNjaGVtYShyZXNvbHZlZFBhcmFtU2NoZW1hKSB8fCAhY2hlY2tQYXJhbXNTY2hlbWEocmVzb2x2ZWRQYXJhbVNjaGVtYSwgZHluYW1pY1BhcmFtcykpKSB7XG4gICAgICB0aHJvdyBuZXcgT3BlbkFQSUdlbmVyYXRvckVycm9yKFxuICAgICAgICAnV2hlbiBpbnB1dCBzdHJ1Y3R1cmUgaXMgXCJkZXRhaWxlZFwiIGFuZCBwYXRoIGhhcyBkeW5hbWljIHBhcmFtcywgdGhlIFwicGFyYW1zXCIgc2NoZW1hIG11c3QgYmUgYW4gb2JqZWN0IHdpdGggYWxsIGR5bmFtaWMgcGFyYW1zIGFzIHJlcXVpcmVkLidcbiAgICAgICk7XG4gICAgfVxuICAgIGZvciAoY29uc3QgZnJvbSBvZiBbXCJwYXJhbXNcIiwgXCJxdWVyeVwiLCBcImhlYWRlcnNcIl0pIHtcbiAgICAgIGNvbnN0IGZyb21TY2hlbWEgPSBzY2hlbWEucHJvcGVydGllcz8uW2Zyb21dO1xuICAgICAgaWYgKGZyb21TY2hlbWEgIT09IHZvaWQgMCkge1xuICAgICAgICBjb25zdCByZXNvbHZlZFNjaGVtYSA9IHJlc29sdmVPcGVuQVBJSnNvblNjaGVtYVJlZihkb2MsIGZyb21TY2hlbWEpO1xuICAgICAgICBpZiAoIWlzT2JqZWN0U2NoZW1hKHJlc29sdmVkU2NoZW1hKSkge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcmFtZXRlckluID0gZnJvbSA9PT0gXCJwYXJhbXNcIiA/IFwicGF0aFwiIDogZnJvbSA9PT0gXCJoZWFkZXJzXCIgPyBcImhlYWRlclwiIDogXCJxdWVyeVwiO1xuICAgICAgICByZWYucGFyYW1ldGVycyA/Pz0gW107XG4gICAgICAgIHJlZi5wYXJhbWV0ZXJzLnB1c2goLi4udG9PcGVuQVBJUGFyYW1ldGVycyhyZXNvbHZlZFNjaGVtYSwgcGFyYW1ldGVySW4pKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHNjaGVtYS5wcm9wZXJ0aWVzPy5ib2R5ICE9PSB2b2lkIDApIHtcbiAgICAgIHJlZi5yZXF1ZXN0Qm9keSA9IHtcbiAgICAgICAgcmVxdWlyZWQ6IHNjaGVtYS5yZXF1aXJlZD8uaW5jbHVkZXMoXCJib2R5XCIpLFxuICAgICAgICBjb250ZW50OiB0b09wZW5BUElDb250ZW50KHNjaGVtYS5wcm9wZXJ0aWVzLmJvZHkpXG4gICAgICB9O1xuICAgIH1cbiAgfVxuICBhc3luYyAjc3VjY2Vzc1Jlc3BvbnNlKGRvYywgcmVmLCBkZWYsIGJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucykge1xuICAgIGNvbnN0IG91dHB1dFNjaGVtYSA9IGRlZi5vdXRwdXRTY2hlbWE7XG4gICAgY29uc3Qgc3RhdHVzID0gZmFsbGJhY2tDb250cmFjdENvbmZpZyhcImRlZmF1bHRTdWNjZXNzU3RhdHVzXCIsIGRlZi5yb3V0ZS5zdWNjZXNzU3RhdHVzKTtcbiAgICBjb25zdCBkZXNjcmlwdGlvbiA9IGZhbGxiYWNrQ29udHJhY3RDb25maWcoXCJkZWZhdWx0U3VjY2Vzc0Rlc2NyaXB0aW9uXCIsIGRlZi5yb3V0ZT8uc3VjY2Vzc0Rlc2NyaXB0aW9uKTtcbiAgICBjb25zdCBldmVudEl0ZXJhdG9yU2NoZW1hRGV0YWlscyA9IGdldEV2ZW50SXRlcmF0b3JTY2hlbWFEZXRhaWxzKG91dHB1dFNjaGVtYSk7XG4gICAgY29uc3Qgb3V0cHV0U3RydWN0dXJlID0gZmFsbGJhY2tDb250cmFjdENvbmZpZyhcImRlZmF1bHRPdXRwdXRTdHJ1Y3R1cmVcIiwgZGVmLnJvdXRlLm91dHB1dFN0cnVjdHVyZSk7XG4gICAgaWYgKGV2ZW50SXRlcmF0b3JTY2hlbWFEZXRhaWxzKSB7XG4gICAgICByZWYucmVzcG9uc2VzID8/PSB7fTtcbiAgICAgIHJlZi5yZXNwb25zZXNbc3RhdHVzXSA9IHtcbiAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgIGNvbnRlbnQ6IHRvT3BlbkFQSUV2ZW50SXRlcmF0b3JDb250ZW50KFxuICAgICAgICAgIGF3YWl0IHRoaXMuY29udmVydGVyLmNvbnZlcnQoZXZlbnRJdGVyYXRvclNjaGVtYURldGFpbHMueWllbGRzLCB7IC4uLmJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucywgc3RyYXRlZ3k6IFwib3V0cHV0XCIgfSksXG4gICAgICAgICAgYXdhaXQgdGhpcy5jb252ZXJ0ZXIuY29udmVydChldmVudEl0ZXJhdG9yU2NoZW1hRGV0YWlscy5yZXR1cm5zLCB7IC4uLmJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucywgc3RyYXRlZ3k6IFwib3V0cHV0XCIgfSlcbiAgICAgICAgKVxuICAgICAgfTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgW3JlcXVpcmVkLCBqc29uXSA9IGF3YWl0IHRoaXMuY29udmVydGVyLmNvbnZlcnQoXG4gICAgICBvdXRwdXRTY2hlbWEsXG4gICAgICB7XG4gICAgICAgIC4uLmJhc2VTY2hlbWFDb252ZXJ0T3B0aW9ucyxcbiAgICAgICAgc3RyYXRlZ3k6IFwib3V0cHV0XCIsXG4gICAgICAgIG1pblN0cnVjdHVyZURlcHRoRm9yUmVmOiBvdXRwdXRTdHJ1Y3R1cmUgPT09IFwiZGV0YWlsZWRcIiA/IDEgOiAwXG4gICAgICB9XG4gICAgKTtcbiAgICBpZiAob3V0cHV0U3RydWN0dXJlID09PSBcImNvbXBhY3RcIikge1xuICAgICAgcmVmLnJlc3BvbnNlcyA/Pz0ge307XG4gICAgICByZWYucmVzcG9uc2VzW3N0YXR1c10gPSB7XG4gICAgICAgIGRlc2NyaXB0aW9uXG4gICAgICB9O1xuICAgICAgcmVmLnJlc3BvbnNlc1tzdGF0dXNdLmNvbnRlbnQgPSB0b09wZW5BUElDb250ZW50KGFwcGx5U2NoZW1hT3B0aW9uYWxpdHkocmVxdWlyZWQsIGpzb24pKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaGFuZGxlZFN0YXR1c2VzID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTtcbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgZXhwYW5kVW5pb25TY2hlbWEoanNvbikpIHtcbiAgICAgIGNvbnN0IGVycm9yID0gbmV3IE9wZW5BUElHZW5lcmF0b3JFcnJvcihgXG4gICAgICAgIFdoZW4gb3V0cHV0IHN0cnVjdHVyZSBpcyBcImRldGFpbGVkXCIsIG91dHB1dCBzY2hlbWEgbXVzdCBzYXRpc2Z5OlxuICAgICAgICB7IFxuICAgICAgICAgIHN0YXR1cz86IG51bWJlciwgLy8gbXVzdCBiZSBhIGxpdGVyYWwgbnVtYmVyIGFuZCBpbiB0aGUgcmFuZ2Ugb2YgMjAwLTM5OVxuICAgICAgICAgIGhlYWRlcnM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgXG4gICAgICAgICAgYm9keT86IHVua25vd24gXG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIEJ1dCBnb3Q6ICR7c3RyaW5naWZ5SlNPTihpdGVtKX1cbiAgICAgIGApO1xuICAgICAgaWYgKCFpc09iamVjdFNjaGVtYShpdGVtKSkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGxldCBzY2hlbWFTdGF0dXM7XG4gICAgICBsZXQgc2NoZW1hRGVzY3JpcHRpb247XG4gICAgICBpZiAoaXRlbS5wcm9wZXJ0aWVzPy5zdGF0dXMgIT09IHZvaWQgMCkge1xuICAgICAgICBjb25zdCBzdGF0dXNTY2hlbWEgPSByZXNvbHZlT3BlbkFQSUpzb25TY2hlbWFSZWYoZG9jLCBpdGVtLnByb3BlcnRpZXMuc3RhdHVzKTtcbiAgICAgICAgaWYgKHR5cGVvZiBzdGF0dXNTY2hlbWEgIT09IFwib2JqZWN0XCIgfHwgc3RhdHVzU2NoZW1hLmNvbnN0ID09PSB2b2lkIDAgfHwgdHlwZW9mIHN0YXR1c1NjaGVtYS5jb25zdCAhPT0gXCJudW1iZXJcIiB8fCAhTnVtYmVyLmlzSW50ZWdlcihzdGF0dXNTY2hlbWEuY29uc3QpIHx8IGlzT1JQQ0Vycm9yU3RhdHVzKHN0YXR1c1NjaGVtYS5jb25zdCkpIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBzY2hlbWFTdGF0dXMgPSBzdGF0dXNTY2hlbWEuY29uc3Q7XG4gICAgICAgIHNjaGVtYURlc2NyaXB0aW9uID0gc3RhdHVzU2NoZW1hLmRlc2NyaXB0aW9uO1xuICAgICAgfVxuICAgICAgY29uc3QgaXRlbVN0YXR1cyA9IHNjaGVtYVN0YXR1cyA/PyBzdGF0dXM7XG4gICAgICBjb25zdCBpdGVtRGVzY3JpcHRpb24gPSBzY2hlbWFEZXNjcmlwdGlvbiA/PyBkZXNjcmlwdGlvbjtcbiAgICAgIGlmIChoYW5kbGVkU3RhdHVzZXMuaGFzKGl0ZW1TdGF0dXMpKSB7XG4gICAgICAgIHRocm93IG5ldyBPcGVuQVBJR2VuZXJhdG9yRXJyb3IoYFxuICAgICAgICAgIFdoZW4gb3V0cHV0IHN0cnVjdHVyZSBpcyBcImRldGFpbGVkXCIsIGVhY2ggc3VjY2VzcyBzdGF0dXMgbXVzdCBiZSB1bmlxdWUuXG4gICAgICAgICAgQnV0IGdvdCBzdGF0dXM6ICR7aXRlbVN0YXR1c30gdXNlZCBtb3JlIHRoYW4gb25jZS5cbiAgICAgICAgYCk7XG4gICAgICB9XG4gICAgICBoYW5kbGVkU3RhdHVzZXMuYWRkKGl0ZW1TdGF0dXMpO1xuICAgICAgcmVmLnJlc3BvbnNlcyA/Pz0ge307XG4gICAgICByZWYucmVzcG9uc2VzW2l0ZW1TdGF0dXNdID0ge1xuICAgICAgICBkZXNjcmlwdGlvbjogaXRlbURlc2NyaXB0aW9uXG4gICAgICB9O1xuICAgICAgaWYgKGl0ZW0ucHJvcGVydGllcz8uaGVhZGVycyAhPT0gdm9pZCAwKSB7XG4gICAgICAgIGNvbnN0IGhlYWRlcnNTY2hlbWEgPSByZXNvbHZlT3BlbkFQSUpzb25TY2hlbWFSZWYoZG9jLCBpdGVtLnByb3BlcnRpZXMuaGVhZGVycyk7XG4gICAgICAgIGlmICghaXNPYmplY3RTY2hlbWEoaGVhZGVyc1NjaGVtYSkpIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGtleSBpbiBoZWFkZXJzU2NoZW1hLnByb3BlcnRpZXMpIHtcbiAgICAgICAgICBjb25zdCBoZWFkZXJTY2hlbWEgPSBoZWFkZXJzU2NoZW1hLnByb3BlcnRpZXNba2V5XTtcbiAgICAgICAgICBpZiAoaGVhZGVyU2NoZW1hICE9PSB2b2lkIDApIHtcbiAgICAgICAgICAgIHJlZi5yZXNwb25zZXNbaXRlbVN0YXR1c10uaGVhZGVycyA/Pz0ge307XG4gICAgICAgICAgICByZWYucmVzcG9uc2VzW2l0ZW1TdGF0dXNdLmhlYWRlcnNba2V5XSA9IHtcbiAgICAgICAgICAgICAgc2NoZW1hOiB0b09wZW5BUElTY2hlbWEoaGVhZGVyU2NoZW1hKSxcbiAgICAgICAgICAgICAgcmVxdWlyZWQ6IGl0ZW0ucmVxdWlyZWQ/LmluY2x1ZGVzKFwiaGVhZGVyc1wiKSAmJiBoZWFkZXJzU2NoZW1hLnJlcXVpcmVkPy5pbmNsdWRlcyhrZXkpXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGl0ZW0ucHJvcGVydGllcz8uYm9keSAhPT0gdm9pZCAwKSB7XG4gICAgICAgIHJlZi5yZXNwb25zZXNbaXRlbVN0YXR1c10uY29udGVudCA9IHRvT3BlbkFQSUNvbnRlbnQoXG4gICAgICAgICAgYXBwbHlTY2hlbWFPcHRpb25hbGl0eShpdGVtLnJlcXVpcmVkPy5pbmNsdWRlcyhcImJvZHlcIikgPz8gZmFsc2UsIGl0ZW0ucHJvcGVydGllcy5ib2R5KVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBhc3luYyAjZXJyb3JSZXNwb25zZShyZWYsIGRlZiwgYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zLCB1bmRlZmluZWRFcnJvclNjaGVtYSwgY3VzdG9tRXJyb3JSZXNwb25zZUJvZHlTY2hlbWEpIHtcbiAgICBjb25zdCBlcnJvck1hcCA9IGRlZi5lcnJvck1hcDtcbiAgICBjb25zdCBlcnJvclJlc3BvbnNlc0J5U3RhdHVzID0ge307XG4gICAgZm9yIChjb25zdCBjb2RlIGluIGVycm9yTWFwKSB7XG4gICAgICBjb25zdCBjb25maWcgPSBlcnJvck1hcFtjb2RlXTtcbiAgICAgIGlmICghY29uZmlnKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RhdHVzID0gZmFsbGJhY2tPUlBDRXJyb3JTdGF0dXMoY29kZSwgY29uZmlnLnN0YXR1cyk7XG4gICAgICBjb25zdCBkZWZhdWx0TWVzc2FnZSA9IGZhbGxiYWNrT1JQQ0Vycm9yTWVzc2FnZShjb2RlLCBjb25maWcubWVzc2FnZSk7XG4gICAgICBlcnJvclJlc3BvbnNlc0J5U3RhdHVzW3N0YXR1c10gPz89IHsgc3RhdHVzLCBkZWZpbmVkRXJyb3JEZWZpbml0aW9uczogW10sIGVycm9yU2NoZW1hVmFyaWFudHM6IFtdIH07XG4gICAgICBjb25zdCBbZGF0YVJlcXVpcmVkLCBkYXRhU2NoZW1hXSA9IGF3YWl0IHRoaXMuY29udmVydGVyLmNvbnZlcnQoY29uZmlnLmRhdGEsIHsgLi4uYmFzZVNjaGVtYUNvbnZlcnRPcHRpb25zLCBzdHJhdGVneTogXCJvdXRwdXRcIiB9KTtcbiAgICAgIGVycm9yUmVzcG9uc2VzQnlTdGF0dXNbc3RhdHVzXS5kZWZpbmVkRXJyb3JEZWZpbml0aW9ucy5wdXNoKFtjb2RlLCBkZWZhdWx0TWVzc2FnZSwgZGF0YVJlcXVpcmVkLCBkYXRhU2NoZW1hXSk7XG4gICAgICBlcnJvclJlc3BvbnNlc0J5U3RhdHVzW3N0YXR1c10uZXJyb3JTY2hlbWFWYXJpYW50cy5wdXNoKHtcbiAgICAgICAgdHlwZTogXCJvYmplY3RcIixcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIGRlZmluZWQ6IHsgY29uc3Q6IHRydWUgfSxcbiAgICAgICAgICBjb2RlOiB7IGNvbnN0OiBjb2RlIH0sXG4gICAgICAgICAgc3RhdHVzOiB7IGNvbnN0OiBzdGF0dXMgfSxcbiAgICAgICAgICBtZXNzYWdlOiB7IHR5cGU6IFwic3RyaW5nXCIsIGRlZmF1bHQ6IGRlZmF1bHRNZXNzYWdlIH0sXG4gICAgICAgICAgZGF0YTogZGF0YVNjaGVtYVxuICAgICAgICB9LFxuICAgICAgICByZXF1aXJlZDogZGF0YVJlcXVpcmVkID8gW1wiZGVmaW5lZFwiLCBcImNvZGVcIiwgXCJzdGF0dXNcIiwgXCJtZXNzYWdlXCIsIFwiZGF0YVwiXSA6IFtcImRlZmluZWRcIiwgXCJjb2RlXCIsIFwic3RhdHVzXCIsIFwibWVzc2FnZVwiXVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJlZi5yZXNwb25zZXMgPz89IHt9O1xuICAgIGZvciAoY29uc3Qgc3RhdHVzU3RyaW5nIGluIGVycm9yUmVzcG9uc2VzQnlTdGF0dXMpIHtcbiAgICAgIGNvbnN0IGVycm9yUmVzcG9uc2UgPSBlcnJvclJlc3BvbnNlc0J5U3RhdHVzW3N0YXR1c1N0cmluZ107XG4gICAgICBjb25zdCBjdXN0b21Cb2R5U2NoZW1hID0gdmFsdWUoY3VzdG9tRXJyb3JSZXNwb25zZUJvZHlTY2hlbWEsIGVycm9yUmVzcG9uc2UuZGVmaW5lZEVycm9yRGVmaW5pdGlvbnMsIGVycm9yUmVzcG9uc2Uuc3RhdHVzKTtcbiAgICAgIHJlZi5yZXNwb25zZXNbc3RhdHVzU3RyaW5nXSA9IHtcbiAgICAgICAgZGVzY3JpcHRpb246IHN0YXR1c1N0cmluZyxcbiAgICAgICAgY29udGVudDogdG9PcGVuQVBJQ29udGVudChjdXN0b21Cb2R5U2NoZW1hID8/IHtcbiAgICAgICAgICBvbmVPZjogW1xuICAgICAgICAgICAgLi4uZXJyb3JSZXNwb25zZS5lcnJvclNjaGVtYVZhcmlhbnRzLFxuICAgICAgICAgICAgdW5kZWZpbmVkRXJyb3JTY2hlbWFcbiAgICAgICAgICBdXG4gICAgICAgIH0pXG4gICAgICB9O1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgeyBDb21wb3NpdGVTY2hlbWFDb252ZXJ0ZXIgYXMgQywgTE9HSUNfS0VZV09SRFMgYXMgTCwgT3BlbkFQSUdlbmVyYXRvciBhcyBPLCBhcHBseUN1c3RvbU9wZW5BUElPcGVyYXRpb24gYXMgYSwgdG9PcGVuQVBJTWV0aG9kIGFzIGIsIGN1c3RvbU9wZW5BUElPcGVyYXRpb24gYXMgYywgdG9PcGVuQVBJQ29udGVudCBhcyBkLCB0b09wZW5BUElFdmVudEl0ZXJhdG9yQ29udGVudCBhcyBlLCB0b09wZW5BUElQYXJhbWV0ZXJzIGFzIGYsIGdldEN1c3RvbU9wZW5BUElPcGVyYXRpb24gYXMgZywgY2hlY2tQYXJhbXNTY2hlbWEgYXMgaCwgdG9PcGVuQVBJU2NoZW1hIGFzIGksIGlzRmlsZVNjaGVtYSBhcyBqLCBpc09iamVjdFNjaGVtYSBhcyBrLCBpc0FueVNjaGVtYSBhcyBsLCBmaWx0ZXJTY2hlbWFCcmFuY2hlcyBhcyBtLCBhcHBseVNjaGVtYU9wdGlvbmFsaXR5IGFzIG4sIGV4cGFuZFVuaW9uU2NoZW1hIGFzIG8sIGV4cGFuZEFycmF5YWJsZVNjaGVtYSBhcyBwLCBpc1ByaW1pdGl2ZVNjaGVtYSBhcyBxLCByZXNvbHZlT3BlbkFQSUpzb25TY2hlbWFSZWYgYXMgciwgc2VwYXJhdGVPYmplY3RTY2hlbWEgYXMgcywgdG9PcGVuQVBJUGF0aCBhcyB0IH07XG4iLCJpbXBvcnQgeyBzdHJpbmdpZnlKU09OLCBvbmNlLCB2YWx1ZSB9IGZyb20gJ0BvcnBjL3NoYXJlZCc7XG5pbXBvcnQgeyBPIGFzIE9wZW5BUElHZW5lcmF0b3IgfSBmcm9tICcuLi9zaGFyZWQvb3BlbmFwaS5EclRjZWxsNS5tanMnO1xuaW1wb3J0ICdAb3JwYy9jbGllbnQnO1xuaW1wb3J0ICdAb3JwYy9jbGllbnQvc3RhbmRhcmQnO1xuaW1wb3J0ICdAb3JwYy9jb250cmFjdCc7XG5pbXBvcnQgJ0BvcnBjL29wZW5hcGktY2xpZW50L3N0YW5kYXJkJztcbmltcG9ydCAnQG9ycGMvc2VydmVyJztcbmltcG9ydCAnQG9ycGMvaW50ZXJvcC9qc29uLXNjaGVtYS10eXBlZC9kcmFmdC0yMDIwLTEyJztcblxuY2xhc3MgT3BlbkFQSVJlZmVyZW5jZVBsdWdpbiB7XG4gIGdlbmVyYXRvcjtcbiAgc3BlY0dlbmVyYXRlT3B0aW9ucztcbiAgc3BlY1BhdGg7XG4gIGRvY3NQYXRoO1xuICBkb2NzVGl0bGU7XG4gIGRvY3NIZWFkO1xuICBkb2NzUHJvdmlkZXI7XG4gIGRvY3NTY3JpcHRVcmw7XG4gIGRvY3NDc3NVcmw7XG4gIGRvY3NDb25maWc7XG4gIHJlbmRlckRvY3NIdG1sO1xuICBjb25zdHJ1Y3RvcihvcHRpb25zID0ge30pIHtcbiAgICB0aGlzLnNwZWNHZW5lcmF0ZU9wdGlvbnMgPSBvcHRpb25zLnNwZWNHZW5lcmF0ZU9wdGlvbnM7XG4gICAgdGhpcy5kb2NzUGF0aCA9IG9wdGlvbnMuZG9jc1BhdGggPz8gXCIvXCI7XG4gICAgdGhpcy5kb2NzVGl0bGUgPSBvcHRpb25zLmRvY3NUaXRsZSA/PyBcIkFQSSBSZWZlcmVuY2VcIjtcbiAgICB0aGlzLmRvY3NDb25maWcgPSBvcHRpb25zLmRvY3NDb25maWcgPz8gdm9pZCAwO1xuICAgIHRoaXMuZG9jc1Byb3ZpZGVyID0gb3B0aW9ucy5kb2NzUHJvdmlkZXIgPz8gXCJzY2FsYXJcIjtcbiAgICB0aGlzLmRvY3NTY3JpcHRVcmwgPSBvcHRpb25zLmRvY3NTY3JpcHRVcmwgPz8gKHRoaXMuZG9jc1Byb3ZpZGVyID09PSBcInN3YWdnZXJcIiA/IFwiaHR0cHM6Ly91bnBrZy5jb20vc3dhZ2dlci11aS1kaXN0L3N3YWdnZXItdWktYnVuZGxlLmpzXCIgOiBcImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vQHNjYWxhci9hcGktcmVmZXJlbmNlXCIpO1xuICAgIHRoaXMuZG9jc0Nzc1VybCA9IG9wdGlvbnMuZG9jc0Nzc1VybCA/PyAodGhpcy5kb2NzUHJvdmlkZXIgPT09IFwic3dhZ2dlclwiID8gXCJodHRwczovL3VucGtnLmNvbS9zd2FnZ2VyLXVpLWRpc3Qvc3dhZ2dlci11aS5jc3NcIiA6IHZvaWQgMCk7XG4gICAgdGhpcy5kb2NzSGVhZCA9IG9wdGlvbnMuZG9jc0hlYWQgPz8gXCJcIjtcbiAgICB0aGlzLnNwZWNQYXRoID0gb3B0aW9ucy5zcGVjUGF0aCA/PyBcIi9zcGVjLmpzb25cIjtcbiAgICB0aGlzLmdlbmVyYXRvciA9IG5ldyBPcGVuQVBJR2VuZXJhdG9yKG9wdGlvbnMpO1xuICAgIGNvbnN0IGVzYyA9IChzKSA9PiBzLnJlcGxhY2UoLyYvZywgXCImYW1wO1wiKS5yZXBsYWNlKC9cIi9nLCBcIiZxdW90O1wiKS5yZXBsYWNlKC88L2csIFwiJmx0O1wiKS5yZXBsYWNlKC8+L2csIFwiJmd0O1wiKTtcbiAgICB0aGlzLnJlbmRlckRvY3NIdG1sID0gb3B0aW9ucy5yZW5kZXJEb2NzSHRtbCA/PyAoKHNwZWNVcmwsIHRpdGxlLCBoZWFkLCBzY3JpcHRVcmwsIGNvbmZpZywgc3BlYywgZG9jc1Byb3ZpZGVyLCBjc3NVcmwpID0+IHtcbiAgICAgIGxldCBib2R5O1xuICAgICAgaWYgKGRvY3NQcm92aWRlciA9PT0gXCJzd2FnZ2VyXCIpIHtcbiAgICAgICAgY29uc3Qgc3dhZ2dlckNvbmZpZyA9IHtcbiAgICAgICAgICBkb21faWQ6IFwiI2FwcFwiLFxuICAgICAgICAgIHNwZWMsXG4gICAgICAgICAgZGVlcExpbmtpbmc6IHRydWUsXG4gICAgICAgICAgcHJlc2V0czogW1xuICAgICAgICAgICAgXCJTd2FnZ2VyVUlCdW5kbGUucHJlc2V0cy5hcGlzXCIsXG4gICAgICAgICAgICBcIlN3YWdnZXJVSUJ1bmRsZS5wcmVzZXRzLnN0YW5kYWxvbmVcIlxuICAgICAgICAgIF0sXG4gICAgICAgICAgcGx1Z2luczogW1xuICAgICAgICAgICAgXCJTd2FnZ2VyVUlCdW5kbGUucGx1Z2lucy5Eb3dubG9hZFVybFwiXG4gICAgICAgICAgXSxcbiAgICAgICAgICAuLi5jb25maWdcbiAgICAgICAgfTtcbiAgICAgICAgYm9keSA9IGBcbiAgICAgICAgPGJvZHk+XG4gICAgICAgICAgPGRpdiBpZD1cImFwcFwiPjwvZGl2PlxuXG4gICAgICAgICAgPHNjcmlwdCBzcmM9XCIke2VzYyhzY3JpcHRVcmwpfVwiPjxcXC9zY3JpcHQ+XG5cbiAgICAgICAgICA8c2NyaXB0PlxuICAgICAgICAgICAgd2luZG93Lm9ubG9hZCA9ICgpID0+IHtcbiAgICAgICAgICAgICAgd2luZG93LnVpID0gU3dhZ2dlclVJQnVuZGxlKCR7c3RyaW5naWZ5SlNPTihzd2FnZ2VyQ29uZmlnKS5yZXBsYWNlKC9cIihTd2FnZ2VyVUlCdW5kbGVcXC5bXlwiXSspXCIvZywgXCIkMVwiKX0pXG4gICAgICAgICAgICB9XG4gICAgICAgICAgPFxcL3NjcmlwdD5cbiAgICAgICAgPC9ib2R5PlxuICAgICAgICBgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgc2NhbGFyQ29uZmlnID0ge1xuICAgICAgICAgIGNvbnRlbnQ6IHN0cmluZ2lmeUpTT04oc3BlYyksXG4gICAgICAgICAgLi4uY29uZmlnXG4gICAgICAgIH07XG4gICAgICAgIGJvZHkgPSBgXG4gICAgICAgIDxib2R5PlxuICAgICAgICAgIDxkaXYgaWQ9XCJhcHBcIiBkYXRhLWNvbmZpZz1cIiR7ZXNjKHN0cmluZ2lmeUpTT04oc2NhbGFyQ29uZmlnKSl9XCI+PC9kaXY+XG5cbiAgICAgICAgICA8c2NyaXB0IHNyYz1cIiR7ZXNjKHNjcmlwdFVybCl9XCI+PFxcL3NjcmlwdD5cblxuICAgICAgICAgIDxzY3JpcHQ+XG4gICAgICAgICAgICBTY2FsYXIuY3JlYXRlQXBpUmVmZXJlbmNlKCcjYXBwJywgSlNPTi5wYXJzZShkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYXBwJykuZGF0YXNldC5jb25maWcpKVxuICAgICAgICAgIDxcXC9zY3JpcHQ+XG4gICAgICAgIDwvYm9keT5cbiAgICAgICAgYDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBgXG4gICAgICAgIDwhZG9jdHlwZSBodG1sPlxuICAgICAgICA8aHRtbD5cbiAgICAgICAgICA8aGVhZD5cbiAgICAgICAgICAgIDxtZXRhIGNoYXJzZXQ9XCJ1dGYtOFwiIC8+XG4gICAgICAgICAgICA8bWV0YSBuYW1lPVwidmlld3BvcnRcIiBjb250ZW50PVwid2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTFcIiAvPlxuICAgICAgICAgICAgPHRpdGxlPiR7ZXNjKHRpdGxlKX08L3RpdGxlPlxuICAgICAgICAgICAgJHtjc3NVcmwgPyBgPGxpbmsgcmVsPVwic3R5bGVzaGVldFwiIHR5cGU9XCJ0ZXh0L2Nzc1wiIGhyZWY9XCIke2VzYyhjc3NVcmwpfVwiIC8+YCA6IFwiXCJ9XG4gICAgICAgICAgICAke2hlYWR9XG4gICAgICAgICAgPC9oZWFkPlxuICAgICAgICAgICR7Ym9keX1cbiAgICAgICAgPC9odG1sPlxuICAgICAgICBgO1xuICAgIH0pO1xuICB9XG4gIGluaXQob3B0aW9ucywgcm91dGVyKSB7XG4gICAgb3B0aW9ucy5pbnRlcmNlcHRvcnMgPz89IFtdO1xuICAgIG9wdGlvbnMuaW50ZXJjZXB0b3JzLnB1c2goYXN5bmMgKG9wdGlvbnMyKSA9PiB7XG4gICAgICBjb25zdCByZXMgPSBhd2FpdCBvcHRpb25zMi5uZXh0KCk7XG4gICAgICBpZiAocmVzLm1hdGNoZWQgfHwgb3B0aW9uczIucmVxdWVzdC5tZXRob2QgIT09IFwiR0VUXCIpIHtcbiAgICAgICAgcmV0dXJuIHJlcztcbiAgICAgIH1cbiAgICAgIGNvbnN0IHByZWZpeCA9IG9wdGlvbnMyLnByZWZpeCA/PyBcIlwiO1xuICAgICAgY29uc3QgcmVxdWVzdFBhdGhuYW1lID0gb3B0aW9uczIucmVxdWVzdC51cmwucGF0aG5hbWUucmVwbGFjZSgvXFwvJC8sIFwiXCIpIHx8IFwiL1wiO1xuICAgICAgY29uc3QgZG9jc1VybCA9IG5ldyBVUkwoYCR7cHJlZml4fSR7dGhpcy5kb2NzUGF0aH1gLnJlcGxhY2UoL1xcLyQvLCBcIlwiKSwgb3B0aW9uczIucmVxdWVzdC51cmwub3JpZ2luKTtcbiAgICAgIGNvbnN0IHNwZWNVcmwgPSBuZXcgVVJMKGAke3ByZWZpeH0ke3RoaXMuc3BlY1BhdGh9YC5yZXBsYWNlKC9cXC8kLywgXCJcIiksIG9wdGlvbnMyLnJlcXVlc3QudXJsLm9yaWdpbik7XG4gICAgICBjb25zdCBnZW5lcmF0ZVNwZWMgPSBvbmNlKGFzeW5jICgpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZ2VuZXJhdG9yLmdlbmVyYXRlKHJvdXRlciwge1xuICAgICAgICAgIHNlcnZlcnM6IFt7IHVybDogbmV3IFVSTChwcmVmaXgsIG9wdGlvbnMyLnJlcXVlc3QudXJsLm9yaWdpbikudG9TdHJpbmcoKSB9XSxcbiAgICAgICAgICAuLi5hd2FpdCB2YWx1ZSh0aGlzLnNwZWNHZW5lcmF0ZU9wdGlvbnMsIG9wdGlvbnMyKVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgaWYgKHJlcXVlc3RQYXRobmFtZSA9PT0gc3BlY1VybC5wYXRobmFtZSkge1xuICAgICAgICBjb25zdCBzcGVjID0gYXdhaXQgZ2VuZXJhdGVTcGVjKCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbWF0Y2hlZDogdHJ1ZSxcbiAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgc3RhdHVzOiAyMDAsXG4gICAgICAgICAgICBoZWFkZXJzOiB7fSxcbiAgICAgICAgICAgIGJvZHk6IG5ldyBGaWxlKFtzdHJpbmdpZnlKU09OKHNwZWMpXSwgXCJzcGVjLmpzb25cIiwgeyB0eXBlOiBcImFwcGxpY2F0aW9uL2pzb25cIiB9KVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXF1ZXN0UGF0aG5hbWUgPT09IGRvY3NVcmwucGF0aG5hbWUpIHtcbiAgICAgICAgY29uc3QgaHRtbCA9IHRoaXMucmVuZGVyRG9jc0h0bWwoXG4gICAgICAgICAgc3BlY1VybC50b1N0cmluZygpLFxuICAgICAgICAgIGF3YWl0IHZhbHVlKHRoaXMuZG9jc1RpdGxlLCBvcHRpb25zMiksXG4gICAgICAgICAgYXdhaXQgdmFsdWUodGhpcy5kb2NzSGVhZCwgb3B0aW9uczIpLFxuICAgICAgICAgIGF3YWl0IHZhbHVlKHRoaXMuZG9jc1NjcmlwdFVybCwgb3B0aW9uczIpLFxuICAgICAgICAgIGF3YWl0IHZhbHVlKHRoaXMuZG9jc0NvbmZpZywgb3B0aW9uczIpLFxuICAgICAgICAgIGF3YWl0IGdlbmVyYXRlU3BlYygpLFxuICAgICAgICAgIHRoaXMuZG9jc1Byb3ZpZGVyLFxuICAgICAgICAgIGF3YWl0IHZhbHVlKHRoaXMuZG9jc0Nzc1VybCwgb3B0aW9uczIpXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbWF0Y2hlZDogdHJ1ZSxcbiAgICAgICAgICByZXNwb25zZToge1xuICAgICAgICAgICAgc3RhdHVzOiAyMDAsXG4gICAgICAgICAgICBoZWFkZXJzOiB7fSxcbiAgICAgICAgICAgIGJvZHk6IG5ldyBGaWxlKFtodG1sXSwgXCJhcGktcmVmZXJlbmNlLmh0bWxcIiwgeyB0eXBlOiBcInRleHQvaHRtbFwiIH0pXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcztcbiAgICB9KTtcbiAgfVxufVxuXG5leHBvcnQgeyBPcGVuQVBJUmVmZXJlbmNlUGx1Z2luIH07XG4iXSwieF9nb29nbGVfaWdub3JlTGlzdCI6WzAsMSwyXSwibWFwcGluZ3MiOiI7Ozs7O0FBUUEsSUFBSTtDQUNILFNBQVMsa0JBQWtCO0FBQ3hCLGtCQUFpQixVQUFVO0FBQzNCLGtCQUFpQixVQUFVO0FBQzNCLGtCQUFpQixZQUFZO0FBQzdCLGtCQUFpQixZQUFZO0FBQzdCLGtCQUFpQixlQUFlO0FBQ2hDLGtCQUFpQixxQkFBcUI7QUFDdEMsa0JBQWlCLFlBQVk7R0FDOUIsb0JBQW9CLGtCQUFrQixFQUFFLEVBQUU7QUFDN0MsSUFBSTtDQUNILFNBQVMsU0FBUztBQUNmLFNBQVEsVUFBVTtBQUNsQixTQUFRLGNBQWM7QUFDdEIsU0FBUSxjQUFjO0FBQ3RCLFNBQVEsV0FBVztBQUNuQixTQUFRLGNBQWM7QUFDdEIsU0FBUSxjQUFjO0FBQ3RCLFNBQVEsaUJBQWlCO0FBQ3pCLFNB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
|