@cartanova/qgrid-cli 2.9.7 → 2.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +3 -2
- package/bundle/dist/application/qgrid/qgrid.types.js +2 -2
- package/bundle/dist/application/request-log/request-log.model.js +2 -1
- package/bundle/dist/utils/providers/anthropic/anthropic-constants.js +4 -2
- package/bundle/dist/utils/providers/common/model-cost.js +3 -2
- package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +3 -2
- package/bundle/dist/utils/providers/openai/openai-dispatcher.js +86 -5
- package/bundle/src/application/qgrid/qgrid-image-generation.test.ts +7 -1
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +13 -0
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +2 -1
- package/bundle/src/application/qgrid/qgrid.frame.test.ts +2 -2
- package/bundle/src/application/qgrid/qgrid.types.ts +2 -2
- package/bundle/src/application/request-log/request-log.model.ts +2 -0
- package/bundle/src/application/sonamu.generated.http +4 -2
- package/bundle/src/utils/providers/anthropic/anthropic-constants.test.ts +5 -1
- package/bundle/src/utils/providers/anthropic/anthropic-constants.ts +4 -2
- package/bundle/src/utils/providers/common/model-cost.test.ts +1 -0
- package/bundle/src/utils/providers/common/model-cost.ts +3 -0
- package/bundle/src/utils/providers/common/provider-dispatcher.ts +1 -1
- package/bundle/src/utils/providers/openai/openai-backend-protocol.test.ts +5 -0
- package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +2 -2
- package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +114 -0
- package/bundle/src/utils/providers/openai/openai-dispatcher.ts +136 -1
- package/bundle/web-dist/client/assets/index-D8VwLsuq.js +106 -0
- package/bundle/web-dist/client/assets/index-D_sagzsR.css +1 -0
- package/bundle/web-dist/client/assets/logs-_T8KV5ne.js +1 -0
- package/bundle/web-dist/client/assets/{monit-7tcWgB20.js → monit-DRCrtO2j.js} +1 -1
- package/bundle/web-dist/client/assets/request-model-eygfdRv7.js +1 -0
- package/bundle/web-dist/client/assets/{routes-CSVp9aNn.js → routes-5A6mia6C.js} +1 -1
- package/bundle/web-dist/client/assets/{services.generated-C6jfEwfK.js → services.generated-Bg2XkD-D.js} +1 -1
- package/bundle/web-dist/client/assets/settings-BpP9WVFI.js +1 -0
- package/bundle/web-dist/client/assets/show-D5ifZXdy.js +2 -0
- package/bundle/web-dist/client/assets/tokens-Cfe6WvLK.js +1 -0
- package/bundle/web-dist/client/assets/{use-oauth-login-flow-DTrmdduV.js → use-oauth-login-flow-BTLUGhwh.js} +1 -1
- package/bundle/web-dist/client/assets/{use-update-token-mutation-BIvO70-M.js → use-update-token-mutation-Dkv_HG-C.js} +1 -1
- package/bundle/web-dist/client/index.html +3 -3
- package/bundle/web-dist/server/assets/{lazyRouteComponent-C_k4R5n6.js → lazyRouteComponent-DyizoQKi.js} +2 -2
- package/bundle/web-dist/server/assets/{logs-lBOU5eUP.js → logs-DO8zBdBR.js} +12 -5
- package/bundle/web-dist/server/assets/{monit-BW2X1D23.js → monit-COH4MckI.js} +2 -2
- package/bundle/web-dist/server/assets/{plus-DilmHifT.js → plus-C1D8z9o0.js} +1 -1
- package/bundle/web-dist/server/assets/{react-dom-CHRRsKwb.js → react-dom-PfWvArTX.js} +1 -1
- package/bundle/web-dist/server/assets/request-model-DXclJfdP.js +13 -0
- package/bundle/web-dist/server/assets/{routes-B408iqh1.js → routes-Btja-741.js} +4 -4
- package/bundle/web-dist/server/assets/{services.generated-buX3cJzR.js → services.generated-BsKOUSXl.js} +1 -1
- package/bundle/web-dist/server/assets/{settings-CFoXQaAg.js → settings-DPcWGvy-.js} +3 -3
- package/bundle/web-dist/server/assets/{show-CcZJO6WF.js → show-CMXbb3TJ.js} +10 -4
- package/bundle/web-dist/server/assets/{tokens-C32lycTe.js → tokens-DAUmTrgO.js} +15 -11
- package/bundle/web-dist/server/assets/{use-oauth-login-flow-DCjxIa80.js → use-oauth-login-flow-GsGwqefs.js} +1 -1
- package/bundle/web-dist/server/assets/{use-update-token-mutation-CqK8i8Fa.js → use-update-token-mutation-RujWERvj.js} +1 -1
- package/bundle/web-dist/server/entry-server.generated.js +272 -51
- package/package.json +1 -1
- package/skills/qgrid/SKILL.md +10 -1
- package/skills/qgrid/references/anthropic-claude-code-runtime.md +3 -2
- package/skills/qgrid/references/decision-rationale.md +11 -2
- package/skills/qgrid/references/openai-codex-runtime.md +11 -1
- package/skills/qgrid/references/request-log-run-lifecycle.md +3 -1
- package/skills/qgrid/references/sonamu-api-web-flow.md +9 -1
- package/skills/qgrid/references/token-auth-quota-lifecycle.md +2 -0
- package/skills/qgrid/references/verification-and-debugging.md +4 -1
- package/bundle/web-dist/client/assets/index-BshX4Gd8.css +0 -1
- package/bundle/web-dist/client/assets/index-D4MEKFjK.js +0 -106
- package/bundle/web-dist/client/assets/logs-BWhH8t7Y.js +0 -1
- package/bundle/web-dist/client/assets/settings-CYgR0YTh.js +0 -1
- package/bundle/web-dist/client/assets/show-Cg8n_Mxg.js +0 -2
- package/bundle/web-dist/client/assets/tokens-B5yg6bP1.js +0 -1
- /package/bundle/web-dist/client/assets/{plus-p4vtg6LN.js → plus-CknMNCP5.js} +0 -0
|
@@ -10,6 +10,7 @@ import { getLogger } from "@logtape/logtape";
|
|
|
10
10
|
//#region src/utils/providers/openai/openai-dispatcher.ts
|
|
11
11
|
const logger = getLogger(["qgrid", "openai-dispatcher"]);
|
|
12
12
|
const DEFAULT_REQUEST_TIMEOUT_MS = 6e5;
|
|
13
|
+
const TRANSPARENT_IMAGE_TOOL = "generate_transparent_image";
|
|
13
14
|
var ImageGenerationError = class extends Error {
|
|
14
15
|
kind;
|
|
15
16
|
constructor(kind, message) {
|
|
@@ -67,9 +68,30 @@ function asReasoning(req) {
|
|
|
67
68
|
}
|
|
68
69
|
function requestOptions(req) {
|
|
69
70
|
const { outputFormat, ...imageControls } = req.imageGenerationOptions ?? {};
|
|
71
|
+
const auto = req.imageGeneration === "auto";
|
|
72
|
+
if (auto && req.outputSchema) throw new ImageGenerationError("gate", "Automatic image generation does not support structured output or external tools");
|
|
70
73
|
return {
|
|
71
74
|
model: req.model ?? "",
|
|
72
75
|
...req.systemPrompt ? { instructions: req.systemPrompt } : {},
|
|
76
|
+
...auto ? {
|
|
77
|
+
instructions: [req.systemPrompt, "Use image_generation for ordinary image generation or editing. Use generate_transparent_image only when a transparent background is requested. Text replies are allowed when no image is needed. Use only one kind of image tool per response, and at most one generate_transparent_image call."].filter(Boolean).join("\n\n"),
|
|
78
|
+
parallelToolCalls: false,
|
|
79
|
+
tools: [{
|
|
80
|
+
type: "function",
|
|
81
|
+
name: TRANSPARENT_IMAGE_TOOL,
|
|
82
|
+
description: "Generate or edit an image with a transparent background using the conversation's reference images.",
|
|
83
|
+
strict: true,
|
|
84
|
+
parameters: {
|
|
85
|
+
type: "object",
|
|
86
|
+
properties: { prompt: {
|
|
87
|
+
type: "string",
|
|
88
|
+
description: "Complete instructions for the transparent image generation or edit."
|
|
89
|
+
} },
|
|
90
|
+
required: ["prompt"],
|
|
91
|
+
additionalProperties: false
|
|
92
|
+
}
|
|
93
|
+
}]
|
|
94
|
+
} : {},
|
|
73
95
|
history: inputItems(req),
|
|
74
96
|
...asReasoning(req) ? { reasoning: asReasoning(req) } : {},
|
|
75
97
|
...req.verbosity ? { verbosity: req.verbosity } : {},
|
|
@@ -78,6 +100,7 @@ function requestOptions(req) {
|
|
|
78
100
|
...req.outputSchema ? { outputSchema: { schema: req.outputSchema } } : {},
|
|
79
101
|
...req.imageGeneration ? { imageGeneration: req.imageGenerationOptions ? {
|
|
80
102
|
...imageControls,
|
|
103
|
+
...auto ? { background: "auto" } : {},
|
|
81
104
|
...outputFormat ? { output_format: outputFormat } : {}
|
|
82
105
|
} : true } : {}
|
|
83
106
|
};
|
|
@@ -195,6 +218,11 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
195
218
|
};
|
|
196
219
|
const images = [];
|
|
197
220
|
let imageAttempted = false;
|
|
221
|
+
const auto = req.imageGeneration === "auto";
|
|
222
|
+
const transparentCalls = /* @__PURE__ */ new Map();
|
|
223
|
+
const transparentCallIds = /* @__PURE__ */ new Set();
|
|
224
|
+
let transparentAttempted = false;
|
|
225
|
+
let driverCompleted = false;
|
|
198
226
|
let servingModel = req.model ?? "";
|
|
199
227
|
const metadata = selection.metadata;
|
|
200
228
|
const clientEntry = this.acquireClient(selection);
|
|
@@ -212,7 +240,23 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
212
240
|
...event.generation ? { generation: event.generation } : {}
|
|
213
241
|
});
|
|
214
242
|
} else if (event.type === "output-item" && event.item.type === "image_generation_call") imageAttempted = true;
|
|
215
|
-
else if (event.type === "
|
|
243
|
+
else if (auto && event.type === "output-item" && event.item.type === "function_call") {
|
|
244
|
+
if (event.item.name !== TRANSPARENT_IMAGE_TOOL) throw new ImageGenerationError("incomplete", "Unexpected automatic image tool call");
|
|
245
|
+
transparentAttempted = true;
|
|
246
|
+
transparentCallIds.add(event.item.call_id);
|
|
247
|
+
if (!event.completed) continue;
|
|
248
|
+
const id = event.item.call_id;
|
|
249
|
+
let args;
|
|
250
|
+
try {
|
|
251
|
+
args = JSON.parse(String(event.item.arguments));
|
|
252
|
+
} catch {
|
|
253
|
+
throw new ImageGenerationError("incomplete", "Invalid transparent image arguments");
|
|
254
|
+
}
|
|
255
|
+
if (typeof id !== "string" || !id || !args || typeof args !== "object" || Array.isArray(args) || Object.keys(args).length !== 1 || !("prompt" in args) || typeof args.prompt !== "string" || !args.prompt.trim()) throw new ImageGenerationError("incomplete", "Invalid transparent image arguments");
|
|
256
|
+
if (transparentCalls.has(id) && transparentCalls.get(id) !== args.prompt) throw new ImageGenerationError("incomplete", "Conflicting transparent image tool calls");
|
|
257
|
+
transparentCalls.set(id, args.prompt);
|
|
258
|
+
} else if (event.type === "completed" && event.usage) {
|
|
259
|
+
driverCompleted = true;
|
|
216
260
|
servingModel = event.model ?? servingModel;
|
|
217
261
|
usage = {
|
|
218
262
|
totalTokens: event.usage.totalTokens,
|
|
@@ -221,15 +265,52 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
221
265
|
cachedInputTokens: event.usage.cachedInputTokens,
|
|
222
266
|
reasoningOutputTokens: event.usage.reasoningTokens
|
|
223
267
|
};
|
|
224
|
-
} else if (event.type === "completed")
|
|
225
|
-
|
|
268
|
+
} else if (event.type === "completed") {
|
|
269
|
+
driverCompleted = true;
|
|
270
|
+
servingModel = event.model ?? servingModel;
|
|
271
|
+
} else if (event.type === "error") {
|
|
226
272
|
if (req.imageGeneration) throw new ImageGenerationError("incomplete", event.error.message);
|
|
227
273
|
throw event.error;
|
|
228
274
|
}
|
|
275
|
+
if (auto && transparentAttempted) {
|
|
276
|
+
if (!driverCompleted || transparentCalls.size !== 1 || transparentCallIds.size !== 1 || imageAttempted) throw new ImageGenerationError("incomplete", "Expected one completed transparent image call without another image tool");
|
|
277
|
+
if (req.abortSignal?.aborted) throw abortError(req.abortSignal);
|
|
278
|
+
const prompt = [...transparentCalls.values()][0];
|
|
279
|
+
let imageCompleted = false;
|
|
280
|
+
for await (const event of clientEntry.client.responses({
|
|
281
|
+
model: req.model ?? "",
|
|
282
|
+
...req.systemPrompt ? { instructions: req.systemPrompt } : {},
|
|
283
|
+
history: [...inputItems(req), {
|
|
284
|
+
type: "message",
|
|
285
|
+
role: "user",
|
|
286
|
+
content: [{
|
|
287
|
+
type: "input_text",
|
|
288
|
+
text: prompt
|
|
289
|
+
}]
|
|
290
|
+
}],
|
|
291
|
+
imageGeneration: {
|
|
292
|
+
quality: req.imageGenerationOptions?.quality,
|
|
293
|
+
size: req.imageGenerationOptions?.size,
|
|
294
|
+
output_format: "png",
|
|
295
|
+
background: "transparent"
|
|
296
|
+
}
|
|
297
|
+
}, req.abortSignal)) if (event.type === "image") images.push({
|
|
298
|
+
data: event.base64,
|
|
299
|
+
mediaType: event.mimeType,
|
|
300
|
+
revisedPrompt: event.revisedPrompt ?? null,
|
|
301
|
+
...event.generation ? { generation: event.generation } : {}
|
|
302
|
+
});
|
|
303
|
+
else if (event.type === "completed") imageCompleted = true;
|
|
304
|
+
else if (event.type === "error") throw new ImageGenerationError("incomplete", event.error.message);
|
|
305
|
+
imageAttempted = true;
|
|
306
|
+
if (!imageCompleted) throw new ImageGenerationError("incomplete", "Transparent image generation did not complete");
|
|
307
|
+
}
|
|
308
|
+
if (auto && imageAttempted && !driverCompleted) throw new ImageGenerationError("incomplete", "Image generation response did not complete");
|
|
309
|
+
if (req.abortSignal?.aborted) throw abortError(req.abortSignal);
|
|
229
310
|
} finally {
|
|
230
311
|
this.releaseClient(clientEntry);
|
|
231
312
|
}
|
|
232
|
-
if (req.imageGeneration && images.length === 0) throw new ImageGenerationError(imageAttempted ? "incomplete" : "not_called", imageAttempted ? "image generation did not complete" : "model did not call image generation");
|
|
313
|
+
if ((req.imageGeneration === true || auto && imageAttempted) && images.length === 0) throw new ImageGenerationError(imageAttempted ? "incomplete" : "not_called", imageAttempted ? "image generation did not complete" : "model did not call image generation");
|
|
233
314
|
return {
|
|
234
315
|
text,
|
|
235
316
|
tokenName: metadata.name,
|
|
@@ -474,4 +555,4 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
474
555
|
//#endregion
|
|
475
556
|
export { ImageGenerationError, OpenAIDispatcher };
|
|
476
557
|
|
|
477
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLWRpc3BhdGNoZXIuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9vcGVuYWkvb3BlbmFpLWRpc3BhdGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcblxuaW1wb3J0IHsgUXVvdGFUaHJlc2hvbGRFeGNlZWRlZEVycm9yIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLnR5cGVzXCI7XG5pbXBvcnQgeyBUb2tlbk1vZGVsIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLm1vZGVsXCI7XG5pbXBvcnQgeyB0eXBlIE9wZW5BSUNyZWRlbnRpYWxzIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLnR5cGVzXCI7XG5pbXBvcnQgeyByZXNvbHZlT3BlbkFJRWZmb3J0IH0gZnJvbSBcIi4uL2NvbW1vbi9lZmZvcnRcIjtcbmltcG9ydCB7XG4gIHR5cGUgR2VuZXJhdGVSZXF1ZXN0LFxuICB0eXBlIEdlbmVyYXRlUmVzdWx0LFxuICB0eXBlIEdlbmVyYXRlU3RyZWFtQ2FsbGJhY2tzLFxuICB0eXBlIEdlbmVyYXRlZEltYWdlLFxuICB0eXBlIFByb3ZpZGVyRGlzcGF0Y2hlcixcbn0gZnJvbSBcIi4uL2NvbW1vbi9wcm92aWRlci1kaXNwYXRjaGVyXCI7XG5pbXBvcnQgeyBTbW9vdGhXZWlnaHRlZFJvdW5kUm9iaW4gfSBmcm9tIFwiLi4vY29tbW9uL3Ntb290aC13ZWlnaHRlZC1yb3VuZC1yb2JpblwiO1xuaW1wb3J0IHtcbiAgdHlwZSBKc29uVmFsdWUsXG4gIHR5cGUgT3BlbkFJUmVzcG9uc2VJdGVtLFxuICB0eXBlIE9wZW5BSVJlc3BvbnNlc09wdGlvbnMsXG59IGZyb20gXCIuL29wZW5haS1iYWNrZW5kLXByb3RvY29sXCI7XG5pbXBvcnQgeyBPcGVuQUlEaXJlY3RDbGllbnQsIHR5cGUgT3BlbkFJRGlyZWN0Q2xpZW50T3B0aW9ucyB9IGZyb20gXCIuL29wZW5haS1kaXJlY3QtY2xpZW50XCI7XG5pbXBvcnQgeyByZWFkT3BlbkFJUXVvdGFVc2FnZSwgdHlwZSBPcGVuQUlSYXRlTGltaXRzV2l0aE1ldGEgfSBmcm9tIFwiLi9vcGVuYWktcXVvdGFcIjtcbmltcG9ydCB7IGhhbmRsZUNoYXRncHRBdXRoVG9rZW5zUmVmcmVzaCB9IGZyb20gXCIuL29wZW5haS1yZWZyZXNoXCI7XG5pbXBvcnQgeyB0eXBlIE9wZW5BSVRyYW5zcG9ydEtpbmQsIHJlc29sdmVPcGVuQUlUcmFuc3BvcnRLaW5kIH0gZnJvbSBcIi4vb3BlbmFpLXRyYW5zcG9ydC1jb25maWdcIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwib3BlbmFpLWRpc3BhdGNoZXJcIl0pO1xuLy8g6rWQ7LK065CcIGNvZGV4IHdvcmtlciDqsIAg6rCV7KCc7ZWY642YIHdhdGNoZG9nLiDtmLjstpzsnpDqsIAgdGltZW91dE1zIOulvCDsg53rnrXtlbTrj4Qg7JqU7LKt7J20XG4vLyDsmIHsm5Dtnogg66ek64us66as7KeAIOyViuuPhOuhnSBkaXJlY3QgdHJhbnNwb3J0IOuPhCDsnKDtlZztlZwg6riw67O4IOyDge2VnOydhCDsnKDsp4DtlZzri6QuXG5jb25zdCBERUZBVUxUX1JFUVVFU1RfVElNRU9VVF9NUyA9IDYwMF8wMDA7XG5cbmV4cG9ydCB0eXBlIEltYWdlRmFpbHVyZUtpbmQgPSBcImdhdGVcIiB8IFwibm90X2NhbGxlZFwiIHwgXCJpbmNvbXBsZXRlXCI7XG5cbmV4cG9ydCBjbGFzcyBJbWFnZUdlbmVyYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcmVhZG9ubHkga2luZDogSW1hZ2VGYWlsdXJlS2luZCxcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiSW1hZ2VHZW5lcmF0aW9uRXJyb3JcIjtcbiAgfVxufVxuXG50eXBlIFRva2VuTWV0YWRhdGEgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzO1xuICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGw7XG4gIHdlaWdodDogbnVtYmVyO1xuICBhY3RpdmU6IGJvb2xlYW47XG4gIGdlbmVyYXRpb246IG51bWJlcjtcbn07XG5cbnR5cGUgVG9rZW5TZWxlY3Rpb24gPSB7IHRva2VuSWQ6IG51bWJlcjsgbWV0YWRhdGE6IFRva2VuTWV0YWRhdGEgfTtcblxuZXhwb3J0IHR5cGUgT3BlbkFJRGlyZWN0Q2xpZW50RmFjdG9yeSA9IChcbiAgb3B0aW9uczogT3BlbkFJRGlyZWN0Q2xpZW50T3B0aW9ucyxcbiAgdG9rZW5JZDogbnVtYmVyLFxuKSA9PiBQaWNrPE9wZW5BSURpcmVjdENsaWVudCwgXCJyZXNwb25zZXNcIj4gJiB7IGNsb3NlPzogKCkgPT4gdm9pZCB9O1xuXG50eXBlIENsaWVudEVudHJ5ID0ge1xuICBnZW5lcmF0aW9uOiBudW1iZXI7XG4gIGNsaWVudDogUGljazxPcGVuQUlEaXJlY3RDbGllbnQsIFwicmVzcG9uc2VzXCI+ICYgeyBjbG9zZT86ICgpID0+IHZvaWQgfTtcbiAgaW5GbGlnaHQ6IG51bWJlcjtcbiAgcmV0aXJlZDogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlbkFJRGlzcGF0Y2hlckRlcGVuZGVuY2llcyB7XG4gIGNsaWVudEZhY3Rvcnk/OiBPcGVuQUlEaXJlY3RDbGllbnRGYWN0b3J5O1xuICBmZXRjaD86IHR5cGVvZiBmZXRjaDtcbn1cblxuZnVuY3Rpb24gYWJvcnRFcnJvcihzaWduYWw6IEFib3J0U2lnbmFsKTogRXJyb3Ige1xuICBjb25zdCByZWFzb24gPSBzaWduYWwucmVhc29uO1xuICByZXR1cm4gcmVhc29uIGluc3RhbmNlb2YgRXJyb3IgPyByZWFzb24gOiBuZXcgRE9NRXhjZXB0aW9uKFwiQWJvcnRlZFwiLCBcIkFib3J0RXJyb3JcIik7XG59XG5cbmZ1bmN0aW9uIGFjdGl2ZVNpZ25hbChzaWduYWw/OiBBYm9ydFNpZ25hbCwgdGltZW91dE1zPzogbnVtYmVyKTogQWJvcnRTaWduYWwge1xuICBjb25zdCB0aW1lb3V0ID0gQWJvcnRTaWduYWwudGltZW91dCh0aW1lb3V0TXMgPz8gREVGQVVMVF9SRVFVRVNUX1RJTUVPVVRfTVMpO1xuICByZXR1cm4gc2lnbmFsID8gQWJvcnRTaWduYWwuYW55KFtzaWduYWwsIHRpbWVvdXRdKSA6IHRpbWVvdXQ7XG59XG5cbmZ1bmN0aW9uIHF1b3RhTWVzc2FnZShlbnRyaWVzOiBBcnJheTx7IG5hbWU6IHN0cmluZzsgdGhyZXNob2xkOiBudW1iZXIgfT4pOiBzdHJpbmcge1xuICBjb25zdCBkZXRhaWwgPSBlbnRyaWVzLm1hcCgoZSkgPT4gYCR7ZS5uYW1lfSAodGhyZXNob2xkICR7ZS50aHJlc2hvbGR9JSlgKS5qb2luKFwiLCBcIik7XG4gIHJldHVybiBkZXRhaWxcbiAgICA/IGBBbGwgb3BlbmFpIHRva2VucyBleGNlZWRlZCBxdW90YSB0aHJlc2hvbGQ6ICR7ZGV0YWlsfWBcbiAgICA6IFwiQWxsIG9wZW5haSB0b2tlbnMgZXhjZWVkZWQgcXVvdGEgdGhyZXNob2xkXCI7XG59XG5cbmZ1bmN0aW9uIGlucHV0SXRlbXMocmVxOiBHZW5lcmF0ZVJlcXVlc3QpOiBPcGVuQUlSZXNwb25zZUl0ZW1bXSB7XG4gIGNvbnN0IGhpc3RvcnkgPSAocmVxLmNvbGRIaXN0b3J5ID8/IFtdKSBhcyBPcGVuQUlSZXNwb25zZUl0ZW1bXTtcbiAgY29uc3QgY29udGVudDogT3BlbkFJUmVzcG9uc2VJdGVtW10gPSByZXEuY29sZElucHV0Lm1hcCgoaW5wdXQpID0+IHtcbiAgICBpZiAoaW5wdXQudHlwZSA9PT0gXCJ0ZXh0XCIpIHJldHVybiB7IHR5cGU6IFwiaW5wdXRfdGV4dFwiLCB0ZXh0OiBpbnB1dC50ZXh0IH07XG4gICAgaWYgKGlucHV0LnR5cGUgPT09IFwiaW1hZ2VcIikgcmV0dXJuIHsgdHlwZTogXCJpbnB1dF9pbWFnZVwiLCBpbWFnZV91cmw6IGlucHV0LnVybCB9O1xuICAgIGlmIChpbnB1dC50eXBlID09PSBcImxvY2FsSW1hZ2VcIikgcmV0dXJuIHsgdHlwZTogXCJpbnB1dF9pbWFnZVwiLCBpbWFnZV91cmw6IGlucHV0LnBhdGggfTtcbiAgICByZXR1cm4geyB0eXBlOiBcImlucHV0X3RleHRcIiwgdGV4dDogYCR7aW5wdXQubmFtZX06ICR7aW5wdXQucGF0aH1gIH07XG4gIH0pO1xuICByZXR1cm4gWy4uLmhpc3RvcnksIHsgdHlwZTogXCJtZXNzYWdlXCIsIHJvbGU6IFwidXNlclwiLCBjb250ZW50IH1dO1xufVxuXG5mdW5jdGlvbiBhc1JlYXNvbmluZyhyZXE6IEdlbmVyYXRlUmVxdWVzdCk6IE9wZW5BSVJlc3BvbnNlc09wdGlvbnNbXCJyZWFzb25pbmdcIl0gfCB1bmRlZmluZWQge1xuICBjb25zdCBzdW1tYXJ5ID1cbiAgICByZXEucmVhc29uaW5nU3VtbWFyeSAmJiByZXEucmVhc29uaW5nU3VtbWFyeSAhPT0gXCJub25lXCIgPyByZXEucmVhc29uaW5nU3VtbWFyeSA6IHVuZGVmaW5lZDtcbiAgLy8gQ29kZXgg7Ja07ZyYwrfrqqjrjbgg7IOB7ZWcIOuwluydmCBlZmZvcnQg64qUIOyXrOq4sOyEnCDsobDsmqntnogg67KE66aw64ukKOuwseyXlOuTnCDquLDrs7jqsJIg7KCB7JqpKS5cbiAgY29uc3QgZWZmb3J0ID0gcmVzb2x2ZU9wZW5BSUVmZm9ydChyZXEubW9kZWwgPz8gXCJcIiwgcmVxLmVmZm9ydCk7XG4gIGlmICghZWZmb3J0ICYmICFzdW1tYXJ5KSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4ge1xuICAgIC4uLihlZmZvcnQgPyB7IGVmZm9ydCB9IDoge30pLFxuICAgIC4uLihzdW1tYXJ5XG4gICAgICA/IHtcbiAgICAgICAgICBzdW1tYXJ5OiBzdW1tYXJ5IGFzIE5vbk51bGxhYmxlPE9wZW5BSVJlc3BvbnNlc09wdGlvbnNbXCJyZWFzb25pbmdcIl0+W1wic3VtbWFyeVwiXSxcbiAgICAgICAgfVxuICAgICAgOiB7fSksXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlcXVlc3RPcHRpb25zKHJlcTogR2VuZXJhdGVSZXF1ZXN0KTogT3BlbkFJUmVzcG9uc2VzT3B0aW9ucyB7XG4gIGNvbnN0IHsgb3V0cHV0Rm9ybWF0LCAuLi5pbWFnZUNvbnRyb2xzIH0gPSByZXEuaW1hZ2VHZW5lcmF0aW9uT3B0aW9ucyA/PyB7fTtcbiAgcmV0dXJuIHtcbiAgICBtb2RlbDogcmVxLm1vZGVsID8/IFwiXCIsXG4gICAgLi4uKHJlcS5zeXN0ZW1Qcm9tcHQgPyB7IGluc3RydWN0aW9uczogcmVxLnN5c3RlbVByb21wdCB9IDoge30pLFxuICAgIGhpc3Rvcnk6IGlucHV0SXRlbXMocmVxKSxcbiAgICAuLi4oYXNSZWFzb25pbmcocmVxKSA/IHsgcmVhc29uaW5nOiBhc1JlYXNvbmluZyhyZXEpIH0gOiB7fSksXG4gICAgLi4uKHJlcS52ZXJib3NpdHkgPyB7IHZlcmJvc2l0eTogcmVxLnZlcmJvc2l0eSBhcyBPcGVuQUlSZXNwb25zZXNPcHRpb25zW1widmVyYm9zaXR5XCJdIH0gOiB7fSksXG4gICAgLi4uKHJlcS5zZXJ2aWNlVGllclxuICAgICAgPyB7IHNlcnZpY2VUaWVyOiByZXEuc2VydmljZVRpZXIgPT09IFwiZmFzdFwiID8gXCJwcmlvcml0eVwiIDogcmVxLnNlcnZpY2VUaWVyIH1cbiAgICAgIDoge30pLFxuICAgIC4uLihyZXEucHJvbXB0Q2FjaGVLZXkgPyB7IHByb21wdENhY2hlS2V5OiByZXEucHJvbXB0Q2FjaGVLZXkgfSA6IHt9KSxcbiAgICAuLi4ocmVxLm91dHB1dFNjaGVtYSA/IHsgb3V0cHV0U2NoZW1hOiB7IHNjaGVtYTogcmVxLm91dHB1dFNjaGVtYSBhcyBKc29uVmFsdWUgfSB9IDoge30pLFxuICAgIC4uLihyZXEuaW1hZ2VHZW5lcmF0aW9uXG4gICAgICA/IHtcbiAgICAgICAgICBpbWFnZUdlbmVyYXRpb246IHJlcS5pbWFnZUdlbmVyYXRpb25PcHRpb25zXG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAuLi5pbWFnZUNvbnRyb2xzLFxuICAgICAgICAgICAgICAgIC4uLihvdXRwdXRGb3JtYXQgPyB7IG91dHB1dF9mb3JtYXQ6IG91dHB1dEZvcm1hdCB9IDoge30pLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IHRydWUsXG4gICAgICAgIH1cbiAgICAgIDoge30pLFxuICB9O1xufVxuXG4vKipcbiAqIERpcmVjdCBPcGVuQUkgZGlzcGF0Y2hlciDigJQgQW50aHJvcGljIOqzvCDrj5nsnbztlZwgc3RhdGVsZXNzIOyLpO2WiSDrqqjrjbguXG4gKlxuICog7JqU7LKtID0g7Yag7YGwIOyEoO2DnShxdW90YSBnYXRlICsgd2VpZ2h0ZWQgcm91bmQtcm9iaW4gKyBjYWNoZSBhZmZpbml0eSDshKDtmLgpIOKGkiBIVFRQUy9XU1xuICog7KCE7IahLiBwZXJtaXQv7YGQIOqwmeydgCDrj5nsi5zshLEg7IOB7ZWc7J2AIOuRkOyngCDslYrripTri6Q6IOyghOyGoeydgCBmZXRjaCDtlZwg67KI7J206528IOuhnOy7rCDsnpDsm5DsnbRcbiAqIO2drOyGjO2VmOyngCDslYrqs6AsIOyDgeulmCDsoJztlZzsnYAg67Cx7JeU65Oc7J2YIOydkeuLtSg0Mjkg65OxKeydtCDsp4Tsi6TsnbTri6QuIHdvcmtlciBwb29sIOyLnOygiOydmFxuICog7YGQIOydmOuvuOuhoChTRVJWRVJfQlVTWSwg7YGQIO2DgOyehOyVhOybgynsnYAg7J20IOyghO2ZmOycvOuhnCDsoJzqsbDrkJDri6QuXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuQUlEaXNwYXRjaGVyIGltcGxlbWVudHMgUHJvdmlkZXJEaXNwYXRjaGVyIHtcbiAgcmVhZG9ubHkgdG9rZW5NZXRhZGF0YSA9IG5ldyBNYXA8bnVtYmVyLCBUb2tlbk1ldGFkYXRhPigpO1xuICByZWFkb25seSB0cmFuc3BvcnRLaW5kOiBPcGVuQUlUcmFuc3BvcnRLaW5kO1xuICByZWFkb25seSByYXRlTGltaXRzQ2FjaGUgPSBuZXcgTWFwPG51bWJlciwgT3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhICYgeyBnZW5lcmF0aW9uOiBudW1iZXIgfT4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBwZW5kaW5nUmF0ZUxpbWl0cyA9IG5ldyBNYXA8XG4gICAgbnVtYmVyLFxuICAgIHsgdG9rZW46IFRva2VuTWV0YWRhdGE7IGdlbmVyYXRpb246IG51bWJlcjsgcHJvbWlzZTogUHJvbWlzZTxPcGVuQUlSYXRlTGltaXRzV2l0aE1ldGE+IH1cbiAgPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudHMgPSBuZXcgTWFwPG51bWJlciwgQ2xpZW50RW50cnk+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmV0aXJlZENsaWVudHMgPSBuZXcgU2V0PENsaWVudEVudHJ5PigpO1xuICBzdGF0aWMgcmVhZG9ubHkgUkFURV9MSU1JVFNfQ0FDSEVfVFRMID0gNjBfMDAwO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgc2VsZWN0b3IgPSBuZXcgU21vb3RoV2VpZ2h0ZWRSb3VuZFJvYmluKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50RmFjdG9yeTogT3BlbkFJRGlyZWN0Q2xpZW50RmFjdG9yeTtcbiAgcHJpdmF0ZSByZWFkb25seSBmZXRjaEltcGw6IHR5cGVvZiBmZXRjaDtcbiAgcHJpdmF0ZSByZWFkb25seSBxdW90YUJsb2NrZWQgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgcHJpdmF0ZSBpbkZsaWdodENvdW50ID0gMDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICB0cmFuc3BvcnRLaW5kOiBPcGVuQUlUcmFuc3BvcnRLaW5kID0gcmVzb2x2ZU9wZW5BSVRyYW5zcG9ydEtpbmQoKSxcbiAgICBkZXBlbmRlbmNpZXM6IE9wZW5BSURpc3BhdGNoZXJEZXBlbmRlbmNpZXMgPSB7fSxcbiAgKSB7XG4gICAgdGhpcy50cmFuc3BvcnRLaW5kID0gdHJhbnNwb3J0S2luZDtcbiAgICB0aGlzLmNsaWVudEZhY3RvcnkgPVxuICAgICAgZGVwZW5kZW5jaWVzLmNsaWVudEZhY3RvcnkgPz8gKChvcHRpb25zKSA9PiBuZXcgT3BlbkFJRGlyZWN0Q2xpZW50KG9wdGlvbnMpKTtcbiAgICB0aGlzLmZldGNoSW1wbCA9IGRlcGVuZGVuY2llcy5mZXRjaCA/PyBmZXRjaDtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgcm93cyB9ID0gYXdhaXQgVG9rZW5Nb2RlbC5maW5kTWFueShcIkFcIik7XG4gICAgZm9yIChjb25zdCByb3cgb2Ygcm93cykge1xuICAgICAgaWYgKHJvdy5wcm92aWRlciAhPT0gXCJvcGVuYWlcIikgY29udGludWU7XG4gICAgICB0aGlzLnNldFRva2VuKFxuICAgICAgICByb3cuaWQsXG4gICAgICAgIHJvdy5uYW1lLFxuICAgICAgICByb3cuY3JlZGVudGlhbHMgYXMgT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgICAgIHJvdy5xdW90YV90aHJlc2hvbGQsXG4gICAgICAgIHJvdy53ZWlnaHQsXG4gICAgICAgIHJvdy5hY3RpdmUsXG4gICAgICApO1xuICAgIH1cbiAgICBsb2dnZXIuaW5mbyhgc3RhcnRlZCBkaXJlY3QgT3BlbkFJIHJ1bnRpbWUgd2l0aCAke3RoaXMudG9rZW5NZXRhZGF0YS5zaXplfSB0b2tlbnNgKTtcbiAgfVxuXG4gIGFzeW5jIHN0b3AoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgZm9yIChjb25zdCB7IGNsaWVudCB9IG9mIHRoaXMuY2xpZW50cy52YWx1ZXMoKSkgY2xpZW50LmNsb3NlPy4oKTtcbiAgICB0aGlzLmNsaWVudHMuY2xlYXIoKTtcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHRoaXMucmV0aXJlZENsaWVudHMpIGVudHJ5LmNsaWVudC5jbG9zZT8uKCk7XG4gICAgdGhpcy5yZXRpcmVkQ2xpZW50cy5jbGVhcigpO1xuICAgIHRoaXMudG9rZW5NZXRhZGF0YS5jbGVhcigpO1xuICAgIHRoaXMucmF0ZUxpbWl0c0NhY2hlLmNsZWFyKCk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWQuY2xlYXIoKTtcbiAgICB0aGlzLnNlbGVjdG9yLnJlc2V0U2NvcmVzKCk7XG4gIH1cblxuICBhc3luYyBvblRva2VuQWRkZWQoXG4gICAgaWQ6IG51bWJlcixcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgIHF1b3RhVGhyZXNob2xkPzogbnVtYmVyIHwgbnVsbCxcbiAgICB3ZWlnaHQgPSAxLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnNldFRva2VuKGlkLCBuYW1lLCBjcmVkZW50aWFscywgcXVvdGFUaHJlc2hvbGQsIHdlaWdodCwgdHJ1ZSk7XG4gIH1cblxuICBhc3luYyBvblRva2VuVXBkYXRlZChcbiAgICBpZDogbnVtYmVyLFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsLFxuICAgIHdlaWdodCA9IDEsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG9sZCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoaWQpO1xuICAgIHRoaXMuc2V0VG9rZW4oaWQsIG5hbWUsIGNyZWRlbnRpYWxzLCBxdW90YVRocmVzaG9sZCwgd2VpZ2h0LCBvbGQ/LmFjdGl2ZSA/PyB0cnVlKTtcbiAgfVxuXG4gIGFzeW5jIG9uVG9rZW5SZW1vdmVkKGlkOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnJldGlyZUNsaWVudChpZCk7XG4gICAgdGhpcy50b2tlbk1ldGFkYXRhLmRlbGV0ZShpZCk7XG4gICAgdGhpcy5zZWxlY3Rvci5yZW1vdmVUb2tlbihpZCk7XG4gICAgdGhpcy5pbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKGlkKTtcbiAgICB0aGlzLnF1b3RhQmxvY2tlZC5kZWxldGUoaWQpO1xuICB9XG5cbiAgb25Ub2tlbkRlYWN0aXZhdGVkKGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoaWQpO1xuICAgIGlmICh0b2tlbikgdG9rZW4uYWN0aXZlID0gZmFsc2U7XG4gICAgdGhpcy5zZWxlY3Rvci5yZXNldFNjb3JlcygpO1xuICB9XG5cbiAgb25Ub2tlbkFjdGl2YXRlZChpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICBpZiAodG9rZW4pIHRva2VuLmFjdGl2ZSA9IHRydWU7XG4gICAgdGhpcy5zZWxlY3Rvci5yZXNldFNjb3JlcygpO1xuICB9XG5cbiAgYXN5bmMgcmVwbGFjZVRva2VucyhcbiAgICByb3dzOiBBcnJheTx7XG4gICAgICBpZDogbnVtYmVyO1xuICAgICAgbmFtZTogc3RyaW5nO1xuICAgICAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzO1xuICAgICAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsO1xuICAgICAgd2VpZ2h0OiBudW1iZXI7XG4gICAgfT4sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGlkcyA9IG5ldyBTZXQocm93cy5tYXAoKHIpID0+IHIuaWQpKTtcbiAgICBmb3IgKGNvbnN0IGlkIG9mIHRoaXMudG9rZW5NZXRhZGF0YS5rZXlzKCkpIGlmICghaWRzLmhhcyhpZCkpIGF3YWl0IHRoaXMub25Ub2tlblJlbW92ZWQoaWQpO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpXG4gICAgICBhd2FpdCB0aGlzLm9uVG9rZW5VcGRhdGVkKHJvdy5pZCwgcm93Lm5hbWUsIHJvdy5jcmVkZW50aWFscywgcm93LnF1b3RhVGhyZXNob2xkLCByb3cud2VpZ2h0KTtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlKHJlcTogR2VuZXJhdGVSZXF1ZXN0KTogUHJvbWlzZTxHZW5lcmF0ZVJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnJ1bihyZXEpO1xuICB9XG5cbiAgYXN5bmMgZ2VuZXJhdGVTdHJlYW0ocmVxOiBHZW5lcmF0ZVJlcXVlc3QsIGNiOiBHZW5lcmF0ZVN0cmVhbUNhbGxiYWNrcyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmIChyZXEuaW1hZ2VHZW5lcmF0aW9uKVxuICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFxuICAgICAgICBcImdhdGVcIixcbiAgICAgICAgXCJpbWFnZSBnZW5lcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgb24gdGhlIHN0cmVhbWluZyBwYXRoXCIsXG4gICAgICApO1xuICAgIHRyeSB7XG4gICAgICBjYi5vbkNvbXBsZXRlKGF3YWl0IHRoaXMucnVuKHJlcSwgY2Iub25EZWx0YSkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjYi5vbkVycm9yKGVycm9yIGFzIEVycm9yKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8vIGdlbmVyYXRlL2dlbmVyYXRlU3RyZWFtIOqzte2GtSDsi6Ttlokg4oCUIO2GoO2BsCDshKDtg53qs7wgaW4tZmxpZ2h0IOynkeqzhOulvCDtlZwg6rOz7JeQIOuRlOuLpC5cbiAgcHJpdmF0ZSBhc3luYyBydW4oXG4gICAgcmVxOiBHZW5lcmF0ZVJlcXVlc3QsXG4gICAgb25EZWx0YT86ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQsXG4gICk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICBjb25zdCBzaWduYWwgPSBhY3RpdmVTaWduYWwocmVxLmFib3J0U2lnbmFsLCByZXEudGltZW91dE1zKTtcbiAgICBpZiAoc2lnbmFsLmFib3J0ZWQpIHRocm93IGFib3J0RXJyb3Ioc2lnbmFsKTtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSBhd2FpdCB0aGlzLnNlbGVjdFRva2VuKFxuICAgICAgcmVxLnByZWZlcnJlZFRva2VuSWQsXG4gICAgICByZXEucmVxdWlyZVByZWZlcnJlZFRva2VuID8/IGZhbHNlLFxuICAgICAgc2lnbmFsLFxuICAgICk7XG4gICAgdGhpcy5pbkZsaWdodENvdW50Kys7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChzaWduYWwuYWJvcnRlZCkgdGhyb3cgYWJvcnRFcnJvcihzaWduYWwpO1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucnVuRGlyZWN0KHNlbGVjdGlvbiwgeyAuLi5yZXEsIGFib3J0U2lnbmFsOiBzaWduYWwgfSwgb25EZWx0YSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuaW5GbGlnaHRDb3VudC0tO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcnVuRGlyZWN0KFxuICAgIHNlbGVjdGlvbjogVG9rZW5TZWxlY3Rpb24sXG4gICAgcmVxOiBHZW5lcmF0ZVJlcXVlc3QsXG4gICAgb25EZWx0YT86ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQsXG4gICk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICBjb25zdCBzdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuICAgIGxldCBmaXJzdERlbHRhQXQ6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICBsZXQgdGV4dCA9IFwiXCI7XG4gICAgbGV0IHVzYWdlID0ge1xuICAgICAgdG90YWxUb2tlbnM6IDAsXG4gICAgICBpbnB1dFRva2VuczogMCxcbiAgICAgIG91dHB1dFRva2VuczogMCxcbiAgICAgIGNhY2hlZElucHV0VG9rZW5zOiAwLFxuICAgICAgcmVhc29uaW5nT3V0cHV0VG9rZW5zOiAwLFxuICAgIH07XG4gICAgY29uc3QgaW1hZ2VzOiBHZW5lcmF0ZWRJbWFnZVtdID0gW107XG4gICAgbGV0IGltYWdlQXR0ZW1wdGVkID0gZmFsc2U7XG4gICAgbGV0IHNlcnZpbmdNb2RlbCA9IHJlcS5tb2RlbCA/PyBcIlwiO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gc2VsZWN0aW9uLm1ldGFkYXRhO1xuICAgIGNvbnN0IGNsaWVudEVudHJ5ID0gdGhpcy5hY3F1aXJlQ2xpZW50KHNlbGVjdGlvbik7XG4gICAgdHJ5IHtcbiAgICAgIGZvciBhd2FpdCAoY29uc3QgZXZlbnQgb2YgY2xpZW50RW50cnkuY2xpZW50LnJlc3BvbnNlcyhcbiAgICAgICAgcmVxdWVzdE9wdGlvbnMocmVxKSxcbiAgICAgICAgcmVxLmFib3J0U2lnbmFsLFxuICAgICAgKSkge1xuICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJ0ZXh0LWRlbHRhXCIpIHtcbiAgICAgICAgICBmaXJzdERlbHRhQXQgPz89IERhdGUubm93KCk7XG4gICAgICAgICAgdGV4dCArPSBldmVudC50ZXh0O1xuICAgICAgICAgIG9uRGVsdGE/LihldmVudC50ZXh0KTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSBcImltYWdlXCIpIHtcbiAgICAgICAgICBpbWFnZUF0dGVtcHRlZCA9IHRydWU7XG4gICAgICAgICAgaW1hZ2VzLnB1c2goe1xuICAgICAgICAgICAgZGF0YTogZXZlbnQuYmFzZTY0LFxuICAgICAgICAgICAgbWVkaWFUeXBlOiBldmVudC5taW1lVHlwZSxcbiAgICAgICAgICAgIHJldmlzZWRQcm9tcHQ6IGV2ZW50LnJldmlzZWRQcm9tcHQgPz8gbnVsbCxcbiAgICAgICAgICAgIC4uLihldmVudC5nZW5lcmF0aW9uID8geyBnZW5lcmF0aW9uOiBldmVudC5nZW5lcmF0aW9uIH0gOiB7fSksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gXCJvdXRwdXQtaXRlbVwiICYmIGV2ZW50Lml0ZW0udHlwZSA9PT0gXCJpbWFnZV9nZW5lcmF0aW9uX2NhbGxcIikge1xuICAgICAgICAgIGltYWdlQXR0ZW1wdGVkID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSBcImNvbXBsZXRlZFwiICYmIGV2ZW50LnVzYWdlKSB7XG4gICAgICAgICAgc2VydmluZ01vZGVsID0gZXZlbnQubW9kZWwgPz8gc2VydmluZ01vZGVsO1xuICAgICAgICAgIHVzYWdlID0ge1xuICAgICAgICAgICAgdG90YWxUb2tlbnM6IGV2ZW50LnVzYWdlLnRvdGFsVG9rZW5zLFxuICAgICAgICAgICAgaW5wdXRUb2tlbnM6IGV2ZW50LnVzYWdlLmlucHV0VG9rZW5zLFxuICAgICAgICAgICAgb3V0cHV0VG9rZW5zOiBldmVudC51c2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICBjYWNoZWRJbnB1dFRva2VuczogZXZlbnQudXNhZ2UuY2FjaGVkSW5wdXRUb2tlbnMsXG4gICAgICAgICAgICByZWFzb25pbmdPdXRwdXRUb2tlbnM6IGV2ZW50LnVzYWdlLnJlYXNvbmluZ1Rva2VucyxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwiY29tcGxldGVkXCIpIHtcbiAgICAgICAgICBzZXJ2aW5nTW9kZWwgPSBldmVudC5tb2RlbCA/PyBzZXJ2aW5nTW9kZWw7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gXCJlcnJvclwiKSB7XG4gICAgICAgICAgaWYgKHJlcS5pbWFnZUdlbmVyYXRpb24pXG4gICAgICAgICAgICB0aHJvdyBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXCJpbmNvbXBsZXRlXCIsIGV2ZW50LmVycm9yLm1lc3NhZ2UpO1xuICAgICAgICAgIHRocm93IGV2ZW50LmVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMucmVsZWFzZUNsaWVudChjbGllbnRFbnRyeSk7XG4gICAgfVxuICAgIGlmIChyZXEuaW1hZ2VHZW5lcmF0aW9uICYmIGltYWdlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcbiAgICAgICAgaW1hZ2VBdHRlbXB0ZWQgPyBcImluY29tcGxldGVcIiA6IFwibm90X2NhbGxlZFwiLFxuICAgICAgICBpbWFnZUF0dGVtcHRlZFxuICAgICAgICAgID8gXCJpbWFnZSBnZW5lcmF0aW9uIGRpZCBub3QgY29tcGxldGVcIlxuICAgICAgICAgIDogXCJtb2RlbCBkaWQgbm90IGNhbGwgaW1hZ2UgZ2VuZXJhdGlvblwiLFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHRleHQsXG4gICAgICB0b2tlbk5hbWU6IG1ldGFkYXRhLm5hbWUsXG4gICAgICB1c2FnZSxcbiAgICAgIGR1cmF0aW9uTXM6IERhdGUubm93KCkgLSBzdGFydGVkQXQsXG4gICAgICB0dGZ0TXM6IGZpcnN0RGVsdGFBdCA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGZpcnN0RGVsdGFBdCAtIHN0YXJ0ZWRBdCxcbiAgICAgIG1vZGVsOiBzZXJ2aW5nTW9kZWwsXG4gICAgICAuLi4oc2VydmluZ01vZGVsICE9PSByZXEubW9kZWwgPyB7IHJlcXVlc3RlZE1vZGVsOiByZXEubW9kZWwgfSA6IHt9KSxcbiAgICAgIHRocmVhZENvb3JkOiB7IHdvcmtlcklkOiBzZWxlY3Rpb24udG9rZW5JZCwgdGhyZWFkSWQ6IHJlcS5wcm9tcHRDYWNoZUtleSA/PyBcIlwiLCBlcG9jaDogLTEgfSxcbiAgICAgIC4uLihpbWFnZXMubGVuZ3RoID8geyBpbWFnZXMgfSA6IHt9KSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIOyEuOuMgOqwgCDrsJTrgJAgY2xpZW50IOuKlCDsgqzsmqkg7KSR7J24IOyalOyyreydtCDrgZ3rgpwg65Kk7JeQIOuLq+uKlOuLpC4gKi9cbiAgcHJpdmF0ZSBhY3F1aXJlQ2xpZW50KHNlbGVjdGlvbjogVG9rZW5TZWxlY3Rpb24pOiBDbGllbnRFbnRyeSB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBzZWxlY3Rpb24ubWV0YWRhdGE7XG4gICAgbGV0IGVudHJ5ID0gdGhpcy5jbGllbnRzLmdldChzZWxlY3Rpb24udG9rZW5JZCk7XG4gICAgaWYgKGVudHJ5ICYmIGVudHJ5LmdlbmVyYXRpb24gIT09IG1ldGFkYXRhLmdlbmVyYXRpb24pIHtcbiAgICAgIHRoaXMucmV0aXJlQ2xpZW50KHNlbGVjdGlvbi50b2tlbklkKTtcbiAgICAgIGVudHJ5ID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBpZiAoIWVudHJ5KSB7XG4gICAgICBjb25zdCBjbGllbnQgPSB0aGlzLmNsaWVudEZhY3RvcnkoXG4gICAgICAgIHtcbiAgICAgICAgICBjcmVkZW50aWFsczoge1xuICAgICAgICAgICAgYWNjZXNzVG9rZW46IG1ldGFkYXRhLmNyZWRlbnRpYWxzLmFjY2Vzc1Rva2VuLFxuICAgICAgICAgICAgYWNjb3VudElkOiBtZXRhZGF0YS5jcmVkZW50aWFscy5hY2NvdW50SWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0cmFuc3BvcnRLaW5kOiB0aGlzLnRyYW5zcG9ydEtpbmQsXG4gICAgICAgICAgZmV0Y2g6IHRoaXMuZmV0Y2hJbXBsLFxuICAgICAgICAgIHJlZnJlc2hDcmVkZW50aWFsczogKCkgPT4gdGhpcy5yZWZyZXNoQ3JlZGVudGlhbHMoc2VsZWN0aW9uLnRva2VuSWQpLFxuICAgICAgICB9LFxuICAgICAgICBzZWxlY3Rpb24udG9rZW5JZCxcbiAgICAgICk7XG4gICAgICBlbnRyeSA9IHsgZ2VuZXJhdGlvbjogbWV0YWRhdGEuZ2VuZXJhdGlvbiwgY2xpZW50LCBpbkZsaWdodDogMCwgcmV0aXJlZDogZmFsc2UgfTtcbiAgICAgIHRoaXMuY2xpZW50cy5zZXQoc2VsZWN0aW9uLnRva2VuSWQsIGVudHJ5KTtcbiAgICB9XG4gICAgZW50cnkuaW5GbGlnaHQrKztcbiAgICByZXR1cm4gZW50cnk7XG4gIH1cblxuICBwcml2YXRlIHJlbGVhc2VDbGllbnQoZW50cnk6IENsaWVudEVudHJ5KTogdm9pZCB7XG4gICAgZW50cnkuaW5GbGlnaHQgPSBNYXRoLm1heCgwLCBlbnRyeS5pbkZsaWdodCAtIDEpO1xuICAgIGlmIChlbnRyeS5yZXRpcmVkICYmIGVudHJ5LmluRmxpZ2h0ID09PSAwKSB7XG4gICAgICB0aGlzLnJldGlyZWRDbGllbnRzLmRlbGV0ZShlbnRyeSk7XG4gICAgICBlbnRyeS5jbGllbnQuY2xvc2U/LigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBtYXAg7JeQ7IScIOuWvOyWtOuCtOqzoCwg7KeE7ZaJIOykkeyduCDsmpTssq3snbQg7JeG7J2EIOuVjOunjCDsponsi5wg64ur64qU64ukLiAqL1xuICBwcml2YXRlIHJldGlyZUNsaWVudCh0b2tlbklkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBlbnRyeSA9IHRoaXMuY2xpZW50cy5nZXQodG9rZW5JZCk7XG4gICAgaWYgKCFlbnRyeSkgcmV0dXJuO1xuICAgIHRoaXMuY2xpZW50cy5kZWxldGUodG9rZW5JZCk7XG4gICAgZW50cnkucmV0aXJlZCA9IHRydWU7XG4gICAgaWYgKGVudHJ5LmluRmxpZ2h0ID09PSAwKSBlbnRyeS5jbGllbnQuY2xvc2U/LigpO1xuICAgIGVsc2UgdGhpcy5yZXRpcmVkQ2xpZW50cy5hZGQoZW50cnkpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2GoO2BsCDshKDtg50g4oCUIHF1b3RhIGdhdGUg66W8IO2GteqzvO2VnCBhY3RpdmUg7Yag7YGwIOykkeyXkOyEnCDqs6Drpbjri6QuIGNhY2hlIGFmZmluaXR5IOyEoO2YuFxuICAgKiDthqDtgbDsnbQgZWxpZ2libGUg7ZWY66m0IOq3uCDtjJDsoJXrp4zsnLzroZwg7KaJ7IucIOqysOygle2VmOqzoCjsoITssrQgc3dlZXAg7IOd6561LCB3ZWlnaHRlZCDsg4Htg5xcbiAgICog67mE67OA6rK9KSwg7JWE64uI66m0IOuzkeugrCBxdW90YSDtjJDsoJUg7ZuEIHNtb290aCB3ZWlnaHRlZCByb3VuZC1yb2Jpbi4g64+Z7Iuc7ISxIOyDge2VnOydtFxuICAgKiDsl4bsnLzrr4DroZwgXCLruYgg7J6Q66asXCIg6rCc64WQ64+EIOyXhuuLpCDigJQg7ISg7YOdIOymieyLnCDsi6TtlonsnbTri6QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHNlbGVjdFRva2VuKFxuICAgIHByZWZlcnJlZFRva2VuSWQ6IG51bWJlciB8IHVuZGVmaW5lZCxcbiAgICByZXF1aXJlUHJlZmVycmVkVG9rZW46IGJvb2xlYW4sXG4gICAgc2lnbmFsOiBBYm9ydFNpZ25hbCxcbiAgKTogUHJvbWlzZTxUb2tlblNlbGVjdGlvbj4ge1xuICAgIGlmIChwcmVmZXJyZWRUb2tlbklkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IHByZWZlcnJlZCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQocHJlZmVycmVkVG9rZW5JZCk7XG4gICAgICBpZiAocHJlZmVycmVkPy5hY3RpdmUgJiYgKGF3YWl0IHRoaXMuaXNRdW90YUVsaWdpYmxlKHByZWZlcnJlZFRva2VuSWQsIHByZWZlcnJlZCwgc2lnbmFsKSkpIHtcbiAgICAgICAgcmV0dXJuIHsgdG9rZW5JZDogcHJlZmVycmVkVG9rZW5JZCwgbWV0YWRhdGE6IHByZWZlcnJlZCB9O1xuICAgICAgfVxuICAgICAgaWYgKHJlcXVpcmVQcmVmZXJyZWRUb2tlbikge1xuICAgICAgICBpZiAoIXByZWZlcnJlZD8uYWN0aXZlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQcmVmZXJyZWQgb3BlbmFpIHRva2VuICR7cHJlZmVycmVkVG9rZW5JZH0gaXMgbm90IGF2YWlsYWJsZWApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRocmVzaG9sZCA9IHByZWZlcnJlZC5xdW90YVRocmVzaG9sZDtcbiAgICAgICAgaWYgKHRocmVzaG9sZCAhPT0gbnVsbCAmJiB0aHJlc2hvbGQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBRdW90YVRocmVzaG9sZEV4Y2VlZGVkRXJyb3IoXG4gICAgICAgICAgICBxdW90YU1lc3NhZ2UoW3sgbmFtZTogcHJlZmVycmVkLm5hbWUsIHRocmVzaG9sZCB9XSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIO2GoO2BsOuzhCBxdW90YSDtjJDsoJXsnYAg7ISc66GcIOuPheumveydtOudvCDrs5HroKzroZwg4oCUIOyngeugrCDrjIDquLDripQg7L2c65OcIOy6kOyLnOyXkOyEnFxuICAgIC8vIO2GoO2BsCDsiJggw5cg7KGw7ZqMIOyngOyXsOunjO2BvCDsmpTssq0g7Iuc7J6R7J2EIOuKpuy2mOuLpC5cbiAgICBjb25zdCBjaGVja3MgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIFsuLi50aGlzLnRva2VuTWV0YWRhdGEuZW50cmllcygpXVxuICAgICAgICAuZmlsdGVyKChbLCB0b2tlbl0pID0+IHRva2VuLmFjdGl2ZSlcbiAgICAgICAgLm1hcChhc3luYyAoW2lkLCB0b2tlbl0pID0+ICh7XG4gICAgICAgICAgaWQsXG4gICAgICAgICAgdG9rZW4sXG4gICAgICAgICAgZWxpZ2libGU6IGF3YWl0IHRoaXMuaXNRdW90YUVsaWdpYmxlKGlkLCB0b2tlbiwgc2lnbmFsKSxcbiAgICAgICAgfSkpLFxuICAgICk7XG4gICAgY29uc3QgZWxpZ2libGUgPSBuZXcgU2V0KGNoZWNrcy5maWx0ZXIoKGMpID0+IGMuZWxpZ2libGUpLm1hcCgoYykgPT4gYy5pZCkpO1xuICAgIGlmIChlbGlnaWJsZS5zaXplID09PSAwKSB7XG4gICAgICBjb25zdCBvdmVyID0gY2hlY2tzXG4gICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgKGMpID0+XG4gICAgICAgICAgICAhYy5lbGlnaWJsZSAmJiBjLnRva2VuLnF1b3RhVGhyZXNob2xkICE9PSBudWxsICYmIGMudG9rZW4ucXVvdGFUaHJlc2hvbGQgIT09IHVuZGVmaW5lZCxcbiAgICAgICAgKVxuICAgICAgICAubWFwKChjKSA9PiAoeyBuYW1lOiBjLnRva2VuLm5hbWUsIHRocmVzaG9sZDogYy50b2tlbi5xdW90YVRocmVzaG9sZCBhcyBudW1iZXIgfSkpO1xuICAgICAgaWYgKG92ZXIubGVuZ3RoKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKFwicXVvdGFfdGhyZXNob2xkIGdhdGU6IGFsbF9leGNlZWRlZFwiLCB7XG4gICAgICAgICAgcHJvdmlkZXI6IFwib3BlbmFpXCIsXG4gICAgICAgICAgb3ZlclRocmVzaG9sZFRva2Vuczogb3ZlcixcbiAgICAgICAgfSk7XG4gICAgICAgIHRocm93IG5ldyBRdW90YVRocmVzaG9sZEV4Y2VlZGVkRXJyb3IocXVvdGFNZXNzYWdlKG92ZXIpKTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5PX09QRU5BSV9XT1JLRVJTXCIpO1xuICAgIH1cbiAgICBjb25zdCBzZWxlY3RlZCA9IHRoaXMuc2VsZWN0b3Iuc2VsZWN0KGVsaWdpYmxlKTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHNlbGVjdGVkICE9PSBudWxsID8gdGhpcy50b2tlbk1ldGFkYXRhLmdldChzZWxlY3RlZCkgOiB1bmRlZmluZWQ7XG4gICAgaWYgKHNlbGVjdGVkID09PSBudWxsIHx8ICFtZXRhZGF0YSkgdGhyb3cgbmV3IEVycm9yKFwiTk9fT1BFTkFJX1dPUktFUlNcIik7XG4gICAgcmV0dXJuIHsgdG9rZW5JZDogc2VsZWN0ZWQsIG1ldGFkYXRhIH07XG4gIH1cblxuICBwcml2YXRlIHNldFRva2VuKFxuICAgIGlkOiBudW1iZXIsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscyxcbiAgICBxdW90YVRocmVzaG9sZDogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgICB3ZWlnaHQ6IG51bWJlcixcbiAgICBhY3RpdmU6IGJvb2xlYW4sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IG9sZCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoaWQpO1xuICAgIGlmIChvbGQpIHtcbiAgICAgIE9iamVjdC5hc3NpZ24ob2xkLCB7XG4gICAgICAgIG5hbWUsXG4gICAgICAgIGNyZWRlbnRpYWxzLFxuICAgICAgICBxdW90YVRocmVzaG9sZCxcbiAgICAgICAgd2VpZ2h0LFxuICAgICAgICBhY3RpdmUsXG4gICAgICAgIGdlbmVyYXRpb246IG9sZC5nZW5lcmF0aW9uICsgMSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRva2VuTWV0YWRhdGEuc2V0KGlkLCB7XG4gICAgICAgIG5hbWUsXG4gICAgICAgIGNyZWRlbnRpYWxzLFxuICAgICAgICBxdW90YVRocmVzaG9sZCxcbiAgICAgICAgd2VpZ2h0LFxuICAgICAgICBhY3RpdmUsXG4gICAgICAgIGdlbmVyYXRpb246IDEsXG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5zZWxlY3Rvci5zZXRUb2tlbihpZCwgd2VpZ2h0KTtcbiAgICB0aGlzLmludmFsaWRhdGVSYXRlTGltaXRzQ2FjaGUoaWQpO1xuICAgIHRoaXMucXVvdGFCbG9ja2VkLmRlbGV0ZShpZCk7XG4gIH1cblxuICBhc3luYyBnZXRSYXRlTGltaXRzQnlUb2tlbklkKFxuICAgIHRva2VuSWQ6IG51bWJlcixcbiAgICBzaWduYWw/OiBBYm9ydFNpZ25hbCxcbiAgKTogUHJvbWlzZTxPcGVuQUlSYXRlTGltaXRzV2l0aE1ldGE+IHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCk7XG4gICAgaWYgKCF0b2tlbikgdGhyb3cgbmV3IEVycm9yKGBvcGVuYWkgdG9rZW4gJHt0b2tlbklkfSBub3QgZm91bmRgKTtcbiAgICBjb25zdCBnZW5lcmF0aW9uID0gdG9rZW4uZ2VuZXJhdGlvbjtcbiAgICBjb25zdCBjYWNoZWQgPSB0aGlzLnJhdGVMaW1pdHNDYWNoZS5nZXQodG9rZW5JZCk7XG4gICAgaWYgKFxuICAgICAgY2FjaGVkICYmXG4gICAgICBjYWNoZWQuZ2VuZXJhdGlvbiA9PT0gdG9rZW4uZ2VuZXJhdGlvbiAmJlxuICAgICAgRGF0ZS5ub3coKSAtIGNhY2hlZC5jYWNoZWRBdCA8IE9wZW5BSURpc3BhdGNoZXIuUkFURV9MSU1JVFNfQ0FDSEVfVFRMXG4gICAgKVxuICAgICAgcmV0dXJuIGNhY2hlZDtcblxuICAgIC8vIHNpbmdsZS1mbGlnaHQ6IOuPmeyLnOyEsSDsg4HtlZzsnbQg7JeG7Ja07KeEIOuSpOuhnCBUVEwg66eM66OMIOyInOqwhCDrj5nsi5wg7JqU7LKtIOyImOunjO2BvCDqsJnsnYBcbiAgICAvLyDsobDtmozqsIAg66qw66a0IOyImCDsnojri6Qg4oCUIOynhO2WiSDspJHsnbggZmV0Y2gg66W8IOqzteycoO2VnOuLpC4g7LWc7LSIIO2YuOy2nOyekOydmCBhYm9ydCDroZxcbiAgICAvLyDqs7XsnKAg7KGw7ZqM6rCAIOyLpO2MqO2VtOuPhCDshozruYTsspgoaXNRdW90YUVsaWdpYmxlKeqwgCBmYWlsLW9wZW4g7Jy866GcIOyymOumrO2VnOuLpC5cbiAgICBjb25zdCBwZW5kaW5nID0gdGhpcy5wZW5kaW5nUmF0ZUxpbWl0cy5nZXQodG9rZW5JZCk7XG4gICAgaWYgKHBlbmRpbmc/LnRva2VuID09PSB0b2tlbiAmJiBwZW5kaW5nLmdlbmVyYXRpb24gPT09IGdlbmVyYXRpb24pIHJldHVybiBwZW5kaW5nLnByb21pc2U7XG4gICAgY29uc3QgZmV0Y2hQcm9taXNlID0gKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlYWRPcGVuQUlRdW90YVVzYWdlKHtcbiAgICAgICAgY3JlZGVudGlhbHM6IHRva2VuLmNyZWRlbnRpYWxzLFxuICAgICAgICByZWZyZXNoQ3JlZGVudGlhbHM6ICgpID0+IHRoaXMucmVmcmVzaENyZWRlbnRpYWxzKHRva2VuSWQpLFxuICAgICAgICBmZXRjaDogdGhpcy5mZXRjaEltcGwsXG4gICAgICAgIC4uLihzaWduYWwgPyB7IHNpZ25hbCB9IDoge30pLFxuICAgICAgfSk7XG4gICAgICBpZiAocmVzdWx0LmtpbmQgPT09IFwibG9va3VwX2ZhaWxlZFwiKSB0aHJvdyBuZXcgRXJyb3IocmVzdWx0LnJlYXNvbik7XG4gICAgICBpZiAoIXJlc3VsdC5yYXcpIHRocm93IG5ldyBFcnJvcihcIk9wZW5BSSBxdW90YSByZXNwb25zZSBtaXNzaW5nIHJhdyByYXRlIGxpbWl0c1wiKTtcbiAgICAgIGNvbnN0IGVudHJ5ID0geyBkYXRhOiByZXN1bHQucmF3LCBjYWNoZWRBdDogRGF0ZS5ub3coKSwgZ2VuZXJhdGlvbiB9O1xuICAgICAgaWYgKHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCkgPT09IHRva2VuICYmIHRva2VuLmdlbmVyYXRpb24gPT09IGdlbmVyYXRpb24pIHtcbiAgICAgICAgdGhpcy5yYXRlTGltaXRzQ2FjaGUuc2V0KHRva2VuSWQsIGVudHJ5KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBlbnRyeTtcbiAgICB9KSgpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMucGVuZGluZ1JhdGVMaW1pdHMuZ2V0KHRva2VuSWQpPy5wcm9taXNlID09PSBmZXRjaFByb21pc2UpIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nUmF0ZUxpbWl0cy5kZWxldGUodG9rZW5JZCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5wZW5kaW5nUmF0ZUxpbWl0cy5zZXQodG9rZW5JZCwgeyB0b2tlbiwgZ2VuZXJhdGlvbiwgcHJvbWlzZTogZmV0Y2hQcm9taXNlIH0pO1xuICAgIHJldHVybiBmZXRjaFByb21pc2U7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlZnJlc2hDcmVkZW50aWFscyh0b2tlbklkOiBudW1iZXIpIHtcbiAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCk7XG4gICAgY29uc3QgZ2VuZXJhdGlvbiA9IHByZXZpb3VzPy5nZW5lcmF0aW9uO1xuICAgIGNvbnN0IHJlZnJlc2hlZCA9IGF3YWl0IGhhbmRsZUNoYXRncHRBdXRoVG9rZW5zUmVmcmVzaCh0b2tlbklkKTtcbiAgICBjb25zdCBjcmVkZW50aWFscyA9IHtcbiAgICAgIGFjY2Vzc1Rva2VuOiByZWZyZXNoZWQuYWNjZXNzVG9rZW4sXG4gICAgICBhY2NvdW50SWQ6IHJlZnJlc2hlZC5jaGF0Z3B0QWNjb3VudElkLFxuICAgIH07XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCk7XG4gICAgaWYgKCFjdXJyZW50Py5hY3RpdmUpIHRocm93IG5ldyBFcnJvcihgb3BlbmFpIHRva2VuICR7dG9rZW5JZH0gaXMgbm8gbG9uZ2VyIGFjdGl2ZWApO1xuICAgIC8vIEEgc3Vic2NyaWJlciB1cGRhdGUgbWF5IGFscmVhZHkgY29udGFpbiBuZXdlciBjcmVkZW50aWFscy4gTmV2ZXIgb3ZlcndyaXRlIGl0XG4gICAgLy8gd2l0aCB0aGUgcmVzdWx0IG9mIGEgcmVmcmVzaCB0aGF0IHN0YXJ0ZWQgYWdhaW5zdCBhbiBvbGRlciBnZW5lcmF0aW9uLlxuICAgIGlmIChjdXJyZW50ID09PSBwcmV2aW91cyAmJiBjdXJyZW50LmdlbmVyYXRpb24gPT09IGdlbmVyYXRpb24pIHtcbiAgICAgIGN1cnJlbnQuY3JlZGVudGlhbHMgPSB7IC4uLmN1cnJlbnQuY3JlZGVudGlhbHMsIC4uLmNyZWRlbnRpYWxzIH07XG4gICAgICB0aGlzLnJldGlyZUNsaWVudCh0b2tlbklkKTtcbiAgICAgIHRoaXMuaW52YWxpZGF0ZVJhdGVMaW1pdHNDYWNoZSh0b2tlbklkKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGFjY2Vzc1Rva2VuOiBjdXJyZW50LmNyZWRlbnRpYWxzLmFjY2Vzc1Rva2VuLFxuICAgICAgYWNjb3VudElkOiBjdXJyZW50LmNyZWRlbnRpYWxzLmFjY291bnRJZCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBpc1F1b3RhRWxpZ2libGUoXG4gICAgaWQ6IG51bWJlcixcbiAgICB0b2tlbjogVG9rZW5NZXRhZGF0YSxcbiAgICBzaWduYWw/OiBBYm9ydFNpZ25hbCxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKHRva2VuLnF1b3RhVGhyZXNob2xkID09PSBudWxsIHx8IHRva2VuLnF1b3RhVGhyZXNob2xkID09PSB1bmRlZmluZWQpIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IGdlbmVyYXRpb24gPSB0b2tlbi5nZW5lcmF0aW9uO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlYWRPcGVuQUlRdW90YVVzYWdlKGFzeW5jICgpID0+IHRoaXMuZ2V0UmF0ZUxpbWl0c0J5VG9rZW5JZChpZCwgc2lnbmFsKSk7XG4gICAgaWYgKHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoaWQpICE9PSB0b2tlbiB8fCB0b2tlbi5nZW5lcmF0aW9uICE9PSBnZW5lcmF0aW9uKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHJlc3VsdC5raW5kID09PSBcImxvb2t1cF9mYWlsZWRcIikge1xuICAgICAgdGhpcy5xdW90YUJsb2NrZWQuZGVsZXRlKGlkKTtcbiAgICAgIGxvZ2dlci53YXJuKFwicXVvdGFfdGhyZXNob2xkIGdhdGU6IGxvb2t1cF9mYWlsX29wZW5cIiwge1xuICAgICAgICB0b2tlbklkOiBpZCxcbiAgICAgICAgdG9rZW5OYW1lOiB0b2tlbi5uYW1lLFxuICAgICAgICBsb29rdXBSZWFzb246IHJlc3VsdC5yZWFzb24sXG4gICAgICB9KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAocmVzdWx0LnV0aWxpemF0aW9uUGN0ID49IHRva2VuLnF1b3RhVGhyZXNob2xkKSB7XG4gICAgICBpZiAoIXRoaXMucXVvdGFCbG9ja2VkLmhhcyhpZCkpXG4gICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgIGBxdW90YV90aHJlc2hvbGQgZ2F0ZTogb3Zlcl90aHJlc2hvbGQgJHt0b2tlbi5uYW1lfVske2lkfV0gKCR7cmVzdWx0LnV0aWxpemF0aW9uUGN0fSUgPj0gJHt0b2tlbi5xdW90YVRocmVzaG9sZH0lKWAsXG4gICAgICAgICk7XG4gICAgICB0aGlzLnF1b3RhQmxvY2tlZC5hZGQoaWQpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodGhpcy5xdW90YUJsb2NrZWQuZGVsZXRlKGlkKSlcbiAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICBgcXVvdGFfdGhyZXNob2xkIGdhdGU6IHJlY292ZXJlZCAke3Rva2VuLm5hbWV9WyR7aWR9XSAoJHtyZXN1bHQudXRpbGl6YXRpb25QY3R9JSA8ICR7dG9rZW4ucXVvdGFUaHJlc2hvbGR9JSlgLFxuICAgICAgKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgaW52YWxpZGF0ZVJhdGVMaW1pdHNDYWNoZShpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5yYXRlTGltaXRzQ2FjaGUuZGVsZXRlKGlkKTtcbiAgfVxuXG4gIGdldCB0b2tlbkNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIFsuLi50aGlzLnRva2VuTWV0YWRhdGEudmFsdWVzKCldLmZpbHRlcigodCkgPT4gdC5hY3RpdmUpLmxlbmd0aDtcbiAgfVxuICBnZXQgaW5GbGlnaHQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5pbkZsaWdodENvdW50O1xuICB9XG5cbiAgLyoqXG4gICAqIO2GoO2BsOuzhCDsv7zthLAg7Iqk64OF7IO3IOKAlCDsi6DshKDtlZwocmF0ZSBsaW1pdHMgVFRMIOuCtCkg7LqQ7Iuc66eMIOydveqzoCDsoIjrjIAgZmV0Y2gg7ZWY7KeAIOyViuuKlOuLpC5cbiAgICogbW9uaXQgdml0YWxzIOuKlCDroZzqt7gg7Y+066eB7JeQIO2OuOyKue2VmOuKlCDqsJLsnbTrnbwg7Jes6riw7IScIOuEpO2KuOybjO2BrOulvCDtg4DrqbQg7JWIIOuQnOuLpC5cbiAgICogdGhyZXNob2xkIOuvuOyEpOyglSDthqDtgbDsnYAg7L+87YSwIO2MkOygleydhCDrj4zsp4Ag7JWK7JWEIHVzZWRQZXJjZW50IOqwgCBudWxsIOuhnCDrgqjsnYQg7IiYIOyeiOuLpC5cbiAgICovXG4gIGdldCBxdW90YUJ5VG9rZW4oKTogQXJyYXk8e1xuICAgIG5hbWU6IHN0cmluZztcbiAgICB1c2VkUGVyY2VudDogbnVtYmVyIHwgbnVsbDtcbiAgICB0aHJlc2hvbGQ6IG51bWJlciB8IG51bGw7XG4gICAgYmxvY2tlZDogYm9vbGVhbjtcbiAgICByZXNldHNBdDogbnVtYmVyIHwgbnVsbDtcbiAgfT4ge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIFsuLi50aGlzLnRva2VuTWV0YWRhdGEuZW50cmllcygpXVxuICAgICAgLm1hcCgoW2lkLCB0XSkgPT4ge1xuICAgICAgICBjb25zdCBjYWNoZWQgPSB0aGlzLnJhdGVMaW1pdHNDYWNoZS5nZXQoaWQpO1xuICAgICAgICBjb25zdCBmcmVzaCA9XG4gICAgICAgICAgY2FjaGVkICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICBjYWNoZWQuZ2VuZXJhdGlvbiA9PT0gdC5nZW5lcmF0aW9uICYmXG4gICAgICAgICAgbm93IC0gY2FjaGVkLmNhY2hlZEF0IDwgT3BlbkFJRGlzcGF0Y2hlci5SQVRFX0xJTUlUU19DQUNIRV9UVEw7XG4gICAgICAgIGNvbnN0IHByaW1hcnkgPSBmcmVzaCA/IGNhY2hlZC5kYXRhLnJhdGVMaW1pdHM/LnByaW1hcnkgOiB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbmFtZTogdC5uYW1lLFxuICAgICAgICAgIHVzZWRQZXJjZW50OiBwcmltYXJ5Py51c2VkUGVyY2VudCA/PyBudWxsLFxuICAgICAgICAgIHRocmVzaG9sZDogdC5xdW90YVRocmVzaG9sZCA/PyBudWxsLFxuICAgICAgICAgIGJsb2NrZWQ6IHRoaXMucXVvdGFCbG9ja2VkLmhhcyhpZCksXG4gICAgICAgICAgLy8gd2hhbSDsnZggcmVzZXRzQXQg7J2AIHVuaXgg7LSIIOuLqOychOuLpChxZ3JpZC5mcmFtZSB1bml4U2Vjb25kc1RvSXNvIOyZgCDrj5nsnbwg6rec7JW9KS5cbiAgICAgICAgICAvLyDshozruYTsspjqsIAg64uo7JyE66W8IOy2lOy4oe2VmOyngCDslYrrj4TroZ0g7Jes6riw7IScIG1zIGVwb2NoIOycvOuhnCDsoJXqt5ztmZTtlZzri6QuXG4gICAgICAgICAgcmVzZXRzQXQ6XG4gICAgICAgICAgICBwcmltYXJ5Py5yZXNldHNBdCAhPT0gbnVsbCAmJiBwcmltYXJ5Py5yZXNldHNBdCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgID8gcHJpbWFyeS5yZXNldHNBdCAqIDEwMDBcbiAgICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICB9O1xuICAgICAgfSlcbiAgICAgIC50b1NvcnRlZCgoYSwgYikgPT4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKSk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQXdCQSxNQUFNLFNBQVMsVUFBVSxDQUFDLFNBQVMsbUJBQW1CLENBQUM7QUFHdkQsTUFBTSw2QkFBNkI7QUFJbkMsSUFBYSx1QkFBYixjQUEwQyxNQUFNO0NBRW5DO0NBRFgsWUFDRSxNQUNBLFNBQ0E7RUFDQSxNQUFNLE9BQU87RUFISixLQUFBLE9BQUE7RUFJVCxLQUFLLE9BQU87Q0FDZDtBQUNGO0FBOEJBLFNBQVMsV0FBVyxRQUE0QjtDQUM5QyxNQUFNLFNBQVMsT0FBTztDQUN0QixPQUFPLGtCQUFrQixRQUFRLFNBQVMsSUFBSSxhQUFhLFdBQVcsWUFBWTtBQUNwRjtBQUVBLFNBQVMsYUFBYSxRQUFzQixXQUFpQztDQUMzRSxNQUFNLFVBQVUsWUFBWSxRQUFRLGFBQWEsMEJBQTBCO0NBQzNFLE9BQU8sU0FBUyxZQUFZLElBQUksQ0FBQyxRQUFRLE9BQU8sQ0FBQyxJQUFJO0FBQ3ZEO0FBRUEsU0FBUyxhQUFhLFNBQTZEO0NBQ2pGLE1BQU0sU0FBUyxRQUFRLEtBQUssTUFBTSxHQUFHLEVBQUUsS0FBSyxjQUFjLEVBQUUsVUFBVSxHQUFHLENBQUMsQ0FBQyxLQUFLLElBQUk7Q0FDcEYsT0FBTyxTQUNILCtDQUErQyxXQUMvQztBQUNOO0FBRUEsU0FBUyxXQUFXLEtBQTRDO0NBQzlELE1BQU0sVUFBVyxJQUFJLGVBQWUsQ0FBQztDQUNyQyxNQUFNLFVBQWdDLElBQUksVUFBVSxLQUFLLFVBQVU7RUFDakUsSUFBSSxNQUFNLFNBQVMsUUFBUSxPQUFPO0dBQUUsTUFBTTtHQUFjLE1BQU0sTUFBTTtFQUFLO0VBQ3pFLElBQUksTUFBTSxTQUFTLFNBQVMsT0FBTztHQUFFLE1BQU07R0FBZSxXQUFXLE1BQU07RUFBSTtFQUMvRSxJQUFJLE1BQU0sU0FBUyxjQUFjLE9BQU87R0FBRSxNQUFNO0dBQWUsV0FBVyxNQUFNO0VBQUs7RUFDckYsT0FBTztHQUFFLE1BQU07R0FBYyxNQUFNLEdBQUcsTUFBTSxLQUFLLElBQUksTUFBTTtFQUFPO0NBQ3BFLENBQUM7Q0FDRCxPQUFPLENBQUMsR0FBRyxTQUFTO0VBQUUsTUFBTTtFQUFXLE1BQU07RUFBUTtDQUFRLENBQUM7QUFDaEU7QUFFQSxTQUFTLFlBQVksS0FBdUU7Q0FDMUYsTUFBTSxVQUNKLElBQUksb0JBQW9CLElBQUkscUJBQXFCLFNBQVMsSUFBSSxtQkFBbUI7Q0FFbkYsTUFBTSxTQUFTLG9CQUFvQixJQUFJLFNBQVMsSUFBSSxJQUFJLE1BQU07Q0FDOUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLE9BQU87Q0FDaEMsT0FBTztFQUNMLEdBQUksU0FBUyxFQUFFLE9BQU8sSUFBSSxDQUFDO0VBQzNCLEdBQUksVUFDQSxFQUNXLFFBQ1gsSUFDQSxDQUFDO0NBQ1A7QUFDRjtBQUVBLFNBQVMsZUFBZSxLQUE4QztDQUNwRSxNQUFNLEVBQUUsY0FBYyxHQUFHLGtCQUFrQixJQUFJLDBCQUEwQixDQUFDO0NBQzFFLE9BQU87RUFDTCxPQUFPLElBQUksU0FBUztFQUNwQixHQUFJLElBQUksZUFBZSxFQUFFLGNBQWMsSUFBSSxhQUFhLElBQUksQ0FBQztFQUM3RCxTQUFTLFdBQVcsR0FBRztFQUN2QixHQUFJLFlBQVksR0FBRyxJQUFJLEVBQUUsV0FBVyxZQUFZLEdBQUcsRUFBRSxJQUFJLENBQUM7RUFDMUQsR0FBSSxJQUFJLFlBQVksRUFBRSxXQUFXLElBQUksVUFBaUQsSUFBSSxDQUFDO0VBQzNGLEdBQUksSUFBSSxjQUNKLEVBQUUsYUFBYSxJQUFJLGdCQUFnQixTQUFTLGFBQWEsSUFBSSxZQUFZLElBQ3pFLENBQUM7RUFDTCxHQUFJLElBQUksaUJBQWlCLEVBQUUsZ0JBQWdCLElBQUksZUFBZSxJQUFJLENBQUM7RUFDbkUsR0FBSSxJQUFJLGVBQWUsRUFBRSxjQUFjLEVBQUUsUUFBUSxJQUFJLGFBQTBCLEVBQUUsSUFBSSxDQUFDO0VBQ3RGLEdBQUksSUFBSSxrQkFDSixFQUNFLGlCQUFpQixJQUFJLHlCQUNqQjtHQUNFLEdBQUc7R0FDSCxHQUFJLGVBQWUsRUFBRSxlQUFlLGFBQWEsSUFBSSxDQUFDO0VBQ3hELElBQ0EsS0FDTixJQUNBLENBQUM7Q0FDUDtBQUNGOzs7Ozs7Ozs7QUFVQSxJQUFhLG1CQUFiLE1BQWEsaUJBQStDO0NBQzFELGdDQUF5QixJQUFJLElBQTJCO0NBQ3hEO0NBQ0Esa0NBQTJCLElBQUksSUFBK0Q7Q0FDOUYsb0NBQXFDLElBQUksSUFHdkM7Q0FDRiwwQkFBMkIsSUFBSSxJQUF5QjtDQUN4RCxpQ0FBa0MsSUFBSSxJQUFpQjtDQUN2RCxPQUFnQix3QkFBd0I7Q0FFeEMsV0FBNEIsSUFBSSx5QkFBeUI7Q0FDekQ7Q0FDQTtDQUNBLCtCQUFnQyxJQUFJLElBQVk7Q0FDaEQsZ0JBQXdCO0NBRXhCLFlBQ0UsZ0JBQXFDLDJCQUEyQixHQUNoRSxlQUE2QyxDQUFDLEdBQzlDO0VBQ0EsS0FBSyxnQkFBZ0I7RUFDckIsS0FBSyxnQkFDSCxhQUFhLG1CQUFtQixZQUFZLElBQUksbUJBQW1CLE9BQU87RUFDNUUsS0FBSyxZQUFZLGFBQWEsU0FBUztDQUN6QztDQUVBLE1BQU0sUUFBdUI7RUFDM0IsTUFBTSxFQUFFLFNBQVMsTUFBTSxXQUFXLFNBQVMsR0FBRztFQUM5QyxLQUFLLE1BQU0sT0FBTyxNQUFNO0dBQ3RCLElBQUksSUFBSSxhQUFhLFVBQVU7R0FDL0IsS0FBSyxTQUNILElBQUksSUFDSixJQUFJLE1BQ0osSUFBSSxhQUNKLElBQUksaUJBQ0osSUFBSSxRQUNKLElBQUksTUFDTjtFQUNGO0VBQ0EsT0FBTyxLQUFLLHNDQUFzQyxLQUFLLGNBQWMsS0FBSyxRQUFRO0NBQ3BGO0NBRUEsTUFBTSxPQUFzQjtFQUMxQixLQUFLLE1BQU0sRUFBRSxZQUFZLEtBQUssUUFBUSxPQUFPLEdBQUcsT0FBTyxRQUFRO0VBQy9ELEtBQUssUUFBUSxNQUFNO0VBQ25CLEtBQUssTUFBTSxTQUFTLEtBQUssZ0JBQWdCLE1BQU0sT0FBTyxRQUFRO0VBQzlELEtBQUssZUFBZSxNQUFNO0VBQzFCLEtBQUssY0FBYyxNQUFNO0VBQ3pCLEtBQUssZ0JBQWdCLE1BQU07RUFDM0IsS0FBSyxhQUFhLE1BQU07RUFDeEIsS0FBSyxTQUFTLFlBQVk7Q0FDNUI7Q0FFQSxNQUFNLGFBQ0osSUFDQSxNQUNBLGFBQ0EsZ0JBQ0EsU0FBUyxHQUNNO0VBQ2YsS0FBSyxTQUFTLElBQUksTUFBTSxhQUFhLGdCQUFnQixRQUFRLElBQUk7Q0FDbkU7Q0FFQSxNQUFNLGVBQ0osSUFDQSxNQUNBLGFBQ0EsZ0JBQ0EsU0FBUyxHQUNNO0VBQ2YsTUFBTSxNQUFNLEtBQUssY0FBYyxJQUFJLEVBQUU7RUFDckMsS0FBSyxTQUFTLElBQUksTUFBTSxhQUFhLGdCQUFnQixRQUFRLEtBQUssVUFBVSxJQUFJO0NBQ2xGO0NBRUEsTUFBTSxlQUFlLElBQTJCO0VBQzlDLEtBQUssYUFBYSxFQUFFO0VBQ3BCLEtBQUssY0FBYyxPQUFPLEVBQUU7RUFDNUIsS0FBSyxTQUFTLFlBQVksRUFBRTtFQUM1QixLQUFLLDBCQUEwQixFQUFFO0VBQ2pDLEtBQUssYUFBYSxPQUFPLEVBQUU7Q0FDN0I7Q0FFQSxtQkFBbUIsSUFBa0I7RUFDbkMsTUFBTSxRQUFRLEtBQUssY0FBYyxJQUFJLEVBQUU7RUFDdkMsSUFBSSxPQUFPLE1BQU0sU0FBUztFQUMxQixLQUFLLFNBQVMsWUFBWTtDQUM1QjtDQUVBLGlCQUFpQixJQUFrQjtFQUNqQyxNQUFNLFFBQVEsS0FBSyxjQUFjLElBQUksRUFBRTtFQUN2QyxJQUFJLE9BQU8sTUFBTSxTQUFTO0VBQzFCLEtBQUssU0FBUyxZQUFZO0NBQzVCO0NBRUEsTUFBTSxjQUNKLE1BT2U7RUFDZixNQUFNLE1BQU0sSUFBSSxJQUFJLEtBQUssS0FBSyxNQUFNLEVBQUUsRUFBRSxDQUFDO0VBQ3pDLEtBQUssTUFBTSxNQUFNLEtBQUssY0FBYyxLQUFLLEdBQUcsSUFBSSxDQUFDLElBQUksSUFBSSxFQUFFLEdBQUcsTUFBTSxLQUFLLGVBQWUsRUFBRTtFQUMxRixLQUFLLE1BQU0sT0FBTyxNQUNoQixNQUFNLEtBQUssZUFBZSxJQUFJLElBQUksSUFBSSxNQUFNLElBQUksYUFBYSxJQUFJLGdCQUFnQixJQUFJLE1BQU07Q0FDL0Y7Q0FFQSxNQUFNLFNBQVMsS0FBK0M7RUFDNUQsT0FBTyxLQUFLLElBQUksR0FBRztDQUNyQjtDQUVBLE1BQU0sZUFBZSxLQUFzQixJQUE0QztFQUNyRixJQUFJLElBQUksaUJBQ04sTUFBTSxJQUFJLHFCQUNSLFFBQ0EseURBQ0Y7RUFDRixJQUFJO0dBQ0YsR0FBRyxXQUFXLE1BQU0sS0FBSyxJQUFJLEtBQUssR0FBRyxPQUFPLENBQUM7RUFDL0MsU0FBUyxPQUFPO0dBQ2QsR0FBRyxRQUFRLEtBQWM7R0FDekIsTUFBTTtFQUNSO0NBQ0Y7Q0FHQSxNQUFjLElBQ1osS0FDQSxTQUN5QjtFQUN6QixNQUFNLFNBQVMsYUFBYSxJQUFJLGFBQWEsSUFBSSxTQUFTO0VBQzFELElBQUksT0FBTyxTQUFTLE1BQU0sV0FBVyxNQUFNO0VBQzNDLE1BQU0sWUFBWSxNQUFNLEtBQUssWUFDM0IsSUFBSSxrQkFDSixJQUFJLHlCQUF5QixPQUM3QixNQUNGO0VBQ0EsS0FBSztFQUNMLElBQUk7R0FDRixJQUFJLE9BQU8sU0FBUyxNQUFNLFdBQVcsTUFBTTtHQUMzQyxPQUFPLE1BQU0sS0FBSyxVQUFVLFdBQVc7SUFBRSxHQUFHO0lBQUssYUFBYTtHQUFPLEdBQUcsT0FBTztFQUNqRixVQUFVO0dBQ1IsS0FBSztFQUNQO0NBQ0Y7Q0FFQSxNQUFjLFVBQ1osV0FDQSxLQUNBLFNBQ3lCO0VBQ3pCLE1BQU0sWUFBWSxLQUFLLElBQUk7RUFDM0IsSUFBSTtFQUNKLElBQUksT0FBTztFQUNYLElBQUksUUFBUTtHQUNWLGFBQWE7R0FDYixhQUFhO0dBQ2IsY0FBYztHQUNkLG1CQUFtQjtHQUNuQix1QkFBdUI7RUFDekI7RUFDQSxNQUFNLFNBQTJCLENBQUM7RUFDbEMsSUFBSSxpQkFBaUI7RUFDckIsSUFBSSxlQUFlLElBQUksU0FBUztFQUNoQyxNQUFNLFdBQVcsVUFBVTtFQUMzQixNQUFNLGNBQWMsS0FBSyxjQUFjLFNBQVM7RUFDaEQsSUFBSTtHQUNGLFdBQVcsTUFBTSxTQUFTLFlBQVksT0FBTyxVQUMzQyxlQUFlLEdBQUcsR0FDbEIsSUFBSSxXQUNOLEdBQ0UsSUFBSSxNQUFNLFNBQVMsY0FBYztJQUMvQixpQkFBaUIsS0FBSyxJQUFJO0lBQzFCLFFBQVEsTUFBTTtJQUNkLFVBQVUsTUFBTSxJQUFJO0dBQ3RCLE9BQU8sSUFBSSxNQUFNLFNBQVMsU0FBUztJQUNqQyxpQkFBaUI7SUFDakIsT0FBTyxLQUFLO0tBQ1YsTUFBTSxNQUFNO0tBQ1osV0FBVyxNQUFNO0tBQ2pCLGVBQWUsTUFBTSxpQkFBaUI7S0FDdEMsR0FBSSxNQUFNLGFBQWEsRUFBRSxZQUFZLE1BQU0sV0FBVyxJQUFJLENBQUM7SUFDN0QsQ0FBQztHQUNILE9BQU8sSUFBSSxNQUFNLFNBQVMsaUJBQWlCLE1BQU0sS0FBSyxTQUFTLHlCQUM3RCxpQkFBaUI7UUFDWixJQUFJLE1BQU0sU0FBUyxlQUFlLE1BQU0sT0FBTztJQUNwRCxlQUFlLE1BQU0sU0FBUztJQUM5QixRQUFRO0tBQ04sYUFBYSxNQUFNLE1BQU07S0FDekIsYUFBYSxNQUFNLE1BQU07S0FDekIsY0FBYyxNQUFNLE1BQU07S0FDMUIsbUJBQW1CLE1BQU0sTUFBTTtLQUMvQix1QkFBdUIsTUFBTSxNQUFNO0lBQ3JDO0dBQ0YsT0FBTyxJQUFJLE1BQU0sU0FBUyxhQUN4QixlQUFlLE1BQU0sU0FBUztRQUN6QixJQUFJLE1BQU0sU0FBUyxTQUFTO0lBQ2pDLElBQUksSUFBSSxpQkFDTixNQUFNLElBQUkscUJBQXFCLGNBQWMsTUFBTSxNQUFNLE9BQU87SUFDbEUsTUFBTSxNQUFNO0dBQ2Q7RUFFSixVQUFVO0dBQ1IsS0FBSyxjQUFjLFdBQVc7RUFDaEM7RUFDQSxJQUFJLElBQUksbUJBQW1CLE9BQU8sV0FBVyxHQUMzQyxNQUFNLElBQUkscUJBQ1IsaUJBQWlCLGVBQWUsY0FDaEMsaUJBQ0ksc0NBQ0EscUNBQ047RUFFRixPQUFPO0dBQ0w7R0FDQSxXQUFXLFNBQVM7R0FDcEI7R0FDQSxZQUFZLEtBQUssSUFBSSxJQUFJO0dBQ3pCLFFBQVEsaUJBQWlCLFNBQVksT0FBTyxlQUFlO0dBQzNELE9BQU87R0FDUCxHQUFJLGlCQUFpQixJQUFJLFFBQVEsRUFBRSxnQkFBZ0IsSUFBSSxNQUFNLElBQUksQ0FBQztHQUNsRSxhQUFhO0lBQUUsVUFBVSxVQUFVO0lBQVMsVUFBVSxJQUFJLGtCQUFrQjtJQUFJLE9BQU87R0FBRztHQUMxRixHQUFJLE9BQU8sU0FBUyxFQUFFLE9BQU8sSUFBSSxDQUFDO0VBQ3BDO0NBQ0Y7O0NBR0EsY0FBc0IsV0FBd0M7RUFDNUQsTUFBTSxXQUFXLFVBQVU7RUFDM0IsSUFBSSxRQUFRLEtBQUssUUFBUSxJQUFJLFVBQVUsT0FBTztFQUM5QyxJQUFJLFNBQVMsTUFBTSxlQUFlLFNBQVMsWUFBWTtHQUNyRCxLQUFLLGFBQWEsVUFBVSxPQUFPO0dBQ25DLFFBQVE7RUFDVjtFQUNBLElBQUksQ0FBQyxPQUFPO0dBQ1YsTUFBTSxTQUFTLEtBQUssY0FDbEI7SUFDRSxhQUFhO0tBQ1gsYUFBYSxTQUFTLFlBQVk7S0FDbEMsV0FBVyxTQUFTLFlBQVk7SUFDbEM7SUFDQSxlQUFlLEtBQUs7SUFDcEIsT0FBTyxLQUFLO0lBQ1osMEJBQTBCLEtBQUssbUJBQW1CLFVBQVUsT0FBTztHQUNyRSxHQUNBLFVBQVUsT0FDWjtHQUNBLFFBQVE7SUFBRSxZQUFZLFNBQVM7SUFBWTtJQUFRLFVBQVU7SUFBRyxTQUFTO0dBQU07R0FDL0UsS0FBSyxRQUFRLElBQUksVUFBVSxTQUFTLEtBQUs7RUFDM0M7RUFDQSxNQUFNO0VBQ04sT0FBTztDQUNUO0NBRUEsY0FBc0IsT0FBMEI7RUFDOUMsTUFBTSxXQUFXLEtBQUssSUFBSSxHQUFHLE1BQU0sV0FBVyxDQUFDO0VBQy9DLElBQUksTUFBTSxXQUFXLE1BQU0sYUFBYSxHQUFHO0dBQ3pDLEtBQUssZUFBZSxPQUFPLEtBQUs7R0FDaEMsTUFBTSxPQUFPLFFBQVE7RUFDdkI7Q0FDRjs7Q0FHQSxhQUFxQixTQUF1QjtFQUMxQyxNQUFNLFFBQVEsS0FBSyxRQUFRLElBQUksT0FBTztFQUN0QyxJQUFJLENBQUMsT0FBTztFQUNaLEtBQUssUUFBUSxPQUFPLE9BQU87RUFDM0IsTUFBTSxVQUFVO0VBQ2hCLElBQUksTUFBTSxhQUFhLEdBQUcsTUFBTSxPQUFPLFFBQVE7T0FDMUMsS0FBSyxlQUFlLElBQUksS0FBSztDQUNwQzs7Ozs7OztDQVFBLE1BQWMsWUFDWixrQkFDQSx1QkFDQSxRQUN5QjtFQUN6QixJQUFJLHFCQUFxQixRQUFXO0dBQ2xDLE1BQU0sWUFBWSxLQUFLLGNBQWMsSUFBSSxnQkFBZ0I7R0FDekQsSUFBSSxXQUFXLFVBQVcsTUFBTSxLQUFLLGdCQUFnQixrQkFBa0IsV0FBVyxNQUFNLEdBQ3RGLE9BQU87SUFBRSxTQUFTO0lBQWtCLFVBQVU7R0FBVTtHQUUxRCxJQUFJLHVCQUF1QjtJQUN6QixJQUFJLENBQUMsV0FBVyxRQUNkLE1BQU0sSUFBSSxNQUFNLDBCQUEwQixpQkFBaUIsa0JBQWtCO0lBRS9FLE1BQU0sWUFBWSxVQUFVO0lBQzVCLElBQUksY0FBYyxRQUFRLGNBQWMsUUFDdEMsTUFBTSxJQUFJLDRCQUNSLGFBQWEsQ0FBQztLQUFFLE1BQU0sVUFBVTtLQUFNO0lBQVUsQ0FBQyxDQUFDLENBQ3BEO0dBRUo7RUFDRjtFQUlBLE1BQU0sU0FBUyxNQUFNLFFBQVEsSUFDM0IsQ0FBQyxHQUFHLEtBQUssY0FBYyxRQUFRLENBQUMsQ0FBQyxDQUM5QixRQUFRLEdBQUcsV0FBVyxNQUFNLE1BQU0sQ0FBQyxDQUNuQyxJQUFJLE9BQU8sQ0FBQyxJQUFJLFlBQVk7R0FDM0I7R0FDQTtHQUNBLFVBQVUsTUFBTSxLQUFLLGdCQUFnQixJQUFJLE9BQU8sTUFBTTtFQUN4RCxFQUFFLENBQ047RUFDQSxNQUFNLFdBQVcsSUFBSSxJQUFJLE9BQU8sUUFBUSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUMsS0FBSyxNQUFNLEVBQUUsRUFBRSxDQUFDO0VBQzFFLElBQUksU0FBUyxTQUFTLEdBQUc7R0FDdkIsTUFBTSxPQUFPLE9BQ1YsUUFDRSxNQUNDLENBQUMsRUFBRSxZQUFZLEVBQUUsTUFBTSxtQkFBbUIsUUFBUSxFQUFFLE1BQU0sbUJBQW1CLE1BQ2pGLENBQUMsQ0FDQSxLQUFLLE9BQU87SUFBRSxNQUFNLEVBQUUsTUFBTTtJQUFNLFdBQVcsRUFBRSxNQUFNO0dBQXlCLEVBQUU7R0FDbkYsSUFBSSxLQUFLLFFBQVE7SUFDZixPQUFPLEtBQUssc0NBQXNDO0tBQ2hELFVBQVU7S0FDVixxQkFBcUI7SUFDdkIsQ0FBQztJQUNELE1BQU0sSUFBSSw0QkFBNEIsYUFBYSxJQUFJLENBQUM7R0FDMUQ7R0FDQSxNQUFNLElBQUksTUFBTSxtQkFBbUI7RUFDckM7RUFDQSxNQUFNLFdBQVcsS0FBSyxTQUFTLE9BQU8sUUFBUTtFQUM5QyxNQUFNLFdBQVcsYUFBYSxPQUFPLEtBQUssY0FBYyxJQUFJLFFBQVEsSUFBSTtFQUN4RSxJQUFJLGFBQWEsUUFBUSxDQUFDLFVBQVUsTUFBTSxJQUFJLE1BQU0sbUJBQW1CO0VBQ3ZFLE9BQU87R0FBRSxTQUFTO0dBQVU7RUFBUztDQUN2QztDQUVBLFNBQ0UsSUFDQSxNQUNBLGFBQ0EsZ0JBQ0EsUUFDQSxRQUNNO0VBQ04sTUFBTSxNQUFNLEtBQUssY0FBYyxJQUFJLEVBQUU7RUFDckMsSUFBSSxLQUNGLE9BQU8sT0FBTyxLQUFLO0dBQ2pCO0dBQ0E7R0FDQTtHQUNBO0dBQ0E7R0FDQSxZQUFZLElBQUksYUFBYTtFQUMvQixDQUFDO09BRUQsS0FBSyxjQUFjLElBQUksSUFBSTtHQUN6QjtHQUNBO0dBQ0E7R0FDQTtHQUNBO0dBQ0EsWUFBWTtFQUNkLENBQUM7RUFFSCxLQUFLLFNBQVMsU0FBUyxJQUFJLE1BQU07RUFDakMsS0FBSywwQkFBMEIsRUFBRTtFQUNqQyxLQUFLLGFBQWEsT0FBTyxFQUFFO0NBQzdCO0NBRUEsTUFBTSx1QkFDSixTQUNBLFFBQ21DO0VBQ25DLE1BQU0sUUFBUSxLQUFLLGNBQWMsSUFBSSxPQUFPO0VBQzVDLElBQUksQ0FBQyxPQUFPLE1BQU0sSUFBSSxNQUFNLGdCQUFnQixRQUFRLFdBQVc7RUFDL0QsTUFBTSxhQUFhLE1BQU07RUFDekIsTUFBTSxTQUFTLEtBQUssZ0JBQWdCLElBQUksT0FBTztFQUMvQyxJQUNFLFVBQ0EsT0FBTyxlQUFlLE1BQU0sY0FDNUIsS0FBSyxJQUFJLElBQUksT0FBTyxXQUFXLGlCQUFpQix1QkFFaEQsT0FBTztFQUtULE1BQU0sVUFBVSxLQUFLLGtCQUFrQixJQUFJLE9BQU87RUFDbEQsSUFBSSxTQUFTLFVBQVUsU0FBUyxRQUFRLGVBQWUsWUFBWSxPQUFPLFFBQVE7RUFDbEYsTUFBTSxnQkFBZ0IsWUFBWTtHQUNoQyxNQUFNLFNBQVMsTUFBTSxxQkFBcUI7SUFDeEMsYUFBYSxNQUFNO0lBQ25CLDBCQUEwQixLQUFLLG1CQUFtQixPQUFPO0lBQ3pELE9BQU8sS0FBSztJQUNaLEdBQUksU0FBUyxFQUFFLE9BQU8sSUFBSSxDQUFDO0dBQzdCLENBQUM7R0FDRCxJQUFJLE9BQU8sU0FBUyxpQkFBaUIsTUFBTSxJQUFJLE1BQU0sT0FBTyxNQUFNO0dBQ2xFLElBQUksQ0FBQyxPQUFPLEtBQUssTUFBTSxJQUFJLE1BQU0sK0NBQStDO0dBQ2hGLE1BQU0sUUFBUTtJQUFFLE1BQU0sT0FBTztJQUFLLFVBQVUsS0FBSyxJQUFJO0lBQUc7R0FBVztHQUNuRSxJQUFJLEtBQUssY0FBYyxJQUFJLE9BQU8sTUFBTSxTQUFTLE1BQU0sZUFBZSxZQUNwRSxLQUFLLGdCQUFnQixJQUFJLFNBQVMsS0FBSztHQUV6QyxPQUFPO0VBQ1QsRUFBQSxDQUFHLENBQUMsQ0FBQyxjQUFjO0dBQ2pCLElBQUksS0FBSyxrQkFBa0IsSUFBSSxPQUFPLENBQUMsRUFBRSxZQUFZLGNBQ25ELEtBQUssa0JBQWtCLE9BQU8sT0FBTztFQUV6QyxDQUFDO0VBQ0QsS0FBSyxrQkFBa0IsSUFBSSxTQUFTO0dBQUU7R0FBTztHQUFZLFNBQVM7RUFBYSxDQUFDO0VBQ2hGLE9BQU87Q0FDVDtDQUVBLE1BQWMsbUJBQW1CLFNBQWlCO0VBQ2hELE1BQU0sV0FBVyxLQUFLLGNBQWMsSUFBSSxPQUFPO0VBQy9DLE1BQU0sYUFBYSxVQUFVO0VBQzdCLE1BQU0sWUFBWSxNQUFNLCtCQUErQixPQUFPO0VBQzlELE1BQU0sY0FBYztHQUNsQixhQUFhLFVBQVU7R0FDdkIsV0FBVyxVQUFVO0VBQ3ZCO0VBQ0EsTUFBTSxVQUFVLEtBQUssY0FBYyxJQUFJLE9BQU87RUFDOUMsSUFBSSxDQUFDLFNBQVMsUUFBUSxNQUFNLElBQUksTUFBTSxnQkFBZ0IsUUFBUSxxQkFBcUI7RUFHbkYsSUFBSSxZQUFZLFlBQVksUUFBUSxlQUFlLFlBQVk7R0FDN0QsUUFBUSxjQUFjO0lBQUUsR0FBRyxRQUFRO0lBQWEsR0FBRztHQUFZO0dBQy9ELEtBQUssYUFBYSxPQUFPO0dBQ3pCLEtBQUssMEJBQTBCLE9BQU87RUFDeEM7RUFDQSxPQUFPO0dBQ0wsYUFBYSxRQUFRLFlBQVk7R0FDakMsV0FBVyxRQUFRLFlBQVk7RUFDakM7Q0FDRjtDQUVBLE1BQWMsZ0JBQ1osSUFDQSxPQUNBLFFBQ2tCO0VBQ2xCLElBQUksTUFBTSxtQkFBbUIsUUFBUSxNQUFNLG1CQUFtQixRQUFXLE9BQU87RUFDaEYsTUFBTSxhQUFhLE1BQU07RUFDekIsTUFBTSxTQUFTLE1BQU0scUJBQXFCLFlBQVksS0FBSyx1QkFBdUIsSUFBSSxNQUFNLENBQUM7RUFDN0YsSUFBSSxLQUFLLGNBQWMsSUFBSSxFQUFFLE1BQU0sU0FBUyxNQUFNLGVBQWUsWUFBWSxPQUFPO0VBQ3BGLElBQUksT0FBTyxTQUFTLGlCQUFpQjtHQUNuQyxLQUFLLGFBQWEsT0FBTyxFQUFFO0dBQzNCLE9BQU8sS0FBSywwQ0FBMEM7SUFDcEQsU0FBUztJQUNULFdBQVcsTUFBTTtJQUNqQixjQUFjLE9BQU87R0FDdkIsQ0FBQztHQUNELE9BQU87RUFDVDtFQUNBLElBQUksT0FBTyxrQkFBa0IsTUFBTSxnQkFBZ0I7R0FDakQsSUFBSSxDQUFDLEtBQUssYUFBYSxJQUFJLEVBQUUsR0FDM0IsT0FBTyxLQUNMLHdDQUF3QyxNQUFNLEtBQUssR0FBRyxHQUFHLEtBQUssT0FBTyxlQUFlLE9BQU8sTUFBTSxlQUFlLEdBQ2xIO0dBQ0YsS0FBSyxhQUFhLElBQUksRUFBRTtHQUN4QixPQUFPO0VBQ1Q7RUFDQSxJQUFJLEtBQUssYUFBYSxPQUFPLEVBQUUsR0FDN0IsT0FBTyxLQUNMLG1DQUFtQyxNQUFNLEtBQUssR0FBRyxHQUFHLEtBQUssT0FBTyxlQUFlLE1BQU0sTUFBTSxlQUFlLEdBQzVHO0VBQ0YsT0FBTztDQUNUO0NBRUEsMEJBQWtDLElBQWtCO0VBQ2xELEtBQUssZ0JBQWdCLE9BQU8sRUFBRTtDQUNoQztDQUVBLElBQUksYUFBcUI7RUFDdkIsT0FBTyxDQUFDLEdBQUcsS0FBSyxjQUFjLE9BQU8sQ0FBQyxDQUFDLENBQUMsUUFBUSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7Q0FDbEU7Q0FDQSxJQUFJLFdBQW1CO0VBQ3JCLE9BQU8sS0FBSztDQUNkOzs7Ozs7Q0FPQSxJQUFJLGVBTUQ7RUFDRCxNQUFNLE1BQU0sS0FBSyxJQUFJO0VBQ3JCLE9BQU8sQ0FBQyxHQUFHLEtBQUssY0FBYyxRQUFRLENBQUMsQ0FBQyxDQUNyQyxLQUFLLENBQUMsSUFBSSxPQUFPO0dBQ2hCLE1BQU0sU0FBUyxLQUFLLGdCQUFnQixJQUFJLEVBQUU7R0FLMUMsTUFBTSxVQUhKLFdBQVcsVUFDWCxPQUFPLGVBQWUsRUFBRSxjQUN4QixNQUFNLE9BQU8sV0FBVyxpQkFBaUIsd0JBQ25CLE9BQU8sS0FBSyxZQUFZLFVBQVU7R0FDMUQsT0FBTztJQUNMLE1BQU0sRUFBRTtJQUNSLGFBQWEsU0FBUyxlQUFlO0lBQ3JDLFdBQVcsRUFBRSxrQkFBa0I7SUFDL0IsU0FBUyxLQUFLLGFBQWEsSUFBSSxFQUFFO0lBR2pDLFVBQ0UsU0FBUyxhQUFhLFFBQVEsU0FBUyxhQUFhLFNBQ2hELFFBQVEsV0FBVyxNQUNuQjtHQUNSO0VBQ0YsQ0FBQyxDQUFDLENBQ0QsVUFBVSxHQUFHLE1BQU0sRUFBRSxLQUFLLGNBQWMsRUFBRSxJQUFJLENBQUM7Q0FDcEQ7QUFDRiJ9
|
|
558
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLWRpc3BhdGNoZXIuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9vcGVuYWkvb3BlbmFpLWRpc3BhdGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcblxuaW1wb3J0IHsgUXVvdGFUaHJlc2hvbGRFeGNlZWRlZEVycm9yIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLnR5cGVzXCI7XG5pbXBvcnQgeyBUb2tlbk1vZGVsIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLm1vZGVsXCI7XG5pbXBvcnQgeyB0eXBlIE9wZW5BSUNyZWRlbnRpYWxzIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLnR5cGVzXCI7XG5pbXBvcnQgeyByZXNvbHZlT3BlbkFJRWZmb3J0IH0gZnJvbSBcIi4uL2NvbW1vbi9lZmZvcnRcIjtcbmltcG9ydCB7XG4gIHR5cGUgR2VuZXJhdGVSZXF1ZXN0LFxuICB0eXBlIEdlbmVyYXRlUmVzdWx0LFxuICB0eXBlIEdlbmVyYXRlU3RyZWFtQ2FsbGJhY2tzLFxuICB0eXBlIEdlbmVyYXRlZEltYWdlLFxuICB0eXBlIFByb3ZpZGVyRGlzcGF0Y2hlcixcbn0gZnJvbSBcIi4uL2NvbW1vbi9wcm92aWRlci1kaXNwYXRjaGVyXCI7XG5pbXBvcnQgeyBTbW9vdGhXZWlnaHRlZFJvdW5kUm9iaW4gfSBmcm9tIFwiLi4vY29tbW9uL3Ntb290aC13ZWlnaHRlZC1yb3VuZC1yb2JpblwiO1xuaW1wb3J0IHtcbiAgdHlwZSBKc29uVmFsdWUsXG4gIHR5cGUgT3BlbkFJUmVzcG9uc2VJdGVtLFxuICB0eXBlIE9wZW5BSVJlc3BvbnNlc09wdGlvbnMsXG59IGZyb20gXCIuL29wZW5haS1iYWNrZW5kLXByb3RvY29sXCI7XG5pbXBvcnQgeyBPcGVuQUlEaXJlY3RDbGllbnQsIHR5cGUgT3BlbkFJRGlyZWN0Q2xpZW50T3B0aW9ucyB9IGZyb20gXCIuL29wZW5haS1kaXJlY3QtY2xpZW50XCI7XG5pbXBvcnQgeyByZWFkT3BlbkFJUXVvdGFVc2FnZSwgdHlwZSBPcGVuQUlSYXRlTGltaXRzV2l0aE1ldGEgfSBmcm9tIFwiLi9vcGVuYWktcXVvdGFcIjtcbmltcG9ydCB7IGhhbmRsZUNoYXRncHRBdXRoVG9rZW5zUmVmcmVzaCB9IGZyb20gXCIuL29wZW5haS1yZWZyZXNoXCI7XG5pbXBvcnQgeyB0eXBlIE9wZW5BSVRyYW5zcG9ydEtpbmQsIHJlc29sdmVPcGVuQUlUcmFuc3BvcnRLaW5kIH0gZnJvbSBcIi4vb3BlbmFpLXRyYW5zcG9ydC1jb25maWdcIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwib3BlbmFpLWRpc3BhdGNoZXJcIl0pO1xuLy8g6rWQ7LK065CcIGNvZGV4IHdvcmtlciDqsIAg6rCV7KCc7ZWY642YIHdhdGNoZG9nLiDtmLjstpzsnpDqsIAgdGltZW91dE1zIOulvCDsg53rnrXtlbTrj4Qg7JqU7LKt7J20XG4vLyDsmIHsm5Dtnogg66ek64us66as7KeAIOyViuuPhOuhnSBkaXJlY3QgdHJhbnNwb3J0IOuPhCDsnKDtlZztlZwg6riw67O4IOyDge2VnOydhCDsnKDsp4DtlZzri6QuXG5jb25zdCBERUZBVUxUX1JFUVVFU1RfVElNRU9VVF9NUyA9IDYwMF8wMDA7XG5jb25zdCBUUkFOU1BBUkVOVF9JTUFHRV9UT09MID0gXCJnZW5lcmF0ZV90cmFuc3BhcmVudF9pbWFnZVwiO1xuXG5leHBvcnQgdHlwZSBJbWFnZUZhaWx1cmVLaW5kID0gXCJnYXRlXCIgfCBcIm5vdF9jYWxsZWRcIiB8IFwiaW5jb21wbGV0ZVwiO1xuXG5leHBvcnQgY2xhc3MgSW1hZ2VHZW5lcmF0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHJlYWRvbmx5IGtpbmQ6IEltYWdlRmFpbHVyZUtpbmQsXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICApIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSBcIkltYWdlR2VuZXJhdGlvbkVycm9yXCI7XG4gIH1cbn1cblxudHlwZSBUb2tlbk1ldGFkYXRhID0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscztcbiAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsO1xuICB3ZWlnaHQ6IG51bWJlcjtcbiAgYWN0aXZlOiBib29sZWFuO1xuICBnZW5lcmF0aW9uOiBudW1iZXI7XG59O1xuXG50eXBlIFRva2VuU2VsZWN0aW9uID0geyB0b2tlbklkOiBudW1iZXI7IG1ldGFkYXRhOiBUb2tlbk1ldGFkYXRhIH07XG5cbmV4cG9ydCB0eXBlIE9wZW5BSURpcmVjdENsaWVudEZhY3RvcnkgPSAoXG4gIG9wdGlvbnM6IE9wZW5BSURpcmVjdENsaWVudE9wdGlvbnMsXG4gIHRva2VuSWQ6IG51bWJlcixcbikgPT4gUGljazxPcGVuQUlEaXJlY3RDbGllbnQsIFwicmVzcG9uc2VzXCI+ICYgeyBjbG9zZT86ICgpID0+IHZvaWQgfTtcblxudHlwZSBDbGllbnRFbnRyeSA9IHtcbiAgZ2VuZXJhdGlvbjogbnVtYmVyO1xuICBjbGllbnQ6IFBpY2s8T3BlbkFJRGlyZWN0Q2xpZW50LCBcInJlc3BvbnNlc1wiPiAmIHsgY2xvc2U/OiAoKSA9PiB2b2lkIH07XG4gIGluRmxpZ2h0OiBudW1iZXI7XG4gIHJldGlyZWQ6IGJvb2xlYW47XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIE9wZW5BSURpc3BhdGNoZXJEZXBlbmRlbmNpZXMge1xuICBjbGllbnRGYWN0b3J5PzogT3BlbkFJRGlyZWN0Q2xpZW50RmFjdG9yeTtcbiAgZmV0Y2g/OiB0eXBlb2YgZmV0Y2g7XG59XG5cbmZ1bmN0aW9uIGFib3J0RXJyb3Ioc2lnbmFsOiBBYm9ydFNpZ25hbCk6IEVycm9yIHtcbiAgY29uc3QgcmVhc29uID0gc2lnbmFsLnJlYXNvbjtcbiAgcmV0dXJuIHJlYXNvbiBpbnN0YW5jZW9mIEVycm9yID8gcmVhc29uIDogbmV3IERPTUV4Y2VwdGlvbihcIkFib3J0ZWRcIiwgXCJBYm9ydEVycm9yXCIpO1xufVxuXG5mdW5jdGlvbiBhY3RpdmVTaWduYWwoc2lnbmFsPzogQWJvcnRTaWduYWwsIHRpbWVvdXRNcz86IG51bWJlcik6IEFib3J0U2lnbmFsIHtcbiAgY29uc3QgdGltZW91dCA9IEFib3J0U2lnbmFsLnRpbWVvdXQodGltZW91dE1zID8/IERFRkFVTFRfUkVRVUVTVF9USU1FT1VUX01TKTtcbiAgcmV0dXJuIHNpZ25hbCA/IEFib3J0U2lnbmFsLmFueShbc2lnbmFsLCB0aW1lb3V0XSkgOiB0aW1lb3V0O1xufVxuXG5mdW5jdGlvbiBxdW90YU1lc3NhZ2UoZW50cmllczogQXJyYXk8eyBuYW1lOiBzdHJpbmc7IHRocmVzaG9sZDogbnVtYmVyIH0+KTogc3RyaW5nIHtcbiAgY29uc3QgZGV0YWlsID0gZW50cmllcy5tYXAoKGUpID0+IGAke2UubmFtZX0gKHRocmVzaG9sZCAke2UudGhyZXNob2xkfSUpYCkuam9pbihcIiwgXCIpO1xuICByZXR1cm4gZGV0YWlsXG4gICAgPyBgQWxsIG9wZW5haSB0b2tlbnMgZXhjZWVkZWQgcXVvdGEgdGhyZXNob2xkOiAke2RldGFpbH1gXG4gICAgOiBcIkFsbCBvcGVuYWkgdG9rZW5zIGV4Y2VlZGVkIHF1b3RhIHRocmVzaG9sZFwiO1xufVxuXG5mdW5jdGlvbiBpbnB1dEl0ZW1zKHJlcTogR2VuZXJhdGVSZXF1ZXN0KTogT3BlbkFJUmVzcG9uc2VJdGVtW10ge1xuICBjb25zdCBoaXN0b3J5ID0gKHJlcS5jb2xkSGlzdG9yeSA/PyBbXSkgYXMgT3BlbkFJUmVzcG9uc2VJdGVtW107XG4gIGNvbnN0IGNvbnRlbnQ6IE9wZW5BSVJlc3BvbnNlSXRlbVtdID0gcmVxLmNvbGRJbnB1dC5tYXAoKGlucHV0KSA9PiB7XG4gICAgaWYgKGlucHV0LnR5cGUgPT09IFwidGV4dFwiKSByZXR1cm4geyB0eXBlOiBcImlucHV0X3RleHRcIiwgdGV4dDogaW5wdXQudGV4dCB9O1xuICAgIGlmIChpbnB1dC50eXBlID09PSBcImltYWdlXCIpIHJldHVybiB7IHR5cGU6IFwiaW5wdXRfaW1hZ2VcIiwgaW1hZ2VfdXJsOiBpbnB1dC51cmwgfTtcbiAgICBpZiAoaW5wdXQudHlwZSA9PT0gXCJsb2NhbEltYWdlXCIpIHJldHVybiB7IHR5cGU6IFwiaW5wdXRfaW1hZ2VcIiwgaW1hZ2VfdXJsOiBpbnB1dC5wYXRoIH07XG4gICAgcmV0dXJuIHsgdHlwZTogXCJpbnB1dF90ZXh0XCIsIHRleHQ6IGAke2lucHV0Lm5hbWV9OiAke2lucHV0LnBhdGh9YCB9O1xuICB9KTtcbiAgcmV0dXJuIFsuLi5oaXN0b3J5LCB7IHR5cGU6IFwibWVzc2FnZVwiLCByb2xlOiBcInVzZXJcIiwgY29udGVudCB9XTtcbn1cblxuZnVuY3Rpb24gYXNSZWFzb25pbmcocmVxOiBHZW5lcmF0ZVJlcXVlc3QpOiBPcGVuQUlSZXNwb25zZXNPcHRpb25zW1wicmVhc29uaW5nXCJdIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgc3VtbWFyeSA9XG4gICAgcmVxLnJlYXNvbmluZ1N1bW1hcnkgJiYgcmVxLnJlYXNvbmluZ1N1bW1hcnkgIT09IFwibm9uZVwiID8gcmVxLnJlYXNvbmluZ1N1bW1hcnkgOiB1bmRlZmluZWQ7XG4gIC8vIENvZGV4IOyWtO2cmMK366qo6424IOyDge2VnCDrsJbsnZggZWZmb3J0IOuKlCDsl6zquLDshJwg7KGw7Jqp7Z6IIOuyhOumsOuLpCjrsLHsl5Trk5wg6riw67O46rCSIOyggeyaqSkuXG4gIGNvbnN0IGVmZm9ydCA9IHJlc29sdmVPcGVuQUlFZmZvcnQocmVxLm1vZGVsID8/IFwiXCIsIHJlcS5lZmZvcnQpO1xuICBpZiAoIWVmZm9ydCAmJiAhc3VtbWFyeSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgcmV0dXJuIHtcbiAgICAuLi4oZWZmb3J0ID8geyBlZmZvcnQgfSA6IHt9KSxcbiAgICAuLi4oc3VtbWFyeVxuICAgICAgPyB7XG4gICAgICAgICAgc3VtbWFyeTogc3VtbWFyeSBhcyBOb25OdWxsYWJsZTxPcGVuQUlSZXNwb25zZXNPcHRpb25zW1wicmVhc29uaW5nXCJdPltcInN1bW1hcnlcIl0sXG4gICAgICAgIH1cbiAgICAgIDoge30pLFxuICB9O1xufVxuXG5mdW5jdGlvbiByZXF1ZXN0T3B0aW9ucyhyZXE6IEdlbmVyYXRlUmVxdWVzdCk6IE9wZW5BSVJlc3BvbnNlc09wdGlvbnMge1xuICBjb25zdCB7IG91dHB1dEZvcm1hdCwgLi4uaW1hZ2VDb250cm9scyB9ID0gcmVxLmltYWdlR2VuZXJhdGlvbk9wdGlvbnMgPz8ge307XG4gIGNvbnN0IGF1dG8gPSByZXEuaW1hZ2VHZW5lcmF0aW9uID09PSBcImF1dG9cIjtcbiAgaWYgKGF1dG8gJiYgcmVxLm91dHB1dFNjaGVtYSkge1xuICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcbiAgICAgIFwiZ2F0ZVwiLFxuICAgICAgXCJBdXRvbWF0aWMgaW1hZ2UgZ2VuZXJhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IHN0cnVjdHVyZWQgb3V0cHV0IG9yIGV4dGVybmFsIHRvb2xzXCIsXG4gICAgKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIG1vZGVsOiByZXEubW9kZWwgPz8gXCJcIixcbiAgICAuLi4ocmVxLnN5c3RlbVByb21wdCA/IHsgaW5zdHJ1Y3Rpb25zOiByZXEuc3lzdGVtUHJvbXB0IH0gOiB7fSksXG4gICAgLi4uKGF1dG9cbiAgICAgID8ge1xuICAgICAgICAgIGluc3RydWN0aW9uczogW1xuICAgICAgICAgICAgcmVxLnN5c3RlbVByb21wdCxcbiAgICAgICAgICAgIFwiVXNlIGltYWdlX2dlbmVyYXRpb24gZm9yIG9yZGluYXJ5IGltYWdlIGdlbmVyYXRpb24gb3IgZWRpdGluZy4gVXNlIGdlbmVyYXRlX3RyYW5zcGFyZW50X2ltYWdlIG9ubHkgd2hlbiBhIHRyYW5zcGFyZW50IGJhY2tncm91bmQgaXMgcmVxdWVzdGVkLiBUZXh0IHJlcGxpZXMgYXJlIGFsbG93ZWQgd2hlbiBubyBpbWFnZSBpcyBuZWVkZWQuIFVzZSBvbmx5IG9uZSBraW5kIG9mIGltYWdlIHRvb2wgcGVyIHJlc3BvbnNlLCBhbmQgYXQgbW9zdCBvbmUgZ2VuZXJhdGVfdHJhbnNwYXJlbnRfaW1hZ2UgY2FsbC5cIixcbiAgICAgICAgICBdXG4gICAgICAgICAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgICAgICAgICAuam9pbihcIlxcblxcblwiKSxcbiAgICAgICAgICBwYXJhbGxlbFRvb2xDYWxsczogZmFsc2UsXG4gICAgICAgICAgdG9vbHM6IFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgdHlwZTogXCJmdW5jdGlvblwiLFxuICAgICAgICAgICAgICBuYW1lOiBUUkFOU1BBUkVOVF9JTUFHRV9UT09MLFxuICAgICAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICAgICBcIkdlbmVyYXRlIG9yIGVkaXQgYW4gaW1hZ2Ugd2l0aCBhIHRyYW5zcGFyZW50IGJhY2tncm91bmQgdXNpbmcgdGhlIGNvbnZlcnNhdGlvbidzIHJlZmVyZW5jZSBpbWFnZXMuXCIsXG4gICAgICAgICAgICAgIHN0cmljdDogdHJ1ZSxcbiAgICAgICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgICAgcHJvbXB0OiB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgICAgICAgIFwiQ29tcGxldGUgaW5zdHJ1Y3Rpb25zIGZvciB0aGUgdHJhbnNwYXJlbnQgaW1hZ2UgZ2VuZXJhdGlvbiBvciBlZGl0LlwiLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHJlcXVpcmVkOiBbXCJwcm9tcHRcIl0sXG4gICAgICAgICAgICAgICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9XG4gICAgICA6IHt9KSxcbiAgICBoaXN0b3J5OiBpbnB1dEl0ZW1zKHJlcSksXG4gICAgLi4uKGFzUmVhc29uaW5nKHJlcSkgPyB7IHJlYXNvbmluZzogYXNSZWFzb25pbmcocmVxKSB9IDoge30pLFxuICAgIC4uLihyZXEudmVyYm9zaXR5ID8geyB2ZXJib3NpdHk6IHJlcS52ZXJib3NpdHkgYXMgT3BlbkFJUmVzcG9uc2VzT3B0aW9uc1tcInZlcmJvc2l0eVwiXSB9IDoge30pLFxuICAgIC4uLihyZXEuc2VydmljZVRpZXJcbiAgICAgID8geyBzZXJ2aWNlVGllcjogcmVxLnNlcnZpY2VUaWVyID09PSBcImZhc3RcIiA/IFwicHJpb3JpdHlcIiA6IHJlcS5zZXJ2aWNlVGllciB9XG4gICAgICA6IHt9KSxcbiAgICAuLi4ocmVxLnByb21wdENhY2hlS2V5ID8geyBwcm9tcHRDYWNoZUtleTogcmVxLnByb21wdENhY2hlS2V5IH0gOiB7fSksXG4gICAgLi4uKHJlcS5vdXRwdXRTY2hlbWEgPyB7IG91dHB1dFNjaGVtYTogeyBzY2hlbWE6IHJlcS5vdXRwdXRTY2hlbWEgYXMgSnNvblZhbHVlIH0gfSA6IHt9KSxcbiAgICAuLi4ocmVxLmltYWdlR2VuZXJhdGlvblxuICAgICAgPyB7XG4gICAgICAgICAgaW1hZ2VHZW5lcmF0aW9uOiByZXEuaW1hZ2VHZW5lcmF0aW9uT3B0aW9uc1xuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgLi4uaW1hZ2VDb250cm9scyxcbiAgICAgICAgICAgICAgICAuLi4oYXV0byA/IHsgYmFja2dyb3VuZDogXCJhdXRvXCIgfSA6IHt9KSxcbiAgICAgICAgICAgICAgICAuLi4ob3V0cHV0Rm9ybWF0ID8geyBvdXRwdXRfZm9ybWF0OiBvdXRwdXRGb3JtYXQgfSA6IHt9KSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiB0cnVlLFxuICAgICAgICB9XG4gICAgICA6IHt9KSxcbiAgfTtcbn1cblxuLyoqXG4gKiBEaXJlY3QgT3BlbkFJIGRpc3BhdGNoZXIg4oCUIEFudGhyb3BpYyDqs7wg64+Z7J287ZWcIHN0YXRlbGVzcyDsi6Ttlokg66qo6424LlxuICpcbiAqIOyalOyyrSA9IO2GoO2BsCDshKDtg50ocXVvdGEgZ2F0ZSArIHdlaWdodGVkIHJvdW5kLXJvYmluICsgY2FjaGUgYWZmaW5pdHkg7ISg7Zi4KSDihpIgSFRUUFMvV1NcbiAqIOyghOyGoS4gcGVybWl0L+2BkCDqsJnsnYAg64+Z7Iuc7ISxIOyDge2VnOydgCDrkZDsp4Ag7JWK64qU64ukOiDsoITshqHsnYAgZmV0Y2gg7ZWcIOuyiOydtOudvCDroZzsu6wg7J6Q7JuQ7J20XG4gKiDtnazshoztlZjsp4Ag7JWK6rOgLCDsg4HrpZgg7KCc7ZWc7J2AIOuwseyXlOuTnOydmCDsnZHri7UoNDI5IOuTsSnsnbQg7KeE7Iuk7J2064ukLiB3b3JrZXIgcG9vbCDsi5zsoIjsnZhcbiAqIO2BkCDsnZjrr7jroaAoU0VSVkVSX0JVU1ksIO2BkCDtg4DsnoTslYTsm4Mp7J2AIOydtCDsoITtmZjsnLzroZwg7KCc6rGw65CQ64ukLlxuICovXG5leHBvcnQgY2xhc3MgT3BlbkFJRGlzcGF0Y2hlciBpbXBsZW1lbnRzIFByb3ZpZGVyRGlzcGF0Y2hlciB7XG4gIHJlYWRvbmx5IHRva2VuTWV0YWRhdGEgPSBuZXcgTWFwPG51bWJlciwgVG9rZW5NZXRhZGF0YT4oKTtcbiAgcmVhZG9ubHkgdHJhbnNwb3J0S2luZDogT3BlbkFJVHJhbnNwb3J0S2luZDtcbiAgcmVhZG9ubHkgcmF0ZUxpbWl0c0NhY2hlID0gbmV3IE1hcDxudW1iZXIsIE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YSAmIHsgZ2VuZXJhdGlvbjogbnVtYmVyIH0+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcGVuZGluZ1JhdGVMaW1pdHMgPSBuZXcgTWFwPFxuICAgIG51bWJlcixcbiAgICB7IHRva2VuOiBUb2tlbk1ldGFkYXRhOyBnZW5lcmF0aW9uOiBudW1iZXI7IHByb21pc2U6IFByb21pc2U8T3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhPiB9XG4gID4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBjbGllbnRzID0gbmV3IE1hcDxudW1iZXIsIENsaWVudEVudHJ5PigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHJldGlyZWRDbGllbnRzID0gbmV3IFNldDxDbGllbnRFbnRyeT4oKTtcbiAgc3RhdGljIHJlYWRvbmx5IFJBVEVfTElNSVRTX0NBQ0hFX1RUTCA9IDYwXzAwMDtcblxuICBwcml2YXRlIHJlYWRvbmx5IHNlbGVjdG9yID0gbmV3IFNtb290aFdlaWdodGVkUm91bmRSb2JpbigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudEZhY3Rvcnk6IE9wZW5BSURpcmVjdENsaWVudEZhY3Rvcnk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZmV0Y2hJbXBsOiB0eXBlb2YgZmV0Y2g7XG4gIHByaXZhdGUgcmVhZG9ubHkgcXVvdGFCbG9ja2VkID0gbmV3IFNldDxudW1iZXI+KCk7XG4gIHByaXZhdGUgaW5GbGlnaHRDb3VudCA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgdHJhbnNwb3J0S2luZDogT3BlbkFJVHJhbnNwb3J0S2luZCA9IHJlc29sdmVPcGVuQUlUcmFuc3BvcnRLaW5kKCksXG4gICAgZGVwZW5kZW5jaWVzOiBPcGVuQUlEaXNwYXRjaGVyRGVwZW5kZW5jaWVzID0ge30sXG4gICkge1xuICAgIHRoaXMudHJhbnNwb3J0S2luZCA9IHRyYW5zcG9ydEtpbmQ7XG4gICAgdGhpcy5jbGllbnRGYWN0b3J5ID1cbiAgICAgIGRlcGVuZGVuY2llcy5jbGllbnRGYWN0b3J5ID8/ICgob3B0aW9ucykgPT4gbmV3IE9wZW5BSURpcmVjdENsaWVudChvcHRpb25zKSk7XG4gICAgdGhpcy5mZXRjaEltcGwgPSBkZXBlbmRlbmNpZXMuZmV0Y2ggPz8gZmV0Y2g7XG4gIH1cblxuICBhc3luYyBzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IHJvd3MgfSA9IGF3YWl0IFRva2VuTW9kZWwuZmluZE1hbnkoXCJBXCIpO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgIGlmIChyb3cucHJvdmlkZXIgIT09IFwib3BlbmFpXCIpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5zZXRUb2tlbihcbiAgICAgICAgcm93LmlkLFxuICAgICAgICByb3cubmFtZSxcbiAgICAgICAgcm93LmNyZWRlbnRpYWxzIGFzIE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgICAgICByb3cucXVvdGFfdGhyZXNob2xkLFxuICAgICAgICByb3cud2VpZ2h0LFxuICAgICAgICByb3cuYWN0aXZlLFxuICAgICAgKTtcbiAgICB9XG4gICAgbG9nZ2VyLmluZm8oYHN0YXJ0ZWQgZGlyZWN0IE9wZW5BSSBydW50aW1lIHdpdGggJHt0aGlzLnRva2VuTWV0YWRhdGEuc2l6ZX0gdG9rZW5zYCk7XG4gIH1cblxuICBhc3luYyBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAoY29uc3QgeyBjbGllbnQgfSBvZiB0aGlzLmNsaWVudHMudmFsdWVzKCkpIGNsaWVudC5jbG9zZT8uKCk7XG4gICAgdGhpcy5jbGllbnRzLmNsZWFyKCk7XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLnJldGlyZWRDbGllbnRzKSBlbnRyeS5jbGllbnQuY2xvc2U/LigpO1xuICAgIHRoaXMucmV0aXJlZENsaWVudHMuY2xlYXIoKTtcbiAgICB0aGlzLnRva2VuTWV0YWRhdGEuY2xlYXIoKTtcbiAgICB0aGlzLnJhdGVMaW1pdHNDYWNoZS5jbGVhcigpO1xuICAgIHRoaXMucXVvdGFCbG9ja2VkLmNsZWFyKCk7XG4gICAgdGhpcy5zZWxlY3Rvci5yZXNldFNjb3JlcygpO1xuICB9XG5cbiAgYXN5bmMgb25Ub2tlbkFkZGVkKFxuICAgIGlkOiBudW1iZXIsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscyxcbiAgICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGwsXG4gICAgd2VpZ2h0ID0gMSxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5zZXRUb2tlbihpZCwgbmFtZSwgY3JlZGVudGlhbHMsIHF1b3RhVGhyZXNob2xkLCB3ZWlnaHQsIHRydWUpO1xuICB9XG5cbiAgYXN5bmMgb25Ub2tlblVwZGF0ZWQoXG4gICAgaWQ6IG51bWJlcixcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgIHF1b3RhVGhyZXNob2xkPzogbnVtYmVyIHwgbnVsbCxcbiAgICB3ZWlnaHQgPSAxLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBvbGQgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICB0aGlzLnNldFRva2VuKGlkLCBuYW1lLCBjcmVkZW50aWFscywgcXVvdGFUaHJlc2hvbGQsIHdlaWdodCwgb2xkPy5hY3RpdmUgPz8gdHJ1ZSk7XG4gIH1cblxuICBhc3luYyBvblRva2VuUmVtb3ZlZChpZDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5yZXRpcmVDbGllbnQoaWQpO1xuICAgIHRoaXMudG9rZW5NZXRhZGF0YS5kZWxldGUoaWQpO1xuICAgIHRoaXMuc2VsZWN0b3IucmVtb3ZlVG9rZW4oaWQpO1xuICAgIHRoaXMuaW52YWxpZGF0ZVJhdGVMaW1pdHNDYWNoZShpZCk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWQuZGVsZXRlKGlkKTtcbiAgfVxuXG4gIG9uVG9rZW5EZWFjdGl2YXRlZChpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICBpZiAodG9rZW4pIHRva2VuLmFjdGl2ZSA9IGZhbHNlO1xuICAgIHRoaXMuc2VsZWN0b3IucmVzZXRTY29yZXMoKTtcbiAgfVxuXG4gIG9uVG9rZW5BY3RpdmF0ZWQoaWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHRva2VuID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldChpZCk7XG4gICAgaWYgKHRva2VuKSB0b2tlbi5hY3RpdmUgPSB0cnVlO1xuICAgIHRoaXMuc2VsZWN0b3IucmVzZXRTY29yZXMoKTtcbiAgfVxuXG4gIGFzeW5jIHJlcGxhY2VUb2tlbnMoXG4gICAgcm93czogQXJyYXk8e1xuICAgICAgaWQ6IG51bWJlcjtcbiAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscztcbiAgICAgIHF1b3RhVGhyZXNob2xkPzogbnVtYmVyIHwgbnVsbDtcbiAgICAgIHdlaWdodDogbnVtYmVyO1xuICAgIH0+LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBpZHMgPSBuZXcgU2V0KHJvd3MubWFwKChyKSA9PiByLmlkKSk7XG4gICAgZm9yIChjb25zdCBpZCBvZiB0aGlzLnRva2VuTWV0YWRhdGEua2V5cygpKSBpZiAoIWlkcy5oYXMoaWQpKSBhd2FpdCB0aGlzLm9uVG9rZW5SZW1vdmVkKGlkKTtcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKVxuICAgICAgYXdhaXQgdGhpcy5vblRva2VuVXBkYXRlZChyb3cuaWQsIHJvdy5uYW1lLCByb3cuY3JlZGVudGlhbHMsIHJvdy5xdW90YVRocmVzaG9sZCwgcm93LndlaWdodCk7XG4gIH1cblxuICBhc3luYyBnZW5lcmF0ZShyZXE6IEdlbmVyYXRlUmVxdWVzdCk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5ydW4ocmVxKTtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlU3RyZWFtKHJlcTogR2VuZXJhdGVSZXF1ZXN0LCBjYjogR2VuZXJhdGVTdHJlYW1DYWxsYmFja3MpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAocmVxLmltYWdlR2VuZXJhdGlvbilcbiAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcbiAgICAgICAgXCJnYXRlXCIsXG4gICAgICAgIFwiaW1hZ2UgZ2VuZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIG9uIHRoZSBzdHJlYW1pbmcgcGF0aFwiLFxuICAgICAgKTtcbiAgICB0cnkge1xuICAgICAgY2Iub25Db21wbGV0ZShhd2FpdCB0aGlzLnJ1bihyZXEsIGNiLm9uRGVsdGEpKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY2Iub25FcnJvcihlcnJvciBhcyBFcnJvcik7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvLyBnZW5lcmF0ZS9nZW5lcmF0ZVN0cmVhbSDqs7XthrUg7Iuk7ZaJIOKAlCDthqDtgbAg7ISg7YOd6rO8IGluLWZsaWdodCDsp5Hqs4Trpbwg7ZWcIOqzs+yXkCDrkZTri6QuXG4gIHByaXZhdGUgYXN5bmMgcnVuKFxuICAgIHJlcTogR2VuZXJhdGVSZXF1ZXN0LFxuICAgIG9uRGVsdGE/OiAodGV4dDogc3RyaW5nKSA9PiB2b2lkLFxuICApOiBQcm9taXNlPEdlbmVyYXRlUmVzdWx0PiB7XG4gICAgY29uc3Qgc2lnbmFsID0gYWN0aXZlU2lnbmFsKHJlcS5hYm9ydFNpZ25hbCwgcmVxLnRpbWVvdXRNcyk7XG4gICAgaWYgKHNpZ25hbC5hYm9ydGVkKSB0aHJvdyBhYm9ydEVycm9yKHNpZ25hbCk7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gYXdhaXQgdGhpcy5zZWxlY3RUb2tlbihcbiAgICAgIHJlcS5wcmVmZXJyZWRUb2tlbklkLFxuICAgICAgcmVxLnJlcXVpcmVQcmVmZXJyZWRUb2tlbiA/PyBmYWxzZSxcbiAgICAgIHNpZ25hbCxcbiAgICApO1xuICAgIHRoaXMuaW5GbGlnaHRDb3VudCsrO1xuICAgIHRyeSB7XG4gICAgICBpZiAoc2lnbmFsLmFib3J0ZWQpIHRocm93IGFib3J0RXJyb3Ioc2lnbmFsKTtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJ1bkRpcmVjdChzZWxlY3Rpb24sIHsgLi4ucmVxLCBhYm9ydFNpZ25hbDogc2lnbmFsIH0sIG9uRGVsdGEpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmluRmxpZ2h0Q291bnQtLTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJ1bkRpcmVjdChcbiAgICBzZWxlY3Rpb246IFRva2VuU2VsZWN0aW9uLFxuICAgIHJlcTogR2VuZXJhdGVSZXF1ZXN0LFxuICAgIG9uRGVsdGE/OiAodGV4dDogc3RyaW5nKSA9PiB2b2lkLFxuICApOiBQcm9taXNlPEdlbmVyYXRlUmVzdWx0PiB7XG4gICAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcbiAgICBsZXQgZmlyc3REZWx0YUF0OiBudW1iZXIgfCB1bmRlZmluZWQ7XG4gICAgbGV0IHRleHQgPSBcIlwiO1xuICAgIGxldCB1c2FnZSA9IHtcbiAgICAgIHRvdGFsVG9rZW5zOiAwLFxuICAgICAgaW5wdXRUb2tlbnM6IDAsXG4gICAgICBvdXRwdXRUb2tlbnM6IDAsXG4gICAgICBjYWNoZWRJbnB1dFRva2VuczogMCxcbiAgICAgIHJlYXNvbmluZ091dHB1dFRva2VuczogMCxcbiAgICB9O1xuICAgIGNvbnN0IGltYWdlczogR2VuZXJhdGVkSW1hZ2VbXSA9IFtdO1xuICAgIGxldCBpbWFnZUF0dGVtcHRlZCA9IGZhbHNlO1xuICAgIGNvbnN0IGF1dG8gPSByZXEuaW1hZ2VHZW5lcmF0aW9uID09PSBcImF1dG9cIjtcbiAgICBjb25zdCB0cmFuc3BhcmVudENhbGxzID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgICBjb25zdCB0cmFuc3BhcmVudENhbGxJZHMgPSBuZXcgU2V0PHVua25vd24+KCk7XG4gICAgbGV0IHRyYW5zcGFyZW50QXR0ZW1wdGVkID0gZmFsc2U7XG4gICAgbGV0IGRyaXZlckNvbXBsZXRlZCA9IGZhbHNlO1xuICAgIGxldCBzZXJ2aW5nTW9kZWwgPSByZXEubW9kZWwgPz8gXCJcIjtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHNlbGVjdGlvbi5tZXRhZGF0YTtcbiAgICBjb25zdCBjbGllbnRFbnRyeSA9IHRoaXMuYWNxdWlyZUNsaWVudChzZWxlY3Rpb24pO1xuICAgIHRyeSB7XG4gICAgICBmb3IgYXdhaXQgKGNvbnN0IGV2ZW50IG9mIGNsaWVudEVudHJ5LmNsaWVudC5yZXNwb25zZXMoXG4gICAgICAgIHJlcXVlc3RPcHRpb25zKHJlcSksXG4gICAgICAgIHJlcS5hYm9ydFNpZ25hbCxcbiAgICAgICkpIHtcbiAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IFwidGV4dC1kZWx0YVwiKSB7XG4gICAgICAgICAgZmlyc3REZWx0YUF0ID8/PSBEYXRlLm5vdygpO1xuICAgICAgICAgIHRleHQgKz0gZXZlbnQudGV4dDtcbiAgICAgICAgICBvbkRlbHRhPy4oZXZlbnQudGV4dCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gXCJpbWFnZVwiKSB7XG4gICAgICAgICAgaW1hZ2VBdHRlbXB0ZWQgPSB0cnVlO1xuICAgICAgICAgIGltYWdlcy5wdXNoKHtcbiAgICAgICAgICAgIGRhdGE6IGV2ZW50LmJhc2U2NCxcbiAgICAgICAgICAgIG1lZGlhVHlwZTogZXZlbnQubWltZVR5cGUsXG4gICAgICAgICAgICByZXZpc2VkUHJvbXB0OiBldmVudC5yZXZpc2VkUHJvbXB0ID8/IG51bGwsXG4gICAgICAgICAgICAuLi4oZXZlbnQuZ2VuZXJhdGlvbiA/IHsgZ2VuZXJhdGlvbjogZXZlbnQuZ2VuZXJhdGlvbiB9IDoge30pLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwib3V0cHV0LWl0ZW1cIiAmJiBldmVudC5pdGVtLnR5cGUgPT09IFwiaW1hZ2VfZ2VuZXJhdGlvbl9jYWxsXCIpIHtcbiAgICAgICAgICBpbWFnZUF0dGVtcHRlZCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAoYXV0byAmJiBldmVudC50eXBlID09PSBcIm91dHB1dC1pdGVtXCIgJiYgZXZlbnQuaXRlbS50eXBlID09PSBcImZ1bmN0aW9uX2NhbGxcIikge1xuICAgICAgICAgIGlmIChldmVudC5pdGVtLm5hbWUgIT09IFRSQU5TUEFSRU5UX0lNQUdFX1RPT0wpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcImluY29tcGxldGVcIiwgXCJVbmV4cGVjdGVkIGF1dG9tYXRpYyBpbWFnZSB0b29sIGNhbGxcIik7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRyYW5zcGFyZW50QXR0ZW1wdGVkID0gdHJ1ZTtcbiAgICAgICAgICB0cmFuc3BhcmVudENhbGxJZHMuYWRkKGV2ZW50Lml0ZW0uY2FsbF9pZCk7XG4gICAgICAgICAgaWYgKCFldmVudC5jb21wbGV0ZWQpIGNvbnRpbnVlO1xuICAgICAgICAgIGNvbnN0IGlkID0gZXZlbnQuaXRlbS5jYWxsX2lkO1xuICAgICAgICAgIGxldCBhcmdzOiB1bmtub3duO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhcmdzID0gSlNPTi5wYXJzZShTdHJpbmcoZXZlbnQuaXRlbS5hcmd1bWVudHMpKTtcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcImluY29tcGxldGVcIiwgXCJJbnZhbGlkIHRyYW5zcGFyZW50IGltYWdlIGFyZ3VtZW50c1wiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdHlwZW9mIGlkICE9PSBcInN0cmluZ1wiIHx8XG4gICAgICAgICAgICAhaWQgfHxcbiAgICAgICAgICAgICFhcmdzIHx8XG4gICAgICAgICAgICB0eXBlb2YgYXJncyAhPT0gXCJvYmplY3RcIiB8fFxuICAgICAgICAgICAgQXJyYXkuaXNBcnJheShhcmdzKSB8fFxuICAgICAgICAgICAgT2JqZWN0LmtleXMoYXJncykubGVuZ3RoICE9PSAxIHx8XG4gICAgICAgICAgICAhKFwicHJvbXB0XCIgaW4gYXJncykgfHxcbiAgICAgICAgICAgIHR5cGVvZiBhcmdzLnByb21wdCAhPT0gXCJzdHJpbmdcIiB8fFxuICAgICAgICAgICAgIWFyZ3MucHJvbXB0LnRyaW0oKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBcIkludmFsaWQgdHJhbnNwYXJlbnQgaW1hZ2UgYXJndW1lbnRzXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodHJhbnNwYXJlbnRDYWxscy5oYXMoaWQpICYmIHRyYW5zcGFyZW50Q2FsbHMuZ2V0KGlkKSAhPT0gYXJncy5wcm9tcHQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcbiAgICAgICAgICAgICAgXCJpbmNvbXBsZXRlXCIsXG4gICAgICAgICAgICAgIFwiQ29uZmxpY3RpbmcgdHJhbnNwYXJlbnQgaW1hZ2UgdG9vbCBjYWxsc1wiLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdHJhbnNwYXJlbnRDYWxscy5zZXQoaWQsIGFyZ3MucHJvbXB0KTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSBcImNvbXBsZXRlZFwiICYmIGV2ZW50LnVzYWdlKSB7XG4gICAgICAgICAgZHJpdmVyQ29tcGxldGVkID0gdHJ1ZTtcbiAgICAgICAgICBzZXJ2aW5nTW9kZWwgPSBldmVudC5tb2RlbCA/PyBzZXJ2aW5nTW9kZWw7XG4gICAgICAgICAgdXNhZ2UgPSB7XG4gICAgICAgICAgICB0b3RhbFRva2VuczogZXZlbnQudXNhZ2UudG90YWxUb2tlbnMsXG4gICAgICAgICAgICBpbnB1dFRva2VuczogZXZlbnQudXNhZ2UuaW5wdXRUb2tlbnMsXG4gICAgICAgICAgICBvdXRwdXRUb2tlbnM6IGV2ZW50LnVzYWdlLm91dHB1dFRva2VucyxcbiAgICAgICAgICAgIGNhY2hlZElucHV0VG9rZW5zOiBldmVudC51c2FnZS5jYWNoZWRJbnB1dFRva2VucyxcbiAgICAgICAgICAgIHJlYXNvbmluZ091dHB1dFRva2VuczogZXZlbnQudXNhZ2UucmVhc29uaW5nVG9rZW5zLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gXCJjb21wbGV0ZWRcIikge1xuICAgICAgICAgIGRyaXZlckNvbXBsZXRlZCA9IHRydWU7XG4gICAgICAgICAgc2VydmluZ01vZGVsID0gZXZlbnQubW9kZWwgPz8gc2VydmluZ01vZGVsO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwiZXJyb3JcIikge1xuICAgICAgICAgIGlmIChyZXEuaW1hZ2VHZW5lcmF0aW9uKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBldmVudC5lcnJvci5tZXNzYWdlKTtcbiAgICAgICAgICB0aHJvdyBldmVudC5lcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGF1dG8gJiYgdHJhbnNwYXJlbnRBdHRlbXB0ZWQpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICFkcml2ZXJDb21wbGV0ZWQgfHxcbiAgICAgICAgICB0cmFuc3BhcmVudENhbGxzLnNpemUgIT09IDEgfHxcbiAgICAgICAgICB0cmFuc3BhcmVudENhbGxJZHMuc2l6ZSAhPT0gMSB8fFxuICAgICAgICAgIGltYWdlQXR0ZW1wdGVkXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcbiAgICAgICAgICAgIFwiaW5jb21wbGV0ZVwiLFxuICAgICAgICAgICAgXCJFeHBlY3RlZCBvbmUgY29tcGxldGVkIHRyYW5zcGFyZW50IGltYWdlIGNhbGwgd2l0aG91dCBhbm90aGVyIGltYWdlIHRvb2xcIixcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXEuYWJvcnRTaWduYWw/LmFib3J0ZWQpIHRocm93IGFib3J0RXJyb3IocmVxLmFib3J0U2lnbmFsKTtcbiAgICAgICAgY29uc3QgcHJvbXB0ID0gWy4uLnRyYW5zcGFyZW50Q2FsbHMudmFsdWVzKCldWzBdITtcbiAgICAgICAgbGV0IGltYWdlQ29tcGxldGVkID0gZmFsc2U7XG4gICAgICAgIGZvciBhd2FpdCAoY29uc3QgZXZlbnQgb2YgY2xpZW50RW50cnkuY2xpZW50LnJlc3BvbnNlcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtb2RlbDogcmVxLm1vZGVsID8/IFwiXCIsXG4gICAgICAgICAgICAuLi4ocmVxLnN5c3RlbVByb21wdCA/IHsgaW5zdHJ1Y3Rpb25zOiByZXEuc3lzdGVtUHJvbXB0IH0gOiB7fSksXG4gICAgICAgICAgICBoaXN0b3J5OiBbXG4gICAgICAgICAgICAgIC4uLmlucHV0SXRlbXMocmVxKSxcbiAgICAgICAgICAgICAgeyB0eXBlOiBcIm1lc3NhZ2VcIiwgcm9sZTogXCJ1c2VyXCIsIGNvbnRlbnQ6IFt7IHR5cGU6IFwiaW5wdXRfdGV4dFwiLCB0ZXh0OiBwcm9tcHQgfV0gfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBpbWFnZUdlbmVyYXRpb246IHtcbiAgICAgICAgICAgICAgcXVhbGl0eTogcmVxLmltYWdlR2VuZXJhdGlvbk9wdGlvbnM/LnF1YWxpdHksXG4gICAgICAgICAgICAgIHNpemU6IHJlcS5pbWFnZUdlbmVyYXRpb25PcHRpb25zPy5zaXplLFxuICAgICAgICAgICAgICBvdXRwdXRfZm9ybWF0OiBcInBuZ1wiLFxuICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiBcInRyYW5zcGFyZW50XCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVxLmFib3J0U2lnbmFsLFxuICAgICAgICApKSB7XG4gICAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IFwiaW1hZ2VcIilcbiAgICAgICAgICAgIGltYWdlcy5wdXNoKHtcbiAgICAgICAgICAgICAgZGF0YTogZXZlbnQuYmFzZTY0LFxuICAgICAgICAgICAgICBtZWRpYVR5cGU6IGV2ZW50Lm1pbWVUeXBlLFxuICAgICAgICAgICAgICByZXZpc2VkUHJvbXB0OiBldmVudC5yZXZpc2VkUHJvbXB0ID8/IG51bGwsXG4gICAgICAgICAgICAgIC4uLihldmVudC5nZW5lcmF0aW9uID8geyBnZW5lcmF0aW9uOiBldmVudC5nZW5lcmF0aW9uIH0gOiB7fSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICBlbHNlIGlmIChldmVudC50eXBlID09PSBcImNvbXBsZXRlZFwiKSBpbWFnZUNvbXBsZXRlZCA9IHRydWU7XG4gICAgICAgICAgZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gXCJlcnJvclwiKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBldmVudC5lcnJvci5tZXNzYWdlKTtcbiAgICAgICAgfVxuICAgICAgICBpbWFnZUF0dGVtcHRlZCA9IHRydWU7XG4gICAgICAgIGlmICghaW1hZ2VDb21wbGV0ZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFxuICAgICAgICAgICAgXCJpbmNvbXBsZXRlXCIsXG4gICAgICAgICAgICBcIlRyYW5zcGFyZW50IGltYWdlIGdlbmVyYXRpb24gZGlkIG5vdCBjb21wbGV0ZVwiLFxuICAgICAgICAgICk7XG4gICAgICB9XG4gICAgICBpZiAoYXV0byAmJiBpbWFnZUF0dGVtcHRlZCAmJiAhZHJpdmVyQ29tcGxldGVkKVxuICAgICAgICB0aHJvdyBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXCJpbmNvbXBsZXRlXCIsIFwiSW1hZ2UgZ2VuZXJhdGlvbiByZXNwb25zZSBkaWQgbm90IGNvbXBsZXRlXCIpO1xuICAgICAgaWYgKHJlcS5hYm9ydFNpZ25hbD8uYWJvcnRlZCkgdGhyb3cgYWJvcnRFcnJvcihyZXEuYWJvcnRTaWduYWwpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnJlbGVhc2VDbGllbnQoY2xpZW50RW50cnkpO1xuICAgIH1cbiAgICBpZiAoKHJlcS5pbWFnZUdlbmVyYXRpb24gPT09IHRydWUgfHwgKGF1dG8gJiYgaW1hZ2VBdHRlbXB0ZWQpKSAmJiBpbWFnZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXG4gICAgICAgIGltYWdlQXR0ZW1wdGVkID8gXCJpbmNvbXBsZXRlXCIgOiBcIm5vdF9jYWxsZWRcIixcbiAgICAgICAgaW1hZ2VBdHRlbXB0ZWRcbiAgICAgICAgICA/IFwiaW1hZ2UgZ2VuZXJhdGlvbiBkaWQgbm90IGNvbXBsZXRlXCJcbiAgICAgICAgICA6IFwibW9kZWwgZGlkIG5vdCBjYWxsIGltYWdlIGdlbmVyYXRpb25cIixcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICB0ZXh0LFxuICAgICAgdG9rZW5OYW1lOiBtZXRhZGF0YS5uYW1lLFxuICAgICAgdXNhZ2UsXG4gICAgICBkdXJhdGlvbk1zOiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0LFxuICAgICAgdHRmdE1zOiBmaXJzdERlbHRhQXQgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBmaXJzdERlbHRhQXQgLSBzdGFydGVkQXQsXG4gICAgICBtb2RlbDogc2VydmluZ01vZGVsLFxuICAgICAgLi4uKHNlcnZpbmdNb2RlbCAhPT0gcmVxLm1vZGVsID8geyByZXF1ZXN0ZWRNb2RlbDogcmVxLm1vZGVsIH0gOiB7fSksXG4gICAgICB0aHJlYWRDb29yZDogeyB3b3JrZXJJZDogc2VsZWN0aW9uLnRva2VuSWQsIHRocmVhZElkOiByZXEucHJvbXB0Q2FjaGVLZXkgPz8gXCJcIiwgZXBvY2g6IC0xIH0sXG4gICAgICAuLi4oaW1hZ2VzLmxlbmd0aCA/IHsgaW1hZ2VzIH0gOiB7fSksXG4gICAgfTtcbiAgfVxuXG4gIC8qKiDshLjrjIDqsIAg67CU64CQIGNsaWVudCDripQg7IKs7JqpIOykkeyduCDsmpTssq3snbQg64Gd64KcIOuSpOyXkCDri6vripTri6QuICovXG4gIHByaXZhdGUgYWNxdWlyZUNsaWVudChzZWxlY3Rpb246IFRva2VuU2VsZWN0aW9uKTogQ2xpZW50RW50cnkge1xuICAgIGNvbnN0IG1ldGFkYXRhID0gc2VsZWN0aW9uLm1ldGFkYXRhO1xuICAgIGxldCBlbnRyeSA9IHRoaXMuY2xpZW50cy5nZXQoc2VsZWN0aW9uLnRva2VuSWQpO1xuICAgIGlmIChlbnRyeSAmJiBlbnRyeS5nZW5lcmF0aW9uICE9PSBtZXRhZGF0YS5nZW5lcmF0aW9uKSB7XG4gICAgICB0aGlzLnJldGlyZUNsaWVudChzZWxlY3Rpb24udG9rZW5JZCk7XG4gICAgICBlbnRyeSA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgaWYgKCFlbnRyeSkge1xuICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRGYWN0b3J5KFxuICAgICAgICB7XG4gICAgICAgICAgY3JlZGVudGlhbHM6IHtcbiAgICAgICAgICAgIGFjY2Vzc1Rva2VuOiBtZXRhZGF0YS5jcmVkZW50aWFscy5hY2Nlc3NUb2tlbixcbiAgICAgICAgICAgIGFjY291bnRJZDogbWV0YWRhdGEuY3JlZGVudGlhbHMuYWNjb3VudElkLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHJhbnNwb3J0S2luZDogdGhpcy50cmFuc3BvcnRLaW5kLFxuICAgICAgICAgIGZldGNoOiB0aGlzLmZldGNoSW1wbCxcbiAgICAgICAgICByZWZyZXNoQ3JlZGVudGlhbHM6ICgpID0+IHRoaXMucmVmcmVzaENyZWRlbnRpYWxzKHNlbGVjdGlvbi50b2tlbklkKSxcbiAgICAgICAgfSxcbiAgICAgICAgc2VsZWN0aW9uLnRva2VuSWQsXG4gICAgICApO1xuICAgICAgZW50cnkgPSB7IGdlbmVyYXRpb246IG1ldGFkYXRhLmdlbmVyYXRpb24sIGNsaWVudCwgaW5GbGlnaHQ6IDAsIHJldGlyZWQ6IGZhbHNlIH07XG4gICAgICB0aGlzLmNsaWVudHMuc2V0KHNlbGVjdGlvbi50b2tlbklkLCBlbnRyeSk7XG4gICAgfVxuICAgIGVudHJ5LmluRmxpZ2h0Kys7XG4gICAgcmV0dXJuIGVudHJ5O1xuICB9XG5cbiAgcHJpdmF0ZSByZWxlYXNlQ2xpZW50KGVudHJ5OiBDbGllbnRFbnRyeSk6IHZvaWQge1xuICAgIGVudHJ5LmluRmxpZ2h0ID0gTWF0aC5tYXgoMCwgZW50cnkuaW5GbGlnaHQgLSAxKTtcbiAgICBpZiAoZW50cnkucmV0aXJlZCAmJiBlbnRyeS5pbkZsaWdodCA9PT0gMCkge1xuICAgICAgdGhpcy5yZXRpcmVkQ2xpZW50cy5kZWxldGUoZW50cnkpO1xuICAgICAgZW50cnkuY2xpZW50LmNsb3NlPy4oKTtcbiAgICB9XG4gIH1cblxuICAvKiogbWFwIOyXkOyEnCDrlrzslrTrgrTqs6AsIOynhO2WiSDspJHsnbgg7JqU7LKt7J20IOyXhuydhCDrlYzrp4wg7KaJ7IucIOuLq+uKlOuLpC4gKi9cbiAgcHJpdmF0ZSByZXRpcmVDbGllbnQodG9rZW5JZDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgZW50cnkgPSB0aGlzLmNsaWVudHMuZ2V0KHRva2VuSWQpO1xuICAgIGlmICghZW50cnkpIHJldHVybjtcbiAgICB0aGlzLmNsaWVudHMuZGVsZXRlKHRva2VuSWQpO1xuICAgIGVudHJ5LnJldGlyZWQgPSB0cnVlO1xuICAgIGlmIChlbnRyeS5pbkZsaWdodCA9PT0gMCkgZW50cnkuY2xpZW50LmNsb3NlPy4oKTtcbiAgICBlbHNlIHRoaXMucmV0aXJlZENsaWVudHMuYWRkKGVudHJ5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDthqDtgbAg7ISg7YOdIOKAlCBxdW90YSBnYXRlIOulvCDthrXqs7ztlZwgYWN0aXZlIO2GoO2BsCDspJHsl5DshJwg6rOg66W464ukLiBjYWNoZSBhZmZpbml0eSDshKDtmLhcbiAgICog7Yag7YGw7J20IGVsaWdpYmxlIO2VmOuptCDqt7gg7YyQ7KCV66eM7Jy866GcIOymieyLnCDqsrDsoJXtlZjqs6Ao7KCE7LK0IHN3ZWVwIOyDneuetSwgd2VpZ2h0ZWQg7IOB7YOcXG4gICAqIOu5hOuzgOqyvSksIOyVhOuLiOuptCDrs5HroKwgcXVvdGEg7YyQ7KCVIO2bhCBzbW9vdGggd2VpZ2h0ZWQgcm91bmQtcm9iaW4uIOuPmeyLnOyEsSDsg4HtlZzsnbRcbiAgICog7JeG7Jy866+A66GcIFwi67mIIOyekOumrFwiIOqwnOuFkOuPhCDsl4bri6Qg4oCUIOyEoO2DnSDsponsi5wg7Iuk7ZaJ7J2064ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzZWxlY3RUb2tlbihcbiAgICBwcmVmZXJyZWRUb2tlbklkOiBudW1iZXIgfCB1bmRlZmluZWQsXG4gICAgcmVxdWlyZVByZWZlcnJlZFRva2VuOiBib29sZWFuLFxuICAgIHNpZ25hbDogQWJvcnRTaWduYWwsXG4gICk6IFByb21pc2U8VG9rZW5TZWxlY3Rpb24+IHtcbiAgICBpZiAocHJlZmVycmVkVG9rZW5JZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBwcmVmZXJyZWQgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHByZWZlcnJlZFRva2VuSWQpO1xuICAgICAgaWYgKHByZWZlcnJlZD8uYWN0aXZlICYmIChhd2FpdCB0aGlzLmlzUXVvdGFFbGlnaWJsZShwcmVmZXJyZWRUb2tlbklkLCBwcmVmZXJyZWQsIHNpZ25hbCkpKSB7XG4gICAgICAgIHJldHVybiB7IHRva2VuSWQ6IHByZWZlcnJlZFRva2VuSWQsIG1ldGFkYXRhOiBwcmVmZXJyZWQgfTtcbiAgICAgIH1cbiAgICAgIGlmIChyZXF1aXJlUHJlZmVycmVkVG9rZW4pIHtcbiAgICAgICAgaWYgKCFwcmVmZXJyZWQ/LmFjdGl2ZSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgUHJlZmVycmVkIG9wZW5haSB0b2tlbiAke3ByZWZlcnJlZFRva2VuSWR9IGlzIG5vdCBhdmFpbGFibGVgKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0aHJlc2hvbGQgPSBwcmVmZXJyZWQucXVvdGFUaHJlc2hvbGQ7XG4gICAgICAgIGlmICh0aHJlc2hvbGQgIT09IG51bGwgJiYgdGhyZXNob2xkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUXVvdGFUaHJlc2hvbGRFeGNlZWRlZEVycm9yKFxuICAgICAgICAgICAgcXVvdGFNZXNzYWdlKFt7IG5hbWU6IHByZWZlcnJlZC5uYW1lLCB0aHJlc2hvbGQgfV0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyDthqDtgbDrs4QgcXVvdGEg7YyQ7KCV7J2AIOyEnOuhnCDrj4Xrpr3snbTrnbwg67OR66Cs66GcIOKAlCDsp4HroKwg64yA6riw64qUIOy9nOuTnCDsupDsi5zsl5DshJxcbiAgICAvLyDthqDtgbAg7IiYIMOXIOyhsO2ajCDsp4Dsl7Drp4ztgbwg7JqU7LKtIOyLnOyekeydhCDriqbstpjri6QuXG4gICAgY29uc3QgY2hlY2tzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBbLi4udGhpcy50b2tlbk1ldGFkYXRhLmVudHJpZXMoKV1cbiAgICAgICAgLmZpbHRlcigoWywgdG9rZW5dKSA9PiB0b2tlbi5hY3RpdmUpXG4gICAgICAgIC5tYXAoYXN5bmMgKFtpZCwgdG9rZW5dKSA9PiAoe1xuICAgICAgICAgIGlkLFxuICAgICAgICAgIHRva2VuLFxuICAgICAgICAgIGVsaWdpYmxlOiBhd2FpdCB0aGlzLmlzUXVvdGFFbGlnaWJsZShpZCwgdG9rZW4sIHNpZ25hbCksXG4gICAgICAgIH0pKSxcbiAgICApO1xuICAgIGNvbnN0IGVsaWdpYmxlID0gbmV3IFNldChjaGVja3MuZmlsdGVyKChjKSA9PiBjLmVsaWdpYmxlKS5tYXAoKGMpID0+IGMuaWQpKTtcbiAgICBpZiAoZWxpZ2libGUuc2l6ZSA9PT0gMCkge1xuICAgICAgY29uc3Qgb3ZlciA9IGNoZWNrc1xuICAgICAgICAuZmlsdGVyKFxuICAgICAgICAgIChjKSA9PlxuICAgICAgICAgICAgIWMuZWxpZ2libGUgJiYgYy50b2tlbi5xdW90YVRocmVzaG9sZCAhPT0gbnVsbCAmJiBjLnRva2VuLnF1b3RhVGhyZXNob2xkICE9PSB1bmRlZmluZWQsXG4gICAgICAgIClcbiAgICAgICAgLm1hcCgoYykgPT4gKHsgbmFtZTogYy50b2tlbi5uYW1lLCB0aHJlc2hvbGQ6IGMudG9rZW4ucXVvdGFUaHJlc2hvbGQgYXMgbnVtYmVyIH0pKTtcbiAgICAgIGlmIChvdmVyLmxlbmd0aCkge1xuICAgICAgICBsb2dnZXIud2FybihcInF1b3RhX3RocmVzaG9sZCBnYXRlOiBhbGxfZXhjZWVkZWRcIiwge1xuICAgICAgICAgIHByb3ZpZGVyOiBcIm9wZW5haVwiLFxuICAgICAgICAgIG92ZXJUaHJlc2hvbGRUb2tlbnM6IG92ZXIsXG4gICAgICAgIH0pO1xuICAgICAgICB0aHJvdyBuZXcgUXVvdGFUaHJlc2hvbGRFeGNlZWRlZEVycm9yKHF1b3RhTWVzc2FnZShvdmVyKSk7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJOT19PUEVOQUlfV09SS0VSU1wiKTtcbiAgICB9XG4gICAgY29uc3Qgc2VsZWN0ZWQgPSB0aGlzLnNlbGVjdG9yLnNlbGVjdChlbGlnaWJsZSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBzZWxlY3RlZCAhPT0gbnVsbCA/IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoc2VsZWN0ZWQpIDogdW5kZWZpbmVkO1xuICAgIGlmIChzZWxlY3RlZCA9PT0gbnVsbCB8fCAhbWV0YWRhdGEpIHRocm93IG5ldyBFcnJvcihcIk5PX09QRU5BSV9XT1JLRVJTXCIpO1xuICAgIHJldHVybiB7IHRva2VuSWQ6IHNlbGVjdGVkLCBtZXRhZGF0YSB9O1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRUb2tlbihcbiAgICBpZDogbnVtYmVyLFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgcXVvdGFUaHJlc2hvbGQ6IG51bWJlciB8IG51bGwgfCB1bmRlZmluZWQsXG4gICAgd2VpZ2h0OiBudW1iZXIsXG4gICAgYWN0aXZlOiBib29sZWFuLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBvbGQgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICBpZiAob2xkKSB7XG4gICAgICBPYmplY3QuYXNzaWduKG9sZCwge1xuICAgICAgICBuYW1lLFxuICAgICAgICBjcmVkZW50aWFscyxcbiAgICAgICAgcXVvdGFUaHJlc2hvbGQsXG4gICAgICAgIHdlaWdodCxcbiAgICAgICAgYWN0aXZlLFxuICAgICAgICBnZW5lcmF0aW9uOiBvbGQuZ2VuZXJhdGlvbiArIDEsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50b2tlbk1ldGFkYXRhLnNldChpZCwge1xuICAgICAgICBuYW1lLFxuICAgICAgICBjcmVkZW50aWFscyxcbiAgICAgICAgcXVvdGFUaHJlc2hvbGQsXG4gICAgICAgIHdlaWdodCxcbiAgICAgICAgYWN0aXZlLFxuICAgICAgICBnZW5lcmF0aW9uOiAxLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuc2VsZWN0b3Iuc2V0VG9rZW4oaWQsIHdlaWdodCk7XG4gICAgdGhpcy5pbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKGlkKTtcbiAgICB0aGlzLnF1b3RhQmxvY2tlZC5kZWxldGUoaWQpO1xuICB9XG5cbiAgYXN5bmMgZ2V0UmF0ZUxpbWl0c0J5VG9rZW5JZChcbiAgICB0b2tlbklkOiBudW1iZXIsXG4gICAgc2lnbmFsPzogQWJvcnRTaWduYWwsXG4gICk6IFByb21pc2U8T3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhPiB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpO1xuICAgIGlmICghdG9rZW4pIHRocm93IG5ldyBFcnJvcihgb3BlbmFpIHRva2VuICR7dG9rZW5JZH0gbm90IGZvdW5kYCk7XG4gICAgY29uc3QgZ2VuZXJhdGlvbiA9IHRva2VuLmdlbmVyYXRpb247XG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5yYXRlTGltaXRzQ2FjaGUuZ2V0KHRva2VuSWQpO1xuICAgIGlmIChcbiAgICAgIGNhY2hlZCAmJlxuICAgICAgY2FjaGVkLmdlbmVyYXRpb24gPT09IHRva2VuLmdlbmVyYXRpb24gJiZcbiAgICAgIERhdGUubm93KCkgLSBjYWNoZWQuY2FjaGVkQXQgPCBPcGVuQUlEaXNwYXRjaGVyLlJBVEVfTElNSVRTX0NBQ0hFX1RUTFxuICAgIClcbiAgICAgIHJldHVybiBjYWNoZWQ7XG5cbiAgICAvLyBzaW5nbGUtZmxpZ2h0OiDrj5nsi5zshLEg7IOB7ZWc7J20IOyXhuyWtOynhCDrkqTroZwgVFRMIOunjOujjCDsiJzqsIQg64+Z7IucIOyalOyyrSDsiJjrp4ztgbwg6rCZ7J2AXG4gICAgLy8g7KGw7ZqM6rCAIOuqsOumtCDsiJgg7J6I64ukIOKAlCDsp4Ttlokg7KSR7J24IGZldGNoIOulvCDqs7XsnKDtlZzri6QuIOy1nOy0iCDtmLjstpzsnpDsnZggYWJvcnQg66GcXG4gICAgLy8g6rO17JygIOyhsO2ajOqwgCDsi6TtjKjtlbTrj4Qg7IaM67mE7LKYKGlzUXVvdGFFbGlnaWJsZSnqsIAgZmFpbC1vcGVuIOycvOuhnCDsspjrpqztlZzri6QuXG4gICAgY29uc3QgcGVuZGluZyA9IHRoaXMucGVuZGluZ1JhdGVMaW1pdHMuZ2V0KHRva2VuSWQpO1xuICAgIGlmIChwZW5kaW5nPy50b2tlbiA9PT0gdG9rZW4gJiYgcGVuZGluZy5nZW5lcmF0aW9uID09PSBnZW5lcmF0aW9uKSByZXR1cm4gcGVuZGluZy5wcm9taXNlO1xuICAgIGNvbnN0IGZldGNoUHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZWFkT3BlbkFJUXVvdGFVc2FnZSh7XG4gICAgICAgIGNyZWRlbnRpYWxzOiB0b2tlbi5jcmVkZW50aWFscyxcbiAgICAgICAgcmVmcmVzaENyZWRlbnRpYWxzOiAoKSA9PiB0aGlzLnJlZnJlc2hDcmVkZW50aWFscyh0b2tlbklkKSxcbiAgICAgICAgZmV0Y2g6IHRoaXMuZmV0Y2hJbXBsLFxuICAgICAgICAuLi4oc2lnbmFsID8geyBzaWduYWwgfSA6IHt9KSxcbiAgICAgIH0pO1xuICAgICAgaWYgKHJlc3VsdC5raW5kID09PSBcImxvb2t1cF9mYWlsZWRcIikgdGhyb3cgbmV3IEVycm9yKHJlc3VsdC5yZWFzb24pO1xuICAgICAgaWYgKCFyZXN1bHQucmF3KSB0aHJvdyBuZXcgRXJyb3IoXCJPcGVuQUkgcXVvdGEgcmVzcG9uc2UgbWlzc2luZyByYXcgcmF0ZSBsaW1pdHNcIik7XG4gICAgICBjb25zdCBlbnRyeSA9IHsgZGF0YTogcmVzdWx0LnJhdywgY2FjaGVkQXQ6IERhdGUubm93KCksIGdlbmVyYXRpb24gfTtcbiAgICAgIGlmICh0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpID09PSB0b2tlbiAmJiB0b2tlbi5nZW5lcmF0aW9uID09PSBnZW5lcmF0aW9uKSB7XG4gICAgICAgIHRoaXMucmF0ZUxpbWl0c0NhY2hlLnNldCh0b2tlbklkLCBlbnRyeSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZW50cnk7XG4gICAgfSkoKS5maW5hbGx5KCgpID0+IHtcbiAgICAgIGlmICh0aGlzLnBlbmRpbmdSYXRlTGltaXRzLmdldCh0b2tlbklkKT8ucHJvbWlzZSA9PT0gZmV0Y2hQcm9taXNlKSB7XG4gICAgICAgIHRoaXMucGVuZGluZ1JhdGVMaW1pdHMuZGVsZXRlKHRva2VuSWQpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMucGVuZGluZ1JhdGVMaW1pdHMuc2V0KHRva2VuSWQsIHsgdG9rZW4sIGdlbmVyYXRpb24sIHByb21pc2U6IGZldGNoUHJvbWlzZSB9KTtcbiAgICByZXR1cm4gZmV0Y2hQcm9taXNlO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZWZyZXNoQ3JlZGVudGlhbHModG9rZW5JZDogbnVtYmVyKSB7XG4gICAgY29uc3QgcHJldmlvdXMgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpO1xuICAgIGNvbnN0IGdlbmVyYXRpb24gPSBwcmV2aW91cz8uZ2VuZXJhdGlvbjtcbiAgICBjb25zdCByZWZyZXNoZWQgPSBhd2FpdCBoYW5kbGVDaGF0Z3B0QXV0aFRva2Vuc1JlZnJlc2godG9rZW5JZCk7XG4gICAgY29uc3QgY3JlZGVudGlhbHMgPSB7XG4gICAgICBhY2Nlc3NUb2tlbjogcmVmcmVzaGVkLmFjY2Vzc1Rva2VuLFxuICAgICAgYWNjb3VudElkOiByZWZyZXNoZWQuY2hhdGdwdEFjY291bnRJZCxcbiAgICB9O1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpO1xuICAgIGlmICghY3VycmVudD8uYWN0aXZlKSB0aHJvdyBuZXcgRXJyb3IoYG9wZW5haSB0b2tlbiAke3Rva2VuSWR9IGlzIG5vIGxvbmdlciBhY3RpdmVgKTtcbiAgICAvLyBBIHN1YnNjcmliZXIgdXBkYXRlIG1heSBhbHJlYWR5IGNvbnRhaW4gbmV3ZXIgY3JlZGVudGlhbHMuIE5ldmVyIG92ZXJ3cml0ZSBpdFxuICAgIC8vIHdpdGggdGhlIHJlc3VsdCBvZiBhIHJlZnJlc2ggdGhhdCBzdGFydGVkIGFnYWluc3QgYW4gb2xkZXIgZ2VuZXJhdGlvbi5cbiAgICBpZiAoY3VycmVudCA9PT0gcHJldmlvdXMgJiYgY3VycmVudC5nZW5lcmF0aW9uID09PSBnZW5lcmF0aW9uKSB7XG4gICAgICBjdXJyZW50LmNyZWRlbnRpYWxzID0geyAuLi5jdXJyZW50LmNyZWRlbnRpYWxzLCAuLi5jcmVkZW50aWFscyB9O1xuICAgICAgdGhpcy5yZXRpcmVDbGllbnQodG9rZW5JZCk7XG4gICAgICB0aGlzLmludmFsaWRhdGVSYXRlTGltaXRzQ2FjaGUodG9rZW5JZCk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICBhY2Nlc3NUb2tlbjogY3VycmVudC5jcmVkZW50aWFscy5hY2Nlc3NUb2tlbixcbiAgICAgIGFjY291bnRJZDogY3VycmVudC5jcmVkZW50aWFscy5hY2NvdW50SWQsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaXNRdW90YUVsaWdpYmxlKFxuICAgIGlkOiBudW1iZXIsXG4gICAgdG9rZW46IFRva2VuTWV0YWRhdGEsXG4gICAgc2lnbmFsPzogQWJvcnRTaWduYWwsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICh0b2tlbi5xdW90YVRocmVzaG9sZCA9PT0gbnVsbCB8fCB0b2tlbi5xdW90YVRocmVzaG9sZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdHJ1ZTtcbiAgICBjb25zdCBnZW5lcmF0aW9uID0gdG9rZW4uZ2VuZXJhdGlvbjtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZWFkT3BlbkFJUXVvdGFVc2FnZShhc3luYyAoKSA9PiB0aGlzLmdldFJhdGVMaW1pdHNCeVRva2VuSWQoaWQsIHNpZ25hbCkpO1xuICAgIGlmICh0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKSAhPT0gdG9rZW4gfHwgdG9rZW4uZ2VuZXJhdGlvbiAhPT0gZ2VuZXJhdGlvbikgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChyZXN1bHQua2luZCA9PT0gXCJsb29rdXBfZmFpbGVkXCIpIHtcbiAgICAgIHRoaXMucXVvdGFCbG9ja2VkLmRlbGV0ZShpZCk7XG4gICAgICBsb2dnZXIud2FybihcInF1b3RhX3RocmVzaG9sZCBnYXRlOiBsb29rdXBfZmFpbF9vcGVuXCIsIHtcbiAgICAgICAgdG9rZW5JZDogaWQsXG4gICAgICAgIHRva2VuTmFtZTogdG9rZW4ubmFtZSxcbiAgICAgICAgbG9va3VwUmVhc29uOiByZXN1bHQucmVhc29uLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHJlc3VsdC51dGlsaXphdGlvblBjdCA+PSB0b2tlbi5xdW90YVRocmVzaG9sZCkge1xuICAgICAgaWYgKCF0aGlzLnF1b3RhQmxvY2tlZC5oYXMoaWQpKVxuICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICBgcXVvdGFfdGhyZXNob2xkIGdhdGU6IG92ZXJfdGhyZXNob2xkICR7dG9rZW4ubmFtZX1bJHtpZH1dICgke3Jlc3VsdC51dGlsaXphdGlvblBjdH0lID49ICR7dG9rZW4ucXVvdGFUaHJlc2hvbGR9JSlgLFxuICAgICAgICApO1xuICAgICAgdGhpcy5xdW90YUJsb2NrZWQuYWRkKGlkKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHRoaXMucXVvdGFCbG9ja2VkLmRlbGV0ZShpZCkpXG4gICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgYHF1b3RhX3RocmVzaG9sZCBnYXRlOiByZWNvdmVyZWQgJHt0b2tlbi5uYW1lfVske2lkfV0gKCR7cmVzdWx0LnV0aWxpemF0aW9uUGN0fSUgPCAke3Rva2VuLnF1b3RhVGhyZXNob2xkfSUpYCxcbiAgICAgICk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGludmFsaWRhdGVSYXRlTGltaXRzQ2FjaGUoaWQ6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMucmF0ZUxpbWl0c0NhY2hlLmRlbGV0ZShpZCk7XG4gIH1cblxuICBnZXQgdG9rZW5Db3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiBbLi4udGhpcy50b2tlbk1ldGFkYXRhLnZhbHVlcygpXS5maWx0ZXIoKHQpID0+IHQuYWN0aXZlKS5sZW5ndGg7XG4gIH1cbiAgZ2V0IGluRmxpZ2h0KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuaW5GbGlnaHRDb3VudDtcbiAgfVxuXG4gIC8qKlxuICAgKiDthqDtgbDrs4Qg7L+87YSwIOyKpOuDheyDtyDigJQg7Iug7ISg7ZWcKHJhdGUgbGltaXRzIFRUTCDrgrQpIOy6kOyLnOunjCDsnb3qs6Ag7KCI64yAIGZldGNoIO2VmOyngCDslYrripTri6QuXG4gICAqIG1vbml0IHZpdGFscyDripQg66Gc6re4IO2PtOungeyXkCDtjrjsirntlZjripQg6rCS7J206528IOyXrOq4sOyEnCDrhKTtirjsm4ztgazrpbwg7YOA66m0IOyViCDrkJzri6QuXG4gICAqIHRocmVzaG9sZCDrr7jshKTsoJUg7Yag7YGw7J2AIOy/vO2EsCDtjJDsoJXsnYQg64+M7KeAIOyViuyVhCB1c2VkUGVyY2VudCDqsIAgbnVsbCDroZwg64Ko7J2EIOyImCDsnojri6QuXG4gICAqL1xuICBnZXQgcXVvdGFCeVRva2VuKCk6IEFycmF5PHtcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgdXNlZFBlcmNlbnQ6IG51bWJlciB8IG51bGw7XG4gICAgdGhyZXNob2xkOiBudW1iZXIgfCBudWxsO1xuICAgIGJsb2NrZWQ6IGJvb2xlYW47XG4gICAgcmVzZXRzQXQ6IG51bWJlciB8IG51bGw7XG4gIH0+IHtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBbLi4udGhpcy50b2tlbk1ldGFkYXRhLmVudHJpZXMoKV1cbiAgICAgIC5tYXAoKFtpZCwgdF0pID0+IHtcbiAgICAgICAgY29uc3QgY2FjaGVkID0gdGhpcy5yYXRlTGltaXRzQ2FjaGUuZ2V0KGlkKTtcbiAgICAgICAgY29uc3QgZnJlc2ggPVxuICAgICAgICAgIGNhY2hlZCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgY2FjaGVkLmdlbmVyYXRpb24gPT09IHQuZ2VuZXJhdGlvbiAmJlxuICAgICAgICAgIG5vdyAtIGNhY2hlZC5jYWNoZWRBdCA8IE9wZW5BSURpc3BhdGNoZXIuUkFURV9MSU1JVFNfQ0FDSEVfVFRMO1xuICAgICAgICBjb25zdCBwcmltYXJ5ID0gZnJlc2ggPyBjYWNoZWQuZGF0YS5yYXRlTGltaXRzPy5wcmltYXJ5IDogdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG5hbWU6IHQubmFtZSxcbiAgICAgICAgICB1c2VkUGVyY2VudDogcHJpbWFyeT8udXNlZFBlcmNlbnQgPz8gbnVsbCxcbiAgICAgICAgICB0aHJlc2hvbGQ6IHQucXVvdGFUaHJlc2hvbGQgPz8gbnVsbCxcbiAgICAgICAgICBibG9ja2VkOiB0aGlzLnF1b3RhQmxvY2tlZC5oYXMoaWQpLFxuICAgICAgICAgIC8vIHdoYW0g7J2YIHJlc2V0c0F0IOydgCB1bml4IOy0iCDri6jsnITri6QocWdyaWQuZnJhbWUgdW5peFNlY29uZHNUb0lzbyDsmYAg64+Z7J28IOq3nOyVvSkuXG4gICAgICAgICAgLy8g7IaM67mE7LKY6rCAIOuLqOychOulvCDstpTsuKHtlZjsp4Ag7JWK64+E66GdIOyXrOq4sOyEnCBtcyBlcG9jaCDsnLzroZwg7KCV6rec7ZmU7ZWc64ukLlxuICAgICAgICAgIHJlc2V0c0F0OlxuICAgICAgICAgICAgcHJpbWFyeT8ucmVzZXRzQXQgIT09IG51bGwgJiYgcHJpbWFyeT8ucmVzZXRzQXQgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICA/IHByaW1hcnkucmVzZXRzQXQgKiAxMDAwXG4gICAgICAgICAgICAgIDogbnVsbCxcbiAgICAgICAgfTtcbiAgICAgIH0pXG4gICAgICAudG9Tb3J0ZWQoKGEsIGIpID0+IGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSkpO1xuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUF3QkEsTUFBTSxTQUFTLFVBQVUsQ0FBQyxTQUFTLG1CQUFtQixDQUFDO0FBR3ZELE1BQU0sNkJBQTZCO0FBQ25DLE1BQU0seUJBQXlCO0FBSS9CLElBQWEsdUJBQWIsY0FBMEMsTUFBTTtDQUVuQztDQURYLFlBQ0UsTUFDQSxTQUNBO0VBQ0EsTUFBTSxPQUFPO0VBSEosS0FBQSxPQUFBO0VBSVQsS0FBSyxPQUFPO0NBQ2Q7QUFDRjtBQThCQSxTQUFTLFdBQVcsUUFBNEI7Q0FDOUMsTUFBTSxTQUFTLE9BQU87Q0FDdEIsT0FBTyxrQkFBa0IsUUFBUSxTQUFTLElBQUksYUFBYSxXQUFXLFlBQVk7QUFDcEY7QUFFQSxTQUFTLGFBQWEsUUFBc0IsV0FBaUM7Q0FDM0UsTUFBTSxVQUFVLFlBQVksUUFBUSxhQUFhLDBCQUEwQjtDQUMzRSxPQUFPLFNBQVMsWUFBWSxJQUFJLENBQUMsUUFBUSxPQUFPLENBQUMsSUFBSTtBQUN2RDtBQUVBLFNBQVMsYUFBYSxTQUE2RDtDQUNqRixNQUFNLFNBQVMsUUFBUSxLQUFLLE1BQU0sR0FBRyxFQUFFLEtBQUssY0FBYyxFQUFFLFVBQVUsR0FBRyxDQUFDLENBQUMsS0FBSyxJQUFJO0NBQ3BGLE9BQU8sU0FDSCwrQ0FBK0MsV0FDL0M7QUFDTjtBQUVBLFNBQVMsV0FBVyxLQUE0QztDQUM5RCxNQUFNLFVBQVcsSUFBSSxlQUFlLENBQUM7Q0FDckMsTUFBTSxVQUFnQyxJQUFJLFVBQVUsS0FBSyxVQUFVO0VBQ2pFLElBQUksTUFBTSxTQUFTLFFBQVEsT0FBTztHQUFFLE1BQU07R0FBYyxNQUFNLE1BQU07RUFBSztFQUN6RSxJQUFJLE1BQU0sU0FBUyxTQUFTLE9BQU87R0FBRSxNQUFNO0dBQWUsV0FBVyxNQUFNO0VBQUk7RUFDL0UsSUFBSSxNQUFNLFNBQVMsY0FBYyxPQUFPO0dBQUUsTUFBTTtHQUFlLFdBQVcsTUFBTTtFQUFLO0VBQ3JGLE9BQU87R0FBRSxNQUFNO0dBQWMsTUFBTSxHQUFHLE1BQU0sS0FBSyxJQUFJLE1BQU07RUFBTztDQUNwRSxDQUFDO0NBQ0QsT0FBTyxDQUFDLEdBQUcsU0FBUztFQUFFLE1BQU07RUFBVyxNQUFNO0VBQVE7Q0FBUSxDQUFDO0FBQ2hFO0FBRUEsU0FBUyxZQUFZLEtBQXVFO0NBQzFGLE1BQU0sVUFDSixJQUFJLG9CQUFvQixJQUFJLHFCQUFxQixTQUFTLElBQUksbUJBQW1CO0NBRW5GLE1BQU0sU0FBUyxvQkFBb0IsSUFBSSxTQUFTLElBQUksSUFBSSxNQUFNO0NBQzlELElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxPQUFPO0NBQ2hDLE9BQU87RUFDTCxHQUFJLFNBQVMsRUFBRSxPQUFPLElBQUksQ0FBQztFQUMzQixHQUFJLFVBQ0EsRUFDVyxRQUNYLElBQ0EsQ0FBQztDQUNQO0FBQ0Y7QUFFQSxTQUFTLGVBQWUsS0FBOEM7Q0FDcEUsTUFBTSxFQUFFLGNBQWMsR0FBRyxrQkFBa0IsSUFBSSwwQkFBMEIsQ0FBQztDQUMxRSxNQUFNLE9BQU8sSUFBSSxvQkFBb0I7Q0FDckMsSUFBSSxRQUFRLElBQUksY0FDZCxNQUFNLElBQUkscUJBQ1IsUUFDQSxpRkFDRjtDQUVGLE9BQU87RUFDTCxPQUFPLElBQUksU0FBUztFQUNwQixHQUFJLElBQUksZUFBZSxFQUFFLGNBQWMsSUFBSSxhQUFhLElBQUksQ0FBQztFQUM3RCxHQUFJLE9BQ0E7R0FDRSxjQUFjLENBQ1osSUFBSSxjQUNKLGlTQUNGLENBQUMsQ0FDRSxPQUFPLE9BQU8sQ0FBQyxDQUNmLEtBQUssTUFBTTtHQUNkLG1CQUFtQjtHQUNuQixPQUFPLENBQ0w7SUFDRSxNQUFNO0lBQ04sTUFBTTtJQUNOLGFBQ0U7SUFDRixRQUFRO0lBQ1IsWUFBWTtLQUNWLE1BQU07S0FDTixZQUFZLEVBQ1YsUUFBUTtNQUNOLE1BQU07TUFDTixhQUNFO0tBQ0osRUFDRjtLQUNBLFVBQVUsQ0FBQyxRQUFRO0tBQ25CLHNCQUFzQjtJQUN4QjtHQUNGLENBQ0Y7RUFDRixJQUNBLENBQUM7RUFDTCxTQUFTLFdBQVcsR0FBRztFQUN2QixHQUFJLFlBQVksR0FBRyxJQUFJLEVBQUUsV0FBVyxZQUFZLEdBQUcsRUFBRSxJQUFJLENBQUM7RUFDMUQsR0FBSSxJQUFJLFlBQVksRUFBRSxXQUFXLElBQUksVUFBaUQsSUFBSSxDQUFDO0VBQzNGLEdBQUksSUFBSSxjQUNKLEVBQUUsYUFBYSxJQUFJLGdCQUFnQixTQUFTLGFBQWEsSUFBSSxZQUFZLElBQ3pFLENBQUM7RUFDTCxHQUFJLElBQUksaUJBQWlCLEVBQUUsZ0JBQWdCLElBQUksZUFBZSxJQUFJLENBQUM7RUFDbkUsR0FBSSxJQUFJLGVBQWUsRUFBRSxjQUFjLEVBQUUsUUFBUSxJQUFJLGFBQTBCLEVBQUUsSUFBSSxDQUFDO0VBQ3RGLEdBQUksSUFBSSxrQkFDSixFQUNFLGlCQUFpQixJQUFJLHlCQUNqQjtHQUNFLEdBQUc7R0FDSCxHQUFJLE9BQU8sRUFBRSxZQUFZLE9BQU8sSUFBSSxDQUFDO0dBQ3JDLEdBQUksZUFBZSxFQUFFLGVBQWUsYUFBYSxJQUFJLENBQUM7RUFDeEQsSUFDQSxLQUNOLElBQ0EsQ0FBQztDQUNQO0FBQ0Y7Ozs7Ozs7OztBQVVBLElBQWEsbUJBQWIsTUFBYSxpQkFBK0M7Q0FDMUQsZ0NBQXlCLElBQUksSUFBMkI7Q0FDeEQ7Q0FDQSxrQ0FBMkIsSUFBSSxJQUErRDtDQUM5RixvQ0FBcUMsSUFBSSxJQUd2QztDQUNGLDBCQUEyQixJQUFJLElBQXlCO0NBQ3hELGlDQUFrQyxJQUFJLElBQWlCO0NBQ3ZELE9BQWdCLHdCQUF3QjtDQUV4QyxXQUE0QixJQUFJLHlCQUF5QjtDQUN6RDtDQUNBO0NBQ0EsK0JBQWdDLElBQUksSUFBWTtDQUNoRCxnQkFBd0I7Q0FFeEIsWUFDRSxnQkFBcUMsMkJBQTJCLEdBQ2hFLGVBQTZDLENBQUMsR0FDOUM7RUFDQSxLQUFLLGdCQUFnQjtFQUNyQixLQUFLLGdCQUNILGFBQWEsbUJBQW1CLFlBQVksSUFBSSxtQkFBbUIsT0FBTztFQUM1RSxLQUFLLFlBQVksYUFBYSxTQUFTO0NBQ3pDO0NBRUEsTUFBTSxRQUF1QjtFQUMzQixNQUFNLEVBQUUsU0FBUyxNQUFNLFdBQVcsU0FBUyxHQUFHO0VBQzlDLEtBQUssTUFBTSxPQUFPLE1BQU07R0FDdEIsSUFBSSxJQUFJLGFBQWEsVUFBVTtHQUMvQixLQUFLLFNBQ0gsSUFBSSxJQUNKLElBQUksTUFDSixJQUFJLGFBQ0osSUFBSSxpQkFDSixJQUFJLFFBQ0osSUFBSSxNQUNOO0VBQ0Y7RUFDQSxPQUFPLEtBQUssc0NBQXNDLEtBQUssY0FBYyxLQUFLLFFBQVE7Q0FDcEY7Q0FFQSxNQUFNLE9BQXNCO0VBQzFCLEtBQUssTUFBTSxFQUFFLFlBQVksS0FBSyxRQUFRLE9BQU8sR0FBRyxPQUFPLFFBQVE7RUFDL0QsS0FBSyxRQUFRLE1BQU07RUFDbkIsS0FBSyxNQUFNLFNBQVMsS0FBSyxnQkFBZ0IsTUFBTSxPQUFPLFFBQVE7RUFDOUQsS0FBSyxlQUFlLE1BQU07RUFDMUIsS0FBSyxjQUFjLE1BQU07RUFDekIsS0FBSyxnQkFBZ0IsTUFBTTtFQUMzQixLQUFLLGFBQWEsTUFBTTtFQUN4QixLQUFLLFNBQVMsWUFBWTtDQUM1QjtDQUVBLE1BQU0sYUFDSixJQUNBLE1BQ0EsYUFDQSxnQkFDQSxTQUFTLEdBQ007RUFDZixLQUFLLFNBQVMsSUFBSSxNQUFNLGFBQWEsZ0JBQWdCLFFBQVEsSUFBSTtDQUNuRTtDQUVBLE1BQU0sZUFDSixJQUNBLE1BQ0EsYUFDQSxnQkFDQSxTQUFTLEdBQ007RUFDZixNQUFNLE1BQU0sS0FBSyxjQUFjLElBQUksRUFBRTtFQUNyQyxLQUFLLFNBQVMsSUFBSSxNQUFNLGFBQWEsZ0JBQWdCLFFBQVEsS0FBSyxVQUFVLElBQUk7Q0FDbEY7Q0FFQSxNQUFNLGVBQWUsSUFBMkI7RUFDOUMsS0FBSyxhQUFhLEVBQUU7RUFDcEIsS0FBSyxjQUFjLE9BQU8sRUFBRTtFQUM1QixLQUFLLFNBQVMsWUFBWSxFQUFFO0VBQzVCLEtBQUssMEJBQTBCLEVBQUU7RUFDakMsS0FBSyxhQUFhLE9BQU8sRUFBRTtDQUM3QjtDQUVBLG1CQUFtQixJQUFrQjtFQUNuQyxNQUFNLFFBQVEsS0FBSyxjQUFjLElBQUksRUFBRTtFQUN2QyxJQUFJLE9BQU8sTUFBTSxTQUFTO0VBQzFCLEtBQUssU0FBUyxZQUFZO0NBQzVCO0NBRUEsaUJBQWlCLElBQWtCO0VBQ2pDLE1BQU0sUUFBUSxLQUFLLGNBQWMsSUFBSSxFQUFFO0VBQ3ZDLElBQUksT0FBTyxNQUFNLFNBQVM7RUFDMUIsS0FBSyxTQUFTLFlBQVk7Q0FDNUI7Q0FFQSxNQUFNLGNBQ0osTUFPZTtFQUNmLE1BQU0sTUFBTSxJQUFJLElBQUksS0FBSyxLQUFLLE1BQU0sRUFBRSxFQUFFLENBQUM7RUFDekMsS0FBSyxNQUFNLE1BQU0sS0FBSyxjQUFjLEtBQUssR0FBRyxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsR0FBRyxNQUFNLEtBQUssZUFBZSxFQUFFO0VBQzFGLEtBQUssTUFBTSxPQUFPLE1BQ2hCLE1BQU0sS0FBSyxlQUFlLElBQUksSUFBSSxJQUFJLE1BQU0sSUFBSSxhQUFhLElBQUksZ0JBQWdCLElBQUksTUFBTTtDQUMvRjtDQUVBLE1BQU0sU0FBUyxLQUErQztFQUM1RCxPQUFPLEtBQUssSUFBSSxHQUFHO0NBQ3JCO0NBRUEsTUFBTSxlQUFlLEtBQXNCLElBQTRDO0VBQ3JGLElBQUksSUFBSSxpQkFDTixNQUFNLElBQUkscUJBQ1IsUUFDQSx5REFDRjtFQUNGLElBQUk7R0FDRixHQUFHLFdBQVcsTUFBTSxLQUFLLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQztFQUMvQyxTQUFTLE9BQU87R0FDZCxHQUFHLFFBQVEsS0FBYztHQUN6QixNQUFNO0VBQ1I7Q0FDRjtDQUdBLE1BQWMsSUFDWixLQUNBLFNBQ3lCO0VBQ3pCLE1BQU0sU0FBUyxhQUFhLElBQUksYUFBYSxJQUFJLFNBQVM7RUFDMUQsSUFBSSxPQUFPLFNBQVMsTUFBTSxXQUFXLE1BQU07RUFDM0MsTUFBTSxZQUFZLE1BQU0sS0FBSyxZQUMzQixJQUFJLGtCQUNKLElBQUkseUJBQXlCLE9BQzdCLE1BQ0Y7RUFDQSxLQUFLO0VBQ0wsSUFBSTtHQUNGLElBQUksT0FBTyxTQUFTLE1BQU0sV0FBVyxNQUFNO0dBQzNDLE9BQU8sTUFBTSxLQUFLLFVBQVUsV0FBVztJQUFFLEdBQUc7SUFBSyxhQUFhO0dBQU8sR0FBRyxPQUFPO0VBQ2pGLFVBQVU7R0FDUixLQUFLO0VBQ1A7Q0FDRjtDQUVBLE1BQWMsVUFDWixXQUNBLEtBQ0EsU0FDeUI7RUFDekIsTUFBTSxZQUFZLEtBQUssSUFBSTtFQUMzQixJQUFJO0VBQ0osSUFBSSxPQUFPO0VBQ1gsSUFBSSxRQUFRO0dBQ1YsYUFBYTtHQUNiLGFBQWE7R0FDYixjQUFjO0dBQ2QsbUJBQW1CO0dBQ25CLHVCQUF1QjtFQUN6QjtFQUNBLE1BQU0sU0FBMkIsQ0FBQztFQUNsQyxJQUFJLGlCQUFpQjtFQUNyQixNQUFNLE9BQU8sSUFBSSxvQkFBb0I7RUFDckMsTUFBTSxtQ0FBbUIsSUFBSSxJQUFvQjtFQUNqRCxNQUFNLHFDQUFxQixJQUFJLElBQWE7RUFDNUMsSUFBSSx1QkFBdUI7RUFDM0IsSUFBSSxrQkFBa0I7RUFDdEIsSUFBSSxlQUFlLElBQUksU0FBUztFQUNoQyxNQUFNLFdBQVcsVUFBVTtFQUMzQixNQUFNLGNBQWMsS0FBSyxjQUFjLFNBQVM7RUFDaEQsSUFBSTtHQUNGLFdBQVcsTUFBTSxTQUFTLFlBQVksT0FBTyxVQUMzQyxlQUFlLEdBQUcsR0FDbEIsSUFBSSxXQUNOLEdBQ0UsSUFBSSxNQUFNLFNBQVMsY0FBYztJQUMvQixpQkFBaUIsS0FBSyxJQUFJO0lBQzFCLFFBQVEsTUFBTTtJQUNkLFVBQVUsTUFBTSxJQUFJO0dBQ3RCLE9BQU8sSUFBSSxNQUFNLFNBQVMsU0FBUztJQUNqQyxpQkFBaUI7SUFDakIsT0FBTyxLQUFLO0tBQ1YsTUFBTSxNQUFNO0tBQ1osV0FBVyxNQUFNO0tBQ2pCLGVBQWUsTUFBTSxpQkFBaUI7S0FDdEMsR0FBSSxNQUFNLGFBQWEsRUFBRSxZQUFZLE1BQU0sV0FBVyxJQUFJLENBQUM7SUFDN0QsQ0FBQztHQUNILE9BQU8sSUFBSSxNQUFNLFNBQVMsaUJBQWlCLE1BQU0sS0FBSyxTQUFTLHlCQUM3RCxpQkFBaUI7UUFDWixJQUFJLFFBQVEsTUFBTSxTQUFTLGlCQUFpQixNQUFNLEtBQUssU0FBUyxpQkFBaUI7SUFDdEYsSUFBSSxNQUFNLEtBQUssU0FBUyx3QkFDdEIsTUFBTSxJQUFJLHFCQUFxQixjQUFjLHNDQUFzQztJQUVyRix1QkFBdUI7SUFDdkIsbUJBQW1CLElBQUksTUFBTSxLQUFLLE9BQU87SUFDekMsSUFBSSxDQUFDLE1BQU0sV0FBVztJQUN0QixNQUFNLEtBQUssTUFBTSxLQUFLO0lBQ3RCLElBQUk7SUFDSixJQUFJO0tBQ0YsT0FBTyxLQUFLLE1BQU0sT0FBTyxNQUFNLEtBQUssU0FBUyxDQUFDO0lBQ2hELFFBQVE7S0FDTixNQUFNLElBQUkscUJBQXFCLGNBQWMscUNBQXFDO0lBQ3BGO0lBQ0EsSUFDRSxPQUFPLE9BQU8sWUFDZCxDQUFDLE1BQ0QsQ0FBQyxRQUNELE9BQU8sU0FBUyxZQUNoQixNQUFNLFFBQVEsSUFBSSxLQUNsQixPQUFPLEtBQUssSUFBSSxDQUFDLENBQUMsV0FBVyxLQUM3QixFQUFFLFlBQVksU0FDZCxPQUFPLEtBQUssV0FBVyxZQUN2QixDQUFDLEtBQUssT0FBTyxLQUFLLEdBRWxCLE1BQU0sSUFBSSxxQkFBcUIsY0FBYyxxQ0FBcUM7SUFFcEYsSUFBSSxpQkFBaUIsSUFBSSxFQUFFLEtBQUssaUJBQWlCLElBQUksRUFBRSxNQUFNLEtBQUssUUFDaEUsTUFBTSxJQUFJLHFCQUNSLGNBQ0EsMENBQ0Y7SUFFRixpQkFBaUIsSUFBSSxJQUFJLEtBQUssTUFBTTtHQUN0QyxPQUFPLElBQUksTUFBTSxTQUFTLGVBQWUsTUFBTSxPQUFPO0lBQ3BELGtCQUFrQjtJQUNsQixlQUFlLE1BQU0sU0FBUztJQUM5QixRQUFRO0tBQ04sYUFBYSxNQUFNLE1BQU07S0FDekIsYUFBYSxNQUFNLE1BQU07S0FDekIsY0FBYyxNQUFNLE1BQU07S0FDMUIsbUJBQW1CLE1BQU0sTUFBTTtLQUMvQix1QkFBdUIsTUFBTSxNQUFNO0lBQ3JDO0dBQ0YsT0FBTyxJQUFJLE1BQU0sU0FBUyxhQUFhO0lBQ3JDLGtCQUFrQjtJQUNsQixlQUFlLE1BQU0sU0FBUztHQUNoQyxPQUFPLElBQUksTUFBTSxTQUFTLFNBQVM7SUFDakMsSUFBSSxJQUFJLGlCQUNOLE1BQU0sSUFBSSxxQkFBcUIsY0FBYyxNQUFNLE1BQU0sT0FBTztJQUNsRSxNQUFNLE1BQU07R0FDZDtHQUVGLElBQUksUUFBUSxzQkFBc0I7SUFDaEMsSUFDRSxDQUFDLG1CQUNELGlCQUFpQixTQUFTLEtBQzFCLG1CQUFtQixTQUFTLEtBQzVCLGdCQUVBLE1BQU0sSUFBSSxxQkFDUixjQUNBLDBFQUNGO0lBRUYsSUFBSSxJQUFJLGFBQWEsU0FBUyxNQUFNLFdBQVcsSUFBSSxXQUFXO0lBQzlELE1BQU0sU0FBUyxDQUFDLEdBQUcsaUJBQWlCLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDOUMsSUFBSSxpQkFBaUI7SUFDckIsV0FBVyxNQUFNLFNBQVMsWUFBWSxPQUFPLFVBQzNDO0tBQ0UsT0FBTyxJQUFJLFNBQVM7S0FDcEIsR0FBSSxJQUFJLGVBQWUsRUFBRSxjQUFjLElBQUksYUFBYSxJQUFJLENBQUM7S0FDN0QsU0FBUyxDQUNQLEdBQUcsV0FBVyxHQUFHLEdBQ2pCO01BQUUsTUFBTTtNQUFXLE1BQU07TUFBUSxTQUFTLENBQUM7T0FBRSxNQUFNO09BQWMsTUFBTTtNQUFPLENBQUM7S0FBRSxDQUNuRjtLQUNBLGlCQUFpQjtNQUNmLFNBQVMsSUFBSSx3QkFBd0I7TUFDckMsTUFBTSxJQUFJLHdCQUF3QjtNQUNsQyxlQUFlO01BQ2YsWUFBWTtLQUNkO0lBQ0YsR0FDQSxJQUFJLFdBQ04sR0FDRSxJQUFJLE1BQU0sU0FBUyxTQUNqQixPQUFPLEtBQUs7S0FDVixNQUFNLE1BQU07S0FDWixXQUFXLE1BQU07S0FDakIsZUFBZSxNQUFNLGlCQUFpQjtLQUN0QyxHQUFJLE1BQU0sYUFBYSxFQUFFLFlBQVksTUFBTSxXQUFXLElBQUksQ0FBQztJQUM3RCxDQUFDO1NBQ0UsSUFBSSxNQUFNLFNBQVMsYUFBYSxpQkFBaUI7U0FDakQsSUFBSSxNQUFNLFNBQVMsU0FDdEIsTUFBTSxJQUFJLHFCQUFxQixjQUFjLE1BQU0sTUFBTSxPQUFPO0lBRXBFLGlCQUFpQjtJQUNqQixJQUFJLENBQUMsZ0JBQ0gsTUFBTSxJQUFJLHFCQUNSLGNBQ0EsK0NBQ0Y7R0FDSjtHQUNBLElBQUksUUFBUSxrQkFBa0IsQ0FBQyxpQkFDN0IsTUFBTSxJQUFJLHFCQUFxQixjQUFjLDRDQUE0QztHQUMzRixJQUFJLElBQUksYUFBYSxTQUFTLE1BQU0sV0FBVyxJQUFJLFdBQVc7RUFDaEUsVUFBVTtHQUNSLEtBQUssY0FBYyxXQUFXO0VBQ2hDO0VBQ0EsS0FBSyxJQUFJLG9CQUFvQixRQUFTLFFBQVEsbUJBQW9CLE9BQU8sV0FBVyxHQUNsRixNQUFNLElBQUkscUJBQ1IsaUJBQWlCLGVBQWUsY0FDaEMsaUJBQ0ksc0NBQ0EscUNBQ047RUFFRixPQUFPO0dBQ0w7R0FDQSxXQUFXLFNBQVM7R0FDcEI7R0FDQSxZQUFZLEtBQUssSUFBSSxJQUFJO0dBQ3pCLFFBQVEsaUJBQWlCLFNBQVksT0FBTyxlQUFlO0dBQzNELE9BQU87R0FDUCxHQUFJLGlCQUFpQixJQUFJLFFBQVEsRUFBRSxnQkFBZ0IsSUFBSSxNQUFNLElBQUksQ0FBQztHQUNsRSxhQUFhO0lBQUUsVUFBVSxVQUFVO0lBQVMsVUFBVSxJQUFJLGtCQUFrQjtJQUFJLE9BQU87R0FBRztHQUMxRixHQUFJLE9BQU8sU0FBUyxFQUFFLE9BQU8sSUFBSSxDQUFDO0VBQ3BDO0NBQ0Y7O0NBR0EsY0FBc0IsV0FBd0M7RUFDNUQsTUFBTSxXQUFXLFVBQVU7RUFDM0IsSUFBSSxRQUFRLEtBQUssUUFBUSxJQUFJLFVBQVUsT0FBTztFQUM5QyxJQUFJLFNBQVMsTUFBTSxlQUFlLFNBQVMsWUFBWTtHQUNyRCxLQUFLLGFBQWEsVUFBVSxPQUFPO0dBQ25DLFFBQVE7RUFDVjtFQUNBLElBQUksQ0FBQyxPQUFPO0dBQ1YsTUFBTSxTQUFTLEtBQUssY0FDbEI7SUFDRSxhQUFhO0tBQ1gsYUFBYSxTQUFTLFlBQVk7S0FDbEMsV0FBVyxTQUFTLFlBQVk7SUFDbEM7SUFDQSxlQUFlLEtBQUs7SUFDcEIsT0FBTyxLQUFLO0lBQ1osMEJBQTBCLEtBQUssbUJBQW1CLFVBQVUsT0FBTztHQUNyRSxHQUNBLFVBQVUsT0FDWjtHQUNBLFFBQVE7SUFBRSxZQUFZLFNBQVM7SUFBWTtJQUFRLFVBQVU7SUFBRyxTQUFTO0dBQU07R0FDL0UsS0FBSyxRQUFRLElBQUksVUFBVSxTQUFTLEtBQUs7RUFDM0M7RUFDQSxNQUFNO0VBQ04sT0FBTztDQUNUO0NBRUEsY0FBc0IsT0FBMEI7RUFDOUMsTUFBTSxXQUFXLEtBQUssSUFBSSxHQUFHLE1BQU0sV0FBVyxDQUFDO0VBQy9DLElBQUksTUFBTSxXQUFXLE1BQU0sYUFBYSxHQUFHO0dBQ3pDLEtBQUssZUFBZSxPQUFPLEtBQUs7R0FDaEMsTUFBTSxPQUFPLFFBQVE7RUFDdkI7Q0FDRjs7Q0FHQSxhQUFxQixTQUF1QjtFQUMxQyxNQUFNLFFBQVEsS0FBSyxRQUFRLElBQUksT0FBTztFQUN0QyxJQUFJLENBQUMsT0FBTztFQUNaLEtBQUssUUFBUSxPQUFPLE9BQU87RUFDM0IsTUFBTSxVQUFVO0VBQ2hCLElBQUksTUFBTSxhQUFhLEdBQUcsTUFBTSxPQUFPLFFBQVE7T0FDMUMsS0FBSyxlQUFlLElBQUksS0FBSztDQUNwQzs7Ozs7OztDQVFBLE1BQWMsWUFDWixrQkFDQSx1QkFDQSxRQUN5QjtFQUN6QixJQUFJLHFCQUFxQixRQUFXO0dBQ2xDLE1BQU0sWUFBWSxLQUFLLGNBQWMsSUFBSSxnQkFBZ0I7R0FDekQsSUFBSSxXQUFXLFVBQVcsTUFBTSxLQUFLLGdCQUFnQixrQkFBa0IsV0FBVyxNQUFNLEdBQ3RGLE9BQU87SUFBRSxTQUFTO0lBQWtCLFVBQVU7R0FBVTtHQUUxRCxJQUFJLHVCQUF1QjtJQUN6QixJQUFJLENBQUMsV0FBVyxRQUNkLE1BQU0sSUFBSSxNQUFNLDBCQUEwQixpQkFBaUIsa0JBQWtCO0lBRS9FLE1BQU0sWUFBWSxVQUFVO0lBQzVCLElBQUksY0FBYyxRQUFRLGNBQWMsUUFDdEMsTUFBTSxJQUFJLDRCQUNSLGFBQWEsQ0FBQztLQUFFLE1BQU0sVUFBVTtLQUFNO0lBQVUsQ0FBQyxDQUFDLENBQ3BEO0dBRUo7RUFDRjtFQUlBLE1BQU0sU0FBUyxNQUFNLFFBQVEsSUFDM0IsQ0FBQyxHQUFHLEtBQUssY0FBYyxRQUFRLENBQUMsQ0FBQyxDQUM5QixRQUFRLEdBQUcsV0FBVyxNQUFNLE1BQU0sQ0FBQyxDQUNuQyxJQUFJLE9BQU8sQ0FBQyxJQUFJLFlBQVk7R0FDM0I7R0FDQTtHQUNBLFVBQVUsTUFBTSxLQUFLLGdCQUFnQixJQUFJLE9BQU8sTUFBTTtFQUN4RCxFQUFFLENBQ047RUFDQSxNQUFNLFdBQVcsSUFBSSxJQUFJLE9BQU8sUUFBUSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUMsS0FBSyxNQUFNLEVBQUUsRUFBRSxDQUFDO0VBQzFFLElBQUksU0FBUyxTQUFTLEdBQUc7R0FDdkIsTUFBTSxPQUFPLE9BQ1YsUUFDRSxNQUNDLENBQUMsRUFBRSxZQUFZLEVBQUUsTUFBTSxtQkFBbUIsUUFBUSxFQUFFLE1BQU0sbUJBQW1CLE1BQ2pGLENBQUMsQ0FDQSxLQUFLLE9BQU87SUFBRSxNQUFNLEVBQUUsTUFBTTtJQUFNLFdBQVcsRUFBRSxNQUFNO0dBQXlCLEVBQUU7R0FDbkYsSUFBSSxLQUFLLFFBQVE7SUFDZixPQUFPLEtBQUssc0NBQXNDO0tBQ2hELFVBQVU7S0FDVixxQkFBcUI7SUFDdkIsQ0FBQztJQUNELE1BQU0sSUFBSSw0QkFBNEIsYUFBYSxJQUFJLENBQUM7R0FDMUQ7R0FDQSxNQUFNLElBQUksTUFBTSxtQkFBbUI7RUFDckM7RUFDQSxNQUFNLFdBQVcsS0FBSyxTQUFTLE9BQU8sUUFBUTtFQUM5QyxNQUFNLFdBQVcsYUFBYSxPQUFPLEtBQUssY0FBYyxJQUFJLFFBQVEsSUFBSTtFQUN4RSxJQUFJLGFBQWEsUUFBUSxDQUFDLFVBQVUsTUFBTSxJQUFJLE1BQU0sbUJBQW1CO0VBQ3ZFLE9BQU87R0FBRSxTQUFTO0dBQVU7RUFBUztDQUN2QztDQUVBLFNBQ0UsSUFDQSxNQUNBLGFBQ0EsZ0JBQ0EsUUFDQSxRQUNNO0VBQ04sTUFBTSxNQUFNLEtBQUssY0FBYyxJQUFJLEVBQUU7RUFDckMsSUFBSSxLQUNGLE9BQU8sT0FBTyxLQUFLO0dBQ2pCO0dBQ0E7R0FDQTtHQUNBO0dBQ0E7R0FDQSxZQUFZLElBQUksYUFBYTtFQUMvQixDQUFDO09BRUQsS0FBSyxjQUFjLElBQUksSUFBSTtHQUN6QjtHQUNBO0dBQ0E7R0FDQTtHQUNBO0dBQ0EsWUFBWTtFQUNkLENBQUM7RUFFSCxLQUFLLFNBQVMsU0FBUyxJQUFJLE1BQU07RUFDakMsS0FBSywwQkFBMEIsRUFBRTtFQUNqQyxLQUFLLGFBQWEsT0FBTyxFQUFFO0NBQzdCO0NBRUEsTUFBTSx1QkFDSixTQUNBLFFBQ21DO0VBQ25DLE1BQU0sUUFBUSxLQUFLLGNBQWMsSUFBSSxPQUFPO0VBQzVDLElBQUksQ0FBQyxPQUFPLE1BQU0sSUFBSSxNQUFNLGdCQUFnQixRQUFRLFdBQVc7RUFDL0QsTUFBTSxhQUFhLE1BQU07RUFDekIsTUFBTSxTQUFTLEtBQUssZ0JBQWdCLElBQUksT0FBTztFQUMvQyxJQUNFLFVBQ0EsT0FBTyxlQUFlLE1BQU0sY0FDNUIsS0FBSyxJQUFJLElBQUksT0FBTyxXQUFXLGlCQUFpQix1QkFFaEQsT0FBTztFQUtULE1BQU0sVUFBVSxLQUFLLGtCQUFrQixJQUFJLE9BQU87RUFDbEQsSUFBSSxTQUFTLFVBQVUsU0FBUyxRQUFRLGVBQWUsWUFBWSxPQUFPLFFBQVE7RUFDbEYsTUFBTSxnQkFBZ0IsWUFBWTtHQUNoQyxNQUFNLFNBQVMsTUFBTSxxQkFBcUI7SUFDeEMsYUFBYSxNQUFNO0lBQ25CLDBCQUEwQixLQUFLLG1CQUFtQixPQUFPO0lBQ3pELE9BQU8sS0FBSztJQUNaLEdBQUksU0FBUyxFQUFFLE9BQU8sSUFBSSxDQUFDO0dBQzdCLENBQUM7R0FDRCxJQUFJLE9BQU8sU0FBUyxpQkFBaUIsTUFBTSxJQUFJLE1BQU0sT0FBTyxNQUFNO0dBQ2xFLElBQUksQ0FBQyxPQUFPLEtBQUssTUFBTSxJQUFJLE1BQU0sK0NBQStDO0dBQ2hGLE1BQU0sUUFBUTtJQUFFLE1BQU0sT0FBTztJQUFLLFVBQVUsS0FBSyxJQUFJO0lBQUc7R0FBVztHQUNuRSxJQUFJLEtBQUssY0FBYyxJQUFJLE9BQU8sTUFBTSxTQUFTLE1BQU0sZUFBZSxZQUNwRSxLQUFLLGdCQUFnQixJQUFJLFNBQVMsS0FBSztHQUV6QyxPQUFPO0VBQ1QsRUFBQSxDQUFHLENBQUMsQ0FBQyxjQUFjO0dBQ2pCLElBQUksS0FBSyxrQkFBa0IsSUFBSSxPQUFPLENBQUMsRUFBRSxZQUFZLGNBQ25ELEtBQUssa0JBQWtCLE9BQU8sT0FBTztFQUV6QyxDQUFDO0VBQ0QsS0FBSyxrQkFBa0IsSUFBSSxTQUFTO0dBQUU7R0FBTztHQUFZLFNBQVM7RUFBYSxDQUFDO0VBQ2hGLE9BQU87Q0FDVDtDQUVBLE1BQWMsbUJBQW1CLFNBQWlCO0VBQ2hELE1BQU0sV0FBVyxLQUFLLGNBQWMsSUFBSSxPQUFPO0VBQy9DLE1BQU0sYUFBYSxVQUFVO0VBQzdCLE1BQU0sWUFBWSxNQUFNLCtCQUErQixPQUFPO0VBQzlELE1BQU0sY0FBYztHQUNsQixhQUFhLFVBQVU7R0FDdkIsV0FBVyxVQUFVO0VBQ3ZCO0VBQ0EsTUFBTSxVQUFVLEtBQUssY0FBYyxJQUFJLE9BQU87RUFDOUMsSUFBSSxDQUFDLFNBQVMsUUFBUSxNQUFNLElBQUksTUFBTSxnQkFBZ0IsUUFBUSxxQkFBcUI7RUFHbkYsSUFBSSxZQUFZLFlBQVksUUFBUSxlQUFlLFlBQVk7R0FDN0QsUUFBUSxjQUFjO0lBQUUsR0FBRyxRQUFRO0lBQWEsR0FBRztHQUFZO0dBQy9ELEtBQUssYUFBYSxPQUFPO0dBQ3pCLEtBQUssMEJBQTBCLE9BQU87RUFDeEM7RUFDQSxPQUFPO0dBQ0wsYUFBYSxRQUFRLFlBQVk7R0FDakMsV0FBVyxRQUFRLFlBQVk7RUFDakM7Q0FDRjtDQUVBLE1BQWMsZ0JBQ1osSUFDQSxPQUNBLFFBQ2tCO0VBQ2xCLElBQUksTUFBTSxtQkFBbUIsUUFBUSxNQUFNLG1CQUFtQixRQUFXLE9BQU87RUFDaEYsTUFBTSxhQUFhLE1BQU07RUFDekIsTUFBTSxTQUFTLE1BQU0scUJBQXFCLFlBQVksS0FBSyx1QkFBdUIsSUFBSSxNQUFNLENBQUM7RUFDN0YsSUFBSSxLQUFLLGNBQWMsSUFBSSxFQUFFLE1BQU0sU0FBUyxNQUFNLGVBQWUsWUFBWSxPQUFPO0VBQ3BGLElBQUksT0FBTyxTQUFTLGlCQUFpQjtHQUNuQyxLQUFLLGFBQWEsT0FBTyxFQUFFO0dBQzNCLE9BQU8sS0FBSywwQ0FBMEM7SUFDcEQsU0FBUztJQUNULFdBQVcsTUFBTTtJQUNqQixjQUFjLE9BQU87R0FDdkIsQ0FBQztHQUNELE9BQU87RUFDVDtFQUNBLElBQUksT0FBTyxrQkFBa0IsTUFBTSxnQkFBZ0I7R0FDakQsSUFBSSxDQUFDLEtBQUssYUFBYSxJQUFJLEVBQUUsR0FDM0IsT0FBTyxLQUNMLHdDQUF3QyxNQUFNLEtBQUssR0FBRyxHQUFHLEtBQUssT0FBTyxlQUFlLE9BQU8sTUFBTSxlQUFlLEdBQ2xIO0dBQ0YsS0FBSyxhQUFhLElBQUksRUFBRTtHQUN4QixPQUFPO0VBQ1Q7RUFDQSxJQUFJLEtBQUssYUFBYSxPQUFPLEVBQUUsR0FDN0IsT0FBTyxLQUNMLG1DQUFtQyxNQUFNLEtBQUssR0FBRyxHQUFHLEtBQUssT0FBTyxlQUFlLE1BQU0sTUFBTSxlQUFlLEdBQzVHO0VBQ0YsT0FBTztDQUNUO0NBRUEsMEJBQWtDLElBQWtCO0VBQ2xELEtBQUssZ0JBQWdCLE9BQU8sRUFBRTtDQUNoQztDQUVBLElBQUksYUFBcUI7RUFDdkIsT0FBTyxDQUFDLEdBQUcsS0FBSyxjQUFjLE9BQU8sQ0FBQyxDQUFDLENBQUMsUUFBUSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7Q0FDbEU7Q0FDQSxJQUFJLFdBQW1CO0VBQ3JCLE9BQU8sS0FBSztDQUNkOzs7Ozs7Q0FPQSxJQUFJLGVBTUQ7RUFDRCxNQUFNLE1BQU0sS0FBSyxJQUFJO0VBQ3JCLE9BQU8sQ0FBQyxHQUFHLEtBQUssY0FBYyxRQUFRLENBQUMsQ0FBQyxDQUNyQyxLQUFLLENBQUMsSUFBSSxPQUFPO0dBQ2hCLE1BQU0sU0FBUyxLQUFLLGdCQUFnQixJQUFJLEVBQUU7R0FLMUMsTUFBTSxVQUhKLFdBQVcsVUFDWCxPQUFPLGVBQWUsRUFBRSxjQUN4QixNQUFNLE9BQU8sV0FBVyxpQkFBaUIsd0JBQ25CLE9BQU8sS0FBSyxZQUFZLFVBQVU7R0FDMUQsT0FBTztJQUNMLE1BQU0sRUFBRTtJQUNSLGFBQWEsU0FBUyxlQUFlO0lBQ3JDLFdBQVcsRUFBRSxrQkFBa0I7SUFDL0IsU0FBUyxLQUFLLGFBQWEsSUFBSSxFQUFFO0lBR2pDLFVBQ0UsU0FBUyxhQUFhLFFBQVEsU0FBUyxhQUFhLFNBQ2hELFFBQVEsV0FBVyxNQUNuQjtHQUNSO0VBQ0YsQ0FBQyxDQUFDLENBQ0QsVUFBVSxHQUFHLE1BQU0sRUFBRSxLQUFLLGNBQWMsRUFBRSxJQUFJLENBQUM7Q0FDcEQ7QUFDRiJ9
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
|
|
3
3
|
import { estimateImageGenerationCostMicroUsd, imageGenerationCostMethod } from "./qgrid-image-generation";
|
|
4
|
-
import { type ImageGenerationMetadata, type QgridContent, type QueryOutput } from "./qgrid.types";
|
|
4
|
+
import { QueryInput, type ImageGenerationMetadata, type QgridContent, type QueryOutput } from "./qgrid.types";
|
|
5
5
|
|
|
6
6
|
const options = { quality: "high" as const, size: "1024x1024" as const, background: "transparent" as const };
|
|
7
7
|
const generation: ImageGenerationMetadata = {
|
|
@@ -17,6 +17,12 @@ function result(content: QgridContent[]): QueryOutput {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
describe("standalone image cost estimates", () => {
|
|
20
|
+
it("accepts automatic image mode while preserving boolean requests", () => {
|
|
21
|
+
for (const imageGeneration of [true, false, "auto"] as const) {
|
|
22
|
+
expect(QueryInput.parse({ prompt: "chat", imageGeneration }).imageGeneration).toBe(imageGeneration);
|
|
23
|
+
}
|
|
24
|
+
expect(QueryInput.safeParse({ prompt: "chat", imageGeneration: "required" }).success).toBe(false);
|
|
25
|
+
});
|
|
20
26
|
it("uses response usage once for multiple outputs without pricing requested settings or driver tokens", () => {
|
|
21
27
|
const output = result([
|
|
22
28
|
{ type: "image", data: "first", generation: { ...generation,
|
|
@@ -122,6 +122,18 @@ describe("qgrid run lifecycle start", () => {
|
|
|
122
122
|
});
|
|
123
123
|
});
|
|
124
124
|
|
|
125
|
+
it.each([false, true])("classifies automatic image output only when produced (%s)", async (hasImage) => {
|
|
126
|
+
const args = { prompt: "chat", model: "openai/gpt-6-astra", imageGeneration: "auto" as const };
|
|
127
|
+
const run = await beforeQuery(args);
|
|
128
|
+
expect(createRunMock).toHaveBeenCalledWith(expect.objectContaining({ is_image_generation: false }));
|
|
129
|
+
await afterQuery(run.requestLogId, run.stepIndex, args, queryOutput({
|
|
130
|
+
content: hasImage ? [{ type: "image", data: "png" }] : [{ type: "text", text: "hello" }],
|
|
131
|
+
}));
|
|
132
|
+
const finish = finishRunMock.mock.calls[0]![1];
|
|
133
|
+
expect(finish.is_image_generation).toBe(hasImage ? true : undefined);
|
|
134
|
+
expect(finish.image_cost_method).toBe(hasImage ? "assumed:gpt-image-2:medium:1536x1024:png" : null);
|
|
135
|
+
});
|
|
136
|
+
|
|
125
137
|
it("stores attached tool definitions on the run and omits them when absent", async () => {
|
|
126
138
|
const tools = [
|
|
127
139
|
{ name: "getWeather", description: "Get weather for a city", inputSchema: { type: "object" } },
|
|
@@ -542,6 +554,7 @@ describe("qgrid run lifecycle TTFT", () => {
|
|
|
542
554
|
10,
|
|
543
555
|
expect.objectContaining({
|
|
544
556
|
image_cost_usd: 41000,
|
|
557
|
+
is_image_generation: true,
|
|
545
558
|
image_cost_method: "assumed:gpt-image-2:medium:1536x1024:png",
|
|
546
559
|
}),
|
|
547
560
|
);
|
|
@@ -135,7 +135,7 @@ export async function beforeQuery(args: QueryInput): Promise<{
|
|
|
135
135
|
project_name: args.projectName,
|
|
136
136
|
history: filterHistoryForStorage(args.history),
|
|
137
137
|
tools: args.tools?.length ? args.tools : undefined,
|
|
138
|
-
is_image_generation: args.imageGeneration,
|
|
138
|
+
is_image_generation: args.imageGeneration === "auto" ? false : args.imageGeneration,
|
|
139
139
|
json_schema: args.jsonSchema ?? null,
|
|
140
140
|
});
|
|
141
141
|
}
|
|
@@ -240,6 +240,7 @@ export async function afterQuery(
|
|
|
240
240
|
cost_usd: agg.cost_usd,
|
|
241
241
|
cost_source: agg.cost_source,
|
|
242
242
|
image_cost_usd: imageCostMicroUsd,
|
|
243
|
+
...(imageParts.length > 0 ? { is_image_generation: true } : {}),
|
|
243
244
|
image_cost_method:
|
|
244
245
|
imageCostMicroUsd !== null
|
|
245
246
|
? imageGenerationCostMethod(args.imageGenerationOptions, result)
|
|
@@ -804,12 +804,12 @@ describe("QgridFrame.prepareStream", () => {
|
|
|
804
804
|
requestLogSaveMock.mockReset();
|
|
805
805
|
});
|
|
806
806
|
|
|
807
|
-
it("rejects imageGeneration before creating an SSE stream", async () => {
|
|
807
|
+
it.each([true, "auto"] as const)("rejects imageGeneration=%s before creating an SSE stream", async (imageGeneration) => {
|
|
808
808
|
await expect(
|
|
809
809
|
QgridFrame.prepareStream({
|
|
810
810
|
prompt: "draw",
|
|
811
811
|
model: "openai/gpt-5-codex",
|
|
812
|
-
imageGeneration
|
|
812
|
+
imageGeneration,
|
|
813
813
|
}),
|
|
814
814
|
).rejects.toThrow(/imageGeneration is not supported with streaming/);
|
|
815
815
|
|
|
@@ -167,8 +167,8 @@ export const QueryInput = z.looseObject({
|
|
|
167
167
|
logger: z.boolean().optional(),
|
|
168
168
|
runContext: QgridRunContext.optional(),
|
|
169
169
|
toolResults: z.array(QgridToolResultInput).optional(),
|
|
170
|
-
// OpenAI
|
|
171
|
-
imageGeneration: z.boolean().optional(),
|
|
170
|
+
// OpenAI only, non-stream: true requires an image; auto permits text or native image tools.
|
|
171
|
+
imageGeneration: z.union([z.boolean(), z.literal("auto")]).optional(),
|
|
172
172
|
// qgrid 가격 추정 및 Codex 이미지 요청 힌트. 이미지 모델은 gpt-image-2 로 고정 가정한다.
|
|
173
173
|
imageGenerationOptions: ImageGenerationOptions.optional(),
|
|
174
174
|
});
|
|
@@ -552,6 +552,7 @@ class RequestLogModelClass extends BaseModelClass<
|
|
|
552
552
|
tool_call_count?: number;
|
|
553
553
|
image_cost_usd?: number | null;
|
|
554
554
|
image_cost_method?: string | null;
|
|
555
|
+
is_image_generation?: boolean;
|
|
555
556
|
response_json_ok?: boolean | null;
|
|
556
557
|
},
|
|
557
558
|
): Promise<void> {
|
|
@@ -578,6 +579,7 @@ class RequestLogModelClass extends BaseModelClass<
|
|
|
578
579
|
"tool_call_count",
|
|
579
580
|
"image_cost_usd",
|
|
580
581
|
"image_cost_method",
|
|
582
|
+
"is_image_generation",
|
|
581
583
|
"response_json_ok",
|
|
582
584
|
] as const;
|
|
583
585
|
for (const key of fields) {
|
|
@@ -327,7 +327,8 @@ Content-Type: application/json
|
|
|
327
327
|
"imageGenerationOptions": {
|
|
328
328
|
"quality": "low",
|
|
329
329
|
"size": "1024x1024",
|
|
330
|
-
"background": "auto"
|
|
330
|
+
"background": "auto",
|
|
331
|
+
"outputFormat": "png"
|
|
331
332
|
}
|
|
332
333
|
}
|
|
333
334
|
}
|
|
@@ -390,7 +391,8 @@ Content-Type: application/json
|
|
|
390
391
|
"imageGenerationOptions": {
|
|
391
392
|
"quality": "low",
|
|
392
393
|
"size": "1024x1024",
|
|
393
|
-
"background": "auto"
|
|
394
|
+
"background": "auto",
|
|
395
|
+
"outputFormat": "png"
|
|
394
396
|
}
|
|
395
397
|
}
|
|
396
398
|
}
|
|
@@ -35,6 +35,7 @@ describe("Anthropic 1M context policy", () => {
|
|
|
35
35
|
expect(supports1MContext("claude-opus-5")).toBe(true);
|
|
36
36
|
expect(supports1MContext("claude-opus-5-5")).toBe(true);
|
|
37
37
|
expect(supports1MContext("claude-sonnet-5")).toBe(true);
|
|
38
|
+
expect(supports1MContext("claude-sonnet-5-5")).toBe(true);
|
|
38
39
|
expect(supports1MContext("claude-sonnet-4-6")).toBe(true);
|
|
39
40
|
expect(supports1MContext("claude-opus-4-6")).toBe(true);
|
|
40
41
|
expect(supports1MContext("claude-opus-4-8")).toBe(true);
|
|
@@ -51,6 +52,7 @@ describe("Anthropic 1M context policy", () => {
|
|
|
51
52
|
expect(needsCli1mSuffix("claude-opus-5")).toBe(false);
|
|
52
53
|
expect(needsCli1mSuffix("claude-opus-5-5")).toBe(false);
|
|
53
54
|
expect(needsCli1mSuffix("claude-sonnet-5")).toBe(false);
|
|
55
|
+
expect(needsCli1mSuffix("claude-sonnet-5-5")).toBe(false);
|
|
54
56
|
expect(needsCli1mSuffix("claude-sonnet-4-6")).toBe(true);
|
|
55
57
|
expect(needsCli1mSuffix("claude-opus-4-6")).toBe(true);
|
|
56
58
|
expect(needsCli1mSuffix("claude-opus-4-8")).toBe(false);
|
|
@@ -80,7 +82,7 @@ describe("Anthropic 1M context policy", () => {
|
|
|
80
82
|
});
|
|
81
83
|
|
|
82
84
|
describe("Anthropic thinking policy", () => {
|
|
83
|
-
it("Fable 5/5.1, Opus 5, Opus 5.5 는 adaptive thinking 을 보존한다", () => {
|
|
85
|
+
it("Fable 5/5.1, Opus 5, Opus 5.5, Sonnet 5.5 는 adaptive thinking 을 보존한다", () => {
|
|
84
86
|
expect(usesAdaptiveThinking("claude-fable-5-1")).toBe(true);
|
|
85
87
|
expect(usesAdaptiveThinking("anthropic/claude-fable-5-1")).toBe(true);
|
|
86
88
|
expect(usesAdaptiveThinking("claude-fable-5")).toBe(true);
|
|
@@ -89,6 +91,8 @@ describe("Anthropic thinking policy", () => {
|
|
|
89
91
|
expect(usesAdaptiveThinking("anthropic/claude-opus-5")).toBe(true);
|
|
90
92
|
expect(usesAdaptiveThinking("claude-opus-5-5")).toBe(true);
|
|
91
93
|
expect(usesAdaptiveThinking("anthropic/claude-opus-5-5[1m]")).toBe(true);
|
|
94
|
+
expect(usesAdaptiveThinking("claude-sonnet-5-5")).toBe(true);
|
|
95
|
+
expect(usesAdaptiveThinking("anthropic/claude-sonnet-5-5[1m]")).toBe(true);
|
|
92
96
|
expect(usesAdaptiveThinking("claude-sonnet-5")).toBe(false);
|
|
93
97
|
expect(usesAdaptiveThinking("claude-opus-4-8")).toBe(false);
|
|
94
98
|
});
|
|
@@ -49,6 +49,7 @@ const ONE_MILLION_CONTEXT_MODELS = new Set([
|
|
|
49
49
|
"claude-fable-5",
|
|
50
50
|
"claude-opus-5",
|
|
51
51
|
"claude-opus-5-5",
|
|
52
|
+
"claude-sonnet-5-5",
|
|
52
53
|
"claude-sonnet-5",
|
|
53
54
|
"claude-sonnet-4-6",
|
|
54
55
|
"claude-opus-4-6",
|
|
@@ -56,8 +57,8 @@ const ONE_MILLION_CONTEXT_MODELS = new Set([
|
|
|
56
57
|
]);
|
|
57
58
|
|
|
58
59
|
const CLI_ONE_MILLION_SUFFIX_MODELS = new Set(["claude-sonnet-4-6", "claude-opus-4-6"]);
|
|
59
|
-
// Fable 5/5.1
|
|
60
|
-
// Opus 5.5: 공식 사양 "can't be turned off", 2026-09-22 출시). Opus 5 는
|
|
60
|
+
// Fable 5/5.1, Opus 5.5, Sonnet 5.5 는 thinking disabled 를 거부한다(Fable: CLI 카탈로그 `rejects_disabled_thinking`,
|
|
61
|
+
// Opus 5.5: 공식 사양 "can't be turned off", 2026-09-22 출시. Sonnet 5.5: API `{type: "disabled"}` 400, CLI 카탈로그 `rejects_disabled_thinking`, 2026-09-29 출시). Opus 5 는
|
|
61
62
|
// disabled 를 high 이하에서 지원하지만, 공식 기본값·권장 동작인 adaptive thinking 을 유지한다. qgrid
|
|
62
63
|
// 기본 effort=low 가 비용/지연 제어를 맡으며, 이 정책은 disabled+xhigh/max 400 오류와 disabled 시
|
|
63
64
|
// tool/XML 출력 오염도 피한다.
|
|
@@ -66,6 +67,7 @@ const ADAPTIVE_THINKING_MODELS = new Set([
|
|
|
66
67
|
"claude-fable-5",
|
|
67
68
|
"claude-opus-5",
|
|
68
69
|
"claude-opus-5-5",
|
|
70
|
+
"claude-sonnet-5-5",
|
|
69
71
|
]);
|
|
70
72
|
|
|
71
73
|
// Fable 계열: 구독 플랜에서 usage credits 가 필요한 최상위 티어. 구독 usage API 의
|
|
@@ -59,6 +59,7 @@ describe("calculateCostUsd", () => {
|
|
|
59
59
|
// Opus 5.5 는 cache read 만 0.05x 특례($0.20), cache write 배율은 표준(5m $5 / 1h $8).
|
|
60
60
|
["claude-opus-5-5", 4, 20, 0.2, 8],
|
|
61
61
|
["claude-sonnet-5", 2, 10, 0.2, 4],
|
|
62
|
+
["claude-sonnet-5-5", 2, 10, 0.2, 4],
|
|
62
63
|
])(
|
|
63
64
|
"%s official Anthropic rates for 5m/1h cache writes",
|
|
64
65
|
(model, inputTokens, outputTokens, cachedInputTokens, cacheCreationInputTokens) => {
|
|
@@ -188,6 +188,9 @@ const ANTHROPIC_COSTS: Record<string, ModelCosts> = {
|
|
|
188
188
|
// Sonnet 5 의 introductory $2/$10 이 정식 단가로 확정됐다. 2026-09-01 에 예정됐던 $3/$15 인상은
|
|
189
189
|
// 취소됐으므로 날짜 분기 없이 고정 단가로 계산한다.
|
|
190
190
|
"claude-sonnet-5": anthropicCosts(2, 10),
|
|
191
|
+
// Sonnet 5.5 (2026-09-29 출시): Sonnet 5 와 같은 $2/$10, cache read 는 표준 0.1x($0.20).
|
|
192
|
+
// @see https://platform.claude.com/docs/en/about-claude/pricing
|
|
193
|
+
"claude-sonnet-5-5": anthropicCosts(2, 10),
|
|
191
194
|
};
|
|
192
195
|
|
|
193
196
|
// gpt-5.3-codex-spark 는 research preview 로 공식 token 단가가 아직 final 이 아니다.
|
|
@@ -79,7 +79,7 @@ export interface GenerateRequest {
|
|
|
79
79
|
reuseInput?: Array<UserInput>;
|
|
80
80
|
// OpenAI image_generation tool 을 켠다(OpenAI 경로 전용, opt-in).
|
|
81
81
|
// 이 플래그가 있으면 dispatcher 는 항상 cold thread 로 실행하고 재사용 라우팅을 건너뛴다.
|
|
82
|
-
imageGeneration?: boolean;
|
|
82
|
+
imageGeneration?: boolean | "auto";
|
|
83
83
|
imageGenerationOptions?: ImageGenerationOptions;
|
|
84
84
|
}
|
|
85
85
|
|