@genspectrum/dashboard-components 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/custom-elements.json +1 -1
  2. package/dist/assets/mutationOverTimeWorker-kjUXkRmn.js.map +1 -0
  3. package/dist/dashboard-components.js +142 -70
  4. package/dist/dashboard-components.js.map +1 -1
  5. package/dist/genspectrum-components.d.ts +2 -2
  6. package/dist/style.css +36 -0
  7. package/package.json +1 -1
  8. package/src/lapisApi/lapisApi.ts +59 -34
  9. package/src/preact/aggregatedData/aggregate.stories.tsx +35 -0
  10. package/src/preact/aggregatedData/aggregate.tsx +1 -2
  11. package/src/preact/components/error-boundary.tsx +9 -4
  12. package/src/preact/components/error-display.stories.tsx +23 -3
  13. package/src/preact/components/error-display.tsx +37 -25
  14. package/src/preact/dateRangeSelector/date-range-selector.tsx +1 -1
  15. package/src/preact/lineageFilter/lineage-filter.tsx +2 -3
  16. package/src/preact/locationFilter/location-filter.tsx +2 -3
  17. package/src/preact/mutationComparison/mutation-comparison.tsx +1 -2
  18. package/src/preact/mutationFilter/mutation-filter.tsx +1 -1
  19. package/src/preact/mutations/mutations.tsx +1 -2
  20. package/src/preact/mutationsOverTime/__mockData__/noDataWhenNoMutationsAreInFilter.ts +22 -0
  21. package/src/preact/mutationsOverTime/__mockData__/noDataWhenThereAreNoDatesInFilter.ts +22 -0
  22. package/src/preact/mutationsOverTime/mutationOverTimeWorker.mock.ts +2 -0
  23. package/src/preact/mutationsOverTime/mutations-over-time-grid.tsx +3 -0
  24. package/src/preact/mutationsOverTime/mutations-over-time.stories.tsx +71 -1
  25. package/src/preact/mutationsOverTime/mutations-over-time.tsx +10 -5
  26. package/src/preact/numberSequencesOverTime/number-sequences-over-time.tsx +1 -2
  27. package/src/preact/prevalenceOverTime/prevalence-over-time.tsx +1 -2
  28. package/src/preact/relativeGrowthAdvantage/relative-growth-advantage.tsx +1 -2
  29. package/src/preact/textInput/text-input.tsx +2 -3
  30. package/src/query/queryMutationsOverTime.spec.ts +30 -0
  31. package/src/query/queryMutationsOverTime.ts +7 -0
  32. package/src/web-components/visualization/gs-mutations-over-time.tsx +2 -2
  33. package/standalone-bundle/dashboard-components.js +4194 -4091
  34. package/standalone-bundle/dashboard-components.js.map +1 -1
  35. package/dist/assets/mutationOverTimeWorker-BOCXtKzd.js.map +0 -1
@@ -413,52 +413,74 @@ class LapisError extends Error {
413
413
  }
414
414
  }
415
415
  async function fetchAggregated(lapisUrl, body, signal) {
416
- const response = await fetch(aggregatedEndpoint(lapisUrl), {
417
- method: "POST",
418
- headers: {
419
- "Content-Type": "application/json"
416
+ const response = await callLapis(
417
+ aggregatedEndpoint(lapisUrl),
418
+ {
419
+ method: "POST",
420
+ headers: {
421
+ "Content-Type": "application/json"
422
+ },
423
+ body: JSON.stringify(body),
424
+ signal
420
425
  },
421
- body: JSON.stringify(body),
422
- signal
423
- });
424
- await handleErrors(response, "aggregated data");
426
+ "aggregated data"
427
+ );
425
428
  return aggregatedResponse.parse(await response.json());
426
429
  }
427
430
  async function fetchInsertions(lapisUrl, body, sequenceType, signal) {
428
- const response = await fetch(insertionsEndpoint(lapisUrl, sequenceType), {
429
- method: "POST",
430
- headers: {
431
- "Content-Type": "application/json"
431
+ const response = await callLapis(
432
+ insertionsEndpoint(lapisUrl, sequenceType),
433
+ {
434
+ method: "POST",
435
+ headers: {
436
+ "Content-Type": "application/json"
437
+ },
438
+ body: JSON.stringify(body),
439
+ signal
432
440
  },
433
- body: JSON.stringify(body),
434
- signal
435
- });
436
- await handleErrors(response, `${sequenceType} insertions`);
441
+ `${sequenceType} insertions`
442
+ );
437
443
  return insertionsResponse.parse(await response.json());
438
444
  }
439
445
  async function fetchSubstitutionsOrDeletions(lapisUrl, body, sequenceType, signal) {
440
- const response = await fetch(substitutionsOrDeletionsEndpoint(lapisUrl, sequenceType), {
441
- method: "POST",
442
- headers: {
443
- "Content-Type": "application/json"
446
+ const response = await callLapis(
447
+ substitutionsOrDeletionsEndpoint(lapisUrl, sequenceType),
448
+ {
449
+ method: "POST",
450
+ headers: {
451
+ "Content-Type": "application/json"
452
+ },
453
+ body: JSON.stringify(body),
454
+ signal
444
455
  },
445
- body: JSON.stringify(body),
446
- signal
447
- });
448
- await handleErrors(response, `${sequenceType} mutations`);
456
+ `${sequenceType} mutations`
457
+ );
449
458
  return mutationsResponse.parse(await response.json());
450
459
  }
451
460
  async function fetchReferenceGenome(lapisUrl, signal) {
452
- const response = await fetch(referenceGenomeEndpoint(lapisUrl), {
453
- method: "GET",
454
- headers: {
455
- "Content-Type": "application/json"
461
+ const response = await callLapis(
462
+ referenceGenomeEndpoint(lapisUrl),
463
+ {
464
+ method: "GET",
465
+ headers: {
466
+ "Content-Type": "application/json"
467
+ },
468
+ signal
456
469
  },
457
- signal
458
- });
459
- await handleErrors(response, "the reference genomes");
470
+ "the reference genomes"
471
+ );
460
472
  return referenceGenomeResponse.parse(await response.json());
461
473
  }
474
+ async function callLapis(input, init, requestedDataName) {
475
+ try {
476
+ const response = await fetch(input, init);
477
+ await handleErrors(response, requestedDataName);
478
+ return response;
479
+ } catch (error) {
480
+ const message = error instanceof Error ? error.message : `${error}`;
481
+ throw new UnknownLapisError(`Failed to connect to LAPIS: ${message}`, 500, requestedDataName);
482
+ }
483
+ }
462
484
  const handleErrors = async (response, requestedData) => {
463
485
  if (!response.ok) {
464
486
  if (response.status >= 400 && response.status < 500) {
@@ -1232,7 +1254,7 @@ class UserFacingError extends Error {
1232
1254
  this.name = "UserFacingError";
1233
1255
  }
1234
1256
  }
1235
- const ErrorDisplay = ({ error }) => {
1257
+ const ErrorDisplay = ({ error, resetError, layout }) => {
1236
1258
  console.error(error);
1237
1259
  const containerRef = A(null);
1238
1260
  const ref = A(null);
@@ -1245,26 +1267,32 @@ const ErrorDisplay = ({ error }) => {
1245
1267
  "div",
1246
1268
  {
1247
1269
  ref: containerRef,
1248
- className: "h-full w-full rounded-md border-2 border-gray-100 p-2 flex items-center justify-center flex-col",
1270
+ className: `h-full w-full rounded-md border-2 border-gray-100 p-2 flex items-center justify-center ${layout === "horizontal" ? "flex-row" : "flex-col"}`,
1249
1271
  children: [
1250
- /* @__PURE__ */ u$1("div", { className: "text-red-700 font-bold", children: headline }),
1251
1272
  /* @__PURE__ */ u$1("div", { children: [
1252
- "Oops! Something went wrong.",
1253
- details !== void 0 && /* @__PURE__ */ u$1(Fragment, { children: [
1254
- " ",
1255
- /* @__PURE__ */ u$1("button", { className: "underline hover:text-gray-400", onClick: () => {
1256
- var _a;
1257
- return (_a = ref.current) == null ? void 0 : _a.showModal();
1258
- }, children: "Show details." }),
1259
- /* @__PURE__ */ u$1("dialog", { ref, class: "modal", children: [
1260
- /* @__PURE__ */ u$1("div", { class: "modal-box", children: [
1261
- /* @__PURE__ */ u$1("form", { method: "dialog", children: /* @__PURE__ */ u$1("button", { className: "btn btn-sm btn-circle btn-ghost absolute right-2 top-2", children: "✕" }) }),
1262
- /* @__PURE__ */ u$1("h1", { class: "text-lg", children: details.headline }),
1263
- /* @__PURE__ */ u$1("p", { class: "py-4", children: details.message })
1264
- ] }),
1265
- /* @__PURE__ */ u$1("form", { method: "dialog", class: "modal-backdrop", children: /* @__PURE__ */ u$1("button", { children: "close" }) })
1273
+ /* @__PURE__ */ u$1("div", { className: "text-red-700 font-bold", children: headline }),
1274
+ /* @__PURE__ */ u$1("div", { children: [
1275
+ "Oops! Something went wrong.",
1276
+ details !== void 0 && /* @__PURE__ */ u$1(Fragment, { children: [
1277
+ " ",
1278
+ /* @__PURE__ */ u$1("button", { className: "underline hover:text-gray-400", onClick: () => {
1279
+ var _a;
1280
+ return (_a = ref.current) == null ? void 0 : _a.showModal();
1281
+ }, children: "Show details." }),
1282
+ /* @__PURE__ */ u$1("dialog", { ref, class: "modal", children: [
1283
+ /* @__PURE__ */ u$1("div", { class: "modal-box", children: [
1284
+ /* @__PURE__ */ u$1("form", { method: "dialog", children: /* @__PURE__ */ u$1("button", { className: "btn btn-sm btn-circle btn-ghost absolute right-2 top-2", children: "✕" }) }),
1285
+ /* @__PURE__ */ u$1("h1", { class: "text-lg", children: details.headline }),
1286
+ /* @__PURE__ */ u$1("p", { class: "py-4", children: details.message })
1287
+ ] }),
1288
+ /* @__PURE__ */ u$1("form", { method: "dialog", class: "modal-backdrop", children: /* @__PURE__ */ u$1("button", { children: "close" }) })
1289
+ ] })
1266
1290
  ] })
1267
1291
  ] })
1292
+ ] }),
1293
+ /* @__PURE__ */ u$1("button", { onClick: resetError, className: "btn btn-sm flex items-center m-4", children: [
1294
+ /* @__PURE__ */ u$1("span", { className: "iconify mdi--reload text-lg" }),
1295
+ "Try again"
1268
1296
  ] })
1269
1297
  ]
1270
1298
  }
@@ -1303,10 +1331,10 @@ function getDisplayedErrorMessage(error) {
1303
1331
  const ResizeContainer = ({ children, size }) => {
1304
1332
  return /* @__PURE__ */ u$1("div", { style: size, className: "bg-white", children });
1305
1333
  };
1306
- const ErrorBoundary = ({ size, children }) => {
1307
- const [internalError] = b2();
1334
+ const ErrorBoundary = ({ size, layout, children }) => {
1335
+ const [internalError, resetError] = b2();
1308
1336
  if (internalError) {
1309
- return /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(ErrorDisplay, { error: internalError }) });
1337
+ return /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(ErrorDisplay, { error: internalError, resetError, layout }) });
1310
1338
  }
1311
1339
  return /* @__PURE__ */ u$1(Fragment, { children });
1312
1340
  };
@@ -1945,7 +1973,7 @@ const MutationComparisonInner = (componentProps) => {
1945
1973
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
1946
1974
  }
1947
1975
  if (error !== null) {
1948
- return /* @__PURE__ */ u$1(ErrorDisplay, { error });
1976
+ throw error;
1949
1977
  }
1950
1978
  if (data === null) {
1951
1979
  return /* @__PURE__ */ u$1(NoDataDisplay, {});
@@ -4210,6 +4238,36 @@ input.tab:checked + .tab-content,
4210
4238
  --togglehandleborder: 0 0 0 3px var(--fallback-bc,oklch(var(--bc)/1)) inset,
4211
4239
  var(--handleoffsetcalculator) 0 0 3px var(--fallback-bc,oklch(var(--bc)/1)) inset;
4212
4240
  }
4241
+ .artboard.phone-1.horizontal,
4242
+ .artboard.phone-1.artboard-horizontal {
4243
+ width: 568px;
4244
+ height: 320px;
4245
+ }
4246
+ .artboard.phone-2.horizontal,
4247
+ .artboard.phone-2.artboard-horizontal {
4248
+ width: 667px;
4249
+ height: 375px;
4250
+ }
4251
+ .artboard.phone-3.horizontal,
4252
+ .artboard.phone-3.artboard-horizontal {
4253
+ width: 736px;
4254
+ height: 414px;
4255
+ }
4256
+ .artboard.phone-4.horizontal,
4257
+ .artboard.phone-4.artboard-horizontal {
4258
+ width: 812px;
4259
+ height: 375px;
4260
+ }
4261
+ .artboard.phone-5.horizontal,
4262
+ .artboard.phone-5.artboard-horizontal {
4263
+ width: 896px;
4264
+ height: 414px;
4265
+ }
4266
+ .artboard.phone-6.horizontal,
4267
+ .artboard.phone-6.artboard-horizontal {
4268
+ width: 1024px;
4269
+ height: 320px;
4270
+ }
4213
4271
  .btm-nav-xs > *:where(.active) {
4214
4272
  border-top-width: 1px;
4215
4273
  }
@@ -4622,6 +4680,9 @@ input.tab:checked + .tab-content,
4622
4680
  .m-2 {
4623
4681
  margin: 0.5rem;
4624
4682
  }
4683
+ .m-4 {
4684
+ margin: 1rem;
4685
+ }
4625
4686
  .mx-1 {
4626
4687
  margin-left: 0.25rem;
4627
4688
  margin-right: 0.25rem;
@@ -5005,6 +5066,9 @@ input.tab:checked + .tab-content,
5005
5066
  .mdi--fullscreen-exit {
5006
5067
  --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M14 14h5v2h-3v3h-2zm-9 0h5v5H8v-3H5zm3-9h2v5H5V8h3zm11 3v2h-5V5h2v3z'/%3E%3C/svg%3E");
5007
5068
  }
5069
+ .mdi--reload {
5070
+ --svg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='24' height='24'%3E%3Cpath fill='black' d='M2 12a9 9 0 0 0 9 9c2.39 0 4.68-.94 6.4-2.6l-1.5-1.5A6.7 6.7 0 0 1 11 19c-6.24 0-9.36-7.54-4.95-11.95S18 5.77 18 12h-3l4 4h.1l3.9-4h-3a9 9 0 0 0-18 0'/%3E%3C/svg%3E");
5071
+ }
5008
5072
  @media (min-width: 640px) {
5009
5073
 
5010
5074
  .sm\\:modal-middle {
@@ -5454,7 +5518,7 @@ const MutationsInner = (componentProps) => {
5454
5518
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
5455
5519
  }
5456
5520
  if (error !== null) {
5457
- return /* @__PURE__ */ u$1(ErrorDisplay, { error });
5521
+ throw error;
5458
5522
  }
5459
5523
  if (data === null) {
5460
5524
  return /* @__PURE__ */ u$1(NoDataDisplay, {});
@@ -7349,7 +7413,7 @@ const PrevalenceOverTimeInner = (componentProps) => {
7349
7413
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
7350
7414
  }
7351
7415
  if (error !== null) {
7352
- return /* @__PURE__ */ u$1(ErrorDisplay, { error });
7416
+ throw error;
7353
7417
  }
7354
7418
  if (data === null || data.every((variant) => variant.content.length === 0)) {
7355
7419
  return /* @__PURE__ */ u$1(NoDataDisplay, {});
@@ -7794,7 +7858,7 @@ const RelativeGrowthAdvantageInner = (componentProps) => {
7794
7858
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
7795
7859
  }
7796
7860
  if (error !== null) {
7797
- return /* @__PURE__ */ u$1(ErrorDisplay, { error });
7861
+ throw error;
7798
7862
  }
7799
7863
  if (data === null) {
7800
7864
  return /* @__PURE__ */ u$1(NoDataDisplay, {});
@@ -8025,7 +8089,7 @@ const AggregateInner = (componentProps) => {
8025
8089
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
8026
8090
  }
8027
8091
  if (error !== null) {
8028
- return /* @__PURE__ */ u$1(ErrorDisplay, { error });
8092
+ throw error;
8029
8093
  }
8030
8094
  if (data === null) {
8031
8095
  return /* @__PURE__ */ u$1(NoDataDisplay, {});
@@ -8309,7 +8373,7 @@ const NumberSequencesOverTimeInner = (componentProps) => {
8309
8373
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
8310
8374
  }
8311
8375
  if (error !== null) {
8312
- return /* @__PURE__ */ u$1(ErrorDisplay, { error });
8376
+ throw error;
8313
8377
  }
8314
8378
  if (data === null) {
8315
8379
  return /* @__PURE__ */ u$1(NoDataDisplay, {});
@@ -8473,7 +8537,7 @@ __decorateClass$6([
8473
8537
  NumberSequencesOverTimeComponent = __decorateClass$6([
8474
8538
  t$2("gs-number-sequences-over-time")
8475
8539
  ], NumberSequencesOverTimeComponent);
8476
- const encodedJs = "KGZ1bmN0aW9uKCkgewogICJ1c2Ugc3RyaWN0IjsKICB2YXIgdXRpbDsKICAoZnVuY3Rpb24odXRpbDIpIHsKICAgIHV0aWwyLmFzc2VydEVxdWFsID0gKHZhbCkgPT4gdmFsOwogICAgZnVuY3Rpb24gYXNzZXJ0SXMoX2FyZykgewogICAgfQogICAgdXRpbDIuYXNzZXJ0SXMgPSBhc3NlcnRJczsKICAgIGZ1bmN0aW9uIGFzc2VydE5ldmVyKF94KSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigpOwogICAgfQogICAgdXRpbDIuYXNzZXJ0TmV2ZXIgPSBhc3NlcnROZXZlcjsKICAgIHV0aWwyLmFycmF5VG9FbnVtID0gKGl0ZW1zKSA9PiB7CiAgICAgIGNvbnN0IG9iaiA9IHt9OwogICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHsKICAgICAgICBvYmpbaXRlbV0gPSBpdGVtOwogICAgICB9CiAgICAgIHJldHVybiBvYmo7CiAgICB9OwogICAgdXRpbDIuZ2V0VmFsaWRFbnVtVmFsdWVzID0gKG9iaikgPT4gewogICAgICBjb25zdCB2YWxpZEtleXMgPSB1dGlsMi5vYmplY3RLZXlzKG9iaikuZmlsdGVyKChrMikgPT4gdHlwZW9mIG9ialtvYmpbazJdXSAhPT0gIm51bWJlciIpOwogICAgICBjb25zdCBmaWx0ZXJlZCA9IHt9OwogICAgICBmb3IgKGNvbnN0IGsyIG9mIHZhbGlkS2V5cykgewogICAgICAgIGZpbHRlcmVkW2syXSA9IG9ialtrMl07CiAgICAgIH0KICAgICAgcmV0dXJuIHV0aWwyLm9iamVjdFZhbHVlcyhmaWx0ZXJlZCk7CiAgICB9OwogICAgdXRpbDIub2JqZWN0VmFsdWVzID0gKG9iaikgPT4gewogICAgICByZXR1cm4gdXRpbDIub2JqZWN0S2V5cyhvYmopLm1hcChmdW5jdGlvbihlMikgewogICAgICAgIHJldHVybiBvYmpbZTJdOwogICAgICB9KTsKICAgIH07CiAgICB1dGlsMi5vYmplY3RLZXlzID0gdHlwZW9mIE9iamVjdC5rZXlzID09PSAiZnVuY3Rpb24iID8gKG9iaikgPT4gT2JqZWN0LmtleXMob2JqKSA6IChvYmplY3QpID0+IHsKICAgICAgY29uc3Qga2V5cyA9IFtdOwogICAgICBmb3IgKGNvbnN0IGtleSBpbiBvYmplY3QpIHsKICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkgewogICAgICAgICAga2V5cy5wdXNoKGtleSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBrZXlzOwogICAgfTsKICAgIHV0aWwyLmZpbmQgPSAoYXJyLCBjaGVja2VyKSA9PiB7CiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBhcnIpIHsKICAgICAgICBpZiAoY2hlY2tlcihpdGVtKSkKICAgICAgICAgIHJldHVybiBpdGVtOwogICAgICB9CiAgICAgIHJldHVybiB2b2lkIDA7CiAgICB9OwogICAgdXRpbDIuaXNJbnRlZ2VyID0gdHlwZW9mIE51bWJlci5pc0ludGVnZXIgPT09ICJmdW5jdGlvbiIgPyAodmFsKSA9PiBOdW1iZXIuaXNJbnRlZ2VyKHZhbCkgOiAodmFsKSA9PiB0eXBlb2YgdmFsID09PSAibnVtYmVyIiAmJiBpc0Zpbml0ZSh2YWwpICYmIE1hdGguZmxvb3IodmFsKSA9PT0gdmFsOwogICAgZnVuY3Rpb24gam9pblZhbHVlcyhhcnJheSwgc2VwYXJhdG9yID0gIiB8ICIpIHsKICAgICAgcmV0dXJuIGFycmF5Lm1hcCgodmFsKSA9PiB0eXBlb2YgdmFsID09PSAic3RyaW5nIiA/IGAnJHt2YWx9J2AgOiB2YWwpLmpvaW4oc2VwYXJhdG9yKTsKICAgIH0KICAgIHV0aWwyLmpvaW5WYWx1ZXMgPSBqb2luVmFsdWVzOwogICAgdXRpbDIuanNvblN0cmluZ2lmeVJlcGxhY2VyID0gKF8sIHZhbHVlKSA9PiB7CiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICJiaWdpbnQiKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlLnRvU3RyaW5nKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHZhbHVlOwogICAgfTsKICB9KSh1dGlsIHx8ICh1dGlsID0ge30pKTsKICB2YXIgb2JqZWN0VXRpbDsKICAoZnVuY3Rpb24ob2JqZWN0VXRpbDIpIHsKICAgIG9iamVjdFV0aWwyLm1lcmdlU2hhcGVzID0gKGZpcnN0LCBzZWNvbmQpID0+IHsKICAgICAgcmV0dXJuIHsKICAgICAgICAuLi5maXJzdCwKICAgICAgICAuLi5zZWNvbmQKICAgICAgICAvLyBzZWNvbmQgb3ZlcndyaXRlcyBmaXJzdAogICAgICB9OwogICAgfTsKICB9KShvYmplY3RVdGlsIHx8IChvYmplY3RVdGlsID0ge30pKTsKICBjb25zdCBab2RQYXJzZWRUeXBlID0gdXRpbC5hcnJheVRvRW51bShbCiAgICAic3RyaW5nIiwKICAgICJuYW4iLAogICAgIm51bWJlciIsCiAgICAiaW50ZWdlciIsCiAgICAiZmxvYXQiLAogICAgImJvb2xlYW4iLAogICAgImRhdGUiLAogICAgImJpZ2ludCIsCiAgICAic3ltYm9sIiwKICAgICJmdW5jdGlvbiIsCiAgICAidW5kZWZpbmVkIiwKICAgICJudWxsIiwKICAgICJhcnJheSIsCiAgICAib2JqZWN0IiwKICAgICJ1bmtub3duIiwKICAgICJwcm9taXNlIiwKICAgICJ2b2lkIiwKICAgICJuZXZlciIsCiAgICAibWFwIiwKICAgICJzZXQiCiAgXSk7CiAgY29uc3QgZ2V0UGFyc2VkVHlwZSA9IChkYXRhKSA9PiB7CiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7CiAgICBzd2l0Y2ggKHQpIHsKICAgICAgY2FzZSAidW5kZWZpbmVkIjoKICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQ7CiAgICAgIGNhc2UgInN0cmluZyI6CiAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUuc3RyaW5nOwogICAgICBjYXNlICJudW1iZXIiOgogICAgICAgIHJldHVybiBpc05hTihkYXRhKSA/IFpvZFBhcnNlZFR5cGUubmFuIDogWm9kUGFyc2VkVHlwZS5udW1iZXI7CiAgICAgIGNhc2UgImJvb2xlYW4iOgogICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLmJvb2xlYW47CiAgICAgIGNhc2UgImZ1bmN0aW9uIjoKICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5mdW5jdGlvbjsKICAgICAgY2FzZSAiYmlnaW50IjoKICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5iaWdpbnQ7CiAgICAgIGNhc2UgInN5bWJvbCI6CiAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUuc3ltYm9sOwogICAgICBjYXNlICJvYmplY3QiOgogICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7CiAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5hcnJheTsKICAgICAgICB9CiAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLm51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChkYXRhLnRoZW4gJiYgdHlwZW9mIGRhdGEudGhlbiA9PT0gImZ1bmN0aW9uIiAmJiBkYXRhLmNhdGNoICYmIHR5cGVvZiBkYXRhLmNhdGNoID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5wcm9taXNlOwogICAgICAgIH0KICAgICAgICBpZiAodHlwZW9mIE1hcCAhPT0gInVuZGVmaW5lZCIgJiYgZGF0YSBpbnN0YW5jZW9mIE1hcCkgewogICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUubWFwOwogICAgICAgIH0KICAgICAgICBpZiAodHlwZW9mIFNldCAhPT0gInVuZGVmaW5lZCIgJiYgZGF0YSBpbnN0YW5jZW9mIFNldCkgewogICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUuc2V0OwogICAgICAgIH0KICAgICAgICBpZiAodHlwZW9mIERhdGUgIT09ICJ1bmRlZmluZWQiICYmIGRhdGEgaW5zdGFuY2VvZiBEYXRlKSB7CiAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5kYXRlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5vYmplY3Q7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUudW5rbm93bjsKICAgIH0KICB9OwogIGNvbnN0IFpvZElzc3VlQ29kZSA9IHV0aWwuYXJyYXlUb0VudW0oWwogICAgImludmFsaWRfdHlwZSIsCiAgICAiaW52YWxpZF9saXRlcmFsIiwKICAgICJjdXN0b20iLAogICAgImludmFsaWRfdW5pb24iLAogICAgImludmFsaWRfdW5pb25fZGlzY3JpbWluYXRvciIsCiAgICAiaW52YWxpZF9lbnVtX3ZhbHVlIiwKICAgICJ1bnJlY29nbml6ZWRfa2V5cyIsCiAgICAiaW52YWxpZF9hcmd1bWVudHMiLAogICAgImludmFsaWRfcmV0dXJuX3R5cGUiLAogICAgImludmFsaWRfZGF0ZSIsCiAgICAiaW52YWxpZF9zdHJpbmciLAogICAgInRvb19zbWFsbCIsCiAgICAidG9vX2JpZyIsCiAgICAiaW52YWxpZF9pbnRlcnNlY3Rpb25fdHlwZXMiLAogICAgIm5vdF9tdWx0aXBsZV9vZiIsCiAgICAibm90X2Zpbml0ZSIKICBdKTsKICBjb25zdCBxdW90ZWxlc3NKc29uID0gKG9iaikgPT4gewogICAgY29uc3QganNvbiA9IEpTT04uc3RyaW5naWZ5KG9iaiwgbnVsbCwgMik7CiAgICByZXR1cm4ganNvbi5yZXBsYWNlKC8iKFteIl0rKSI6L2csICIkMToiKTsKICB9OwogIGNsYXNzIFpvZEVycm9yIGV4dGVuZHMgRXJyb3IgewogICAgY29uc3RydWN0b3IoaXNzdWVzKSB7CiAgICAgIHN1cGVyKCk7CiAgICAgIHRoaXMuaXNzdWVzID0gW107CiAgICAgIHRoaXMuYWRkSXNzdWUgPSAoc3ViKSA9PiB7CiAgICAgICAgdGhpcy5pc3N1ZXMgPSBbLi4udGhpcy5pc3N1ZXMsIHN1Yl07CiAgICAgIH07CiAgICAgIHRoaXMuYWRkSXNzdWVzID0gKHN1YnMgPSBbXSkgPT4gewogICAgICAgIHRoaXMuaXNzdWVzID0gWy4uLnRoaXMuaXNzdWVzLCAuLi5zdWJzXTsKICAgICAgfTsKICAgICAgY29uc3QgYWN0dWFsUHJvdG8gPSBuZXcudGFyZ2V0LnByb3RvdHlwZTsKICAgICAgaWYgKE9iamVjdC5zZXRQcm90b3R5cGVPZikgewogICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBhY3R1YWxQcm90byk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhpcy5fX3Byb3RvX18gPSBhY3R1YWxQcm90bzsKICAgICAgfQogICAgICB0aGlzLm5hbWUgPSAiWm9kRXJyb3IiOwogICAgICB0aGlzLmlzc3VlcyA9IGlzc3VlczsKICAgIH0KICAgIGdldCBlcnJvcnMoKSB7CiAgICAgIHJldHVybiB0aGlzLmlzc3VlczsKICAgIH0KICAgIGZvcm1hdChfbWFwcGVyKSB7CiAgICAgIGNvbnN0IG1hcHBlciA9IF9tYXBwZXIgfHwgZnVuY3Rpb24oaXNzdWUpIHsKICAgICAgICByZXR1cm4gaXNzdWUubWVzc2FnZTsKICAgICAgfTsKICAgICAgY29uc3QgZmllbGRFcnJvcnMgPSB7IF9lcnJvcnM6IFtdIH07CiAgICAgIGNvbnN0IHByb2Nlc3NFcnJvciA9IChlcnJvcikgPT4gewogICAgICAgIGZvciAoY29uc3QgaXNzdWUgb2YgZXJyb3IuaXNzdWVzKSB7CiAgICAgICAgICBpZiAoaXNzdWUuY29kZSA9PT0gImludmFsaWRfdW5pb24iKSB7CiAgICAgICAgICAgIGlzc3VlLnVuaW9uRXJyb3JzLm1hcChwcm9jZXNzRXJyb3IpOwogICAgICAgICAgfSBlbHNlIGlmIChpc3N1ZS5jb2RlID09PSAiaW52YWxpZF9yZXR1cm5fdHlwZSIpIHsKICAgICAgICAgICAgcHJvY2Vzc0Vycm9yKGlzc3VlLnJldHVyblR5cGVFcnJvcik7CiAgICAgICAgICB9IGVsc2UgaWYgKGlzc3VlLmNvZGUgPT09ICJpbnZhbGlkX2FyZ3VtZW50cyIpIHsKICAgICAgICAgICAgcHJvY2Vzc0Vycm9yKGlzc3VlLmFyZ3VtZW50c0Vycm9yKTsKICAgICAgICAgIH0gZWxzZSBpZiAoaXNzdWUucGF0aC5sZW5ndGggPT09IDApIHsKICAgICAgICAgICAgZmllbGRFcnJvcnMuX2Vycm9ycy5wdXNoKG1hcHBlcihpc3N1ZSkpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGV0IGN1cnIgPSBmaWVsZEVycm9yczsKICAgICAgICAgICAgbGV0IGkyID0gMDsKICAgICAgICAgICAgd2hpbGUgKGkyIDwgaXNzdWUucGF0aC5sZW5ndGgpIHsKICAgICAgICAgICAgICBjb25zdCBlbCA9IGlzc3VlLnBhdGhbaTJdOwogICAgICAgICAgICAgIGNvbnN0IHRlcm1pbmFsID0gaTIgPT09IGlzc3VlLnBhdGgubGVuZ3RoIC0gMTsKICAgICAgICAgICAgICBpZiAoIXRlcm1pbmFsKSB7CiAgICAgICAgICAgICAgICBjdXJyW2VsXSA9IGN1cnJbZWxdIHx8IHsgX2Vycm9yczogW10gfTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY3VycltlbF0gPSBjdXJyW2VsXSB8fCB7IF9lcnJvcnM6IFtdIH07CiAgICAgICAgICAgICAgICBjdXJyW2VsXS5fZXJyb3JzLnB1c2gobWFwcGVyKGlzc3VlKSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGN1cnIgPSBjdXJyW2VsXTsKICAgICAgICAgICAgICBpMisrOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9OwogICAgICBwcm9jZXNzRXJyb3IodGhpcyk7CiAgICAgIHJldHVybiBmaWVsZEVycm9yczsKICAgIH0KICAgIHN0YXRpYyBhc3NlcnQodmFsdWUpIHsKICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBab2RFcnJvcikpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdCBhIFpvZEVycm9yOiAke3ZhbHVlfWApOwogICAgICB9CiAgICB9CiAgICB0b1N0cmluZygpIHsKICAgICAgcmV0dXJuIHRoaXMubWVzc2FnZTsKICAgIH0KICAgIGdldCBtZXNzYWdlKCkgewogICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcy5pc3N1ZXMsIHV0aWwuanNvblN0cmluZ2lmeVJlcGxhY2VyLCAyKTsKICAgIH0KICAgIGdldCBpc0VtcHR5KCkgewogICAgICByZXR1cm4gdGhpcy5pc3N1ZXMubGVuZ3RoID09PSAwOwogICAgfQogICAgZmxhdHRlbihtYXBwZXIgPSAoaXNzdWUpID0+IGlzc3VlLm1lc3NhZ2UpIHsKICAgICAgY29uc3QgZmllbGRFcnJvcnMgPSB7fTsKICAgICAgY29uc3QgZm9ybUVycm9ycyA9IFtdOwogICAgICBmb3IgKGNvbnN0IHN1YiBvZiB0aGlzLmlzc3VlcykgewogICAgICAgIGlmIChzdWIucGF0aC5sZW5ndGggPiAwKSB7CiAgICAgICAgICBmaWVsZEVycm9yc1tzdWIucGF0aFswXV0gPSBmaWVsZEVycm9yc1tzdWIucGF0aFswXV0gfHwgW107CiAgICAgICAgICBmaWVsZEVycm9yc1tzdWIucGF0aFswXV0ucHVzaChtYXBwZXIoc3ViKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZvcm1FcnJvcnMucHVzaChtYXBwZXIoc3ViKSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiB7IGZvcm1FcnJvcnMsIGZpZWxkRXJyb3JzIH07CiAgICB9CiAgICBnZXQgZm9ybUVycm9ycygpIHsKICAgICAgcmV0dXJuIHRoaXMuZmxhdHRlbigpOwogICAgfQogIH0KICBab2RFcnJvci5jcmVhdGUgPSAoaXNzdWVzKSA9PiB7CiAgICBjb25zdCBlcnJvciA9IG5ldyBab2RFcnJvcihpc3N1ZXMpOwogICAgcmV0dXJuIGVycm9yOwogIH07CiAgY29uc3QgZXJyb3JNYXAgPSAoaXNzdWUsIF9jdHgpID0+IHsKICAgIGxldCBtZXNzYWdlOwogICAgc3dpdGNoIChpc3N1ZS5jb2RlKSB7CiAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZToKICAgICAgICBpZiAoaXNzdWUucmVjZWl2ZWQgPT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7CiAgICAgICAgICBtZXNzYWdlID0gIlJlcXVpcmVkIjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZSA9IGBFeHBlY3RlZCAke2lzc3VlLmV4cGVjdGVkfSwgcmVjZWl2ZWQgJHtpc3N1ZS5yZWNlaXZlZH1gOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9saXRlcmFsOgogICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBsaXRlcmFsIHZhbHVlLCBleHBlY3RlZCAke0pTT04uc3RyaW5naWZ5KGlzc3VlLmV4cGVjdGVkLCB1dGlsLmpzb25TdHJpbmdpZnlSZXBsYWNlcil9YDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUudW5yZWNvZ25pemVkX2tleXM6CiAgICAgICAgbWVzc2FnZSA9IGBVbnJlY29nbml6ZWQga2V5KHMpIGluIG9iamVjdDogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgIiwgIil9YDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF91bmlvbjoKICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgaW5wdXRgOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFpvZElzc3VlQ29kZS5pbnZhbGlkX3VuaW9uX2Rpc2NyaW1pbmF0b3I6CiAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGRpc2NyaW1pbmF0b3IgdmFsdWUuIEV4cGVjdGVkICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLm9wdGlvbnMpfWA7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfZW51bV92YWx1ZToKICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgZW51bSB2YWx1ZS4gRXhwZWN0ZWQgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUub3B0aW9ucyl9LCByZWNlaXZlZCAnJHtpc3N1ZS5yZWNlaXZlZH0nYDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9hcmd1bWVudHM6CiAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGZ1bmN0aW9uIGFyZ3VtZW50c2A7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfcmV0dXJuX3R5cGU6CiAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGZ1bmN0aW9uIHJldHVybiB0eXBlYDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9kYXRlOgogICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBkYXRlYDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmc6CiAgICAgICAgaWYgKHR5cGVvZiBpc3N1ZS52YWxpZGF0aW9uID09PSAib2JqZWN0IikgewogICAgICAgICAgaWYgKCJpbmNsdWRlcyIgaW4gaXNzdWUudmFsaWRhdGlvbikgewogICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgaW5wdXQ6IG11c3QgaW5jbHVkZSAiJHtpc3N1ZS52YWxpZGF0aW9uLmluY2x1ZGVzfSJgOwogICAgICAgICAgICBpZiAodHlwZW9mIGlzc3VlLnZhbGlkYXRpb24ucG9zaXRpb24gPT09ICJudW1iZXIiKSB7CiAgICAgICAgICAgICAgbWVzc2FnZSA9IGAke21lc3NhZ2V9IGF0IG9uZSBvciBtb3JlIHBvc2l0aW9ucyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJHtpc3N1ZS52YWxpZGF0aW9uLnBvc2l0aW9ufWA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSBpZiAoInN0YXJ0c1dpdGgiIGluIGlzc3VlLnZhbGlkYXRpb24pIHsKICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGlucHV0OiBtdXN0IHN0YXJ0IHdpdGggIiR7aXNzdWUudmFsaWRhdGlvbi5zdGFydHNXaXRofSJgOwogICAgICAgICAgfSBlbHNlIGlmICgiZW5kc1dpdGgiIGluIGlzc3VlLnZhbGlkYXRpb24pIHsKICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGlucHV0OiBtdXN0IGVuZCB3aXRoICIke2lzc3VlLnZhbGlkYXRpb24uZW5kc1dpdGh9ImA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGlzc3VlLnZhbGlkYXRpb24pOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoaXNzdWUudmFsaWRhdGlvbiAhPT0gInJlZ2V4IikgewogICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkICR7aXNzdWUudmFsaWRhdGlvbn1gOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlID0gIkludmFsaWQiOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUudG9vX3NtYWxsOgogICAgICAgIGlmIChpc3N1ZS50eXBlID09PSAiYXJyYXkiKQogICAgICAgICAgbWVzc2FnZSA9IGBBcnJheSBtdXN0IGNvbnRhaW4gJHtpc3N1ZS5leGFjdCA/ICJleGFjdGx5IiA6IGlzc3VlLmluY2x1c2l2ZSA/IGBhdCBsZWFzdGAgOiBgbW9yZSB0aGFuYH0gJHtpc3N1ZS5taW5pbXVtfSBlbGVtZW50KHMpYDsKICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSAic3RyaW5nIikKICAgICAgICAgIG1lc3NhZ2UgPSBgU3RyaW5nIG11c3QgY29udGFpbiAke2lzc3VlLmV4YWN0ID8gImV4YWN0bHkiIDogaXNzdWUuaW5jbHVzaXZlID8gYGF0IGxlYXN0YCA6IGBvdmVyYH0gJHtpc3N1ZS5taW5pbXVtfSBjaGFyYWN0ZXIocylgOwogICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09ICJudW1iZXIiKQogICAgICAgICAgbWVzc2FnZSA9IGBOdW1iZXIgbXVzdCBiZSAke2lzc3VlLmV4YWN0ID8gYGV4YWN0bHkgZXF1YWwgdG8gYCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYCA6IGBncmVhdGVyIHRoYW4gYH0ke2lzc3VlLm1pbmltdW19YDsKICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSAiZGF0ZSIpCiAgICAgICAgICBtZXNzYWdlID0gYERhdGUgbXVzdCBiZSAke2lzc3VlLmV4YWN0ID8gYGV4YWN0bHkgZXF1YWwgdG8gYCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYCA6IGBncmVhdGVyIHRoYW4gYH0ke25ldyBEYXRlKE51bWJlcihpc3N1ZS5taW5pbXVtKSl9YDsKICAgICAgICBlbHNlCiAgICAgICAgICBtZXNzYWdlID0gIkludmFsaWQgaW5wdXQiOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFpvZElzc3VlQ29kZS50b29fYmlnOgogICAgICAgIGlmIChpc3N1ZS50eXBlID09PSAiYXJyYXkiKQogICAgICAgICAgbWVzc2FnZSA9IGBBcnJheSBtdXN0IGNvbnRhaW4gJHtpc3N1ZS5leGFjdCA/IGBleGFjdGx5YCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBhdCBtb3N0YCA6IGBsZXNzIHRoYW5gfSAke2lzc3VlLm1heGltdW19IGVsZW1lbnQocylgOwogICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09ICJzdHJpbmciKQogICAgICAgICAgbWVzc2FnZSA9IGBTdHJpbmcgbXVzdCBjb250YWluICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseWAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgYXQgbW9zdGAgOiBgdW5kZXJgfSAke2lzc3VlLm1heGltdW19IGNoYXJhY3RlcihzKWA7CiAgICAgICAgZWxzZSBpZiAoaXNzdWUudHlwZSA9PT0gIm51bWJlciIpCiAgICAgICAgICBtZXNzYWdlID0gYE51bWJlciBtdXN0IGJlICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseWAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgbGVzcyB0aGFuIG9yIGVxdWFsIHRvYCA6IGBsZXNzIHRoYW5gfSAke2lzc3VlLm1heGltdW19YDsKICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSAiYmlnaW50IikKICAgICAgICAgIG1lc3NhZ2UgPSBgQmlnSW50IG11c3QgYmUgJHtpc3N1ZS5leGFjdCA/IGBleGFjdGx5YCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBsZXNzIHRoYW4gb3IgZXF1YWwgdG9gIDogYGxlc3MgdGhhbmB9ICR7aXNzdWUubWF4aW11bX1gOwogICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09ICJkYXRlIikKICAgICAgICAgIG1lc3NhZ2UgPSBgRGF0ZSBtdXN0IGJlICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseWAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgc21hbGxlciB0aGFuIG9yIGVxdWFsIHRvYCA6IGBzbWFsbGVyIHRoYW5gfSAke25ldyBEYXRlKE51bWJlcihpc3N1ZS5tYXhpbXVtKSl9YDsKICAgICAgICBlbHNlCiAgICAgICAgICBtZXNzYWdlID0gIkludmFsaWQgaW5wdXQiOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFpvZElzc3VlQ29kZS5jdXN0b206CiAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGlucHV0YDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9pbnRlcnNlY3Rpb25fdHlwZXM6CiAgICAgICAgbWVzc2FnZSA9IGBJbnRlcnNlY3Rpb24gcmVzdWx0cyBjb3VsZCBub3QgYmUgbWVyZ2VkYDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUubm90X211bHRpcGxlX29mOgogICAgICAgIG1lc3NhZ2UgPSBgTnVtYmVyIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAke2lzc3VlLm11bHRpcGxlT2Z9YDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUubm90X2Zpbml0ZToKICAgICAgICBtZXNzYWdlID0gIk51bWJlciBtdXN0IGJlIGZpbml0ZSI7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgbWVzc2FnZSA9IF9jdHguZGVmYXVsdEVycm9yOwogICAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoaXNzdWUpOwogICAgfQogICAgcmV0dXJuIHsgbWVzc2FnZSB9OwogIH07CiAgbGV0IG92ZXJyaWRlRXJyb3JNYXAgPSBlcnJvck1hcDsKICBmdW5jdGlvbiBzZXRFcnJvck1hcChtYXApIHsKICAgIG92ZXJyaWRlRXJyb3JNYXAgPSBtYXA7CiAgfQogIGZ1bmN0aW9uIGdldEVycm9yTWFwKCkgewogICAgcmV0dXJuIG92ZXJyaWRlRXJyb3JNYXA7CiAgfQogIGNvbnN0IG1ha2VJc3N1ZSA9IChwYXJhbXMpID0+IHsKICAgIGNvbnN0IHsgZGF0YSwgcGF0aCwgZXJyb3JNYXBzLCBpc3N1ZURhdGEgfSA9IHBhcmFtczsKICAgIGNvbnN0IGZ1bGxQYXRoID0gWy4uLnBhdGgsIC4uLmlzc3VlRGF0YS5wYXRoIHx8IFtdXTsKICAgIGNvbnN0IGZ1bGxJc3N1ZSA9IHsKICAgICAgLi4uaXNzdWVEYXRhLAogICAgICBwYXRoOiBmdWxsUGF0aAogICAgfTsKICAgIGlmIChpc3N1ZURhdGEubWVzc2FnZSAhPT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAgLi4uaXNzdWVEYXRhLAogICAgICAgIHBhdGg6IGZ1bGxQYXRoLAogICAgICAgIG1lc3NhZ2U6IGlzc3VlRGF0YS5tZXNzYWdlCiAgICAgIH07CiAgICB9CiAgICBsZXQgZXJyb3JNZXNzYWdlID0gIiI7CiAgICBjb25zdCBtYXBzID0gZXJyb3JNYXBzLmZpbHRlcigobTIpID0+ICEhbTIpLnNsaWNlKCkucmV2ZXJzZSgpOwogICAgZm9yIChjb25zdCBtYXAgb2YgbWFwcykgewogICAgICBlcnJvck1lc3NhZ2UgPSBtYXAoZnVsbElzc3VlLCB7IGRhdGEsIGRlZmF1bHRFcnJvcjogZXJyb3JNZXNzYWdlIH0pLm1lc3NhZ2U7CiAgICB9CiAgICByZXR1cm4gewogICAgICAuLi5pc3N1ZURhdGEsCiAgICAgIHBhdGg6IGZ1bGxQYXRoLAogICAgICBtZXNzYWdlOiBlcnJvck1lc3NhZ2UKICAgIH07CiAgfTsKICBjb25zdCBFTVBUWV9QQVRIID0gW107CiAgZnVuY3Rpb24gYWRkSXNzdWVUb0NvbnRleHQoY3R4LCBpc3N1ZURhdGEpIHsKICAgIGNvbnN0IG92ZXJyaWRlTWFwID0gZ2V0RXJyb3JNYXAoKTsKICAgIGNvbnN0IGlzc3VlID0gbWFrZUlzc3VlKHsKICAgICAgaXNzdWVEYXRhLAogICAgICBkYXRhOiBjdHguZGF0YSwKICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgIGVycm9yTWFwczogWwogICAgICAgIGN0eC5jb21tb24uY29udGV4dHVhbEVycm9yTWFwLAogICAgICAgIGN0eC5zY2hlbWFFcnJvck1hcCwKICAgICAgICBvdmVycmlkZU1hcCwKICAgICAgICBvdmVycmlkZU1hcCA9PT0gZXJyb3JNYXAgPyB2b2lkIDAgOiBlcnJvck1hcAogICAgICAgIC8vIHRoZW4gZ2xvYmFsIGRlZmF1bHQgbWFwCiAgICAgIF0uZmlsdGVyKCh4KSA9PiAhIXgpCiAgICB9KTsKICAgIGN0eC5jb21tb24uaXNzdWVzLnB1c2goaXNzdWUpOwogIH0KICBjbGFzcyBQYXJzZVN0YXR1cyB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgdGhpcy52YWx1ZSA9ICJ2YWxpZCI7CiAgICB9CiAgICBkaXJ0eSgpIHsKICAgICAgaWYgKHRoaXMudmFsdWUgPT09ICJ2YWxpZCIpCiAgICAgICAgdGhpcy52YWx1ZSA9ICJkaXJ0eSI7CiAgICB9CiAgICBhYm9ydCgpIHsKICAgICAgaWYgKHRoaXMudmFsdWUgIT09ICJhYm9ydGVkIikKICAgICAgICB0aGlzLnZhbHVlID0gImFib3J0ZWQiOwogICAgfQogICAgc3RhdGljIG1lcmdlQXJyYXkoc3RhdHVzLCByZXN1bHRzKSB7CiAgICAgIGNvbnN0IGFycmF5VmFsdWUgPSBbXTsKICAgICAgZm9yIChjb25zdCBzMiBvZiByZXN1bHRzKSB7CiAgICAgICAgaWYgKHMyLnN0YXR1cyA9PT0gImFib3J0ZWQiKQogICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgaWYgKHMyLnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgIGFycmF5VmFsdWUucHVzaChzMi52YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBhcnJheVZhbHVlIH07CiAgICB9CiAgICBzdGF0aWMgYXN5bmMgbWVyZ2VPYmplY3RBc3luYyhzdGF0dXMsIHBhaXJzKSB7CiAgICAgIGNvbnN0IHN5bmNQYWlycyA9IFtdOwogICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpIHsKICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBwYWlyLmtleTsKICAgICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IHBhaXIudmFsdWU7CiAgICAgICAgc3luY1BhaXJzLnB1c2goewogICAgICAgICAga2V5LAogICAgICAgICAgdmFsdWUKICAgICAgICB9KTsKICAgICAgfQogICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VPYmplY3RTeW5jKHN0YXR1cywgc3luY1BhaXJzKTsKICAgIH0KICAgIHN0YXRpYyBtZXJnZU9iamVjdFN5bmMoc3RhdHVzLCBwYWlycykgewogICAgICBjb25zdCBmaW5hbE9iamVjdCA9IHt9OwogICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpIHsKICAgICAgICBjb25zdCB7IGtleSwgdmFsdWUgfSA9IHBhaXI7CiAgICAgICAgaWYgKGtleS5zdGF0dXMgPT09ICJhYm9ydGVkIikKICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgIGlmICh2YWx1ZS5zdGF0dXMgPT09ICJhYm9ydGVkIikKICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgIGlmIChrZXkuc3RhdHVzID09PSAiZGlydHkiKQogICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgaWYgKHZhbHVlLnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgIGlmIChrZXkudmFsdWUgIT09ICJfX3Byb3RvX18iICYmICh0eXBlb2YgdmFsdWUudmFsdWUgIT09ICJ1bmRlZmluZWQiIHx8IHBhaXIuYWx3YXlzU2V0KSkgewogICAgICAgICAgZmluYWxPYmplY3Rba2V5LnZhbHVlXSA9IHZhbHVlLnZhbHVlOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IGZpbmFsT2JqZWN0IH07CiAgICB9CiAgfQogIGNvbnN0IElOVkFMSUQgPSBPYmplY3QuZnJlZXplKHsKICAgIHN0YXR1czogImFib3J0ZWQiCiAgfSk7CiAgY29uc3QgRElSVFkgPSAodmFsdWUpID0+ICh7IHN0YXR1czogImRpcnR5IiwgdmFsdWUgfSk7CiAgY29uc3QgT0sgPSAodmFsdWUpID0+ICh7IHN0YXR1czogInZhbGlkIiwgdmFsdWUgfSk7CiAgY29uc3QgaXNBYm9ydGVkID0gKHgpID0+IHguc3RhdHVzID09PSAiYWJvcnRlZCI7CiAgY29uc3QgaXNEaXJ0eSA9ICh4KSA9PiB4LnN0YXR1cyA9PT0gImRpcnR5IjsKICBjb25zdCBpc1ZhbGlkID0gKHgpID0+IHguc3RhdHVzID09PSAidmFsaWQiOwogIGNvbnN0IGlzQXN5bmMgPSAoeCkgPT4gdHlwZW9mIFByb21pc2UgIT09ICJ1bmRlZmluZWQiICYmIHggaW5zdGFuY2VvZiBQcm9taXNlOwogIGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRHZXQocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmMikgewogICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gImZ1bmN0aW9uIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZjIgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0Iik7CiAgICByZXR1cm4gc3RhdGUuZ2V0KHJlY2VpdmVyKTsKICB9CiAgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmMikgewogICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gImZ1bmN0aW9uIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZjIgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXQiKTsKICAgIHJldHVybiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSwgdmFsdWU7CiAgfQogIHR5cGVvZiBTdXBwcmVzc2VkRXJyb3IgPT09ICJmdW5jdGlvbiIgPyBTdXBwcmVzc2VkRXJyb3IgOiBmdW5jdGlvbihlcnJvciwgc3VwcHJlc3NlZCwgbWVzc2FnZSkgewogICAgdmFyIGUyID0gbmV3IEVycm9yKG1lc3NhZ2UpOwogICAgcmV0dXJuIGUyLm5hbWUgPSAiU3VwcHJlc3NlZEVycm9yIiwgZTIuZXJyb3IgPSBlcnJvciwgZTIuc3VwcHJlc3NlZCA9IHN1cHByZXNzZWQsIGUyOwogIH07CiAgdmFyIGVycm9yVXRpbDsKICAoZnVuY3Rpb24oZXJyb3JVdGlsMikgewogICAgZXJyb3JVdGlsMi5lcnJUb09iaiA9IChtZXNzYWdlKSA9PiB0eXBlb2YgbWVzc2FnZSA9PT0gInN0cmluZyIgPyB7IG1lc3NhZ2UgfSA6IG1lc3NhZ2UgfHwge307CiAgICBlcnJvclV0aWwyLnRvU3RyaW5nID0gKG1lc3NhZ2UpID0+IHR5cGVvZiBtZXNzYWdlID09PSAic3RyaW5nIiA/IG1lc3NhZ2UgOiBtZXNzYWdlID09PSBudWxsIHx8IG1lc3NhZ2UgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG1lc3NhZ2UubWVzc2FnZTsKICB9KShlcnJvclV0aWwgfHwgKGVycm9yVXRpbCA9IHt9KSk7CiAgdmFyIF9ab2RFbnVtX2NhY2hlLCBfWm9kTmF0aXZlRW51bV9jYWNoZTsKICBjbGFzcyBQYXJzZUlucHV0TGF6eVBhdGggewogICAgY29uc3RydWN0b3IocGFyZW50LCB2YWx1ZSwgcGF0aCwga2V5KSB7CiAgICAgIHRoaXMuX2NhY2hlZFBhdGggPSBbXTsKICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CiAgICAgIHRoaXMuZGF0YSA9IHZhbHVlOwogICAgICB0aGlzLl9wYXRoID0gcGF0aDsKICAgICAgdGhpcy5fa2V5ID0ga2V5OwogICAgfQogICAgZ2V0IHBhdGgoKSB7CiAgICAgIGlmICghdGhpcy5fY2FjaGVkUGF0aC5sZW5ndGgpIHsKICAgICAgICBpZiAodGhpcy5fa2V5IGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgICAgIHRoaXMuX2NhY2hlZFBhdGgucHVzaCguLi50aGlzLl9wYXRoLCAuLi50aGlzLl9rZXkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aGlzLl9jYWNoZWRQYXRoLnB1c2goLi4udGhpcy5fcGF0aCwgdGhpcy5fa2V5KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZFBhdGg7CiAgICB9CiAgfQogIGNvbnN0IGhhbmRsZVJlc3VsdCA9IChjdHgsIHJlc3VsdCkgPT4gewogICAgaWYgKGlzVmFsaWQocmVzdWx0KSkgewogICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCBkYXRhOiByZXN1bHQudmFsdWUgfTsKICAgIH0gZWxzZSB7CiAgICAgIGlmICghY3R4LmNvbW1vbi5pc3N1ZXMubGVuZ3RoKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJWYWxpZGF0aW9uIGZhaWxlZCBidXQgbm8gaXNzdWVzIGRldGVjdGVkLiIpOwogICAgICB9CiAgICAgIHJldHVybiB7CiAgICAgICAgc3VjY2VzczogZmFsc2UsCiAgICAgICAgZ2V0IGVycm9yKCkgewogICAgICAgICAgaWYgKHRoaXMuX2Vycm9yKQogICAgICAgICAgICByZXR1cm4gdGhpcy5fZXJyb3I7CiAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBab2RFcnJvcihjdHguY29tbW9uLmlzc3Vlcyk7CiAgICAgICAgICB0aGlzLl9lcnJvciA9IGVycm9yOwogICAgICAgICAgcmV0dXJuIHRoaXMuX2Vycm9yOwogICAgICAgIH0KICAgICAgfTsKICAgIH0KICB9OwogIGZ1bmN0aW9uIHByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSB7CiAgICBpZiAoIXBhcmFtcykKICAgICAgcmV0dXJuIHt9OwogICAgY29uc3QgeyBlcnJvck1hcDogZXJyb3JNYXAyLCBpbnZhbGlkX3R5cGVfZXJyb3IsIHJlcXVpcmVkX2Vycm9yLCBkZXNjcmlwdGlvbiB9ID0gcGFyYW1zOwogICAgaWYgKGVycm9yTWFwMiAmJiAoaW52YWxpZF90eXBlX2Vycm9yIHx8IHJlcXVpcmVkX2Vycm9yKSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbid0IHVzZSAiaW52YWxpZF90eXBlX2Vycm9yIiBvciAicmVxdWlyZWRfZXJyb3IiIGluIGNvbmp1bmN0aW9uIHdpdGggY3VzdG9tIGVycm9yIG1hcC5gKTsKICAgIH0KICAgIGlmIChlcnJvck1hcDIpCiAgICAgIHJldHVybiB7IGVycm9yTWFwOiBlcnJvck1hcDIsIGRlc2NyaXB0aW9uIH07CiAgICBjb25zdCBjdXN0b21NYXAgPSAoaXNzLCBjdHgpID0+IHsKICAgICAgdmFyIF9hLCBfYjsKICAgICAgY29uc3QgeyBtZXNzYWdlIH0gPSBwYXJhbXM7CiAgICAgIGlmIChpc3MuY29kZSA9PT0gImludmFsaWRfZW51bV92YWx1ZSIpIHsKICAgICAgICByZXR1cm4geyBtZXNzYWdlOiBtZXNzYWdlICE9PSBudWxsICYmIG1lc3NhZ2UgIT09IHZvaWQgMCA/IG1lc3NhZ2UgOiBjdHguZGVmYXVsdEVycm9yIH07CiAgICAgIH0KICAgICAgaWYgKHR5cGVvZiBjdHguZGF0YSA9PT0gInVuZGVmaW5lZCIpIHsKICAgICAgICByZXR1cm4geyBtZXNzYWdlOiAoX2EgPSBtZXNzYWdlICE9PSBudWxsICYmIG1lc3NhZ2UgIT09IHZvaWQgMCA/IG1lc3NhZ2UgOiByZXF1aXJlZF9lcnJvcikgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogY3R4LmRlZmF1bHRFcnJvciB9OwogICAgICB9CiAgICAgIGlmIChpc3MuY29kZSAhPT0gImludmFsaWRfdHlwZSIpCiAgICAgICAgcmV0dXJuIHsgbWVzc2FnZTogY3R4LmRlZmF1bHRFcnJvciB9OwogICAgICByZXR1cm4geyBtZXNzYWdlOiAoX2IgPSBtZXNzYWdlICE9PSBudWxsICYmIG1lc3NhZ2UgIT09IHZvaWQgMCA/IG1lc3NhZ2UgOiBpbnZhbGlkX3R5cGVfZXJyb3IpICE9PSBudWxsICYmIF9iICE9PSB2b2lkIDAgPyBfYiA6IGN0eC5kZWZhdWx0RXJyb3IgfTsKICAgIH07CiAgICByZXR1cm4geyBlcnJvck1hcDogY3VzdG9tTWFwLCBkZXNjcmlwdGlvbiB9OwogIH0KICBjbGFzcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKGRlZikgewogICAgICB0aGlzLnNwYSA9IHRoaXMuc2FmZVBhcnNlQXN5bmM7CiAgICAgIHRoaXMuX2RlZiA9IGRlZjsKICAgICAgdGhpcy5wYXJzZSA9IHRoaXMucGFyc2UuYmluZCh0aGlzKTsKICAgICAgdGhpcy5zYWZlUGFyc2UgPSB0aGlzLnNhZmVQYXJzZS5iaW5kKHRoaXMpOwogICAgICB0aGlzLnBhcnNlQXN5bmMgPSB0aGlzLnBhcnNlQXN5bmMuYmluZCh0aGlzKTsKICAgICAgdGhpcy5zYWZlUGFyc2VBc3luYyA9IHRoaXMuc2FmZVBhcnNlQXN5bmMuYmluZCh0aGlzKTsKICAgICAgdGhpcy5zcGEgPSB0aGlzLnNwYS5iaW5kKHRoaXMpOwogICAgICB0aGlzLnJlZmluZSA9IHRoaXMucmVmaW5lLmJpbmQodGhpcyk7CiAgICAgIHRoaXMucmVmaW5lbWVudCA9IHRoaXMucmVmaW5lbWVudC5iaW5kKHRoaXMpOwogICAgICB0aGlzLnN1cGVyUmVmaW5lID0gdGhpcy5zdXBlclJlZmluZS5iaW5kKHRoaXMpOwogICAgICB0aGlzLm9wdGlvbmFsID0gdGhpcy5vcHRpb25hbC5iaW5kKHRoaXMpOwogICAgICB0aGlzLm51bGxhYmxlID0gdGhpcy5udWxsYWJsZS5iaW5kKHRoaXMpOwogICAgICB0aGlzLm51bGxpc2ggPSB0aGlzLm51bGxpc2guYmluZCh0aGlzKTsKICAgICAgdGhpcy5hcnJheSA9IHRoaXMuYXJyYXkuYmluZCh0aGlzKTsKICAgICAgdGhpcy5wcm9taXNlID0gdGhpcy5wcm9taXNlLmJpbmQodGhpcyk7CiAgICAgIHRoaXMub3IgPSB0aGlzLm9yLmJpbmQodGhpcyk7CiAgICAgIHRoaXMuYW5kID0gdGhpcy5hbmQuYmluZCh0aGlzKTsKICAgICAgdGhpcy50cmFuc2Zvcm0gPSB0aGlzLnRyYW5zZm9ybS5iaW5kKHRoaXMpOwogICAgICB0aGlzLmJyYW5kID0gdGhpcy5icmFuZC5iaW5kKHRoaXMpOwogICAgICB0aGlzLmRlZmF1bHQgPSB0aGlzLmRlZmF1bHQuYmluZCh0aGlzKTsKICAgICAgdGhpcy5jYXRjaCA9IHRoaXMuY2F0Y2guYmluZCh0aGlzKTsKICAgICAgdGhpcy5kZXNjcmliZSA9IHRoaXMuZGVzY3JpYmUuYmluZCh0aGlzKTsKICAgICAgdGhpcy5waXBlID0gdGhpcy5waXBlLmJpbmQodGhpcyk7CiAgICAgIHRoaXMucmVhZG9ubHkgPSB0aGlzLnJlYWRvbmx5LmJpbmQodGhpcyk7CiAgICAgIHRoaXMuaXNOdWxsYWJsZSA9IHRoaXMuaXNOdWxsYWJsZS5iaW5kKHRoaXMpOwogICAgICB0aGlzLmlzT3B0aW9uYWwgPSB0aGlzLmlzT3B0aW9uYWwuYmluZCh0aGlzKTsKICAgIH0KICAgIGdldCBkZXNjcmlwdGlvbigpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5kZXNjcmlwdGlvbjsKICAgIH0KICAgIF9nZXRUeXBlKGlucHV0KSB7CiAgICAgIHJldHVybiBnZXRQYXJzZWRUeXBlKGlucHV0LmRhdGEpOwogICAgfQogICAgX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpIHsKICAgICAgcmV0dXJuIGN0eCB8fCB7CiAgICAgICAgY29tbW9uOiBpbnB1dC5wYXJlbnQuY29tbW9uLAogICAgICAgIGRhdGE6IGlucHV0LmRhdGEsCiAgICAgICAgcGFyc2VkVHlwZTogZ2V0UGFyc2VkVHlwZShpbnB1dC5kYXRhKSwKICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLAogICAgICAgIHBhdGg6IGlucHV0LnBhdGgsCiAgICAgICAgcGFyZW50OiBpbnB1dC5wYXJlbnQKICAgICAgfTsKICAgIH0KICAgIF9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpIHsKICAgICAgcmV0dXJuIHsKICAgICAgICBzdGF0dXM6IG5ldyBQYXJzZVN0YXR1cygpLAogICAgICAgIGN0eDogewogICAgICAgICAgY29tbW9uOiBpbnB1dC5wYXJlbnQuY29tbW9uLAogICAgICAgICAgZGF0YTogaW5wdXQuZGF0YSwKICAgICAgICAgIHBhcnNlZFR5cGU6IGdldFBhcnNlZFR5cGUoaW5wdXQuZGF0YSksCiAgICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLAogICAgICAgICAgcGF0aDogaW5wdXQucGF0aCwKICAgICAgICAgIHBhcmVudDogaW5wdXQucGFyZW50CiAgICAgICAgfQogICAgICB9OwogICAgfQogICAgX3BhcnNlU3luYyhpbnB1dCkgewogICAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9wYXJzZShpbnB1dCk7CiAgICAgIGlmIChpc0FzeW5jKHJlc3VsdCkpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlN5bmNocm9ub3VzIHBhcnNlIGVuY291bnRlcmVkIHByb21pc2UuIik7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICAgIF9wYXJzZUFzeW5jKGlucHV0KSB7CiAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX3BhcnNlKGlucHV0KTsKICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXN1bHQpOwogICAgfQogICAgcGFyc2UoZGF0YSwgcGFyYW1zKSB7CiAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuc2FmZVBhcnNlKGRhdGEsIHBhcmFtcyk7CiAgICAgIGlmIChyZXN1bHQuc3VjY2VzcykKICAgICAgICByZXR1cm4gcmVzdWx0LmRhdGE7CiAgICAgIHRocm93IHJlc3VsdC5lcnJvcjsKICAgIH0KICAgIHNhZmVQYXJzZShkYXRhLCBwYXJhbXMpIHsKICAgICAgdmFyIF9hOwogICAgICBjb25zdCBjdHggPSB7CiAgICAgICAgY29tbW9uOiB7CiAgICAgICAgICBpc3N1ZXM6IFtdLAogICAgICAgICAgYXN5bmM6IChfYSA9IHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5hc3luYykgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogZmFsc2UsCiAgICAgICAgICBjb250ZXh0dWFsRXJyb3JNYXA6IHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5lcnJvck1hcAogICAgICAgIH0sCiAgICAgICAgcGF0aDogKHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5wYXRoKSB8fCBbXSwKICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLAogICAgICAgIHBhcmVudDogbnVsbCwKICAgICAgICBkYXRhLAogICAgICAgIHBhcnNlZFR5cGU6IGdldFBhcnNlZFR5cGUoZGF0YSkKICAgICAgfTsKICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fcGFyc2VTeW5jKHsgZGF0YSwgcGF0aDogY3R4LnBhdGgsIHBhcmVudDogY3R4IH0pOwogICAgICByZXR1cm4gaGFuZGxlUmVzdWx0KGN0eCwgcmVzdWx0KTsKICAgIH0KICAgIGFzeW5jIHBhcnNlQXN5bmMoZGF0YSwgcGFyYW1zKSB7CiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuc2FmZVBhcnNlQXN5bmMoZGF0YSwgcGFyYW1zKTsKICAgICAgaWYgKHJlc3VsdC5zdWNjZXNzKQogICAgICAgIHJldHVybiByZXN1bHQuZGF0YTsKICAgICAgdGhyb3cgcmVzdWx0LmVycm9yOwogICAgfQogICAgYXN5bmMgc2FmZVBhcnNlQXN5bmMoZGF0YSwgcGFyYW1zKSB7CiAgICAgIGNvbnN0IGN0eCA9IHsKICAgICAgICBjb21tb246IHsKICAgICAgICAgIGlzc3VlczogW10sCiAgICAgICAgICBjb250ZXh0dWFsRXJyb3JNYXA6IHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5lcnJvck1hcCwKICAgICAgICAgIGFzeW5jOiB0cnVlCiAgICAgICAgfSwKICAgICAgICBwYXRoOiAocGFyYW1zID09PSBudWxsIHx8IHBhcmFtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFyYW1zLnBhdGgpIHx8IFtdLAogICAgICAgIHNjaGVtYUVycm9yTWFwOiB0aGlzLl9kZWYuZXJyb3JNYXAsCiAgICAgICAgcGFyZW50OiBudWxsLAogICAgICAgIGRhdGEsCiAgICAgICAgcGFyc2VkVHlwZTogZ2V0UGFyc2VkVHlwZShkYXRhKQogICAgICB9OwogICAgICBjb25zdCBtYXliZUFzeW5jUmVzdWx0ID0gdGhpcy5fcGFyc2UoeyBkYXRhLCBwYXRoOiBjdHgucGF0aCwgcGFyZW50OiBjdHggfSk7CiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IChpc0FzeW5jKG1heWJlQXN5bmNSZXN1bHQpID8gbWF5YmVBc3luY1Jlc3VsdCA6IFByb21pc2UucmVzb2x2ZShtYXliZUFzeW5jUmVzdWx0KSk7CiAgICAgIHJldHVybiBoYW5kbGVSZXN1bHQoY3R4LCByZXN1bHQpOwogICAgfQogICAgcmVmaW5lKGNoZWNrLCBtZXNzYWdlKSB7CiAgICAgIGNvbnN0IGdldElzc3VlUHJvcGVydGllcyA9ICh2YWwpID0+IHsKICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICJzdHJpbmciIHx8IHR5cGVvZiBtZXNzYWdlID09PSAidW5kZWZpbmVkIikgewogICAgICAgICAgcmV0dXJuIHsgbWVzc2FnZSB9OwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlKHZhbCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlOwogICAgICAgIH0KICAgICAgfTsKICAgICAgcmV0dXJuIHRoaXMuX3JlZmluZW1lbnQoKHZhbCwgY3R4KSA9PiB7CiAgICAgICAgY29uc3QgcmVzdWx0ID0gY2hlY2sodmFsKTsKICAgICAgICBjb25zdCBzZXRFcnJvciA9ICgpID0+IGN0eC5hZGRJc3N1ZSh7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuY3VzdG9tLAogICAgICAgICAgLi4uZ2V0SXNzdWVQcm9wZXJ0aWVzKHZhbCkKICAgICAgICB9KTsKICAgICAgICBpZiAodHlwZW9mIFByb21pc2UgIT09ICJ1bmRlZmluZWQiICYmIHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHsKICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbigoZGF0YSkgPT4gewogICAgICAgICAgICBpZiAoIWRhdGEpIHsKICAgICAgICAgICAgICBzZXRFcnJvcigpOwogICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIGlmICghcmVzdWx0KSB7CiAgICAgICAgICBzZXRFcnJvcigpOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgIH0pOwogICAgfQogICAgcmVmaW5lbWVudChjaGVjaywgcmVmaW5lbWVudERhdGEpIHsKICAgICAgcmV0dXJuIHRoaXMuX3JlZmluZW1lbnQoKHZhbCwgY3R4KSA9PiB7CiAgICAgICAgaWYgKCFjaGVjayh2YWwpKSB7CiAgICAgICAgICBjdHguYWRkSXNzdWUodHlwZW9mIHJlZmluZW1lbnREYXRhID09PSAiZnVuY3Rpb24iID8gcmVmaW5lbWVudERhdGEodmFsLCBjdHgpIDogcmVmaW5lbWVudERhdGEpOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgIH0pOwogICAgfQogICAgX3JlZmluZW1lbnQocmVmaW5lbWVudCkgewogICAgICByZXR1cm4gbmV3IFpvZEVmZmVjdHMoewogICAgICAgIHNjaGVtYTogdGhpcywKICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsCiAgICAgICAgZWZmZWN0OiB7IHR5cGU6ICJyZWZpbmVtZW50IiwgcmVmaW5lbWVudCB9CiAgICAgIH0pOwogICAgfQogICAgc3VwZXJSZWZpbmUocmVmaW5lbWVudCkgewogICAgICByZXR1cm4gdGhpcy5fcmVmaW5lbWVudChyZWZpbmVtZW50KTsKICAgIH0KICAgIG9wdGlvbmFsKCkgewogICAgICByZXR1cm4gWm9kT3B0aW9uYWwuY3JlYXRlKHRoaXMsIHRoaXMuX2RlZik7CiAgICB9CiAgICBudWxsYWJsZSgpIHsKICAgICAgcmV0dXJuIFpvZE51bGxhYmxlLmNyZWF0ZSh0aGlzLCB0aGlzLl9kZWYpOwogICAgfQogICAgbnVsbGlzaCgpIHsKICAgICAgcmV0dXJuIHRoaXMubnVsbGFibGUoKS5vcHRpb25hbCgpOwogICAgfQogICAgYXJyYXkoKSB7CiAgICAgIHJldHVybiBab2RBcnJheS5jcmVhdGUodGhpcywgdGhpcy5fZGVmKTsKICAgIH0KICAgIHByb21pc2UoKSB7CiAgICAgIHJldHVybiBab2RQcm9taXNlLmNyZWF0ZSh0aGlzLCB0aGlzLl9kZWYpOwogICAgfQogICAgb3Iob3B0aW9uKSB7CiAgICAgIHJldHVybiBab2RVbmlvbi5jcmVhdGUoW3RoaXMsIG9wdGlvbl0sIHRoaXMuX2RlZik7CiAgICB9CiAgICBhbmQoaW5jb21pbmcpIHsKICAgICAgcmV0dXJuIFpvZEludGVyc2VjdGlvbi5jcmVhdGUodGhpcywgaW5jb21pbmcsIHRoaXMuX2RlZik7CiAgICB9CiAgICB0cmFuc2Zvcm0odHJhbnNmb3JtKSB7CiAgICAgIHJldHVybiBuZXcgWm9kRWZmZWN0cyh7CiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyh0aGlzLl9kZWYpLAogICAgICAgIHNjaGVtYTogdGhpcywKICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsCiAgICAgICAgZWZmZWN0OiB7IHR5cGU6ICJ0cmFuc2Zvcm0iLCB0cmFuc2Zvcm0gfQogICAgICB9KTsKICAgIH0KICAgIGRlZmF1bHQoZGVmKSB7CiAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZUZ1bmMgPSB0eXBlb2YgZGVmID09PSAiZnVuY3Rpb24iID8gZGVmIDogKCkgPT4gZGVmOwogICAgICByZXR1cm4gbmV3IFpvZERlZmF1bHQoewogICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXModGhpcy5fZGVmKSwKICAgICAgICBpbm5lclR5cGU6IHRoaXMsCiAgICAgICAgZGVmYXVsdFZhbHVlOiBkZWZhdWx0VmFsdWVGdW5jLAogICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRGVmYXVsdAogICAgICB9KTsKICAgIH0KICAgIGJyYW5kKCkgewogICAgICByZXR1cm4gbmV3IFpvZEJyYW5kZWQoewogICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQnJhbmRlZCwKICAgICAgICB0eXBlOiB0aGlzLAogICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXModGhpcy5fZGVmKQogICAgICB9KTsKICAgIH0KICAgIGNhdGNoKGRlZikgewogICAgICBjb25zdCBjYXRjaFZhbHVlRnVuYyA9IHR5cGVvZiBkZWYgPT09ICJmdW5jdGlvbiIgPyBkZWYgOiAoKSA9PiBkZWY7CiAgICAgIHJldHVybiBuZXcgWm9kQ2F0Y2goewogICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXModGhpcy5fZGVmKSwKICAgICAgICBpbm5lclR5cGU6IHRoaXMsCiAgICAgICAgY2F0Y2hWYWx1ZTogY2F0Y2hWYWx1ZUZ1bmMsCiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RDYXRjaAogICAgICB9KTsKICAgIH0KICAgIGRlc2NyaWJlKGRlc2NyaXB0aW9uKSB7CiAgICAgIGNvbnN0IFRoaXMgPSB0aGlzLmNvbnN0cnVjdG9yOwogICAgICByZXR1cm4gbmV3IFRoaXMoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBkZXNjcmlwdGlvbgogICAgICB9KTsKICAgIH0KICAgIHBpcGUodGFyZ2V0KSB7CiAgICAgIHJldHVybiBab2RQaXBlbGluZS5jcmVhdGUodGhpcywgdGFyZ2V0KTsKICAgIH0KICAgIHJlYWRvbmx5KCkgewogICAgICByZXR1cm4gWm9kUmVhZG9ubHkuY3JlYXRlKHRoaXMpOwogICAgfQogICAgaXNPcHRpb25hbCgpIHsKICAgICAgcmV0dXJuIHRoaXMuc2FmZVBhcnNlKHZvaWQgMCkuc3VjY2VzczsKICAgIH0KICAgIGlzTnVsbGFibGUoKSB7CiAgICAgIHJldHVybiB0aGlzLnNhZmVQYXJzZShudWxsKS5zdWNjZXNzOwogICAgfQogIH0KICBjb25zdCBjdWlkUmVnZXggPSAvXmNbXlxzLV17OCx9JC9pOwogIGNvbnN0IGN1aWQyUmVnZXggPSAvXlswLTlhLXpdKyQvOwogIGNvbnN0IHVsaWRSZWdleCA9IC9eWzAtOUEtSEpLTU5QLVRWLVpdezI2fSQvOwogIGNvbnN0IHV1aWRSZWdleCA9IC9eWzAtOWEtZkEtRl17OH1cYi1bMC05YS1mQS1GXXs0fVxiLVswLTlhLWZBLUZdezR9XGItWzAtOWEtZkEtRl17NH1cYi1bMC05YS1mQS1GXXsxMn0kL2k7CiAgY29uc3QgbmFub2lkUmVnZXggPSAvXlthLXowLTlfLV17MjF9JC9pOwogIGNvbnN0IGR1cmF0aW9uUmVnZXggPSAvXlstK10/UCg/ISQpKD86KD86Wy0rXT9cZCtZKXwoPzpbLStdP1xkK1suLF1cZCtZJCkpPyg/Oig/OlstK10/XGQrTSl8KD86Wy0rXT9cZCtbLixdXGQrTSQpKT8oPzooPzpbLStdP1xkK1cpfCg/OlstK10/XGQrWy4sXVxkK1ckKSk/KD86KD86Wy0rXT9cZCtEKXwoPzpbLStdP1xkK1suLF1cZCtEJCkpPyg/OlQoPz1bXGQrLV0pKD86KD86Wy0rXT9cZCtIKXwoPzpbLStdP1xkK1suLF1cZCtIJCkpPyg/Oig/OlstK10/XGQrTSl8KD86Wy0rXT9cZCtbLixdXGQrTSQpKT8oPzpbLStdP1xkKyg/OlsuLF1cZCspP1MpPyk/PyQvOwogIGNvbnN0IGVtYWlsUmVnZXggPSAvXig/IVwuKSg/IS4qXC5cLikoW0EtWjAtOV8nK1wtXC5dKilbQS1aMC05XystXUAoW0EtWjAtOV1bQS1aMC05XC1dKlwuKStbQS1aXXsyLH0kL2k7CiAgY29uc3QgX2Vtb2ppUmVnZXggPSBgXihcXHB7RXh0ZW5kZWRfUGljdG9ncmFwaGljfXxcXHB7RW1vamlfQ29tcG9uZW50fSkrJGA7CiAgbGV0IGVtb2ppUmVnZXg7CiAgY29uc3QgaXB2NFJlZ2V4ID0gL14oPzooPzoyNVswLTVdfDJbMC00XVswLTldfDFbMC05XVswLTldfFsxLTldWzAtOV18WzAtOV0pXC4pezN9KD86MjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV1bMC05XXxbMS05XVswLTldfFswLTldKSQvOwogIGNvbnN0IGlwdjZSZWdleCA9IC9eKChbYS1mMC05XXsxLDR9Oil7N318OjooW2EtZjAtOV17MSw0fTopezAsNn18KFthLWYwLTldezEsNH06KXsxfTooW2EtZjAtOV17MSw0fTopezAsNX18KFthLWYwLTldezEsNH06KXsyfTooW2EtZjAtOV17MSw0fTopezAsNH18KFthLWYwLTldezEsNH06KXszfTooW2EtZjAtOV17MSw0fTopezAsM318KFthLWYwLTldezEsNH06KXs0fTooW2EtZjAtOV17MSw0fTopezAsMn18KFthLWYwLTldezEsNH06KXs1fTooW2EtZjAtOV17MSw0fTopezAsMX0pKFthLWYwLTldezEsNH18KCgoMjVbMC01XSl8KDJbMC00XVswLTldKXwoMVswLTldezJ9KXwoWzAtOV17MSwyfSkpXC4pezN9KCgyNVswLTVdKXwoMlswLTRdWzAtOV0pfCgxWzAtOV17Mn0pfChbMC05XXsxLDJ9KSkpJC87CiAgY29uc3QgYmFzZTY0UmVnZXggPSAvXihbMC05YS16QS1aKy9dezR9KSooKFswLTlhLXpBLVorL117Mn09PSl8KFswLTlhLXpBLVorL117M309KSk/JC87CiAgY29uc3QgZGF0ZVJlZ2V4U291cmNlID0gYCgoXFxkXFxkWzI0NjhdWzA0OF18XFxkXFxkWzEzNTc5XVsyNl18XFxkXFxkMFs0OF18WzAyNDY4XVswNDhdMDB8WzEzNTc5XVsyNl0wMCktMDItMjl8XFxkezR9LSgoMFsxMzU3OF18MVswMl0pLSgwWzEtOV18WzEyXVxcZHwzWzAxXSl8KDBbNDY5XXwxMSktKDBbMS05XXxbMTJdXFxkfDMwKXwoMDIpLSgwWzEtOV18MVxcZHwyWzAtOF0pKSlgOwogIGNvbnN0IGRhdGVSZWdleCA9IG5ldyBSZWdFeHAoYF4ke2RhdGVSZWdleFNvdXJjZX0kYCk7CiAgZnVuY3Rpb24gdGltZVJlZ2V4U291cmNlKGFyZ3MpIHsKICAgIGxldCByZWdleCA9IGAoWzAxXVxcZHwyWzAtM10pOlswLTVdXFxkOlswLTVdXFxkYDsKICAgIGlmIChhcmdzLnByZWNpc2lvbikgewogICAgICByZWdleCA9IGAke3JlZ2V4fVxcLlxcZHske2FyZ3MucHJlY2lzaW9ufX1gOwogICAgfSBlbHNlIGlmIChhcmdzLnByZWNpc2lvbiA9PSBudWxsKSB7CiAgICAgIHJlZ2V4ID0gYCR7cmVnZXh9KFxcLlxcZCspP2A7CiAgICB9CiAgICByZXR1cm4gcmVnZXg7CiAgfQogIGZ1bmN0aW9uIHRpbWVSZWdleChhcmdzKSB7CiAgICByZXR1cm4gbmV3IFJlZ0V4cChgXiR7dGltZVJlZ2V4U291cmNlKGFyZ3MpfSRgKTsKICB9CiAgZnVuY3Rpb24gZGF0ZXRpbWVSZWdleChhcmdzKSB7CiAgICBsZXQgcmVnZXggPSBgJHtkYXRlUmVnZXhTb3VyY2V9VCR7dGltZVJlZ2V4U291cmNlKGFyZ3MpfWA7CiAgICBjb25zdCBvcHRzID0gW107CiAgICBvcHRzLnB1c2goYXJncy5sb2NhbCA/IGBaP2AgOiBgWmApOwogICAgaWYgKGFyZ3Mub2Zmc2V0KQogICAgICBvcHRzLnB1c2goYChbKy1dXFxkezJ9Oj9cXGR7Mn0pYCk7CiAgICByZWdleCA9IGAke3JlZ2V4fSgke29wdHMuam9pbigifCIpfSlgOwogICAgcmV0dXJuIG5ldyBSZWdFeHAoYF4ke3JlZ2V4fSRgKTsKICB9CiAgZnVuY3Rpb24gaXNWYWxpZElQKGlwLCB2ZXJzaW9uKSB7CiAgICBpZiAoKHZlcnNpb24gPT09ICJ2NCIgfHwgIXZlcnNpb24pICYmIGlwdjRSZWdleC50ZXN0KGlwKSkgewogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIGlmICgodmVyc2lvbiA9PT0gInY2IiB8fCAhdmVyc2lvbikgJiYgaXB2NlJlZ2V4LnRlc3QoaXApKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgcmV0dXJuIGZhbHNlOwogIH0KICBjbGFzcyBab2RTdHJpbmcgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBpZiAodGhpcy5fZGVmLmNvZXJjZSkgewogICAgICAgIGlucHV0LmRhdGEgPSBTdHJpbmcoaW5wdXQuZGF0YSk7CiAgICAgIH0KICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpOwogICAgICBpZiAocGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5zdHJpbmcpIHsKICAgICAgICBjb25zdCBjdHgyID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpOwogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eDIsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsCiAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5zdHJpbmcsCiAgICAgICAgICByZWNlaXZlZDogY3R4Mi5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgY29uc3Qgc3RhdHVzID0gbmV3IFBhcnNlU3RhdHVzKCk7CiAgICAgIGxldCBjdHggPSB2b2lkIDA7CiAgICAgIGZvciAoY29uc3QgY2hlY2sgb2YgdGhpcy5fZGVmLmNoZWNrcykgewogICAgICAgIGlmIChjaGVjay5raW5kID09PSAibWluIikgewogICAgICAgICAgaWYgKGlucHV0LmRhdGEubGVuZ3RoIDwgY2hlY2sudmFsdWUpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsCiAgICAgICAgICAgICAgbWluaW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgdHlwZTogInN0cmluZyIsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBpZiAoaW5wdXQuZGF0YS5sZW5ndGggPiBjaGVjay52YWx1ZSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsCiAgICAgICAgICAgICAgbWF4aW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgdHlwZTogInN0cmluZyIsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJsZW5ndGgiKSB7CiAgICAgICAgICBjb25zdCB0b29CaWcgPSBpbnB1dC5kYXRhLmxlbmd0aCA+IGNoZWNrLnZhbHVlOwogICAgICAgICAgY29uc3QgdG9vU21hbGwgPSBpbnB1dC5kYXRhLmxlbmd0aCA8IGNoZWNrLnZhbHVlOwogICAgICAgICAgaWYgKHRvb0JpZyB8fCB0b29TbWFsbCkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgaWYgKHRvb0JpZykgewogICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsCiAgICAgICAgICAgICAgICBtYXhpbXVtOiBjaGVjay52YWx1ZSwKICAgICAgICAgICAgICAgIHR5cGU6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgICAgZXhhY3Q6IHRydWUsCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodG9vU21hbGwpIHsKICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsCiAgICAgICAgICAgICAgICBtaW5pbXVtOiBjaGVjay52YWx1ZSwKICAgICAgICAgICAgICAgIHR5cGU6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgICAgZXhhY3Q6IHRydWUsCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiZW1haWwiKSB7CiAgICAgICAgICBpZiAoIWVtYWlsUmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogImVtYWlsIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiZW1vamkiKSB7CiAgICAgICAgICBpZiAoIWVtb2ppUmVnZXgpIHsKICAgICAgICAgICAgZW1vamlSZWdleCA9IG5ldyBSZWdFeHAoX2Vtb2ppUmVnZXgsICJ1Iik7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIWVtb2ppUmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogImVtb2ppIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAidXVpZCIpIHsKICAgICAgICAgIGlmICghdXVpZFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJ1dWlkIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAibmFub2lkIikgewogICAgICAgICAgaWYgKCFuYW5vaWRSZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICB2YWxpZGF0aW9uOiAibmFub2lkIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiY3VpZCIpIHsKICAgICAgICAgIGlmICghY3VpZFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJjdWlkIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiY3VpZDIiKSB7CiAgICAgICAgICBpZiAoIWN1aWQyUmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogImN1aWQyIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAidWxpZCIpIHsKICAgICAgICAgIGlmICghdWxpZFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJ1bGlkIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAidXJsIikgewogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgbmV3IFVSTChpbnB1dC5kYXRhKTsKICAgICAgICAgIH0gY2F0Y2ggKF9hKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICB2YWxpZGF0aW9uOiAidXJsIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAicmVnZXgiKSB7CiAgICAgICAgICBjaGVjay5yZWdleC5sYXN0SW5kZXggPSAwOwogICAgICAgICAgY29uc3QgdGVzdFJlc3VsdCA9IGNoZWNrLnJlZ2V4LnRlc3QoaW5wdXQuZGF0YSk7CiAgICAgICAgICBpZiAoIXRlc3RSZXN1bHQpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJyZWdleCIsCiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gInRyaW0iKSB7CiAgICAgICAgICBpbnB1dC5kYXRhID0gaW5wdXQuZGF0YS50cmltKCk7CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiaW5jbHVkZXMiKSB7CiAgICAgICAgICBpZiAoIWlucHV0LmRhdGEuaW5jbHVkZXMoY2hlY2sudmFsdWUsIGNoZWNrLnBvc2l0aW9uKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIHZhbGlkYXRpb246IHsgaW5jbHVkZXM6IGNoZWNrLnZhbHVlLCBwb3NpdGlvbjogY2hlY2sucG9zaXRpb24gfSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJ0b0xvd2VyQ2FzZSIpIHsKICAgICAgICAgIGlucHV0LmRhdGEgPSBpbnB1dC5kYXRhLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAidG9VcHBlckNhc2UiKSB7CiAgICAgICAgICBpbnB1dC5kYXRhID0gaW5wdXQuZGF0YS50b1VwcGVyQ2FzZSgpOwogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gInN0YXJ0c1dpdGgiKSB7CiAgICAgICAgICBpZiAoIWlucHV0LmRhdGEuc3RhcnRzV2l0aChjaGVjay52YWx1ZSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZywKICAgICAgICAgICAgICB2YWxpZGF0aW9uOiB7IHN0YXJ0c1dpdGg6IGNoZWNrLnZhbHVlIH0sCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiZW5kc1dpdGgiKSB7CiAgICAgICAgICBpZiAoIWlucHV0LmRhdGEuZW5kc1dpdGgoY2hlY2sudmFsdWUpKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogeyBlbmRzV2l0aDogY2hlY2sudmFsdWUgfSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJkYXRldGltZSIpIHsKICAgICAgICAgIGNvbnN0IHJlZ2V4ID0gZGF0ZXRpbWVSZWdleChjaGVjayk7CiAgICAgICAgICBpZiAoIXJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZywKICAgICAgICAgICAgICB2YWxpZGF0aW9uOiAiZGF0ZXRpbWUiLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gImRhdGUiKSB7CiAgICAgICAgICBjb25zdCByZWdleCA9IGRhdGVSZWdleDsKICAgICAgICAgIGlmICghcmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJkYXRlIiwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJ0aW1lIikgewogICAgICAgICAgY29uc3QgcmVnZXggPSB0aW1lUmVnZXgoY2hlY2spOwogICAgICAgICAgaWYgKCFyZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogInRpbWUiLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gImR1cmF0aW9uIikgewogICAgICAgICAgaWYgKCFkdXJhdGlvblJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJkdXJhdGlvbiIsCiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gImlwIikgewogICAgICAgICAgaWYgKCFpc1ZhbGlkSVAoaW5wdXQuZGF0YSwgY2hlY2sudmVyc2lvbikpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJpcCIsCiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gImJhc2U2NCIpIHsKICAgICAgICAgIGlmICghYmFzZTY0UmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogImJhc2U2NCIsCiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGNoZWNrKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBpbnB1dC5kYXRhIH07CiAgICB9CiAgICBfcmVnZXgocmVnZXgsIHZhbGlkYXRpb24sIG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMucmVmaW5lbWVudCgoZGF0YSkgPT4gcmVnZXgudGVzdChkYXRhKSwgewogICAgICAgIHZhbGlkYXRpb24sCiAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIF9hZGRDaGVjayhjaGVjaykgewogICAgICByZXR1cm4gbmV3IFpvZFN0cmluZyh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIGNoZWNrczogWy4uLnRoaXMuX2RlZi5jaGVja3MsIGNoZWNrXQogICAgICB9KTsKICAgIH0KICAgIGVtYWlsKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImVtYWlsIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgdXJsKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogInVybCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTsKICAgIH0KICAgIGVtb2ppKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImVtb2ppIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgdXVpZChtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7IGtpbmQ6ICJ1dWlkIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgbmFub2lkKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogIm5hbm9pZCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTsKICAgIH0KICAgIGN1aWQobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soeyBraW5kOiAiY3VpZCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTsKICAgIH0KICAgIGN1aWQyKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImN1aWQyIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgdWxpZChtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7IGtpbmQ6ICJ1bGlkIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgYmFzZTY0KG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImJhc2U2NCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTsKICAgIH0KICAgIGlwKG9wdGlvbnMpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImlwIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnMpIH0pOwogICAgfQogICAgZGF0ZXRpbWUob3B0aW9ucykgewogICAgICB2YXIgX2EsIF9iOwogICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICJzdHJpbmciKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICAgIGtpbmQ6ICJkYXRldGltZSIsCiAgICAgICAgICBwcmVjaXNpb246IG51bGwsCiAgICAgICAgICBvZmZzZXQ6IGZhbHNlLAogICAgICAgICAgbG9jYWw6IGZhbHNlLAogICAgICAgICAgbWVzc2FnZTogb3B0aW9ucwogICAgICAgIH0pOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogImRhdGV0aW1lIiwKICAgICAgICBwcmVjaXNpb246IHR5cGVvZiAob3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZWNpc2lvbikgPT09ICJ1bmRlZmluZWQiID8gbnVsbCA6IG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy5wcmVjaXNpb24sCiAgICAgICAgb2Zmc2V0OiAoX2EgPSBvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMub2Zmc2V0KSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiBmYWxzZSwKICAgICAgICBsb2NhbDogKF9iID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLmxvY2FsKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBmYWxzZSwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoob3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLm1lc3NhZ2UpCiAgICAgIH0pOwogICAgfQogICAgZGF0ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7IGtpbmQ6ICJkYXRlIiwgbWVzc2FnZSB9KTsKICAgIH0KICAgIHRpbWUob3B0aW9ucykgewogICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICJzdHJpbmciKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICAgIGtpbmQ6ICJ0aW1lIiwKICAgICAgICAgIHByZWNpc2lvbjogbnVsbCwKICAgICAgICAgIG1lc3NhZ2U6IG9wdGlvbnMKICAgICAgICB9KTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJ0aW1lIiwKICAgICAgICBwcmVjaXNpb246IHR5cGVvZiAob3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZWNpc2lvbikgPT09ICJ1bmRlZmluZWQiID8gbnVsbCA6IG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy5wcmVjaXNpb24sCiAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy5tZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIGR1cmF0aW9uKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImR1cmF0aW9uIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgcmVnZXgocmVnZXgsIG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICBraW5kOiAicmVnZXgiLAogICAgICAgIHJlZ2V4LAogICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIGluY2x1ZGVzKHZhbHVlLCBvcHRpb25zKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogImluY2x1ZGVzIiwKICAgICAgICB2YWx1ZSwKICAgICAgICBwb3NpdGlvbjogb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnBvc2l0aW9uLAogICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMubWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBzdGFydHNXaXRoKHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogInN0YXJ0c1dpdGgiLAogICAgICAgIHZhbHVlLAogICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIGVuZHNXaXRoKHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogImVuZHNXaXRoIiwKICAgICAgICB2YWx1ZSwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBtaW4obWluTGVuZ3RoLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1pbiIsCiAgICAgICAgdmFsdWU6IG1pbkxlbmd0aCwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBtYXgobWF4TGVuZ3RoLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IG1heExlbmd0aCwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBsZW5ndGgobGVuLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogImxlbmd0aCIsCiAgICAgICAgdmFsdWU6IGxlbiwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICAvKioKICAgICAqIEBkZXByZWNhdGVkIFVzZSB6LnN0cmluZygpLm1pbigxKSBpbnN0ZWFkLgogICAgICogQHNlZSB7QGxpbmsgWm9kU3RyaW5nLm1pbn0KICAgICAqLwogICAgbm9uZW1wdHkobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5taW4oMSwgZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpKTsKICAgIH0KICAgIHRyaW0oKSB7CiAgICAgIHJldHVybiBuZXcgWm9kU3RyaW5nKHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbLi4udGhpcy5fZGVmLmNoZWNrcywgeyBraW5kOiAidHJpbSIgfV0KICAgICAgfSk7CiAgICB9CiAgICB0b0xvd2VyQ2FzZSgpIHsKICAgICAgcmV0dXJuIG5ldyBab2RTdHJpbmcoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBjaGVja3M6IFsuLi50aGlzLl9kZWYuY2hlY2tzLCB7IGtpbmQ6ICJ0b0xvd2VyQ2FzZSIgfV0KICAgICAgfSk7CiAgICB9CiAgICB0b1VwcGVyQ2FzZSgpIHsKICAgICAgcmV0dXJuIG5ldyBab2RTdHJpbmcoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBjaGVja3M6IFsuLi50aGlzLl9kZWYuY2hlY2tzLCB7IGtpbmQ6ICJ0b1VwcGVyQ2FzZSIgfV0KICAgICAgfSk7CiAgICB9CiAgICBnZXQgaXNEYXRldGltZSgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gImRhdGV0aW1lIik7CiAgICB9CiAgICBnZXQgaXNEYXRlKCkgewogICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSAiZGF0ZSIpOwogICAgfQogICAgZ2V0IGlzVGltZSgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gInRpbWUiKTsKICAgIH0KICAgIGdldCBpc0R1cmF0aW9uKCkgewogICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSAiZHVyYXRpb24iKTsKICAgIH0KICAgIGdldCBpc0VtYWlsKCkgewogICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSAiZW1haWwiKTsKICAgIH0KICAgIGdldCBpc1VSTCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gInVybCIpOwogICAgfQogICAgZ2V0IGlzRW1vamkoKSB7CiAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09ICJlbW9qaSIpOwogICAgfQogICAgZ2V0IGlzVVVJRCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gInV1aWQiKTsKICAgIH0KICAgIGdldCBpc05BTk9JRCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gIm5hbm9pZCIpOwogICAgfQogICAgZ2V0IGlzQ1VJRCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gImN1aWQiKTsKICAgIH0KICAgIGdldCBpc0NVSUQyKCkgewogICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSAiY3VpZDIiKTsKICAgIH0KICAgIGdldCBpc1VMSUQoKSB7CiAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09ICJ1bGlkIik7CiAgICB9CiAgICBnZXQgaXNJUCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gImlwIik7CiAgICB9CiAgICBnZXQgaXNCYXNlNjQoKSB7CiAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09ICJiYXNlNjQiKTsKICAgIH0KICAgIGdldCBtaW5MZW5ndGgoKSB7CiAgICAgIGxldCBtaW4gPSBudWxsOwogICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2gua2luZCA9PT0gIm1pbiIpIHsKICAgICAgICAgIGlmIChtaW4gPT09IG51bGwgfHwgY2gudmFsdWUgPiBtaW4pCiAgICAgICAgICAgIG1pbiA9IGNoLnZhbHVlOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gbWluOwogICAgfQogICAgZ2V0IG1heExlbmd0aCgpIHsKICAgICAgbGV0IG1heCA9IG51bGw7CiAgICAgIGZvciAoY29uc3QgY2ggb2YgdGhpcy5fZGVmLmNoZWNrcykgewogICAgICAgIGlmIChjaC5raW5kID09PSAibWF4IikgewogICAgICAgICAgaWYgKG1heCA9PT0gbnVsbCB8fCBjaC52YWx1ZSA8IG1heCkKICAgICAgICAgICAgbWF4ID0gY2gudmFsdWU7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBtYXg7CiAgICB9CiAgfQogIFpvZFN0cmluZy5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICB2YXIgX2E7CiAgICByZXR1cm4gbmV3IFpvZFN0cmluZyh7CiAgICAgIGNoZWNrczogW10sCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3RyaW5nLAogICAgICBjb2VyY2U6IChfYSA9IHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5jb2VyY2UpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6IGZhbHNlLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgZnVuY3Rpb24gZmxvYXRTYWZlUmVtYWluZGVyKHZhbCwgc3RlcCkgewogICAgY29uc3QgdmFsRGVjQ291bnQgPSAodmFsLnRvU3RyaW5nKCkuc3BsaXQoIi4iKVsxXSB8fCAiIikubGVuZ3RoOwogICAgY29uc3Qgc3RlcERlY0NvdW50ID0gKHN0ZXAudG9TdHJpbmcoKS5zcGxpdCgiLiIpWzFdIHx8ICIiKS5sZW5ndGg7CiAgICBjb25zdCBkZWNDb3VudCA9IHZhbERlY0NvdW50ID4gc3RlcERlY0NvdW50ID8gdmFsRGVjQ291bnQgOiBzdGVwRGVjQ291bnQ7CiAgICBjb25zdCB2YWxJbnQgPSBwYXJzZUludCh2YWwudG9GaXhlZChkZWNDb3VudCkucmVwbGFjZSgiLiIsICIiKSk7CiAgICBjb25zdCBzdGVwSW50ID0gcGFyc2VJbnQoc3RlcC50b0ZpeGVkKGRlY0NvdW50KS5yZXBsYWNlKCIuIiwgIiIpKTsKICAgIHJldHVybiB2YWxJbnQgJSBzdGVwSW50IC8gTWF0aC5wb3coMTAsIGRlY0NvdW50KTsKICB9CiAgY2xhc3MgWm9kTnVtYmVyIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTsKICAgICAgdGhpcy5taW4gPSB0aGlzLmd0ZTsKICAgICAgdGhpcy5tYXggPSB0aGlzLmx0ZTsKICAgICAgdGhpcy5zdGVwID0gdGhpcy5tdWx0aXBsZU9mOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGlmICh0aGlzLl9kZWYuY29lcmNlKSB7CiAgICAgICAgaW5wdXQuZGF0YSA9IE51bWJlcihpbnB1dC5kYXRhKTsKICAgICAgfQogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm51bWJlcikgewogICAgICAgIGNvbnN0IGN0eDIgPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4MiwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm51bWJlciwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgyLnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICBsZXQgY3R4ID0gdm9pZCAwOwogICAgICBjb25zdCBzdGF0dXMgPSBuZXcgUGFyc2VTdGF0dXMoKTsKICAgICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoZWNrLmtpbmQgPT09ICJpbnQiKSB7CiAgICAgICAgICBpZiAoIXV0aWwuaXNJbnRlZ2VyKGlucHV0LmRhdGEpKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgICAgIGV4cGVjdGVkOiAiaW50ZWdlciIsCiAgICAgICAgICAgICAgcmVjZWl2ZWQ6ICJmbG9hdCIsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAibWluIikgewogICAgICAgICAgY29uc3QgdG9vU21hbGwgPSBjaGVjay5pbmNsdXNpdmUgPyBpbnB1dC5kYXRhIDwgY2hlY2sudmFsdWUgOiBpbnB1dC5kYXRhIDw9IGNoZWNrLnZhbHVlOwogICAgICAgICAgaWYgKHRvb1NtYWxsKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLAogICAgICAgICAgICAgIG1pbmltdW06IGNoZWNrLnZhbHVlLAogICAgICAgICAgICAgIHR5cGU6ICJudW1iZXIiLAogICAgICAgICAgICAgIGluY2x1c2l2ZTogY2hlY2suaW5jbHVzaXZlLAogICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBjb25zdCB0b29CaWcgPSBjaGVjay5pbmNsdXNpdmUgPyBpbnB1dC5kYXRhID4gY2hlY2sudmFsdWUgOiBpbnB1dC5kYXRhID49IGNoZWNrLnZhbHVlOwogICAgICAgICAgaWYgKHRvb0JpZykgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsCiAgICAgICAgICAgICAgbWF4aW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgdHlwZTogIm51bWJlciIsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiBjaGVjay5pbmNsdXNpdmUsCiAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gIm11bHRpcGxlT2YiKSB7CiAgICAgICAgICBpZiAoZmxvYXRTYWZlUmVtYWluZGVyKGlucHV0LmRhdGEsIGNoZWNrLnZhbHVlKSAhPT0gMCkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLm5vdF9tdWx0aXBsZV9vZiwKICAgICAgICAgICAgICBtdWx0aXBsZU9mOiBjaGVjay52YWx1ZSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJmaW5pdGUiKSB7CiAgICAgICAgICBpZiAoIU51bWJlci5pc0Zpbml0ZShpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLm5vdF9maW5pdGUsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoY2hlY2spOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IGlucHV0LmRhdGEgfTsKICAgIH0KICAgIGd0ZSh2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdCgibWluIiwgdmFsdWUsIHRydWUsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7CiAgICB9CiAgICBndCh2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdCgibWluIiwgdmFsdWUsIGZhbHNlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpOwogICAgfQogICAgbHRlKHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KCJtYXgiLCB2YWx1ZSwgdHJ1ZSwgZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpKTsKICAgIH0KICAgIGx0KHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KCJtYXgiLCB2YWx1ZSwgZmFsc2UsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7CiAgICB9CiAgICBzZXRMaW1pdChraW5kLCB2YWx1ZSwgaW5jbHVzaXZlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kTnVtYmVyKHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbCiAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLAogICAgICAgICAgewogICAgICAgICAgICBraW5kLAogICAgICAgICAgICB2YWx1ZSwKICAgICAgICAgICAgaW5jbHVzaXZlLAogICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgICAgIH0KICAgICAgICBdCiAgICAgIH0pOwogICAgfQogICAgX2FkZENoZWNrKGNoZWNrKSB7CiAgICAgIHJldHVybiBuZXcgWm9kTnVtYmVyKHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbLi4udGhpcy5fZGVmLmNoZWNrcywgY2hlY2tdCiAgICAgIH0pOwogICAgfQogICAgaW50KG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICBraW5kOiAiaW50IiwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBwb3NpdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1pbiIsCiAgICAgICAgdmFsdWU6IDAsCiAgICAgICAgaW5jbHVzaXZlOiBmYWxzZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBuZWdhdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IDAsCiAgICAgICAgaW5jbHVzaXZlOiBmYWxzZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBub25wb3NpdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IDAsCiAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIG5vbm5lZ2F0aXZlKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICBraW5kOiAibWluIiwKICAgICAgICB2YWx1ZTogMCwKICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpCiAgICAgIH0pOwogICAgfQogICAgbXVsdGlwbGVPZih2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJtdWx0aXBsZU9mIiwKICAgICAgICB2YWx1ZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBmaW5pdGUobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJmaW5pdGUiLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIHNhZmUobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJtaW4iLAogICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICB2YWx1ZTogTnVtYmVyLk1JTl9TQUZFX0lOVEVHRVIsCiAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpCiAgICAgIH0pLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgIHZhbHVlOiBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBnZXQgbWluVmFsdWUoKSB7CiAgICAgIGxldCBtaW4gPSBudWxsOwogICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2gua2luZCA9PT0gIm1pbiIpIHsKICAgICAgICAgIGlmIChtaW4gPT09IG51bGwgfHwgY2gudmFsdWUgPiBtaW4pCiAgICAgICAgICAgIG1pbiA9IGNoLnZhbHVlOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gbWluOwogICAgfQogICAgZ2V0IG1heFZhbHVlKCkgewogICAgICBsZXQgbWF4ID0gbnVsbDsKICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNoLnZhbHVlIDwgbWF4KQogICAgICAgICAgICBtYXggPSBjaC52YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIG1heDsKICAgIH0KICAgIGdldCBpc0ludCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gImludCIgfHwgY2gua2luZCA9PT0gIm11bHRpcGxlT2YiICYmIHV0aWwuaXNJbnRlZ2VyKGNoLnZhbHVlKSk7CiAgICB9CiAgICBnZXQgaXNGaW5pdGUoKSB7CiAgICAgIGxldCBtYXggPSBudWxsLCBtaW4gPSBudWxsOwogICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2gua2luZCA9PT0gImZpbml0ZSIgfHwgY2gua2luZCA9PT0gImludCIgfHwgY2gua2luZCA9PT0gIm11bHRpcGxlT2YiKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9IGVsc2UgaWYgKGNoLmtpbmQgPT09ICJtaW4iKSB7CiAgICAgICAgICBpZiAobWluID09PSBudWxsIHx8IGNoLnZhbHVlID4gbWluKQogICAgICAgICAgICBtaW4gPSBjaC52YWx1ZTsKICAgICAgICB9IGVsc2UgaWYgKGNoLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNoLnZhbHVlIDwgbWF4KQogICAgICAgICAgICBtYXggPSBjaC52YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShtaW4pICYmIE51bWJlci5pc0Zpbml0ZShtYXgpOwogICAgfQogIH0KICBab2ROdW1iZXIuY3JlYXRlID0gKHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2ROdW1iZXIoewogICAgICBjaGVja3M6IFtdLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bWJlciwKICAgICAgY29lcmNlOiAocGFyYW1zID09PSBudWxsIHx8IHBhcmFtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFyYW1zLmNvZXJjZSkgfHwgZmFsc2UsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RCaWdJbnQgZXh0ZW5kcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICBzdXBlciguLi5hcmd1bWVudHMpOwogICAgICB0aGlzLm1pbiA9IHRoaXMuZ3RlOwogICAgICB0aGlzLm1heCA9IHRoaXMubHRlOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGlmICh0aGlzLl9kZWYuY29lcmNlKSB7CiAgICAgICAgaW5wdXQuZGF0YSA9IEJpZ0ludChpbnB1dC5kYXRhKTsKICAgICAgfQogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLmJpZ2ludCkgewogICAgICAgIGNvbnN0IGN0eDIgPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4MiwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmJpZ2ludCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgyLnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICBsZXQgY3R4ID0gdm9pZCAwOwogICAgICBjb25zdCBzdGF0dXMgPSBuZXcgUGFyc2VTdGF0dXMoKTsKICAgICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoZWNrLmtpbmQgPT09ICJtaW4iKSB7CiAgICAgICAgICBjb25zdCB0b29TbWFsbCA9IGNoZWNrLmluY2x1c2l2ZSA/IGlucHV0LmRhdGEgPCBjaGVjay52YWx1ZSA6IGlucHV0LmRhdGEgPD0gY2hlY2sudmFsdWU7CiAgICAgICAgICBpZiAodG9vU21hbGwpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsCiAgICAgICAgICAgICAgdHlwZTogImJpZ2ludCIsCiAgICAgICAgICAgICAgbWluaW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiBjaGVjay5pbmNsdXNpdmUsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAibWF4IikgewogICAgICAgICAgY29uc3QgdG9vQmlnID0gY2hlY2suaW5jbHVzaXZlID8gaW5wdXQuZGF0YSA+IGNoZWNrLnZhbHVlIDogaW5wdXQuZGF0YSA+PSBjaGVjay52YWx1ZTsKICAgICAgICAgIGlmICh0b29CaWcpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fYmlnLAogICAgICAgICAgICAgIHR5cGU6ICJiaWdpbnQiLAogICAgICAgICAgICAgIG1heGltdW06IGNoZWNrLnZhbHVlLAogICAgICAgICAgICAgIGluY2x1c2l2ZTogY2hlY2suaW5jbHVzaXZlLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gIm11bHRpcGxlT2YiKSB7CiAgICAgICAgICBpZiAoaW5wdXQuZGF0YSAlIGNoZWNrLnZhbHVlICE9PSBCaWdJbnQoMCkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5ub3RfbXVsdGlwbGVfb2YsCiAgICAgICAgICAgICAgbXVsdGlwbGVPZjogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoY2hlY2spOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IGlucHV0LmRhdGEgfTsKICAgIH0KICAgIGd0ZSh2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdCgibWluIiwgdmFsdWUsIHRydWUsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7CiAgICB9CiAgICBndCh2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdCgibWluIiwgdmFsdWUsIGZhbHNlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpOwogICAgfQogICAgbHRlKHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KCJtYXgiLCB2YWx1ZSwgdHJ1ZSwgZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpKTsKICAgIH0KICAgIGx0KHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KCJtYXgiLCB2YWx1ZSwgZmFsc2UsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7CiAgICB9CiAgICBzZXRMaW1pdChraW5kLCB2YWx1ZSwgaW5jbHVzaXZlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQmlnSW50KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbCiAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLAogICAgICAgICAgewogICAgICAgICAgICBraW5kLAogICAgICAgICAgICB2YWx1ZSwKICAgICAgICAgICAgaW5jbHVzaXZlLAogICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgICAgIH0KICAgICAgICBdCiAgICAgIH0pOwogICAgfQogICAgX2FkZENoZWNrKGNoZWNrKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQmlnSW50KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbLi4udGhpcy5fZGVmLmNoZWNrcywgY2hlY2tdCiAgICAgIH0pOwogICAgfQogICAgcG9zaXRpdmUobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJtaW4iLAogICAgICAgIHZhbHVlOiBCaWdJbnQoMCksCiAgICAgICAgaW5jbHVzaXZlOiBmYWxzZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBuZWdhdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IEJpZ0ludCgwKSwKICAgICAgICBpbmNsdXNpdmU6IGZhbHNlLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIG5vbnBvc2l0aXZlKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICBraW5kOiAibWF4IiwKICAgICAgICB2YWx1ZTogQmlnSW50KDApLAogICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBub25uZWdhdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1pbiIsCiAgICAgICAgdmFsdWU6IEJpZ0ludCgwKSwKICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpCiAgICAgIH0pOwogICAgfQogICAgbXVsdGlwbGVPZih2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJtdWx0aXBsZU9mIiwKICAgICAgICB2YWx1ZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBnZXQgbWluVmFsdWUoKSB7CiAgICAgIGxldCBtaW4gPSBudWxsOwogICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2gua2luZCA9PT0gIm1pbiIpIHsKICAgICAgICAgIGlmIChtaW4gPT09IG51bGwgfHwgY2gudmFsdWUgPiBtaW4pCiAgICAgICAgICAgIG1pbiA9IGNoLnZhbHVlOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gbWluOwogICAgfQogICAgZ2V0IG1heFZhbHVlKCkgewogICAgICBsZXQgbWF4ID0gbnVsbDsKICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNoLnZhbHVlIDwgbWF4KQogICAgICAgICAgICBtYXggPSBjaC52YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIG1heDsKICAgIH0KICB9CiAgWm9kQmlnSW50LmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHZhciBfYTsKICAgIHJldHVybiBuZXcgWm9kQmlnSW50KHsKICAgICAgY2hlY2tzOiBbXSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RCaWdJbnQsCiAgICAgIGNvZXJjZTogKF9hID0gcGFyYW1zID09PSBudWxsIHx8IHBhcmFtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFyYW1zLmNvZXJjZSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogZmFsc2UsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RCb29sZWFuIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgaWYgKHRoaXMuX2RlZi5jb2VyY2UpIHsKICAgICAgICBpbnB1dC5kYXRhID0gQm9vbGVhbihpbnB1dC5kYXRhKTsKICAgICAgfQogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLmJvb2xlYW4pIHsKICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUuYm9vbGVhbiwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTsKICAgIH0KICB9CiAgWm9kQm9vbGVhbi5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZEJvb2xlYW4oewogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEJvb2xlYW4sCiAgICAgIGNvZXJjZTogKHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5jb2VyY2UpIHx8IGZhbHNlLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kRGF0ZSBleHRlbmRzIFpvZFR5cGUgewogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGlmICh0aGlzLl9kZWYuY29lcmNlKSB7CiAgICAgICAgaW5wdXQuZGF0YSA9IG5ldyBEYXRlKGlucHV0LmRhdGEpOwogICAgICB9CiAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTsKICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuZGF0ZSkgewogICAgICAgIGNvbnN0IGN0eDIgPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4MiwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmRhdGUsCiAgICAgICAgICByZWNlaXZlZDogY3R4Mi5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgaWYgKGlzTmFOKGlucHV0LmRhdGEuZ2V0VGltZSgpKSkgewogICAgICAgIGNvbnN0IGN0eDIgPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4MiwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfZGF0ZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IHN0YXR1cyA9IG5ldyBQYXJzZVN0YXR1cygpOwogICAgICBsZXQgY3R4ID0gdm9pZCAwOwogICAgICBmb3IgKGNvbnN0IGNoZWNrIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2hlY2sua2luZCA9PT0gIm1pbiIpIHsKICAgICAgICAgIGlmIChpbnB1dC5kYXRhLmdldFRpbWUoKSA8IGNoZWNrLnZhbHVlKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgICBtaW5pbXVtOiBjaGVjay52YWx1ZSwKICAgICAgICAgICAgICB0eXBlOiAiZGF0ZSIKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gIm1heCIpIHsKICAgICAgICAgIGlmIChpbnB1dC5kYXRhLmdldFRpbWUoKSA+IGNoZWNrLnZhbHVlKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZywKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLAogICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICAgICAgICBleGFjdDogZmFsc2UsCiAgICAgICAgICAgICAgbWF4aW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgdHlwZTogImRhdGUiCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgdXRpbC5hc3NlcnROZXZlcihjaGVjayk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiB7CiAgICAgICAgc3RhdHVzOiBzdGF0dXMudmFsdWUsCiAgICAgICAgdmFsdWU6IG5ldyBEYXRlKGlucHV0LmRhdGEuZ2V0VGltZSgpKQogICAgICB9OwogICAgfQogICAgX2FkZENoZWNrKGNoZWNrKSB7CiAgICAgIHJldHVybiBuZXcgWm9kRGF0ZSh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIGNoZWNrczogWy4uLnRoaXMuX2RlZi5jaGVja3MsIGNoZWNrXQogICAgICB9KTsKICAgIH0KICAgIG1pbihtaW5EYXRlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1pbiIsCiAgICAgICAgdmFsdWU6IG1pbkRhdGUuZ2V0VGltZSgpLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIG1heChtYXhEYXRlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IG1heERhdGUuZ2V0VGltZSgpLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIGdldCBtaW5EYXRlKCkgewogICAgICBsZXQgbWluID0gbnVsbDsKICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoLmtpbmQgPT09ICJtaW4iKSB7CiAgICAgICAgICBpZiAobWluID09PSBudWxsIHx8IGNoLnZhbHVlID4gbWluKQogICAgICAgICAgICBtaW4gPSBjaC52YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIG1pbiAhPSBudWxsID8gbmV3IERhdGUobWluKSA6IG51bGw7CiAgICB9CiAgICBnZXQgbWF4RGF0ZSgpIHsKICAgICAgbGV0IG1heCA9IG51bGw7CiAgICAgIGZvciAoY29uc3QgY2ggb2YgdGhpcy5fZGVmLmNoZWNrcykgewogICAgICAgIGlmIChjaC5raW5kID09PSAibWF4IikgewogICAgICAgICAgaWYgKG1heCA9PT0gbnVsbCB8fCBjaC52YWx1ZSA8IG1heCkKICAgICAgICAgICAgbWF4ID0gY2gudmFsdWU7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBtYXggIT0gbnVsbCA/IG5ldyBEYXRlKG1heCkgOiBudWxsOwogICAgfQogIH0KICBab2REYXRlLmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kRGF0ZSh7CiAgICAgIGNoZWNrczogW10sCiAgICAgIGNvZXJjZTogKHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5jb2VyY2UpIHx8IGZhbHNlLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZERhdGUsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RTeW1ib2wgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLnN5bWJvbCkgewogICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsCiAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5zeW1ib2wsCiAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7CiAgICB9CiAgfQogIFpvZFN5bWJvbC5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZFN5bWJvbCh7CiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3ltYm9sLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kVW5kZWZpbmVkIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpOwogICAgICBpZiAocGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQpIHsKICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkLAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpOwogICAgfQogIH0KICBab2RVbmRlZmluZWQuY3JlYXRlID0gKHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RVbmRlZmluZWQoewogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFVuZGVmaW5lZCwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZE51bGwgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm51bGwpIHsKICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUubnVsbCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTsKICAgIH0KICB9CiAgWm9kTnVsbC5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE51bGwoewogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bGwsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RBbnkgZXh0ZW5kcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICBzdXBlciguLi5hcmd1bWVudHMpOwogICAgICB0aGlzLl9hbnkgPSB0cnVlOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTsKICAgIH0KICB9CiAgWm9kQW55LmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kQW55KHsKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RBbnksCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RVbmtub3duIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTsKICAgICAgdGhpcy5fdW5rbm93biA9IHRydWU7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpOwogICAgfQogIH0KICBab2RVbmtub3duLmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kVW5rbm93bih7CiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kVW5rbm93biwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZE5ldmVyIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpOwogICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm5ldmVyLAogICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICB9KTsKICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICB9CiAgfQogIFpvZE5ldmVyLmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kTmV2ZXIoewogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE5ldmVyLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kVm9pZCBleHRlbmRzIFpvZFR5cGUgewogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTsKICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7CiAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpOwogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLnZvaWQsCiAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7CiAgICB9CiAgfQogIFpvZFZvaWQuY3JlYXRlID0gKHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RWb2lkKHsKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RWb2lkLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kQXJyYXkgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IGN0eCwgc3RhdHVzIH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBjb25zdCBkZWYgPSB0aGlzLl9kZWY7CiAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5hcnJheSkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmFycmF5LAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgaWYgKGRlZi5leGFjdExlbmd0aCAhPT0gbnVsbCkgewogICAgICAgIGNvbnN0IHRvb0JpZyA9IGN0eC5kYXRhLmxlbmd0aCA+IGRlZi5leGFjdExlbmd0aC52YWx1ZTsKICAgICAgICBjb25zdCB0b29TbWFsbCA9IGN0eC5kYXRhLmxlbmd0aCA8IGRlZi5leGFjdExlbmd0aC52YWx1ZTsKICAgICAgICBpZiAodG9vQmlnIHx8IHRvb1NtYWxsKSB7CiAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgY29kZTogdG9vQmlnID8gWm9kSXNzdWVDb2RlLnRvb19iaWcgOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLAogICAgICAgICAgICBtaW5pbXVtOiB0b29TbWFsbCA/IGRlZi5leGFjdExlbmd0aC52YWx1ZSA6IHZvaWQgMCwKICAgICAgICAgICAgbWF4aW11bTogdG9vQmlnID8gZGVmLmV4YWN0TGVuZ3RoLnZhbHVlIDogdm9pZCAwLAogICAgICAgICAgICB0eXBlOiAiYXJyYXkiLAogICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgICAgIGV4YWN0OiB0cnVlLAogICAgICAgICAgICBtZXNzYWdlOiBkZWYuZXhhY3RMZW5ndGgubWVzc2FnZQogICAgICAgICAgfSk7CiAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGRlZi5taW5MZW5ndGggIT09IG51bGwpIHsKICAgICAgICBpZiAoY3R4LmRhdGEubGVuZ3RoIDwgZGVmLm1pbkxlbmd0aC52YWx1ZSkgewogICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsCiAgICAgICAgICAgIG1pbmltdW06IGRlZi5taW5MZW5ndGgudmFsdWUsCiAgICAgICAgICAgIHR5cGU6ICJhcnJheSIsCiAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLAogICAgICAgICAgICBtZXNzYWdlOiBkZWYubWluTGVuZ3RoLm1lc3NhZ2UKICAgICAgICAgIH0pOwogICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChkZWYubWF4TGVuZ3RoICE9PSBudWxsKSB7CiAgICAgICAgaWYgKGN0eC5kYXRhLmxlbmd0aCA+IGRlZi5tYXhMZW5ndGgudmFsdWUpIHsKICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZywKICAgICAgICAgICAgbWF4aW11bTogZGVmLm1heExlbmd0aC52YWx1ZSwKICAgICAgICAgICAgdHlwZTogImFycmF5IiwKICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICBleGFjdDogZmFsc2UsCiAgICAgICAgICAgIG1lc3NhZ2U6IGRlZi5tYXhMZW5ndGgubWVzc2FnZQogICAgICAgICAgfSk7CiAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoWy4uLmN0eC5kYXRhXS5tYXAoKGl0ZW0sIGkyKSA9PiB7CiAgICAgICAgICByZXR1cm4gZGVmLnR5cGUuX3BhcnNlQXN5bmMobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGl0ZW0sIGN0eC5wYXRoLCBpMikpOwogICAgICAgIH0pKS50aGVuKChyZXN1bHQyKSA9PiB7CiAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIHJlc3VsdDIpOwogICAgICAgIH0pOwogICAgICB9CiAgICAgIGNvbnN0IHJlc3VsdCA9IFsuLi5jdHguZGF0YV0ubWFwKChpdGVtLCBpMikgPT4gewogICAgICAgIHJldHVybiBkZWYudHlwZS5fcGFyc2VTeW5jKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCBpdGVtLCBjdHgucGF0aCwgaTIpKTsKICAgICAgfSk7CiAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZUFycmF5KHN0YXR1cywgcmVzdWx0KTsKICAgIH0KICAgIGdldCBlbGVtZW50KCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLnR5cGU7CiAgICB9CiAgICBtaW4obWluTGVuZ3RoLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQXJyYXkoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBtaW5MZW5ndGg6IHsgdmFsdWU6IG1pbkxlbmd0aCwgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpIH0KICAgICAgfSk7CiAgICB9CiAgICBtYXgobWF4TGVuZ3RoLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQXJyYXkoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBtYXhMZW5ndGg6IHsgdmFsdWU6IG1heExlbmd0aCwgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpIH0KICAgICAgfSk7CiAgICB9CiAgICBsZW5ndGgobGVuLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQXJyYXkoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBleGFjdExlbmd0aDogeyB2YWx1ZTogbGVuLCBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkgfQogICAgICB9KTsKICAgIH0KICAgIG5vbmVtcHR5KG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMubWluKDEsIG1lc3NhZ2UpOwogICAgfQogIH0KICBab2RBcnJheS5jcmVhdGUgPSAoc2NoZW1hLCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kQXJyYXkoewogICAgICB0eXBlOiBzY2hlbWEsCiAgICAgIG1pbkxlbmd0aDogbnVsbCwKICAgICAgbWF4TGVuZ3RoOiBudWxsLAogICAgICBleGFjdExlbmd0aDogbnVsbCwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RBcnJheSwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGZ1bmN0aW9uIGRlZXBQYXJ0aWFsaWZ5KHNjaGVtYSkgewogICAgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZE9iamVjdCkgewogICAgICBjb25zdCBuZXdTaGFwZSA9IHt9OwogICAgICBmb3IgKGNvbnN0IGtleSBpbiBzY2hlbWEuc2hhcGUpIHsKICAgICAgICBjb25zdCBmaWVsZFNjaGVtYSA9IHNjaGVtYS5zaGFwZVtrZXldOwogICAgICAgIG5ld1NoYXBlW2tleV0gPSBab2RPcHRpb25hbC5jcmVhdGUoZGVlcFBhcnRpYWxpZnkoZmllbGRTY2hlbWEpKTsKICAgICAgfQogICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgICAgLi4uc2NoZW1hLl9kZWYsCiAgICAgICAgc2hhcGU6ICgpID0+IG5ld1NoYXBlCiAgICAgIH0pOwogICAgfSBlbHNlIGlmIChzY2hlbWEgaW5zdGFuY2VvZiBab2RBcnJheSkgewogICAgICByZXR1cm4gbmV3IFpvZEFycmF5KHsKICAgICAgICAuLi5zY2hlbWEuX2RlZiwKICAgICAgICB0eXBlOiBkZWVwUGFydGlhbGlmeShzY2hlbWEuZWxlbWVudCkKICAgICAgfSk7CiAgICB9IGVsc2UgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZE9wdGlvbmFsKSB7CiAgICAgIHJldHVybiBab2RPcHRpb25hbC5jcmVhdGUoZGVlcFBhcnRpYWxpZnkoc2NoZW1hLnVud3JhcCgpKSk7CiAgICB9IGVsc2UgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZE51bGxhYmxlKSB7CiAgICAgIHJldHVybiBab2ROdWxsYWJsZS5jcmVhdGUoZGVlcFBhcnRpYWxpZnkoc2NoZW1hLnVud3JhcCgpKSk7CiAgICB9IGVsc2UgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZFR1cGxlKSB7CiAgICAgIHJldHVybiBab2RUdXBsZS5jcmVhdGUoc2NoZW1hLml0ZW1zLm1hcCgoaXRlbSkgPT4gZGVlcFBhcnRpYWxpZnkoaXRlbSkpKTsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiBzY2hlbWE7CiAgICB9CiAgfQogIGNsYXNzIFpvZE9iamVjdCBleHRlbmRzIFpvZFR5cGUgewogICAgY29uc3RydWN0b3IoKSB7CiAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7CiAgICAgIHRoaXMuX2NhY2hlZCA9IG51bGw7CiAgICAgIHRoaXMubm9uc3RyaWN0ID0gdGhpcy5wYXNzdGhyb3VnaDsKICAgICAgdGhpcy5hdWdtZW50ID0gdGhpcy5leHRlbmQ7CiAgICB9CiAgICBfZ2V0Q2FjaGVkKCkgewogICAgICBpZiAodGhpcy5fY2FjaGVkICE9PSBudWxsKQogICAgICAgIHJldHVybiB0aGlzLl9jYWNoZWQ7CiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5fZGVmLnNoYXBlKCk7CiAgICAgIGNvbnN0IGtleXMgPSB1dGlsLm9iamVjdEtleXMoc2hhcGUpOwogICAgICByZXR1cm4gdGhpcy5fY2FjaGVkID0geyBzaGFwZSwga2V5cyB9OwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTsKICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUub2JqZWN0KSB7CiAgICAgICAgY29uc3QgY3R4MiA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgyLCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUub2JqZWN0LAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eDIucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IHsgc3RhdHVzLCBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7CiAgICAgIGNvbnN0IHsgc2hhcGUsIGtleXM6IHNoYXBlS2V5cyB9ID0gdGhpcy5fZ2V0Q2FjaGVkKCk7CiAgICAgIGNvbnN0IGV4dHJhS2V5cyA9IFtdOwogICAgICBpZiAoISh0aGlzLl9kZWYuY2F0Y2hhbGwgaW5zdGFuY2VvZiBab2ROZXZlciAmJiB0aGlzLl9kZWYudW5rbm93bktleXMgPT09ICJzdHJpcCIpKSB7CiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gY3R4LmRhdGEpIHsKICAgICAgICAgIGlmICghc2hhcGVLZXlzLmluY2x1ZGVzKGtleSkpIHsKICAgICAgICAgICAgZXh0cmFLZXlzLnB1c2goa2V5KTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgY29uc3QgcGFpcnMgPSBbXTsKICAgICAgZm9yIChjb25zdCBrZXkgb2Ygc2hhcGVLZXlzKSB7CiAgICAgICAgY29uc3Qga2V5VmFsaWRhdG9yID0gc2hhcGVba2V5XTsKICAgICAgICBjb25zdCB2YWx1ZSA9IGN0eC5kYXRhW2tleV07CiAgICAgICAgcGFpcnMucHVzaCh7CiAgICAgICAgICBrZXk6IHsgc3RhdHVzOiAidmFsaWQiLCB2YWx1ZToga2V5IH0sCiAgICAgICAgICB2YWx1ZToga2V5VmFsaWRhdG9yLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgdmFsdWUsIGN0eC5wYXRoLCBrZXkpKSwKICAgICAgICAgIGFsd2F5c1NldDoga2V5IGluIGN0eC5kYXRhCiAgICAgICAgfSk7CiAgICAgIH0KICAgICAgaWYgKHRoaXMuX2RlZi5jYXRjaGFsbCBpbnN0YW5jZW9mIFpvZE5ldmVyKSB7CiAgICAgICAgY29uc3QgdW5rbm93bktleXMgPSB0aGlzLl9kZWYudW5rbm93bktleXM7CiAgICAgICAgaWYgKHVua25vd25LZXlzID09PSAicGFzc3Rocm91Z2giKSB7CiAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBleHRyYUtleXMpIHsKICAgICAgICAgICAgcGFpcnMucHVzaCh7CiAgICAgICAgICAgICAga2V5OiB7IHN0YXR1czogInZhbGlkIiwgdmFsdWU6IGtleSB9LAogICAgICAgICAgICAgIHZhbHVlOiB7IHN0YXR1czogInZhbGlkIiwgdmFsdWU6IGN0eC5kYXRhW2tleV0gfQogICAgICAgICAgICB9KTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKHVua25vd25LZXlzID09PSAic3RyaWN0IikgewogICAgICAgICAgaWYgKGV4dHJhS2V5cy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS51bnJlY29nbml6ZWRfa2V5cywKICAgICAgICAgICAgICBrZXlzOiBleHRyYUtleXMKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAodW5rbm93bktleXMgPT09ICJzdHJpcCIpIDsKICAgICAgICBlbHNlIHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW50ZXJuYWwgWm9kT2JqZWN0IGVycm9yOiBpbnZhbGlkIHVua25vd25LZXlzIHZhbHVlLmApOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBjb25zdCBjYXRjaGFsbCA9IHRoaXMuX2RlZi5jYXRjaGFsbDsKICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBleHRyYUtleXMpIHsKICAgICAgICAgIGNvbnN0IHZhbHVlID0gY3R4LmRhdGFba2V5XTsKICAgICAgICAgIHBhaXJzLnB1c2goewogICAgICAgICAgICBrZXk6IHsgc3RhdHVzOiAidmFsaWQiLCB2YWx1ZToga2V5IH0sCiAgICAgICAgICAgIHZhbHVlOiBjYXRjaGFsbC5fcGFyc2UoCiAgICAgICAgICAgICAgbmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIHZhbHVlLCBjdHgucGF0aCwga2V5KQogICAgICAgICAgICAgIC8vLCBjdHguY2hpbGQoa2V5KSwgdmFsdWUsIGdldFBhcnNlZFR5cGUodmFsdWUpCiAgICAgICAgICAgICksCiAgICAgICAgICAgIGFsd2F5c1NldDoga2V5IGluIGN0eC5kYXRhCiAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihhc3luYyAoKSA9PiB7CiAgICAgICAgICBjb25zdCBzeW5jUGFpcnMgPSBbXTsKICAgICAgICAgIGZvciAoY29uc3QgcGFpciBvZiBwYWlycykgewogICAgICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBwYWlyLmtleTsKICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCBwYWlyLnZhbHVlOwogICAgICAgICAgICBzeW5jUGFpcnMucHVzaCh7CiAgICAgICAgICAgICAga2V5LAogICAgICAgICAgICAgIHZhbHVlLAogICAgICAgICAgICAgIGFsd2F5c1NldDogcGFpci5hbHdheXNTZXQKICAgICAgICAgICAgfSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gc3luY1BhaXJzOwogICAgICAgIH0pLnRoZW4oKHN5bmNQYWlycykgPT4gewogICAgICAgICAgcmV0dXJuIFBhcnNlU3RhdHVzLm1lcmdlT2JqZWN0U3luYyhzdGF0dXMsIHN5bmNQYWlycyk7CiAgICAgICAgfSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIFBhcnNlU3RhdHVzLm1lcmdlT2JqZWN0U3luYyhzdGF0dXMsIHBhaXJzKTsKICAgICAgfQogICAgfQogICAgZ2V0IHNoYXBlKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLnNoYXBlKCk7CiAgICB9CiAgICBzdHJpY3QobWVzc2FnZSkgewogICAgICBlcnJvclV0aWwuZXJyVG9PYmo7CiAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgdW5rbm93bktleXM6ICJzdHJpY3QiLAogICAgICAgIC4uLm1lc3NhZ2UgIT09IHZvaWQgMCA/IHsKICAgICAgICAgIGVycm9yTWFwOiAoaXNzdWUsIGN0eCkgPT4gewogICAgICAgICAgICB2YXIgX2EsIF9iLCBfYywgX2Q7CiAgICAgICAgICAgIGNvbnN0IGRlZmF1bHRFcnJvciA9IChfYyA9IChfYiA9IChfYSA9IHRoaXMuX2RlZikuZXJyb3JNYXApID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5jYWxsKF9hLCBpc3N1ZSwgY3R4KS5tZXNzYWdlKSAhPT0gbnVsbCAmJiBfYyAhPT0gdm9pZCAwID8gX2MgOiBjdHguZGVmYXVsdEVycm9yOwogICAgICAgICAgICBpZiAoaXNzdWUuY29kZSA9PT0gInVucmVjb2duaXplZF9rZXlzIikKICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgbWVzc2FnZTogKF9kID0gZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpLm1lc3NhZ2UpICE9PSBudWxsICYmIF9kICE9PSB2b2lkIDAgPyBfZCA6IGRlZmF1bHRFcnJvcgogICAgICAgICAgICAgIH07CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgbWVzc2FnZTogZGVmYXVsdEVycm9yCiAgICAgICAgICAgIH07CiAgICAgICAgICB9CiAgICAgICAgfSA6IHt9CiAgICAgIH0pOwogICAgfQogICAgc3RyaXAoKSB7CiAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgdW5rbm93bktleXM6ICJzdHJpcCIKICAgICAgfSk7CiAgICB9CiAgICBwYXNzdGhyb3VnaCgpIHsKICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3QoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICB1bmtub3duS2V5czogInBhc3N0aHJvdWdoIgogICAgICB9KTsKICAgIH0KICAgIC8vIGNvbnN0IEF1Z21lbnRGYWN0b3J5ID0KICAgIC8vICAgPERlZiBleHRlbmRzIFpvZE9iamVjdERlZj4oZGVmOiBEZWYpID0+CiAgICAvLyAgIDxBdWdtZW50YXRpb24gZXh0ZW5kcyBab2RSYXdTaGFwZT4oCiAgICAvLyAgICAgYXVnbWVudGF0aW9uOiBBdWdtZW50YXRpb24KICAgIC8vICAgKTogWm9kT2JqZWN0PAogICAgLy8gICAgIGV4dGVuZFNoYXBlPFJldHVyblR5cGU8RGVmWyJzaGFwZSJdPiwgQXVnbWVudGF0aW9uPiwKICAgIC8vICAgICBEZWZbInVua25vd25LZXlzIl0sCiAgICAvLyAgICAgRGVmWyJjYXRjaGFsbCJdCiAgICAvLyAgID4gPT4gewogICAgLy8gICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgIC8vICAgICAgIC4uLmRlZiwKICAgIC8vICAgICAgIHNoYXBlOiAoKSA9PiAoewogICAgLy8gICAgICAgICAuLi5kZWYuc2hhcGUoKSwKICAgIC8vICAgICAgICAgLi4uYXVnbWVudGF0aW9uLAogICAgLy8gICAgICAgfSksCiAgICAvLyAgICAgfSkgYXMgYW55OwogICAgLy8gICB9OwogICAgZXh0ZW5kKGF1Z21lbnRhdGlvbikgewogICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIHNoYXBlOiAoKSA9PiAoewogICAgICAgICAgLi4udGhpcy5fZGVmLnNoYXBlKCksCiAgICAgICAgICAuLi5hdWdtZW50YXRpb24KICAgICAgICB9KQogICAgICB9KTsKICAgIH0KICAgIC8qKgogICAgICogUHJpb3IgdG8gem9kQDEuMC4xMiB0aGVyZSB3YXMgYSBidWcgaW4gdGhlCiAgICAgKiBpbmZlcnJlZCB0eXBlIG9mIG1lcmdlZCBvYmplY3RzLiBQbGVhc2UKICAgICAqIHVwZ3JhZGUgaWYgeW91IGFyZSBleHBlcmllbmNpbmcgaXNzdWVzLgogICAgICovCiAgICBtZXJnZShtZXJnaW5nKSB7CiAgICAgIGNvbnN0IG1lcmdlZCA9IG5ldyBab2RPYmplY3QoewogICAgICAgIHVua25vd25LZXlzOiBtZXJnaW5nLl9kZWYudW5rbm93bktleXMsCiAgICAgICAgY2F0Y2hhbGw6IG1lcmdpbmcuX2RlZi5jYXRjaGFsbCwKICAgICAgICBzaGFwZTogKCkgPT4gKHsKICAgICAgICAgIC4uLnRoaXMuX2RlZi5zaGFwZSgpLAogICAgICAgICAgLi4ubWVyZ2luZy5fZGVmLnNoYXBlKCkKICAgICAgICB9KSwKICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9iamVjdAogICAgICB9KTsKICAgICAgcmV0dXJuIG1lcmdlZDsKICAgIH0KICAgIC8vIG1lcmdlPAogICAgLy8gICBJbmNvbWluZyBleHRlbmRzIEFueVpvZE9iamVjdCwKICAgIC8vICAgQXVnbWVudGF0aW9uIGV4dGVuZHMgSW5jb21pbmdbInNoYXBlIl0sCiAgICAvLyAgIE5ld091dHB1dCBleHRlbmRzIHsKICAgIC8vICAgICBbayBpbiBrZXlvZiBBdWdtZW50YXRpb24gfCBrZXlvZiBPdXRwdXRdOiBrIGV4dGVuZHMga2V5b2YgQXVnbWVudGF0aW9uCiAgICAvLyAgICAgICA/IEF1Z21lbnRhdGlvbltrXVsiX291dHB1dCJdCiAgICAvLyAgICAgICA6IGsgZXh0ZW5kcyBrZXlvZiBPdXRwdXQKICAgIC8vICAgICAgID8gT3V0cHV0W2tdCiAgICAvLyAgICAgICA6IG5ldmVyOwogICAgLy8gICB9LAogICAgLy8gICBOZXdJbnB1dCBleHRlbmRzIHsKICAgIC8vICAgICBbayBpbiBrZXlvZiBBdWdtZW50YXRpb24gfCBrZXlvZiBJbnB1dF06IGsgZXh0ZW5kcyBrZXlvZiBBdWdtZW50YXRpb24KICAgIC8vICAgICAgID8gQXVnbWVudGF0aW9uW2tdWyJfaW5wdXQiXQogICAgLy8gICAgICAgOiBrIGV4dGVuZHMga2V5b2YgSW5wdXQKICAgIC8vICAgICAgID8gSW5wdXRba10KICAgIC8vICAgICAgIDogbmV2ZXI7CiAgICAvLyAgIH0KICAgIC8vID4oCiAgICAvLyAgIG1lcmdpbmc6IEluY29taW5nCiAgICAvLyApOiBab2RPYmplY3Q8CiAgICAvLyAgIGV4dGVuZFNoYXBlPFQsIFJldHVyblR5cGU8SW5jb21pbmdbIl9kZWYiXVsic2hhcGUiXT4+LAogICAgLy8gICBJbmNvbWluZ1siX2RlZiJdWyJ1bmtub3duS2V5cyJdLAogICAgLy8gICBJbmNvbWluZ1siX2RlZiJdWyJjYXRjaGFsbCJdLAogICAgLy8gICBOZXdPdXRwdXQsCiAgICAvLyAgIE5ld0lucHV0CiAgICAvLyA+IHsKICAgIC8vICAgY29uc3QgbWVyZ2VkOiBhbnkgPSBuZXcgWm9kT2JqZWN0KHsKICAgIC8vICAgICB1bmtub3duS2V5czogbWVyZ2luZy5fZGVmLnVua25vd25LZXlzLAogICAgLy8gICAgIGNhdGNoYWxsOiBtZXJnaW5nLl9kZWYuY2F0Y2hhbGwsCiAgICAvLyAgICAgc2hhcGU6ICgpID0+CiAgICAvLyAgICAgICBvYmplY3RVdGlsLm1lcmdlU2hhcGVzKHRoaXMuX2RlZi5zaGFwZSgpLCBtZXJnaW5nLl9kZWYuc2hhcGUoKSksCiAgICAvLyAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPYmplY3QsCiAgICAvLyAgIH0pIGFzIGFueTsKICAgIC8vICAgcmV0dXJuIG1lcmdlZDsKICAgIC8vIH0KICAgIHNldEtleShrZXksIHNjaGVtYSkgewogICAgICByZXR1cm4gdGhpcy5hdWdtZW50KHsgW2tleV06IHNjaGVtYSB9KTsKICAgIH0KICAgIC8vIG1lcmdlPEluY29taW5nIGV4dGVuZHMgQW55Wm9kT2JqZWN0PigKICAgIC8vICAgbWVyZ2luZzogSW5jb21pbmcKICAgIC8vICk6IC8vWm9kT2JqZWN0PFQgJiBJbmNvbWluZ1siX3NoYXBlIl0sIFVua25vd25LZXlzLCBDYXRjaGFsbD4gPSAobWVyZ2luZykgPT4gewogICAgLy8gWm9kT2JqZWN0PAogICAgLy8gICBleHRlbmRTaGFwZTxULCBSZXR1cm5UeXBlPEluY29taW5nWyJfZGVmIl1bInNoYXBlIl0+PiwKICAgIC8vICAgSW5jb21pbmdbIl9kZWYiXVsidW5rbm93bktleXMiXSwKICAgIC8vICAgSW5jb21pbmdbIl9kZWYiXVsiY2F0Y2hhbGwiXQogICAgLy8gPiB7CiAgICAvLyAgIC8vIGNvbnN0IG1lcmdlZFNoYXBlID0gb2JqZWN0VXRpbC5tZXJnZVNoYXBlcygKICAgIC8vICAgLy8gICB0aGlzLl9kZWYuc2hhcGUoKSwKICAgIC8vICAgLy8gICBtZXJnaW5nLl9kZWYuc2hhcGUoKQogICAgLy8gICAvLyApOwogICAgLy8gICBjb25zdCBtZXJnZWQ6IGFueSA9IG5ldyBab2RPYmplY3QoewogICAgLy8gICAgIHVua25vd25LZXlzOiBtZXJnaW5nLl9kZWYudW5rbm93bktleXMsCiAgICAvLyAgICAgY2F0Y2hhbGw6IG1lcmdpbmcuX2RlZi5jYXRjaGFsbCwKICAgIC8vICAgICBzaGFwZTogKCkgPT4KICAgIC8vICAgICAgIG9iamVjdFV0aWwubWVyZ2VTaGFwZXModGhpcy5fZGVmLnNoYXBlKCksIG1lcmdpbmcuX2RlZi5zaGFwZSgpKSwKICAgIC8vICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9iamVjdCwKICAgIC8vICAgfSkgYXMgYW55OwogICAgLy8gICByZXR1cm4gbWVyZ2VkOwogICAgLy8gfQogICAgY2F0Y2hhbGwoaW5kZXgpIHsKICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3QoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBjYXRjaGFsbDogaW5kZXgKICAgICAgfSk7CiAgICB9CiAgICBwaWNrKG1hc2spIHsKICAgICAgY29uc3Qgc2hhcGUgPSB7fTsKICAgICAgdXRpbC5vYmplY3RLZXlzKG1hc2spLmZvckVhY2goKGtleSkgPT4gewogICAgICAgIGlmIChtYXNrW2tleV0gJiYgdGhpcy5zaGFwZVtrZXldKSB7CiAgICAgICAgICBzaGFwZVtrZXldID0gdGhpcy5zaGFwZVtrZXldOwogICAgICAgIH0KICAgICAgfSk7CiAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgc2hhcGU6ICgpID0+IHNoYXBlCiAgICAgIH0pOwogICAgfQogICAgb21pdChtYXNrKSB7CiAgICAgIGNvbnN0IHNoYXBlID0ge307CiAgICAgIHV0aWwub2JqZWN0S2V5cyh0aGlzLnNoYXBlKS5mb3JFYWNoKChrZXkpID0+IHsKICAgICAgICBpZiAoIW1hc2tba2V5XSkgewogICAgICAgICAgc2hhcGVba2V5XSA9IHRoaXMuc2hhcGVba2V5XTsKICAgICAgICB9CiAgICAgIH0pOwogICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIHNoYXBlOiAoKSA9PiBzaGFwZQogICAgICB9KTsKICAgIH0KICAgIC8qKgogICAgICogQGRlcHJlY2F0ZWQKICAgICAqLwogICAgZGVlcFBhcnRpYWwoKSB7CiAgICAgIHJldHVybiBkZWVwUGFydGlhbGlmeSh0aGlzKTsKICAgIH0KICAgIHBhcnRpYWwobWFzaykgewogICAgICBjb25zdCBuZXdTaGFwZSA9IHt9OwogICAgICB1dGlsLm9iamVjdEtleXModGhpcy5zaGFwZSkuZm9yRWFjaCgoa2V5KSA9PiB7CiAgICAgICAgY29uc3QgZmllbGRTY2hlbWEgPSB0aGlzLnNoYXBlW2tleV07CiAgICAgICAgaWYgKG1hc2sgJiYgIW1hc2tba2V5XSkgewogICAgICAgICAgbmV3U2hhcGVba2V5XSA9IGZpZWxkU2NoZW1hOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBuZXdTaGFwZVtrZXldID0gZmllbGRTY2hlbWEub3B0aW9uYWwoKTsKICAgICAgICB9CiAgICAgIH0pOwogICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIHNoYXBlOiAoKSA9PiBuZXdTaGFwZQogICAgICB9KTsKICAgIH0KICAgIHJlcXVpcmVkKG1hc2spIHsKICAgICAgY29uc3QgbmV3U2hhcGUgPSB7fTsKICAgICAgdXRpbC5vYmplY3RLZXlzKHRoaXMuc2hhcGUpLmZvckVhY2goKGtleSkgPT4gewogICAgICAgIGlmIChtYXNrICYmICFtYXNrW2tleV0pIHsKICAgICAgICAgIG5ld1NoYXBlW2tleV0gPSB0aGlzLnNoYXBlW2tleV07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNvbnN0IGZpZWxkU2NoZW1hID0gdGhpcy5zaGFwZVtrZXldOwogICAgICAgICAgbGV0IG5ld0ZpZWxkID0gZmllbGRTY2hlbWE7CiAgICAgICAgICB3aGlsZSAobmV3RmllbGQgaW5zdGFuY2VvZiBab2RPcHRpb25hbCkgewogICAgICAgICAgICBuZXdGaWVsZCA9IG5ld0ZpZWxkLl9kZWYuaW5uZXJUeXBlOwogICAgICAgICAgfQogICAgICAgICAgbmV3U2hhcGVba2V5XSA9IG5ld0ZpZWxkOwogICAgICAgIH0KICAgICAgfSk7CiAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgc2hhcGU6ICgpID0+IG5ld1NoYXBlCiAgICAgIH0pOwogICAgfQogICAga2V5b2YoKSB7CiAgICAgIHJldHVybiBjcmVhdGVab2RFbnVtKHV0aWwub2JqZWN0S2V5cyh0aGlzLnNoYXBlKSk7CiAgICB9CiAgfQogIFpvZE9iamVjdC5jcmVhdGUgPSAoc2hhcGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RPYmplY3QoewogICAgICBzaGFwZTogKCkgPT4gc2hhcGUsCiAgICAgIHVua25vd25LZXlzOiAic3RyaXAiLAogICAgICBjYXRjaGFsbDogWm9kTmV2ZXIuY3JlYXRlKCksCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT2JqZWN0LAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgWm9kT2JqZWN0LnN0cmljdENyZWF0ZSA9IChzaGFwZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgIHNoYXBlOiAoKSA9PiBzaGFwZSwKICAgICAgdW5rbm93bktleXM6ICJzdHJpY3QiLAogICAgICBjYXRjaGFsbDogWm9kTmV2ZXIuY3JlYXRlKCksCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT2JqZWN0LAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgWm9kT2JqZWN0LmxhenljcmVhdGUgPSAoc2hhcGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RPYmplY3QoewogICAgICBzaGFwZSwKICAgICAgdW5rbm93bktleXM6ICJzdHJpcCIsCiAgICAgIGNhdGNoYWxsOiBab2ROZXZlci5jcmVhdGUoKSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPYmplY3QsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RVbmlvbiBleHRlbmRzIFpvZFR5cGUgewogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5fZGVmLm9wdGlvbnM7CiAgICAgIGZ1bmN0aW9uIGhhbmRsZVJlc3VsdHMocmVzdWx0cykgewogICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHMpIHsKICAgICAgICAgIGlmIChyZXN1bHQucmVzdWx0LnN0YXR1cyA9PT0gInZhbGlkIikgewogICAgICAgICAgICByZXR1cm4gcmVzdWx0LnJlc3VsdDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChjb25zdCByZXN1bHQgb2YgcmVzdWx0cykgewogICAgICAgICAgaWYgKHJlc3VsdC5yZXN1bHQuc3RhdHVzID09PSAiZGlydHkiKSB7CiAgICAgICAgICAgIGN0eC5jb21tb24uaXNzdWVzLnB1c2goLi4ucmVzdWx0LmN0eC5jb21tb24uaXNzdWVzKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5yZXN1bHQ7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvbnN0IHVuaW9uRXJyb3JzID0gcmVzdWx0cy5tYXAoKHJlc3VsdCkgPT4gbmV3IFpvZEVycm9yKHJlc3VsdC5jdHguY29tbW9uLmlzc3VlcykpOwogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdW5pb24sCiAgICAgICAgICB1bmlvbkVycm9ycwogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKG9wdGlvbnMubWFwKGFzeW5jIChvcHRpb24pID0+IHsKICAgICAgICAgIGNvbnN0IGNoaWxkQ3R4ID0gewogICAgICAgICAgICAuLi5jdHgsCiAgICAgICAgICAgIGNvbW1vbjogewogICAgICAgICAgICAgIC4uLmN0eC5jb21tb24sCiAgICAgICAgICAgICAgaXNzdWVzOiBbXQogICAgICAgICAgICB9LAogICAgICAgICAgICBwYXJlbnQ6IG51bGwKICAgICAgICAgIH07CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICByZXN1bHQ6IGF3YWl0IG9wdGlvbi5fcGFyc2VBc3luYyh7CiAgICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgICAgICAgICAgcGFyZW50OiBjaGlsZEN0eAogICAgICAgICAgICB9KSwKICAgICAgICAgICAgY3R4OiBjaGlsZEN0eAogICAgICAgICAgfTsKICAgICAgICB9KSkudGhlbihoYW5kbGVSZXN1bHRzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBsZXQgZGlydHkgPSB2b2lkIDA7CiAgICAgICAgY29uc3QgaXNzdWVzID0gW107CiAgICAgICAgZm9yIChjb25zdCBvcHRpb24gb2Ygb3B0aW9ucykgewogICAgICAgICAgY29uc3QgY2hpbGRDdHggPSB7CiAgICAgICAgICAgIC4uLmN0eCwKICAgICAgICAgICAgY29tbW9uOiB7CiAgICAgICAgICAgICAgLi4uY3R4LmNvbW1vbiwKICAgICAgICAgICAgICBpc3N1ZXM6IFtdCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHBhcmVudDogbnVsbAogICAgICAgICAgfTsKICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IG9wdGlvbi5fcGFyc2VTeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGNoaWxkQ3R4CiAgICAgICAgICB9KTsKICAgICAgICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSAidmFsaWQiKSB7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdC5zdGF0dXMgPT09ICJkaXJ0eSIgJiYgIWRpcnR5KSB7CiAgICAgICAgICAgIGRpcnR5ID0geyByZXN1bHQsIGN0eDogY2hpbGRDdHggfTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChjaGlsZEN0eC5jb21tb24uaXNzdWVzLmxlbmd0aCkgewogICAgICAgICAgICBpc3N1ZXMucHVzaChjaGlsZEN0eC5jb21tb24uaXNzdWVzKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGRpcnR5KSB7CiAgICAgICAgICBjdHguY29tbW9uLmlzc3Vlcy5wdXNoKC4uLmRpcnR5LmN0eC5jb21tb24uaXNzdWVzKTsKICAgICAgICAgIHJldHVybiBkaXJ0eS5yZXN1bHQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHVuaW9uRXJyb3JzID0gaXNzdWVzLm1hcCgoaXNzdWVzMikgPT4gbmV3IFpvZEVycm9yKGlzc3VlczIpKTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3VuaW9uLAogICAgICAgICAgdW5pb25FcnJvcnMKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgfQogICAgZ2V0IG9wdGlvbnMoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYub3B0aW9uczsKICAgIH0KICB9CiAgWm9kVW5pb24uY3JlYXRlID0gKHR5cGVzLCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kVW5pb24oewogICAgICBvcHRpb25zOiB0eXBlcywKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RVbmlvbiwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNvbnN0IGdldERpc2NyaW1pbmF0b3IgPSAodHlwZSkgPT4gewogICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RMYXp5KSB7CiAgICAgIHJldHVybiBnZXREaXNjcmltaW5hdG9yKHR5cGUuc2NoZW1hKTsKICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZEVmZmVjdHMpIHsKICAgICAgcmV0dXJuIGdldERpc2NyaW1pbmF0b3IodHlwZS5pbm5lclR5cGUoKSk7CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RMaXRlcmFsKSB7CiAgICAgIHJldHVybiBbdHlwZS52YWx1ZV07CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RFbnVtKSB7CiAgICAgIHJldHVybiB0eXBlLm9wdGlvbnM7CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2ROYXRpdmVFbnVtKSB7CiAgICAgIHJldHVybiB1dGlsLm9iamVjdFZhbHVlcyh0eXBlLmVudW0pOwogICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kRGVmYXVsdCkgewogICAgICByZXR1cm4gZ2V0RGlzY3JpbWluYXRvcih0eXBlLl9kZWYuaW5uZXJUeXBlKTsKICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZFVuZGVmaW5lZCkgewogICAgICByZXR1cm4gW3ZvaWQgMF07CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2ROdWxsKSB7CiAgICAgIHJldHVybiBbbnVsbF07CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RPcHRpb25hbCkgewogICAgICByZXR1cm4gW3ZvaWQgMCwgLi4uZ2V0RGlzY3JpbWluYXRvcih0eXBlLnVud3JhcCgpKV07CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2ROdWxsYWJsZSkgewogICAgICByZXR1cm4gW251bGwsIC4uLmdldERpc2NyaW1pbmF0b3IodHlwZS51bndyYXAoKSldOwogICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kQnJhbmRlZCkgewogICAgICByZXR1cm4gZ2V0RGlzY3JpbWluYXRvcih0eXBlLnVud3JhcCgpKTsKICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZFJlYWRvbmx5KSB7CiAgICAgIHJldHVybiBnZXREaXNjcmltaW5hdG9yKHR5cGUudW53cmFwKCkpOwogICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kQ2F0Y2gpIHsKICAgICAgcmV0dXJuIGdldERpc2NyaW1pbmF0b3IodHlwZS5fZGVmLmlubmVyVHlwZSk7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gW107CiAgICB9CiAgfTsKICBjbGFzcyBab2REaXNjcmltaW5hdGVkVW5pb24gZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm9iamVjdCkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm9iamVjdCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IGRpc2NyaW1pbmF0b3IgPSB0aGlzLmRpc2NyaW1pbmF0b3I7CiAgICAgIGNvbnN0IGRpc2NyaW1pbmF0b3JWYWx1ZSA9IGN0eC5kYXRhW2Rpc2NyaW1pbmF0b3JdOwogICAgICBjb25zdCBvcHRpb24gPSB0aGlzLm9wdGlvbnNNYXAuZ2V0KGRpc2NyaW1pbmF0b3JWYWx1ZSk7CiAgICAgIGlmICghb3B0aW9uKSB7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF91bmlvbl9kaXNjcmltaW5hdG9yLAogICAgICAgICAgb3B0aW9uczogQXJyYXkuZnJvbSh0aGlzLm9wdGlvbnNNYXAua2V5cygpKSwKICAgICAgICAgIHBhdGg6IFtkaXNjcmltaW5hdG9yXQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbi5fcGFyc2VBc3luYyh7CiAgICAgICAgICBkYXRhOiBjdHguZGF0YSwKICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgcGFyZW50OiBjdHgKICAgICAgICB9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gb3B0aW9uLl9wYXJzZVN5bmMoewogICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgIHBhcmVudDogY3R4CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KICAgIGdldCBkaXNjcmltaW5hdG9yKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmRpc2NyaW1pbmF0b3I7CiAgICB9CiAgICBnZXQgb3B0aW9ucygpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5vcHRpb25zOwogICAgfQogICAgZ2V0IG9wdGlvbnNNYXAoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYub3B0aW9uc01hcDsKICAgIH0KICAgIC8qKgogICAgICogVGhlIGNvbnN0cnVjdG9yIG9mIHRoZSBkaXNjcmltaW5hdGVkIHVuaW9uIHNjaGVtYS4gSXRzIGJlaGF2aW91ciBpcyB2ZXJ5IHNpbWlsYXIgdG8gdGhhdCBvZiB0aGUgbm9ybWFsIHoudW5pb24oKSBjb25zdHJ1Y3Rvci4KICAgICAqIEhvd2V2ZXIsIGl0IG9ubHkgYWxsb3dzIGEgdW5pb24gb2Ygb2JqZWN0cywgYWxsIG9mIHdoaWNoIG5lZWQgdG8gc2hhcmUgYSBkaXNjcmltaW5hdG9yIHByb3BlcnR5LiBUaGlzIHByb3BlcnR5IG11c3QKICAgICAqIGhhdmUgYSBkaWZmZXJlbnQgdmFsdWUgZm9yIGVhY2ggb2JqZWN0IGluIHRoZSB1bmlvbi4KICAgICAqIEBwYXJhbSBkaXNjcmltaW5hdG9yIHRoZSBuYW1lIG9mIHRoZSBkaXNjcmltaW5hdG9yIHByb3BlcnR5CiAgICAgKiBAcGFyYW0gdHlwZXMgYW4gYXJyYXkgb2Ygb2JqZWN0IHNjaGVtYXMKICAgICAqIEBwYXJhbSBwYXJhbXMKICAgICAqLwogICAgc3RhdGljIGNyZWF0ZShkaXNjcmltaW5hdG9yLCBvcHRpb25zLCBwYXJhbXMpIHsKICAgICAgY29uc3Qgb3B0aW9uc01hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgIGZvciAoY29uc3QgdHlwZSBvZiBvcHRpb25zKSB7CiAgICAgICAgY29uc3QgZGlzY3JpbWluYXRvclZhbHVlcyA9IGdldERpc2NyaW1pbmF0b3IodHlwZS5zaGFwZVtkaXNjcmltaW5hdG9yXSk7CiAgICAgICAgaWYgKCFkaXNjcmltaW5hdG9yVmFsdWVzLmxlbmd0aCkgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBBIGRpc2NyaW1pbmF0b3IgdmFsdWUgZm9yIGtleSBcYCR7ZGlzY3JpbWluYXRvcn1cYCBjb3VsZCBub3QgYmUgZXh0cmFjdGVkIGZyb20gYWxsIHNjaGVtYSBvcHRpb25zYCk7CiAgICAgICAgfQogICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgZGlzY3JpbWluYXRvclZhbHVlcykgewogICAgICAgICAgaWYgKG9wdGlvbnNNYXAuaGFzKHZhbHVlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYERpc2NyaW1pbmF0b3IgcHJvcGVydHkgJHtTdHJpbmcoZGlzY3JpbWluYXRvcil9IGhhcyBkdXBsaWNhdGUgdmFsdWUgJHtTdHJpbmcodmFsdWUpfWApOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uc01hcC5zZXQodmFsdWUsIHR5cGUpOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gbmV3IFpvZERpc2NyaW1pbmF0ZWRVbmlvbih7CiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2REaXNjcmltaW5hdGVkVW5pb24sCiAgICAgICAgZGlzY3JpbWluYXRvciwKICAgICAgICBvcHRpb25zLAogICAgICAgIG9wdGlvbnNNYXAsCiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICAgIH0pOwogICAgfQogIH0KICBmdW5jdGlvbiBtZXJnZVZhbHVlcyhhMiwgYikgewogICAgY29uc3QgYVR5cGUgPSBnZXRQYXJzZWRUeXBlKGEyKTsKICAgIGNvbnN0IGJUeXBlID0gZ2V0UGFyc2VkVHlwZShiKTsKICAgIGlmIChhMiA9PT0gYikgewogICAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgZGF0YTogYTIgfTsKICAgIH0gZWxzZSBpZiAoYVR5cGUgPT09IFpvZFBhcnNlZFR5cGUub2JqZWN0ICYmIGJUeXBlID09PSBab2RQYXJzZWRUeXBlLm9iamVjdCkgewogICAgICBjb25zdCBiS2V5cyA9IHV0aWwub2JqZWN0S2V5cyhiKTsKICAgICAgY29uc3Qgc2hhcmVkS2V5cyA9IHV0aWwub2JqZWN0S2V5cyhhMikuZmlsdGVyKChrZXkpID0+IGJLZXlzLmluZGV4T2Yoa2V5KSAhPT0gLTEpOwogICAgICBjb25zdCBuZXdPYmogPSB7IC4uLmEyLCAuLi5iIH07CiAgICAgIGZvciAoY29uc3Qga2V5IG9mIHNoYXJlZEtleXMpIHsKICAgICAgICBjb25zdCBzaGFyZWRWYWx1ZSA9IG1lcmdlVmFsdWVzKGEyW2tleV0sIGJba2V5XSk7CiAgICAgICAgaWYgKCFzaGFyZWRWYWx1ZS52YWxpZCkgewogICAgICAgICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlIH07CiAgICAgICAgfQogICAgICAgIG5ld09ialtrZXldID0gc2hhcmVkVmFsdWUuZGF0YTsKICAgICAgfQogICAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgZGF0YTogbmV3T2JqIH07CiAgICB9IGVsc2UgaWYgKGFUeXBlID09PSBab2RQYXJzZWRUeXBlLmFycmF5ICYmIGJUeXBlID09PSBab2RQYXJzZWRUeXBlLmFycmF5KSB7CiAgICAgIGlmIChhMi5sZW5ndGggIT09IGIubGVuZ3RoKSB7CiAgICAgICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlIH07CiAgICAgIH0KICAgICAgY29uc3QgbmV3QXJyYXkgPSBbXTsKICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGEyLmxlbmd0aDsgaW5kZXgrKykgewogICAgICAgIGNvbnN0IGl0ZW1BID0gYTJbaW5kZXhdOwogICAgICAgIGNvbnN0IGl0ZW1CID0gYltpbmRleF07CiAgICAgICAgY29uc3Qgc2hhcmVkVmFsdWUgPSBtZXJnZVZhbHVlcyhpdGVtQSwgaXRlbUIpOwogICAgICAgIGlmICghc2hhcmVkVmFsdWUudmFsaWQpIHsKICAgICAgICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSB9OwogICAgICAgIH0KICAgICAgICBuZXdBcnJheS5wdXNoKHNoYXJlZFZhbHVlLmRhdGEpOwogICAgICB9CiAgICAgIHJldHVybiB7IHZhbGlkOiB0cnVlLCBkYXRhOiBuZXdBcnJheSB9OwogICAgfSBlbHNlIGlmIChhVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5kYXRlICYmIGJUeXBlID09PSBab2RQYXJzZWRUeXBlLmRhdGUgJiYgK2EyID09PSArYikgewogICAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgZGF0YTogYTIgfTsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSB9OwogICAgfQogIH0KICBjbGFzcyBab2RJbnRlcnNlY3Rpb24gZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBjb25zdCBoYW5kbGVQYXJzZWQgPSAocGFyc2VkTGVmdCwgcGFyc2VkUmlnaHQpID0+IHsKICAgICAgICBpZiAoaXNBYm9ydGVkKHBhcnNlZExlZnQpIHx8IGlzQWJvcnRlZChwYXJzZWRSaWdodCkpIHsKICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgIH0KICAgICAgICBjb25zdCBtZXJnZWQgPSBtZXJnZVZhbHVlcyhwYXJzZWRMZWZ0LnZhbHVlLCBwYXJzZWRSaWdodC52YWx1ZSk7CiAgICAgICAgaWYgKCFtZXJnZWQudmFsaWQpIHsKICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9pbnRlcnNlY3Rpb25fdHlwZXMKICAgICAgICAgIH0pOwogICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgfQogICAgICAgIGlmIChpc0RpcnR5KHBhcnNlZExlZnQpIHx8IGlzRGlydHkocGFyc2VkUmlnaHQpKSB7CiAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBtZXJnZWQuZGF0YSB9OwogICAgICB9OwogICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykgewogICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbCiAgICAgICAgICB0aGlzLl9kZWYubGVmdC5fcGFyc2VBc3luYyh7CiAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLAogICAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgICAgcGFyZW50OiBjdHgKICAgICAgICAgIH0pLAogICAgICAgICAgdGhpcy5fZGVmLnJpZ2h0Ll9wYXJzZUFzeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgfSkKICAgICAgICBdKS50aGVuKChbbGVmdCwgcmlnaHRdKSA9PiBoYW5kbGVQYXJzZWQobGVmdCwgcmlnaHQpKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gaGFuZGxlUGFyc2VkKHRoaXMuX2RlZi5sZWZ0Ll9wYXJzZVN5bmMoewogICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgIHBhcmVudDogY3R4CiAgICAgICAgfSksIHRoaXMuX2RlZi5yaWdodC5fcGFyc2VTeW5jKHsKICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLAogICAgICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgIH0pKTsKICAgICAgfQogICAgfQogIH0KICBab2RJbnRlcnNlY3Rpb24uY3JlYXRlID0gKGxlZnQsIHJpZ2h0LCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kSW50ZXJzZWN0aW9uKHsKICAgICAgbGVmdCwKICAgICAgcmlnaHQsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kSW50ZXJzZWN0aW9uLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kVHVwbGUgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuYXJyYXkpIHsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsCiAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5hcnJheSwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmIChjdHguZGF0YS5sZW5ndGggPCB0aGlzLl9kZWYuaXRlbXMubGVuZ3RoKSB7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLAogICAgICAgICAgbWluaW11bTogdGhpcy5fZGVmLml0ZW1zLmxlbmd0aCwKICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgIHR5cGU6ICJhcnJheSIKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICBjb25zdCByZXN0ID0gdGhpcy5fZGVmLnJlc3Q7CiAgICAgIGlmICghcmVzdCAmJiBjdHguZGF0YS5sZW5ndGggPiB0aGlzLl9kZWYuaXRlbXMubGVuZ3RoKSB7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZywKICAgICAgICAgIG1heGltdW06IHRoaXMuX2RlZi5pdGVtcy5sZW5ndGgsCiAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgICBleGFjdDogZmFsc2UsCiAgICAgICAgICB0eXBlOiAiYXJyYXkiCiAgICAgICAgfSk7CiAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgIH0KICAgICAgY29uc3QgaXRlbXMgPSBbLi4uY3R4LmRhdGFdLm1hcCgoaXRlbSwgaXRlbUluZGV4KSA9PiB7CiAgICAgICAgY29uc3Qgc2NoZW1hID0gdGhpcy5fZGVmLml0ZW1zW2l0ZW1JbmRleF0gfHwgdGhpcy5fZGVmLnJlc3Q7CiAgICAgICAgaWYgKCFzY2hlbWEpCiAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICByZXR1cm4gc2NoZW1hLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgaXRlbSwgY3R4LnBhdGgsIGl0ZW1JbmRleCkpOwogICAgICB9KS5maWx0ZXIoKHgpID0+ICEheCk7CiAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKGl0ZW1zKS50aGVuKChyZXN1bHRzKSA9PiB7CiAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIHJlc3VsdHMpOwogICAgICAgIH0pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZUFycmF5KHN0YXR1cywgaXRlbXMpOwogICAgICB9CiAgICB9CiAgICBnZXQgaXRlbXMoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYuaXRlbXM7CiAgICB9CiAgICByZXN0KHJlc3QpIHsKICAgICAgcmV0dXJuIG5ldyBab2RUdXBsZSh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIHJlc3QKICAgICAgfSk7CiAgICB9CiAgfQogIFpvZFR1cGxlLmNyZWF0ZSA9IChzY2hlbWFzLCBwYXJhbXMpID0+IHsKICAgIGlmICghQXJyYXkuaXNBcnJheShzY2hlbWFzKSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoIllvdSBtdXN0IHBhc3MgYW4gYXJyYXkgb2Ygc2NoZW1hcyB0byB6LnR1cGxlKFsgLi4uIF0pIik7CiAgICB9CiAgICByZXR1cm4gbmV3IFpvZFR1cGxlKHsKICAgICAgaXRlbXM6IHNjaGVtYXMsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kVHVwbGUsCiAgICAgIHJlc3Q6IG51bGwsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RSZWNvcmQgZXh0ZW5kcyBab2RUeXBlIHsKICAgIGdldCBrZXlTY2hlbWEoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYua2V5VHlwZTsKICAgIH0KICAgIGdldCB2YWx1ZVNjaGVtYSgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZVR5cGU7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm9iamVjdCkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm9iamVjdCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IHBhaXJzID0gW107CiAgICAgIGNvbnN0IGtleVR5cGUgPSB0aGlzLl9kZWYua2V5VHlwZTsKICAgICAgY29uc3QgdmFsdWVUeXBlID0gdGhpcy5fZGVmLnZhbHVlVHlwZTsKICAgICAgZm9yIChjb25zdCBrZXkgaW4gY3R4LmRhdGEpIHsKICAgICAgICBwYWlycy5wdXNoKHsKICAgICAgICAgIGtleToga2V5VHlwZS5fcGFyc2UobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGtleSwgY3R4LnBhdGgsIGtleSkpLAogICAgICAgICAgdmFsdWU6IHZhbHVlVHlwZS5fcGFyc2UobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGN0eC5kYXRhW2tleV0sIGN0eC5wYXRoLCBrZXkpKSwKICAgICAgICAgIGFsd2F5c1NldDoga2V5IGluIGN0eC5kYXRhCiAgICAgICAgfSk7CiAgICAgIH0KICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHsKICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VPYmplY3RBc3luYyhzdGF0dXMsIHBhaXJzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VPYmplY3RTeW5jKHN0YXR1cywgcGFpcnMpOwogICAgICB9CiAgICB9CiAgICBnZXQgZWxlbWVudCgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZVR5cGU7CiAgICB9CiAgICBzdGF0aWMgY3JlYXRlKGZpcnN0LCBzZWNvbmQsIHRoaXJkKSB7CiAgICAgIGlmIChzZWNvbmQgaW5zdGFuY2VvZiBab2RUeXBlKSB7CiAgICAgICAgcmV0dXJuIG5ldyBab2RSZWNvcmQoewogICAgICAgICAga2V5VHlwZTogZmlyc3QsCiAgICAgICAgICB2YWx1ZVR5cGU6IHNlY29uZCwKICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kUmVjb3JkLAogICAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyh0aGlyZCkKICAgICAgICB9KTsKICAgICAgfQogICAgICByZXR1cm4gbmV3IFpvZFJlY29yZCh7CiAgICAgICAga2V5VHlwZTogWm9kU3RyaW5nLmNyZWF0ZSgpLAogICAgICAgIHZhbHVlVHlwZTogZmlyc3QsCiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RSZWNvcmQsCiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhzZWNvbmQpCiAgICAgIH0pOwogICAgfQogIH0KICBjbGFzcyBab2RNYXAgZXh0ZW5kcyBab2RUeXBlIHsKICAgIGdldCBrZXlTY2hlbWEoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYua2V5VHlwZTsKICAgIH0KICAgIGdldCB2YWx1ZVNjaGVtYSgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZVR5cGU7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm1hcCkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm1hcCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IGtleVR5cGUgPSB0aGlzLl9kZWYua2V5VHlwZTsKICAgICAgY29uc3QgdmFsdWVUeXBlID0gdGhpcy5fZGVmLnZhbHVlVHlwZTsKICAgICAgY29uc3QgcGFpcnMgPSBbLi4uY3R4LmRhdGEuZW50cmllcygpXS5tYXAoKFtrZXksIHZhbHVlXSwgaW5kZXgpID0+IHsKICAgICAgICByZXR1cm4gewogICAgICAgICAga2V5OiBrZXlUeXBlLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwga2V5LCBjdHgucGF0aCwgW2luZGV4LCAia2V5Il0pKSwKICAgICAgICAgIHZhbHVlOiB2YWx1ZVR5cGUuX3BhcnNlKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCB2YWx1ZSwgY3R4LnBhdGgsIFtpbmRleCwgInZhbHVlIl0pKQogICAgICAgIH07CiAgICAgIH0pOwogICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykgewogICAgICAgIGNvbnN0IGZpbmFsTWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihhc3luYyAoKSA9PiB7CiAgICAgICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpIHsKICAgICAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgcGFpci5rZXk7CiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gYXdhaXQgcGFpci52YWx1ZTsKICAgICAgICAgICAgaWYgKGtleS5zdGF0dXMgPT09ICJhYm9ydGVkIiB8fCB2YWx1ZS5zdGF0dXMgPT09ICJhYm9ydGVkIikgewogICAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSAiZGlydHkiIHx8IHZhbHVlLnN0YXR1cyA9PT0gImRpcnR5IikgewogICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZpbmFsTWFwLnNldChrZXkudmFsdWUsIHZhbHVlLnZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB7IHN0YXR1czogc3RhdHVzLnZhbHVlLCB2YWx1ZTogZmluYWxNYXAgfTsKICAgICAgICB9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb25zdCBmaW5hbE1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgICAgZm9yIChjb25zdCBwYWlyIG9mIHBhaXJzKSB7CiAgICAgICAgICBjb25zdCBrZXkgPSBwYWlyLmtleTsKICAgICAgICAgIGNvbnN0IHZhbHVlID0gcGFpci52YWx1ZTsKICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSAiYWJvcnRlZCIgfHwgdmFsdWUuc3RhdHVzID09PSAiYWJvcnRlZCIpIHsKICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoa2V5LnN0YXR1cyA9PT0gImRpcnR5IiB8fCB2YWx1ZS5zdGF0dXMgPT09ICJkaXJ0eSIpIHsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgICBmaW5hbE1hcC5zZXQoa2V5LnZhbHVlLCB2YWx1ZS52YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB7IHN0YXR1czogc3RhdHVzLnZhbHVlLCB2YWx1ZTogZmluYWxNYXAgfTsKICAgICAgfQogICAgfQogIH0KICBab2RNYXAuY3JlYXRlID0gKGtleVR5cGUsIHZhbHVlVHlwZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE1hcCh7CiAgICAgIHZhbHVlVHlwZSwKICAgICAga2V5VHlwZSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RNYXAsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RTZXQgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuc2V0KSB7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUuc2V0LAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgY29uc3QgZGVmID0gdGhpcy5fZGVmOwogICAgICBpZiAoZGVmLm1pblNpemUgIT09IG51bGwpIHsKICAgICAgICBpZiAoY3R4LmRhdGEuc2l6ZSA8IGRlZi5taW5TaXplLnZhbHVlKSB7CiAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19zbWFsbCwKICAgICAgICAgICAgbWluaW11bTogZGVmLm1pblNpemUudmFsdWUsCiAgICAgICAgICAgIHR5cGU6ICJzZXQiLAogICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgbWVzc2FnZTogZGVmLm1pblNpemUubWVzc2FnZQogICAgICAgICAgfSk7CiAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGRlZi5tYXhTaXplICE9PSBudWxsKSB7CiAgICAgICAgaWYgKGN0eC5kYXRhLnNpemUgPiBkZWYubWF4U2l6ZS52YWx1ZSkgewogICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fYmlnLAogICAgICAgICAgICBtYXhpbXVtOiBkZWYubWF4U2l6ZS52YWx1ZSwKICAgICAgICAgICAgdHlwZTogInNldCIsCiAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLAogICAgICAgICAgICBtZXNzYWdlOiBkZWYubWF4U2l6ZS5tZXNzYWdlCiAgICAgICAgICB9KTsKICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgIH0KICAgICAgfQogICAgICBjb25zdCB2YWx1ZVR5cGUgPSB0aGlzLl9kZWYudmFsdWVUeXBlOwogICAgICBmdW5jdGlvbiBmaW5hbGl6ZVNldChlbGVtZW50czIpIHsKICAgICAgICBjb25zdCBwYXJzZWRTZXQgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpOwogICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50czIpIHsKICAgICAgICAgIGlmIChlbGVtZW50LnN0YXR1cyA9PT0gImFib3J0ZWQiKQogICAgICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgICAgIGlmIChlbGVtZW50LnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICBwYXJzZWRTZXQuYWRkKGVsZW1lbnQudmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IHBhcnNlZFNldCB9OwogICAgICB9CiAgICAgIGNvbnN0IGVsZW1lbnRzID0gWy4uLmN0eC5kYXRhLnZhbHVlcygpXS5tYXAoKGl0ZW0sIGkyKSA9PiB2YWx1ZVR5cGUuX3BhcnNlKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCBpdGVtLCBjdHgucGF0aCwgaTIpKSk7CiAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKGVsZW1lbnRzKS50aGVuKChlbGVtZW50czIpID0+IGZpbmFsaXplU2V0KGVsZW1lbnRzMikpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBmaW5hbGl6ZVNldChlbGVtZW50cyk7CiAgICAgIH0KICAgIH0KICAgIG1pbihtaW5TaXplLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kU2V0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgbWluU2l6ZTogeyB2YWx1ZTogbWluU2l6ZSwgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpIH0KICAgICAgfSk7CiAgICB9CiAgICBtYXgobWF4U2l6ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gbmV3IFpvZFNldCh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIG1heFNpemU6IHsgdmFsdWU6IG1heFNpemUsIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSB9CiAgICAgIH0pOwogICAgfQogICAgc2l6ZShzaXplLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLm1pbihzaXplLCBtZXNzYWdlKS5tYXgoc2l6ZSwgbWVzc2FnZSk7CiAgICB9CiAgICBub25lbXB0eShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLm1pbigxLCBtZXNzYWdlKTsKICAgIH0KICB9CiAgWm9kU2V0LmNyZWF0ZSA9ICh2YWx1ZVR5cGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RTZXQoewogICAgICB2YWx1ZVR5cGUsCiAgICAgIG1pblNpemU6IG51bGwsCiAgICAgIG1heFNpemU6IG51bGwsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU2V0LAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kRnVuY3Rpb24gZXh0ZW5kcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICBzdXBlciguLi5hcmd1bWVudHMpOwogICAgICB0aGlzLnZhbGlkYXRlID0gdGhpcy5pbXBsZW1lbnQ7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7CiAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5mdW5jdGlvbikgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmZ1bmN0aW9uLAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgZnVuY3Rpb24gbWFrZUFyZ3NJc3N1ZShhcmdzLCBlcnJvcikgewogICAgICAgIHJldHVybiBtYWtlSXNzdWUoewogICAgICAgICAgZGF0YTogYXJncywKICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgZXJyb3JNYXBzOiBbCiAgICAgICAgICAgIGN0eC5jb21tb24uY29udGV4dHVhbEVycm9yTWFwLAogICAgICAgICAgICBjdHguc2NoZW1hRXJyb3JNYXAsCiAgICAgICAgICAgIGdldEVycm9yTWFwKCksCiAgICAgICAgICAgIGVycm9yTWFwCiAgICAgICAgICBdLmZpbHRlcigoeCkgPT4gISF4KSwKICAgICAgICAgIGlzc3VlRGF0YTogewogICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9hcmd1bWVudHMsCiAgICAgICAgICAgIGFyZ3VtZW50c0Vycm9yOiBlcnJvcgogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICB9CiAgICAgIGZ1bmN0aW9uIG1ha2VSZXR1cm5zSXNzdWUocmV0dXJucywgZXJyb3IpIHsKICAgICAgICByZXR1cm4gbWFrZUlzc3VlKHsKICAgICAgICAgIGRhdGE6IHJldHVybnMsCiAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgIGVycm9yTWFwczogWwogICAgICAgICAgICBjdHguY29tbW9uLmNvbnRleHR1YWxFcnJvck1hcCwKICAgICAgICAgICAgY3R4LnNjaGVtYUVycm9yTWFwLAogICAgICAgICAgICBnZXRFcnJvck1hcCgpLAogICAgICAgICAgICBlcnJvck1hcAogICAgICAgICAgXS5maWx0ZXIoKHgpID0+ICEheCksCiAgICAgICAgICBpc3N1ZURhdGE6IHsKICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfcmV0dXJuX3R5cGUsCiAgICAgICAgICAgIHJldHVyblR5cGVFcnJvcjogZXJyb3IKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgfQogICAgICBjb25zdCBwYXJhbXMgPSB7IGVycm9yTWFwOiBjdHguY29tbW9uLmNvbnRleHR1YWxFcnJvck1hcCB9OwogICAgICBjb25zdCBmbiA9IGN0eC5kYXRhOwogICAgICBpZiAodGhpcy5fZGVmLnJldHVybnMgaW5zdGFuY2VvZiBab2RQcm9taXNlKSB7CiAgICAgICAgY29uc3QgbWUgPSB0aGlzOwogICAgICAgIHJldHVybiBPSyhhc3luYyBmdW5jdGlvbiguLi5hcmdzKSB7CiAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBab2RFcnJvcihbXSk7CiAgICAgICAgICBjb25zdCBwYXJzZWRBcmdzID0gYXdhaXQgbWUuX2RlZi5hcmdzLnBhcnNlQXN5bmMoYXJncywgcGFyYW1zKS5jYXRjaCgoZTIpID0+IHsKICAgICAgICAgICAgZXJyb3IuYWRkSXNzdWUobWFrZUFyZ3NJc3N1ZShhcmdzLCBlMikpOwogICAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICAgIH0pOwogICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUmVmbGVjdC5hcHBseShmbiwgdGhpcywgcGFyc2VkQXJncyk7CiAgICAgICAgICBjb25zdCBwYXJzZWRSZXR1cm5zID0gYXdhaXQgbWUuX2RlZi5yZXR1cm5zLl9kZWYudHlwZS5wYXJzZUFzeW5jKHJlc3VsdCwgcGFyYW1zKS5jYXRjaCgoZTIpID0+IHsKICAgICAgICAgICAgZXJyb3IuYWRkSXNzdWUobWFrZVJldHVybnNJc3N1ZShyZXN1bHQsIGUyKSk7CiAgICAgICAgICAgIHRocm93IGVycm9yOwogICAgICAgICAgfSk7CiAgICAgICAgICByZXR1cm4gcGFyc2VkUmV0dXJuczsKICAgICAgICB9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb25zdCBtZSA9IHRoaXM7CiAgICAgICAgcmV0dXJuIE9LKGZ1bmN0aW9uKC4uLmFyZ3MpIHsKICAgICAgICAgIGNvbnN0IHBhcnNlZEFyZ3MgPSBtZS5fZGVmLmFyZ3Muc2FmZVBhcnNlKGFyZ3MsIHBhcmFtcyk7CiAgICAgICAgICBpZiAoIXBhcnNlZEFyZ3Muc3VjY2VzcykgewogICAgICAgICAgICB0aHJvdyBuZXcgWm9kRXJyb3IoW21ha2VBcmdzSXNzdWUoYXJncywgcGFyc2VkQXJncy5lcnJvcildKTsKICAgICAgICAgIH0KICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuYXBwbHkoZm4sIHRoaXMsIHBhcnNlZEFyZ3MuZGF0YSk7CiAgICAgICAgICBjb25zdCBwYXJzZWRSZXR1cm5zID0gbWUuX2RlZi5yZXR1cm5zLnNhZmVQYXJzZShyZXN1bHQsIHBhcmFtcyk7CiAgICAgICAgICBpZiAoIXBhcnNlZFJldHVybnMuc3VjY2VzcykgewogICAgICAgICAgICB0aHJvdyBuZXcgWm9kRXJyb3IoW21ha2VSZXR1cm5zSXNzdWUocmVzdWx0LCBwYXJzZWRSZXR1cm5zLmVycm9yKV0pOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHBhcnNlZFJldHVybnMuZGF0YTsKICAgICAgICB9KTsKICAgICAgfQogICAgfQogICAgcGFyYW1ldGVycygpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5hcmdzOwogICAgfQogICAgcmV0dXJuVHlwZSgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5yZXR1cm5zOwogICAgfQogICAgYXJncyguLi5pdGVtcykgewogICAgICByZXR1cm4gbmV3IFpvZEZ1bmN0aW9uKHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgYXJnczogWm9kVHVwbGUuY3JlYXRlKGl0ZW1zKS5yZXN0KFpvZFVua25vd24uY3JlYXRlKCkpCiAgICAgIH0pOwogICAgfQogICAgcmV0dXJucyhyZXR1cm5UeXBlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kRnVuY3Rpb24oewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICByZXR1cm5zOiByZXR1cm5UeXBlCiAgICAgIH0pOwogICAgfQogICAgaW1wbGVtZW50KGZ1bmMpIHsKICAgICAgY29uc3QgdmFsaWRhdGVkRnVuYyA9IHRoaXMucGFyc2UoZnVuYyk7CiAgICAgIHJldHVybiB2YWxpZGF0ZWRGdW5jOwogICAgfQogICAgc3RyaWN0SW1wbGVtZW50KGZ1bmMpIHsKICAgICAgY29uc3QgdmFsaWRhdGVkRnVuYyA9IHRoaXMucGFyc2UoZnVuYyk7CiAgICAgIHJldHVybiB2YWxpZGF0ZWRGdW5jOwogICAgfQogICAgc3RhdGljIGNyZWF0ZShhcmdzLCByZXR1cm5zLCBwYXJhbXMpIHsKICAgICAgcmV0dXJuIG5ldyBab2RGdW5jdGlvbih7CiAgICAgICAgYXJnczogYXJncyA/IGFyZ3MgOiBab2RUdXBsZS5jcmVhdGUoW10pLnJlc3QoWm9kVW5rbm93bi5jcmVhdGUoKSksCiAgICAgICAgcmV0dXJuczogcmV0dXJucyB8fCBab2RVbmtub3duLmNyZWF0ZSgpLAogICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRnVuY3Rpb24sCiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICAgIH0pOwogICAgfQogIH0KICBjbGFzcyBab2RMYXp5IGV4dGVuZHMgWm9kVHlwZSB7CiAgICBnZXQgc2NoZW1hKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmdldHRlcigpOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBjb25zdCBsYXp5U2NoZW1hID0gdGhpcy5fZGVmLmdldHRlcigpOwogICAgICByZXR1cm4gbGF6eVNjaGVtYS5fcGFyc2UoeyBkYXRhOiBjdHguZGF0YSwgcGF0aDogY3R4LnBhdGgsIHBhcmVudDogY3R4IH0pOwogICAgfQogIH0KICBab2RMYXp5LmNyZWF0ZSA9IChnZXR0ZXIsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RMYXp5KHsKICAgICAgZ2V0dGVyLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZExhenksCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RMaXRlcmFsIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgaWYgKGlucHV0LmRhdGEgIT09IHRoaXMuX2RlZi52YWx1ZSkgewogICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIHJlY2VpdmVkOiBjdHguZGF0YSwKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX2xpdGVyYWwsCiAgICAgICAgICBleHBlY3RlZDogdGhpcy5fZGVmLnZhbHVlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgcmV0dXJuIHsgc3RhdHVzOiAidmFsaWQiLCB2YWx1ZTogaW5wdXQuZGF0YSB9OwogICAgfQogICAgZ2V0IHZhbHVlKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLnZhbHVlOwogICAgfQogIH0KICBab2RMaXRlcmFsLmNyZWF0ZSA9ICh2YWx1ZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZExpdGVyYWwoewogICAgICB2YWx1ZSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RMaXRlcmFsLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgZnVuY3Rpb24gY3JlYXRlWm9kRW51bSh2YWx1ZXMsIHBhcmFtcykgewogICAgcmV0dXJuIG5ldyBab2RFbnVtKHsKICAgICAgdmFsdWVzLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVudW0sCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfQogIGNsYXNzIFpvZEVudW0gZXh0ZW5kcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICBzdXBlciguLi5hcmd1bWVudHMpOwogICAgICBfWm9kRW51bV9jYWNoZS5zZXQodGhpcywgdm9pZCAwKTsKICAgIH0KICAgIF9wYXJzZShpbnB1dCkgewogICAgICBpZiAodHlwZW9mIGlucHV0LmRhdGEgIT09ICJzdHJpbmciKSB7CiAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpOwogICAgICAgIGNvbnN0IGV4cGVjdGVkVmFsdWVzID0gdGhpcy5fZGVmLnZhbHVlczsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGV4cGVjdGVkOiB1dGlsLmpvaW5WYWx1ZXMoZXhwZWN0ZWRWYWx1ZXMpLAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlLAogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfWm9kRW51bV9jYWNoZSkpIHsKICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9ab2RFbnVtX2NhY2hlLCBuZXcgU2V0KHRoaXMuX2RlZi52YWx1ZXMpKTsKICAgICAgfQogICAgICBpZiAoIV9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1pvZEVudW1fY2FjaGUpLmhhcyhpbnB1dC5kYXRhKSkgewogICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBjb25zdCBleHBlY3RlZFZhbHVlcyA9IHRoaXMuX2RlZi52YWx1ZXM7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICByZWNlaXZlZDogY3R4LmRhdGEsCiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9lbnVtX3ZhbHVlLAogICAgICAgICAgb3B0aW9uczogZXhwZWN0ZWRWYWx1ZXMKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7CiAgICB9CiAgICBnZXQgb3B0aW9ucygpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZXM7CiAgICB9CiAgICBnZXQgZW51bSgpIHsKICAgICAgY29uc3QgZW51bVZhbHVlcyA9IHt9OwogICAgICBmb3IgKGNvbnN0IHZhbCBvZiB0aGlzLl9kZWYudmFsdWVzKSB7CiAgICAgICAgZW51bVZhbHVlc1t2YWxdID0gdmFsOwogICAgICB9CiAgICAgIHJldHVybiBlbnVtVmFsdWVzOwogICAgfQogICAgZ2V0IFZhbHVlcygpIHsKICAgICAgY29uc3QgZW51bVZhbHVlcyA9IHt9OwogICAgICBmb3IgKGNvbnN0IHZhbCBvZiB0aGlzLl9kZWYudmFsdWVzKSB7CiAgICAgICAgZW51bVZhbHVlc1t2YWxdID0gdmFsOwogICAgICB9CiAgICAgIHJldHVybiBlbnVtVmFsdWVzOwogICAgfQogICAgZ2V0IEVudW0oKSB7CiAgICAgIGNvbnN0IGVudW1WYWx1ZXMgPSB7fTsKICAgICAgZm9yIChjb25zdCB2YWwgb2YgdGhpcy5fZGVmLnZhbHVlcykgewogICAgICAgIGVudW1WYWx1ZXNbdmFsXSA9IHZhbDsKICAgICAgfQogICAgICByZXR1cm4gZW51bVZhbHVlczsKICAgIH0KICAgIGV4dHJhY3QodmFsdWVzLCBuZXdEZWYgPSB0aGlzLl9kZWYpIHsKICAgICAgcmV0dXJuIFpvZEVudW0uY3JlYXRlKHZhbHVlcywgewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICAuLi5uZXdEZWYKICAgICAgfSk7CiAgICB9CiAgICBleGNsdWRlKHZhbHVlcywgbmV3RGVmID0gdGhpcy5fZGVmKSB7CiAgICAgIHJldHVybiBab2RFbnVtLmNyZWF0ZSh0aGlzLm9wdGlvbnMuZmlsdGVyKChvcHQpID0+ICF2YWx1ZXMuaW5jbHVkZXMob3B0KSksIHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgLi4ubmV3RGVmCiAgICAgIH0pOwogICAgfQogIH0KICBfWm9kRW51bV9jYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOwogIFpvZEVudW0uY3JlYXRlID0gY3JlYXRlWm9kRW51bTsKICBjbGFzcyBab2ROYXRpdmVFbnVtIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTsKICAgICAgX1pvZE5hdGl2ZUVudW1fY2FjaGUuc2V0KHRoaXMsIHZvaWQgMCk7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgbmF0aXZlRW51bVZhbHVlcyA9IHV0aWwuZ2V0VmFsaWRFbnVtVmFsdWVzKHRoaXMuX2RlZi52YWx1ZXMpOwogICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5zdHJpbmcgJiYgY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUubnVtYmVyKSB7CiAgICAgICAgY29uc3QgZXhwZWN0ZWRWYWx1ZXMgPSB1dGlsLm9iamVjdFZhbHVlcyhuYXRpdmVFbnVtVmFsdWVzKTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGV4cGVjdGVkOiB1dGlsLmpvaW5WYWx1ZXMoZXhwZWN0ZWRWYWx1ZXMpLAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlLAogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfWm9kTmF0aXZlRW51bV9jYWNoZSkpIHsKICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9ab2ROYXRpdmVFbnVtX2NhY2hlLCBuZXcgU2V0KHV0aWwuZ2V0VmFsaWRFbnVtVmFsdWVzKHRoaXMuX2RlZi52YWx1ZXMpKSk7CiAgICAgIH0KICAgICAgaWYgKCFfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9ab2ROYXRpdmVFbnVtX2NhY2hlKS5oYXMoaW5wdXQuZGF0YSkpIHsKICAgICAgICBjb25zdCBleHBlY3RlZFZhbHVlcyA9IHV0aWwub2JqZWN0VmFsdWVzKG5hdGl2ZUVudW1WYWx1ZXMpOwogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5kYXRhLAogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfZW51bV92YWx1ZSwKICAgICAgICAgIG9wdGlvbnM6IGV4cGVjdGVkVmFsdWVzCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpOwogICAgfQogICAgZ2V0IGVudW0oKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYudmFsdWVzOwogICAgfQogIH0KICBfWm9kTmF0aXZlRW51bV9jYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOwogIFpvZE5hdGl2ZUVudW0uY3JlYXRlID0gKHZhbHVlcywgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE5hdGl2ZUVudW0oewogICAgICB2YWx1ZXMsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTmF0aXZlRW51bSwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZFByb21pc2UgZXh0ZW5kcyBab2RUeXBlIHsKICAgIHVud3JhcCgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi50eXBlOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUucHJvbWlzZSAmJiBjdHguY29tbW9uLmFzeW5jID09PSBmYWxzZSkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLnByb21pc2UsCiAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICBjb25zdCBwcm9taXNpZmllZCA9IGN0eC5wYXJzZWRUeXBlID09PSBab2RQYXJzZWRUeXBlLnByb21pc2UgPyBjdHguZGF0YSA6IFByb21pc2UucmVzb2x2ZShjdHguZGF0YSk7CiAgICAgIHJldHVybiBPSyhwcm9taXNpZmllZC50aGVuKChkYXRhKSA9PiB7CiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi50eXBlLnBhcnNlQXN5bmMoZGF0YSwgewogICAgICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgICAgICBlcnJvck1hcDogY3R4LmNvbW1vbi5jb250ZXh0dWFsRXJyb3JNYXAKICAgICAgICB9KTsKICAgICAgfSkpOwogICAgfQogIH0KICBab2RQcm9taXNlLmNyZWF0ZSA9IChzY2hlbWEsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RQcm9taXNlKHsKICAgICAgdHlwZTogc2NoZW1hLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFByb21pc2UsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RFZmZlY3RzIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBpbm5lclR5cGUoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYuc2NoZW1hOwogICAgfQogICAgc291cmNlVHlwZSgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5zY2hlbWEuX2RlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMgPyB0aGlzLl9kZWYuc2NoZW1hLnNvdXJjZVR5cGUoKSA6IHRoaXMuX2RlZi5zY2hlbWE7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgY29uc3QgZWZmZWN0ID0gdGhpcy5fZGVmLmVmZmVjdCB8fCBudWxsOwogICAgICBjb25zdCBjaGVja0N0eCA9IHsKICAgICAgICBhZGRJc3N1ZTogKGFyZykgPT4gewogICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCBhcmcpOwogICAgICAgICAgaWYgKGFyZy5mYXRhbCkgewogICAgICAgICAgICBzdGF0dXMuYWJvcnQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZ2V0IHBhdGgoKSB7CiAgICAgICAgICByZXR1cm4gY3R4LnBhdGg7CiAgICAgICAgfQogICAgICB9OwogICAgICBjaGVja0N0eC5hZGRJc3N1ZSA9IGNoZWNrQ3R4LmFkZElzc3VlLmJpbmQoY2hlY2tDdHgpOwogICAgICBpZiAoZWZmZWN0LnR5cGUgPT09ICJwcmVwcm9jZXNzIikgewogICAgICAgIGNvbnN0IHByb2Nlc3NlZCA9IGVmZmVjdC50cmFuc2Zvcm0oY3R4LmRhdGEsIGNoZWNrQ3R4KTsKICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykgewogICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShwcm9jZXNzZWQpLnRoZW4oYXN5bmMgKHByb2Nlc3NlZDIpID0+IHsKICAgICAgICAgICAgaWYgKHN0YXR1cy52YWx1ZSA9PT0gImFib3J0ZWQiKQogICAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLl9kZWYuc2NoZW1hLl9wYXJzZUFzeW5jKHsKICAgICAgICAgICAgICBkYXRhOiBwcm9jZXNzZWQyLAogICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICAgIHBhcmVudDogY3R4CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gImFib3J0ZWQiKQogICAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgICAgICByZXR1cm4gRElSVFkocmVzdWx0LnZhbHVlKTsKICAgICAgICAgICAgaWYgKHN0YXR1cy52YWx1ZSA9PT0gImRpcnR5IikKICAgICAgICAgICAgICByZXR1cm4gRElSVFkocmVzdWx0LnZhbHVlKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoc3RhdHVzLnZhbHVlID09PSAiYWJvcnRlZCIpCiAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VTeW5jKHsKICAgICAgICAgICAgZGF0YTogcHJvY2Vzc2VkLAogICAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgICAgcGFyZW50OiBjdHgKICAgICAgICAgIH0pOwogICAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09ICJhYm9ydGVkIikKICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgICAgcmV0dXJuIERJUlRZKHJlc3VsdC52YWx1ZSk7CiAgICAgICAgICBpZiAoc3RhdHVzLnZhbHVlID09PSAiZGlydHkiKQogICAgICAgICAgICByZXR1cm4gRElSVFkocmVzdWx0LnZhbHVlKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChlZmZlY3QudHlwZSA9PT0gInJlZmluZW1lbnQiKSB7CiAgICAgICAgY29uc3QgZXhlY3V0ZVJlZmluZW1lbnQgPSAoYWNjKSA9PiB7CiAgICAgICAgICBjb25zdCByZXN1bHQgPSBlZmZlY3QucmVmaW5lbWVudChhY2MsIGNoZWNrQ3R4KTsKICAgICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiQXN5bmMgcmVmaW5lbWVudCBlbmNvdW50ZXJlZCBkdXJpbmcgc3luY2hyb25vdXMgcGFyc2Ugb3BlcmF0aW9uLiBVc2UgLnBhcnNlQXN5bmMgaW5zdGVhZC4iKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBhY2M7CiAgICAgICAgfTsKICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYyA9PT0gZmFsc2UpIHsKICAgICAgICAgIGNvbnN0IGlubmVyID0gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VTeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgfSk7CiAgICAgICAgICBpZiAoaW5uZXIuc3RhdHVzID09PSAiYWJvcnRlZCIpCiAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgaWYgKGlubmVyLnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICBleGVjdXRlUmVmaW5lbWVudChpbm5lci52YWx1ZSk7CiAgICAgICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IGlubmVyLnZhbHVlIH07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiB0aGlzLl9kZWYuc2NoZW1hLl9wYXJzZUFzeW5jKHsgZGF0YTogY3R4LmRhdGEsIHBhdGg6IGN0eC5wYXRoLCBwYXJlbnQ6IGN0eCB9KS50aGVuKChpbm5lcikgPT4gewogICAgICAgICAgICBpZiAoaW5uZXIuc3RhdHVzID09PSAiYWJvcnRlZCIpCiAgICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgICAgIGlmIChpbm5lci5zdGF0dXMgPT09ICJkaXJ0eSIpCiAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICAgIHJldHVybiBleGVjdXRlUmVmaW5lbWVudChpbm5lci52YWx1ZSkudGhlbigoKSA9PiB7CiAgICAgICAgICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBpbm5lci52YWx1ZSB9OwogICAgICAgICAgICB9KTsKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoZWZmZWN0LnR5cGUgPT09ICJ0cmFuc2Zvcm0iKSB7CiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMgPT09IGZhbHNlKSB7CiAgICAgICAgICBjb25zdCBiYXNlID0gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VTeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgfSk7CiAgICAgICAgICBpZiAoIWlzVmFsaWQoYmFzZSkpCiAgICAgICAgICAgIHJldHVybiBiYXNlOwogICAgICAgICAgY29uc3QgcmVzdWx0ID0gZWZmZWN0LnRyYW5zZm9ybShiYXNlLnZhbHVlLCBjaGVja0N0eCk7CiAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEFzeW5jaHJvbm91cyB0cmFuc2Zvcm0gZW5jb3VudGVyZWQgZHVyaW5nIHN5bmNocm9ub3VzIHBhcnNlIG9wZXJhdGlvbi4gVXNlIC5wYXJzZUFzeW5jIGluc3RlYWQuYCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IHJlc3VsdCB9OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VBc3luYyh7IGRhdGE6IGN0eC5kYXRhLCBwYXRoOiBjdHgucGF0aCwgcGFyZW50OiBjdHggfSkudGhlbigoYmFzZSkgPT4gewogICAgICAgICAgICBpZiAoIWlzVmFsaWQoYmFzZSkpCiAgICAgICAgICAgICAgcmV0dXJuIGJhc2U7CiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZWZmZWN0LnRyYW5zZm9ybShiYXNlLnZhbHVlLCBjaGVja0N0eCkpLnRoZW4oKHJlc3VsdCkgPT4gKHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiByZXN1bHQgfSkpOwogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoZWZmZWN0KTsKICAgIH0KICB9CiAgWm9kRWZmZWN0cy5jcmVhdGUgPSAoc2NoZW1hLCBlZmZlY3QsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RFZmZlY3RzKHsKICAgICAgc2NoZW1hLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsCiAgICAgIGVmZmVjdCwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIFpvZEVmZmVjdHMuY3JlYXRlV2l0aFByZXByb2Nlc3MgPSAocHJlcHJvY2Vzcywgc2NoZW1hLCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kRWZmZWN0cyh7CiAgICAgIHNjaGVtYSwKICAgICAgZWZmZWN0OiB7IHR5cGU6ICJwcmVwcm9jZXNzIiwgdHJhbnNmb3JtOiBwcmVwcm9jZXNzIH0sCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRWZmZWN0cywKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZE9wdGlvbmFsIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpOwogICAgICBpZiAocGFyc2VkVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4gT0sodm9pZCAwKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZS5fcGFyc2UoaW5wdXQpOwogICAgfQogICAgdW53cmFwKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZTsKICAgIH0KICB9CiAgWm9kT3B0aW9uYWwuY3JlYXRlID0gKHR5cGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RPcHRpb25hbCh7CiAgICAgIGlubmVyVHlwZTogdHlwZSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPcHRpb25hbCwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZE51bGxhYmxlIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpOwogICAgICBpZiAocGFyc2VkVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5udWxsKSB7CiAgICAgICAgcmV0dXJuIE9LKG51bGwpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZShpbnB1dCk7CiAgICB9CiAgICB1bndyYXAoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlOwogICAgfQogIH0KICBab2ROdWxsYWJsZS5jcmVhdGUgPSAodHlwZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE51bGxhYmxlKHsKICAgICAgaW5uZXJUeXBlOiB0eXBlLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bGxhYmxlLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kRGVmYXVsdCBleHRlbmRzIFpvZFR5cGUgewogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBsZXQgZGF0YSA9IGN0eC5kYXRhOwogICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgPT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7CiAgICAgICAgZGF0YSA9IHRoaXMuX2RlZi5kZWZhdWx0VmFsdWUoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZS5fcGFyc2UoewogICAgICAgIGRhdGEsCiAgICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgICAgcGFyZW50OiBjdHgKICAgICAgfSk7CiAgICB9CiAgICByZW1vdmVEZWZhdWx0KCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZTsKICAgIH0KICB9CiAgWm9kRGVmYXVsdC5jcmVhdGUgPSAodHlwZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZERlZmF1bHQoewogICAgICBpbm5lclR5cGU6IHR5cGUsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRGVmYXVsdCwKICAgICAgZGVmYXVsdFZhbHVlOiB0eXBlb2YgcGFyYW1zLmRlZmF1bHQgPT09ICJmdW5jdGlvbiIgPyBwYXJhbXMuZGVmYXVsdCA6ICgpID0+IHBhcmFtcy5kZWZhdWx0LAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kQ2F0Y2ggZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgY29uc3QgbmV3Q3R4ID0gewogICAgICAgIC4uLmN0eCwKICAgICAgICBjb21tb246IHsKICAgICAgICAgIC4uLmN0eC5jb21tb24sCiAgICAgICAgICBpc3N1ZXM6IFtdCiAgICAgICAgfQogICAgICB9OwogICAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZSh7CiAgICAgICAgZGF0YTogbmV3Q3R4LmRhdGEsCiAgICAgICAgcGF0aDogbmV3Q3R4LnBhdGgsCiAgICAgICAgcGFyZW50OiB7CiAgICAgICAgICAuLi5uZXdDdHgKICAgICAgICB9CiAgICAgIH0pOwogICAgICBpZiAoaXNBc3luYyhyZXN1bHQpKSB7CiAgICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKChyZXN1bHQyKSA9PiB7CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICBzdGF0dXM6ICJ2YWxpZCIsCiAgICAgICAgICAgIHZhbHVlOiByZXN1bHQyLnN0YXR1cyA9PT0gInZhbGlkIiA/IHJlc3VsdDIudmFsdWUgOiB0aGlzLl9kZWYuY2F0Y2hWYWx1ZSh7CiAgICAgICAgICAgICAgZ2V0IGVycm9yKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBab2RFcnJvcihuZXdDdHguY29tbW9uLmlzc3Vlcyk7CiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICBpbnB1dDogbmV3Q3R4LmRhdGEKICAgICAgICAgICAgfSkKICAgICAgICAgIH07CiAgICAgICAgfSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIHN0YXR1czogInZhbGlkIiwKICAgICAgICAgIHZhbHVlOiByZXN1bHQuc3RhdHVzID09PSAidmFsaWQiID8gcmVzdWx0LnZhbHVlIDogdGhpcy5fZGVmLmNhdGNoVmFsdWUoewogICAgICAgICAgICBnZXQgZXJyb3IoKSB7CiAgICAgICAgICAgICAgcmV0dXJuIG5ldyBab2RFcnJvcihuZXdDdHguY29tbW9uLmlzc3Vlcyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGlucHV0OiBuZXdDdHguZGF0YQogICAgICAgICAgfSkKICAgICAgICB9OwogICAgICB9CiAgICB9CiAgICByZW1vdmVDYXRjaCgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5pbm5lclR5cGU7CiAgICB9CiAgfQogIFpvZENhdGNoLmNyZWF0ZSA9ICh0eXBlLCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kQ2F0Y2goewogICAgICBpbm5lclR5cGU6IHR5cGUsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQ2F0Y2gsCiAgICAgIGNhdGNoVmFsdWU6IHR5cGVvZiBwYXJhbXMuY2F0Y2ggPT09ICJmdW5jdGlvbiIgPyBwYXJhbXMuY2F0Y2ggOiAoKSA9PiBwYXJhbXMuY2F0Y2gsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2ROYU4gZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm5hbikgewogICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsCiAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5uYW4sCiAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICByZXR1cm4geyBzdGF0dXM6ICJ2YWxpZCIsIHZhbHVlOiBpbnB1dC5kYXRhIH07CiAgICB9CiAgfQogIFpvZE5hTi5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE5hTih7CiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTmFOLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY29uc3QgQlJBTkQgPSBTeW1ib2woInpvZF9icmFuZCIpOwogIGNsYXNzIFpvZEJyYW5kZWQgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgY29uc3QgZGF0YSA9IGN0eC5kYXRhOwogICAgICByZXR1cm4gdGhpcy5fZGVmLnR5cGUuX3BhcnNlKHsKICAgICAgICBkYXRhLAogICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgIHBhcmVudDogY3R4CiAgICAgIH0pOwogICAgfQogICAgdW53cmFwKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLnR5cGU7CiAgICB9CiAgfQogIGNsYXNzIFpvZFBpcGVsaW5lIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHsKICAgICAgICBjb25zdCBoYW5kbGVBc3luYyA9IGFzeW5jICgpID0+IHsKICAgICAgICAgIGNvbnN0IGluUmVzdWx0ID0gYXdhaXQgdGhpcy5fZGVmLmluLl9wYXJzZUFzeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgfSk7CiAgICAgICAgICBpZiAoaW5SZXN1bHQuc3RhdHVzID09PSAiYWJvcnRlZCIpCiAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgaWYgKGluUmVzdWx0LnN0YXR1cyA9PT0gImRpcnR5IikgewogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgICAgcmV0dXJuIERJUlRZKGluUmVzdWx0LnZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZWYub3V0Ll9wYXJzZUFzeW5jKHsKICAgICAgICAgICAgICBkYXRhOiBpblJlc3VsdC52YWx1ZSwKICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgICB9KTsKICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIHJldHVybiBoYW5kbGVBc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IGluUmVzdWx0ID0gdGhpcy5fZGVmLmluLl9wYXJzZVN5bmMoewogICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgIHBhcmVudDogY3R4CiAgICAgICAgfSk7CiAgICAgICAgaWYgKGluUmVzdWx0LnN0YXR1cyA9PT0gImFib3J0ZWQiKQogICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgaWYgKGluUmVzdWx0LnN0YXR1cyA9PT0gImRpcnR5IikgewogICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICBzdGF0dXM6ICJkaXJ0eSIsCiAgICAgICAgICAgIHZhbHVlOiBpblJlc3VsdC52YWx1ZQogICAgICAgICAgfTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5vdXQuX3BhcnNlU3luYyh7CiAgICAgICAgICAgIGRhdGE6IGluUmVzdWx0LnZhbHVlLAogICAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgICAgcGFyZW50OiBjdHgKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgc3RhdGljIGNyZWF0ZShhMiwgYikgewogICAgICByZXR1cm4gbmV3IFpvZFBpcGVsaW5lKHsKICAgICAgICBpbjogYTIsCiAgICAgICAgb3V0OiBiLAogICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kUGlwZWxpbmUKICAgICAgfSk7CiAgICB9CiAgfQogIGNsYXNzIFpvZFJlYWRvbmx5IGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fZGVmLmlubmVyVHlwZS5fcGFyc2UoaW5wdXQpOwogICAgICBjb25zdCBmcmVlemUgPSAoZGF0YSkgPT4gewogICAgICAgIGlmIChpc1ZhbGlkKGRhdGEpKSB7CiAgICAgICAgICBkYXRhLnZhbHVlID0gT2JqZWN0LmZyZWV6ZShkYXRhLnZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGRhdGE7CiAgICAgIH07CiAgICAgIHJldHVybiBpc0FzeW5jKHJlc3VsdCkgPyByZXN1bHQudGhlbigoZGF0YSkgPT4gZnJlZXplKGRhdGEpKSA6IGZyZWV6ZShyZXN1bHQpOwogICAgfQogICAgdW53cmFwKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZTsKICAgIH0KICB9CiAgWm9kUmVhZG9ubHkuY3JlYXRlID0gKHR5cGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RSZWFkb25seSh7CiAgICAgIGlubmVyVHlwZTogdHlwZSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RSZWFkb25seSwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGZ1bmN0aW9uIGN1c3RvbShjaGVjaywgcGFyYW1zID0ge30sIGZhdGFsKSB7CiAgICBpZiAoY2hlY2spCiAgICAgIHJldHVybiBab2RBbnkuY3JlYXRlKCkuc3VwZXJSZWZpbmUoKGRhdGEsIGN0eCkgPT4gewogICAgICAgIHZhciBfYSwgX2I7CiAgICAgICAgaWYgKCFjaGVjayhkYXRhKSkgewogICAgICAgICAgY29uc3QgcCA9IHR5cGVvZiBwYXJhbXMgPT09ICJmdW5jdGlvbiIgPyBwYXJhbXMoZGF0YSkgOiB0eXBlb2YgcGFyYW1zID09PSAic3RyaW5nIiA/IHsgbWVzc2FnZTogcGFyYW1zIH0gOiBwYXJhbXM7CiAgICAgICAgICBjb25zdCBfZmF0YWwgPSAoX2IgPSAoX2EgPSBwLmZhdGFsKSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiBmYXRhbCkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogdHJ1ZTsKICAgICAgICAgIGNvbnN0IHAyID0gdHlwZW9mIHAgPT09ICJzdHJpbmciID8geyBtZXNzYWdlOiBwIH0gOiBwOwogICAgICAgICAgY3R4LmFkZElzc3VlKHsgY29kZTogImN1c3RvbSIsIC4uLnAyLCBmYXRhbDogX2ZhdGFsIH0pOwogICAgICAgIH0KICAgICAgfSk7CiAgICByZXR1cm4gWm9kQW55LmNyZWF0ZSgpOwogIH0KICBjb25zdCBsYXRlID0gewogICAgb2JqZWN0OiBab2RPYmplY3QubGF6eWNyZWF0ZQogIH07CiAgdmFyIFpvZEZpcnN0UGFydHlUeXBlS2luZDsKICAoZnVuY3Rpb24oWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMikgewogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kU3RyaW5nIl0gPSAiWm9kU3RyaW5nIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZE51bWJlciJdID0gIlpvZE51bWJlciI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2ROYU4iXSA9ICJab2ROYU4iOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kQmlnSW50Il0gPSAiWm9kQmlnSW50IjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZEJvb2xlYW4iXSA9ICJab2RCb29sZWFuIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZERhdGUiXSA9ICJab2REYXRlIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZFN5bWJvbCJdID0gIlpvZFN5bWJvbCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RVbmRlZmluZWQiXSA9ICJab2RVbmRlZmluZWQiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kTnVsbCJdID0gIlpvZE51bGwiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kQW55Il0gPSAiWm9kQW55IjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZFVua25vd24iXSA9ICJab2RVbmtub3duIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZE5ldmVyIl0gPSAiWm9kTmV2ZXIiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kVm9pZCJdID0gIlpvZFZvaWQiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kQXJyYXkiXSA9ICJab2RBcnJheSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RPYmplY3QiXSA9ICJab2RPYmplY3QiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kVW5pb24iXSA9ICJab2RVbmlvbiI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2REaXNjcmltaW5hdGVkVW5pb24iXSA9ICJab2REaXNjcmltaW5hdGVkVW5pb24iOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kSW50ZXJzZWN0aW9uIl0gPSAiWm9kSW50ZXJzZWN0aW9uIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZFR1cGxlIl0gPSAiWm9kVHVwbGUiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kUmVjb3JkIl0gPSAiWm9kUmVjb3JkIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZE1hcCJdID0gIlpvZE1hcCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RTZXQiXSA9ICJab2RTZXQiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kRnVuY3Rpb24iXSA9ICJab2RGdW5jdGlvbiI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RMYXp5Il0gPSAiWm9kTGF6eSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RMaXRlcmFsIl0gPSAiWm9kTGl0ZXJhbCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RFbnVtIl0gPSAiWm9kRW51bSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RFZmZlY3RzIl0gPSAiWm9kRWZmZWN0cyI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2ROYXRpdmVFbnVtIl0gPSAiWm9kTmF0aXZlRW51bSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RPcHRpb25hbCJdID0gIlpvZE9wdGlvbmFsIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZE51bGxhYmxlIl0gPSAiWm9kTnVsbGFibGUiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kRGVmYXVsdCJdID0gIlpvZERlZmF1bHQiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kQ2F0Y2giXSA9ICJab2RDYXRjaCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RQcm9taXNlIl0gPSAiWm9kUHJvbWlzZSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RCcmFuZGVkIl0gPSAiWm9kQnJhbmRlZCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RQaXBlbGluZSJdID0gIlpvZFBpcGVsaW5lIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZFJlYWRvbmx5Il0gPSAiWm9kUmVhZG9ubHkiOwogIH0pKFpvZEZpcnN0UGFydHlUeXBlS2luZCB8fCAoWm9kRmlyc3RQYXJ0eVR5cGVLaW5kID0ge30pKTsKICBjb25zdCBpbnN0YW5jZU9mVHlwZSA9IChjbHMsIHBhcmFtcyA9IHsKICAgIG1lc3NhZ2U6IGBJbnB1dCBub3QgaW5zdGFuY2Ugb2YgJHtjbHMubmFtZX1gCiAgfSkgPT4gY3VzdG9tKChkYXRhKSA9PiBkYXRhIGluc3RhbmNlb2YgY2xzLCBwYXJhbXMpOwogIGNvbnN0IHN0cmluZ1R5cGUgPSBab2RTdHJpbmcuY3JlYXRlOwogIGNvbnN0IG51bWJlclR5cGUgPSBab2ROdW1iZXIuY3JlYXRlOwogIGNvbnN0IG5hblR5cGUgPSBab2ROYU4uY3JlYXRlOwogIGNvbnN0IGJpZ0ludFR5cGUgPSBab2RCaWdJbnQuY3JlYXRlOwogIGNvbnN0IGJvb2xlYW5UeXBlID0gWm9kQm9vbGVhbi5jcmVhdGU7CiAgY29uc3QgZGF0ZVR5cGUgPSBab2REYXRlLmNyZWF0ZTsKICBjb25zdCBzeW1ib2xUeXBlID0gWm9kU3ltYm9sLmNyZWF0ZTsKICBjb25zdCB1bmRlZmluZWRUeXBlID0gWm9kVW5kZWZpbmVkLmNyZWF0ZTsKICBjb25zdCBudWxsVHlwZSA9IFpvZE51bGwuY3JlYXRlOwogIGNvbnN0IGFueVR5cGUgPSBab2RBbnkuY3JlYXRlOwogIGNvbnN0IHVua25vd25UeXBlID0gWm9kVW5rbm93bi5jcmVhdGU7CiAgY29uc3QgbmV2ZXJUeXBlID0gWm9kTmV2ZXIuY3JlYXRlOwogIGNvbnN0IHZvaWRUeXBlID0gWm9kVm9pZC5jcmVhdGU7CiAgY29uc3QgYXJyYXlUeXBlID0gWm9kQXJyYXkuY3JlYXRlOwogIGNvbnN0IG9iamVjdFR5cGUgPSBab2RPYmplY3QuY3JlYXRlOwogIGNvbnN0IHN0cmljdE9iamVjdFR5cGUgPSBab2RPYmplY3Quc3RyaWN0Q3JlYXRlOwogIGNvbnN0IHVuaW9uVHlwZSA9IFpvZFVuaW9uLmNyZWF0ZTsKICBjb25zdCBkaXNjcmltaW5hdGVkVW5pb25UeXBlID0gWm9kRGlzY3JpbWluYXRlZFVuaW9uLmNyZWF0ZTsKICBjb25zdCBpbnRlcnNlY3Rpb25UeXBlID0gWm9kSW50ZXJzZWN0aW9uLmNyZWF0ZTsKICBjb25zdCB0dXBsZVR5cGUgPSBab2RUdXBsZS5jcmVhdGU7CiAgY29uc3QgcmVjb3JkVHlwZSA9IFpvZFJlY29yZC5jcmVhdGU7CiAgY29uc3QgbWFwVHlwZSA9IFpvZE1hcC5jcmVhdGU7CiAgY29uc3Qgc2V0VHlwZSA9IFpvZFNldC5jcmVhdGU7CiAgY29uc3QgZnVuY3Rpb25UeXBlID0gWm9kRnVuY3Rpb24uY3JlYXRlOwogIGNvbnN0IGxhenlUeXBlID0gWm9kTGF6eS5jcmVhdGU7CiAgY29uc3QgbGl0ZXJhbFR5cGUgPSBab2RMaXRlcmFsLmNyZWF0ZTsKICBjb25zdCBlbnVtVHlwZSA9IFpvZEVudW0uY3JlYXRlOwogIGNvbnN0IG5hdGl2ZUVudW1UeXBlID0gWm9kTmF0aXZlRW51bS5jcmVhdGU7CiAgY29uc3QgcHJvbWlzZVR5cGUgPSBab2RQcm9taXNlLmNyZWF0ZTsKICBjb25zdCBlZmZlY3RzVHlwZSA9IFpvZEVmZmVjdHMuY3JlYXRlOwogIGNvbnN0IG9wdGlvbmFsVHlwZSA9IFpvZE9wdGlvbmFsLmNyZWF0ZTsKICBjb25zdCBudWxsYWJsZVR5cGUgPSBab2ROdWxsYWJsZS5jcmVhdGU7CiAgY29uc3QgcHJlcHJvY2Vzc1R5cGUgPSBab2RFZmZlY3RzLmNyZWF0ZVdpdGhQcmVwcm9jZXNzOwogIGNvbnN0IHBpcGVsaW5lVHlwZSA9IFpvZFBpcGVsaW5lLmNyZWF0ZTsKICBjb25zdCBvc3RyaW5nID0gKCkgPT4gc3RyaW5nVHlwZSgpLm9wdGlvbmFsKCk7CiAgY29uc3Qgb251bWJlciA9ICgpID0+IG51bWJlclR5cGUoKS5vcHRpb25hbCgpOwogIGNvbnN0IG9ib29sZWFuID0gKCkgPT4gYm9vbGVhblR5cGUoKS5vcHRpb25hbCgpOwogIGNvbnN0IGNvZXJjZSA9IHsKICAgIHN0cmluZzogKGFyZykgPT4gWm9kU3RyaW5nLmNyZWF0ZSh7IC4uLmFyZywgY29lcmNlOiB0cnVlIH0pLAogICAgbnVtYmVyOiAoYXJnKSA9PiBab2ROdW1iZXIuY3JlYXRlKHsgLi4uYXJnLCBjb2VyY2U6IHRydWUgfSksCiAgICBib29sZWFuOiAoYXJnKSA9PiBab2RCb29sZWFuLmNyZWF0ZSh7CiAgICAgIC4uLmFyZywKICAgICAgY29lcmNlOiB0cnVlCiAgICB9KSwKICAgIGJpZ2ludDogKGFyZykgPT4gWm9kQmlnSW50LmNyZWF0ZSh7IC4uLmFyZywgY29lcmNlOiB0cnVlIH0pLAogICAgZGF0ZTogKGFyZykgPT4gWm9kRGF0ZS5jcmVhdGUoeyAuLi5hcmcsIGNvZXJjZTogdHJ1ZSB9KQogIH07CiAgY29uc3QgTkVWRVIgPSBJTlZBTElEOwogIHZhciB6JDEgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmZyZWV6ZSh7CiAgICBfX3Byb3RvX186IG51bGwsCiAgICBkZWZhdWx0RXJyb3JNYXA6IGVycm9yTWFwLAogICAgc2V0RXJyb3JNYXAsCiAgICBnZXRFcnJvck1hcCwKICAgIG1ha2VJc3N1ZSwKICAgIEVNUFRZX1BBVEgsCiAgICBhZGRJc3N1ZVRvQ29udGV4dCwKICAgIFBhcnNlU3RhdHVzLAogICAgSU5WQUxJRCwKICAgIERJUlRZLAogICAgT0ssCiAgICBpc0Fib3J0ZWQsCiAgICBpc0RpcnR5LAogICAgaXNWYWxpZCwKICAgIGlzQXN5bmMsCiAgICBnZXQgdXRpbCgpIHsKICAgICAgcmV0dXJuIHV0aWw7CiAgICB9LAogICAgZ2V0IG9iamVjdFV0aWwoKSB7CiAgICAgIHJldHVybiBvYmplY3RVdGlsOwogICAgfSwKICAgIFpvZFBhcnNlZFR5cGUsCiAgICBnZXRQYXJzZWRUeXBlLAogICAgWm9kVHlwZSwKICAgIGRhdGV0aW1lUmVnZXgsCiAgICBab2RTdHJpbmcsCiAgICBab2ROdW1iZXIsCiAgICBab2RCaWdJbnQsCiAgICBab2RCb29sZWFuLAogICAgWm9kRGF0ZSwKICAgIFpvZFN5bWJvbCwKICAgIFpvZFVuZGVmaW5lZCwKICAgIFpvZE51bGwsCiAgICBab2RBbnksCiAgICBab2RVbmtub3duLAogICAgWm9kTmV2ZXIsCiAgICBab2RWb2lkLAogICAgWm9kQXJyYXksCiAgICBab2RPYmplY3QsCiAgICBab2RVbmlvbiwKICAgIFpvZERpc2NyaW1pbmF0ZWRVbmlvbiwKICAgIFpvZEludGVyc2VjdGlvbiwKICAgIFpvZFR1cGxlLAogICAgWm9kUmVjb3JkLAogICAgWm9kTWFwLAogICAgWm9kU2V0LAogICAgWm9kRnVuY3Rpb24sCiAgICBab2RMYXp5LAogICAgWm9kTGl0ZXJhbCwKICAgIFpvZEVudW0sCiAgICBab2ROYXRpdmVFbnVtLAogICAgWm9kUHJvbWlzZSwKICAgIFpvZEVmZmVjdHMsCiAgICBab2RUcmFuc2Zvcm1lcjogWm9kRWZmZWN0cywKICAgIFpvZE9wdGlvbmFsLAogICAgWm9kTnVsbGFibGUsCiAgICBab2REZWZhdWx0LAogICAgWm9kQ2F0Y2gsCiAgICBab2ROYU4sCiAgICBCUkFORCwKICAgIFpvZEJyYW5kZWQsCiAgICBab2RQaXBlbGluZSwKICAgIFpvZFJlYWRvbmx5LAogICAgY3VzdG9tLAogICAgU2NoZW1hOiBab2RUeXBlLAogICAgWm9kU2NoZW1hOiBab2RUeXBlLAogICAgbGF0ZSwKICAgIGdldCBab2RGaXJzdFBhcnR5VHlwZUtpbmQoKSB7CiAgICAgIHJldHVybiBab2RGaXJzdFBhcnR5VHlwZUtpbmQ7CiAgICB9LAogICAgY29lcmNlLAogICAgYW55OiBhbnlUeXBlLAogICAgYXJyYXk6IGFycmF5VHlwZSwKICAgIGJpZ2ludDogYmlnSW50VHlwZSwKICAgIGJvb2xlYW46IGJvb2xlYW5UeXBlLAogICAgZGF0ZTogZGF0ZVR5cGUsCiAgICBkaXNjcmltaW5hdGVkVW5pb246IGRpc2NyaW1pbmF0ZWRVbmlvblR5cGUsCiAgICBlZmZlY3Q6IGVmZmVjdHNUeXBlLAogICAgImVudW0iOiBlbnVtVHlwZSwKICAgICJmdW5jdGlvbiI6IGZ1bmN0aW9uVHlwZSwKICAgICJpbnN0YW5jZW9mIjogaW5zdGFuY2VPZlR5cGUsCiAgICBpbnRlcnNlY3Rpb246IGludGVyc2VjdGlvblR5cGUsCiAgICBsYXp5OiBsYXp5VHlwZSwKICAgIGxpdGVyYWw6IGxpdGVyYWxUeXBlLAogICAgbWFwOiBtYXBUeXBlLAogICAgbmFuOiBuYW5UeXBlLAogICAgbmF0aXZlRW51bTogbmF0aXZlRW51bVR5cGUsCiAgICBuZXZlcjogbmV2ZXJUeXBlLAogICAgIm51bGwiOiBudWxsVHlwZSwKICAgIG51bGxhYmxlOiBudWxsYWJsZVR5cGUsCiAgICBudW1iZXI6IG51bWJlclR5cGUsCiAgICBvYmplY3Q6IG9iamVjdFR5cGUsCiAgICBvYm9vbGVhbiwKICAgIG9udW1iZXIsCiAgICBvcHRpb25hbDogb3B0aW9uYWxUeXBlLAogICAgb3N0cmluZywKICAgIHBpcGVsaW5lOiBwaXBlbGluZVR5cGUsCiAgICBwcmVwcm9jZXNzOiBwcmVwcm9jZXNzVHlwZSwKICAgIHByb21pc2U6IHByb21pc2VUeXBlLAogICAgcmVjb3JkOiByZWNvcmRUeXBlLAogICAgc2V0OiBzZXRUeXBlLAogICAgc3RyaWN0T2JqZWN0OiBzdHJpY3RPYmplY3RUeXBlLAogICAgc3RyaW5nOiBzdHJpbmdUeXBlLAogICAgc3ltYm9sOiBzeW1ib2xUeXBlLAogICAgdHJhbnNmb3JtZXI6IGVmZmVjdHNUeXBlLAogICAgdHVwbGU6IHR1cGxlVHlwZSwKICAgICJ1bmRlZmluZWQiOiB1bmRlZmluZWRUeXBlLAogICAgdW5pb246IHVuaW9uVHlwZSwKICAgIHVua25vd246IHVua25vd25UeXBlLAogICAgInZvaWQiOiB2b2lkVHlwZSwKICAgIE5FVkVSLAogICAgWm9kSXNzdWVDb2RlLAogICAgcXVvdGVsZXNzSnNvbiwKICAgIFpvZEVycm9yCiAgfSk7CiAgeiQxLm9iamVjdCh7CiAgICBudWNsZW90aWRlU2VxdWVuY2VzOiB6JDEuYXJyYXkoCiAgICAgIHokMS5vYmplY3QoewogICAgICAgIG5hbWU6IHokMS5zdHJpbmcoKSwKICAgICAgICBzZXF1ZW5jZTogeiQxLnN0cmluZygpCiAgICAgIH0pCiAgICApLAogICAgZ2VuZXM6IHokMS5hcnJheSgKICAgICAgeiQxLm9iamVjdCh7CiAgICAgICAgbmFtZTogeiQxLnN0cmluZygpLAogICAgICAgIHNlcXVlbmNlOiB6JDEuc3RyaW5nKCkKICAgICAgfSkKICAgICkKICB9KTsKICBjb25zdCBvcmRlckJ5VHlwZSA9IHokMS5lbnVtKFsiYXNjZW5kaW5nIiwgImRlc2NlbmRpbmciXSk7CiAgY29uc3Qgb3JkZXJCeSA9IHokMS5vYmplY3QoewogICAgZmllbGQ6IHokMS5zdHJpbmcoKSwKICAgIHR5cGU6IG9yZGVyQnlUeXBlCiAgfSk7CiAgY29uc3QgbGFwaXNCYXNlUmVxdWVzdCA9IHokMS5vYmplY3QoewogICAgbGltaXQ6IHokMS5udW1iZXIoKS5vcHRpb25hbCgpLAogICAgb2Zmc2V0OiB6JDEubnVtYmVyKCkub3B0aW9uYWwoKSwKICAgIGZpZWxkczogeiQxLmFycmF5KHokMS5zdHJpbmcoKSkub3B0aW9uYWwoKSwKICAgIG9yZGVyQnk6IHokMS5hcnJheShvcmRlckJ5KS5vcHRpb25hbCgpCiAgfSkuY2F0Y2hhbGwoeiQxLnVuaW9uKFt6JDEuYm9vbGVhbigpLCB6JDEudW5kZWZpbmVkKCksIHokMS5zdHJpbmcoKSwgeiQxLm51bWJlcigpLCB6JDEubnVsbCgpLCB6JDEuYXJyYXkoeiQxLnN0cmluZygpKV0pKTsKICBsYXBpc0Jhc2VSZXF1ZXN0LmV4dGVuZCh7IG1pblByb3BvcnRpb246IHokMS5udW1iZXIoKS5vcHRpb25hbCgpIH0pOwogIGNvbnN0IG11dGF0aW9uUHJvcG9ydGlvbkNvdW50ID0geiQxLm9iamVjdCh7CiAgICBtdXRhdGlvbjogeiQxLnN0cmluZygpLAogICAgcHJvcG9ydGlvbjogeiQxLm51bWJlcigpLAogICAgY291bnQ6IHokMS5udW1iZXIoKSwKICAgIHNlcXVlbmNlTmFtZTogeiQxLnVuaW9uKFt6JDEuc3RyaW5nKCksIHokMS5udWxsKCldKSwKICAgIG11dGF0aW9uRnJvbTogeiQxLnN0cmluZygpLAogICAgbXV0YXRpb25UbzogeiQxLnN0cmluZygpLAogICAgcG9zaXRpb246IHokMS5udW1iZXIoKQogIH0pOwogIGNvbnN0IG11dGF0aW9uc1Jlc3BvbnNlID0gbWFrZUxhcGlzUmVzcG9uc2UoeiQxLmFycmF5KG11dGF0aW9uUHJvcG9ydGlvbkNvdW50KSk7CiAgY29uc3QgaW5zZXJ0aW9uQ291bnQgPSB6JDEub2JqZWN0KHsKICAgIGluc2VydGlvbjogeiQxLnN0cmluZygpLAogICAgY291bnQ6IHokMS5udW1iZXIoKSwKICAgIGluc2VydGVkU3ltYm9sczogeiQxLnN0cmluZygpLAogICAgcG9zaXRpb246IHokMS5udW1iZXIoKSwKICAgIHNlcXVlbmNlTmFtZTogeiQxLnVuaW9uKFt6JDEuc3RyaW5nKCksIHokMS5udWxsKCldKQogIH0pOwogIG1ha2VMYXBpc1Jlc3BvbnNlKHokMS5hcnJheShpbnNlcnRpb25Db3VudCkpOwogIGNvbnN0IGFnZ3JlZ2F0ZWRJdGVtID0geiQxLm9iamVjdCh7IGNvdW50OiB6JDEubnVtYmVyKCkgfSkuY2F0Y2hhbGwoeiQxLnVuaW9uKFt6JDEuc3RyaW5nKCksIHokMS5udW1iZXIoKSwgeiQxLm51bGwoKV0pKTsKICBjb25zdCBhZ2dyZWdhdGVkUmVzcG9uc2UgPSBtYWtlTGFwaXNSZXNwb25zZSh6JDEuYXJyYXkoYWdncmVnYXRlZEl0ZW0pKTsKICBmdW5jdGlvbiBtYWtlTGFwaXNSZXNwb25zZShkYXRhKSB7CiAgICByZXR1cm4geiQxLm9iamVjdCh7CiAgICAgIGRhdGEKICAgIH0pOwogIH0KICBjb25zdCBwcm9ibGVtRGV0YWlsID0geiQxLm9iamVjdCh7CiAgICB0aXRsZTogeiQxLnN0cmluZygpLm9wdGlvbmFsKCksCiAgICBzdGF0dXM6IHokMS5udW1iZXIoKSwKICAgIGRldGFpbDogeiQxLnN0cmluZygpLm9wdGlvbmFsKCksCiAgICB0eXBlOiB6JDEuc3RyaW5nKCksCiAgICBpbnN0YW5jZTogeiQxLnN0cmluZygpLm9wdGlvbmFsKCkKICB9KTsKICBjb25zdCBsYXBpc0Vycm9yID0geiQxLm9iamVjdCh7CiAgICBlcnJvcjogcHJvYmxlbURldGFpbAogIH0pOwogIGNsYXNzIFVua25vd25MYXBpc0Vycm9yIGV4dGVuZHMgRXJyb3IgewogICAgY29uc3RydWN0b3IobWVzc2FnZSwgc3RhdHVzLCByZXF1ZXN0ZWREYXRhKSB7CiAgICAgIHN1cGVyKG1lc3NhZ2UpOwogICAgICB0aGlzLnN0YXR1cyA9IHN0YXR1czsKICAgICAgdGhpcy5yZXF1ZXN0ZWREYXRhID0gcmVxdWVzdGVkRGF0YTsKICAgICAgdGhpcy5uYW1lID0gIlVua25vd25MYXBpc0Vycm9yIjsKICAgIH0KICB9CiAgY2xhc3MgTGFwaXNFcnJvciBleHRlbmRzIEVycm9yIHsKICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHN0YXR1cywgcHJvYmxlbURldGFpbDIsIHJlcXVlc3RlZERhdGEpIHsKICAgICAgc3VwZXIobWVzc2FnZSk7CiAgICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzOwogICAgICB0aGlzLnByb2JsZW1EZXRhaWwgPSBwcm9ibGVtRGV0YWlsMjsKICAgICAgdGhpcy5yZXF1ZXN0ZWREYXRhID0gcmVxdWVzdGVkRGF0YTsKICAgICAgdGhpcy5uYW1lID0gIkxhcGlzRXJyb3IiOwogICAgfQogIH0KICBhc3luYyBmdW5jdGlvbiBmZXRjaEFnZ3JlZ2F0ZWQobGFwaXNVcmwsIGJvZHksIHNpZ25hbCkgewogICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChhZ2dyZWdhdGVkRW5kcG9pbnQobGFwaXNVcmwpLCB7CiAgICAgIG1ldGhvZDogIlBPU1QiLAogICAgICBoZWFkZXJzOiB7CiAgICAgICAgIkNvbnRlbnQtVHlwZSI6ICJhcHBsaWNhdGlvbi9qc29uIgogICAgICB9LAogICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShib2R5KSwKICAgICAgc2lnbmFsCiAgICB9KTsKICAgIGF3YWl0IGhhbmRsZUVycm9ycyhyZXNwb25zZSwgImFnZ3JlZ2F0ZWQgZGF0YSIpOwogICAgcmV0dXJuIGFnZ3JlZ2F0ZWRSZXNwb25zZS5wYXJzZShhd2FpdCByZXNwb25zZS5qc29uKCkpOwogIH0KICBhc3luYyBmdW5jdGlvbiBmZXRjaFN1YnN0aXR1dGlvbnNPckRlbGV0aW9ucyhsYXBpc1VybCwgYm9keSwgc2VxdWVuY2VUeXBlLCBzaWduYWwpIHsKICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goc3Vic3RpdHV0aW9uc09yRGVsZXRpb25zRW5kcG9pbnQobGFwaXNVcmwsIHNlcXVlbmNlVHlwZSksIHsKICAgICAgbWV0aG9kOiAiUE9TVCIsCiAgICAgIGhlYWRlcnM6IHsKICAgICAgICAiQ29udGVudC1UeXBlIjogImFwcGxpY2F0aW9uL2pzb24iCiAgICAgIH0sCiAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KGJvZHkpLAogICAgICBzaWduYWwKICAgIH0pOwogICAgYXdhaXQgaGFuZGxlRXJyb3JzKHJlc3BvbnNlLCBgJHtzZXF1ZW5jZVR5cGV9IG11dGF0aW9uc2ApOwogICAgcmV0dXJuIG11dGF0aW9uc1Jlc3BvbnNlLnBhcnNlKGF3YWl0IHJlc3BvbnNlLmpzb24oKSk7CiAgfQogIGNvbnN0IGhhbmRsZUVycm9ycyA9IGFzeW5jIChyZXNwb25zZSwgcmVxdWVzdGVkRGF0YSkgPT4gewogICAgaWYgKCFyZXNwb25zZS5vaykgewogICAgICBpZiAocmVzcG9uc2Uuc3RhdHVzID49IDQwMCAmJiByZXNwb25zZS5zdGF0dXMgPCA1MDApIHsKICAgICAgICBjb25zdCBqc29uID0gYXdhaXQgcmVzcG9uc2UuanNvbigpOwogICAgICAgIGNvbnN0IGxhcGlzRXJyb3JSZXN1bHQgPSBsYXBpc0Vycm9yLnNhZmVQYXJzZShqc29uKTsKICAgICAgICBpZiAobGFwaXNFcnJvclJlc3VsdC5zdWNjZXNzKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTGFwaXNFcnJvcigKICAgICAgICAgICAgcmVzcG9uc2Uuc3RhdHVzVGV4dCArIGxhcGlzRXJyb3JSZXN1bHQuZGF0YS5lcnJvci5kZXRhaWwsCiAgICAgICAgICAgIHJlc3BvbnNlLnN0YXR1cywKICAgICAgICAgICAgbGFwaXNFcnJvclJlc3VsdC5kYXRhLmVycm9yLAogICAgICAgICAgICByZXF1ZXN0ZWREYXRhCiAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICBjb25zdCBwcm9ibGVtRGV0YWlsUmVzdWx0ID0gcHJvYmxlbURldGFpbC5zYWZlUGFyc2UoanNvbik7CiAgICAgICAgaWYgKHByb2JsZW1EZXRhaWxSZXN1bHQuc3VjY2VzcykgewogICAgICAgICAgdGhyb3cgbmV3IExhcGlzRXJyb3IoCiAgICAgICAgICAgIHJlc3BvbnNlLnN0YXR1c1RleHQgKyBwcm9ibGVtRGV0YWlsUmVzdWx0LmRhdGEuZGV0YWlsLAogICAgICAgICAgICByZXNwb25zZS5zdGF0dXMsCiAgICAgICAgICAgIHByb2JsZW1EZXRhaWxSZXN1bHQuZGF0YSwKICAgICAgICAgICAgcmVxdWVzdGVkRGF0YQogICAgICAgICAgKTsKICAgICAgICB9CiAgICAgICAgdGhyb3cgbmV3IFVua25vd25MYXBpc0Vycm9yKAogICAgICAgICAgYCR7cmVzcG9uc2Uuc3RhdHVzVGV4dH06ICR7SlNPTi5zdHJpbmdpZnkoanNvbil9YCwKICAgICAgICAgIHJlc3BvbnNlLnN0YXR1cywKICAgICAgICAgIHJlcXVlc3RlZERhdGEKICAgICAgICApOwogICAgICB9CiAgICAgIHRocm93IG5ldyBVbmtub3duTGFwaXNFcnJvcihgJHtyZXNwb25zZS5zdGF0dXNUZXh0fTogJHtyZXNwb25zZS5zdGF0dXN9YCwgcmVzcG9uc2Uuc3RhdHVzLCByZXF1ZXN0ZWREYXRhKTsKICAgIH0KICB9OwogIGNvbnN0IGFnZ3JlZ2F0ZWRFbmRwb2ludCA9IChsYXBpc1VybCkgPT4gYCR7bGFwaXNVcmx9L3NhbXBsZS9hZ2dyZWdhdGVkYDsKICBjb25zdCBzdWJzdGl0dXRpb25zT3JEZWxldGlvbnNFbmRwb2ludCA9IChsYXBpc1VybCwgc2VxdWVuY2VUeXBlKSA9PiB7CiAgICByZXR1cm4gc2VxdWVuY2VUeXBlID09PSAiYW1pbm8gYWNpZCIgPyBgJHtsYXBpc1VybH0vc2FtcGxlL2FtaW5vQWNpZE11dGF0aW9uc2AgOiBgJHtsYXBpc1VybH0vc2FtcGxlL251Y2xlb3RpZGVNdXRhdGlvbnNgOwogIH07CiAgY2xhc3MgRmV0Y2hBZ2dyZWdhdGVkT3BlcmF0b3IgewogICAgY29uc3RydWN0b3IoZmlsdGVyLCBmaWVsZHMgPSBbXSkgewogICAgICB0aGlzLmZpbHRlciA9IGZpbHRlcjsKICAgICAgdGhpcy5maWVsZHMgPSBmaWVsZHM7CiAgICB9CiAgICBhc3luYyBldmFsdWF0ZShsYXBpc1VybCwgc2lnbmFsKSB7CiAgICAgIGNvbnN0IGFnZ3JlZ2F0ZWRSZXNwb25zZTIgPSAoYXdhaXQgZmV0Y2hBZ2dyZWdhdGVkKAogICAgICAgIGxhcGlzVXJsLAogICAgICAgIHsKICAgICAgICAgIC4uLnRoaXMuZmlsdGVyLAogICAgICAgICAgZmllbGRzOiB0aGlzLmZpZWxkcwogICAgICAgIH0sCiAgICAgICAgc2lnbmFsCiAgICAgICkpLmRhdGE7CiAgICAgIGlmIChpc0ZpZWxkc0FycmF5V2l0aENvdW50KGFnZ3JlZ2F0ZWRSZXNwb25zZTIpKSB7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIGNvbnRlbnQ6IGFnZ3JlZ2F0ZWRSZXNwb25zZTIKICAgICAgICB9OwogICAgICB9CiAgICAgIHRocm93IG5ldyBFcnJvcigiQWdncmVnYXRlZCByZXNwb25zZSBkb2VzIG5vdCBoYXZlIGNvdW50Iik7CiAgICB9CiAgfQogIGZ1bmN0aW9uIGlzRmllbGRzQXJyYXlXaXRoQ291bnQoZGF0YSkgewogICAgcmV0dXJuIGRhdGEuZXZlcnkoKGl0ZW0pID0+IHR5cGVvZiBpdGVtID09PSAib2JqZWN0IiAmJiAiY291bnQiIGluIGl0ZW0gJiYgdHlwZW9mIGl0ZW0uY291bnQgPT09ICJudW1iZXIiKTsKICB9CiAgY2xhc3MgR3JvdXBCeU9wZXJhdG9yIHsKICAgIGNvbnN0cnVjdG9yKGNoaWxkLCBmaWVsZCwgYWdncmVnYXRlKSB7CiAgICAgIHRoaXMuY2hpbGQgPSBjaGlsZDsKICAgICAgdGhpcy5maWVsZCA9IGZpZWxkOwogICAgICB0aGlzLmFnZ3JlZ2F0ZSA9IGFnZ3JlZ2F0ZTsKICAgIH0KICAgIGFzeW5jIGV2YWx1YXRlKGxhcGlzLCBzaWduYWwpIHsKICAgICAgY29uc3QgY2hpbGRFdmFsdWF0ZWQgPSBhd2FpdCB0aGlzLmNoaWxkLmV2YWx1YXRlKGxhcGlzLCBzaWduYWwpOwogICAgICBjb25zdCBncm91cGVkID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAgICAgZm9yIChjb25zdCByb3cgb2YgY2hpbGRFdmFsdWF0ZWQuY29udGVudCkgewogICAgICAgIGNvbnN0IGtleSA9IHJvd1t0aGlzLmZpZWxkXTsKICAgICAgICBpZiAoIWdyb3VwZWQuaGFzKGtleSkpIHsKICAgICAgICAgIGdyb3VwZWQuc2V0KGtleSwgW10pOwogICAgICAgIH0KICAgICAgICBncm91cGVkLmdldChrZXkpLnB1c2gocm93KTsKICAgICAgfQogICAgICBjb25zdCByZXN1bHQgPSBuZXcgQXJyYXkoKTsKICAgICAgZm9yIChjb25zdCBbLCB2YWx1ZXNdIG9mIGdyb3VwZWQpIHsKICAgICAgICByZXN1bHQucHVzaCh0aGlzLmFnZ3JlZ2F0ZSh2YWx1ZXMpKTsKICAgICAgfQogICAgICByZXR1cm4gewogICAgICAgIGNvbnRlbnQ6IHJlc3VsdAogICAgICB9OwogICAgfQogIH0KICBjbGFzcyBHcm91cEJ5QW5kU3VtT3BlcmF0b3IgZXh0ZW5kcyBHcm91cEJ5T3BlcmF0b3IgewogICAgY29uc3RydWN0b3IoY2hpbGQsIGdyb3VwQnlGaWVsZCwgc3VtRmllbGQpIHsKICAgICAgc3VwZXIoY2hpbGQsIGdyb3VwQnlGaWVsZCwgKHZhbHVlcykgPT4gewogICAgICAgIGxldCBuID0gMDsKICAgICAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIHZhbHVlcykgewogICAgICAgICAgbiArPSB2YWx1ZVtzdW1GaWVsZF07CiAgICAgICAgfQogICAgICAgIHJldHVybiB7CiAgICAgICAgICBbZ3JvdXBCeUZpZWxkXTogdmFsdWVzWzBdW2dyb3VwQnlGaWVsZF0sCiAgICAgICAgICBbc3VtRmllbGRdOiBuCiAgICAgICAgfTsKICAgICAgfSk7CiAgICB9CiAgfQogIGNsYXNzIE1hcE9wZXJhdG9yIHsKICAgIGNvbnN0cnVjdG9yKGNoaWxkLCBmdW5jKSB7CiAgICAgIHRoaXMuY2hpbGQgPSBjaGlsZDsKICAgICAgdGhpcy5mdW5jID0gZnVuYzsKICAgIH0KICAgIGFzeW5jIGV2YWx1YXRlKGxhcGlzLCBzaWduYWwpIHsKICAgICAgY29uc3QgY2hpbGRFdmFsdWF0ZWQgPSBhd2FpdCB0aGlzLmNoaWxkLmV2YWx1YXRlKGxhcGlzLCBzaWduYWwpOwogICAgICByZXR1cm4gewogICAgICAgIGNvbnRlbnQ6IGNoaWxkRXZhbHVhdGVkLmNvbnRlbnQubWFwKHRoaXMuZnVuYykKICAgICAgfTsKICAgIH0KICB9CiAgY2xhc3MgUmVuYW1lRmllbGRPcGVyYXRvciBleHRlbmRzIE1hcE9wZXJhdG9yIHsKICAgIGNvbnN0cnVjdG9yKGNoaWxkLCBvbGRGaWVsZE5hbWUsIG5ld0ZpZWxkTmFtZSkgewogICAgICBzdXBlcigKICAgICAgICBjaGlsZCwKICAgICAgICAodmFsdWUpID0+ICh7CiAgICAgICAgICAuLi52YWx1ZSwKICAgICAgICAgIFtuZXdGaWVsZE5hbWVdOiB2YWx1ZVtvbGRGaWVsZE5hbWVdCiAgICAgICAgfSkKICAgICAgKTsKICAgIH0KICB9CiAgY2xhc3MgU29ydE9wZXJhdG9yIHsKICAgIGNvbnN0cnVjdG9yKGNoaWxkLCBjb21wYXJlRm4pIHsKICAgICAgdGhpcy5jaGlsZCA9IGNoaWxkOwogICAgICB0aGlzLmNvbXBhcmVGbiA9IGNvbXBhcmVGbjsKICAgIH0KICAgIGFzeW5jIGV2YWx1YXRlKGxhcGlzLCBzaWduYWwpIHsKICAgICAgY29uc3QgY2hpbGRFdmFsdWF0ZWQgPSBhd2FpdCB0aGlzLmNoaWxkLmV2YWx1YXRlKGxhcGlzLCBzaWduYWwpOwogICAgICByZXR1cm4gewogICAgICAgIGNvbnRlbnQ6IGNoaWxkRXZhbHVhdGVkLmNvbnRlbnQuc29ydCh0aGlzLmNvbXBhcmVGbikKICAgICAgfTsKICAgIH0KICB9CiAgdmFyIFNFQ09ORFNfQV9NSU5VVEUgPSA2MDsKICB2YXIgU0VDT05EU19BX0hPVVIgPSBTRUNPTkRTX0FfTUlOVVRFICogNjA7CiAgdmFyIFNFQ09ORFNfQV9EQVkgPSBTRUNPTkRTX0FfSE9VUiAqIDI0OwogIHZhciBTRUNPTkRTX0FfV0VFSyA9IFNFQ09ORFNfQV9EQVkgKiA3OwogIHZhciBNSUxMSVNFQ09ORFNfQV9TRUNPTkQgPSAxZTM7CiAgdmFyIE1JTExJU0VDT05EU19BX01JTlVURSA9IFNFQ09ORFNfQV9NSU5VVEUgKiBNSUxMSVNFQ09ORFNfQV9TRUNPTkQ7CiAgdmFyIE1JTExJU0VDT05EU19BX0hPVVIgPSBTRUNPTkRTX0FfSE9VUiAqIE1JTExJU0VDT05EU19BX1NFQ09ORDsKICB2YXIgTUlMTElTRUNPTkRTX0FfREFZID0gU0VDT05EU19BX0RBWSAqIE1JTExJU0VDT05EU19BX1NFQ09ORDsKICB2YXIgTUlMTElTRUNPTkRTX0FfV0VFSyA9IFNFQ09ORFNfQV9XRUVLICogTUlMTElTRUNPTkRTX0FfU0VDT05EOwogIHZhciBNUyA9ICJtaWxsaXNlY29uZCI7CiAgdmFyIFMgPSAic2Vjb25kIjsKICB2YXIgTUlOID0gIm1pbnV0ZSI7CiAgdmFyIEggPSAiaG91ciI7CiAgdmFyIEQgPSAiZGF5IjsKICB2YXIgVyA9ICJ3ZWVrIjsKICB2YXIgTSA9ICJtb250aCI7CiAgdmFyIFEgPSAicXVhcnRlciI7CiAgdmFyIFkgPSAieWVhciI7CiAgdmFyIERBVEUgPSAiZGF0ZSI7CiAgdmFyIEZPUk1BVF9ERUZBVUxUID0gIllZWVktTU0tRERUSEg6bW06c3NaIjsKICB2YXIgSU5WQUxJRF9EQVRFX1NUUklORyA9ICJJbnZhbGlkIERhdGUiOwogIHZhciBSRUdFWF9QQVJTRSA9IC9eKFxkezR9KVstL10/KFxkezEsMn0pP1stL10/KFxkezAsMn0pW1R0XHNdKihcZHsxLDJ9KT86PyhcZHsxLDJ9KT86PyhcZHsxLDJ9KT9bLjpdPyhcZCspPyQvOwogIHZhciBSRUdFWF9GT1JNQVQgPSAvXFsoW15cXV0rKV18WXsxLDR9fE17MSw0fXxEezEsMn18ZHsxLDR9fEh7MSwyfXxoezEsMn18YXxBfG17MSwyfXxzezEsMn18WnsxLDJ9fFNTUy9nOwogIHZhciBlbiA9IHsKICAgIG5hbWU6ICJlbiIsCiAgICB3ZWVrZGF5czogIlN1bmRheV9Nb25kYXlfVHVlc2RheV9XZWRuZXNkYXlfVGh1cnNkYXlfRnJpZGF5X1NhdHVyZGF5Ii5zcGxpdCgiXyIpLAogICAgbW9udGhzOiAiSmFudWFyeV9GZWJydWFyeV9NYXJjaF9BcHJpbF9NYXlfSnVuZV9KdWx5X0F1Z3VzdF9TZXB0ZW1iZXJfT2N0b2Jlcl9Ob3ZlbWJlcl9EZWNlbWJlciIuc3BsaXQoIl8iKSwKICAgIG9yZGluYWw6IGZ1bmN0aW9uIG9yZGluYWwobikgewogICAgICB2YXIgczIgPSBbInRoIiwgInN0IiwgIm5kIiwgInJkIl07CiAgICAgIHZhciB2MiA9IG4gJSAxMDA7CiAgICAgIHJldHVybiAiWyIgKyBuICsgKHMyWyh2MiAtIDIwKSAlIDEwXSB8fCBzMlt2Ml0gfHwgczJbMF0pICsgIl0iOwogICAgfQogIH07CiAgdmFyIHBhZFN0YXJ0ID0gZnVuY3Rpb24gcGFkU3RhcnQyKHN0cmluZywgbGVuZ3RoLCBwYWQpIHsKICAgIHZhciBzMiA9IFN0cmluZyhzdHJpbmcpOwogICAgaWYgKCFzMiB8fCBzMi5sZW5ndGggPj0gbGVuZ3RoKSByZXR1cm4gc3RyaW5nOwogICAgcmV0dXJuICIiICsgQXJyYXkobGVuZ3RoICsgMSAtIHMyLmxlbmd0aCkuam9pbihwYWQpICsgc3RyaW5nOwogIH07CiAgdmFyIHBhZFpvbmVTdHIgPSBmdW5jdGlvbiBwYWRab25lU3RyMihpbnN0YW5jZSkgewogICAgdmFyIG5lZ01pbnV0ZXMgPSAtaW5zdGFuY2UudXRjT2Zmc2V0KCk7CiAgICB2YXIgbWludXRlcyA9IE1hdGguYWJzKG5lZ01pbnV0ZXMpOwogICAgdmFyIGhvdXJPZmZzZXQgPSBNYXRoLmZsb29yKG1pbnV0ZXMgLyA2MCk7CiAgICB2YXIgbWludXRlT2Zmc2V0ID0gbWludXRlcyAlIDYwOwogICAgcmV0dXJuIChuZWdNaW51dGVzIDw9IDAgPyAiKyIgOiAiLSIpICsgcGFkU3RhcnQoaG91ck9mZnNldCwgMiwgIjAiKSArICI6IiArIHBhZFN0YXJ0KG1pbnV0ZU9mZnNldCwgMiwgIjAiKTsKICB9OwogIHZhciBtb250aERpZmYgPSBmdW5jdGlvbiBtb250aERpZmYyKGEyLCBiKSB7CiAgICBpZiAoYTIuZGF0ZSgpIDwgYi5kYXRlKCkpIHJldHVybiAtbW9udGhEaWZmMihiLCBhMik7CiAgICB2YXIgd2hvbGVNb250aERpZmYgPSAoYi55ZWFyKCkgLSBhMi55ZWFyKCkpICogMTIgKyAoYi5tb250aCgpIC0gYTIubW9udGgoKSk7CiAgICB2YXIgYW5jaG9yID0gYTIuY2xvbmUoKS5hZGQod2hvbGVNb250aERpZmYsIE0pOwogICAgdmFyIGMyID0gYiAtIGFuY2hvciA8IDA7CiAgICB2YXIgYW5jaG9yMiA9IGEyLmNsb25lKCkuYWRkKHdob2xlTW9udGhEaWZmICsgKGMyID8gLTEgOiAxKSwgTSk7CiAgICByZXR1cm4gKygtKHdob2xlTW9udGhEaWZmICsgKGIgLSBhbmNob3IpIC8gKGMyID8gYW5jaG9yIC0gYW5jaG9yMiA6IGFuY2hvcjIgLSBhbmNob3IpKSB8fCAwKTsKICB9OwogIHZhciBhYnNGbG9vciA9IGZ1bmN0aW9uIGFic0Zsb29yMihuKSB7CiAgICByZXR1cm4gbiA8IDAgPyBNYXRoLmNlaWwobikgfHwgMCA6IE1hdGguZmxvb3Iobik7CiAgfTsKICB2YXIgcHJldHR5VW5pdCA9IGZ1bmN0aW9uIHByZXR0eVVuaXQyKHUyKSB7CiAgICB2YXIgc3BlY2lhbCA9IHsKICAgICAgTSwKICAgICAgeTogWSwKICAgICAgdzogVywKICAgICAgZDogRCwKICAgICAgRDogREFURSwKICAgICAgaDogSCwKICAgICAgbTogTUlOLAogICAgICBzOiBTLAogICAgICBtczogTVMsCiAgICAgIFEKICAgIH07CiAgICByZXR1cm4gc3BlY2lhbFt1Ml0gfHwgU3RyaW5nKHUyIHx8ICIiKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL3MkLywgIiIpOwogIH07CiAgdmFyIGlzVW5kZWZpbmVkID0gZnVuY3Rpb24gaXNVbmRlZmluZWQyKHMyKSB7CiAgICByZXR1cm4gczIgPT09IHZvaWQgMDsKICB9OwogIHZhciBVID0gewogICAgczogcGFkU3RhcnQsCiAgICB6OiBwYWRab25lU3RyLAogICAgbTogbW9udGhEaWZmLAogICAgYTogYWJzRmxvb3IsCiAgICBwOiBwcmV0dHlVbml0LAogICAgdTogaXNVbmRlZmluZWQKICB9OwogIHZhciBMID0gImVuIjsKICB2YXIgTHMgPSB7fTsKICBMc1tMXSA9IGVuOwogIHZhciBJU19EQVlKUyA9ICIkaXNEYXlqc09iamVjdCI7CiAgdmFyIGlzRGF5anMgPSBmdW5jdGlvbiBpc0RheWpzMihkKSB7CiAgICByZXR1cm4gZCBpbnN0YW5jZW9mIERheWpzIHx8ICEhKGQgJiYgZFtJU19EQVlKU10pOwogIH07CiAgdmFyIHBhcnNlTG9jYWxlID0gZnVuY3Rpb24gcGFyc2VMb2NhbGUyKHByZXNldCwgb2JqZWN0LCBpc0xvY2FsKSB7CiAgICB2YXIgbDI7CiAgICBpZiAoIXByZXNldCkgcmV0dXJuIEw7CiAgICBpZiAodHlwZW9mIHByZXNldCA9PT0gInN0cmluZyIpIHsKICAgICAgdmFyIHByZXNldExvd2VyID0gcHJlc2V0LnRvTG93ZXJDYXNlKCk7CiAgICAgIGlmIChMc1twcmVzZXRMb3dlcl0pIHsKICAgICAgICBsMiA9IHByZXNldExvd2VyOwogICAgICB9CiAgICAgIGlmIChvYmplY3QpIHsKICAgICAgICBMc1twcmVzZXRMb3dlcl0gPSBvYmplY3Q7CiAgICAgICAgbDIgPSBwcmVzZXRMb3dlcjsKICAgICAgfQogICAgICB2YXIgcHJlc2V0U3BsaXQgPSBwcmVzZXQuc3BsaXQoIi0iKTsKICAgICAgaWYgKCFsMiAmJiBwcmVzZXRTcGxpdC5sZW5ndGggPiAxKSB7CiAgICAgICAgcmV0dXJuIHBhcnNlTG9jYWxlMihwcmVzZXRTcGxpdFswXSk7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHZhciBuYW1lID0gcHJlc2V0Lm5hbWU7CiAgICAgIExzW25hbWVdID0gcHJlc2V0OwogICAgICBsMiA9IG5hbWU7CiAgICB9CiAgICBpZiAoIWlzTG9jYWwgJiYgbDIpIEwgPSBsMjsKICAgIHJldHVybiBsMiB8fCAhaXNMb2NhbCAmJiBMOwogIH07CiAgdmFyIGRheWpzID0gZnVuY3Rpb24gZGF5anMyKGRhdGUsIGMyKSB7CiAgICBpZiAoaXNEYXlqcyhkYXRlKSkgewogICAgICByZXR1cm4gZGF0ZS5jbG9uZSgpOwogICAgfQogICAgdmFyIGNmZyA9IHR5cGVvZiBjMiA9PT0gIm9iamVjdCIgPyBjMiA6IHt9OwogICAgY2ZnLmRhdGUgPSBkYXRlOwogICAgY2ZnLmFyZ3MgPSBhcmd1bWVudHM7CiAgICByZXR1cm4gbmV3IERheWpzKGNmZyk7CiAgfTsKICB2YXIgd3JhcHBlciA9IGZ1bmN0aW9uIHdyYXBwZXIyKGRhdGUsIGluc3RhbmNlKSB7CiAgICByZXR1cm4gZGF5anMoZGF0ZSwgewogICAgICBsb2NhbGU6IGluc3RhbmNlLiRMLAogICAgICB1dGM6IGluc3RhbmNlLiR1LAogICAgICB4OiBpbnN0YW5jZS4keCwKICAgICAgJG9mZnNldDogaW5zdGFuY2UuJG9mZnNldAogICAgICAvLyB0b2RvOiByZWZhY3RvcjsgZG8gbm90IHVzZSB0aGlzLiRvZmZzZXQgaW4geW91IGNvZGUKICAgIH0pOwogIH07CiAgdmFyIFV0aWxzID0gVTsKICBVdGlscy5sID0gcGFyc2VMb2NhbGU7CiAgVXRpbHMuaSA9IGlzRGF5anM7CiAgVXRpbHMudyA9IHdyYXBwZXI7CiAgdmFyIHBhcnNlRGF0ZSA9IGZ1bmN0aW9uIHBhcnNlRGF0ZTIoY2ZnKSB7CiAgICB2YXIgZGF0ZSA9IGNmZy5kYXRlLCB1dGMgPSBjZmcudXRjOwogICAgaWYgKGRhdGUgPT09IG51bGwpIHJldHVybiAvKiBAX19QVVJFX18gKi8gbmV3IERhdGUoTmFOKTsKICAgIGlmIChVdGlscy51KGRhdGUpKSByZXR1cm4gLyogQF9fUFVSRV9fICovIG5ldyBEYXRlKCk7CiAgICBpZiAoZGF0ZSBpbnN0YW5jZW9mIERhdGUpIHJldHVybiBuZXcgRGF0ZShkYXRlKTsKICAgIGlmICh0eXBlb2YgZGF0ZSA9PT0gInN0cmluZyIgJiYgIS9aJC9pLnRlc3QoZGF0ZSkpIHsKICAgICAgdmFyIGQgPSBkYXRlLm1hdGNoKFJFR0VYX1BBUlNFKTsKICAgICAgaWYgKGQpIHsKICAgICAgICB2YXIgbTIgPSBkWzJdIC0gMSB8fCAwOwogICAgICAgIHZhciBtcyA9IChkWzddIHx8ICIwIikuc3Vic3RyaW5nKDAsIDMpOwogICAgICAgIGlmICh1dGMpIHsKICAgICAgICAgIHJldHVybiBuZXcgRGF0ZShEYXRlLlVUQyhkWzFdLCBtMiwgZFszXSB8fCAxLCBkWzRdIHx8IDAsIGRbNV0gfHwgMCwgZFs2XSB8fCAwLCBtcykpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbmV3IERhdGUoZFsxXSwgbTIsIGRbM10gfHwgMSwgZFs0XSB8fCAwLCBkWzVdIHx8IDAsIGRbNl0gfHwgMCwgbXMpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gbmV3IERhdGUoZGF0ZSk7CiAgfTsKICB2YXIgRGF5anMgPSAvKiBAX19QVVJFX18gKi8gZnVuY3Rpb24oKSB7CiAgICBmdW5jdGlvbiBEYXlqczIoY2ZnKSB7CiAgICAgIHRoaXMuJEwgPSBwYXJzZUxvY2FsZShjZmcubG9jYWxlLCBudWxsLCB0cnVlKTsKICAgICAgdGhpcy5wYXJzZShjZmcpOwogICAgICB0aGlzLiR4ID0gdGhpcy4keCB8fCBjZmcueCB8fCB7fTsKICAgICAgdGhpc1tJU19EQVlKU10gPSB0cnVlOwogICAgfQogICAgdmFyIF9wcm90byA9IERheWpzMi5wcm90b3R5cGU7CiAgICBfcHJvdG8ucGFyc2UgPSBmdW5jdGlvbiBwYXJzZShjZmcpIHsKICAgICAgdGhpcy4kZCA9IHBhcnNlRGF0ZShjZmcpOwogICAgICB0aGlzLmluaXQoKTsKICAgIH07CiAgICBfcHJvdG8uaW5pdCA9IGZ1bmN0aW9uIGluaXQoKSB7CiAgICAgIHZhciAkZCA9IHRoaXMuJGQ7CiAgICAgIHRoaXMuJHkgPSAkZC5nZXRGdWxsWWVhcigpOwogICAgICB0aGlzLiRNID0gJGQuZ2V0TW9udGgoKTsKICAgICAgdGhpcy4kRCA9ICRkLmdldERhdGUoKTsKICAgICAgdGhpcy4kVyA9ICRkLmdldERheSgpOwogICAgICB0aGlzLiRIID0gJGQuZ2V0SG91cnMoKTsKICAgICAgdGhpcy4kbSA9ICRkLmdldE1pbnV0ZXMoKTsKICAgICAgdGhpcy4kcyA9ICRkLmdldFNlY29uZHMoKTsKICAgICAgdGhpcy4kbXMgPSAkZC5nZXRNaWxsaXNlY29uZHMoKTsKICAgIH07CiAgICBfcHJvdG8uJHV0aWxzID0gZnVuY3Rpb24gJHV0aWxzKCkgewogICAgICByZXR1cm4gVXRpbHM7CiAgICB9OwogICAgX3Byb3RvLmlzVmFsaWQgPSBmdW5jdGlvbiBpc1ZhbGlkMigpIHsKICAgICAgcmV0dXJuICEodGhpcy4kZC50b1N0cmluZygpID09PSBJTlZBTElEX0RBVEVfU1RSSU5HKTsKICAgIH07CiAgICBfcHJvdG8uaXNTYW1lID0gZnVuY3Rpb24gaXNTYW1lKHRoYXQsIHVuaXRzKSB7CiAgICAgIHZhciBvdGhlciA9IGRheWpzKHRoYXQpOwogICAgICByZXR1cm4gdGhpcy5zdGFydE9mKHVuaXRzKSA8PSBvdGhlciAmJiBvdGhlciA8PSB0aGlzLmVuZE9mKHVuaXRzKTsKICAgIH07CiAgICBfcHJvdG8uaXNBZnRlciA9IGZ1bmN0aW9uIGlzQWZ0ZXIodGhhdCwgdW5pdHMpIHsKICAgICAgcmV0dXJuIGRheWpzKHRoYXQpIDwgdGhpcy5zdGFydE9mKHVuaXRzKTsKICAgIH07CiAgICBfcHJvdG8uaXNCZWZvcmUgPSBmdW5jdGlvbiBpc0JlZm9yZSh0aGF0LCB1bml0cykgewogICAgICByZXR1cm4gdGhpcy5lbmRPZih1bml0cykgPCBkYXlqcyh0aGF0KTsKICAgIH07CiAgICBfcHJvdG8uJGcgPSBmdW5jdGlvbiAkZyhpbnB1dCwgZ2V0LCBzZXQpIHsKICAgICAgaWYgKFV0aWxzLnUoaW5wdXQpKSByZXR1cm4gdGhpc1tnZXRdOwogICAgICByZXR1cm4gdGhpcy5zZXQoc2V0LCBpbnB1dCk7CiAgICB9OwogICAgX3Byb3RvLnVuaXggPSBmdW5jdGlvbiB1bml4KCkgewogICAgICByZXR1cm4gTWF0aC5mbG9vcih0aGlzLnZhbHVlT2YoKSAvIDFlMyk7CiAgICB9OwogICAgX3Byb3RvLnZhbHVlT2YgPSBmdW5jdGlvbiB2YWx1ZU9mKCkgewogICAgICByZXR1cm4gdGhpcy4kZC5nZXRUaW1lKCk7CiAgICB9OwogICAgX3Byb3RvLnN0YXJ0T2YgPSBmdW5jdGlvbiBzdGFydE9mKHVuaXRzLCBfc3RhcnRPZikgewogICAgICB2YXIgX3RoaXMgPSB0aGlzOwogICAgICB2YXIgaXNTdGFydE9mID0gIVV0aWxzLnUoX3N0YXJ0T2YpID8gX3N0YXJ0T2YgOiB0cnVlOwogICAgICB2YXIgdW5pdCA9IFV0aWxzLnAodW5pdHMpOwogICAgICB2YXIgaW5zdGFuY2VGYWN0b3J5ID0gZnVuY3Rpb24gaW5zdGFuY2VGYWN0b3J5MihkLCBtMikgewogICAgICAgIHZhciBpbnMgPSBVdGlscy53KF90aGlzLiR1ID8gRGF0ZS5VVEMoX3RoaXMuJHksIG0yLCBkKSA6IG5ldyBEYXRlKF90aGlzLiR5LCBtMiwgZCksIF90aGlzKTsKICAgICAgICByZXR1cm4gaXNTdGFydE9mID8gaW5zIDogaW5zLmVuZE9mKEQpOwogICAgICB9OwogICAgICB2YXIgaW5zdGFuY2VGYWN0b3J5U2V0ID0gZnVuY3Rpb24gaW5zdGFuY2VGYWN0b3J5U2V0MihtZXRob2QsIHNsaWNlKSB7CiAgICAgICAgdmFyIGFyZ3VtZW50U3RhcnQgPSBbMCwgMCwgMCwgMF07CiAgICAgICAgdmFyIGFyZ3VtZW50RW5kID0gWzIzLCA1OSwgNTksIDk5OV07CiAgICAgICAgcmV0dXJuIFV0aWxzLncoX3RoaXMudG9EYXRlKClbbWV0aG9kXS5hcHBseSgKICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLWxpbmUgcHJlZmVyLXNwcmVhZAogICAgICAgICAgX3RoaXMudG9EYXRlKCJzIiksCiAgICAgICAgICAoaXNTdGFydE9mID8gYXJndW1lbnRTdGFydCA6IGFyZ3VtZW50RW5kKS5zbGljZShzbGljZSkKICAgICAgICApLCBfdGhpcyk7CiAgICAgIH07CiAgICAgIHZhciAkVyA9IHRoaXMuJFcsICRNID0gdGhpcy4kTSwgJEQgPSB0aGlzLiREOwogICAgICB2YXIgdXRjUGFkID0gInNldCIgKyAodGhpcy4kdSA/ICJVVEMiIDogIiIpOwogICAgICBzd2l0Y2ggKHVuaXQpIHsKICAgICAgICBjYXNlIFk6CiAgICAgICAgICByZXR1cm4gaXNTdGFydE9mID8gaW5zdGFuY2VGYWN0b3J5KDEsIDApIDogaW5zdGFuY2VGYWN0b3J5KDMxLCAxMSk7CiAgICAgICAgY2FzZSBNOgogICAgICAgICAgcmV0dXJuIGlzU3RhcnRPZiA/IGluc3RhbmNlRmFjdG9yeSgxLCAkTSkgOiBpbnN0YW5jZUZhY3RvcnkoMCwgJE0gKyAxKTsKICAgICAgICBjYXNlIFc6IHsKICAgICAgICAgIHZhciB3ZWVrU3RhcnQgPSB0aGlzLiRsb2NhbGUoKS53ZWVrU3RhcnQgfHwgMDsKICAgICAgICAgIHZhciBnYXAgPSAoJFcgPCB3ZWVrU3RhcnQgPyAkVyArIDcgOiAkVykgLSB3ZWVrU3RhcnQ7CiAgICAgICAgICByZXR1cm4gaW5zdGFuY2VGYWN0b3J5KGlzU3RhcnRPZiA/ICREIC0gZ2FwIDogJEQgKyAoNiAtIGdhcCksICRNKTsKICAgICAgICB9CiAgICAgICAgY2FzZSBEOgogICAgICAgIGNhc2UgREFURToKICAgICAgICAgIHJldHVybiBpbnN0YW5jZUZhY3RvcnlTZXQodXRjUGFkICsgIkhvdXJzIiwgMCk7CiAgICAgICAgY2FzZSBIOgogICAgICAgICAgcmV0dXJuIGluc3RhbmNlRmFjdG9yeVNldCh1dGNQYWQgKyAiTWludXRlcyIsIDEpOwogICAgICAgIGNhc2UgTUlOOgogICAgICAgICAgcmV0dXJuIGluc3RhbmNlRmFjdG9yeVNldCh1dGNQYWQgKyAiU2Vjb25kcyIsIDIpOwogICAgICAgIGNhc2UgUzoKICAgICAgICAgIHJldHVybiBpbnN0YW5jZUZhY3RvcnlTZXQodXRjUGFkICsgIk1pbGxpc2Vjb25kcyIsIDMpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gdGhpcy5jbG9uZSgpOwogICAgICB9CiAgICB9OwogICAgX3Byb3RvLmVuZE9mID0gZnVuY3Rpb24gZW5kT2YoYXJnKSB7CiAgICAgIHJldHVybiB0aGlzLnN0YXJ0T2YoYXJnLCBmYWxzZSk7CiAgICB9OwogICAgX3Byb3RvLiRzZXQgPSBmdW5jdGlvbiAkc2V0KHVuaXRzLCBfaW50KSB7CiAgICAgIHZhciBfQyREJEMkREFURSRDJE0kQyRZJEM7CiAgICAgIHZhciB1bml0ID0gVXRpbHMucCh1bml0cyk7CiAgICAgIHZhciB1dGNQYWQgPSAic2V0IiArICh0aGlzLiR1ID8gIlVUQyIgOiAiIik7CiAgICAgIHZhciBuYW1lID0gKF9DJEQkQyREQVRFJEMkTSRDJFkkQyA9IHt9LCBfQyREJEMkREFURSRDJE0kQyRZJENbRF0gPSB1dGNQYWQgKyAiRGF0ZSIsIF9DJEQkQyREQVRFJEMkTSRDJFkkQ1tEQVRFXSA9IHV0Y1BhZCArICJEYXRlIiwgX0MkRCRDJERBVEUkQyRNJEMkWSRDW01dID0gdXRjUGFkICsgIk1vbnRoIiwgX0MkRCRDJERBVEUkQyRNJEMkWSRDW1ldID0gdXRjUGFkICsgIkZ1bGxZZWFyIiwgX0MkRCRDJERBVEUkQyRNJEMkWSRDW0hdID0gdXRjUGFkICsgIkhvdXJzIiwgX0MkRCRDJERBVEUkQyRNJEMkWSRDW01JTl0gPSB1dGNQYWQgKyAiTWludXRlcyIsIF9DJEQkQyREQVRFJEMkTSRDJFkkQ1tTXSA9IHV0Y1BhZCArICJTZWNvbmRzIiwgX0MkRCRDJERBVEUkQyRNJEMkWSRDW01TXSA9IHV0Y1BhZCArICJNaWxsaXNlY29uZHMiLCBfQyREJEMkREFURSRDJE0kQyRZJEMpW3VuaXRdOwogICAgICB2YXIgYXJnID0gdW5pdCA9PT0gRCA/IHRoaXMuJEQgKyAoX2ludCAtIHRoaXMuJFcpIDogX2ludDsKICAgICAgaWYgKHVuaXQgPT09IE0gfHwgdW5pdCA9PT0gWSkgewogICAgICAgIHZhciBkYXRlID0gdGhpcy5jbG9uZSgpLnNldChEQVRFLCAxKTsKICAgICAgICBkYXRlLiRkW25hbWVdKGFyZyk7CiAgICAgICAgZGF0ZS5pbml0KCk7CiAgICAgICAgdGhpcy4kZCA9IGRhdGUuc2V0KERBVEUsIE1hdGgubWluKHRoaXMuJEQsIGRhdGUuZGF5c0luTW9udGgoKSkpLiRkOwogICAgICB9IGVsc2UgaWYgKG5hbWUpIHRoaXMuJGRbbmFtZV0oYXJnKTsKICAgICAgdGhpcy5pbml0KCk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfTsKICAgIF9wcm90by5zZXQgPSBmdW5jdGlvbiBzZXQoc3RyaW5nLCBfaW50MikgewogICAgICByZXR1cm4gdGhpcy5jbG9uZSgpLiRzZXQoc3RyaW5nLCBfaW50Mik7CiAgICB9OwogICAgX3Byb3RvLmdldCA9IGZ1bmN0aW9uIGdldCh1bml0KSB7CiAgICAgIHJldHVybiB0aGlzW1V0aWxzLnAodW5pdCldKCk7CiAgICB9OwogICAgX3Byb3RvLmFkZCA9IGZ1bmN0aW9uIGFkZChudW1iZXIsIHVuaXRzKSB7CiAgICAgIHZhciBfdGhpczIgPSB0aGlzLCBfQyRNSU4kQyRIJEMkUyR1bml0OwogICAgICBudW1iZXIgPSBOdW1iZXIobnVtYmVyKTsKICAgICAgdmFyIHVuaXQgPSBVdGlscy5wKHVuaXRzKTsKICAgICAgdmFyIGluc3RhbmNlRmFjdG9yeVNldCA9IGZ1bmN0aW9uIGluc3RhbmNlRmFjdG9yeVNldDIobikgewogICAgICAgIHZhciBkID0gZGF5anMoX3RoaXMyKTsKICAgICAgICByZXR1cm4gVXRpbHMudyhkLmRhdGUoZC5kYXRlKCkgKyBNYXRoLnJvdW5kKG4gKiBudW1iZXIpKSwgX3RoaXMyKTsKICAgICAgfTsKICAgICAgaWYgKHVuaXQgPT09IE0pIHsKICAgICAgICByZXR1cm4gdGhpcy5zZXQoTSwgdGhpcy4kTSArIG51bWJlcik7CiAgICAgIH0KICAgICAgaWYgKHVuaXQgPT09IFkpIHsKICAgICAgICByZXR1cm4gdGhpcy5zZXQoWSwgdGhpcy4keSArIG51bWJlcik7CiAgICAgIH0KICAgICAgaWYgKHVuaXQgPT09IEQpIHsKICAgICAgICByZXR1cm4gaW5zdGFuY2VGYWN0b3J5U2V0KDEpOwogICAgICB9CiAgICAgIGlmICh1bml0ID09PSBXKSB7CiAgICAgICAgcmV0dXJuIGluc3RhbmNlRmFjdG9yeVNldCg3KTsKICAgICAgfQogICAgICB2YXIgc3RlcCA9IChfQyRNSU4kQyRIJEMkUyR1bml0ID0ge30sIF9DJE1JTiRDJEgkQyRTJHVuaXRbTUlOXSA9IE1JTExJU0VDT05EU19BX01JTlVURSwgX0MkTUlOJEMkSCRDJFMkdW5pdFtIXSA9IE1JTExJU0VDT05EU19BX0hPVVIsIF9DJE1JTiRDJEgkQyRTJHVuaXRbU10gPSBNSUxMSVNFQ09ORFNfQV9TRUNPTkQsIF9DJE1JTiRDJEgkQyRTJHVuaXQpW3VuaXRdIHx8IDE7CiAgICAgIHZhciBuZXh0VGltZVN0YW1wID0gdGhpcy4kZC5nZXRUaW1lKCkgKyBudW1iZXIgKiBzdGVwOwogICAgICByZXR1cm4gVXRpbHMudyhuZXh0VGltZVN0YW1wLCB0aGlzKTsKICAgIH07CiAgICBfcHJvdG8uc3VidHJhY3QgPSBmdW5jdGlvbiBzdWJ0cmFjdChudW1iZXIsIHN0cmluZykgewogICAgICByZXR1cm4gdGhpcy5hZGQobnVtYmVyICogLTEsIHN0cmluZyk7CiAgICB9OwogICAgX3Byb3RvLmZvcm1hdCA9IGZ1bmN0aW9uIGZvcm1hdChmb3JtYXRTdHIpIHsKICAgICAgdmFyIF90aGlzMyA9IHRoaXM7CiAgICAgIHZhciBsb2NhbGUgPSB0aGlzLiRsb2NhbGUoKTsKICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkgcmV0dXJuIGxvY2FsZS5pbnZhbGlkRGF0ZSB8fCBJTlZBTElEX0RBVEVfU1RSSU5HOwogICAgICB2YXIgc3RyID0gZm9ybWF0U3RyIHx8IEZPUk1BVF9ERUZBVUxUOwogICAgICB2YXIgem9uZVN0ciA9IFV0aWxzLnoodGhpcyk7CiAgICAgIHZhciAkSCA9IHRoaXMuJEgsICRtID0gdGhpcy4kbSwgJE0gPSB0aGlzLiRNOwogICAgICB2YXIgd2Vla2RheXMgPSBsb2NhbGUud2Vla2RheXMsIG1vbnRocyA9IGxvY2FsZS5tb250aHMsIG1lcmlkaWVtID0gbG9jYWxlLm1lcmlkaWVtOwogICAgICB2YXIgZ2V0U2hvcnQgPSBmdW5jdGlvbiBnZXRTaG9ydDIoYXJyLCBpbmRleCwgZnVsbCwgbGVuZ3RoKSB7CiAgICAgICAgcmV0dXJuIGFyciAmJiAoYXJyW2luZGV4XSB8fCBhcnIoX3RoaXMzLCBzdHIpKSB8fCBmdWxsW2luZGV4XS5zbGljZSgwLCBsZW5ndGgpOwogICAgICB9OwogICAgICB2YXIgZ2V0JEggPSBmdW5jdGlvbiBnZXQkSDIobnVtKSB7CiAgICAgICAgcmV0dXJuIFV0aWxzLnMoJEggJSAxMiB8fCAxMiwgbnVtLCAiMCIpOwogICAgICB9OwogICAgICB2YXIgbWVyaWRpZW1GdW5jID0gbWVyaWRpZW0gfHwgZnVuY3Rpb24oaG91ciwgbWludXRlLCBpc0xvd2VyY2FzZSkgewogICAgICAgIHZhciBtMiA9IGhvdXIgPCAxMiA/ICJBTSIgOiAiUE0iOwogICAgICAgIHJldHVybiBpc0xvd2VyY2FzZSA/IG0yLnRvTG93ZXJDYXNlKCkgOiBtMjsKICAgICAgfTsKICAgICAgdmFyIG1hdGNoZXMgPSBmdW5jdGlvbiBtYXRjaGVzMihtYXRjaCkgewogICAgICAgIHN3aXRjaCAobWF0Y2gpIHsKICAgICAgICAgIGNhc2UgIllZIjoKICAgICAgICAgICAgcmV0dXJuIFN0cmluZyhfdGhpczMuJHkpLnNsaWNlKC0yKTsKICAgICAgICAgIGNhc2UgIllZWVkiOgogICAgICAgICAgICByZXR1cm4gVXRpbHMucyhfdGhpczMuJHksIDQsICIwIik7CiAgICAgICAgICBjYXNlICJNIjoKICAgICAgICAgICAgcmV0dXJuICRNICsgMTsKICAgICAgICAgIGNhc2UgIk1NIjoKICAgICAgICAgICAgcmV0dXJuIFV0aWxzLnMoJE0gKyAxLCAyLCAiMCIpOwogICAgICAgICAgY2FzZSAiTU1NIjoKICAgICAgICAgICAgcmV0dXJuIGdldFNob3J0KGxvY2FsZS5tb250aHNTaG9ydCwgJE0sIG1vbnRocywgMyk7CiAgICAgICAgICBjYXNlICJNTU1NIjoKICAgICAgICAgICAgcmV0dXJuIGdldFNob3J0KG1vbnRocywgJE0pOwogICAgICAgICAgY2FzZSAiRCI6CiAgICAgICAgICAgIHJldHVybiBfdGhpczMuJEQ7CiAgICAgICAgICBjYXNlICJERCI6CiAgICAgICAgICAgIHJldHVybiBVdGlscy5zKF90aGlzMy4kRCwgMiwgIjAiKTsKICAgICAgICAgIGNhc2UgImQiOgogICAgICAgICAgICByZXR1cm4gU3RyaW5nKF90aGlzMy4kVyk7CiAgICAgICAgICBjYXNlICJkZCI6CiAgICAgICAgICAgIHJldHVybiBnZXRTaG9ydChsb2NhbGUud2Vla2RheXNNaW4sIF90aGlzMy4kVywgd2Vla2RheXMsIDIpOwogICAgICAgICAgY2FzZSAiZGRkIjoKICAgICAgICAgICAgcmV0dXJuIGdldFNob3J0KGxvY2FsZS53ZWVrZGF5c1Nob3J0LCBfdGhpczMuJFcsIHdlZWtkYXlzLCAzKTsKICAgICAgICAgIGNhc2UgImRkZGQiOgogICAgICAgICAgICByZXR1cm4gd2Vla2RheXNbX3RoaXMzLiRXXTsKICAgICAgICAgIGNhc2UgIkgiOgogICAgICAgICAgICByZXR1cm4gU3RyaW5nKCRIKTsKICAgICAgICAgIGNhc2UgIkhIIjoKICAgICAgICAgICAgcmV0dXJuIFV0aWxzLnMoJEgsIDIsICIwIik7CiAgICAgICAgICBjYXNlICJoIjoKICAgICAgICAgICAgcmV0dXJuIGdldCRIKDEpOwogICAgICAgICAgY2FzZSAiaGgiOgogICAgICAgICAgICByZXR1cm4gZ2V0JEgoMik7CiAgICAgICAgICBjYXNlICJhIjoKICAgICAgICAgICAgcmV0dXJuIG1lcmlkaWVtRnVuYygkSCwgJG0sIHRydWUpOwogICAgICAgICAgY2FzZSAiQSI6CiAgICAgICAgICAgIHJldHVybiBtZXJpZGllbUZ1bmMoJEgsICRtLCBmYWxzZSk7CiAgICAgICAgICBjYXNlICJtIjoKICAgICAgICAgICAgcmV0dXJuIFN0cmluZygkbSk7CiAgICAgICAgICBjYXNlICJtbSI6CiAgICAgICAgICAgIHJldHVybiBVdGlscy5zKCRtLCAyLCAiMCIpOwogICAgICAgICAgY2FzZSAicyI6CiAgICAgICAgICAgIHJldHVybiBTdHJpbmcoX3RoaXMzLiRzKTsKICAgICAgICAgIGNhc2UgInNzIjoKICAgICAgICAgICAgcmV0dXJuIFV0aWxzLnMoX3RoaXMzLiRzLCAyLCAiMCIpOwogICAgICAgICAgY2FzZSAiU1NTIjoKICAgICAgICAgICAgcmV0dXJuIFV0aWxzLnMoX3RoaXMzLiRtcywgMywgIjAiKTsKICAgICAgICAgIGNhc2UgIloiOgogICAgICAgICAgICByZXR1cm4gem9uZVN0cjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgIH07CiAgICAgIHJldHVybiBzdHIucmVwbGFjZShSRUdFWF9GT1JNQVQsIGZ1bmN0aW9uKG1hdGNoLCAkMSkgewogICAgICAgIHJldHVybiAkMSB8fCBtYXRjaGVzKG1hdGNoKSB8fCB6b25lU3RyLnJlcGxhY2UoIjoiLCAiIik7CiAgICAgIH0pOwogICAgfTsKICAgIF9wcm90by51dGNPZmZzZXQgPSBmdW5jdGlvbiB1dGNPZmZzZXQoKSB7CiAgICAgIHJldHVybiAtTWF0aC5yb3VuZCh0aGlzLiRkLmdldFRpbWV6b25lT2Zmc2V0KCkgLyAxNSkgKiAxNTsKICAgIH07CiAgICBfcHJvdG8uZGlmZiA9IGZ1bmN0aW9uIGRpZmYoaW5wdXQsIHVuaXRzLCBfZmxvYXQpIHsKICAgICAgdmFyIF90aGlzNCA9IHRoaXM7CiAgICAgIHZhciB1bml0ID0gVXRpbHMucCh1bml0cyk7CiAgICAgIHZhciB0aGF0ID0gZGF5anMoaW5wdXQpOwogICAgICB2YXIgem9uZURlbHRhID0gKHRoYXQudXRjT2Zmc2V0KCkgLSB0aGlzLnV0Y09mZnNldCgpKSAqIE1JTExJU0VDT05EU19BX01JTlVURTsKICAgICAgdmFyIGRpZmYyID0gdGhpcyAtIHRoYXQ7CiAgICAgIHZhciBnZXRNb250aCA9IGZ1bmN0aW9uIGdldE1vbnRoMigpIHsKICAgICAgICByZXR1cm4gVXRpbHMubShfdGhpczQsIHRoYXQpOwogICAgICB9OwogICAgICB2YXIgcmVzdWx0OwogICAgICBzd2l0Y2ggKHVuaXQpIHsKICAgICAgICBjYXNlIFk6CiAgICAgICAgICByZXN1bHQgPSBnZXRNb250aCgpIC8gMTI7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIE06CiAgICAgICAgICByZXN1bHQgPSBnZXRNb250aCgpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBROgogICAgICAgICAgcmVzdWx0ID0gZ2V0TW9udGgoKSAvIDM7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFc6CiAgICAgICAgICByZXN1bHQgPSAoZGlmZjIgLSB6b25lRGVsdGEpIC8gTUlMTElTRUNPTkRTX0FfV0VFSzsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgRDoKICAgICAgICAgIHJlc3VsdCA9IChkaWZmMiAtIHpvbmVEZWx0YSkgLyBNSUxMSVNFQ09ORFNfQV9EQVk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEg6CiAgICAgICAgICByZXN1bHQgPSBkaWZmMiAvIE1JTExJU0VDT05EU19BX0hPVVI7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIE1JTjoKICAgICAgICAgIHJlc3VsdCA9IGRpZmYyIC8gTUlMTElTRUNPTkRTX0FfTUlOVVRFOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBTOgogICAgICAgICAgcmVzdWx0ID0gZGlmZjIgLyBNSUxMSVNFQ09ORFNfQV9TRUNPTkQ7CiAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgcmVzdWx0ID0gZGlmZjI7CiAgICAgICAgICBicmVhazsKICAgICAgfQogICAgICByZXR1cm4gX2Zsb2F0ID8gcmVzdWx0IDogVXRpbHMuYShyZXN1bHQpOwogICAgfTsKICAgIF9wcm90by5kYXlzSW5Nb250aCA9IGZ1bmN0aW9uIGRheXNJbk1vbnRoKCkgewogICAgICByZXR1cm4gdGhpcy5lbmRPZihNKS4kRDsKICAgIH07CiAgICBfcHJvdG8uJGxvY2FsZSA9IGZ1bmN0aW9uICRsb2NhbGUoKSB7CiAgICAgIHJldHVybiBMc1t0aGlzLiRMXTsKICAgIH07CiAgICBfcHJvdG8ubG9jYWxlID0gZnVuY3Rpb24gbG9jYWxlKHByZXNldCwgb2JqZWN0KSB7CiAgICAgIGlmICghcHJlc2V0KSByZXR1cm4gdGhpcy4kTDsKICAgICAgdmFyIHRoYXQgPSB0aGlzLmNsb25lKCk7CiAgICAgIHZhciBuZXh0TG9jYWxlTmFtZSA9IHBhcnNlTG9jYWxlKHByZXNldCwgb2JqZWN0LCB0cnVlKTsKICAgICAgaWYgKG5leHRMb2NhbGVOYW1lKSB0aGF0LiRMID0gbmV4dExvY2FsZU5hbWU7CiAgICAgIHJldHVybiB0aGF0OwogICAgfTsKICAgIF9wcm90by5jbG9uZSA9IGZ1bmN0aW9uIGNsb25lKCkgewogICAgICByZXR1cm4gVXRpbHMudyh0aGlzLiRkLCB0aGlzKTsKICAgIH07CiAgICBfcHJvdG8udG9EYXRlID0gZnVuY3Rpb24gdG9EYXRlKCkgewogICAgICByZXR1cm4gbmV3IERhdGUodGhpcy52YWx1ZU9mKCkpOwogICAgfTsKICAgIF9wcm90by50b0pTT04gPSBmdW5jdGlvbiB0b0pTT04oKSB7CiAgICAgIHJldHVybiB0aGlzLmlzVmFsaWQoKSA/IHRoaXMudG9JU09TdHJpbmcoKSA6IG51bGw7CiAgICB9OwogICAgX3Byb3RvLnRvSVNPU3RyaW5nID0gZnVuY3Rpb24gdG9JU09TdHJpbmcoKSB7CiAgICAgIHJldHVybiB0aGlzLiRkLnRvSVNPU3RyaW5nKCk7CiAgICB9OwogICAgX3Byb3RvLnRvU3RyaW5nID0gZnVuY3Rpb24gdG9TdHJpbmcoKSB7CiAgICAgIHJldHVybiB0aGlzLiRkLnRvVVRDU3RyaW5nKCk7CiAgICB9OwogICAgcmV0dXJuIERheWpzMjsKICB9KCk7CiAgdmFyIHByb3RvID0gRGF5anMucHJvdG90eXBlOwogIGRheWpzLnByb3RvdHlwZSA9IHByb3RvOwogIFtbIiRtcyIsIE1TXSwgWyIkcyIsIFNdLCBbIiRtIiwgTUlOXSwgWyIkSCIsIEhdLCBbIiRXIiwgRF0sIFsiJE0iLCBNXSwgWyIkeSIsIFldLCBbIiREIiwgREFURV1dLmZvckVhY2goZnVuY3Rpb24oZykgewogICAgcHJvdG9bZ1sxXV0gPSBmdW5jdGlvbihpbnB1dCkgewogICAgICByZXR1cm4gdGhpcy4kZyhpbnB1dCwgZ1swXSwgZ1sxXSk7CiAgICB9OwogIH0pOwogIGRheWpzLmV4dGVuZCA9IGZ1bmN0aW9uKHBsdWdpbiwgb3B0aW9uKSB7CiAgICBpZiAoIXBsdWdpbi4kaSkgewogICAgICBwbHVnaW4ob3B0aW9uLCBEYXlqcywgZGF5anMpOwogICAgICBwbHVnaW4uJGkgPSB0cnVlOwogICAgfQogICAgcmV0dXJuIGRheWpzOwogIH07CiAgZGF5anMubG9jYWxlID0gcGFyc2VMb2NhbGU7CiAgZGF5anMuaXNEYXlqcyA9IGlzRGF5anM7CiAgZGF5anMudW5peCA9IGZ1bmN0aW9uKHRpbWVzdGFtcCkgewogICAgcmV0dXJuIGRheWpzKHRpbWVzdGFtcCAqIDFlMyk7CiAgfTsKICBkYXlqcy5lbiA9IExzW0xdOwogIGRheWpzLkxzID0gTHM7CiAgZGF5anMucCA9IHt9OwogIHZhciBhZHZhbmNlZEZvcm1hdCA9IGZ1bmN0aW9uKG8sIGMyKSB7CiAgICB2YXIgcHJvdG8yID0gYzIucHJvdG90eXBlOwogICAgdmFyIG9sZEZvcm1hdCA9IHByb3RvMi5mb3JtYXQ7CiAgICBwcm90bzIuZm9ybWF0ID0gZnVuY3Rpb24oZm9ybWF0U3RyKSB7CiAgICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICAgIHZhciBsb2NhbGUgPSB0aGlzLiRsb2NhbGUoKTsKICAgICAgaWYgKCF0aGlzLmlzVmFsaWQoKSkgewogICAgICAgIHJldHVybiBvbGRGb3JtYXQuYmluZCh0aGlzKShmb3JtYXRTdHIpOwogICAgICB9CiAgICAgIHZhciB1dGlscyA9IHRoaXMuJHV0aWxzKCk7CiAgICAgIHZhciBzdHIgPSBmb3JtYXRTdHIgfHwgRk9STUFUX0RFRkFVTFQ7CiAgICAgIHZhciByZXN1bHQgPSBzdHIucmVwbGFjZSgvXFsoW15cXV0rKV18UXx3b3x3d3x3fFdXfFd8enp6fHp8Z2dnZ3xHR0dHfERvfFh8eHxrezEsMn18Uy9nLCBmdW5jdGlvbihtYXRjaCkgewogICAgICAgIHN3aXRjaCAobWF0Y2gpIHsKICAgICAgICAgIGNhc2UgIlEiOgogICAgICAgICAgICByZXR1cm4gTWF0aC5jZWlsKChfdGhpcy4kTSArIDEpIC8gMyk7CiAgICAgICAgICBjYXNlICJEbyI6CiAgICAgICAgICAgIHJldHVybiBsb2NhbGUub3JkaW5hbChfdGhpcy4kRCk7CiAgICAgICAgICBjYXNlICJnZ2dnIjoKICAgICAgICAgICAgcmV0dXJuIF90aGlzLndlZWtZZWFyKCk7CiAgICAgICAgICBjYXNlICJHR0dHIjoKICAgICAgICAgICAgcmV0dXJuIF90aGlzLmlzb1dlZWtZZWFyKCk7CiAgICAgICAgICBjYXNlICJ3byI6CiAgICAgICAgICAgIHJldHVybiBsb2NhbGUub3JkaW5hbChfdGhpcy53ZWVrKCksICJXIik7CiAgICAgICAgICBjYXNlICJ3IjoKICAgICAgICAgIGNhc2UgInd3IjoKICAgICAgICAgICAgcmV0dXJuIHV0aWxzLnMoX3RoaXMud2VlaygpLCBtYXRjaCA9PT0gInciID8gMSA6IDIsICIwIik7CiAgICAgICAgICBjYXNlICJXIjoKICAgICAgICAgIGNhc2UgIldXIjoKICAgICAgICAgICAgcmV0dXJuIHV0aWxzLnMoX3RoaXMuaXNvV2VlaygpLCBtYXRjaCA9PT0gIlciID8gMSA6IDIsICIwIik7CiAgICAgICAgICBjYXNlICJrIjoKICAgICAgICAgIGNhc2UgImtrIjoKICAgICAgICAgICAgcmV0dXJuIHV0aWxzLnMoU3RyaW5nKF90aGlzLiRIID09PSAwID8gMjQgOiBfdGhpcy4kSCksIG1hdGNoID09PSAiayIgPyAxIDogMiwgIjAiKTsKICAgICAgICAgIGNhc2UgIlgiOgogICAgICAgICAgICByZXR1cm4gTWF0aC5mbG9vcihfdGhpcy4kZC5nZXRUaW1lKCkgLyAxZTMpOwogICAgICAgICAgY2FzZSAieCI6CiAgICAgICAgICAgIHJldHVybiBfdGhpcy4kZC5nZXRUaW1lKCk7CiAgICAgICAgICBjYXNlICJ6IjoKICAgICAgICAgICAgcmV0dXJuICJbIiArIF90aGlzLm9mZnNldE5hbWUoKSArICJdIjsKICAgICAgICAgIGNhc2UgInp6eiI6CiAgICAgICAgICAgIHJldHVybiAiWyIgKyBfdGhpcy5vZmZzZXROYW1lKCJsb25nIikgKyAiXSI7CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gbWF0Y2g7CiAgICAgICAgfQogICAgICB9KTsKICAgICAgcmV0dXJuIG9sZEZvcm1hdC5iaW5kKHRoaXMpKHJlc3VsdCk7CiAgICB9OwogIH07CiAgdmFyIGlzb1dlZWtQcmV0dHlVbml0ID0gImlzb3dlZWsiOwogIHZhciBpc29XZWVrID0gZnVuY3Rpb24obywgYzIsIGQpIHsKICAgIHZhciBnZXRZZWFyRmlyc3RUaHVyc2RheSA9IGZ1bmN0aW9uIGdldFllYXJGaXJzdFRodXJzZGF5Mih5ZWFyLCBpc1V0YykgewogICAgICB2YXIgeWVhckZpcnN0RGF5ID0gKGlzVXRjID8gZC51dGMgOiBkKSgpLnllYXIoeWVhcikuc3RhcnRPZihZKTsKICAgICAgdmFyIGFkZERpZmZEYXlzID0gNCAtIHllYXJGaXJzdERheS5pc29XZWVrZGF5KCk7CiAgICAgIGlmICh5ZWFyRmlyc3REYXkuaXNvV2Vla2RheSgpID4gNCkgewogICAgICAgIGFkZERpZmZEYXlzICs9IDc7CiAgICAgIH0KICAgICAgcmV0dXJuIHllYXJGaXJzdERheS5hZGQoYWRkRGlmZkRheXMsIEQpOwogICAgfTsKICAgIHZhciBnZXRDdXJyZW50V2Vla1RodXJzZGF5ID0gZnVuY3Rpb24gZ2V0Q3VycmVudFdlZWtUaHVyc2RheTIoaW5zKSB7CiAgICAgIHJldHVybiBpbnMuYWRkKDQgLSBpbnMuaXNvV2Vla2RheSgpLCBEKTsKICAgIH07CiAgICB2YXIgcHJvdG8yID0gYzIucHJvdG90eXBlOwogICAgcHJvdG8yLmlzb1dlZWtZZWFyID0gZnVuY3Rpb24oKSB7CiAgICAgIHZhciBub3dXZWVrVGh1cnNkYXkgPSBnZXRDdXJyZW50V2Vla1RodXJzZGF5KHRoaXMpOwogICAgICByZXR1cm4gbm93V2Vla1RodXJzZGF5LnllYXIoKTsKICAgIH07CiAgICBwcm90bzIuaXNvV2VlayA9IGZ1bmN0aW9uKHdlZWspIHsKICAgICAgaWYgKCF0aGlzLiR1dGlscygpLnUod2VlaykpIHsKICAgICAgICByZXR1cm4gdGhpcy5hZGQoKHdlZWsgLSB0aGlzLmlzb1dlZWsoKSkgKiA3LCBEKTsKICAgICAgfQogICAgICB2YXIgbm93V2Vla1RodXJzZGF5ID0gZ2V0Q3VycmVudFdlZWtUaHVyc2RheSh0aGlzKTsKICAgICAgdmFyIGRpZmZXZWVrVGh1cnNkYXkgPSBnZXRZZWFyRmlyc3RUaHVyc2RheSh0aGlzLmlzb1dlZWtZZWFyKCksIHRoaXMuJHUpOwogICAgICByZXR1cm4gbm93V2Vla1RodXJzZGF5LmRpZmYoZGlmZldlZWtUaHVyc2RheSwgVykgKyAxOwogICAgfTsKICAgIHByb3RvMi5pc29XZWVrZGF5ID0gZnVuY3Rpb24od2VlaykgewogICAgICBpZiAoIXRoaXMuJHV0aWxzKCkudSh3ZWVrKSkgewogICAgICAgIHJldHVybiB0aGlzLmRheSh0aGlzLmRheSgpICUgNyA/IHdlZWsgOiB3ZWVrIC0gNyk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMuZGF5KCkgfHwgNzsKICAgIH07CiAgICB2YXIgb2xkU3RhcnRPZiA9IHByb3RvMi5zdGFydE9mOwogICAgcHJvdG8yLnN0YXJ0T2YgPSBmdW5jdGlvbih1bml0cywgc3RhcnRPZikgewogICAgICB2YXIgdXRpbHMgPSB0aGlzLiR1dGlscygpOwogICAgICB2YXIgaXNTdGFydE9mID0gIXV0aWxzLnUoc3RhcnRPZikgPyBzdGFydE9mIDogdHJ1ZTsKICAgICAgdmFyIHVuaXQgPSB1dGlscy5wKHVuaXRzKTsKICAgICAgaWYgKHVuaXQgPT09IGlzb1dlZWtQcmV0dHlVbml0KSB7CiAgICAgICAgcmV0dXJuIGlzU3RhcnRPZiA/IHRoaXMuZGF0ZSh0aGlzLmRhdGUoKSAtICh0aGlzLmlzb1dlZWtkYXkoKSAtIDEpKS5zdGFydE9mKCJkYXkiKSA6IHRoaXMuZGF0ZSh0aGlzLmRhdGUoKSAtIDEgLSAodGhpcy5pc29XZWVrZGF5KCkgLSAxKSArIDcpLmVuZE9mKCJkYXkiKTsKICAgICAgfQogICAgICByZXR1cm4gb2xkU3RhcnRPZi5iaW5kKHRoaXMpKHVuaXRzLCBzdGFydE9mKTsKICAgIH07CiAgfTsKICBkYXlqcy5leHRlbmQoaXNvV2Vlayk7CiAgZGF5anMuZXh0ZW5kKGFkdmFuY2VkRm9ybWF0KTsKICBjb25zdCBGT1JNQVRfSVNPX1dFRUtfWUVBUl9XRUVLID0gIkdHR0ctW1ddV1ciOwogIGNvbnN0IF9UZW1wb3JhbENhY2hlID0gY2xhc3MgX1RlbXBvcmFsQ2FjaGUgewogICAgY29uc3RydWN0b3IoKSB7CiAgICAgIHRoaXMueWVhck1vbnRoRGF5Q2FjaGUgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogICAgICB0aGlzLnllYXJXZWVrQ2FjaGUgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogICAgICB0aGlzLnllYXJNb250aENhY2hlID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAgICAgdGhpcy55ZWFyQ2FjaGUgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogICAgfQogICAgZ2V0WWVhck1vbnRoRGF5KHMyKSB7CiAgICAgIGlmICghdGhpcy55ZWFyTW9udGhEYXlDYWNoZS5oYXMoczIpKSB7CiAgICAgICAgdGhpcy55ZWFyTW9udGhEYXlDYWNoZS5zZXQoczIsIFllYXJNb250aERheUNsYXNzLnBhcnNlKHMyLCB0aGlzKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMueWVhck1vbnRoRGF5Q2FjaGUuZ2V0KHMyKTsKICAgIH0KICAgIGdldFllYXJNb250aChzMikgewogICAgICBpZiAoIXRoaXMueWVhck1vbnRoQ2FjaGUuaGFzKHMyKSkgewogICAgICAgIHRoaXMueWVhck1vbnRoQ2FjaGUuc2V0KHMyLCBZZWFyTW9udGhDbGFzcy5wYXJzZShzMiwgdGhpcykpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLnllYXJNb250aENhY2hlLmdldChzMik7CiAgICB9CiAgICBnZXRZZWFyV2VlayhzMikgewogICAgICBpZiAoIXRoaXMueWVhcldlZWtDYWNoZS5oYXMoczIpKSB7CiAgICAgICAgdGhpcy55ZWFyV2Vla0NhY2hlLnNldChzMiwgWWVhcldlZWtDbGFzcy5wYXJzZShzMiwgdGhpcykpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLnllYXJXZWVrQ2FjaGUuZ2V0KHMyKTsKICAgIH0KICAgIGdldFllYXIoczIpIHsKICAgICAgaWYgKCF0aGlzLnllYXJDYWNoZS5oYXMoczIpKSB7CiAgICAgICAgdGhpcy55ZWFyQ2FjaGUuc2V0KHMyLCBZZWFyQ2xhc3MucGFyc2UoczIsIHRoaXMpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy55ZWFyQ2FjaGUuZ2V0KHMyKTsKICAgIH0KICAgIHN0YXRpYyBnZXRJbnN0YW5jZSgpIHsKICAgICAgcmV0dXJuIHRoaXMuaW5zdGFuY2U7CiAgICB9CiAgfTsKICBfVGVtcG9yYWxDYWNoZS5pbnN0YW5jZSA9IG5ldyBfVGVtcG9yYWxDYWNoZSgpOwogIGxldCBUZW1wb3JhbENhY2hlID0gX1RlbXBvcmFsQ2FjaGU7CiAgY2xhc3MgWWVhck1vbnRoRGF5Q2xhc3MgewogICAgY29uc3RydWN0b3IoeWVhck51bWJlciwgbW9udGhOdW1iZXIsIGRheU51bWJlciwgY2FjaGUpIHsKICAgICAgdGhpcy55ZWFyTnVtYmVyID0geWVhck51bWJlcjsKICAgICAgdGhpcy5tb250aE51bWJlciA9IG1vbnRoTnVtYmVyOwogICAgICB0aGlzLmRheU51bWJlciA9IGRheU51bWJlcjsKICAgICAgdGhpcy5jYWNoZSA9IGNhY2hlOwogICAgICB0aGlzLnR5cGUgPSAiWWVhck1vbnRoRGF5IjsKICAgICAgdGhpcy5kYXRlID0gbmV3IERhdGUodGhpcy55ZWFyTnVtYmVyLCB0aGlzLm1vbnRoTnVtYmVyIC0gMSwgdGhpcy5kYXlOdW1iZXIpOwogICAgICB0aGlzLmRheWpzID0gZGF5anModGhpcy5kYXRlKTsKICAgICAgdGhpcy5kYXRlU3RyaW5nID0gdGhpcy50b1N0cmluZygpOwogICAgfQogICAgZ2V0IHRleHQoKSB7CiAgICAgIHJldHVybiB0aGlzLmRheWpzLmZvcm1hdCgiWVlZWS1NTS1ERCIpOwogICAgfQogICAgdG9TdHJpbmcoKSB7CiAgICAgIHJldHVybiB0aGlzLnRleHQ7CiAgICB9CiAgICBlbmdsaXNoTmFtZSgpIHsKICAgICAgcmV0dXJuIHRoaXMuZGF5anMuZm9ybWF0KCJkZGRkLCBNTU1NIEQsIFlZWVkiKTsKICAgIH0KICAgIGdldCBmaXJzdERheSgpIHsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICBnZXQgbGFzdERheSgpIHsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CiAgICBnZXQgeWVhcigpIHsKICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0WWVhcihgJHt0aGlzLnllYXJOdW1iZXJ9YCk7CiAgICB9CiAgICBnZXQgbW9udGgoKSB7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXJNb250aCh0aGlzLmRheWpzLmZvcm1hdCgiWVlZWS1NTSIpKTsKICAgIH0KICAgIGdldCB3ZWVrKCkgewogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyV2Vlayh0aGlzLmRheWpzLmZvcm1hdChGT1JNQVRfSVNPX1dFRUtfWUVBUl9XRUVLKSk7CiAgICB9CiAgICBhZGREYXlzKGRheXMpIHsKICAgICAgY29uc3QgZGF0ZSA9IHRoaXMuZGF5anMuYWRkKGRheXMsICJkYXkiKTsKICAgICAgY29uc3QgczIgPSBkYXRlLmZvcm1hdCgiWVlZWS1NTS1ERCIpOwogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyTW9udGhEYXkoczIpOwogICAgfQogICAgbWludXMob3RoZXIpIHsKICAgICAgcmV0dXJuIHRoaXMuZGF5anMuZGlmZihvdGhlci5kYXlqcywgImRheSIpOwogICAgfQogICAgc3RhdGljIHBhcnNlKHMyLCBjYWNoZSkgewogICAgICBjb25zdCBbeWVhciwgbW9udGgsIGRheV0gPSBzMi5zcGxpdCgiLSIpLm1hcCgoczIyKSA9PiBwYXJzZUludChzMjIsIDEwKSk7CiAgICAgIHJldHVybiBuZXcgWWVhck1vbnRoRGF5Q2xhc3MoeWVhciwgbW9udGgsIGRheSwgY2FjaGUpOwogICAgfQogIH0KICBjbGFzcyBZZWFyV2Vla0NsYXNzIHsKICAgIGNvbnN0cnVjdG9yKGlzb1llYXJOdW1iZXIsIGlzb1dlZWtOdW1iZXIsIGNhY2hlKSB7CiAgICAgIHRoaXMuaXNvWWVhck51bWJlciA9IGlzb1llYXJOdW1iZXI7CiAgICAgIHRoaXMuaXNvV2Vla051bWJlciA9IGlzb1dlZWtOdW1iZXI7CiAgICAgIHRoaXMuY2FjaGUgPSBjYWNoZTsKICAgICAgdGhpcy50eXBlID0gIlllYXJXZWVrIjsKICAgICAgdGhpcy5kYXRlU3RyaW5nID0gdGhpcy50b1N0cmluZygpOwogICAgfQogICAgZ2V0IHRleHQoKSB7CiAgICAgIHJldHVybiB0aGlzLmZpcnN0RGF5LmRheWpzLmZvcm1hdChGT1JNQVRfSVNPX1dFRUtfWUVBUl9XRUVLKTsKICAgIH0KICAgIHRvU3RyaW5nKCkgewogICAgICByZXR1cm4gdGhpcy50ZXh0OwogICAgfQogICAgZW5nbGlzaE5hbWUoKSB7CiAgICAgIHJldHVybiBgV2VlayAke3RoaXMuaXNvV2Vla051bWJlcn0sICR7dGhpcy5pc29ZZWFyTnVtYmVyfWA7CiAgICB9CiAgICBnZXQgZmlyc3REYXkoKSB7CiAgICAgIGNvbnN0IGZpcnN0RGF5ID0gZGF5anMoKS55ZWFyKHRoaXMuaXNvWWVhck51bWJlcikubW9udGgoMSkuZGF0ZSg0KS5pc29XZWVrKHRoaXMuaXNvV2Vla051bWJlcikuc3RhcnRPZigiaXNvV2VlayIpOwogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyTW9udGhEYXkoZmlyc3REYXkuZm9ybWF0KCJZWVlZLU1NLUREIikpOwogICAgfQogICAgZ2V0IGxhc3REYXkoKSB7CiAgICAgIGNvbnN0IGZpcnN0RGF5ID0gZGF5anMoKS55ZWFyKHRoaXMuaXNvWWVhck51bWJlcikuc3RhcnRPZigieWVhciIpLmFkZCgodGhpcy5pc29XZWVrTnVtYmVyIC0gMSkgKiA3LCAiZGF5Iikuc3RhcnRPZigid2VlayIpLmFkZCgxLCAiZGF5Iik7CiAgICAgIGNvbnN0IGxhc3REYXkgPSBmaXJzdERheS5hZGQoNiwgImRheSIpOwogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyTW9udGhEYXkobGFzdERheS5mb3JtYXQoIllZWVktTU0tREQiKSk7CiAgICB9CiAgICBnZXQgeWVhcigpIHsKICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0WWVhcihgJHt0aGlzLmlzb1llYXJOdW1iZXJ9YCk7CiAgICB9CiAgICBhZGRXZWVrcyh3ZWVrcykgewogICAgICBjb25zdCBkYXRlID0gdGhpcy5maXJzdERheS5kYXlqcy5hZGQod2Vla3MsICJ3ZWVrIik7CiAgICAgIGNvbnN0IHMyID0gZGF0ZS5mb3JtYXQoRk9STUFUX0lTT19XRUVLX1lFQVJfV0VFSyk7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXJXZWVrKHMyKTsKICAgIH0KICAgIG1pbnVzKG90aGVyKSB7CiAgICAgIHJldHVybiB0aGlzLmZpcnN0RGF5LmRheWpzLmRpZmYob3RoZXIuZmlyc3REYXkuZGF5anMsICJ3ZWVrIik7CiAgICB9CiAgICBzdGF0aWMgcGFyc2UoczIsIGNhY2hlKSB7CiAgICAgIGNvbnN0IFt5ZWFyLCB3ZWVrXSA9IHMyLnNwbGl0KCItVyIpLm1hcCgoczIyKSA9PiBwYXJzZUludChzMjIsIDEwKSk7CiAgICAgIHJldHVybiBuZXcgWWVhcldlZWtDbGFzcyh5ZWFyLCB3ZWVrLCBjYWNoZSk7CiAgICB9CiAgfQogIGNsYXNzIFllYXJNb250aENsYXNzIHsKICAgIGNvbnN0cnVjdG9yKHllYXJOdW1iZXIsIG1vbnRoTnVtYmVyLCBjYWNoZSkgewogICAgICB0aGlzLnllYXJOdW1iZXIgPSB5ZWFyTnVtYmVyOwogICAgICB0aGlzLm1vbnRoTnVtYmVyID0gbW9udGhOdW1iZXI7CiAgICAgIHRoaXMuY2FjaGUgPSBjYWNoZTsKICAgICAgdGhpcy50eXBlID0gIlllYXJNb250aCI7CiAgICAgIHRoaXMuZGF0ZVN0cmluZyA9IHRoaXMudG9TdHJpbmcoKTsKICAgIH0KICAgIGdldCB0ZXh0KCkgewogICAgICByZXR1cm4gdGhpcy5maXJzdERheS5kYXlqcy5mb3JtYXQoIllZWVktTU0iKTsKICAgIH0KICAgIHRvU3RyaW5nKCkgewogICAgICByZXR1cm4gdGhpcy50ZXh0OwogICAgfQogICAgZW5nbGlzaE5hbWUoKSB7CiAgICAgIHJldHVybiBgJHttb250aE5hbWUodGhpcy5tb250aE51bWJlcil9ICR7dGhpcy55ZWFyTnVtYmVyfWA7CiAgICB9CiAgICBnZXQgZmlyc3REYXkoKSB7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXJNb250aERheShkYXlqcyhgJHt0aGlzLnllYXJOdW1iZXJ9LSR7dGhpcy5tb250aE51bWJlcn0tMDFgKS5mb3JtYXQoIllZWVktTU0tREQiKSk7CiAgICB9CiAgICBnZXQgbGFzdERheSgpIHsKICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0WWVhck1vbnRoRGF5KAogICAgICAgIGRheWpzKGAke3RoaXMueWVhck51bWJlcn0tJHt0aGlzLm1vbnRoTnVtYmVyfS0wMWApLmVuZE9mKCJtb250aCIpLmZvcm1hdCgiWVlZWS1NTS1ERCIpCiAgICAgICk7CiAgICB9CiAgICBnZXQgeWVhcigpIHsKICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0WWVhcihgJHt0aGlzLnllYXJOdW1iZXJ9YCk7CiAgICB9CiAgICBhZGRNb250aHMobW9udGhzKSB7CiAgICAgIGNvbnN0IGRhdGUgPSB0aGlzLmZpcnN0RGF5LmRheWpzLmFkZChtb250aHMsICJtb250aCIpOwogICAgICBjb25zdCBzMiA9IGRhdGUuZm9ybWF0KCJZWVlZLU1NIik7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXJNb250aChzMik7CiAgICB9CiAgICBtaW51cyhvdGhlcikgewogICAgICByZXR1cm4gdGhpcy5maXJzdERheS5kYXlqcy5kaWZmKG90aGVyLmZpcnN0RGF5LmRheWpzLCAibW9udGgiKTsKICAgIH0KICAgIHN0YXRpYyBwYXJzZShzMiwgY2FjaGUpIHsKICAgICAgY29uc3QgW3llYXIsIG1vbnRoXSA9IHMyLnNwbGl0KCItIikubWFwKChzMjIpID0+IHBhcnNlSW50KHMyMiwgMTApKTsKICAgICAgcmV0dXJuIG5ldyBZZWFyTW9udGhDbGFzcyh5ZWFyLCBtb250aCwgY2FjaGUpOwogICAgfQogIH0KICBjbGFzcyBZZWFyQ2xhc3MgewogICAgY29uc3RydWN0b3IoeWVhciwgY2FjaGUpIHsKICAgICAgdGhpcy55ZWFyID0geWVhcjsKICAgICAgdGhpcy5jYWNoZSA9IGNhY2hlOwogICAgICB0aGlzLnR5cGUgPSAiWWVhciI7CiAgICAgIHRoaXMuZGF0ZVN0cmluZyA9IHRoaXMudG9TdHJpbmcoKTsKICAgIH0KICAgIGdldCB0ZXh0KCkgewogICAgICByZXR1cm4gdGhpcy5maXJzdERheS5kYXlqcy5mb3JtYXQoIllZWVkiKTsKICAgIH0KICAgIHRvU3RyaW5nKCkgewogICAgICByZXR1cm4gdGhpcy50ZXh0OwogICAgfQogICAgZW5nbGlzaE5hbWUoKSB7CiAgICAgIHJldHVybiB0aGlzLnllYXIudG9TdHJpbmcoKTsKICAgIH0KICAgIGdldCBmaXJzdE1vbnRoKCkgewogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyTW9udGgoYCR7dGhpcy55ZWFyfS0wMWApOwogICAgfQogICAgZ2V0IGxhc3RNb250aCgpIHsKICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0WWVhck1vbnRoKGAke3RoaXMueWVhcn0tMTJgKTsKICAgIH0KICAgIGdldCBmaXJzdERheSgpIHsKICAgICAgcmV0dXJuIHRoaXMuZmlyc3RNb250aC5maXJzdERheTsKICAgIH0KICAgIGdldCBsYXN0RGF5KCkgewogICAgICByZXR1cm4gdGhpcy5sYXN0TW9udGgubGFzdERheTsKICAgIH0KICAgIGFkZFllYXJzKHllYXJzKSB7CiAgICAgIGNvbnN0IGRhdGUgPSB0aGlzLmZpcnN0RGF5LmRheWpzLmFkZCh5ZWFycywgInllYXIiKTsKICAgICAgY29uc3QgczIgPSBkYXRlLmZvcm1hdCgiWVlZWSIpOwogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyKHMyKTsKICAgIH0KICAgIG1pbnVzKG90aGVyKSB7CiAgICAgIHJldHVybiB0aGlzLmZpcnN0RGF5LmRheWpzLmRpZmYob3RoZXIuZmlyc3REYXkuZGF5anMsICJ5ZWFyIik7CiAgICB9CiAgICBzdGF0aWMgcGFyc2UoczIsIGNhY2hlKSB7CiAgICAgIGNvbnN0IHllYXIgPSBwYXJzZUludChzMiwgMTApOwogICAgICByZXR1cm4gbmV3IFllYXJDbGFzcyh5ZWFyLCBjYWNoZSk7CiAgICB9CiAgfQogIGZ1bmN0aW9uIG1vbnRoTmFtZShtb250aCkgewogICAgcmV0dXJuIGRheWpzKCkubW9udGgobW9udGggLSAxKS5mb3JtYXQoIk1NTU0iKTsKICB9CiAgZnVuY3Rpb24gdG9UZW1wb3JhbCh0ZW1wb3JhbENsYXNzKSB7CiAgICBzd2l0Y2ggKHRlbXBvcmFsQ2xhc3MudHlwZSkgewogICAgICBjYXNlICJZZWFyTW9udGhEYXkiOgogICAgICAgIHJldHVybiB7CiAgICAgICAgICB0eXBlOiAiWWVhck1vbnRoRGF5IiwKICAgICAgICAgIHllYXJOdW1iZXI6IHRlbXBvcmFsQ2xhc3MueWVhck51bWJlciwKICAgICAgICAgIG1vbnRoTnVtYmVyOiB0ZW1wb3JhbENsYXNzLm1vbnRoTnVtYmVyLAogICAgICAgICAgZGF5TnVtYmVyOiB0ZW1wb3JhbENsYXNzLmRheU51bWJlciwKICAgICAgICAgIGRhdGVTdHJpbmc6IHRlbXBvcmFsQ2xhc3MuZGF0ZVN0cmluZwogICAgICAgIH07CiAgICAgIGNhc2UgIlllYXJXZWVrIjoKICAgICAgICByZXR1cm4gewogICAgICAgICAgdHlwZTogIlllYXJXZWVrIiwKICAgICAgICAgIGlzb1llYXJOdW1iZXI6IHRlbXBvcmFsQ2xhc3MuaXNvWWVhck51bWJlciwKICAgICAgICAgIGlzb1dlZWtOdW1iZXI6IHRlbXBvcmFsQ2xhc3MuaXNvV2Vla051bWJlciwKICAgICAgICAgIGRhdGVTdHJpbmc6IHRlbXBvcmFsQ2xhc3MuZGF0ZVN0cmluZwogICAgICAgIH07CiAgICAgIGNhc2UgIlllYXJNb250aCI6CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIHR5cGU6ICJZZWFyTW9udGgiLAogICAgICAgICAgeWVhck51bWJlcjogdGVtcG9yYWxDbGFzcy55ZWFyTnVtYmVyLAogICAgICAgICAgbW9udGhOdW1iZXI6IHRlbXBvcmFsQ2xhc3MubW9udGhOdW1iZXIsCiAgICAgICAgICBkYXRlU3RyaW5nOiB0ZW1wb3JhbENsYXNzLmRhdGVTdHJpbmcKICAgICAgICB9OwogICAgICBjYXNlICJZZWFyIjoKICAgICAgICByZXR1cm4gewogICAgICAgICAgdHlwZTogIlllYXIiLAogICAgICAgICAgeWVhcjogdGVtcG9yYWxDbGFzcy55ZWFyLAogICAgICAgICAgZGF0ZVN0cmluZzogdGVtcG9yYWxDbGFzcy5kYXRlU3RyaW5nCiAgICAgICAgfTsKICAgIH0KICB9CiAgZnVuY3Rpb24gZ2VuZXJhdGVBbGxEYXlzSW5SYW5nZShzdGFydCwgZW5kKSB7CiAgICBjb25zdCBkYXlzID0gW107CiAgICBjb25zdCBkYXlzSW5CZXR3ZWVuID0gZW5kLm1pbnVzKHN0YXJ0KTsKICAgIGZvciAobGV0IGkyID0gMDsgaTIgPD0gZGF5c0luQmV0d2VlbjsgaTIrKykgewogICAgICBkYXlzLnB1c2goc3RhcnQuYWRkRGF5cyhpMikpOwogICAgfQogICAgcmV0dXJuIGRheXM7CiAgfQogIGZ1bmN0aW9uIGdlbmVyYXRlQWxsV2Vla3NJblJhbmdlKHN0YXJ0LCBlbmQpIHsKICAgIGNvbnN0IHdlZWtzID0gW107CiAgICBjb25zdCB3ZWVrc0luQmV0d2VlbiA9IGVuZC5taW51cyhzdGFydCk7CiAgICBmb3IgKGxldCBpMiA9IDA7IGkyIDw9IHdlZWtzSW5CZXR3ZWVuOyBpMisrKSB7CiAgICAgIHdlZWtzLnB1c2goc3RhcnQuYWRkV2Vla3MoaTIpKTsKICAgIH0KICAgIHJldHVybiB3ZWVrczsKICB9CiAgZnVuY3Rpb24gZ2VuZXJhdGVBbGxNb250aHNJblJhbmdlKHN0YXJ0LCBlbmQpIHsKICAgIGNvbnN0IG1vbnRocyA9IFtdOwogICAgY29uc3QgbW9udGhzSW5CZXR3ZWVuID0gZW5kLm1pbnVzKHN0YXJ0KTsKICAgIGZvciAobGV0IGkyID0gMDsgaTIgPD0gbW9udGhzSW5CZXR3ZWVuOyBpMisrKSB7CiAgICAgIG1vbnRocy5wdXNoKHN0YXJ0LmFkZE1vbnRocyhpMikpOwogICAgfQogICAgcmV0dXJuIG1vbnRoczsKICB9CiAgZnVuY3Rpb24gZ2VuZXJhdGVBbGxZZWFyc0luUmFuZ2Uoc3RhcnQsIGVuZCkgewogICAgY29uc3QgeWVhcnMgPSBbXTsKICAgIGNvbnN0IHllYXJzSW5CZXR3ZWVuID0gZW5kLm1pbnVzKHN0YXJ0KTsKICAgIGZvciAobGV0IGkyID0gMDsgaTIgPD0geWVhcnNJbkJldHdlZW47IGkyKyspIHsKICAgICAgeWVhcnMucHVzaChzdGFydC5hZGRZZWFycyhpMikpOwogICAgfQogICAgcmV0dXJuIHllYXJzOwogIH0KICBmdW5jdGlvbiBnZW5lcmF0ZUFsbEluUmFuZ2Uoc3RhcnQsIGVuZCkgewogICAgaWYgKHN0YXJ0ID09PSBudWxsIHx8IGVuZCA9PT0gbnVsbCkgewogICAgICByZXR1cm4gW107CiAgICB9CiAgICBpZiAoc3RhcnQgaW5zdGFuY2VvZiBZZWFyTW9udGhEYXlDbGFzcyAmJiBlbmQgaW5zdGFuY2VvZiBZZWFyTW9udGhEYXlDbGFzcykgewogICAgICByZXR1cm4gZ2VuZXJhdGVBbGxEYXlzSW5SYW5nZShzdGFydCwgZW5kKTsKICAgIH0KICAgIGlmIChzdGFydCBpbnN0YW5jZW9mIFllYXJXZWVrQ2xhc3MgJiYgZW5kIGluc3RhbmNlb2YgWWVhcldlZWtDbGFzcykgewogICAgICByZXR1cm4gZ2VuZXJhdGVBbGxXZWVrc0luUmFuZ2Uoc3RhcnQsIGVuZCk7CiAgICB9CiAgICBpZiAoc3RhcnQgaW5zdGFuY2VvZiBZZWFyTW9udGhDbGFzcyAmJiBlbmQgaW5zdGFuY2VvZiBZZWFyTW9udGhDbGFzcykgewogICAgICByZXR1cm4gZ2VuZXJhdGVBbGxNb250aHNJblJhbmdlKHN0YXJ0LCBlbmQpOwogICAgfQogICAgaWYgKHN0YXJ0IGluc3RhbmNlb2YgWWVhckNsYXNzICYmIGVuZCBpbnN0YW5jZW9mIFllYXJDbGFzcykgewogICAgICByZXR1cm4gZ2VuZXJhdGVBbGxZZWFyc0luUmFuZ2Uoc3RhcnQsIGVuZCk7CiAgICB9CiAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgYXJndW1lbnRzOiBzdGFydCBhbmQgZW5kIG11c3QgYmUgb2YgdGhlIHNhbWUgdHlwZTogJHtzdGFydH0sICR7ZW5kfWApOwogIH0KICBmdW5jdGlvbiBtaW51c1RlbXBvcmFsKGEyLCBiKSB7CiAgICBpZiAoYTIgaW5zdGFuY2VvZiBZZWFyTW9udGhEYXlDbGFzcyAmJiBiIGluc3RhbmNlb2YgWWVhck1vbnRoRGF5Q2xhc3MpIHsKICAgICAgcmV0dXJuIGEyLm1pbnVzKGIpOwogICAgfQogICAgaWYgKGEyIGluc3RhbmNlb2YgWWVhcldlZWtDbGFzcyAmJiBiIGluc3RhbmNlb2YgWWVhcldlZWtDbGFzcykgewogICAgICByZXR1cm4gYTIubWludXMoYik7CiAgICB9CiAgICBpZiAoYTIgaW5zdGFuY2VvZiBZZWFyTW9udGhDbGFzcyAmJiBiIGluc3RhbmNlb2YgWWVhck1vbnRoQ2xhc3MpIHsKICAgICAgcmV0dXJuIGEyLm1pbnVzKGIpOwogICAgfQogICAgaWYgKGEyIGluc3RhbmNlb2YgWWVhckNsYXNzICYmIGIgaW5zdGFuY2VvZiBZZWFyQ2xhc3MpIHsKICAgICAgcmV0dXJuIGEyLm1pbnVzKGIpOwogICAgfQogICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgY29tcGFyZSAke2EyfSBhbmQgJHtifWApOwogIH0KICBmdW5jdGlvbiBjb21wYXJlVGVtcG9yYWwoYTIsIGIpIHsKICAgIGlmIChhMiA9PT0gbnVsbCkgewogICAgICByZXR1cm4gMTsKICAgIH0KICAgIGlmIChiID09PSBudWxsKSB7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGNvbnN0IGRpZmYgPSBtaW51c1RlbXBvcmFsKGEyLCBiKTsKICAgIGlmIChkaWZmIDwgMCkgewogICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBpZiAoZGlmZiA+IDApIHsKICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gMDsKICB9CiAgZnVuY3Rpb24gZ2V0TWluTWF4VGVtcG9yYWwodmFsdWVzKSB7CiAgICBsZXQgbWluID0gbnVsbDsKICAgIGxldCBtYXggPSBudWxsOwogICAgZm9yIChjb25zdCB2YWx1ZSBvZiB2YWx1ZXMpIHsKICAgICAgaWYgKHZhbHVlID09PSBudWxsKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgaWYgKG1pbiA9PT0gbnVsbCB8fCBjb21wYXJlVGVtcG9yYWwodmFsdWUsIG1pbikgPCAwKSB7CiAgICAgICAgbWluID0gdmFsdWU7CiAgICAgIH0KICAgICAgaWYgKG1heCA9PT0gbnVsbCB8fCBjb21wYXJlVGVtcG9yYWwodmFsdWUsIG1heCkgPiAwKSB7CiAgICAgICAgbWF4ID0gdmFsdWU7CiAgICAgIH0KICAgIH0KICAgIGlmIChtaW4gPT09IG51bGwgfHwgbWF4ID09PSBudWxsKSB7CiAgICAgIHJldHVybiB7IG1pbjogbnVsbCwgbWF4OiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyBtaW4sIG1heCB9OwogIH0KICBmdW5jdGlvbiBwYXJzZURhdGVTdHJpbmdUb1RlbXBvcmFsKGRhdGUsIGdyYW51bGFyaXR5KSB7CiAgICBjb25zdCBjYWNoZSA9IFRlbXBvcmFsQ2FjaGUuZ2V0SW5zdGFuY2UoKTsKICAgIGNvbnN0IGRheSA9IGNhY2hlLmdldFllYXJNb250aERheShkYXRlKTsKICAgIHN3aXRjaCAoZ3JhbnVsYXJpdHkpIHsKICAgICAgY2FzZSAiZGF5IjoKICAgICAgICByZXR1cm4gZGF5OwogICAgICBjYXNlICJ3ZWVrIjoKICAgICAgICByZXR1cm4gZGF5LndlZWs7CiAgICAgIGNhc2UgIm1vbnRoIjoKICAgICAgICByZXR1cm4gZGF5Lm1vbnRoOwogICAgICBjYXNlICJ5ZWFyIjoKICAgICAgICByZXR1cm4gZGF5LnllYXI7CiAgICB9CiAgfQogIGZ1bmN0aW9uIGRhdGVSYW5nZUNvbXBhcmUoYTIsIGIpIHsKICAgIGlmIChhMi5kYXRlUmFuZ2UgPT09IG51bGwpIHsKICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICBpZiAoYi5kYXRlUmFuZ2UgPT09IG51bGwpIHsKICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgcmV0dXJuIGNvbXBhcmVUZW1wb3JhbChhMi5kYXRlUmFuZ2UsIGIuZGF0ZVJhbmdlKTsKICB9CiAgZnVuY3Rpb24gbWFwRGF0ZVRvR3JhbnVsYXJpdHlSYW5nZShkYXRhLCBncmFudWxhcml0eSkgewogICAgcmV0dXJuIHsKICAgICAgZGF0ZVJhbmdlOiBkYXRhLmRhdGUgPT09IG51bGwgPyBudWxsIDogcGFyc2VEYXRlU3RyaW5nVG9UZW1wb3JhbChkYXRhLmRhdGUsIGdyYW51bGFyaXR5KSwKICAgICAgY291bnQ6IGRhdGEuY291bnQKICAgIH07CiAgfQogIGNvbnN0IHN1YnN0aXR1dGlvblJlZ2V4ID0gL14oKD88c2VnbWVudD5bQS1aYS16MC05Xy1dKykoPz06KTopPyg/PHZhbHVlQXRSZWZlcmVuY2U+W0EtWmEtel0pPyg/PHBvc2l0aW9uPlxkKykoPzxzdWJzdGl0dXRpb25WYWx1ZT5bQS1aYS16Ll0pPyQvOwogIGNsYXNzIFN1YnN0aXR1dGlvbkNsYXNzIHsKICAgIGNvbnN0cnVjdG9yKHNlZ21lbnQsIHZhbHVlQXRSZWZlcmVuY2UsIHN1YnN0aXR1dGlvblZhbHVlLCBwb3NpdGlvbikgewogICAgICB0aGlzLnNlZ21lbnQgPSBzZWdtZW50OwogICAgICB0aGlzLnZhbHVlQXRSZWZlcmVuY2UgPSB2YWx1ZUF0UmVmZXJlbmNlOwogICAgICB0aGlzLnN1YnN0aXR1dGlvblZhbHVlID0gc3Vic3RpdHV0aW9uVmFsdWU7CiAgICAgIHRoaXMucG9zaXRpb24gPSBwb3NpdGlvbjsKICAgICAgdGhpcy50eXBlID0gInN1YnN0aXR1dGlvbiI7CiAgICAgIGNvbnN0IHNlZ21lbnRTdHJpbmcgPSB0aGlzLnNlZ21lbnQgPyBgJHt0aGlzLnNlZ21lbnR9OmAgOiAiIjsKICAgICAgY29uc3QgdmFsdWVBdFJlZmVyZW5jZVN0cmluZyA9IHRoaXMudmFsdWVBdFJlZmVyZW5jZSA/IGAke3RoaXMudmFsdWVBdFJlZmVyZW5jZX1gIDogIiI7CiAgICAgIGNvbnN0IHN1YnN0aXR1dGlvblZhbHVlU3RyaW5nID0gdGhpcy5zdWJzdGl0dXRpb25WYWx1ZSA/IGAke3RoaXMuc3Vic3RpdHV0aW9uVmFsdWV9YCA6ICIiOwogICAgICB0aGlzLmNvZGUgPSBgJHtzZWdtZW50U3RyaW5nfSR7dmFsdWVBdFJlZmVyZW5jZVN0cmluZ30ke3RoaXMucG9zaXRpb259JHtzdWJzdGl0dXRpb25WYWx1ZVN0cmluZ31gOwogICAgfQogICAgZXF1YWxzKG90aGVyKSB7CiAgICAgIGlmICghKG90aGVyIGluc3RhbmNlb2YgU3Vic3RpdHV0aW9uQ2xhc3MpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLnNlZ21lbnQgPT09IG90aGVyLnNlZ21lbnQgJiYgdGhpcy52YWx1ZUF0UmVmZXJlbmNlID09PSBvdGhlci52YWx1ZUF0UmVmZXJlbmNlICYmIHRoaXMuc3Vic3RpdHV0aW9uVmFsdWUgPT09IG90aGVyLnN1YnN0aXR1dGlvblZhbHVlICYmIHRoaXMucG9zaXRpb24gPT09IG90aGVyLnBvc2l0aW9uOwogICAgfQogICAgdG9TdHJpbmcoKSB7CiAgICAgIHJldHVybiB0aGlzLmNvZGU7CiAgICB9CiAgICBzdGF0aWMgcGFyc2UobXV0YXRpb25TdHIpIHsKICAgICAgY29uc3QgbWF0Y2ggPSBtdXRhdGlvblN0ci5tYXRjaChzdWJzdGl0dXRpb25SZWdleCk7CiAgICAgIGlmIChtYXRjaCA9PT0gbnVsbCB8fCBtYXRjaC5ncm91cHMgPT09IHZvaWQgMCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBuZXcgU3Vic3RpdHV0aW9uQ2xhc3MoCiAgICAgICAgbWF0Y2guZ3JvdXBzLnNlZ21lbnQsCiAgICAgICAgbWF0Y2guZ3JvdXBzLnZhbHVlQXRSZWZlcmVuY2UsCiAgICAgICAgbWF0Y2guZ3JvdXBzLnN1YnN0aXR1dGlvblZhbHVlLAogICAgICAgIHBhcnNlSW50KG1hdGNoLmdyb3Vwcy5wb3NpdGlvbiwgMTApCiAgICAgICk7CiAgICB9CiAgfQogIGNvbnN0IGRlbGV0aW9uUmVnZXggPSAvXigoPzxzZWdtZW50PltBLVphLXowLTlfLV0rKSg/PTopOik/KD88dmFsdWVBdFJlZmVyZW5jZT5bQS1aYS16XSk/KD88cG9zaXRpb24+XGQrKSgtKSQvOwogIGNsYXNzIERlbGV0aW9uQ2xhc3MgewogICAgY29uc3RydWN0b3Ioc2VnbWVudCwgdmFsdWVBdFJlZmVyZW5jZSwgcG9zaXRpb24pIHsKICAgICAgdGhpcy5zZWdtZW50ID0gc2VnbWVudDsKICAgICAgdGhpcy52YWx1ZUF0UmVmZXJlbmNlID0gdmFsdWVBdFJlZmVyZW5jZTsKICAgICAgdGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uOwogICAgICB0aGlzLnR5cGUgPSAiZGVsZXRpb24iOwogICAgICBjb25zdCBzZWdtZW50U3RyaW5nID0gdGhpcy5zZWdtZW50ID8gYCR7dGhpcy5zZWdtZW50fTpgIDogIiI7CiAgICAgIGNvbnN0IHZhbHVlQXRSZWZlcmVuY2VTdHJpbmcgPSB0aGlzLnZhbHVlQXRSZWZlcmVuY2UgPyBgJHt0aGlzLnZhbHVlQXRSZWZlcmVuY2V9YCA6ICIiOwogICAgICB0aGlzLmNvZGUgPSBgJHtzZWdtZW50U3RyaW5nfSR7dmFsdWVBdFJlZmVyZW5jZVN0cmluZ30ke3RoaXMucG9zaXRpb259LWA7CiAgICB9CiAgICBlcXVhbHMob3RoZXIpIHsKICAgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBEZWxldGlvbkNsYXNzKSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5zZWdtZW50ID09PSBvdGhlci5zZWdtZW50ICYmIHRoaXMudmFsdWVBdFJlZmVyZW5jZSA9PT0gb3RoZXIudmFsdWVBdFJlZmVyZW5jZSAmJiB0aGlzLnBvc2l0aW9uID09PSBvdGhlci5wb3NpdGlvbjsKICAgIH0KICAgIHRvU3RyaW5nKCkgewogICAgICByZXR1cm4gdGhpcy5jb2RlOwogICAgfQogICAgc3RhdGljIHBhcnNlKG11dGF0aW9uU3RyKSB7CiAgICAgIGNvbnN0IG1hdGNoID0gbXV0YXRpb25TdHIubWF0Y2goZGVsZXRpb25SZWdleCk7CiAgICAgIGlmIChtYXRjaCA9PT0gbnVsbCB8fCBtYXRjaC5ncm91cHMgPT09IHZvaWQgMCkgewogICAgICAgIHJldHVybiBudWxsOwogICAgICB9CiAgICAgIHJldHVybiBuZXcgRGVsZXRpb25DbGFzcygKICAgICAgICBtYXRjaC5ncm91cHMuc2VnbWVudCwKICAgICAgICBtYXRjaC5ncm91cHMudmFsdWVBdFJlZmVyZW5jZSwKICAgICAgICBwYXJzZUludChtYXRjaC5ncm91cHMucG9zaXRpb24sIDEwKQogICAgICApOwogICAgfQogIH0KICBmdW5jdGlvbiB0b1N1YnN0aXR1dGlvbk9yRGVsZXRpb24obXV0YXRpb24pIHsKICAgIHN3aXRjaCAobXV0YXRpb24udHlwZSkgewogICAgICBjYXNlICJzdWJzdGl0dXRpb24iOgogICAgICAgIHJldHVybiB7CiAgICAgICAgICB0eXBlOiAic3Vic3RpdHV0aW9uIiwKICAgICAgICAgIGNvZGU6IG11dGF0aW9uLmNvZGUsCiAgICAgICAgICBzZWdtZW50OiBtdXRhdGlvbi5zZWdtZW50LAogICAgICAgICAgcG9zaXRpb246IG11dGF0aW9uLnBvc2l0aW9uLAogICAgICAgICAgdmFsdWVBdFJlZmVyZW5jZTogbXV0YXRpb24udmFsdWVBdFJlZmVyZW5jZSwKICAgICAgICAgIHN1YnN0aXR1dGlvblZhbHVlOiBtdXRhdGlvbi5zdWJzdGl0dXRpb25WYWx1ZQogICAgICAgIH07CiAgICAgIGNhc2UgImRlbGV0aW9uIjoKICAgICAgICByZXR1cm4gewogICAgICAgICAgdHlwZTogImRlbGV0aW9uIiwKICAgICAgICAgIGNvZGU6IG11dGF0aW9uLmNvZGUsCiAgICAgICAgICBzZWdtZW50OiBtdXRhdGlvbi5zZWdtZW50LAogICAgICAgICAgcG9zaXRpb246IG11dGF0aW9uLnBvc2l0aW9uLAogICAgICAgICAgdmFsdWVBdFJlZmVyZW5jZTogbXV0YXRpb24udmFsdWVBdFJlZmVyZW5jZQogICAgICAgIH07CiAgICB9CiAgfQogIGNsYXNzIEZldGNoU3Vic3RpdHV0aW9uc09yRGVsZXRpb25zT3BlcmF0b3IgewogICAgY29uc3RydWN0b3IoZmlsdGVyLCBzZXF1ZW5jZVR5cGUsIG1pblByb3BvcnRpb24pIHsKICAgICAgdGhpcy5maWx0ZXIgPSBmaWx0ZXI7CiAgICAgIHRoaXMuc2VxdWVuY2VUeXBlID0gc2VxdWVuY2VUeXBlOwogICAgICB0aGlzLm1pblByb3BvcnRpb24gPSBtaW5Qcm9wb3J0aW9uOwogICAgfQogICAgYXN5bmMgZXZhbHVhdGUobGFwaXMsIHNpZ25hbCkgewogICAgICBjb25zdCBtdXRhdGlvbnMgPSBhd2FpdCB0aGlzLmZldGNoTXV0YXRpb25zKGxhcGlzLCBzaWduYWwpOwogICAgICBjb25zdCBjb250ZW50ID0gbXV0YXRpb25zLm1hcCgKICAgICAgICAoeyBjb3VudCwgcHJvcG9ydGlvbiwgbXV0YXRpb25Gcm9tLCBtdXRhdGlvblRvLCBwb3NpdGlvbiwgc2VxdWVuY2VOYW1lIH0pID0+IHsKICAgICAgICAgIGlmIChtdXRhdGlvblRvID09PSAiLSIpIHsKICAgICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICB0eXBlOiAiZGVsZXRpb24iLAogICAgICAgICAgICAgIG11dGF0aW9uOiBuZXcgRGVsZXRpb25DbGFzcyhzZXF1ZW5jZU5hbWUgPz8gdm9pZCAwLCBtdXRhdGlvbkZyb20sIHBvc2l0aW9uKSwKICAgICAgICAgICAgICBjb3VudCwKICAgICAgICAgICAgICBwcm9wb3J0aW9uCiAgICAgICAgICAgIH07CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICB0eXBlOiAic3Vic3RpdHV0aW9uIiwKICAgICAgICAgICAgbXV0YXRpb246IG5ldyBTdWJzdGl0dXRpb25DbGFzcyhzZXF1ZW5jZU5hbWUgPz8gdm9pZCAwLCBtdXRhdGlvbkZyb20sIG11dGF0aW9uVG8sIHBvc2l0aW9uKSwKICAgICAgICAgICAgY291bnQsCiAgICAgICAgICAgIHByb3BvcnRpb24KICAgICAgICAgIH07CiAgICAgICAgfQogICAgICApOwogICAgICByZXR1cm4geyBjb250ZW50IH07CiAgICB9CiAgICBhc3luYyBmZXRjaE11dGF0aW9ucyhsYXBpcywgc2lnbmFsKSB7CiAgICAgIGNvbnN0IGZpbHRlciA9IHsKICAgICAgICAuLi50aGlzLmZpbHRlciwKICAgICAgICBtaW5Qcm9wb3J0aW9uOiB0aGlzLm1pblByb3BvcnRpb24KICAgICAgfTsKICAgICAgcmV0dXJuIGZldGNoU3Vic3RpdHV0aW9uc09yRGVsZXRpb25zKGxhcGlzLCBmaWx0ZXIsIHRoaXMuc2VxdWVuY2VUeXBlLCBzaWduYWwpLnRoZW4oCiAgICAgICAgKHJlc3BvbnNlKSA9PiByZXNwb25zZS5kYXRhCiAgICAgICk7CiAgICB9CiAgfQogIHZhciBsJDE7CiAgbCQxID0geyBfX2U6IGZ1bmN0aW9uKG4sIGwyLCB1MiwgdCkgewogICAgZm9yICh2YXIgaTIsIG8sIHIyOyBsMiA9IGwyLl9fOyApIGlmICgoaTIgPSBsMi5fX2MpICYmICFpMi5fXykgdHJ5IHsKICAgICAgaWYgKChvID0gaTIuY29uc3RydWN0b3IpICYmIG51bGwgIT0gby5nZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IgJiYgKGkyLnNldFN0YXRlKG8uZ2V0RGVyaXZlZFN0YXRlRnJvbUVycm9yKG4pKSwgcjIgPSBpMi5fX2QpLCBudWxsICE9IGkyLmNvbXBvbmVudERpZENhdGNoICYmIChpMi5jb21wb25lbnREaWRDYXRjaChuLCB0IHx8IHt9KSwgcjIgPSBpMi5fX2QpLCByMikgcmV0dXJuIGkyLl9fRSA9IGkyOwogICAgfSBjYXRjaCAobDMpIHsKICAgICAgbiA9IGwzOwogICAgfQogICAgdGhyb3cgbjsKICB9IH0sICJmdW5jdGlvbiIgPT0gdHlwZW9mIFByb21pc2UgPyBQcm9taXNlLnByb3RvdHlwZS50aGVuLmJpbmQoUHJvbWlzZS5yZXNvbHZlKCkpIDogc2V0VGltZW91dDsKICB2YXIgciwgdSwgaSwgZiA9IFtdLCBjID0gbCQxLCBlID0gYy5fX2IsIGEgPSBjLl9fciwgdiA9IGMuZGlmZmVkLCBsID0gYy5fX2MsIG0gPSBjLnVubW91bnQsIHMgPSBjLl9fOwogIGZ1bmN0aW9uIGooKSB7CiAgICBmb3IgKHZhciBuOyBuID0gZi5zaGlmdCgpOyApIGlmIChuLl9fUCAmJiBuLl9fSCkgdHJ5IHsKICAgICAgbi5fX0guX19oLmZvckVhY2goeiksIG4uX19ILl9faC5mb3JFYWNoKEIpLCBuLl9fSC5fX2ggPSBbXTsKICAgIH0gY2F0Y2ggKHQpIHsKICAgICAgbi5fX0guX19oID0gW10sIGMuX19lKHQsIG4uX192KTsKICAgIH0KICB9CiAgYy5fX2IgPSBmdW5jdGlvbihuKSB7CiAgICByID0gbnVsbCwgZSAmJiBlKG4pOwogIH0sIGMuX18gPSBmdW5jdGlvbihuLCB0KSB7CiAgICBuICYmIHQuX19rICYmIHQuX19rLl9fbSAmJiAobi5fX20gPSB0Ll9fay5fX20pLCBzICYmIHMobiwgdCk7CiAgfSwgYy5fX3IgPSBmdW5jdGlvbihuKSB7CiAgICBhICYmIGEobik7CiAgICB2YXIgaTIgPSAociA9IG4uX19jKS5fX0g7CiAgICBpMiAmJiAodSA9PT0gciA/IChpMi5fX2ggPSBbXSwgci5fX2ggPSBbXSwgaTIuX18uZm9yRWFjaChmdW5jdGlvbihuMikgewogICAgICBuMi5fX04gJiYgKG4yLl9fID0gbjIuX19OKSwgbjIuaSA9IG4yLl9fTiA9IHZvaWQgMDsKICAgIH0pKSA6IChpMi5fX2guZm9yRWFjaCh6KSwgaTIuX19oLmZvckVhY2goQiksIGkyLl9faCA9IFtdLCAwKSksIHUgPSByOwogIH0sIGMuZGlmZmVkID0gZnVuY3Rpb24obikgewogICAgdiAmJiB2KG4pOwogICAgdmFyIHQgPSBuLl9fYzsKICAgIHQgJiYgdC5fX0ggJiYgKHQuX19ILl9faC5sZW5ndGggJiYgKDEgIT09IGYucHVzaCh0KSAmJiBpID09PSBjLnJlcXVlc3RBbmltYXRpb25GcmFtZSB8fCAoKGkgPSBjLnJlcXVlc3RBbmltYXRpb25GcmFtZSkgfHwgdykoaikpLCB0Ll9fSC5fXy5mb3JFYWNoKGZ1bmN0aW9uKG4yKSB7CiAgICAgIG4yLmkgJiYgKG4yLl9fSCA9IG4yLmkpLCBuMi5pID0gdm9pZCAwOwogICAgfSkpLCB1ID0gciA9IG51bGw7CiAgfSwgYy5fX2MgPSBmdW5jdGlvbihuLCB0KSB7CiAgICB0LnNvbWUoZnVuY3Rpb24objIpIHsKICAgICAgdHJ5IHsKICAgICAgICBuMi5fX2guZm9yRWFjaCh6KSwgbjIuX19oID0gbjIuX19oLmZpbHRlcihmdW5jdGlvbihuMykgewogICAgICAgICAgcmV0dXJuICFuMy5fXyB8fCBCKG4zKTsKICAgICAgICB9KTsKICAgICAgfSBjYXRjaCAocjIpIHsKICAgICAgICB0LnNvbWUoZnVuY3Rpb24objMpIHsKICAgICAgICAgIG4zLl9faCAmJiAobjMuX19oID0gW10pOwogICAgICAgIH0pLCB0ID0gW10sIGMuX19lKHIyLCBuMi5fX3YpOwogICAgICB9CiAgICB9KSwgbCAmJiBsKG4sIHQpOwogIH0sIGMudW5tb3VudCA9IGZ1bmN0aW9uKG4pIHsKICAgIG0gJiYgbShuKTsKICAgIHZhciB0LCByMiA9IG4uX19jOwogICAgcjIgJiYgcjIuX19IICYmIChyMi5fX0guX18uZm9yRWFjaChmdW5jdGlvbihuMikgewogICAgICB0cnkgewogICAgICAgIHoobjIpOwogICAgICB9IGNhdGNoIChuMykgewogICAgICAgIHQgPSBuMzsKICAgICAgfQogICAgfSksIHIyLl9fSCA9IHZvaWQgMCwgdCAmJiBjLl9fZSh0LCByMi5fX3YpKTsKICB9OwogIHZhciBrID0gImZ1bmN0aW9uIiA9PSB0eXBlb2YgcmVxdWVzdEFuaW1hdGlvbkZyYW1lOwogIGZ1bmN0aW9uIHcobikgewogICAgdmFyIHQsIHIyID0gZnVuY3Rpb24oKSB7CiAgICAgIGNsZWFyVGltZW91dCh1MiksIGsgJiYgY2FuY2VsQW5pbWF0aW9uRnJhbWUodCksIHNldFRpbWVvdXQobik7CiAgICB9LCB1MiA9IHNldFRpbWVvdXQocjIsIDEwMCk7CiAgICBrICYmICh0ID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHIyKSk7CiAgfQogIGZ1bmN0aW9uIHoobikgewogICAgdmFyIHQgPSByLCB1MiA9IG4uX19jOwogICAgImZ1bmN0aW9uIiA9PSB0eXBlb2YgdTIgJiYgKG4uX19jID0gdm9pZCAwLCB1MigpKSwgciA9IHQ7CiAgfQogIGZ1bmN0aW9uIEIobikgewogICAgdmFyIHQgPSByOwogICAgbi5fX2MgPSBuLl9fKCksIHIgPSB0OwogIH0KICBjbGFzcyBVc2VyRmFjaW5nRXJyb3IgZXh0ZW5kcyBFcnJvciB7CiAgICBjb25zdHJ1Y3RvcihoZWFkbGluZSwgbWVzc2FnZSkgewogICAgICBzdXBlcihtZXNzYWdlKTsKICAgICAgdGhpcy5oZWFkbGluZSA9IGhlYWRsaW5lOwogICAgICB0aGlzLm5hbWUgPSAiVXNlckZhY2luZ0Vycm9yIjsKICAgIH0KICB9CiAgY2xhc3MgTWFwMmRCYXNlIHsKICAgIGNvbnN0cnVjdG9yKHNlcmlhbGl6ZUZpcnN0QXhpcywgc2VyaWFsaXplU2Vjb25kQXhpcywgaW5pdGlhbENvbnRlbnQpIHsKICAgICAgdGhpcy5zZXJpYWxpemVGaXJzdEF4aXMgPSBzZXJpYWxpemVGaXJzdEF4aXM7CiAgICAgIHRoaXMuc2VyaWFsaXplU2Vjb25kQXhpcyA9IHNlcmlhbGl6ZVNlY29uZEF4aXM7CiAgICAgIHRoaXMuZGF0YSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgIHRoaXMua2V5c0ZpcnN0QXhpcyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgIHRoaXMua2V5c1NlY29uZEF4aXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogICAgICBpZiAoaW5pdGlhbENvbnRlbnQpIHsKICAgICAgICB0aGlzLmtleXNGaXJzdEF4aXMgPSBuZXcgTWFwKGluaXRpYWxDb250ZW50LmtleXNGaXJzdEF4aXMpOwogICAgICAgIHRoaXMua2V5c1NlY29uZEF4aXMgPSBuZXcgTWFwKGluaXRpYWxDb250ZW50LmtleXNTZWNvbmRBeGlzKTsKICAgICAgICB0aGlzLmRhdGEgPSBuZXcgTWFwKGluaXRpYWxDb250ZW50LmRhdGEpOwogICAgICB9CiAgICB9CiAgICBnZXQoa2V5Rmlyc3RBeGlzLCBrZXlTZWNvbmRBeGlzKSB7CiAgICAgIHZhciBfYTsKICAgICAgY29uc3Qgc2VyaWFsaXplZEtleUZpcnN0QXhpcyA9IHRoaXMuc2VyaWFsaXplRmlyc3RBeGlzKGtleUZpcnN0QXhpcyk7CiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRLZXlTZWNvbmRBeGlzID0gdGhpcy5zZXJpYWxpemVTZWNvbmRBeGlzKGtleVNlY29uZEF4aXMpOwogICAgICByZXR1cm4gKF9hID0gdGhpcy5kYXRhLmdldChzZXJpYWxpemVkS2V5Rmlyc3RBeGlzKSkgPT0gbnVsbCA/IHZvaWQgMCA6IF9hLmdldChzZXJpYWxpemVkS2V5U2Vjb25kQXhpcyk7CiAgICB9CiAgICBnZXRSb3coa2V5LCBmaWxsRW1wdHlXaXRoKSB7CiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRLZXlGaXJzdEF4aXMgPSB0aGlzLnNlcmlhbGl6ZUZpcnN0QXhpcyhrZXkpOwogICAgICBjb25zdCByb3cgPSB0aGlzLmRhdGEuZ2V0KHNlcmlhbGl6ZWRLZXlGaXJzdEF4aXMpOwogICAgICBpZiAocm93ID09PSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gW107CiAgICAgIH0KICAgICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5rZXlzU2Vjb25kQXhpcy5rZXlzKCkpLm1hcCgoa2V5MikgPT4gcm93LmdldChrZXkyKSA/PyBmaWxsRW1wdHlXaXRoKTsKICAgIH0KICAgIHNldChrZXlGaXJzdEF4aXMsIGtleVNlY29uZEF4aXMsIHZhbHVlKSB7CiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRLZXlGaXJzdEF4aXMgPSB0aGlzLnNlcmlhbGl6ZUZpcnN0QXhpcyhrZXlGaXJzdEF4aXMpOwogICAgICBjb25zdCBzZXJpYWxpemVkS2V5U2Vjb25kQXhpcyA9IHRoaXMuc2VyaWFsaXplU2Vjb25kQXhpcyhrZXlTZWNvbmRBeGlzKTsKICAgICAgaWYgKCF0aGlzLmRhdGEuaGFzKHNlcmlhbGl6ZWRLZXlGaXJzdEF4aXMpKSB7CiAgICAgICAgdGhpcy5kYXRhLnNldChzZXJpYWxpemVkS2V5Rmlyc3RBeGlzLCAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsKICAgICAgfQogICAgICB0aGlzLmRhdGEuZ2V0KHNlcmlhbGl6ZWRLZXlGaXJzdEF4aXMpLnNldChzZXJpYWxpemVkS2V5U2Vjb25kQXhpcywgdmFsdWUpOwogICAgICB0aGlzLmtleXNGaXJzdEF4aXMuc2V0KHNlcmlhbGl6ZWRLZXlGaXJzdEF4aXMsIGtleUZpcnN0QXhpcyk7CiAgICAgIHRoaXMua2V5c1NlY29uZEF4aXMuc2V0KHNlcmlhbGl6ZWRLZXlTZWNvbmRBeGlzLCBrZXlTZWNvbmRBeGlzKTsKICAgIH0KICAgIGRlbGV0ZVJvdyhrZXkpIHsKICAgICAgY29uc3Qgc2VyaWFsaXplZEtleUZpcnN0QXhpcyA9IHRoaXMuc2VyaWFsaXplRmlyc3RBeGlzKGtleSk7CiAgICAgIHRoaXMuZGF0YS5kZWxldGUoc2VyaWFsaXplZEtleUZpcnN0QXhpcyk7CiAgICAgIHRoaXMua2V5c0ZpcnN0QXhpcy5kZWxldGUoc2VyaWFsaXplZEtleUZpcnN0QXhpcyk7CiAgICB9CiAgICBnZXRGaXJzdEF4aXNLZXlzKCkgewogICAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmtleXNGaXJzdEF4aXMudmFsdWVzKCkpOwogICAgfQogICAgZ2V0U2Vjb25kQXhpc0tleXMoKSB7CiAgICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMua2V5c1NlY29uZEF4aXMudmFsdWVzKCkpOwogICAgfQogICAgZ2V0QXNBcnJheShmaWxsRW1wdHlXaXRoKSB7CiAgICAgIHJldHVybiB0aGlzLmdldEZpcnN0QXhpc0tleXMoKS5tYXAoKGZpcnN0QXhpc0tleSkgPT4gewogICAgICAgIHJldHVybiB0aGlzLmdldFNlY29uZEF4aXNLZXlzKCkubWFwKChzZWNvbmRBeGlzS2V5KSA9PiB7CiAgICAgICAgICByZXR1cm4gdGhpcy5nZXQoZmlyc3RBeGlzS2V5LCBzZWNvbmRBeGlzS2V5KSA/PyBmaWxsRW1wdHlXaXRoOwogICAgICAgIH0pOwogICAgICB9KTsKICAgIH0KICAgIGdldENvbnRlbnRzKCkgewogICAgICByZXR1cm4gewogICAgICAgIGtleXNGaXJzdEF4aXM6IHRoaXMua2V5c0ZpcnN0QXhpcywKICAgICAgICBrZXlzU2Vjb25kQXhpczogdGhpcy5rZXlzU2Vjb25kQXhpcywKICAgICAgICBkYXRhOiB0aGlzLmRhdGEKICAgICAgfTsKICAgIH0KICB9CiAgY2xhc3MgQmFzZU11dGF0aW9uT3ZlclRpbWVEYXRhTWFwIGV4dGVuZHMgTWFwMmRCYXNlIHsKICAgIGNvbnN0cnVjdG9yKGluaXRpYWxDb250ZW50KSB7CiAgICAgIHN1cGVyKHNlcmlhbGl6ZVN1YnN0aXR1dGlvbk9yRGVsZXRpb24sIHNlcmlhbGl6ZVRlbXBvcmFsLCBpbml0aWFsQ29udGVudCk7CiAgICB9CiAgfQogIGNvbnN0IHNvcnRTdWJzdGl0dXRpb25zQW5kRGVsZXRpb25zID0gKGEyLCBiKSA9PiB7CiAgICBpZiAoYTIuc2VnbWVudCAhPT0gYi5zZWdtZW50KSB7CiAgICAgIHJldHVybiBjb21wYXJlU2VnbWVudHMoYTIuc2VnbWVudCwgYi5zZWdtZW50KTsKICAgIH0KICAgIGlmIChhMi5wb3NpdGlvbiAhPT0gYi5wb3NpdGlvbikgewogICAgICByZXR1cm4gY29tcGFyZVBvc2l0aW9ucyhhMi5wb3NpdGlvbiwgYi5wb3NpdGlvbik7CiAgICB9CiAgICBjb25zdCBhSXNEZWxldGlvbiA9IGEyIGluc3RhbmNlb2YgRGVsZXRpb25DbGFzczsKICAgIGNvbnN0IGJJc0RlbGV0aW9uID0gYiBpbnN0YW5jZW9mIERlbGV0aW9uQ2xhc3M7CiAgICBpZiAoYUlzRGVsZXRpb24gIT09IGJJc0RlbGV0aW9uKSB7CiAgICAgIHJldHVybiBhSXNEZWxldGlvbiA/IDEgOiAtMTsKICAgIH0KICAgIGlmICghYUlzRGVsZXRpb24gJiYgIWJJc0RlbGV0aW9uKSB7CiAgICAgIGlmIChhMi5zdWJzdGl0dXRpb25WYWx1ZSAhPT0gYi5zdWJzdGl0dXRpb25WYWx1ZSkgewogICAgICAgIHJldHVybiBjb21wYXJlU3Vic3RpdHV0aW9uVmFsdWVzKGEyLnN1YnN0aXR1dGlvblZhbHVlLCBiLnN1YnN0aXR1dGlvblZhbHVlKTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIDA7CiAgfTsKICBjb25zdCBjb21wYXJlU2VnbWVudHMgPSAoYTIsIGIpID0+IHsKICAgIGlmIChhMiA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGlmIChiID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gYTIubG9jYWxlQ29tcGFyZShiKTsKICB9OwogIGNvbnN0IGNvbXBhcmVQb3NpdGlvbnMgPSAoYTIsIGIpID0+IHsKICAgIHJldHVybiBhMiAtIGI7CiAgfTsKICBjb25zdCBjb21wYXJlU3Vic3RpdHV0aW9uVmFsdWVzID0gKGEyLCBiKSA9PiB7CiAgICBpZiAoYTIgPT09IHZvaWQgMCkgewogICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBpZiAoYiA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiAxOwogICAgfQogICAgcmV0dXJuIGEyLmxvY2FsZUNvbXBhcmUoYik7CiAgfTsKICBjb25zdCBNQVhfTlVNQkVSX09GX0dSSURfQ09MVU1OUyA9IDIwMDsKICBhc3luYyBmdW5jdGlvbiBxdWVyeU92ZXJhbGxNdXRhdGlvbkRhdGEoewogICAgbGFwaXNGaWx0ZXIsCiAgICBzZXF1ZW5jZVR5cGUsCiAgICBsYXBpcywKICAgIGdyYW51bGFyaXR5LAogICAgbGFwaXNEYXRlRmllbGQsCiAgICBzaWduYWwKICB9KSB7CiAgICBjb25zdCBhbGxEYXRlcyA9IGF3YWl0IGdldERhdGVzSW5EYXRhc2V0KGxhcGlzRmlsdGVyLCBsYXBpcywgZ3JhbnVsYXJpdHksIGxhcGlzRGF0ZUZpZWxkLCBzaWduYWwpOwogICAgY29uc3QgZmlsdGVyID0gewogICAgICAuLi5sYXBpc0ZpbHRlciwKICAgICAgW2Ake2xhcGlzRGF0ZUZpZWxkfUZyb21gXTogYWxsRGF0ZXNbMF0uZmlyc3REYXkudG9TdHJpbmcoKSwKICAgICAgW2Ake2xhcGlzRGF0ZUZpZWxkfVRvYF06IGFsbERhdGVzW2FsbERhdGVzLmxlbmd0aCAtIDFdLmxhc3REYXkudG9TdHJpbmcoKQogICAgfTsKICAgIHJldHVybiBmZXRjaEFuZFByZXBhcmVTdWJzdGl0dXRpb25zT3JEZWxldGlvbnMoZmlsdGVyLCBzZXF1ZW5jZVR5cGUpLmV2YWx1YXRlKGxhcGlzLCBzaWduYWwpOwogIH0KICBhc3luYyBmdW5jdGlvbiBxdWVyeU11dGF0aW9uc092ZXJUaW1lRGF0YSh7CiAgICBsYXBpc0ZpbHRlciwKICAgIHNlcXVlbmNlVHlwZSwKICAgIGxhcGlzLAogICAgbGFwaXNEYXRlRmllbGQsCiAgICBncmFudWxhcml0eSwKICAgIHNpZ25hbAogIH0pIHsKICAgIGNvbnN0IGFsbERhdGVzID0gYXdhaXQgZ2V0RGF0ZXNJbkRhdGFzZXQobGFwaXNGaWx0ZXIsIGxhcGlzLCBncmFudWxhcml0eSwgbGFwaXNEYXRlRmllbGQsIHNpZ25hbCk7CiAgICBpZiAoYWxsRGF0ZXMubGVuZ3RoID4gTUFYX05VTUJFUl9PRl9HUklEX0NPTFVNTlMpIHsKICAgICAgdGhyb3cgbmV3IFVzZXJGYWNpbmdFcnJvcigKICAgICAgICAiVG9vIG1hbnkgZGF0ZXMiLAogICAgICAgIGBUaGUgZGF0YXNldCB3b3VsZCBjb250YWluICR7YWxsRGF0ZXMubGVuZ3RofSBkYXRlIGludGVydmFscy4gUGxlYXNlIHJlZHVjZSB0aGUgbnVtYmVyIHRvIGJlbG93ICR7TUFYX05VTUJFUl9PRl9HUklEX0NPTFVNTlN9IHRvIGRpc3BsYXkgdGhlIGRhdGEuIFlvdSBjYW4gYWNoaWV2ZSB0aGlzIGJ5IGVpdGhlciBuYXJyb3dpbmcgdGhlIGRhdGUgcmFuZ2UgaW4gdGhlIHByb3ZpZGVkIExBUElTIGZpbHRlciBvciBieSBzZWxlY3RpbmcgYSBsYXJnZXIgZ3JhbnVsYXJpdHkuYAogICAgICApOwogICAgfQogICAgY29uc3Qgc3ViUXVlcmllcyA9IGFsbERhdGVzLm1hcChhc3luYyAoZGF0ZSkgPT4gewogICAgICBjb25zdCBkYXRlRnJvbSA9IGRhdGUuZmlyc3REYXkudG9TdHJpbmcoKTsKICAgICAgY29uc3QgZGF0ZVRvID0gZGF0ZS5sYXN0RGF5LnRvU3RyaW5nKCk7CiAgICAgIGNvbnN0IGZpbHRlciA9IHsKICAgICAgICAuLi5sYXBpc0ZpbHRlciwKICAgICAgICBbYCR7bGFwaXNEYXRlRmllbGR9RnJvbWBdOiBkYXRlRnJvbSwKICAgICAgICBbYCR7bGFwaXNEYXRlRmllbGR9VG9gXTogZGF0ZVRvCiAgICAgIH07CiAgICAgIGNvbnN0IGRhdGEyID0gYXdhaXQgZmV0Y2hBbmRQcmVwYXJlU3Vic3RpdHV0aW9uc09yRGVsZXRpb25zKGZpbHRlciwgc2VxdWVuY2VUeXBlKS5ldmFsdWF0ZShsYXBpcywgc2lnbmFsKTsKICAgICAgY29uc3QgdG90YWxDb3VudFF1ZXJ5ID0gYXdhaXQgZ2V0VG90YWxOdW1iZXJPZlNlcXVlbmNlc0luRGF0ZVJhbmdlKGZpbHRlcikuZXZhbHVhdGUobGFwaXMsIHNpZ25hbCk7CiAgICAgIHJldHVybiB7CiAgICAgICAgZGF0ZSwKICAgICAgICBtdXRhdGlvbnM6IGRhdGEyLmNvbnRlbnQsCiAgICAgICAgdG90YWxDb3VudDogdG90YWxDb3VudFF1ZXJ5LmNvbnRlbnRbMF0uY291bnQKICAgICAgfTsKICAgIH0pOwogICAgY29uc3QgZGF0YSA9IGF3YWl0IFByb21pc2UuYWxsKHN1YlF1ZXJpZXMpOwogICAgY29uc3Qgb3ZlcmFsbE11dGF0aW9uc0RhdGEgPSAoYXdhaXQgcXVlcnlPdmVyYWxsTXV0YXRpb25EYXRhKHsKICAgICAgbGFwaXNGaWx0ZXIsCiAgICAgIHNlcXVlbmNlVHlwZSwKICAgICAgbGFwaXMsCiAgICAgIGxhcGlzRGF0ZUZpZWxkLAogICAgICBncmFudWxhcml0eQogICAgfSkpLmNvbnRlbnQ7CiAgICByZXR1cm4gewogICAgICBtdXRhdGlvbk92ZXJUaW1lRGF0YTogZ3JvdXBCeU11dGF0aW9uKGRhdGEsIG92ZXJhbGxNdXRhdGlvbnNEYXRhKSwKICAgICAgb3ZlcmFsbE11dGF0aW9uRGF0YTogb3ZlcmFsbE11dGF0aW9uc0RhdGEKICAgIH07CiAgfQogIGFzeW5jIGZ1bmN0aW9uIGdldERhdGVzSW5EYXRhc2V0KGxhcGlzRmlsdGVyLCBsYXBpcywgZ3JhbnVsYXJpdHksIGxhcGlzRGF0ZUZpZWxkLCBzaWduYWwpIHsKICAgIGNvbnN0IHsgY29udGVudDogYXZhaWxhYmxlRGF0ZXMgfSA9IGF3YWl0IHF1ZXJ5QXZhaWxhYmxlRGF0ZXMoCiAgICAgIGxhcGlzRmlsdGVyLAogICAgICBsYXBpcywKICAgICAgZ3JhbnVsYXJpdHksCiAgICAgIGxhcGlzRGF0ZUZpZWxkLAogICAgICBzaWduYWwKICAgICk7CiAgICBjb25zdCB7IGRhdGVGcm9tLCBkYXRlVG8gfSA9IGdldERhdGVSYW5nZUZyb21GaWx0ZXIobGFwaXNGaWx0ZXIsIGxhcGlzRGF0ZUZpZWxkLCBncmFudWxhcml0eSk7CiAgICBjb25zdCB7IG1pbiwgbWF4IH0gPSBnZXRNaW5NYXhUZW1wb3JhbChhdmFpbGFibGVEYXRlcyk7CiAgICByZXR1cm4gZ2VuZXJhdGVBbGxJblJhbmdlKGRhdGVGcm9tID8/IG1pbiwgZGF0ZVRvID8/IG1heCk7CiAgfQogIGZ1bmN0aW9uIGdldERhdGVSYW5nZUZyb21GaWx0ZXIobGFwaXNGaWx0ZXIsIGxhcGlzRGF0ZUZpZWxkLCBncmFudWxhcml0eSkgewogICAgY29uc3QgdmFsdWVGcm9tRmlsdGVyID0gbGFwaXNGaWx0ZXJbbGFwaXNEYXRlRmllbGRdOwogICAgaWYgKHZhbHVlRnJvbUZpbHRlcikgewogICAgICByZXR1cm4gewogICAgICAgIGRhdGVGcm9tOiBwYXJzZURhdGVTdHJpbmdUb1RlbXBvcmFsKHZhbHVlRnJvbUZpbHRlciwgZ3JhbnVsYXJpdHkpLAogICAgICAgIGRhdGVUbzogcGFyc2VEYXRlU3RyaW5nVG9UZW1wb3JhbCh2YWx1ZUZyb21GaWx0ZXIsIGdyYW51bGFyaXR5KQogICAgICB9OwogICAgfQogICAgY29uc3QgbWluRnJvbUZpbHRlciA9IGxhcGlzRmlsdGVyW2Ake2xhcGlzRGF0ZUZpZWxkfUZyb21gXTsKICAgIGNvbnN0IG1heEZyb21GaWx0ZXIgPSBsYXBpc0ZpbHRlcltgJHtsYXBpc0RhdGVGaWVsZH1Ub2BdOwogICAgcmV0dXJuIHsKICAgICAgZGF0ZUZyb206IG1pbkZyb21GaWx0ZXIgPyBwYXJzZURhdGVTdHJpbmdUb1RlbXBvcmFsKG1pbkZyb21GaWx0ZXIsIGdyYW51bGFyaXR5KSA6IG51bGwsCiAgICAgIGRhdGVUbzogbWF4RnJvbUZpbHRlciA/IHBhcnNlRGF0ZVN0cmluZ1RvVGVtcG9yYWwobWF4RnJvbUZpbHRlciwgZ3JhbnVsYXJpdHkpIDogbnVsbAogICAgfTsKICB9CiAgZnVuY3Rpb24gcXVlcnlBdmFpbGFibGVEYXRlcyhsYXBpc0ZpbHRlciwgbGFwaXMsIGdyYW51bGFyaXR5LCBsYXBpc0RhdGVGaWVsZCwgc2lnbmFsKSB7CiAgICByZXR1cm4gZmV0Y2hBbmRQcmVwYXJlRGF0ZXMobGFwaXNGaWx0ZXIsIGdyYW51bGFyaXR5LCBsYXBpc0RhdGVGaWVsZCkuZXZhbHVhdGUobGFwaXMsIHNpZ25hbCk7CiAgfQogIGZ1bmN0aW9uIGZldGNoQW5kUHJlcGFyZURhdGVzKGZpbHRlciwgZ3JhbnVsYXJpdHksIGxhcGlzRGF0ZUZpZWxkKSB7CiAgICBjb25zdCBmZXRjaERhdGEgPSBuZXcgRmV0Y2hBZ2dyZWdhdGVkT3BlcmF0b3IoZmlsdGVyLCBbbGFwaXNEYXRlRmllbGRdKTsKICAgIGNvbnN0IGRhdGFXaXRoRml4ZWREYXRlS2V5ID0gbmV3IFJlbmFtZUZpZWxkT3BlcmF0b3IoZmV0Y2hEYXRhLCBsYXBpc0RhdGVGaWVsZCwgImRhdGUiKTsKICAgIGNvbnN0IG1hcERhdGEgPSBuZXcgTWFwT3BlcmF0b3IoZGF0YVdpdGhGaXhlZERhdGVLZXksIChkYXRhKSA9PiBtYXBEYXRlVG9HcmFudWxhcml0eVJhbmdlKGRhdGEsIGdyYW51bGFyaXR5KSk7CiAgICBjb25zdCBncm91cEJ5RGF0YSA9IG5ldyBHcm91cEJ5QW5kU3VtT3BlcmF0b3IobWFwRGF0YSwgImRhdGVSYW5nZSIsICJjb3VudCIpOwogICAgY29uc3Qgc29ydERhdGEgPSBuZXcgU29ydE9wZXJhdG9yKGdyb3VwQnlEYXRhLCBkYXRlUmFuZ2VDb21wYXJlKTsKICAgIHJldHVybiBuZXcgTWFwT3BlcmF0b3Ioc29ydERhdGEsIChkYXRhKSA9PiBkYXRhLmRhdGVSYW5nZSk7CiAgfQogIGZ1bmN0aW9uIGZldGNoQW5kUHJlcGFyZVN1YnN0aXR1dGlvbnNPckRlbGV0aW9ucyhmaWx0ZXIsIHNlcXVlbmNlVHlwZSkgewogICAgcmV0dXJuIG5ldyBGZXRjaFN1YnN0aXR1dGlvbnNPckRlbGV0aW9uc09wZXJhdG9yKGZpbHRlciwgc2VxdWVuY2VUeXBlLCAxZS0zKTsKICB9CiAgZnVuY3Rpb24gc2VyaWFsaXplU3Vic3RpdHV0aW9uT3JEZWxldGlvbihtdXRhdGlvbikgewogICAgcmV0dXJuIG11dGF0aW9uLmNvZGU7CiAgfQogIGZ1bmN0aW9uIHNlcmlhbGl6ZVRlbXBvcmFsKGRhdGUpIHsKICAgIHJldHVybiBkYXRlLmRhdGVTdHJpbmc7CiAgfQogIGZ1bmN0aW9uIGdyb3VwQnlNdXRhdGlvbihkYXRhLCBvdmVyYWxsTXV0YXRpb25EYXRhKSB7CiAgICBjb25zdCBkYXRhQXJyYXkgPSBuZXcgQmFzZU11dGF0aW9uT3ZlclRpbWVEYXRhTWFwKCk7CiAgICBjb25zdCBhbGxEYXRlcyA9IGRhdGEubWFwKChtdXRhdGlvbkRhdGEpID0+IG11dGF0aW9uRGF0YS5kYXRlKTsKICAgIGNvbnN0IHNvcnRlZE92ZXJhbGxNdXRhdGlvbkRhdGEgPSBvdmVyYWxsTXV0YXRpb25EYXRhLnNvcnQoKGEyLCBiKSA9PiBzb3J0U3Vic3RpdHV0aW9uc0FuZERlbGV0aW9ucyhhMi5tdXRhdGlvbiwgYi5tdXRhdGlvbikpLm1hcCgoZW50cnkpID0+IHsKICAgICAgcmV0dXJuIHRvU3Vic3RpdHV0aW9uT3JEZWxldGlvbihlbnRyeS5tdXRhdGlvbik7CiAgICB9KTsKICAgIGNvbnN0IHNvcnRlZERhdGVzID0gYWxsRGF0ZXMuc29ydCgoYTIsIGIpID0+IGNvbXBhcmVUZW1wb3JhbChhMiwgYikpLm1hcCgoZGF0ZSkgPT4gdG9UZW1wb3JhbChkYXRlKSk7CiAgICBzb3J0ZWRPdmVyYWxsTXV0YXRpb25EYXRhLmZvckVhY2goKG11dGF0aW9uRGF0YSkgPT4gewogICAgICBzb3J0ZWREYXRlcy5mb3JFYWNoKChkYXRlKSA9PiB7CiAgICAgICAgZGF0YUFycmF5LnNldChtdXRhdGlvbkRhdGEsIGRhdGUsIHsKICAgICAgICAgIGNvdW50OiAwLAogICAgICAgICAgcHJvcG9ydGlvbjogMCwKICAgICAgICAgIHRvdGFsQ291bnQ6IDAKICAgICAgICB9KTsKICAgICAgfSk7CiAgICB9KTsKICAgIGRhdGEuZm9yRWFjaCgobXV0YXRpb25EYXRhKSA9PiB7CiAgICAgIG11dGF0aW9uRGF0YS5tdXRhdGlvbnMuZm9yRWFjaCgobXV0YXRpb25FbnRyeSkgPT4gewogICAgICAgIGNvbnN0IG11dGF0aW9uID0gdG9TdWJzdGl0dXRpb25PckRlbGV0aW9uKG11dGF0aW9uRW50cnkubXV0YXRpb24pOwogICAgICAgIGNvbnN0IGRhdGUgPSB0b1RlbXBvcmFsKG11dGF0aW9uRGF0YS5kYXRlKTsKICAgICAgICBpZiAoZGF0YUFycmF5LmdldChtdXRhdGlvbiwgZGF0ZSkgIT09IHZvaWQgMCkgewogICAgICAgICAgZGF0YUFycmF5LnNldChtdXRhdGlvbiwgZGF0ZSwgewogICAgICAgICAgICBjb3VudDogbXV0YXRpb25FbnRyeS5jb3VudCwKICAgICAgICAgICAgcHJvcG9ydGlvbjogbXV0YXRpb25FbnRyeS5wcm9wb3J0aW9uLAogICAgICAgICAgICB0b3RhbENvdW50OiBtdXRhdGlvbkRhdGEudG90YWxDb3VudAogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9KTsKICAgIH0pOwogICAgcmV0dXJuIGRhdGFBcnJheTsKICB9CiAgZnVuY3Rpb24gZ2V0VG90YWxOdW1iZXJPZlNlcXVlbmNlc0luRGF0ZVJhbmdlKGZpbHRlcikgewogICAgcmV0dXJuIG5ldyBGZXRjaEFnZ3JlZ2F0ZWRPcGVyYXRvcihmaWx0ZXIpOwogIH0KICBhc3luYyBmdW5jdGlvbiB3b3JrZXJGdW5jdGlvbihxdWVyeUZ1bmN0aW9uKSB7CiAgICB0cnkgewogICAgICBwb3N0TWVzc2FnZSh7IHN0YXR1czogImxvYWRpbmciIH0pOwogICAgICBjb25zdCB3b3JrZXJSZXNwb25zZSA9IGF3YWl0IHF1ZXJ5RnVuY3Rpb24oKTsKICAgICAgcG9zdE1lc3NhZ2UoewogICAgICAgIHN0YXR1czogInN1Y2Nlc3MiLAogICAgICAgIGRhdGE6IHdvcmtlclJlc3BvbnNlCiAgICAgIH0pOwogICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgcG9zdE1lc3NhZ2UoeyBzdGF0dXM6ICJlcnJvciIsIGVycm9yIH0pOwogICAgfQogIH0KICBhc3luYyBmdW5jdGlvbiBnZXRNdXRhdGlvbk92ZXJUaW1lV29ya2VyRnVuY3Rpb24oZXZlbnQpIHsKICAgIGNvbnN0IG11dGF0aW9uT3ZlclRpbWVEYXRhID0gYXdhaXQgcXVlcnlNdXRhdGlvbnNPdmVyVGltZURhdGEoZXZlbnQuZGF0YSk7CiAgICBjb25zdCB3b3JrZXJSZXNwb25zZSA9IHsKICAgICAgb3ZlcmFsbE11dGF0aW9uRGF0YTogbXV0YXRpb25PdmVyVGltZURhdGEub3ZlcmFsbE11dGF0aW9uRGF0YSwKICAgICAgbXV0YXRpb25PdmVyVGltZVNlcmlhbGl6ZWQ6IG11dGF0aW9uT3ZlclRpbWVEYXRhLm11dGF0aW9uT3ZlclRpbWVEYXRhLmdldENvbnRlbnRzKCkKICAgIH07CiAgICByZXR1cm4gd29ya2VyUmVzcG9uc2U7CiAgfQogIHNlbGYub25tZXNzYWdlID0gYXN5bmMgZnVuY3Rpb24oZXZlbnQpIHsKICAgIGF3YWl0IHdvcmtlckZ1bmN0aW9uKCgpID0+IGdldE11dGF0aW9uT3ZlclRpbWVXb3JrZXJGdW5jdGlvbihldmVudCkpOwogIH07Cn0pKCk7Ci8vIyBzb3VyY2VNYXBwaW5nVVJMPW11dGF0aW9uT3ZlclRpbWVXb3JrZXItQk9DWHRLemQuanMubWFwCg==";
8540
+ const encodedJs = "KGZ1bmN0aW9uKCkgewogICJ1c2Ugc3RyaWN0IjsKICB2YXIgdXRpbDsKICAoZnVuY3Rpb24odXRpbDIpIHsKICAgIHV0aWwyLmFzc2VydEVxdWFsID0gKHZhbCkgPT4gdmFsOwogICAgZnVuY3Rpb24gYXNzZXJ0SXMoX2FyZykgewogICAgfQogICAgdXRpbDIuYXNzZXJ0SXMgPSBhc3NlcnRJczsKICAgIGZ1bmN0aW9uIGFzc2VydE5ldmVyKF94KSB7CiAgICAgIHRocm93IG5ldyBFcnJvcigpOwogICAgfQogICAgdXRpbDIuYXNzZXJ0TmV2ZXIgPSBhc3NlcnROZXZlcjsKICAgIHV0aWwyLmFycmF5VG9FbnVtID0gKGl0ZW1zKSA9PiB7CiAgICAgIGNvbnN0IG9iaiA9IHt9OwogICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHsKICAgICAgICBvYmpbaXRlbV0gPSBpdGVtOwogICAgICB9CiAgICAgIHJldHVybiBvYmo7CiAgICB9OwogICAgdXRpbDIuZ2V0VmFsaWRFbnVtVmFsdWVzID0gKG9iaikgPT4gewogICAgICBjb25zdCB2YWxpZEtleXMgPSB1dGlsMi5vYmplY3RLZXlzKG9iaikuZmlsdGVyKChrMikgPT4gdHlwZW9mIG9ialtvYmpbazJdXSAhPT0gIm51bWJlciIpOwogICAgICBjb25zdCBmaWx0ZXJlZCA9IHt9OwogICAgICBmb3IgKGNvbnN0IGsyIG9mIHZhbGlkS2V5cykgewogICAgICAgIGZpbHRlcmVkW2syXSA9IG9ialtrMl07CiAgICAgIH0KICAgICAgcmV0dXJuIHV0aWwyLm9iamVjdFZhbHVlcyhmaWx0ZXJlZCk7CiAgICB9OwogICAgdXRpbDIub2JqZWN0VmFsdWVzID0gKG9iaikgPT4gewogICAgICByZXR1cm4gdXRpbDIub2JqZWN0S2V5cyhvYmopLm1hcChmdW5jdGlvbihlMikgewogICAgICAgIHJldHVybiBvYmpbZTJdOwogICAgICB9KTsKICAgIH07CiAgICB1dGlsMi5vYmplY3RLZXlzID0gdHlwZW9mIE9iamVjdC5rZXlzID09PSAiZnVuY3Rpb24iID8gKG9iaikgPT4gT2JqZWN0LmtleXMob2JqKSA6IChvYmplY3QpID0+IHsKICAgICAgY29uc3Qga2V5cyA9IFtdOwogICAgICBmb3IgKGNvbnN0IGtleSBpbiBvYmplY3QpIHsKICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkgewogICAgICAgICAga2V5cy5wdXNoKGtleSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBrZXlzOwogICAgfTsKICAgIHV0aWwyLmZpbmQgPSAoYXJyLCBjaGVja2VyKSA9PiB7CiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBhcnIpIHsKICAgICAgICBpZiAoY2hlY2tlcihpdGVtKSkKICAgICAgICAgIHJldHVybiBpdGVtOwogICAgICB9CiAgICAgIHJldHVybiB2b2lkIDA7CiAgICB9OwogICAgdXRpbDIuaXNJbnRlZ2VyID0gdHlwZW9mIE51bWJlci5pc0ludGVnZXIgPT09ICJmdW5jdGlvbiIgPyAodmFsKSA9PiBOdW1iZXIuaXNJbnRlZ2VyKHZhbCkgOiAodmFsKSA9PiB0eXBlb2YgdmFsID09PSAibnVtYmVyIiAmJiBpc0Zpbml0ZSh2YWwpICYmIE1hdGguZmxvb3IodmFsKSA9PT0gdmFsOwogICAgZnVuY3Rpb24gam9pblZhbHVlcyhhcnJheSwgc2VwYXJhdG9yID0gIiB8ICIpIHsKICAgICAgcmV0dXJuIGFycmF5Lm1hcCgodmFsKSA9PiB0eXBlb2YgdmFsID09PSAic3RyaW5nIiA/IGAnJHt2YWx9J2AgOiB2YWwpLmpvaW4oc2VwYXJhdG9yKTsKICAgIH0KICAgIHV0aWwyLmpvaW5WYWx1ZXMgPSBqb2luVmFsdWVzOwogICAgdXRpbDIuanNvblN0cmluZ2lmeVJlcGxhY2VyID0gKF8sIHZhbHVlKSA9PiB7CiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICJiaWdpbnQiKSB7CiAgICAgICAgcmV0dXJuIHZhbHVlLnRvU3RyaW5nKCk7CiAgICAgIH0KICAgICAgcmV0dXJuIHZhbHVlOwogICAgfTsKICB9KSh1dGlsIHx8ICh1dGlsID0ge30pKTsKICB2YXIgb2JqZWN0VXRpbDsKICAoZnVuY3Rpb24ob2JqZWN0VXRpbDIpIHsKICAgIG9iamVjdFV0aWwyLm1lcmdlU2hhcGVzID0gKGZpcnN0LCBzZWNvbmQpID0+IHsKICAgICAgcmV0dXJuIHsKICAgICAgICAuLi5maXJzdCwKICAgICAgICAuLi5zZWNvbmQKICAgICAgICAvLyBzZWNvbmQgb3ZlcndyaXRlcyBmaXJzdAogICAgICB9OwogICAgfTsKICB9KShvYmplY3RVdGlsIHx8IChvYmplY3RVdGlsID0ge30pKTsKICBjb25zdCBab2RQYXJzZWRUeXBlID0gdXRpbC5hcnJheVRvRW51bShbCiAgICAic3RyaW5nIiwKICAgICJuYW4iLAogICAgIm51bWJlciIsCiAgICAiaW50ZWdlciIsCiAgICAiZmxvYXQiLAogICAgImJvb2xlYW4iLAogICAgImRhdGUiLAogICAgImJpZ2ludCIsCiAgICAic3ltYm9sIiwKICAgICJmdW5jdGlvbiIsCiAgICAidW5kZWZpbmVkIiwKICAgICJudWxsIiwKICAgICJhcnJheSIsCiAgICAib2JqZWN0IiwKICAgICJ1bmtub3duIiwKICAgICJwcm9taXNlIiwKICAgICJ2b2lkIiwKICAgICJuZXZlciIsCiAgICAibWFwIiwKICAgICJzZXQiCiAgXSk7CiAgY29uc3QgZ2V0UGFyc2VkVHlwZSA9IChkYXRhKSA9PiB7CiAgICBjb25zdCB0ID0gdHlwZW9mIGRhdGE7CiAgICBzd2l0Y2ggKHQpIHsKICAgICAgY2FzZSAidW5kZWZpbmVkIjoKICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQ7CiAgICAgIGNhc2UgInN0cmluZyI6CiAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUuc3RyaW5nOwogICAgICBjYXNlICJudW1iZXIiOgogICAgICAgIHJldHVybiBpc05hTihkYXRhKSA/IFpvZFBhcnNlZFR5cGUubmFuIDogWm9kUGFyc2VkVHlwZS5udW1iZXI7CiAgICAgIGNhc2UgImJvb2xlYW4iOgogICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLmJvb2xlYW47CiAgICAgIGNhc2UgImZ1bmN0aW9uIjoKICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5mdW5jdGlvbjsKICAgICAgY2FzZSAiYmlnaW50IjoKICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5iaWdpbnQ7CiAgICAgIGNhc2UgInN5bWJvbCI6CiAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUuc3ltYm9sOwogICAgICBjYXNlICJvYmplY3QiOgogICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7CiAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5hcnJheTsKICAgICAgICB9CiAgICAgICAgaWYgKGRhdGEgPT09IG51bGwpIHsKICAgICAgICAgIHJldHVybiBab2RQYXJzZWRUeXBlLm51bGw7CiAgICAgICAgfQogICAgICAgIGlmIChkYXRhLnRoZW4gJiYgdHlwZW9mIGRhdGEudGhlbiA9PT0gImZ1bmN0aW9uIiAmJiBkYXRhLmNhdGNoICYmIHR5cGVvZiBkYXRhLmNhdGNoID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5wcm9taXNlOwogICAgICAgIH0KICAgICAgICBpZiAodHlwZW9mIE1hcCAhPT0gInVuZGVmaW5lZCIgJiYgZGF0YSBpbnN0YW5jZW9mIE1hcCkgewogICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUubWFwOwogICAgICAgIH0KICAgICAgICBpZiAodHlwZW9mIFNldCAhPT0gInVuZGVmaW5lZCIgJiYgZGF0YSBpbnN0YW5jZW9mIFNldCkgewogICAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUuc2V0OwogICAgICAgIH0KICAgICAgICBpZiAodHlwZW9mIERhdGUgIT09ICJ1bmRlZmluZWQiICYmIGRhdGEgaW5zdGFuY2VvZiBEYXRlKSB7CiAgICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5kYXRlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gWm9kUGFyc2VkVHlwZS5vYmplY3Q7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIFpvZFBhcnNlZFR5cGUudW5rbm93bjsKICAgIH0KICB9OwogIGNvbnN0IFpvZElzc3VlQ29kZSA9IHV0aWwuYXJyYXlUb0VudW0oWwogICAgImludmFsaWRfdHlwZSIsCiAgICAiaW52YWxpZF9saXRlcmFsIiwKICAgICJjdXN0b20iLAogICAgImludmFsaWRfdW5pb24iLAogICAgImludmFsaWRfdW5pb25fZGlzY3JpbWluYXRvciIsCiAgICAiaW52YWxpZF9lbnVtX3ZhbHVlIiwKICAgICJ1bnJlY29nbml6ZWRfa2V5cyIsCiAgICAiaW52YWxpZF9hcmd1bWVudHMiLAogICAgImludmFsaWRfcmV0dXJuX3R5cGUiLAogICAgImludmFsaWRfZGF0ZSIsCiAgICAiaW52YWxpZF9zdHJpbmciLAogICAgInRvb19zbWFsbCIsCiAgICAidG9vX2JpZyIsCiAgICAiaW52YWxpZF9pbnRlcnNlY3Rpb25fdHlwZXMiLAogICAgIm5vdF9tdWx0aXBsZV9vZiIsCiAgICAibm90X2Zpbml0ZSIKICBdKTsKICBjb25zdCBxdW90ZWxlc3NKc29uID0gKG9iaikgPT4gewogICAgY29uc3QganNvbiA9IEpTT04uc3RyaW5naWZ5KG9iaiwgbnVsbCwgMik7CiAgICByZXR1cm4ganNvbi5yZXBsYWNlKC8iKFteIl0rKSI6L2csICIkMToiKTsKICB9OwogIGNsYXNzIFpvZEVycm9yIGV4dGVuZHMgRXJyb3IgewogICAgY29uc3RydWN0b3IoaXNzdWVzKSB7CiAgICAgIHN1cGVyKCk7CiAgICAgIHRoaXMuaXNzdWVzID0gW107CiAgICAgIHRoaXMuYWRkSXNzdWUgPSAoc3ViKSA9PiB7CiAgICAgICAgdGhpcy5pc3N1ZXMgPSBbLi4udGhpcy5pc3N1ZXMsIHN1Yl07CiAgICAgIH07CiAgICAgIHRoaXMuYWRkSXNzdWVzID0gKHN1YnMgPSBbXSkgPT4gewogICAgICAgIHRoaXMuaXNzdWVzID0gWy4uLnRoaXMuaXNzdWVzLCAuLi5zdWJzXTsKICAgICAgfTsKICAgICAgY29uc3QgYWN0dWFsUHJvdG8gPSBuZXcudGFyZ2V0LnByb3RvdHlwZTsKICAgICAgaWYgKE9iamVjdC5zZXRQcm90b3R5cGVPZikgewogICAgICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBhY3R1YWxQcm90byk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhpcy5fX3Byb3RvX18gPSBhY3R1YWxQcm90bzsKICAgICAgfQogICAgICB0aGlzLm5hbWUgPSAiWm9kRXJyb3IiOwogICAgICB0aGlzLmlzc3VlcyA9IGlzc3VlczsKICAgIH0KICAgIGdldCBlcnJvcnMoKSB7CiAgICAgIHJldHVybiB0aGlzLmlzc3VlczsKICAgIH0KICAgIGZvcm1hdChfbWFwcGVyKSB7CiAgICAgIGNvbnN0IG1hcHBlciA9IF9tYXBwZXIgfHwgZnVuY3Rpb24oaXNzdWUpIHsKICAgICAgICByZXR1cm4gaXNzdWUubWVzc2FnZTsKICAgICAgfTsKICAgICAgY29uc3QgZmllbGRFcnJvcnMgPSB7IF9lcnJvcnM6IFtdIH07CiAgICAgIGNvbnN0IHByb2Nlc3NFcnJvciA9IChlcnJvcikgPT4gewogICAgICAgIGZvciAoY29uc3QgaXNzdWUgb2YgZXJyb3IuaXNzdWVzKSB7CiAgICAgICAgICBpZiAoaXNzdWUuY29kZSA9PT0gImludmFsaWRfdW5pb24iKSB7CiAgICAgICAgICAgIGlzc3VlLnVuaW9uRXJyb3JzLm1hcChwcm9jZXNzRXJyb3IpOwogICAgICAgICAgfSBlbHNlIGlmIChpc3N1ZS5jb2RlID09PSAiaW52YWxpZF9yZXR1cm5fdHlwZSIpIHsKICAgICAgICAgICAgcHJvY2Vzc0Vycm9yKGlzc3VlLnJldHVyblR5cGVFcnJvcik7CiAgICAgICAgICB9IGVsc2UgaWYgKGlzc3VlLmNvZGUgPT09ICJpbnZhbGlkX2FyZ3VtZW50cyIpIHsKICAgICAgICAgICAgcHJvY2Vzc0Vycm9yKGlzc3VlLmFyZ3VtZW50c0Vycm9yKTsKICAgICAgICAgIH0gZWxzZSBpZiAoaXNzdWUucGF0aC5sZW5ndGggPT09IDApIHsKICAgICAgICAgICAgZmllbGRFcnJvcnMuX2Vycm9ycy5wdXNoKG1hcHBlcihpc3N1ZSkpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbGV0IGN1cnIgPSBmaWVsZEVycm9yczsKICAgICAgICAgICAgbGV0IGkyID0gMDsKICAgICAgICAgICAgd2hpbGUgKGkyIDwgaXNzdWUucGF0aC5sZW5ndGgpIHsKICAgICAgICAgICAgICBjb25zdCBlbCA9IGlzc3VlLnBhdGhbaTJdOwogICAgICAgICAgICAgIGNvbnN0IHRlcm1pbmFsID0gaTIgPT09IGlzc3VlLnBhdGgubGVuZ3RoIC0gMTsKICAgICAgICAgICAgICBpZiAoIXRlcm1pbmFsKSB7CiAgICAgICAgICAgICAgICBjdXJyW2VsXSA9IGN1cnJbZWxdIHx8IHsgX2Vycm9yczogW10gfTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgY3VycltlbF0gPSBjdXJyW2VsXSB8fCB7IF9lcnJvcnM6IFtdIH07CiAgICAgICAgICAgICAgICBjdXJyW2VsXS5fZXJyb3JzLnB1c2gobWFwcGVyKGlzc3VlKSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGN1cnIgPSBjdXJyW2VsXTsKICAgICAgICAgICAgICBpMisrOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9OwogICAgICBwcm9jZXNzRXJyb3IodGhpcyk7CiAgICAgIHJldHVybiBmaWVsZEVycm9yczsKICAgIH0KICAgIHN0YXRpYyBhc3NlcnQodmFsdWUpIHsKICAgICAgaWYgKCEodmFsdWUgaW5zdGFuY2VvZiBab2RFcnJvcikpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vdCBhIFpvZEVycm9yOiAke3ZhbHVlfWApOwogICAgICB9CiAgICB9CiAgICB0b1N0cmluZygpIHsKICAgICAgcmV0dXJuIHRoaXMubWVzc2FnZTsKICAgIH0KICAgIGdldCBtZXNzYWdlKCkgewogICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodGhpcy5pc3N1ZXMsIHV0aWwuanNvblN0cmluZ2lmeVJlcGxhY2VyLCAyKTsKICAgIH0KICAgIGdldCBpc0VtcHR5KCkgewogICAgICByZXR1cm4gdGhpcy5pc3N1ZXMubGVuZ3RoID09PSAwOwogICAgfQogICAgZmxhdHRlbihtYXBwZXIgPSAoaXNzdWUpID0+IGlzc3VlLm1lc3NhZ2UpIHsKICAgICAgY29uc3QgZmllbGRFcnJvcnMgPSB7fTsKICAgICAgY29uc3QgZm9ybUVycm9ycyA9IFtdOwogICAgICBmb3IgKGNvbnN0IHN1YiBvZiB0aGlzLmlzc3VlcykgewogICAgICAgIGlmIChzdWIucGF0aC5sZW5ndGggPiAwKSB7CiAgICAgICAgICBmaWVsZEVycm9yc1tzdWIucGF0aFswXV0gPSBmaWVsZEVycm9yc1tzdWIucGF0aFswXV0gfHwgW107CiAgICAgICAgICBmaWVsZEVycm9yc1tzdWIucGF0aFswXV0ucHVzaChtYXBwZXIoc3ViKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGZvcm1FcnJvcnMucHVzaChtYXBwZXIoc3ViKSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiB7IGZvcm1FcnJvcnMsIGZpZWxkRXJyb3JzIH07CiAgICB9CiAgICBnZXQgZm9ybUVycm9ycygpIHsKICAgICAgcmV0dXJuIHRoaXMuZmxhdHRlbigpOwogICAgfQogIH0KICBab2RFcnJvci5jcmVhdGUgPSAoaXNzdWVzKSA9PiB7CiAgICBjb25zdCBlcnJvciA9IG5ldyBab2RFcnJvcihpc3N1ZXMpOwogICAgcmV0dXJuIGVycm9yOwogIH07CiAgY29uc3QgZXJyb3JNYXAgPSAoaXNzdWUsIF9jdHgpID0+IHsKICAgIGxldCBtZXNzYWdlOwogICAgc3dpdGNoIChpc3N1ZS5jb2RlKSB7CiAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZToKICAgICAgICBpZiAoaXNzdWUucmVjZWl2ZWQgPT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7CiAgICAgICAgICBtZXNzYWdlID0gIlJlcXVpcmVkIjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbWVzc2FnZSA9IGBFeHBlY3RlZCAke2lzc3VlLmV4cGVjdGVkfSwgcmVjZWl2ZWQgJHtpc3N1ZS5yZWNlaXZlZH1gOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9saXRlcmFsOgogICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBsaXRlcmFsIHZhbHVlLCBleHBlY3RlZCAke0pTT04uc3RyaW5naWZ5KGlzc3VlLmV4cGVjdGVkLCB1dGlsLmpzb25TdHJpbmdpZnlSZXBsYWNlcil9YDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUudW5yZWNvZ25pemVkX2tleXM6CiAgICAgICAgbWVzc2FnZSA9IGBVbnJlY29nbml6ZWQga2V5KHMpIGluIG9iamVjdDogJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUua2V5cywgIiwgIil9YDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF91bmlvbjoKICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgaW5wdXRgOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFpvZElzc3VlQ29kZS5pbnZhbGlkX3VuaW9uX2Rpc2NyaW1pbmF0b3I6CiAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGRpc2NyaW1pbmF0b3IgdmFsdWUuIEV4cGVjdGVkICR7dXRpbC5qb2luVmFsdWVzKGlzc3VlLm9wdGlvbnMpfWA7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfZW51bV92YWx1ZToKICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgZW51bSB2YWx1ZS4gRXhwZWN0ZWQgJHt1dGlsLmpvaW5WYWx1ZXMoaXNzdWUub3B0aW9ucyl9LCByZWNlaXZlZCAnJHtpc3N1ZS5yZWNlaXZlZH0nYDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9hcmd1bWVudHM6CiAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGZ1bmN0aW9uIGFyZ3VtZW50c2A7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgWm9kSXNzdWVDb2RlLmludmFsaWRfcmV0dXJuX3R5cGU6CiAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGZ1bmN0aW9uIHJldHVybiB0eXBlYDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9kYXRlOgogICAgICAgIG1lc3NhZ2UgPSBgSW52YWxpZCBkYXRlYDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmc6CiAgICAgICAgaWYgKHR5cGVvZiBpc3N1ZS52YWxpZGF0aW9uID09PSAib2JqZWN0IikgewogICAgICAgICAgaWYgKCJpbmNsdWRlcyIgaW4gaXNzdWUudmFsaWRhdGlvbikgewogICAgICAgICAgICBtZXNzYWdlID0gYEludmFsaWQgaW5wdXQ6IG11c3QgaW5jbHVkZSAiJHtpc3N1ZS52YWxpZGF0aW9uLmluY2x1ZGVzfSJgOwogICAgICAgICAgICBpZiAodHlwZW9mIGlzc3VlLnZhbGlkYXRpb24ucG9zaXRpb24gPT09ICJudW1iZXIiKSB7CiAgICAgICAgICAgICAgbWVzc2FnZSA9IGAke21lc3NhZ2V9IGF0IG9uZSBvciBtb3JlIHBvc2l0aW9ucyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gJHtpc3N1ZS52YWxpZGF0aW9uLnBvc2l0aW9ufWA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSBpZiAoInN0YXJ0c1dpdGgiIGluIGlzc3VlLnZhbGlkYXRpb24pIHsKICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGlucHV0OiBtdXN0IHN0YXJ0IHdpdGggIiR7aXNzdWUudmFsaWRhdGlvbi5zdGFydHNXaXRofSJgOwogICAgICAgICAgfSBlbHNlIGlmICgiZW5kc1dpdGgiIGluIGlzc3VlLnZhbGlkYXRpb24pIHsKICAgICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGlucHV0OiBtdXN0IGVuZCB3aXRoICIke2lzc3VlLnZhbGlkYXRpb24uZW5kc1dpdGh9ImA7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGlzc3VlLnZhbGlkYXRpb24pOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoaXNzdWUudmFsaWRhdGlvbiAhPT0gInJlZ2V4IikgewogICAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkICR7aXNzdWUudmFsaWRhdGlvbn1gOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBtZXNzYWdlID0gIkludmFsaWQiOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUudG9vX3NtYWxsOgogICAgICAgIGlmIChpc3N1ZS50eXBlID09PSAiYXJyYXkiKQogICAgICAgICAgbWVzc2FnZSA9IGBBcnJheSBtdXN0IGNvbnRhaW4gJHtpc3N1ZS5leGFjdCA/ICJleGFjdGx5IiA6IGlzc3VlLmluY2x1c2l2ZSA/IGBhdCBsZWFzdGAgOiBgbW9yZSB0aGFuYH0gJHtpc3N1ZS5taW5pbXVtfSBlbGVtZW50KHMpYDsKICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSAic3RyaW5nIikKICAgICAgICAgIG1lc3NhZ2UgPSBgU3RyaW5nIG11c3QgY29udGFpbiAke2lzc3VlLmV4YWN0ID8gImV4YWN0bHkiIDogaXNzdWUuaW5jbHVzaXZlID8gYGF0IGxlYXN0YCA6IGBvdmVyYH0gJHtpc3N1ZS5taW5pbXVtfSBjaGFyYWN0ZXIocylgOwogICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09ICJudW1iZXIiKQogICAgICAgICAgbWVzc2FnZSA9IGBOdW1iZXIgbXVzdCBiZSAke2lzc3VlLmV4YWN0ID8gYGV4YWN0bHkgZXF1YWwgdG8gYCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYCA6IGBncmVhdGVyIHRoYW4gYH0ke2lzc3VlLm1pbmltdW19YDsKICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSAiZGF0ZSIpCiAgICAgICAgICBtZXNzYWdlID0gYERhdGUgbXVzdCBiZSAke2lzc3VlLmV4YWN0ID8gYGV4YWN0bHkgZXF1YWwgdG8gYCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gYCA6IGBncmVhdGVyIHRoYW4gYH0ke25ldyBEYXRlKE51bWJlcihpc3N1ZS5taW5pbXVtKSl9YDsKICAgICAgICBlbHNlCiAgICAgICAgICBtZXNzYWdlID0gIkludmFsaWQgaW5wdXQiOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFpvZElzc3VlQ29kZS50b29fYmlnOgogICAgICAgIGlmIChpc3N1ZS50eXBlID09PSAiYXJyYXkiKQogICAgICAgICAgbWVzc2FnZSA9IGBBcnJheSBtdXN0IGNvbnRhaW4gJHtpc3N1ZS5leGFjdCA/IGBleGFjdGx5YCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBhdCBtb3N0YCA6IGBsZXNzIHRoYW5gfSAke2lzc3VlLm1heGltdW19IGVsZW1lbnQocylgOwogICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09ICJzdHJpbmciKQogICAgICAgICAgbWVzc2FnZSA9IGBTdHJpbmcgbXVzdCBjb250YWluICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseWAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgYXQgbW9zdGAgOiBgdW5kZXJgfSAke2lzc3VlLm1heGltdW19IGNoYXJhY3RlcihzKWA7CiAgICAgICAgZWxzZSBpZiAoaXNzdWUudHlwZSA9PT0gIm51bWJlciIpCiAgICAgICAgICBtZXNzYWdlID0gYE51bWJlciBtdXN0IGJlICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseWAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgbGVzcyB0aGFuIG9yIGVxdWFsIHRvYCA6IGBsZXNzIHRoYW5gfSAke2lzc3VlLm1heGltdW19YDsKICAgICAgICBlbHNlIGlmIChpc3N1ZS50eXBlID09PSAiYmlnaW50IikKICAgICAgICAgIG1lc3NhZ2UgPSBgQmlnSW50IG11c3QgYmUgJHtpc3N1ZS5leGFjdCA/IGBleGFjdGx5YCA6IGlzc3VlLmluY2x1c2l2ZSA/IGBsZXNzIHRoYW4gb3IgZXF1YWwgdG9gIDogYGxlc3MgdGhhbmB9ICR7aXNzdWUubWF4aW11bX1gOwogICAgICAgIGVsc2UgaWYgKGlzc3VlLnR5cGUgPT09ICJkYXRlIikKICAgICAgICAgIG1lc3NhZ2UgPSBgRGF0ZSBtdXN0IGJlICR7aXNzdWUuZXhhY3QgPyBgZXhhY3RseWAgOiBpc3N1ZS5pbmNsdXNpdmUgPyBgc21hbGxlciB0aGFuIG9yIGVxdWFsIHRvYCA6IGBzbWFsbGVyIHRoYW5gfSAke25ldyBEYXRlKE51bWJlcihpc3N1ZS5tYXhpbXVtKSl9YDsKICAgICAgICBlbHNlCiAgICAgICAgICBtZXNzYWdlID0gIkludmFsaWQgaW5wdXQiOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFpvZElzc3VlQ29kZS5jdXN0b206CiAgICAgICAgbWVzc2FnZSA9IGBJbnZhbGlkIGlucHV0YDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUuaW52YWxpZF9pbnRlcnNlY3Rpb25fdHlwZXM6CiAgICAgICAgbWVzc2FnZSA9IGBJbnRlcnNlY3Rpb24gcmVzdWx0cyBjb3VsZCBub3QgYmUgbWVyZ2VkYDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUubm90X211bHRpcGxlX29mOgogICAgICAgIG1lc3NhZ2UgPSBgTnVtYmVyIG11c3QgYmUgYSBtdWx0aXBsZSBvZiAke2lzc3VlLm11bHRpcGxlT2Z9YDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBab2RJc3N1ZUNvZGUubm90X2Zpbml0ZToKICAgICAgICBtZXNzYWdlID0gIk51bWJlciBtdXN0IGJlIGZpbml0ZSI7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgbWVzc2FnZSA9IF9jdHguZGVmYXVsdEVycm9yOwogICAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoaXNzdWUpOwogICAgfQogICAgcmV0dXJuIHsgbWVzc2FnZSB9OwogIH07CiAgbGV0IG92ZXJyaWRlRXJyb3JNYXAgPSBlcnJvck1hcDsKICBmdW5jdGlvbiBzZXRFcnJvck1hcChtYXApIHsKICAgIG92ZXJyaWRlRXJyb3JNYXAgPSBtYXA7CiAgfQogIGZ1bmN0aW9uIGdldEVycm9yTWFwKCkgewogICAgcmV0dXJuIG92ZXJyaWRlRXJyb3JNYXA7CiAgfQogIGNvbnN0IG1ha2VJc3N1ZSA9IChwYXJhbXMpID0+IHsKICAgIGNvbnN0IHsgZGF0YSwgcGF0aCwgZXJyb3JNYXBzLCBpc3N1ZURhdGEgfSA9IHBhcmFtczsKICAgIGNvbnN0IGZ1bGxQYXRoID0gWy4uLnBhdGgsIC4uLmlzc3VlRGF0YS5wYXRoIHx8IFtdXTsKICAgIGNvbnN0IGZ1bGxJc3N1ZSA9IHsKICAgICAgLi4uaXNzdWVEYXRhLAogICAgICBwYXRoOiBmdWxsUGF0aAogICAgfTsKICAgIGlmIChpc3N1ZURhdGEubWVzc2FnZSAhPT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAgLi4uaXNzdWVEYXRhLAogICAgICAgIHBhdGg6IGZ1bGxQYXRoLAogICAgICAgIG1lc3NhZ2U6IGlzc3VlRGF0YS5tZXNzYWdlCiAgICAgIH07CiAgICB9CiAgICBsZXQgZXJyb3JNZXNzYWdlID0gIiI7CiAgICBjb25zdCBtYXBzID0gZXJyb3JNYXBzLmZpbHRlcigobTIpID0+ICEhbTIpLnNsaWNlKCkucmV2ZXJzZSgpOwogICAgZm9yIChjb25zdCBtYXAgb2YgbWFwcykgewogICAgICBlcnJvck1lc3NhZ2UgPSBtYXAoZnVsbElzc3VlLCB7IGRhdGEsIGRlZmF1bHRFcnJvcjogZXJyb3JNZXNzYWdlIH0pLm1lc3NhZ2U7CiAgICB9CiAgICByZXR1cm4gewogICAgICAuLi5pc3N1ZURhdGEsCiAgICAgIHBhdGg6IGZ1bGxQYXRoLAogICAgICBtZXNzYWdlOiBlcnJvck1lc3NhZ2UKICAgIH07CiAgfTsKICBjb25zdCBFTVBUWV9QQVRIID0gW107CiAgZnVuY3Rpb24gYWRkSXNzdWVUb0NvbnRleHQoY3R4LCBpc3N1ZURhdGEpIHsKICAgIGNvbnN0IG92ZXJyaWRlTWFwID0gZ2V0RXJyb3JNYXAoKTsKICAgIGNvbnN0IGlzc3VlID0gbWFrZUlzc3VlKHsKICAgICAgaXNzdWVEYXRhLAogICAgICBkYXRhOiBjdHguZGF0YSwKICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgIGVycm9yTWFwczogWwogICAgICAgIGN0eC5jb21tb24uY29udGV4dHVhbEVycm9yTWFwLAogICAgICAgIGN0eC5zY2hlbWFFcnJvck1hcCwKICAgICAgICBvdmVycmlkZU1hcCwKICAgICAgICBvdmVycmlkZU1hcCA9PT0gZXJyb3JNYXAgPyB2b2lkIDAgOiBlcnJvck1hcAogICAgICAgIC8vIHRoZW4gZ2xvYmFsIGRlZmF1bHQgbWFwCiAgICAgIF0uZmlsdGVyKCh4KSA9PiAhIXgpCiAgICB9KTsKICAgIGN0eC5jb21tb24uaXNzdWVzLnB1c2goaXNzdWUpOwogIH0KICBjbGFzcyBQYXJzZVN0YXR1cyB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgdGhpcy52YWx1ZSA9ICJ2YWxpZCI7CiAgICB9CiAgICBkaXJ0eSgpIHsKICAgICAgaWYgKHRoaXMudmFsdWUgPT09ICJ2YWxpZCIpCiAgICAgICAgdGhpcy52YWx1ZSA9ICJkaXJ0eSI7CiAgICB9CiAgICBhYm9ydCgpIHsKICAgICAgaWYgKHRoaXMudmFsdWUgIT09ICJhYm9ydGVkIikKICAgICAgICB0aGlzLnZhbHVlID0gImFib3J0ZWQiOwogICAgfQogICAgc3RhdGljIG1lcmdlQXJyYXkoc3RhdHVzLCByZXN1bHRzKSB7CiAgICAgIGNvbnN0IGFycmF5VmFsdWUgPSBbXTsKICAgICAgZm9yIChjb25zdCBzMiBvZiByZXN1bHRzKSB7CiAgICAgICAgaWYgKHMyLnN0YXR1cyA9PT0gImFib3J0ZWQiKQogICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgaWYgKHMyLnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgIGFycmF5VmFsdWUucHVzaChzMi52YWx1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBhcnJheVZhbHVlIH07CiAgICB9CiAgICBzdGF0aWMgYXN5bmMgbWVyZ2VPYmplY3RBc3luYyhzdGF0dXMsIHBhaXJzKSB7CiAgICAgIGNvbnN0IHN5bmNQYWlycyA9IFtdOwogICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpIHsKICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBwYWlyLmtleTsKICAgICAgICBjb25zdCB2YWx1ZSA9IGF3YWl0IHBhaXIudmFsdWU7CiAgICAgICAgc3luY1BhaXJzLnB1c2goewogICAgICAgICAga2V5LAogICAgICAgICAgdmFsdWUKICAgICAgICB9KTsKICAgICAgfQogICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VPYmplY3RTeW5jKHN0YXR1cywgc3luY1BhaXJzKTsKICAgIH0KICAgIHN0YXRpYyBtZXJnZU9iamVjdFN5bmMoc3RhdHVzLCBwYWlycykgewogICAgICBjb25zdCBmaW5hbE9iamVjdCA9IHt9OwogICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpIHsKICAgICAgICBjb25zdCB7IGtleSwgdmFsdWUgfSA9IHBhaXI7CiAgICAgICAgaWYgKGtleS5zdGF0dXMgPT09ICJhYm9ydGVkIikKICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgIGlmICh2YWx1ZS5zdGF0dXMgPT09ICJhYm9ydGVkIikKICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgIGlmIChrZXkuc3RhdHVzID09PSAiZGlydHkiKQogICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgaWYgKHZhbHVlLnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgIGlmIChrZXkudmFsdWUgIT09ICJfX3Byb3RvX18iICYmICh0eXBlb2YgdmFsdWUudmFsdWUgIT09ICJ1bmRlZmluZWQiIHx8IHBhaXIuYWx3YXlzU2V0KSkgewogICAgICAgICAgZmluYWxPYmplY3Rba2V5LnZhbHVlXSA9IHZhbHVlLnZhbHVlOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IGZpbmFsT2JqZWN0IH07CiAgICB9CiAgfQogIGNvbnN0IElOVkFMSUQgPSBPYmplY3QuZnJlZXplKHsKICAgIHN0YXR1czogImFib3J0ZWQiCiAgfSk7CiAgY29uc3QgRElSVFkgPSAodmFsdWUpID0+ICh7IHN0YXR1czogImRpcnR5IiwgdmFsdWUgfSk7CiAgY29uc3QgT0sgPSAodmFsdWUpID0+ICh7IHN0YXR1czogInZhbGlkIiwgdmFsdWUgfSk7CiAgY29uc3QgaXNBYm9ydGVkID0gKHgpID0+IHguc3RhdHVzID09PSAiYWJvcnRlZCI7CiAgY29uc3QgaXNEaXJ0eSA9ICh4KSA9PiB4LnN0YXR1cyA9PT0gImRpcnR5IjsKICBjb25zdCBpc1ZhbGlkID0gKHgpID0+IHguc3RhdHVzID09PSAidmFsaWQiOwogIGNvbnN0IGlzQXN5bmMgPSAoeCkgPT4gdHlwZW9mIFByb21pc2UgIT09ICJ1bmRlZmluZWQiICYmIHggaW5zdGFuY2VvZiBQcm9taXNlOwogIGZ1bmN0aW9uIF9fY2xhc3NQcml2YXRlRmllbGRHZXQocmVjZWl2ZXIsIHN0YXRlLCBraW5kLCBmMikgewogICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gImZ1bmN0aW9uIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZjIgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IHJlYWQgcHJpdmF0ZSBtZW1iZXIgZnJvbSBhbiBvYmplY3Qgd2hvc2UgY2xhc3MgZGlkIG5vdCBkZWNsYXJlIGl0Iik7CiAgICByZXR1cm4gc3RhdGUuZ2V0KHJlY2VpdmVyKTsKICB9CiAgZnVuY3Rpb24gX19jbGFzc1ByaXZhdGVGaWVsZFNldChyZWNlaXZlciwgc3RhdGUsIHZhbHVlLCBraW5kLCBmMikgewogICAgaWYgKHR5cGVvZiBzdGF0ZSA9PT0gImZ1bmN0aW9uIiA/IHJlY2VpdmVyICE9PSBzdGF0ZSB8fCAhZjIgOiAhc3RhdGUuaGFzKHJlY2VpdmVyKSkgdGhyb3cgbmV3IFR5cGVFcnJvcigiQ2Fubm90IHdyaXRlIHByaXZhdGUgbWVtYmVyIHRvIGFuIG9iamVjdCB3aG9zZSBjbGFzcyBkaWQgbm90IGRlY2xhcmUgaXQiKTsKICAgIHJldHVybiBzdGF0ZS5zZXQocmVjZWl2ZXIsIHZhbHVlKSwgdmFsdWU7CiAgfQogIHR5cGVvZiBTdXBwcmVzc2VkRXJyb3IgPT09ICJmdW5jdGlvbiIgPyBTdXBwcmVzc2VkRXJyb3IgOiBmdW5jdGlvbihlcnJvciwgc3VwcHJlc3NlZCwgbWVzc2FnZSkgewogICAgdmFyIGUyID0gbmV3IEVycm9yKG1lc3NhZ2UpOwogICAgcmV0dXJuIGUyLm5hbWUgPSAiU3VwcHJlc3NlZEVycm9yIiwgZTIuZXJyb3IgPSBlcnJvciwgZTIuc3VwcHJlc3NlZCA9IHN1cHByZXNzZWQsIGUyOwogIH07CiAgdmFyIGVycm9yVXRpbDsKICAoZnVuY3Rpb24oZXJyb3JVdGlsMikgewogICAgZXJyb3JVdGlsMi5lcnJUb09iaiA9IChtZXNzYWdlKSA9PiB0eXBlb2YgbWVzc2FnZSA9PT0gInN0cmluZyIgPyB7IG1lc3NhZ2UgfSA6IG1lc3NhZ2UgfHwge307CiAgICBlcnJvclV0aWwyLnRvU3RyaW5nID0gKG1lc3NhZ2UpID0+IHR5cGVvZiBtZXNzYWdlID09PSAic3RyaW5nIiA/IG1lc3NhZ2UgOiBtZXNzYWdlID09PSBudWxsIHx8IG1lc3NhZ2UgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG1lc3NhZ2UubWVzc2FnZTsKICB9KShlcnJvclV0aWwgfHwgKGVycm9yVXRpbCA9IHt9KSk7CiAgdmFyIF9ab2RFbnVtX2NhY2hlLCBfWm9kTmF0aXZlRW51bV9jYWNoZTsKICBjbGFzcyBQYXJzZUlucHV0TGF6eVBhdGggewogICAgY29uc3RydWN0b3IocGFyZW50LCB2YWx1ZSwgcGF0aCwga2V5KSB7CiAgICAgIHRoaXMuX2NhY2hlZFBhdGggPSBbXTsKICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7CiAgICAgIHRoaXMuZGF0YSA9IHZhbHVlOwogICAgICB0aGlzLl9wYXRoID0gcGF0aDsKICAgICAgdGhpcy5fa2V5ID0ga2V5OwogICAgfQogICAgZ2V0IHBhdGgoKSB7CiAgICAgIGlmICghdGhpcy5fY2FjaGVkUGF0aC5sZW5ndGgpIHsKICAgICAgICBpZiAodGhpcy5fa2V5IGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgICAgIHRoaXMuX2NhY2hlZFBhdGgucHVzaCguLi50aGlzLl9wYXRoLCAuLi50aGlzLl9rZXkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aGlzLl9jYWNoZWRQYXRoLnB1c2goLi4udGhpcy5fcGF0aCwgdGhpcy5fa2V5KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMuX2NhY2hlZFBhdGg7CiAgICB9CiAgfQogIGNvbnN0IGhhbmRsZVJlc3VsdCA9IChjdHgsIHJlc3VsdCkgPT4gewogICAgaWYgKGlzVmFsaWQocmVzdWx0KSkgewogICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCBkYXRhOiByZXN1bHQudmFsdWUgfTsKICAgIH0gZWxzZSB7CiAgICAgIGlmICghY3R4LmNvbW1vbi5pc3N1ZXMubGVuZ3RoKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJWYWxpZGF0aW9uIGZhaWxlZCBidXQgbm8gaXNzdWVzIGRldGVjdGVkLiIpOwogICAgICB9CiAgICAgIHJldHVybiB7CiAgICAgICAgc3VjY2VzczogZmFsc2UsCiAgICAgICAgZ2V0IGVycm9yKCkgewogICAgICAgICAgaWYgKHRoaXMuX2Vycm9yKQogICAgICAgICAgICByZXR1cm4gdGhpcy5fZXJyb3I7CiAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBab2RFcnJvcihjdHguY29tbW9uLmlzc3Vlcyk7CiAgICAgICAgICB0aGlzLl9lcnJvciA9IGVycm9yOwogICAgICAgICAgcmV0dXJuIHRoaXMuX2Vycm9yOwogICAgICAgIH0KICAgICAgfTsKICAgIH0KICB9OwogIGZ1bmN0aW9uIHByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKSB7CiAgICBpZiAoIXBhcmFtcykKICAgICAgcmV0dXJuIHt9OwogICAgY29uc3QgeyBlcnJvck1hcDogZXJyb3JNYXAyLCBpbnZhbGlkX3R5cGVfZXJyb3IsIHJlcXVpcmVkX2Vycm9yLCBkZXNjcmlwdGlvbiB9ID0gcGFyYW1zOwogICAgaWYgKGVycm9yTWFwMiAmJiAoaW52YWxpZF90eXBlX2Vycm9yIHx8IHJlcXVpcmVkX2Vycm9yKSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbid0IHVzZSAiaW52YWxpZF90eXBlX2Vycm9yIiBvciAicmVxdWlyZWRfZXJyb3IiIGluIGNvbmp1bmN0aW9uIHdpdGggY3VzdG9tIGVycm9yIG1hcC5gKTsKICAgIH0KICAgIGlmIChlcnJvck1hcDIpCiAgICAgIHJldHVybiB7IGVycm9yTWFwOiBlcnJvck1hcDIsIGRlc2NyaXB0aW9uIH07CiAgICBjb25zdCBjdXN0b21NYXAgPSAoaXNzLCBjdHgpID0+IHsKICAgICAgdmFyIF9hLCBfYjsKICAgICAgY29uc3QgeyBtZXNzYWdlIH0gPSBwYXJhbXM7CiAgICAgIGlmIChpc3MuY29kZSA9PT0gImludmFsaWRfZW51bV92YWx1ZSIpIHsKICAgICAgICByZXR1cm4geyBtZXNzYWdlOiBtZXNzYWdlICE9PSBudWxsICYmIG1lc3NhZ2UgIT09IHZvaWQgMCA/IG1lc3NhZ2UgOiBjdHguZGVmYXVsdEVycm9yIH07CiAgICAgIH0KICAgICAgaWYgKHR5cGVvZiBjdHguZGF0YSA9PT0gInVuZGVmaW5lZCIpIHsKICAgICAgICByZXR1cm4geyBtZXNzYWdlOiAoX2EgPSBtZXNzYWdlICE9PSBudWxsICYmIG1lc3NhZ2UgIT09IHZvaWQgMCA/IG1lc3NhZ2UgOiByZXF1aXJlZF9lcnJvcikgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogY3R4LmRlZmF1bHRFcnJvciB9OwogICAgICB9CiAgICAgIGlmIChpc3MuY29kZSAhPT0gImludmFsaWRfdHlwZSIpCiAgICAgICAgcmV0dXJuIHsgbWVzc2FnZTogY3R4LmRlZmF1bHRFcnJvciB9OwogICAgICByZXR1cm4geyBtZXNzYWdlOiAoX2IgPSBtZXNzYWdlICE9PSBudWxsICYmIG1lc3NhZ2UgIT09IHZvaWQgMCA/IG1lc3NhZ2UgOiBpbnZhbGlkX3R5cGVfZXJyb3IpICE9PSBudWxsICYmIF9iICE9PSB2b2lkIDAgPyBfYiA6IGN0eC5kZWZhdWx0RXJyb3IgfTsKICAgIH07CiAgICByZXR1cm4geyBlcnJvck1hcDogY3VzdG9tTWFwLCBkZXNjcmlwdGlvbiB9OwogIH0KICBjbGFzcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKGRlZikgewogICAgICB0aGlzLnNwYSA9IHRoaXMuc2FmZVBhcnNlQXN5bmM7CiAgICAgIHRoaXMuX2RlZiA9IGRlZjsKICAgICAgdGhpcy5wYXJzZSA9IHRoaXMucGFyc2UuYmluZCh0aGlzKTsKICAgICAgdGhpcy5zYWZlUGFyc2UgPSB0aGlzLnNhZmVQYXJzZS5iaW5kKHRoaXMpOwogICAgICB0aGlzLnBhcnNlQXN5bmMgPSB0aGlzLnBhcnNlQXN5bmMuYmluZCh0aGlzKTsKICAgICAgdGhpcy5zYWZlUGFyc2VBc3luYyA9IHRoaXMuc2FmZVBhcnNlQXN5bmMuYmluZCh0aGlzKTsKICAgICAgdGhpcy5zcGEgPSB0aGlzLnNwYS5iaW5kKHRoaXMpOwogICAgICB0aGlzLnJlZmluZSA9IHRoaXMucmVmaW5lLmJpbmQodGhpcyk7CiAgICAgIHRoaXMucmVmaW5lbWVudCA9IHRoaXMucmVmaW5lbWVudC5iaW5kKHRoaXMpOwogICAgICB0aGlzLnN1cGVyUmVmaW5lID0gdGhpcy5zdXBlclJlZmluZS5iaW5kKHRoaXMpOwogICAgICB0aGlzLm9wdGlvbmFsID0gdGhpcy5vcHRpb25hbC5iaW5kKHRoaXMpOwogICAgICB0aGlzLm51bGxhYmxlID0gdGhpcy5udWxsYWJsZS5iaW5kKHRoaXMpOwogICAgICB0aGlzLm51bGxpc2ggPSB0aGlzLm51bGxpc2guYmluZCh0aGlzKTsKICAgICAgdGhpcy5hcnJheSA9IHRoaXMuYXJyYXkuYmluZCh0aGlzKTsKICAgICAgdGhpcy5wcm9taXNlID0gdGhpcy5wcm9taXNlLmJpbmQodGhpcyk7CiAgICAgIHRoaXMub3IgPSB0aGlzLm9yLmJpbmQodGhpcyk7CiAgICAgIHRoaXMuYW5kID0gdGhpcy5hbmQuYmluZCh0aGlzKTsKICAgICAgdGhpcy50cmFuc2Zvcm0gPSB0aGlzLnRyYW5zZm9ybS5iaW5kKHRoaXMpOwogICAgICB0aGlzLmJyYW5kID0gdGhpcy5icmFuZC5iaW5kKHRoaXMpOwogICAgICB0aGlzLmRlZmF1bHQgPSB0aGlzLmRlZmF1bHQuYmluZCh0aGlzKTsKICAgICAgdGhpcy5jYXRjaCA9IHRoaXMuY2F0Y2guYmluZCh0aGlzKTsKICAgICAgdGhpcy5kZXNjcmliZSA9IHRoaXMuZGVzY3JpYmUuYmluZCh0aGlzKTsKICAgICAgdGhpcy5waXBlID0gdGhpcy5waXBlLmJpbmQodGhpcyk7CiAgICAgIHRoaXMucmVhZG9ubHkgPSB0aGlzLnJlYWRvbmx5LmJpbmQodGhpcyk7CiAgICAgIHRoaXMuaXNOdWxsYWJsZSA9IHRoaXMuaXNOdWxsYWJsZS5iaW5kKHRoaXMpOwogICAgICB0aGlzLmlzT3B0aW9uYWwgPSB0aGlzLmlzT3B0aW9uYWwuYmluZCh0aGlzKTsKICAgIH0KICAgIGdldCBkZXNjcmlwdGlvbigpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5kZXNjcmlwdGlvbjsKICAgIH0KICAgIF9nZXRUeXBlKGlucHV0KSB7CiAgICAgIHJldHVybiBnZXRQYXJzZWRUeXBlKGlucHV0LmRhdGEpOwogICAgfQogICAgX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpIHsKICAgICAgcmV0dXJuIGN0eCB8fCB7CiAgICAgICAgY29tbW9uOiBpbnB1dC5wYXJlbnQuY29tbW9uLAogICAgICAgIGRhdGE6IGlucHV0LmRhdGEsCiAgICAgICAgcGFyc2VkVHlwZTogZ2V0UGFyc2VkVHlwZShpbnB1dC5kYXRhKSwKICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLAogICAgICAgIHBhdGg6IGlucHV0LnBhdGgsCiAgICAgICAgcGFyZW50OiBpbnB1dC5wYXJlbnQKICAgICAgfTsKICAgIH0KICAgIF9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpIHsKICAgICAgcmV0dXJuIHsKICAgICAgICBzdGF0dXM6IG5ldyBQYXJzZVN0YXR1cygpLAogICAgICAgIGN0eDogewogICAgICAgICAgY29tbW9uOiBpbnB1dC5wYXJlbnQuY29tbW9uLAogICAgICAgICAgZGF0YTogaW5wdXQuZGF0YSwKICAgICAgICAgIHBhcnNlZFR5cGU6IGdldFBhcnNlZFR5cGUoaW5wdXQuZGF0YSksCiAgICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLAogICAgICAgICAgcGF0aDogaW5wdXQucGF0aCwKICAgICAgICAgIHBhcmVudDogaW5wdXQucGFyZW50CiAgICAgICAgfQogICAgICB9OwogICAgfQogICAgX3BhcnNlU3luYyhpbnB1dCkgewogICAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9wYXJzZShpbnB1dCk7CiAgICAgIGlmIChpc0FzeW5jKHJlc3VsdCkpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlN5bmNocm9ub3VzIHBhcnNlIGVuY291bnRlcmVkIHByb21pc2UuIik7CiAgICAgIH0KICAgICAgcmV0dXJuIHJlc3VsdDsKICAgIH0KICAgIF9wYXJzZUFzeW5jKGlucHV0KSB7CiAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuX3BhcnNlKGlucHV0KTsKICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShyZXN1bHQpOwogICAgfQogICAgcGFyc2UoZGF0YSwgcGFyYW1zKSB7CiAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuc2FmZVBhcnNlKGRhdGEsIHBhcmFtcyk7CiAgICAgIGlmIChyZXN1bHQuc3VjY2VzcykKICAgICAgICByZXR1cm4gcmVzdWx0LmRhdGE7CiAgICAgIHRocm93IHJlc3VsdC5lcnJvcjsKICAgIH0KICAgIHNhZmVQYXJzZShkYXRhLCBwYXJhbXMpIHsKICAgICAgdmFyIF9hOwogICAgICBjb25zdCBjdHggPSB7CiAgICAgICAgY29tbW9uOiB7CiAgICAgICAgICBpc3N1ZXM6IFtdLAogICAgICAgICAgYXN5bmM6IChfYSA9IHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5hc3luYykgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogZmFsc2UsCiAgICAgICAgICBjb250ZXh0dWFsRXJyb3JNYXA6IHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5lcnJvck1hcAogICAgICAgIH0sCiAgICAgICAgcGF0aDogKHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5wYXRoKSB8fCBbXSwKICAgICAgICBzY2hlbWFFcnJvck1hcDogdGhpcy5fZGVmLmVycm9yTWFwLAogICAgICAgIHBhcmVudDogbnVsbCwKICAgICAgICBkYXRhLAogICAgICAgIHBhcnNlZFR5cGU6IGdldFBhcnNlZFR5cGUoZGF0YSkKICAgICAgfTsKICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fcGFyc2VTeW5jKHsgZGF0YSwgcGF0aDogY3R4LnBhdGgsIHBhcmVudDogY3R4IH0pOwogICAgICByZXR1cm4gaGFuZGxlUmVzdWx0KGN0eCwgcmVzdWx0KTsKICAgIH0KICAgIGFzeW5jIHBhcnNlQXN5bmMoZGF0YSwgcGFyYW1zKSB7CiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuc2FmZVBhcnNlQXN5bmMoZGF0YSwgcGFyYW1zKTsKICAgICAgaWYgKHJlc3VsdC5zdWNjZXNzKQogICAgICAgIHJldHVybiByZXN1bHQuZGF0YTsKICAgICAgdGhyb3cgcmVzdWx0LmVycm9yOwogICAgfQogICAgYXN5bmMgc2FmZVBhcnNlQXN5bmMoZGF0YSwgcGFyYW1zKSB7CiAgICAgIGNvbnN0IGN0eCA9IHsKICAgICAgICBjb21tb246IHsKICAgICAgICAgIGlzc3VlczogW10sCiAgICAgICAgICBjb250ZXh0dWFsRXJyb3JNYXA6IHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5lcnJvck1hcCwKICAgICAgICAgIGFzeW5jOiB0cnVlCiAgICAgICAgfSwKICAgICAgICBwYXRoOiAocGFyYW1zID09PSBudWxsIHx8IHBhcmFtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFyYW1zLnBhdGgpIHx8IFtdLAogICAgICAgIHNjaGVtYUVycm9yTWFwOiB0aGlzLl9kZWYuZXJyb3JNYXAsCiAgICAgICAgcGFyZW50OiBudWxsLAogICAgICAgIGRhdGEsCiAgICAgICAgcGFyc2VkVHlwZTogZ2V0UGFyc2VkVHlwZShkYXRhKQogICAgICB9OwogICAgICBjb25zdCBtYXliZUFzeW5jUmVzdWx0ID0gdGhpcy5fcGFyc2UoeyBkYXRhLCBwYXRoOiBjdHgucGF0aCwgcGFyZW50OiBjdHggfSk7CiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IChpc0FzeW5jKG1heWJlQXN5bmNSZXN1bHQpID8gbWF5YmVBc3luY1Jlc3VsdCA6IFByb21pc2UucmVzb2x2ZShtYXliZUFzeW5jUmVzdWx0KSk7CiAgICAgIHJldHVybiBoYW5kbGVSZXN1bHQoY3R4LCByZXN1bHQpOwogICAgfQogICAgcmVmaW5lKGNoZWNrLCBtZXNzYWdlKSB7CiAgICAgIGNvbnN0IGdldElzc3VlUHJvcGVydGllcyA9ICh2YWwpID0+IHsKICAgICAgICBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICJzdHJpbmciIHx8IHR5cGVvZiBtZXNzYWdlID09PSAidW5kZWZpbmVkIikgewogICAgICAgICAgcmV0dXJuIHsgbWVzc2FnZSB9OwogICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIG1lc3NhZ2UgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlKHZhbCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBtZXNzYWdlOwogICAgICAgIH0KICAgICAgfTsKICAgICAgcmV0dXJuIHRoaXMuX3JlZmluZW1lbnQoKHZhbCwgY3R4KSA9PiB7CiAgICAgICAgY29uc3QgcmVzdWx0ID0gY2hlY2sodmFsKTsKICAgICAgICBjb25zdCBzZXRFcnJvciA9ICgpID0+IGN0eC5hZGRJc3N1ZSh7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuY3VzdG9tLAogICAgICAgICAgLi4uZ2V0SXNzdWVQcm9wZXJ0aWVzKHZhbCkKICAgICAgICB9KTsKICAgICAgICBpZiAodHlwZW9mIFByb21pc2UgIT09ICJ1bmRlZmluZWQiICYmIHJlc3VsdCBpbnN0YW5jZW9mIFByb21pc2UpIHsKICAgICAgICAgIHJldHVybiByZXN1bHQudGhlbigoZGF0YSkgPT4gewogICAgICAgICAgICBpZiAoIWRhdGEpIHsKICAgICAgICAgICAgICBzZXRFcnJvcigpOwogICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICAgIGlmICghcmVzdWx0KSB7CiAgICAgICAgICBzZXRFcnJvcigpOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgIH0pOwogICAgfQogICAgcmVmaW5lbWVudChjaGVjaywgcmVmaW5lbWVudERhdGEpIHsKICAgICAgcmV0dXJuIHRoaXMuX3JlZmluZW1lbnQoKHZhbCwgY3R4KSA9PiB7CiAgICAgICAgaWYgKCFjaGVjayh2YWwpKSB7CiAgICAgICAgICBjdHguYWRkSXNzdWUodHlwZW9mIHJlZmluZW1lbnREYXRhID09PSAiZnVuY3Rpb24iID8gcmVmaW5lbWVudERhdGEodmFsLCBjdHgpIDogcmVmaW5lbWVudERhdGEpOwogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgIH0pOwogICAgfQogICAgX3JlZmluZW1lbnQocmVmaW5lbWVudCkgewogICAgICByZXR1cm4gbmV3IFpvZEVmZmVjdHMoewogICAgICAgIHNjaGVtYTogdGhpcywKICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsCiAgICAgICAgZWZmZWN0OiB7IHR5cGU6ICJyZWZpbmVtZW50IiwgcmVmaW5lbWVudCB9CiAgICAgIH0pOwogICAgfQogICAgc3VwZXJSZWZpbmUocmVmaW5lbWVudCkgewogICAgICByZXR1cm4gdGhpcy5fcmVmaW5lbWVudChyZWZpbmVtZW50KTsKICAgIH0KICAgIG9wdGlvbmFsKCkgewogICAgICByZXR1cm4gWm9kT3B0aW9uYWwuY3JlYXRlKHRoaXMsIHRoaXMuX2RlZik7CiAgICB9CiAgICBudWxsYWJsZSgpIHsKICAgICAgcmV0dXJuIFpvZE51bGxhYmxlLmNyZWF0ZSh0aGlzLCB0aGlzLl9kZWYpOwogICAgfQogICAgbnVsbGlzaCgpIHsKICAgICAgcmV0dXJuIHRoaXMubnVsbGFibGUoKS5vcHRpb25hbCgpOwogICAgfQogICAgYXJyYXkoKSB7CiAgICAgIHJldHVybiBab2RBcnJheS5jcmVhdGUodGhpcywgdGhpcy5fZGVmKTsKICAgIH0KICAgIHByb21pc2UoKSB7CiAgICAgIHJldHVybiBab2RQcm9taXNlLmNyZWF0ZSh0aGlzLCB0aGlzLl9kZWYpOwogICAgfQogICAgb3Iob3B0aW9uKSB7CiAgICAgIHJldHVybiBab2RVbmlvbi5jcmVhdGUoW3RoaXMsIG9wdGlvbl0sIHRoaXMuX2RlZik7CiAgICB9CiAgICBhbmQoaW5jb21pbmcpIHsKICAgICAgcmV0dXJuIFpvZEludGVyc2VjdGlvbi5jcmVhdGUodGhpcywgaW5jb21pbmcsIHRoaXMuX2RlZik7CiAgICB9CiAgICB0cmFuc2Zvcm0odHJhbnNmb3JtKSB7CiAgICAgIHJldHVybiBuZXcgWm9kRWZmZWN0cyh7CiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyh0aGlzLl9kZWYpLAogICAgICAgIHNjaGVtYTogdGhpcywKICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsCiAgICAgICAgZWZmZWN0OiB7IHR5cGU6ICJ0cmFuc2Zvcm0iLCB0cmFuc2Zvcm0gfQogICAgICB9KTsKICAgIH0KICAgIGRlZmF1bHQoZGVmKSB7CiAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZUZ1bmMgPSB0eXBlb2YgZGVmID09PSAiZnVuY3Rpb24iID8gZGVmIDogKCkgPT4gZGVmOwogICAgICByZXR1cm4gbmV3IFpvZERlZmF1bHQoewogICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXModGhpcy5fZGVmKSwKICAgICAgICBpbm5lclR5cGU6IHRoaXMsCiAgICAgICAgZGVmYXVsdFZhbHVlOiBkZWZhdWx0VmFsdWVGdW5jLAogICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRGVmYXVsdAogICAgICB9KTsKICAgIH0KICAgIGJyYW5kKCkgewogICAgICByZXR1cm4gbmV3IFpvZEJyYW5kZWQoewogICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQnJhbmRlZCwKICAgICAgICB0eXBlOiB0aGlzLAogICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXModGhpcy5fZGVmKQogICAgICB9KTsKICAgIH0KICAgIGNhdGNoKGRlZikgewogICAgICBjb25zdCBjYXRjaFZhbHVlRnVuYyA9IHR5cGVvZiBkZWYgPT09ICJmdW5jdGlvbiIgPyBkZWYgOiAoKSA9PiBkZWY7CiAgICAgIHJldHVybiBuZXcgWm9kQ2F0Y2goewogICAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXModGhpcy5fZGVmKSwKICAgICAgICBpbm5lclR5cGU6IHRoaXMsCiAgICAgICAgY2F0Y2hWYWx1ZTogY2F0Y2hWYWx1ZUZ1bmMsCiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RDYXRjaAogICAgICB9KTsKICAgIH0KICAgIGRlc2NyaWJlKGRlc2NyaXB0aW9uKSB7CiAgICAgIGNvbnN0IFRoaXMgPSB0aGlzLmNvbnN0cnVjdG9yOwogICAgICByZXR1cm4gbmV3IFRoaXMoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBkZXNjcmlwdGlvbgogICAgICB9KTsKICAgIH0KICAgIHBpcGUodGFyZ2V0KSB7CiAgICAgIHJldHVybiBab2RQaXBlbGluZS5jcmVhdGUodGhpcywgdGFyZ2V0KTsKICAgIH0KICAgIHJlYWRvbmx5KCkgewogICAgICByZXR1cm4gWm9kUmVhZG9ubHkuY3JlYXRlKHRoaXMpOwogICAgfQogICAgaXNPcHRpb25hbCgpIHsKICAgICAgcmV0dXJuIHRoaXMuc2FmZVBhcnNlKHZvaWQgMCkuc3VjY2VzczsKICAgIH0KICAgIGlzTnVsbGFibGUoKSB7CiAgICAgIHJldHVybiB0aGlzLnNhZmVQYXJzZShudWxsKS5zdWNjZXNzOwogICAgfQogIH0KICBjb25zdCBjdWlkUmVnZXggPSAvXmNbXlxzLV17OCx9JC9pOwogIGNvbnN0IGN1aWQyUmVnZXggPSAvXlswLTlhLXpdKyQvOwogIGNvbnN0IHVsaWRSZWdleCA9IC9eWzAtOUEtSEpLTU5QLVRWLVpdezI2fSQvOwogIGNvbnN0IHV1aWRSZWdleCA9IC9eWzAtOWEtZkEtRl17OH1cYi1bMC05YS1mQS1GXXs0fVxiLVswLTlhLWZBLUZdezR9XGItWzAtOWEtZkEtRl17NH1cYi1bMC05YS1mQS1GXXsxMn0kL2k7CiAgY29uc3QgbmFub2lkUmVnZXggPSAvXlthLXowLTlfLV17MjF9JC9pOwogIGNvbnN0IGR1cmF0aW9uUmVnZXggPSAvXlstK10/UCg/ISQpKD86KD86Wy0rXT9cZCtZKXwoPzpbLStdP1xkK1suLF1cZCtZJCkpPyg/Oig/OlstK10/XGQrTSl8KD86Wy0rXT9cZCtbLixdXGQrTSQpKT8oPzooPzpbLStdP1xkK1cpfCg/OlstK10/XGQrWy4sXVxkK1ckKSk/KD86KD86Wy0rXT9cZCtEKXwoPzpbLStdP1xkK1suLF1cZCtEJCkpPyg/OlQoPz1bXGQrLV0pKD86KD86Wy0rXT9cZCtIKXwoPzpbLStdP1xkK1suLF1cZCtIJCkpPyg/Oig/OlstK10/XGQrTSl8KD86Wy0rXT9cZCtbLixdXGQrTSQpKT8oPzpbLStdP1xkKyg/OlsuLF1cZCspP1MpPyk/PyQvOwogIGNvbnN0IGVtYWlsUmVnZXggPSAvXig/IVwuKSg/IS4qXC5cLikoW0EtWjAtOV8nK1wtXC5dKilbQS1aMC05XystXUAoW0EtWjAtOV1bQS1aMC05XC1dKlwuKStbQS1aXXsyLH0kL2k7CiAgY29uc3QgX2Vtb2ppUmVnZXggPSBgXihcXHB7RXh0ZW5kZWRfUGljdG9ncmFwaGljfXxcXHB7RW1vamlfQ29tcG9uZW50fSkrJGA7CiAgbGV0IGVtb2ppUmVnZXg7CiAgY29uc3QgaXB2NFJlZ2V4ID0gL14oPzooPzoyNVswLTVdfDJbMC00XVswLTldfDFbMC05XVswLTldfFsxLTldWzAtOV18WzAtOV0pXC4pezN9KD86MjVbMC01XXwyWzAtNF1bMC05XXwxWzAtOV1bMC05XXxbMS05XVswLTldfFswLTldKSQvOwogIGNvbnN0IGlwdjZSZWdleCA9IC9eKChbYS1mMC05XXsxLDR9Oil7N318OjooW2EtZjAtOV17MSw0fTopezAsNn18KFthLWYwLTldezEsNH06KXsxfTooW2EtZjAtOV17MSw0fTopezAsNX18KFthLWYwLTldezEsNH06KXsyfTooW2EtZjAtOV17MSw0fTopezAsNH18KFthLWYwLTldezEsNH06KXszfTooW2EtZjAtOV17MSw0fTopezAsM318KFthLWYwLTldezEsNH06KXs0fTooW2EtZjAtOV17MSw0fTopezAsMn18KFthLWYwLTldezEsNH06KXs1fTooW2EtZjAtOV17MSw0fTopezAsMX0pKFthLWYwLTldezEsNH18KCgoMjVbMC01XSl8KDJbMC00XVswLTldKXwoMVswLTldezJ9KXwoWzAtOV17MSwyfSkpXC4pezN9KCgyNVswLTVdKXwoMlswLTRdWzAtOV0pfCgxWzAtOV17Mn0pfChbMC05XXsxLDJ9KSkpJC87CiAgY29uc3QgYmFzZTY0UmVnZXggPSAvXihbMC05YS16QS1aKy9dezR9KSooKFswLTlhLXpBLVorL117Mn09PSl8KFswLTlhLXpBLVorL117M309KSk/JC87CiAgY29uc3QgZGF0ZVJlZ2V4U291cmNlID0gYCgoXFxkXFxkWzI0NjhdWzA0OF18XFxkXFxkWzEzNTc5XVsyNl18XFxkXFxkMFs0OF18WzAyNDY4XVswNDhdMDB8WzEzNTc5XVsyNl0wMCktMDItMjl8XFxkezR9LSgoMFsxMzU3OF18MVswMl0pLSgwWzEtOV18WzEyXVxcZHwzWzAxXSl8KDBbNDY5XXwxMSktKDBbMS05XXxbMTJdXFxkfDMwKXwoMDIpLSgwWzEtOV18MVxcZHwyWzAtOF0pKSlgOwogIGNvbnN0IGRhdGVSZWdleCA9IG5ldyBSZWdFeHAoYF4ke2RhdGVSZWdleFNvdXJjZX0kYCk7CiAgZnVuY3Rpb24gdGltZVJlZ2V4U291cmNlKGFyZ3MpIHsKICAgIGxldCByZWdleCA9IGAoWzAxXVxcZHwyWzAtM10pOlswLTVdXFxkOlswLTVdXFxkYDsKICAgIGlmIChhcmdzLnByZWNpc2lvbikgewogICAgICByZWdleCA9IGAke3JlZ2V4fVxcLlxcZHske2FyZ3MucHJlY2lzaW9ufX1gOwogICAgfSBlbHNlIGlmIChhcmdzLnByZWNpc2lvbiA9PSBudWxsKSB7CiAgICAgIHJlZ2V4ID0gYCR7cmVnZXh9KFxcLlxcZCspP2A7CiAgICB9CiAgICByZXR1cm4gcmVnZXg7CiAgfQogIGZ1bmN0aW9uIHRpbWVSZWdleChhcmdzKSB7CiAgICByZXR1cm4gbmV3IFJlZ0V4cChgXiR7dGltZVJlZ2V4U291cmNlKGFyZ3MpfSRgKTsKICB9CiAgZnVuY3Rpb24gZGF0ZXRpbWVSZWdleChhcmdzKSB7CiAgICBsZXQgcmVnZXggPSBgJHtkYXRlUmVnZXhTb3VyY2V9VCR7dGltZVJlZ2V4U291cmNlKGFyZ3MpfWA7CiAgICBjb25zdCBvcHRzID0gW107CiAgICBvcHRzLnB1c2goYXJncy5sb2NhbCA/IGBaP2AgOiBgWmApOwogICAgaWYgKGFyZ3Mub2Zmc2V0KQogICAgICBvcHRzLnB1c2goYChbKy1dXFxkezJ9Oj9cXGR7Mn0pYCk7CiAgICByZWdleCA9IGAke3JlZ2V4fSgke29wdHMuam9pbigifCIpfSlgOwogICAgcmV0dXJuIG5ldyBSZWdFeHAoYF4ke3JlZ2V4fSRgKTsKICB9CiAgZnVuY3Rpb24gaXNWYWxpZElQKGlwLCB2ZXJzaW9uKSB7CiAgICBpZiAoKHZlcnNpb24gPT09ICJ2NCIgfHwgIXZlcnNpb24pICYmIGlwdjRSZWdleC50ZXN0KGlwKSkgewogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIGlmICgodmVyc2lvbiA9PT0gInY2IiB8fCAhdmVyc2lvbikgJiYgaXB2NlJlZ2V4LnRlc3QoaXApKSB7CiAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgcmV0dXJuIGZhbHNlOwogIH0KICBjbGFzcyBab2RTdHJpbmcgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBpZiAodGhpcy5fZGVmLmNvZXJjZSkgewogICAgICAgIGlucHV0LmRhdGEgPSBTdHJpbmcoaW5wdXQuZGF0YSk7CiAgICAgIH0KICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpOwogICAgICBpZiAocGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5zdHJpbmcpIHsKICAgICAgICBjb25zdCBjdHgyID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpOwogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eDIsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsCiAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5zdHJpbmcsCiAgICAgICAgICByZWNlaXZlZDogY3R4Mi5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgY29uc3Qgc3RhdHVzID0gbmV3IFBhcnNlU3RhdHVzKCk7CiAgICAgIGxldCBjdHggPSB2b2lkIDA7CiAgICAgIGZvciAoY29uc3QgY2hlY2sgb2YgdGhpcy5fZGVmLmNoZWNrcykgewogICAgICAgIGlmIChjaGVjay5raW5kID09PSAibWluIikgewogICAgICAgICAgaWYgKGlucHV0LmRhdGEubGVuZ3RoIDwgY2hlY2sudmFsdWUpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsCiAgICAgICAgICAgICAgbWluaW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgdHlwZTogInN0cmluZyIsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBpZiAoaW5wdXQuZGF0YS5sZW5ndGggPiBjaGVjay52YWx1ZSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsCiAgICAgICAgICAgICAgbWF4aW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgdHlwZTogInN0cmluZyIsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJsZW5ndGgiKSB7CiAgICAgICAgICBjb25zdCB0b29CaWcgPSBpbnB1dC5kYXRhLmxlbmd0aCA+IGNoZWNrLnZhbHVlOwogICAgICAgICAgY29uc3QgdG9vU21hbGwgPSBpbnB1dC5kYXRhLmxlbmd0aCA8IGNoZWNrLnZhbHVlOwogICAgICAgICAgaWYgKHRvb0JpZyB8fCB0b29TbWFsbCkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgaWYgKHRvb0JpZykgewogICAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsCiAgICAgICAgICAgICAgICBtYXhpbXVtOiBjaGVjay52YWx1ZSwKICAgICAgICAgICAgICAgIHR5cGU6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgICAgZXhhY3Q6IHRydWUsCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0gZWxzZSBpZiAodG9vU21hbGwpIHsKICAgICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsCiAgICAgICAgICAgICAgICBtaW5pbXVtOiBjaGVjay52YWx1ZSwKICAgICAgICAgICAgICAgIHR5cGU6ICJzdHJpbmciLAogICAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgICAgZXhhY3Q6IHRydWUsCiAgICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiZW1haWwiKSB7CiAgICAgICAgICBpZiAoIWVtYWlsUmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogImVtYWlsIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiZW1vamkiKSB7CiAgICAgICAgICBpZiAoIWVtb2ppUmVnZXgpIHsKICAgICAgICAgICAgZW1vamlSZWdleCA9IG5ldyBSZWdFeHAoX2Vtb2ppUmVnZXgsICJ1Iik7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoIWVtb2ppUmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogImVtb2ppIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAidXVpZCIpIHsKICAgICAgICAgIGlmICghdXVpZFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJ1dWlkIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAibmFub2lkIikgewogICAgICAgICAgaWYgKCFuYW5vaWRSZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICB2YWxpZGF0aW9uOiAibmFub2lkIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiY3VpZCIpIHsKICAgICAgICAgIGlmICghY3VpZFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJjdWlkIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiY3VpZDIiKSB7CiAgICAgICAgICBpZiAoIWN1aWQyUmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogImN1aWQyIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAidWxpZCIpIHsKICAgICAgICAgIGlmICghdWxpZFJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJ1bGlkIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAidXJsIikgewogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgbmV3IFVSTChpbnB1dC5kYXRhKTsKICAgICAgICAgIH0gY2F0Y2ggKF9hKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICB2YWxpZGF0aW9uOiAidXJsIiwKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAicmVnZXgiKSB7CiAgICAgICAgICBjaGVjay5yZWdleC5sYXN0SW5kZXggPSAwOwogICAgICAgICAgY29uc3QgdGVzdFJlc3VsdCA9IGNoZWNrLnJlZ2V4LnRlc3QoaW5wdXQuZGF0YSk7CiAgICAgICAgICBpZiAoIXRlc3RSZXN1bHQpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJyZWdleCIsCiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gInRyaW0iKSB7CiAgICAgICAgICBpbnB1dC5kYXRhID0gaW5wdXQuZGF0YS50cmltKCk7CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiaW5jbHVkZXMiKSB7CiAgICAgICAgICBpZiAoIWlucHV0LmRhdGEuaW5jbHVkZXMoY2hlY2sudmFsdWUsIGNoZWNrLnBvc2l0aW9uKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIHZhbGlkYXRpb246IHsgaW5jbHVkZXM6IGNoZWNrLnZhbHVlLCBwb3NpdGlvbjogY2hlY2sucG9zaXRpb24gfSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJ0b0xvd2VyQ2FzZSIpIHsKICAgICAgICAgIGlucHV0LmRhdGEgPSBpbnB1dC5kYXRhLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAidG9VcHBlckNhc2UiKSB7CiAgICAgICAgICBpbnB1dC5kYXRhID0gaW5wdXQuZGF0YS50b1VwcGVyQ2FzZSgpOwogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gInN0YXJ0c1dpdGgiKSB7CiAgICAgICAgICBpZiAoIWlucHV0LmRhdGEuc3RhcnRzV2l0aChjaGVjay52YWx1ZSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZywKICAgICAgICAgICAgICB2YWxpZGF0aW9uOiB7IHN0YXJ0c1dpdGg6IGNoZWNrLnZhbHVlIH0sCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAiZW5kc1dpdGgiKSB7CiAgICAgICAgICBpZiAoIWlucHV0LmRhdGEuZW5kc1dpdGgoY2hlY2sudmFsdWUpKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogeyBlbmRzV2l0aDogY2hlY2sudmFsdWUgfSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJkYXRldGltZSIpIHsKICAgICAgICAgIGNvbnN0IHJlZ2V4ID0gZGF0ZXRpbWVSZWdleChjaGVjayk7CiAgICAgICAgICBpZiAoIXJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3N0cmluZywKICAgICAgICAgICAgICB2YWxpZGF0aW9uOiAiZGF0ZXRpbWUiLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gImRhdGUiKSB7CiAgICAgICAgICBjb25zdCByZWdleCA9IGRhdGVSZWdleDsKICAgICAgICAgIGlmICghcmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJkYXRlIiwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJ0aW1lIikgewogICAgICAgICAgY29uc3QgcmVnZXggPSB0aW1lUmVnZXgoY2hlY2spOwogICAgICAgICAgaWYgKCFyZWdleC50ZXN0KGlucHV0LmRhdGEpKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9zdHJpbmcsCiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogInRpbWUiLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gImR1cmF0aW9uIikgewogICAgICAgICAgaWYgKCFkdXJhdGlvblJlZ2V4LnRlc3QoaW5wdXQuZGF0YSkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJkdXJhdGlvbiIsCiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gImlwIikgewogICAgICAgICAgaWYgKCFpc1ZhbGlkSVAoaW5wdXQuZGF0YSwgY2hlY2sudmVyc2lvbikpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIHZhbGlkYXRpb246ICJpcCIsCiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gImJhc2U2NCIpIHsKICAgICAgICAgIGlmICghYmFzZTY0UmVnZXgudGVzdChpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgdmFsaWRhdGlvbjogImJhc2U2NCIsCiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB1dGlsLmFzc2VydE5ldmVyKGNoZWNrKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBpbnB1dC5kYXRhIH07CiAgICB9CiAgICBfcmVnZXgocmVnZXgsIHZhbGlkYXRpb24sIG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMucmVmaW5lbWVudCgoZGF0YSkgPT4gcmVnZXgudGVzdChkYXRhKSwgewogICAgICAgIHZhbGlkYXRpb24sCiAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfc3RyaW5nLAogICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIF9hZGRDaGVjayhjaGVjaykgewogICAgICByZXR1cm4gbmV3IFpvZFN0cmluZyh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIGNoZWNrczogWy4uLnRoaXMuX2RlZi5jaGVja3MsIGNoZWNrXQogICAgICB9KTsKICAgIH0KICAgIGVtYWlsKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImVtYWlsIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgdXJsKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogInVybCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTsKICAgIH0KICAgIGVtb2ppKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImVtb2ppIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgdXVpZChtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7IGtpbmQ6ICJ1dWlkIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgbmFub2lkKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogIm5hbm9pZCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTsKICAgIH0KICAgIGN1aWQobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soeyBraW5kOiAiY3VpZCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTsKICAgIH0KICAgIGN1aWQyKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImN1aWQyIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgdWxpZChtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7IGtpbmQ6ICJ1bGlkIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgYmFzZTY0KG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImJhc2U2NCIsIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKSB9KTsKICAgIH0KICAgIGlwKG9wdGlvbnMpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImlwIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnMpIH0pOwogICAgfQogICAgZGF0ZXRpbWUob3B0aW9ucykgewogICAgICB2YXIgX2EsIF9iOwogICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICJzdHJpbmciKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICAgIGtpbmQ6ICJkYXRldGltZSIsCiAgICAgICAgICBwcmVjaXNpb246IG51bGwsCiAgICAgICAgICBvZmZzZXQ6IGZhbHNlLAogICAgICAgICAgbG9jYWw6IGZhbHNlLAogICAgICAgICAgbWVzc2FnZTogb3B0aW9ucwogICAgICAgIH0pOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogImRhdGV0aW1lIiwKICAgICAgICBwcmVjaXNpb246IHR5cGVvZiAob3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZWNpc2lvbikgPT09ICJ1bmRlZmluZWQiID8gbnVsbCA6IG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy5wcmVjaXNpb24sCiAgICAgICAgb2Zmc2V0OiAoX2EgPSBvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMub2Zmc2V0KSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiBmYWxzZSwKICAgICAgICBsb2NhbDogKF9iID0gb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLmxvY2FsKSAhPT0gbnVsbCAmJiBfYiAhPT0gdm9pZCAwID8gX2IgOiBmYWxzZSwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoob3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLm1lc3NhZ2UpCiAgICAgIH0pOwogICAgfQogICAgZGF0ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7IGtpbmQ6ICJkYXRlIiwgbWVzc2FnZSB9KTsKICAgIH0KICAgIHRpbWUob3B0aW9ucykgewogICAgICBpZiAodHlwZW9mIG9wdGlvbnMgPT09ICJzdHJpbmciKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICAgIGtpbmQ6ICJ0aW1lIiwKICAgICAgICAgIHByZWNpc2lvbjogbnVsbCwKICAgICAgICAgIG1lc3NhZ2U6IG9wdGlvbnMKICAgICAgICB9KTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJ0aW1lIiwKICAgICAgICBwcmVjaXNpb246IHR5cGVvZiAob3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnByZWNpc2lvbikgPT09ICJ1bmRlZmluZWQiID8gbnVsbCA6IG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy5wcmVjaXNpb24sCiAgICAgICAgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG9wdGlvbnMgPT09IG51bGwgfHwgb3B0aW9ucyA9PT0gdm9pZCAwID8gdm9pZCAwIDogb3B0aW9ucy5tZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIGR1cmF0aW9uKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsga2luZDogImR1cmF0aW9uIiwgLi4uZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpIH0pOwogICAgfQogICAgcmVnZXgocmVnZXgsIG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICBraW5kOiAicmVnZXgiLAogICAgICAgIHJlZ2V4LAogICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIGluY2x1ZGVzKHZhbHVlLCBvcHRpb25zKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogImluY2x1ZGVzIiwKICAgICAgICB2YWx1ZSwKICAgICAgICBwb3NpdGlvbjogb3B0aW9ucyA9PT0gbnVsbCB8fCBvcHRpb25zID09PSB2b2lkIDAgPyB2b2lkIDAgOiBvcHRpb25zLnBvc2l0aW9uLAogICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihvcHRpb25zID09PSBudWxsIHx8IG9wdGlvbnMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IG9wdGlvbnMubWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBzdGFydHNXaXRoKHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogInN0YXJ0c1dpdGgiLAogICAgICAgIHZhbHVlLAogICAgICAgIC4uLmVycm9yVXRpbC5lcnJUb09iaihtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIGVuZHNXaXRoKHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogImVuZHNXaXRoIiwKICAgICAgICB2YWx1ZSwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBtaW4obWluTGVuZ3RoLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1pbiIsCiAgICAgICAgdmFsdWU6IG1pbkxlbmd0aCwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBtYXgobWF4TGVuZ3RoLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IG1heExlbmd0aCwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBsZW5ndGgobGVuLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogImxlbmd0aCIsCiAgICAgICAgdmFsdWU6IGxlbiwKICAgICAgICAuLi5lcnJvclV0aWwuZXJyVG9PYmoobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICAvKioKICAgICAqIEBkZXByZWNhdGVkIFVzZSB6LnN0cmluZygpLm1pbigxKSBpbnN0ZWFkLgogICAgICogQHNlZSB7QGxpbmsgWm9kU3RyaW5nLm1pbn0KICAgICAqLwogICAgbm9uZW1wdHkobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5taW4oMSwgZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpKTsKICAgIH0KICAgIHRyaW0oKSB7CiAgICAgIHJldHVybiBuZXcgWm9kU3RyaW5nKHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbLi4udGhpcy5fZGVmLmNoZWNrcywgeyBraW5kOiAidHJpbSIgfV0KICAgICAgfSk7CiAgICB9CiAgICB0b0xvd2VyQ2FzZSgpIHsKICAgICAgcmV0dXJuIG5ldyBab2RTdHJpbmcoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBjaGVja3M6IFsuLi50aGlzLl9kZWYuY2hlY2tzLCB7IGtpbmQ6ICJ0b0xvd2VyQ2FzZSIgfV0KICAgICAgfSk7CiAgICB9CiAgICB0b1VwcGVyQ2FzZSgpIHsKICAgICAgcmV0dXJuIG5ldyBab2RTdHJpbmcoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBjaGVja3M6IFsuLi50aGlzLl9kZWYuY2hlY2tzLCB7IGtpbmQ6ICJ0b1VwcGVyQ2FzZSIgfV0KICAgICAgfSk7CiAgICB9CiAgICBnZXQgaXNEYXRldGltZSgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gImRhdGV0aW1lIik7CiAgICB9CiAgICBnZXQgaXNEYXRlKCkgewogICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSAiZGF0ZSIpOwogICAgfQogICAgZ2V0IGlzVGltZSgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gInRpbWUiKTsKICAgIH0KICAgIGdldCBpc0R1cmF0aW9uKCkgewogICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSAiZHVyYXRpb24iKTsKICAgIH0KICAgIGdldCBpc0VtYWlsKCkgewogICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSAiZW1haWwiKTsKICAgIH0KICAgIGdldCBpc1VSTCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gInVybCIpOwogICAgfQogICAgZ2V0IGlzRW1vamkoKSB7CiAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09ICJlbW9qaSIpOwogICAgfQogICAgZ2V0IGlzVVVJRCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gInV1aWQiKTsKICAgIH0KICAgIGdldCBpc05BTk9JRCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gIm5hbm9pZCIpOwogICAgfQogICAgZ2V0IGlzQ1VJRCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gImN1aWQiKTsKICAgIH0KICAgIGdldCBpc0NVSUQyKCkgewogICAgICByZXR1cm4gISF0aGlzLl9kZWYuY2hlY2tzLmZpbmQoKGNoKSA9PiBjaC5raW5kID09PSAiY3VpZDIiKTsKICAgIH0KICAgIGdldCBpc1VMSUQoKSB7CiAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09ICJ1bGlkIik7CiAgICB9CiAgICBnZXQgaXNJUCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gImlwIik7CiAgICB9CiAgICBnZXQgaXNCYXNlNjQoKSB7CiAgICAgIHJldHVybiAhIXRoaXMuX2RlZi5jaGVja3MuZmluZCgoY2gpID0+IGNoLmtpbmQgPT09ICJiYXNlNjQiKTsKICAgIH0KICAgIGdldCBtaW5MZW5ndGgoKSB7CiAgICAgIGxldCBtaW4gPSBudWxsOwogICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2gua2luZCA9PT0gIm1pbiIpIHsKICAgICAgICAgIGlmIChtaW4gPT09IG51bGwgfHwgY2gudmFsdWUgPiBtaW4pCiAgICAgICAgICAgIG1pbiA9IGNoLnZhbHVlOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gbWluOwogICAgfQogICAgZ2V0IG1heExlbmd0aCgpIHsKICAgICAgbGV0IG1heCA9IG51bGw7CiAgICAgIGZvciAoY29uc3QgY2ggb2YgdGhpcy5fZGVmLmNoZWNrcykgewogICAgICAgIGlmIChjaC5raW5kID09PSAibWF4IikgewogICAgICAgICAgaWYgKG1heCA9PT0gbnVsbCB8fCBjaC52YWx1ZSA8IG1heCkKICAgICAgICAgICAgbWF4ID0gY2gudmFsdWU7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBtYXg7CiAgICB9CiAgfQogIFpvZFN0cmluZy5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICB2YXIgX2E7CiAgICByZXR1cm4gbmV3IFpvZFN0cmluZyh7CiAgICAgIGNoZWNrczogW10sCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3RyaW5nLAogICAgICBjb2VyY2U6IChfYSA9IHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5jb2VyY2UpICE9PSBudWxsICYmIF9hICE9PSB2b2lkIDAgPyBfYSA6IGZhbHNlLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgZnVuY3Rpb24gZmxvYXRTYWZlUmVtYWluZGVyKHZhbCwgc3RlcCkgewogICAgY29uc3QgdmFsRGVjQ291bnQgPSAodmFsLnRvU3RyaW5nKCkuc3BsaXQoIi4iKVsxXSB8fCAiIikubGVuZ3RoOwogICAgY29uc3Qgc3RlcERlY0NvdW50ID0gKHN0ZXAudG9TdHJpbmcoKS5zcGxpdCgiLiIpWzFdIHx8ICIiKS5sZW5ndGg7CiAgICBjb25zdCBkZWNDb3VudCA9IHZhbERlY0NvdW50ID4gc3RlcERlY0NvdW50ID8gdmFsRGVjQ291bnQgOiBzdGVwRGVjQ291bnQ7CiAgICBjb25zdCB2YWxJbnQgPSBwYXJzZUludCh2YWwudG9GaXhlZChkZWNDb3VudCkucmVwbGFjZSgiLiIsICIiKSk7CiAgICBjb25zdCBzdGVwSW50ID0gcGFyc2VJbnQoc3RlcC50b0ZpeGVkKGRlY0NvdW50KS5yZXBsYWNlKCIuIiwgIiIpKTsKICAgIHJldHVybiB2YWxJbnQgJSBzdGVwSW50IC8gTWF0aC5wb3coMTAsIGRlY0NvdW50KTsKICB9CiAgY2xhc3MgWm9kTnVtYmVyIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTsKICAgICAgdGhpcy5taW4gPSB0aGlzLmd0ZTsKICAgICAgdGhpcy5tYXggPSB0aGlzLmx0ZTsKICAgICAgdGhpcy5zdGVwID0gdGhpcy5tdWx0aXBsZU9mOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGlmICh0aGlzLl9kZWYuY29lcmNlKSB7CiAgICAgICAgaW5wdXQuZGF0YSA9IE51bWJlcihpbnB1dC5kYXRhKTsKICAgICAgfQogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm51bWJlcikgewogICAgICAgIGNvbnN0IGN0eDIgPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4MiwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm51bWJlciwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgyLnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICBsZXQgY3R4ID0gdm9pZCAwOwogICAgICBjb25zdCBzdGF0dXMgPSBuZXcgUGFyc2VTdGF0dXMoKTsKICAgICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoZWNrLmtpbmQgPT09ICJpbnQiKSB7CiAgICAgICAgICBpZiAoIXV0aWwuaXNJbnRlZ2VyKGlucHV0LmRhdGEpKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgICAgIGV4cGVjdGVkOiAiaW50ZWdlciIsCiAgICAgICAgICAgICAgcmVjZWl2ZWQ6ICJmbG9hdCIsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAibWluIikgewogICAgICAgICAgY29uc3QgdG9vU21hbGwgPSBjaGVjay5pbmNsdXNpdmUgPyBpbnB1dC5kYXRhIDwgY2hlY2sudmFsdWUgOiBpbnB1dC5kYXRhIDw9IGNoZWNrLnZhbHVlOwogICAgICAgICAgaWYgKHRvb1NtYWxsKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLAogICAgICAgICAgICAgIG1pbmltdW06IGNoZWNrLnZhbHVlLAogICAgICAgICAgICAgIHR5cGU6ICJudW1iZXIiLAogICAgICAgICAgICAgIGluY2x1c2l2ZTogY2hlY2suaW5jbHVzaXZlLAogICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBjb25zdCB0b29CaWcgPSBjaGVjay5pbmNsdXNpdmUgPyBpbnB1dC5kYXRhID4gY2hlY2sudmFsdWUgOiBpbnB1dC5kYXRhID49IGNoZWNrLnZhbHVlOwogICAgICAgICAgaWYgKHRvb0JpZykgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19iaWcsCiAgICAgICAgICAgICAgbWF4aW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgdHlwZTogIm51bWJlciIsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiBjaGVjay5pbmNsdXNpdmUsCiAgICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gIm11bHRpcGxlT2YiKSB7CiAgICAgICAgICBpZiAoZmxvYXRTYWZlUmVtYWluZGVyKGlucHV0LmRhdGEsIGNoZWNrLnZhbHVlKSAhPT0gMCkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLm5vdF9tdWx0aXBsZV9vZiwKICAgICAgICAgICAgICBtdWx0aXBsZU9mOiBjaGVjay52YWx1ZSwKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKGNoZWNrLmtpbmQgPT09ICJmaW5pdGUiKSB7CiAgICAgICAgICBpZiAoIU51bWJlci5pc0Zpbml0ZShpbnB1dC5kYXRhKSkgewogICAgICAgICAgICBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCwgY3R4KTsKICAgICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLm5vdF9maW5pdGUsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoY2hlY2spOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IGlucHV0LmRhdGEgfTsKICAgIH0KICAgIGd0ZSh2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdCgibWluIiwgdmFsdWUsIHRydWUsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7CiAgICB9CiAgICBndCh2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdCgibWluIiwgdmFsdWUsIGZhbHNlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpOwogICAgfQogICAgbHRlKHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KCJtYXgiLCB2YWx1ZSwgdHJ1ZSwgZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpKTsKICAgIH0KICAgIGx0KHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KCJtYXgiLCB2YWx1ZSwgZmFsc2UsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7CiAgICB9CiAgICBzZXRMaW1pdChraW5kLCB2YWx1ZSwgaW5jbHVzaXZlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kTnVtYmVyKHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbCiAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLAogICAgICAgICAgewogICAgICAgICAgICBraW5kLAogICAgICAgICAgICB2YWx1ZSwKICAgICAgICAgICAgaW5jbHVzaXZlLAogICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgICAgIH0KICAgICAgICBdCiAgICAgIH0pOwogICAgfQogICAgX2FkZENoZWNrKGNoZWNrKSB7CiAgICAgIHJldHVybiBuZXcgWm9kTnVtYmVyKHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbLi4udGhpcy5fZGVmLmNoZWNrcywgY2hlY2tdCiAgICAgIH0pOwogICAgfQogICAgaW50KG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICBraW5kOiAiaW50IiwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBwb3NpdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1pbiIsCiAgICAgICAgdmFsdWU6IDAsCiAgICAgICAgaW5jbHVzaXZlOiBmYWxzZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBuZWdhdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IDAsCiAgICAgICAgaW5jbHVzaXZlOiBmYWxzZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBub25wb3NpdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IDAsCiAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIG5vbm5lZ2F0aXZlKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICBraW5kOiAibWluIiwKICAgICAgICB2YWx1ZTogMCwKICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpCiAgICAgIH0pOwogICAgfQogICAgbXVsdGlwbGVPZih2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJtdWx0aXBsZU9mIiwKICAgICAgICB2YWx1ZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBmaW5pdGUobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJmaW5pdGUiLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIHNhZmUobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJtaW4iLAogICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICB2YWx1ZTogTnVtYmVyLk1JTl9TQUZFX0lOVEVHRVIsCiAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpCiAgICAgIH0pLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgIHZhbHVlOiBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUiwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBnZXQgbWluVmFsdWUoKSB7CiAgICAgIGxldCBtaW4gPSBudWxsOwogICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2gua2luZCA9PT0gIm1pbiIpIHsKICAgICAgICAgIGlmIChtaW4gPT09IG51bGwgfHwgY2gudmFsdWUgPiBtaW4pCiAgICAgICAgICAgIG1pbiA9IGNoLnZhbHVlOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gbWluOwogICAgfQogICAgZ2V0IG1heFZhbHVlKCkgewogICAgICBsZXQgbWF4ID0gbnVsbDsKICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNoLnZhbHVlIDwgbWF4KQogICAgICAgICAgICBtYXggPSBjaC52YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIG1heDsKICAgIH0KICAgIGdldCBpc0ludCgpIHsKICAgICAgcmV0dXJuICEhdGhpcy5fZGVmLmNoZWNrcy5maW5kKChjaCkgPT4gY2gua2luZCA9PT0gImludCIgfHwgY2gua2luZCA9PT0gIm11bHRpcGxlT2YiICYmIHV0aWwuaXNJbnRlZ2VyKGNoLnZhbHVlKSk7CiAgICB9CiAgICBnZXQgaXNGaW5pdGUoKSB7CiAgICAgIGxldCBtYXggPSBudWxsLCBtaW4gPSBudWxsOwogICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2gua2luZCA9PT0gImZpbml0ZSIgfHwgY2gua2luZCA9PT0gImludCIgfHwgY2gua2luZCA9PT0gIm11bHRpcGxlT2YiKSB7CiAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9IGVsc2UgaWYgKGNoLmtpbmQgPT09ICJtaW4iKSB7CiAgICAgICAgICBpZiAobWluID09PSBudWxsIHx8IGNoLnZhbHVlID4gbWluKQogICAgICAgICAgICBtaW4gPSBjaC52YWx1ZTsKICAgICAgICB9IGVsc2UgaWYgKGNoLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNoLnZhbHVlIDwgbWF4KQogICAgICAgICAgICBtYXggPSBjaC52YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShtaW4pICYmIE51bWJlci5pc0Zpbml0ZShtYXgpOwogICAgfQogIH0KICBab2ROdW1iZXIuY3JlYXRlID0gKHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2ROdW1iZXIoewogICAgICBjaGVja3M6IFtdLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bWJlciwKICAgICAgY29lcmNlOiAocGFyYW1zID09PSBudWxsIHx8IHBhcmFtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFyYW1zLmNvZXJjZSkgfHwgZmFsc2UsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RCaWdJbnQgZXh0ZW5kcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICBzdXBlciguLi5hcmd1bWVudHMpOwogICAgICB0aGlzLm1pbiA9IHRoaXMuZ3RlOwogICAgICB0aGlzLm1heCA9IHRoaXMubHRlOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGlmICh0aGlzLl9kZWYuY29lcmNlKSB7CiAgICAgICAgaW5wdXQuZGF0YSA9IEJpZ0ludChpbnB1dC5kYXRhKTsKICAgICAgfQogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLmJpZ2ludCkgewogICAgICAgIGNvbnN0IGN0eDIgPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4MiwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmJpZ2ludCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgyLnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICBsZXQgY3R4ID0gdm9pZCAwOwogICAgICBjb25zdCBzdGF0dXMgPSBuZXcgUGFyc2VTdGF0dXMoKTsKICAgICAgZm9yIChjb25zdCBjaGVjayBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoZWNrLmtpbmQgPT09ICJtaW4iKSB7CiAgICAgICAgICBjb25zdCB0b29TbWFsbCA9IGNoZWNrLmluY2x1c2l2ZSA/IGlucHV0LmRhdGEgPCBjaGVjay52YWx1ZSA6IGlucHV0LmRhdGEgPD0gY2hlY2sudmFsdWU7CiAgICAgICAgICBpZiAodG9vU21hbGwpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsCiAgICAgICAgICAgICAgdHlwZTogImJpZ2ludCIsCiAgICAgICAgICAgICAgbWluaW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiBjaGVjay5pbmNsdXNpdmUsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChjaGVjay5raW5kID09PSAibWF4IikgewogICAgICAgICAgY29uc3QgdG9vQmlnID0gY2hlY2suaW5jbHVzaXZlID8gaW5wdXQuZGF0YSA+IGNoZWNrLnZhbHVlIDogaW5wdXQuZGF0YSA+PSBjaGVjay52YWx1ZTsKICAgICAgICAgIGlmICh0b29CaWcpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fYmlnLAogICAgICAgICAgICAgIHR5cGU6ICJiaWdpbnQiLAogICAgICAgICAgICAgIG1heGltdW06IGNoZWNrLnZhbHVlLAogICAgICAgICAgICAgIGluY2x1c2l2ZTogY2hlY2suaW5jbHVzaXZlLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gIm11bHRpcGxlT2YiKSB7CiAgICAgICAgICBpZiAoaW5wdXQuZGF0YSAlIGNoZWNrLnZhbHVlICE9PSBCaWdJbnQoMCkpIHsKICAgICAgICAgICAgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQsIGN0eCk7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5ub3RfbXVsdGlwbGVfb2YsCiAgICAgICAgICAgICAgbXVsdGlwbGVPZjogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgbWVzc2FnZTogY2hlY2subWVzc2FnZQogICAgICAgICAgICB9KTsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoY2hlY2spOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IGlucHV0LmRhdGEgfTsKICAgIH0KICAgIGd0ZSh2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdCgibWluIiwgdmFsdWUsIHRydWUsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7CiAgICB9CiAgICBndCh2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5zZXRMaW1pdCgibWluIiwgdmFsdWUsIGZhbHNlLCBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkpOwogICAgfQogICAgbHRlKHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KCJtYXgiLCB2YWx1ZSwgdHJ1ZSwgZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpKTsKICAgIH0KICAgIGx0KHZhbHVlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLnNldExpbWl0KCJtYXgiLCB2YWx1ZSwgZmFsc2UsIGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSk7CiAgICB9CiAgICBzZXRMaW1pdChraW5kLCB2YWx1ZSwgaW5jbHVzaXZlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQmlnSW50KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbCiAgICAgICAgICAuLi50aGlzLl9kZWYuY2hlY2tzLAogICAgICAgICAgewogICAgICAgICAgICBraW5kLAogICAgICAgICAgICB2YWx1ZSwKICAgICAgICAgICAgaW5jbHVzaXZlLAogICAgICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgICAgIH0KICAgICAgICBdCiAgICAgIH0pOwogICAgfQogICAgX2FkZENoZWNrKGNoZWNrKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQmlnSW50KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgY2hlY2tzOiBbLi4udGhpcy5fZGVmLmNoZWNrcywgY2hlY2tdCiAgICAgIH0pOwogICAgfQogICAgcG9zaXRpdmUobWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJtaW4iLAogICAgICAgIHZhbHVlOiBCaWdJbnQoMCksCiAgICAgICAgaW5jbHVzaXZlOiBmYWxzZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBuZWdhdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IEJpZ0ludCgwKSwKICAgICAgICBpbmNsdXNpdmU6IGZhbHNlLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIG5vbnBvc2l0aXZlKG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMuX2FkZENoZWNrKHsKICAgICAgICBraW5kOiAibWF4IiwKICAgICAgICB2YWx1ZTogQmlnSW50KDApLAogICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBub25uZWdhdGl2ZShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1pbiIsCiAgICAgICAgdmFsdWU6IEJpZ0ludCgwKSwKICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpCiAgICAgIH0pOwogICAgfQogICAgbXVsdGlwbGVPZih2YWx1ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gdGhpcy5fYWRkQ2hlY2soewogICAgICAgIGtpbmQ6ICJtdWx0aXBsZU9mIiwKICAgICAgICB2YWx1ZSwKICAgICAgICBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkKICAgICAgfSk7CiAgICB9CiAgICBnZXQgbWluVmFsdWUoKSB7CiAgICAgIGxldCBtaW4gPSBudWxsOwogICAgICBmb3IgKGNvbnN0IGNoIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2gua2luZCA9PT0gIm1pbiIpIHsKICAgICAgICAgIGlmIChtaW4gPT09IG51bGwgfHwgY2gudmFsdWUgPiBtaW4pCiAgICAgICAgICAgIG1pbiA9IGNoLnZhbHVlOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gbWluOwogICAgfQogICAgZ2V0IG1heFZhbHVlKCkgewogICAgICBsZXQgbWF4ID0gbnVsbDsKICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoLmtpbmQgPT09ICJtYXgiKSB7CiAgICAgICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNoLnZhbHVlIDwgbWF4KQogICAgICAgICAgICBtYXggPSBjaC52YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIG1heDsKICAgIH0KICB9CiAgWm9kQmlnSW50LmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHZhciBfYTsKICAgIHJldHVybiBuZXcgWm9kQmlnSW50KHsKICAgICAgY2hlY2tzOiBbXSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RCaWdJbnQsCiAgICAgIGNvZXJjZTogKF9hID0gcGFyYW1zID09PSBudWxsIHx8IHBhcmFtcyA9PT0gdm9pZCAwID8gdm9pZCAwIDogcGFyYW1zLmNvZXJjZSkgIT09IG51bGwgJiYgX2EgIT09IHZvaWQgMCA/IF9hIDogZmFsc2UsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RCb29sZWFuIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgaWYgKHRoaXMuX2RlZi5jb2VyY2UpIHsKICAgICAgICBpbnB1dC5kYXRhID0gQm9vbGVhbihpbnB1dC5kYXRhKTsKICAgICAgfQogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLmJvb2xlYW4pIHsKICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUuYm9vbGVhbiwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTsKICAgIH0KICB9CiAgWm9kQm9vbGVhbi5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZEJvb2xlYW4oewogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEJvb2xlYW4sCiAgICAgIGNvZXJjZTogKHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5jb2VyY2UpIHx8IGZhbHNlLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kRGF0ZSBleHRlbmRzIFpvZFR5cGUgewogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGlmICh0aGlzLl9kZWYuY29lcmNlKSB7CiAgICAgICAgaW5wdXQuZGF0YSA9IG5ldyBEYXRlKGlucHV0LmRhdGEpOwogICAgICB9CiAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTsKICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuZGF0ZSkgewogICAgICAgIGNvbnN0IGN0eDIgPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4MiwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmRhdGUsCiAgICAgICAgICByZWNlaXZlZDogY3R4Mi5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgaWYgKGlzTmFOKGlucHV0LmRhdGEuZ2V0VGltZSgpKSkgewogICAgICAgIGNvbnN0IGN0eDIgPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4MiwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfZGF0ZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IHN0YXR1cyA9IG5ldyBQYXJzZVN0YXR1cygpOwogICAgICBsZXQgY3R4ID0gdm9pZCAwOwogICAgICBmb3IgKGNvbnN0IGNoZWNrIG9mIHRoaXMuX2RlZi5jaGVja3MpIHsKICAgICAgICBpZiAoY2hlY2sua2luZCA9PT0gIm1pbiIpIHsKICAgICAgICAgIGlmIChpbnB1dC5kYXRhLmdldFRpbWUoKSA8IGNoZWNrLnZhbHVlKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLAogICAgICAgICAgICAgIG1lc3NhZ2U6IGNoZWNrLm1lc3NhZ2UsCiAgICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgICBtaW5pbXVtOiBjaGVjay52YWx1ZSwKICAgICAgICAgICAgICB0eXBlOiAiZGF0ZSIKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoY2hlY2sua2luZCA9PT0gIm1heCIpIHsKICAgICAgICAgIGlmIChpbnB1dC5kYXRhLmdldFRpbWUoKSA+IGNoZWNrLnZhbHVlKSB7CiAgICAgICAgICAgIGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0LCBjdHgpOwogICAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZywKICAgICAgICAgICAgICBtZXNzYWdlOiBjaGVjay5tZXNzYWdlLAogICAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICAgICAgICBleGFjdDogZmFsc2UsCiAgICAgICAgICAgICAgbWF4aW11bTogY2hlY2sudmFsdWUsCiAgICAgICAgICAgICAgdHlwZTogImRhdGUiCiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgdXRpbC5hc3NlcnROZXZlcihjaGVjayk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiB7CiAgICAgICAgc3RhdHVzOiBzdGF0dXMudmFsdWUsCiAgICAgICAgdmFsdWU6IG5ldyBEYXRlKGlucHV0LmRhdGEuZ2V0VGltZSgpKQogICAgICB9OwogICAgfQogICAgX2FkZENoZWNrKGNoZWNrKSB7CiAgICAgIHJldHVybiBuZXcgWm9kRGF0ZSh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIGNoZWNrczogWy4uLnRoaXMuX2RlZi5jaGVja3MsIGNoZWNrXQogICAgICB9KTsKICAgIH0KICAgIG1pbihtaW5EYXRlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1pbiIsCiAgICAgICAgdmFsdWU6IG1pbkRhdGUuZ2V0VGltZSgpLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIG1heChtYXhEYXRlLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLl9hZGRDaGVjayh7CiAgICAgICAga2luZDogIm1heCIsCiAgICAgICAgdmFsdWU6IG1heERhdGUuZ2V0VGltZSgpLAogICAgICAgIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKQogICAgICB9KTsKICAgIH0KICAgIGdldCBtaW5EYXRlKCkgewogICAgICBsZXQgbWluID0gbnVsbDsKICAgICAgZm9yIChjb25zdCBjaCBvZiB0aGlzLl9kZWYuY2hlY2tzKSB7CiAgICAgICAgaWYgKGNoLmtpbmQgPT09ICJtaW4iKSB7CiAgICAgICAgICBpZiAobWluID09PSBudWxsIHx8IGNoLnZhbHVlID4gbWluKQogICAgICAgICAgICBtaW4gPSBjaC52YWx1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIG1pbiAhPSBudWxsID8gbmV3IERhdGUobWluKSA6IG51bGw7CiAgICB9CiAgICBnZXQgbWF4RGF0ZSgpIHsKICAgICAgbGV0IG1heCA9IG51bGw7CiAgICAgIGZvciAoY29uc3QgY2ggb2YgdGhpcy5fZGVmLmNoZWNrcykgewogICAgICAgIGlmIChjaC5raW5kID09PSAibWF4IikgewogICAgICAgICAgaWYgKG1heCA9PT0gbnVsbCB8fCBjaC52YWx1ZSA8IG1heCkKICAgICAgICAgICAgbWF4ID0gY2gudmFsdWU7CiAgICAgICAgfQogICAgICB9CiAgICAgIHJldHVybiBtYXggIT0gbnVsbCA/IG5ldyBEYXRlKG1heCkgOiBudWxsOwogICAgfQogIH0KICBab2REYXRlLmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kRGF0ZSh7CiAgICAgIGNoZWNrczogW10sCiAgICAgIGNvZXJjZTogKHBhcmFtcyA9PT0gbnVsbCB8fCBwYXJhbXMgPT09IHZvaWQgMCA/IHZvaWQgMCA6IHBhcmFtcy5jb2VyY2UpIHx8IGZhbHNlLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZERhdGUsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RTeW1ib2wgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLnN5bWJvbCkgewogICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsCiAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5zeW1ib2wsCiAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7CiAgICB9CiAgfQogIFpvZFN5bWJvbC5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZFN5bWJvbCh7CiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU3ltYm9sLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kVW5kZWZpbmVkIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpOwogICAgICBpZiAocGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQpIHsKICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkLAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpOwogICAgfQogIH0KICBab2RVbmRlZmluZWQuY3JlYXRlID0gKHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RVbmRlZmluZWQoewogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFVuZGVmaW5lZCwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZE51bGwgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm51bGwpIHsKICAgICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUubnVsbCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTsKICAgIH0KICB9CiAgWm9kTnVsbC5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE51bGwoewogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bGwsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RBbnkgZXh0ZW5kcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICBzdXBlciguLi5hcmd1bWVudHMpOwogICAgICB0aGlzLl9hbnkgPSB0cnVlOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIHJldHVybiBPSyhpbnB1dC5kYXRhKTsKICAgIH0KICB9CiAgWm9kQW55LmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kQW55KHsKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RBbnksCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RVbmtub3duIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTsKICAgICAgdGhpcy5fdW5rbm93biA9IHRydWU7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpOwogICAgfQogIH0KICBab2RVbmtub3duLmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kVW5rbm93bih7CiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kVW5rbm93biwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZE5ldmVyIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpOwogICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm5ldmVyLAogICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICB9KTsKICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICB9CiAgfQogIFpvZE5ldmVyLmNyZWF0ZSA9IChwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kTmV2ZXIoewogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE5ldmVyLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kVm9pZCBleHRlbmRzIFpvZFR5cGUgewogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTsKICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7CiAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpOwogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLnZvaWQsCiAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7CiAgICB9CiAgfQogIFpvZFZvaWQuY3JlYXRlID0gKHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RWb2lkKHsKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RWb2lkLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kQXJyYXkgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IGN0eCwgc3RhdHVzIH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBjb25zdCBkZWYgPSB0aGlzLl9kZWY7CiAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5hcnJheSkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmFycmF5LAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgaWYgKGRlZi5leGFjdExlbmd0aCAhPT0gbnVsbCkgewogICAgICAgIGNvbnN0IHRvb0JpZyA9IGN0eC5kYXRhLmxlbmd0aCA+IGRlZi5leGFjdExlbmd0aC52YWx1ZTsKICAgICAgICBjb25zdCB0b29TbWFsbCA9IGN0eC5kYXRhLmxlbmd0aCA8IGRlZi5leGFjdExlbmd0aC52YWx1ZTsKICAgICAgICBpZiAodG9vQmlnIHx8IHRvb1NtYWxsKSB7CiAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgY29kZTogdG9vQmlnID8gWm9kSXNzdWVDb2RlLnRvb19iaWcgOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLAogICAgICAgICAgICBtaW5pbXVtOiB0b29TbWFsbCA/IGRlZi5leGFjdExlbmd0aC52YWx1ZSA6IHZvaWQgMCwKICAgICAgICAgICAgbWF4aW11bTogdG9vQmlnID8gZGVmLmV4YWN0TGVuZ3RoLnZhbHVlIDogdm9pZCAwLAogICAgICAgICAgICB0eXBlOiAiYXJyYXkiLAogICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgICAgIGV4YWN0OiB0cnVlLAogICAgICAgICAgICBtZXNzYWdlOiBkZWYuZXhhY3RMZW5ndGgubWVzc2FnZQogICAgICAgICAgfSk7CiAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGRlZi5taW5MZW5ndGggIT09IG51bGwpIHsKICAgICAgICBpZiAoY3R4LmRhdGEubGVuZ3RoIDwgZGVmLm1pbkxlbmd0aC52YWx1ZSkgewogICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fc21hbGwsCiAgICAgICAgICAgIG1pbmltdW06IGRlZi5taW5MZW5ndGgudmFsdWUsCiAgICAgICAgICAgIHR5cGU6ICJhcnJheSIsCiAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLAogICAgICAgICAgICBtZXNzYWdlOiBkZWYubWluTGVuZ3RoLm1lc3NhZ2UKICAgICAgICAgIH0pOwogICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChkZWYubWF4TGVuZ3RoICE9PSBudWxsKSB7CiAgICAgICAgaWYgKGN0eC5kYXRhLmxlbmd0aCA+IGRlZi5tYXhMZW5ndGgudmFsdWUpIHsKICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZywKICAgICAgICAgICAgbWF4aW11bTogZGVmLm1heExlbmd0aC52YWx1ZSwKICAgICAgICAgICAgdHlwZTogImFycmF5IiwKICAgICAgICAgICAgaW5jbHVzaXZlOiB0cnVlLAogICAgICAgICAgICBleGFjdDogZmFsc2UsCiAgICAgICAgICAgIG1lc3NhZ2U6IGRlZi5tYXhMZW5ndGgubWVzc2FnZQogICAgICAgICAgfSk7CiAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5hbGwoWy4uLmN0eC5kYXRhXS5tYXAoKGl0ZW0sIGkyKSA9PiB7CiAgICAgICAgICByZXR1cm4gZGVmLnR5cGUuX3BhcnNlQXN5bmMobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGl0ZW0sIGN0eC5wYXRoLCBpMikpOwogICAgICAgIH0pKS50aGVuKChyZXN1bHQyKSA9PiB7CiAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIHJlc3VsdDIpOwogICAgICAgIH0pOwogICAgICB9CiAgICAgIGNvbnN0IHJlc3VsdCA9IFsuLi5jdHguZGF0YV0ubWFwKChpdGVtLCBpMikgPT4gewogICAgICAgIHJldHVybiBkZWYudHlwZS5fcGFyc2VTeW5jKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCBpdGVtLCBjdHgucGF0aCwgaTIpKTsKICAgICAgfSk7CiAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZUFycmF5KHN0YXR1cywgcmVzdWx0KTsKICAgIH0KICAgIGdldCBlbGVtZW50KCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLnR5cGU7CiAgICB9CiAgICBtaW4obWluTGVuZ3RoLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQXJyYXkoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBtaW5MZW5ndGg6IHsgdmFsdWU6IG1pbkxlbmd0aCwgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpIH0KICAgICAgfSk7CiAgICB9CiAgICBtYXgobWF4TGVuZ3RoLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQXJyYXkoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBtYXhMZW5ndGg6IHsgdmFsdWU6IG1heExlbmd0aCwgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpIH0KICAgICAgfSk7CiAgICB9CiAgICBsZW5ndGgobGVuLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kQXJyYXkoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBleGFjdExlbmd0aDogeyB2YWx1ZTogbGVuLCBtZXNzYWdlOiBlcnJvclV0aWwudG9TdHJpbmcobWVzc2FnZSkgfQogICAgICB9KTsKICAgIH0KICAgIG5vbmVtcHR5KG1lc3NhZ2UpIHsKICAgICAgcmV0dXJuIHRoaXMubWluKDEsIG1lc3NhZ2UpOwogICAgfQogIH0KICBab2RBcnJheS5jcmVhdGUgPSAoc2NoZW1hLCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kQXJyYXkoewogICAgICB0eXBlOiBzY2hlbWEsCiAgICAgIG1pbkxlbmd0aDogbnVsbCwKICAgICAgbWF4TGVuZ3RoOiBudWxsLAogICAgICBleGFjdExlbmd0aDogbnVsbCwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RBcnJheSwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGZ1bmN0aW9uIGRlZXBQYXJ0aWFsaWZ5KHNjaGVtYSkgewogICAgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZE9iamVjdCkgewogICAgICBjb25zdCBuZXdTaGFwZSA9IHt9OwogICAgICBmb3IgKGNvbnN0IGtleSBpbiBzY2hlbWEuc2hhcGUpIHsKICAgICAgICBjb25zdCBmaWVsZFNjaGVtYSA9IHNjaGVtYS5zaGFwZVtrZXldOwogICAgICAgIG5ld1NoYXBlW2tleV0gPSBab2RPcHRpb25hbC5jcmVhdGUoZGVlcFBhcnRpYWxpZnkoZmllbGRTY2hlbWEpKTsKICAgICAgfQogICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgICAgLi4uc2NoZW1hLl9kZWYsCiAgICAgICAgc2hhcGU6ICgpID0+IG5ld1NoYXBlCiAgICAgIH0pOwogICAgfSBlbHNlIGlmIChzY2hlbWEgaW5zdGFuY2VvZiBab2RBcnJheSkgewogICAgICByZXR1cm4gbmV3IFpvZEFycmF5KHsKICAgICAgICAuLi5zY2hlbWEuX2RlZiwKICAgICAgICB0eXBlOiBkZWVwUGFydGlhbGlmeShzY2hlbWEuZWxlbWVudCkKICAgICAgfSk7CiAgICB9IGVsc2UgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZE9wdGlvbmFsKSB7CiAgICAgIHJldHVybiBab2RPcHRpb25hbC5jcmVhdGUoZGVlcFBhcnRpYWxpZnkoc2NoZW1hLnVud3JhcCgpKSk7CiAgICB9IGVsc2UgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZE51bGxhYmxlKSB7CiAgICAgIHJldHVybiBab2ROdWxsYWJsZS5jcmVhdGUoZGVlcFBhcnRpYWxpZnkoc2NoZW1hLnVud3JhcCgpKSk7CiAgICB9IGVsc2UgaWYgKHNjaGVtYSBpbnN0YW5jZW9mIFpvZFR1cGxlKSB7CiAgICAgIHJldHVybiBab2RUdXBsZS5jcmVhdGUoc2NoZW1hLml0ZW1zLm1hcCgoaXRlbSkgPT4gZGVlcFBhcnRpYWxpZnkoaXRlbSkpKTsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiBzY2hlbWE7CiAgICB9CiAgfQogIGNsYXNzIFpvZE9iamVjdCBleHRlbmRzIFpvZFR5cGUgewogICAgY29uc3RydWN0b3IoKSB7CiAgICAgIHN1cGVyKC4uLmFyZ3VtZW50cyk7CiAgICAgIHRoaXMuX2NhY2hlZCA9IG51bGw7CiAgICAgIHRoaXMubm9uc3RyaWN0ID0gdGhpcy5wYXNzdGhyb3VnaDsKICAgICAgdGhpcy5hdWdtZW50ID0gdGhpcy5leHRlbmQ7CiAgICB9CiAgICBfZ2V0Q2FjaGVkKCkgewogICAgICBpZiAodGhpcy5fY2FjaGVkICE9PSBudWxsKQogICAgICAgIHJldHVybiB0aGlzLl9jYWNoZWQ7CiAgICAgIGNvbnN0IHNoYXBlID0gdGhpcy5fZGVmLnNoYXBlKCk7CiAgICAgIGNvbnN0IGtleXMgPSB1dGlsLm9iamVjdEtleXMoc2hhcGUpOwogICAgICByZXR1cm4gdGhpcy5fY2FjaGVkID0geyBzaGFwZSwga2V5cyB9OwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHBhcnNlZFR5cGUgPSB0aGlzLl9nZXRUeXBlKGlucHV0KTsKICAgICAgaWYgKHBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUub2JqZWN0KSB7CiAgICAgICAgY29uc3QgY3R4MiA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgyLCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUub2JqZWN0LAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eDIucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IHsgc3RhdHVzLCBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7CiAgICAgIGNvbnN0IHsgc2hhcGUsIGtleXM6IHNoYXBlS2V5cyB9ID0gdGhpcy5fZ2V0Q2FjaGVkKCk7CiAgICAgIGNvbnN0IGV4dHJhS2V5cyA9IFtdOwogICAgICBpZiAoISh0aGlzLl9kZWYuY2F0Y2hhbGwgaW5zdGFuY2VvZiBab2ROZXZlciAmJiB0aGlzLl9kZWYudW5rbm93bktleXMgPT09ICJzdHJpcCIpKSB7CiAgICAgICAgZm9yIChjb25zdCBrZXkgaW4gY3R4LmRhdGEpIHsKICAgICAgICAgIGlmICghc2hhcGVLZXlzLmluY2x1ZGVzKGtleSkpIHsKICAgICAgICAgICAgZXh0cmFLZXlzLnB1c2goa2V5KTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgICAgY29uc3QgcGFpcnMgPSBbXTsKICAgICAgZm9yIChjb25zdCBrZXkgb2Ygc2hhcGVLZXlzKSB7CiAgICAgICAgY29uc3Qga2V5VmFsaWRhdG9yID0gc2hhcGVba2V5XTsKICAgICAgICBjb25zdCB2YWx1ZSA9IGN0eC5kYXRhW2tleV07CiAgICAgICAgcGFpcnMucHVzaCh7CiAgICAgICAgICBrZXk6IHsgc3RhdHVzOiAidmFsaWQiLCB2YWx1ZToga2V5IH0sCiAgICAgICAgICB2YWx1ZToga2V5VmFsaWRhdG9yLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgdmFsdWUsIGN0eC5wYXRoLCBrZXkpKSwKICAgICAgICAgIGFsd2F5c1NldDoga2V5IGluIGN0eC5kYXRhCiAgICAgICAgfSk7CiAgICAgIH0KICAgICAgaWYgKHRoaXMuX2RlZi5jYXRjaGFsbCBpbnN0YW5jZW9mIFpvZE5ldmVyKSB7CiAgICAgICAgY29uc3QgdW5rbm93bktleXMgPSB0aGlzLl9kZWYudW5rbm93bktleXM7CiAgICAgICAgaWYgKHVua25vd25LZXlzID09PSAicGFzc3Rocm91Z2giKSB7CiAgICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBleHRyYUtleXMpIHsKICAgICAgICAgICAgcGFpcnMucHVzaCh7CiAgICAgICAgICAgICAga2V5OiB7IHN0YXR1czogInZhbGlkIiwgdmFsdWU6IGtleSB9LAogICAgICAgICAgICAgIHZhbHVlOiB7IHN0YXR1czogInZhbGlkIiwgdmFsdWU6IGN0eC5kYXRhW2tleV0gfQogICAgICAgICAgICB9KTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKHVua25vd25LZXlzID09PSAic3RyaWN0IikgewogICAgICAgICAgaWYgKGV4dHJhS2V5cy5sZW5ndGggPiAwKSB7CiAgICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS51bnJlY29nbml6ZWRfa2V5cywKICAgICAgICAgICAgICBrZXlzOiBleHRyYUtleXMKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAodW5rbm93bktleXMgPT09ICJzdHJpcCIpIDsKICAgICAgICBlbHNlIHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW50ZXJuYWwgWm9kT2JqZWN0IGVycm9yOiBpbnZhbGlkIHVua25vd25LZXlzIHZhbHVlLmApOwogICAgICAgIH0KICAgICAgfSBlbHNlIHsKICAgICAgICBjb25zdCBjYXRjaGFsbCA9IHRoaXMuX2RlZi5jYXRjaGFsbDsKICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBleHRyYUtleXMpIHsKICAgICAgICAgIGNvbnN0IHZhbHVlID0gY3R4LmRhdGFba2V5XTsKICAgICAgICAgIHBhaXJzLnB1c2goewogICAgICAgICAgICBrZXk6IHsgc3RhdHVzOiAidmFsaWQiLCB2YWx1ZToga2V5IH0sCiAgICAgICAgICAgIHZhbHVlOiBjYXRjaGFsbC5fcGFyc2UoCiAgICAgICAgICAgICAgbmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIHZhbHVlLCBjdHgucGF0aCwga2V5KQogICAgICAgICAgICAgIC8vLCBjdHguY2hpbGQoa2V5KSwgdmFsdWUsIGdldFBhcnNlZFR5cGUodmFsdWUpCiAgICAgICAgICAgICksCiAgICAgICAgICAgIGFsd2F5c1NldDoga2V5IGluIGN0eC5kYXRhCiAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihhc3luYyAoKSA9PiB7CiAgICAgICAgICBjb25zdCBzeW5jUGFpcnMgPSBbXTsKICAgICAgICAgIGZvciAoY29uc3QgcGFpciBvZiBwYWlycykgewogICAgICAgICAgICBjb25zdCBrZXkgPSBhd2FpdCBwYWlyLmtleTsKICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBhd2FpdCBwYWlyLnZhbHVlOwogICAgICAgICAgICBzeW5jUGFpcnMucHVzaCh7CiAgICAgICAgICAgICAga2V5LAogICAgICAgICAgICAgIHZhbHVlLAogICAgICAgICAgICAgIGFsd2F5c1NldDogcGFpci5hbHdheXNTZXQKICAgICAgICAgICAgfSk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gc3luY1BhaXJzOwogICAgICAgIH0pLnRoZW4oKHN5bmNQYWlycykgPT4gewogICAgICAgICAgcmV0dXJuIFBhcnNlU3RhdHVzLm1lcmdlT2JqZWN0U3luYyhzdGF0dXMsIHN5bmNQYWlycyk7CiAgICAgICAgfSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIFBhcnNlU3RhdHVzLm1lcmdlT2JqZWN0U3luYyhzdGF0dXMsIHBhaXJzKTsKICAgICAgfQogICAgfQogICAgZ2V0IHNoYXBlKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLnNoYXBlKCk7CiAgICB9CiAgICBzdHJpY3QobWVzc2FnZSkgewogICAgICBlcnJvclV0aWwuZXJyVG9PYmo7CiAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgdW5rbm93bktleXM6ICJzdHJpY3QiLAogICAgICAgIC4uLm1lc3NhZ2UgIT09IHZvaWQgMCA/IHsKICAgICAgICAgIGVycm9yTWFwOiAoaXNzdWUsIGN0eCkgPT4gewogICAgICAgICAgICB2YXIgX2EsIF9iLCBfYywgX2Q7CiAgICAgICAgICAgIGNvbnN0IGRlZmF1bHRFcnJvciA9IChfYyA9IChfYiA9IChfYSA9IHRoaXMuX2RlZikuZXJyb3JNYXApID09PSBudWxsIHx8IF9iID09PSB2b2lkIDAgPyB2b2lkIDAgOiBfYi5jYWxsKF9hLCBpc3N1ZSwgY3R4KS5tZXNzYWdlKSAhPT0gbnVsbCAmJiBfYyAhPT0gdm9pZCAwID8gX2MgOiBjdHguZGVmYXVsdEVycm9yOwogICAgICAgICAgICBpZiAoaXNzdWUuY29kZSA9PT0gInVucmVjb2duaXplZF9rZXlzIikKICAgICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgICAgbWVzc2FnZTogKF9kID0gZXJyb3JVdGlsLmVyclRvT2JqKG1lc3NhZ2UpLm1lc3NhZ2UpICE9PSBudWxsICYmIF9kICE9PSB2b2lkIDAgPyBfZCA6IGRlZmF1bHRFcnJvcgogICAgICAgICAgICAgIH07CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgbWVzc2FnZTogZGVmYXVsdEVycm9yCiAgICAgICAgICAgIH07CiAgICAgICAgICB9CiAgICAgICAgfSA6IHt9CiAgICAgIH0pOwogICAgfQogICAgc3RyaXAoKSB7CiAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgdW5rbm93bktleXM6ICJzdHJpcCIKICAgICAgfSk7CiAgICB9CiAgICBwYXNzdGhyb3VnaCgpIHsKICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3QoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICB1bmtub3duS2V5czogInBhc3N0aHJvdWdoIgogICAgICB9KTsKICAgIH0KICAgIC8vIGNvbnN0IEF1Z21lbnRGYWN0b3J5ID0KICAgIC8vICAgPERlZiBleHRlbmRzIFpvZE9iamVjdERlZj4oZGVmOiBEZWYpID0+CiAgICAvLyAgIDxBdWdtZW50YXRpb24gZXh0ZW5kcyBab2RSYXdTaGFwZT4oCiAgICAvLyAgICAgYXVnbWVudGF0aW9uOiBBdWdtZW50YXRpb24KICAgIC8vICAgKTogWm9kT2JqZWN0PAogICAgLy8gICAgIGV4dGVuZFNoYXBlPFJldHVyblR5cGU8RGVmWyJzaGFwZSJdPiwgQXVnbWVudGF0aW9uPiwKICAgIC8vICAgICBEZWZbInVua25vd25LZXlzIl0sCiAgICAvLyAgICAgRGVmWyJjYXRjaGFsbCJdCiAgICAvLyAgID4gPT4gewogICAgLy8gICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgIC8vICAgICAgIC4uLmRlZiwKICAgIC8vICAgICAgIHNoYXBlOiAoKSA9PiAoewogICAgLy8gICAgICAgICAuLi5kZWYuc2hhcGUoKSwKICAgIC8vICAgICAgICAgLi4uYXVnbWVudGF0aW9uLAogICAgLy8gICAgICAgfSksCiAgICAvLyAgICAgfSkgYXMgYW55OwogICAgLy8gICB9OwogICAgZXh0ZW5kKGF1Z21lbnRhdGlvbikgewogICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIHNoYXBlOiAoKSA9PiAoewogICAgICAgICAgLi4udGhpcy5fZGVmLnNoYXBlKCksCiAgICAgICAgICAuLi5hdWdtZW50YXRpb24KICAgICAgICB9KQogICAgICB9KTsKICAgIH0KICAgIC8qKgogICAgICogUHJpb3IgdG8gem9kQDEuMC4xMiB0aGVyZSB3YXMgYSBidWcgaW4gdGhlCiAgICAgKiBpbmZlcnJlZCB0eXBlIG9mIG1lcmdlZCBvYmplY3RzLiBQbGVhc2UKICAgICAqIHVwZ3JhZGUgaWYgeW91IGFyZSBleHBlcmllbmNpbmcgaXNzdWVzLgogICAgICovCiAgICBtZXJnZShtZXJnaW5nKSB7CiAgICAgIGNvbnN0IG1lcmdlZCA9IG5ldyBab2RPYmplY3QoewogICAgICAgIHVua25vd25LZXlzOiBtZXJnaW5nLl9kZWYudW5rbm93bktleXMsCiAgICAgICAgY2F0Y2hhbGw6IG1lcmdpbmcuX2RlZi5jYXRjaGFsbCwKICAgICAgICBzaGFwZTogKCkgPT4gKHsKICAgICAgICAgIC4uLnRoaXMuX2RlZi5zaGFwZSgpLAogICAgICAgICAgLi4ubWVyZ2luZy5fZGVmLnNoYXBlKCkKICAgICAgICB9KSwKICAgICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9iamVjdAogICAgICB9KTsKICAgICAgcmV0dXJuIG1lcmdlZDsKICAgIH0KICAgIC8vIG1lcmdlPAogICAgLy8gICBJbmNvbWluZyBleHRlbmRzIEFueVpvZE9iamVjdCwKICAgIC8vICAgQXVnbWVudGF0aW9uIGV4dGVuZHMgSW5jb21pbmdbInNoYXBlIl0sCiAgICAvLyAgIE5ld091dHB1dCBleHRlbmRzIHsKICAgIC8vICAgICBbayBpbiBrZXlvZiBBdWdtZW50YXRpb24gfCBrZXlvZiBPdXRwdXRdOiBrIGV4dGVuZHMga2V5b2YgQXVnbWVudGF0aW9uCiAgICAvLyAgICAgICA/IEF1Z21lbnRhdGlvbltrXVsiX291dHB1dCJdCiAgICAvLyAgICAgICA6IGsgZXh0ZW5kcyBrZXlvZiBPdXRwdXQKICAgIC8vICAgICAgID8gT3V0cHV0W2tdCiAgICAvLyAgICAgICA6IG5ldmVyOwogICAgLy8gICB9LAogICAgLy8gICBOZXdJbnB1dCBleHRlbmRzIHsKICAgIC8vICAgICBbayBpbiBrZXlvZiBBdWdtZW50YXRpb24gfCBrZXlvZiBJbnB1dF06IGsgZXh0ZW5kcyBrZXlvZiBBdWdtZW50YXRpb24KICAgIC8vICAgICAgID8gQXVnbWVudGF0aW9uW2tdWyJfaW5wdXQiXQogICAgLy8gICAgICAgOiBrIGV4dGVuZHMga2V5b2YgSW5wdXQKICAgIC8vICAgICAgID8gSW5wdXRba10KICAgIC8vICAgICAgIDogbmV2ZXI7CiAgICAvLyAgIH0KICAgIC8vID4oCiAgICAvLyAgIG1lcmdpbmc6IEluY29taW5nCiAgICAvLyApOiBab2RPYmplY3Q8CiAgICAvLyAgIGV4dGVuZFNoYXBlPFQsIFJldHVyblR5cGU8SW5jb21pbmdbIl9kZWYiXVsic2hhcGUiXT4+LAogICAgLy8gICBJbmNvbWluZ1siX2RlZiJdWyJ1bmtub3duS2V5cyJdLAogICAgLy8gICBJbmNvbWluZ1siX2RlZiJdWyJjYXRjaGFsbCJdLAogICAgLy8gICBOZXdPdXRwdXQsCiAgICAvLyAgIE5ld0lucHV0CiAgICAvLyA+IHsKICAgIC8vICAgY29uc3QgbWVyZ2VkOiBhbnkgPSBuZXcgWm9kT2JqZWN0KHsKICAgIC8vICAgICB1bmtub3duS2V5czogbWVyZ2luZy5fZGVmLnVua25vd25LZXlzLAogICAgLy8gICAgIGNhdGNoYWxsOiBtZXJnaW5nLl9kZWYuY2F0Y2hhbGwsCiAgICAvLyAgICAgc2hhcGU6ICgpID0+CiAgICAvLyAgICAgICBvYmplY3RVdGlsLm1lcmdlU2hhcGVzKHRoaXMuX2RlZi5zaGFwZSgpLCBtZXJnaW5nLl9kZWYuc2hhcGUoKSksCiAgICAvLyAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPYmplY3QsCiAgICAvLyAgIH0pIGFzIGFueTsKICAgIC8vICAgcmV0dXJuIG1lcmdlZDsKICAgIC8vIH0KICAgIHNldEtleShrZXksIHNjaGVtYSkgewogICAgICByZXR1cm4gdGhpcy5hdWdtZW50KHsgW2tleV06IHNjaGVtYSB9KTsKICAgIH0KICAgIC8vIG1lcmdlPEluY29taW5nIGV4dGVuZHMgQW55Wm9kT2JqZWN0PigKICAgIC8vICAgbWVyZ2luZzogSW5jb21pbmcKICAgIC8vICk6IC8vWm9kT2JqZWN0PFQgJiBJbmNvbWluZ1siX3NoYXBlIl0sIFVua25vd25LZXlzLCBDYXRjaGFsbD4gPSAobWVyZ2luZykgPT4gewogICAgLy8gWm9kT2JqZWN0PAogICAgLy8gICBleHRlbmRTaGFwZTxULCBSZXR1cm5UeXBlPEluY29taW5nWyJfZGVmIl1bInNoYXBlIl0+PiwKICAgIC8vICAgSW5jb21pbmdbIl9kZWYiXVsidW5rbm93bktleXMiXSwKICAgIC8vICAgSW5jb21pbmdbIl9kZWYiXVsiY2F0Y2hhbGwiXQogICAgLy8gPiB7CiAgICAvLyAgIC8vIGNvbnN0IG1lcmdlZFNoYXBlID0gb2JqZWN0VXRpbC5tZXJnZVNoYXBlcygKICAgIC8vICAgLy8gICB0aGlzLl9kZWYuc2hhcGUoKSwKICAgIC8vICAgLy8gICBtZXJnaW5nLl9kZWYuc2hhcGUoKQogICAgLy8gICAvLyApOwogICAgLy8gICBjb25zdCBtZXJnZWQ6IGFueSA9IG5ldyBab2RPYmplY3QoewogICAgLy8gICAgIHVua25vd25LZXlzOiBtZXJnaW5nLl9kZWYudW5rbm93bktleXMsCiAgICAvLyAgICAgY2F0Y2hhbGw6IG1lcmdpbmcuX2RlZi5jYXRjaGFsbCwKICAgIC8vICAgICBzaGFwZTogKCkgPT4KICAgIC8vICAgICAgIG9iamVjdFV0aWwubWVyZ2VTaGFwZXModGhpcy5fZGVmLnNoYXBlKCksIG1lcmdpbmcuX2RlZi5zaGFwZSgpKSwKICAgIC8vICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE9iamVjdCwKICAgIC8vICAgfSkgYXMgYW55OwogICAgLy8gICByZXR1cm4gbWVyZ2VkOwogICAgLy8gfQogICAgY2F0Y2hhbGwoaW5kZXgpIHsKICAgICAgcmV0dXJuIG5ldyBab2RPYmplY3QoewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICBjYXRjaGFsbDogaW5kZXgKICAgICAgfSk7CiAgICB9CiAgICBwaWNrKG1hc2spIHsKICAgICAgY29uc3Qgc2hhcGUgPSB7fTsKICAgICAgdXRpbC5vYmplY3RLZXlzKG1hc2spLmZvckVhY2goKGtleSkgPT4gewogICAgICAgIGlmIChtYXNrW2tleV0gJiYgdGhpcy5zaGFwZVtrZXldKSB7CiAgICAgICAgICBzaGFwZVtrZXldID0gdGhpcy5zaGFwZVtrZXldOwogICAgICAgIH0KICAgICAgfSk7CiAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgc2hhcGU6ICgpID0+IHNoYXBlCiAgICAgIH0pOwogICAgfQogICAgb21pdChtYXNrKSB7CiAgICAgIGNvbnN0IHNoYXBlID0ge307CiAgICAgIHV0aWwub2JqZWN0S2V5cyh0aGlzLnNoYXBlKS5mb3JFYWNoKChrZXkpID0+IHsKICAgICAgICBpZiAoIW1hc2tba2V5XSkgewogICAgICAgICAgc2hhcGVba2V5XSA9IHRoaXMuc2hhcGVba2V5XTsKICAgICAgICB9CiAgICAgIH0pOwogICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIHNoYXBlOiAoKSA9PiBzaGFwZQogICAgICB9KTsKICAgIH0KICAgIC8qKgogICAgICogQGRlcHJlY2F0ZWQKICAgICAqLwogICAgZGVlcFBhcnRpYWwoKSB7CiAgICAgIHJldHVybiBkZWVwUGFydGlhbGlmeSh0aGlzKTsKICAgIH0KICAgIHBhcnRpYWwobWFzaykgewogICAgICBjb25zdCBuZXdTaGFwZSA9IHt9OwogICAgICB1dGlsLm9iamVjdEtleXModGhpcy5zaGFwZSkuZm9yRWFjaCgoa2V5KSA9PiB7CiAgICAgICAgY29uc3QgZmllbGRTY2hlbWEgPSB0aGlzLnNoYXBlW2tleV07CiAgICAgICAgaWYgKG1hc2sgJiYgIW1hc2tba2V5XSkgewogICAgICAgICAgbmV3U2hhcGVba2V5XSA9IGZpZWxkU2NoZW1hOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBuZXdTaGFwZVtrZXldID0gZmllbGRTY2hlbWEub3B0aW9uYWwoKTsKICAgICAgICB9CiAgICAgIH0pOwogICAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIHNoYXBlOiAoKSA9PiBuZXdTaGFwZQogICAgICB9KTsKICAgIH0KICAgIHJlcXVpcmVkKG1hc2spIHsKICAgICAgY29uc3QgbmV3U2hhcGUgPSB7fTsKICAgICAgdXRpbC5vYmplY3RLZXlzKHRoaXMuc2hhcGUpLmZvckVhY2goKGtleSkgPT4gewogICAgICAgIGlmIChtYXNrICYmICFtYXNrW2tleV0pIHsKICAgICAgICAgIG5ld1NoYXBlW2tleV0gPSB0aGlzLnNoYXBlW2tleV07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGNvbnN0IGZpZWxkU2NoZW1hID0gdGhpcy5zaGFwZVtrZXldOwogICAgICAgICAgbGV0IG5ld0ZpZWxkID0gZmllbGRTY2hlbWE7CiAgICAgICAgICB3aGlsZSAobmV3RmllbGQgaW5zdGFuY2VvZiBab2RPcHRpb25hbCkgewogICAgICAgICAgICBuZXdGaWVsZCA9IG5ld0ZpZWxkLl9kZWYuaW5uZXJUeXBlOwogICAgICAgICAgfQogICAgICAgICAgbmV3U2hhcGVba2V5XSA9IG5ld0ZpZWxkOwogICAgICAgIH0KICAgICAgfSk7CiAgICAgIHJldHVybiBuZXcgWm9kT2JqZWN0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgc2hhcGU6ICgpID0+IG5ld1NoYXBlCiAgICAgIH0pOwogICAgfQogICAga2V5b2YoKSB7CiAgICAgIHJldHVybiBjcmVhdGVab2RFbnVtKHV0aWwub2JqZWN0S2V5cyh0aGlzLnNoYXBlKSk7CiAgICB9CiAgfQogIFpvZE9iamVjdC5jcmVhdGUgPSAoc2hhcGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RPYmplY3QoewogICAgICBzaGFwZTogKCkgPT4gc2hhcGUsCiAgICAgIHVua25vd25LZXlzOiAic3RyaXAiLAogICAgICBjYXRjaGFsbDogWm9kTmV2ZXIuY3JlYXRlKCksCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT2JqZWN0LAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgWm9kT2JqZWN0LnN0cmljdENyZWF0ZSA9IChzaGFwZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE9iamVjdCh7CiAgICAgIHNoYXBlOiAoKSA9PiBzaGFwZSwKICAgICAgdW5rbm93bktleXM6ICJzdHJpY3QiLAogICAgICBjYXRjaGFsbDogWm9kTmV2ZXIuY3JlYXRlKCksCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kT2JqZWN0LAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgWm9kT2JqZWN0LmxhenljcmVhdGUgPSAoc2hhcGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RPYmplY3QoewogICAgICBzaGFwZSwKICAgICAgdW5rbm93bktleXM6ICJzdHJpcCIsCiAgICAgIGNhdGNoYWxsOiBab2ROZXZlci5jcmVhdGUoKSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPYmplY3QsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RVbmlvbiBleHRlbmRzIFpvZFR5cGUgewogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5fZGVmLm9wdGlvbnM7CiAgICAgIGZ1bmN0aW9uIGhhbmRsZVJlc3VsdHMocmVzdWx0cykgewogICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHMpIHsKICAgICAgICAgIGlmIChyZXN1bHQucmVzdWx0LnN0YXR1cyA9PT0gInZhbGlkIikgewogICAgICAgICAgICByZXR1cm4gcmVzdWx0LnJlc3VsdDsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZm9yIChjb25zdCByZXN1bHQgb2YgcmVzdWx0cykgewogICAgICAgICAgaWYgKHJlc3VsdC5yZXN1bHQuc3RhdHVzID09PSAiZGlydHkiKSB7CiAgICAgICAgICAgIGN0eC5jb21tb24uaXNzdWVzLnB1c2goLi4ucmVzdWx0LmN0eC5jb21tb24uaXNzdWVzKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5yZXN1bHQ7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGNvbnN0IHVuaW9uRXJyb3JzID0gcmVzdWx0cy5tYXAoKHJlc3VsdCkgPT4gbmV3IFpvZEVycm9yKHJlc3VsdC5jdHguY29tbW9uLmlzc3VlcykpOwogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdW5pb24sCiAgICAgICAgICB1bmlvbkVycm9ycwogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKG9wdGlvbnMubWFwKGFzeW5jIChvcHRpb24pID0+IHsKICAgICAgICAgIGNvbnN0IGNoaWxkQ3R4ID0gewogICAgICAgICAgICAuLi5jdHgsCiAgICAgICAgICAgIGNvbW1vbjogewogICAgICAgICAgICAgIC4uLmN0eC5jb21tb24sCiAgICAgICAgICAgICAgaXNzdWVzOiBbXQogICAgICAgICAgICB9LAogICAgICAgICAgICBwYXJlbnQ6IG51bGwKICAgICAgICAgIH07CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICByZXN1bHQ6IGF3YWl0IG9wdGlvbi5fcGFyc2VBc3luYyh7CiAgICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgICAgICAgICAgcGFyZW50OiBjaGlsZEN0eAogICAgICAgICAgICB9KSwKICAgICAgICAgICAgY3R4OiBjaGlsZEN0eAogICAgICAgICAgfTsKICAgICAgICB9KSkudGhlbihoYW5kbGVSZXN1bHRzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBsZXQgZGlydHkgPSB2b2lkIDA7CiAgICAgICAgY29uc3QgaXNzdWVzID0gW107CiAgICAgICAgZm9yIChjb25zdCBvcHRpb24gb2Ygb3B0aW9ucykgewogICAgICAgICAgY29uc3QgY2hpbGRDdHggPSB7CiAgICAgICAgICAgIC4uLmN0eCwKICAgICAgICAgICAgY29tbW9uOiB7CiAgICAgICAgICAgICAgLi4uY3R4LmNvbW1vbiwKICAgICAgICAgICAgICBpc3N1ZXM6IFtdCiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIHBhcmVudDogbnVsbAogICAgICAgICAgfTsKICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IG9wdGlvbi5fcGFyc2VTeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGNoaWxkQ3R4CiAgICAgICAgICB9KTsKICAgICAgICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSAidmFsaWQiKSB7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdC5zdGF0dXMgPT09ICJkaXJ0eSIgJiYgIWRpcnR5KSB7CiAgICAgICAgICAgIGRpcnR5ID0geyByZXN1bHQsIGN0eDogY2hpbGRDdHggfTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChjaGlsZEN0eC5jb21tb24uaXNzdWVzLmxlbmd0aCkgewogICAgICAgICAgICBpc3N1ZXMucHVzaChjaGlsZEN0eC5jb21tb24uaXNzdWVzKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGRpcnR5KSB7CiAgICAgICAgICBjdHguY29tbW9uLmlzc3Vlcy5wdXNoKC4uLmRpcnR5LmN0eC5jb21tb24uaXNzdWVzKTsKICAgICAgICAgIHJldHVybiBkaXJ0eS5yZXN1bHQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHVuaW9uRXJyb3JzID0gaXNzdWVzLm1hcCgoaXNzdWVzMikgPT4gbmV3IFpvZEVycm9yKGlzc3VlczIpKTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3VuaW9uLAogICAgICAgICAgdW5pb25FcnJvcnMKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgfQogICAgZ2V0IG9wdGlvbnMoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYub3B0aW9uczsKICAgIH0KICB9CiAgWm9kVW5pb24uY3JlYXRlID0gKHR5cGVzLCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kVW5pb24oewogICAgICBvcHRpb25zOiB0eXBlcywKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RVbmlvbiwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNvbnN0IGdldERpc2NyaW1pbmF0b3IgPSAodHlwZSkgPT4gewogICAgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RMYXp5KSB7CiAgICAgIHJldHVybiBnZXREaXNjcmltaW5hdG9yKHR5cGUuc2NoZW1hKTsKICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZEVmZmVjdHMpIHsKICAgICAgcmV0dXJuIGdldERpc2NyaW1pbmF0b3IodHlwZS5pbm5lclR5cGUoKSk7CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RMaXRlcmFsKSB7CiAgICAgIHJldHVybiBbdHlwZS52YWx1ZV07CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RFbnVtKSB7CiAgICAgIHJldHVybiB0eXBlLm9wdGlvbnM7CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2ROYXRpdmVFbnVtKSB7CiAgICAgIHJldHVybiB1dGlsLm9iamVjdFZhbHVlcyh0eXBlLmVudW0pOwogICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kRGVmYXVsdCkgewogICAgICByZXR1cm4gZ2V0RGlzY3JpbWluYXRvcih0eXBlLl9kZWYuaW5uZXJUeXBlKTsKICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZFVuZGVmaW5lZCkgewogICAgICByZXR1cm4gW3ZvaWQgMF07CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2ROdWxsKSB7CiAgICAgIHJldHVybiBbbnVsbF07CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2RPcHRpb25hbCkgewogICAgICByZXR1cm4gW3ZvaWQgMCwgLi4uZ2V0RGlzY3JpbWluYXRvcih0eXBlLnVud3JhcCgpKV07CiAgICB9IGVsc2UgaWYgKHR5cGUgaW5zdGFuY2VvZiBab2ROdWxsYWJsZSkgewogICAgICByZXR1cm4gW251bGwsIC4uLmdldERpc2NyaW1pbmF0b3IodHlwZS51bndyYXAoKSldOwogICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kQnJhbmRlZCkgewogICAgICByZXR1cm4gZ2V0RGlzY3JpbWluYXRvcih0eXBlLnVud3JhcCgpKTsKICAgIH0gZWxzZSBpZiAodHlwZSBpbnN0YW5jZW9mIFpvZFJlYWRvbmx5KSB7CiAgICAgIHJldHVybiBnZXREaXNjcmltaW5hdG9yKHR5cGUudW53cmFwKCkpOwogICAgfSBlbHNlIGlmICh0eXBlIGluc3RhbmNlb2YgWm9kQ2F0Y2gpIHsKICAgICAgcmV0dXJuIGdldERpc2NyaW1pbmF0b3IodHlwZS5fZGVmLmlubmVyVHlwZSk7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gW107CiAgICB9CiAgfTsKICBjbGFzcyBab2REaXNjcmltaW5hdGVkVW5pb24gZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm9iamVjdCkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm9iamVjdCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IGRpc2NyaW1pbmF0b3IgPSB0aGlzLmRpc2NyaW1pbmF0b3I7CiAgICAgIGNvbnN0IGRpc2NyaW1pbmF0b3JWYWx1ZSA9IGN0eC5kYXRhW2Rpc2NyaW1pbmF0b3JdOwogICAgICBjb25zdCBvcHRpb24gPSB0aGlzLm9wdGlvbnNNYXAuZ2V0KGRpc2NyaW1pbmF0b3JWYWx1ZSk7CiAgICAgIGlmICghb3B0aW9uKSB7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF91bmlvbl9kaXNjcmltaW5hdG9yLAogICAgICAgICAgb3B0aW9uczogQXJyYXkuZnJvbSh0aGlzLm9wdGlvbnNNYXAua2V5cygpKSwKICAgICAgICAgIHBhdGg6IFtkaXNjcmltaW5hdG9yXQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgcmV0dXJuIG9wdGlvbi5fcGFyc2VBc3luYyh7CiAgICAgICAgICBkYXRhOiBjdHguZGF0YSwKICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgcGFyZW50OiBjdHgKICAgICAgICB9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gb3B0aW9uLl9wYXJzZVN5bmMoewogICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgIHBhcmVudDogY3R4CiAgICAgICAgfSk7CiAgICAgIH0KICAgIH0KICAgIGdldCBkaXNjcmltaW5hdG9yKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmRpc2NyaW1pbmF0b3I7CiAgICB9CiAgICBnZXQgb3B0aW9ucygpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5vcHRpb25zOwogICAgfQogICAgZ2V0IG9wdGlvbnNNYXAoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYub3B0aW9uc01hcDsKICAgIH0KICAgIC8qKgogICAgICogVGhlIGNvbnN0cnVjdG9yIG9mIHRoZSBkaXNjcmltaW5hdGVkIHVuaW9uIHNjaGVtYS4gSXRzIGJlaGF2aW91ciBpcyB2ZXJ5IHNpbWlsYXIgdG8gdGhhdCBvZiB0aGUgbm9ybWFsIHoudW5pb24oKSBjb25zdHJ1Y3Rvci4KICAgICAqIEhvd2V2ZXIsIGl0IG9ubHkgYWxsb3dzIGEgdW5pb24gb2Ygb2JqZWN0cywgYWxsIG9mIHdoaWNoIG5lZWQgdG8gc2hhcmUgYSBkaXNjcmltaW5hdG9yIHByb3BlcnR5LiBUaGlzIHByb3BlcnR5IG11c3QKICAgICAqIGhhdmUgYSBkaWZmZXJlbnQgdmFsdWUgZm9yIGVhY2ggb2JqZWN0IGluIHRoZSB1bmlvbi4KICAgICAqIEBwYXJhbSBkaXNjcmltaW5hdG9yIHRoZSBuYW1lIG9mIHRoZSBkaXNjcmltaW5hdG9yIHByb3BlcnR5CiAgICAgKiBAcGFyYW0gdHlwZXMgYW4gYXJyYXkgb2Ygb2JqZWN0IHNjaGVtYXMKICAgICAqIEBwYXJhbSBwYXJhbXMKICAgICAqLwogICAgc3RhdGljIGNyZWF0ZShkaXNjcmltaW5hdG9yLCBvcHRpb25zLCBwYXJhbXMpIHsKICAgICAgY29uc3Qgb3B0aW9uc01hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgIGZvciAoY29uc3QgdHlwZSBvZiBvcHRpb25zKSB7CiAgICAgICAgY29uc3QgZGlzY3JpbWluYXRvclZhbHVlcyA9IGdldERpc2NyaW1pbmF0b3IodHlwZS5zaGFwZVtkaXNjcmltaW5hdG9yXSk7CiAgICAgICAgaWYgKCFkaXNjcmltaW5hdG9yVmFsdWVzLmxlbmd0aCkgewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBBIGRpc2NyaW1pbmF0b3IgdmFsdWUgZm9yIGtleSBcYCR7ZGlzY3JpbWluYXRvcn1cYCBjb3VsZCBub3QgYmUgZXh0cmFjdGVkIGZyb20gYWxsIHNjaGVtYSBvcHRpb25zYCk7CiAgICAgICAgfQogICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgZGlzY3JpbWluYXRvclZhbHVlcykgewogICAgICAgICAgaWYgKG9wdGlvbnNNYXAuaGFzKHZhbHVlKSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYERpc2NyaW1pbmF0b3IgcHJvcGVydHkgJHtTdHJpbmcoZGlzY3JpbWluYXRvcil9IGhhcyBkdXBsaWNhdGUgdmFsdWUgJHtTdHJpbmcodmFsdWUpfWApOwogICAgICAgICAgfQogICAgICAgICAgb3B0aW9uc01hcC5zZXQodmFsdWUsIHR5cGUpOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gbmV3IFpvZERpc2NyaW1pbmF0ZWRVbmlvbih7CiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2REaXNjcmltaW5hdGVkVW5pb24sCiAgICAgICAgZGlzY3JpbWluYXRvciwKICAgICAgICBvcHRpb25zLAogICAgICAgIG9wdGlvbnNNYXAsCiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICAgIH0pOwogICAgfQogIH0KICBmdW5jdGlvbiBtZXJnZVZhbHVlcyhhMiwgYikgewogICAgY29uc3QgYVR5cGUgPSBnZXRQYXJzZWRUeXBlKGEyKTsKICAgIGNvbnN0IGJUeXBlID0gZ2V0UGFyc2VkVHlwZShiKTsKICAgIGlmIChhMiA9PT0gYikgewogICAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgZGF0YTogYTIgfTsKICAgIH0gZWxzZSBpZiAoYVR5cGUgPT09IFpvZFBhcnNlZFR5cGUub2JqZWN0ICYmIGJUeXBlID09PSBab2RQYXJzZWRUeXBlLm9iamVjdCkgewogICAgICBjb25zdCBiS2V5cyA9IHV0aWwub2JqZWN0S2V5cyhiKTsKICAgICAgY29uc3Qgc2hhcmVkS2V5cyA9IHV0aWwub2JqZWN0S2V5cyhhMikuZmlsdGVyKChrZXkpID0+IGJLZXlzLmluZGV4T2Yoa2V5KSAhPT0gLTEpOwogICAgICBjb25zdCBuZXdPYmogPSB7IC4uLmEyLCAuLi5iIH07CiAgICAgIGZvciAoY29uc3Qga2V5IG9mIHNoYXJlZEtleXMpIHsKICAgICAgICBjb25zdCBzaGFyZWRWYWx1ZSA9IG1lcmdlVmFsdWVzKGEyW2tleV0sIGJba2V5XSk7CiAgICAgICAgaWYgKCFzaGFyZWRWYWx1ZS52YWxpZCkgewogICAgICAgICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlIH07CiAgICAgICAgfQogICAgICAgIG5ld09ialtrZXldID0gc2hhcmVkVmFsdWUuZGF0YTsKICAgICAgfQogICAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgZGF0YTogbmV3T2JqIH07CiAgICB9IGVsc2UgaWYgKGFUeXBlID09PSBab2RQYXJzZWRUeXBlLmFycmF5ICYmIGJUeXBlID09PSBab2RQYXJzZWRUeXBlLmFycmF5KSB7CiAgICAgIGlmIChhMi5sZW5ndGggIT09IGIubGVuZ3RoKSB7CiAgICAgICAgcmV0dXJuIHsgdmFsaWQ6IGZhbHNlIH07CiAgICAgIH0KICAgICAgY29uc3QgbmV3QXJyYXkgPSBbXTsKICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGEyLmxlbmd0aDsgaW5kZXgrKykgewogICAgICAgIGNvbnN0IGl0ZW1BID0gYTJbaW5kZXhdOwogICAgICAgIGNvbnN0IGl0ZW1CID0gYltpbmRleF07CiAgICAgICAgY29uc3Qgc2hhcmVkVmFsdWUgPSBtZXJnZVZhbHVlcyhpdGVtQSwgaXRlbUIpOwogICAgICAgIGlmICghc2hhcmVkVmFsdWUudmFsaWQpIHsKICAgICAgICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSB9OwogICAgICAgIH0KICAgICAgICBuZXdBcnJheS5wdXNoKHNoYXJlZFZhbHVlLmRhdGEpOwogICAgICB9CiAgICAgIHJldHVybiB7IHZhbGlkOiB0cnVlLCBkYXRhOiBuZXdBcnJheSB9OwogICAgfSBlbHNlIGlmIChhVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5kYXRlICYmIGJUeXBlID09PSBab2RQYXJzZWRUeXBlLmRhdGUgJiYgK2EyID09PSArYikgewogICAgICByZXR1cm4geyB2YWxpZDogdHJ1ZSwgZGF0YTogYTIgfTsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiB7IHZhbGlkOiBmYWxzZSB9OwogICAgfQogIH0KICBjbGFzcyBab2RJbnRlcnNlY3Rpb24gZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBjb25zdCBoYW5kbGVQYXJzZWQgPSAocGFyc2VkTGVmdCwgcGFyc2VkUmlnaHQpID0+IHsKICAgICAgICBpZiAoaXNBYm9ydGVkKHBhcnNlZExlZnQpIHx8IGlzQWJvcnRlZChwYXJzZWRSaWdodCkpIHsKICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgIH0KICAgICAgICBjb25zdCBtZXJnZWQgPSBtZXJnZVZhbHVlcyhwYXJzZWRMZWZ0LnZhbHVlLCBwYXJzZWRSaWdodC52YWx1ZSk7CiAgICAgICAgaWYgKCFtZXJnZWQudmFsaWQpIHsKICAgICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9pbnRlcnNlY3Rpb25fdHlwZXMKICAgICAgICAgIH0pOwogICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgfQogICAgICAgIGlmIChpc0RpcnR5KHBhcnNlZExlZnQpIHx8IGlzRGlydHkocGFyc2VkUmlnaHQpKSB7CiAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBtZXJnZWQuZGF0YSB9OwogICAgICB9OwogICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykgewogICAgICAgIHJldHVybiBQcm9taXNlLmFsbChbCiAgICAgICAgICB0aGlzLl9kZWYubGVmdC5fcGFyc2VBc3luYyh7CiAgICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLAogICAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgICAgcGFyZW50OiBjdHgKICAgICAgICAgIH0pLAogICAgICAgICAgdGhpcy5fZGVmLnJpZ2h0Ll9wYXJzZUFzeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgfSkKICAgICAgICBdKS50aGVuKChbbGVmdCwgcmlnaHRdKSA9PiBoYW5kbGVQYXJzZWQobGVmdCwgcmlnaHQpKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gaGFuZGxlUGFyc2VkKHRoaXMuX2RlZi5sZWZ0Ll9wYXJzZVN5bmMoewogICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgIHBhcmVudDogY3R4CiAgICAgICAgfSksIHRoaXMuX2RlZi5yaWdodC5fcGFyc2VTeW5jKHsKICAgICAgICAgIGRhdGE6IGN0eC5kYXRhLAogICAgICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgIH0pKTsKICAgICAgfQogICAgfQogIH0KICBab2RJbnRlcnNlY3Rpb24uY3JlYXRlID0gKGxlZnQsIHJpZ2h0LCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kSW50ZXJzZWN0aW9uKHsKICAgICAgbGVmdCwKICAgICAgcmlnaHQsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kSW50ZXJzZWN0aW9uLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kVHVwbGUgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuYXJyYXkpIHsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsCiAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5hcnJheSwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmIChjdHguZGF0YS5sZW5ndGggPCB0aGlzLl9kZWYuaXRlbXMubGVuZ3RoKSB7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX3NtYWxsLAogICAgICAgICAgbWluaW11bTogdGhpcy5fZGVmLml0ZW1zLmxlbmd0aCwKICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgIHR5cGU6ICJhcnJheSIKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICBjb25zdCByZXN0ID0gdGhpcy5fZGVmLnJlc3Q7CiAgICAgIGlmICghcmVzdCAmJiBjdHguZGF0YS5sZW5ndGggPiB0aGlzLl9kZWYuaXRlbXMubGVuZ3RoKSB7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUudG9vX2JpZywKICAgICAgICAgIG1heGltdW06IHRoaXMuX2RlZi5pdGVtcy5sZW5ndGgsCiAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgICBleGFjdDogZmFsc2UsCiAgICAgICAgICB0eXBlOiAiYXJyYXkiCiAgICAgICAgfSk7CiAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgIH0KICAgICAgY29uc3QgaXRlbXMgPSBbLi4uY3R4LmRhdGFdLm1hcCgoaXRlbSwgaXRlbUluZGV4KSA9PiB7CiAgICAgICAgY29uc3Qgc2NoZW1hID0gdGhpcy5fZGVmLml0ZW1zW2l0ZW1JbmRleF0gfHwgdGhpcy5fZGVmLnJlc3Q7CiAgICAgICAgaWYgKCFzY2hlbWEpCiAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICByZXR1cm4gc2NoZW1hLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwgaXRlbSwgY3R4LnBhdGgsIGl0ZW1JbmRleCkpOwogICAgICB9KS5maWx0ZXIoKHgpID0+ICEheCk7CiAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKGl0ZW1zKS50aGVuKChyZXN1bHRzKSA9PiB7CiAgICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VBcnJheShzdGF0dXMsIHJlc3VsdHMpOwogICAgICAgIH0pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBQYXJzZVN0YXR1cy5tZXJnZUFycmF5KHN0YXR1cywgaXRlbXMpOwogICAgICB9CiAgICB9CiAgICBnZXQgaXRlbXMoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYuaXRlbXM7CiAgICB9CiAgICByZXN0KHJlc3QpIHsKICAgICAgcmV0dXJuIG5ldyBab2RUdXBsZSh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIHJlc3QKICAgICAgfSk7CiAgICB9CiAgfQogIFpvZFR1cGxlLmNyZWF0ZSA9IChzY2hlbWFzLCBwYXJhbXMpID0+IHsKICAgIGlmICghQXJyYXkuaXNBcnJheShzY2hlbWFzKSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoIllvdSBtdXN0IHBhc3MgYW4gYXJyYXkgb2Ygc2NoZW1hcyB0byB6LnR1cGxlKFsgLi4uIF0pIik7CiAgICB9CiAgICByZXR1cm4gbmV3IFpvZFR1cGxlKHsKICAgICAgaXRlbXM6IHNjaGVtYXMsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kVHVwbGUsCiAgICAgIHJlc3Q6IG51bGwsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RSZWNvcmQgZXh0ZW5kcyBab2RUeXBlIHsKICAgIGdldCBrZXlTY2hlbWEoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYua2V5VHlwZTsKICAgIH0KICAgIGdldCB2YWx1ZVNjaGVtYSgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZVR5cGU7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm9iamVjdCkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm9iamVjdCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IHBhaXJzID0gW107CiAgICAgIGNvbnN0IGtleVR5cGUgPSB0aGlzLl9kZWYua2V5VHlwZTsKICAgICAgY29uc3QgdmFsdWVUeXBlID0gdGhpcy5fZGVmLnZhbHVlVHlwZTsKICAgICAgZm9yIChjb25zdCBrZXkgaW4gY3R4LmRhdGEpIHsKICAgICAgICBwYWlycy5wdXNoKHsKICAgICAgICAgIGtleToga2V5VHlwZS5fcGFyc2UobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGtleSwgY3R4LnBhdGgsIGtleSkpLAogICAgICAgICAgdmFsdWU6IHZhbHVlVHlwZS5fcGFyc2UobmV3IFBhcnNlSW5wdXRMYXp5UGF0aChjdHgsIGN0eC5kYXRhW2tleV0sIGN0eC5wYXRoLCBrZXkpKSwKICAgICAgICAgIGFsd2F5c1NldDoga2V5IGluIGN0eC5kYXRhCiAgICAgICAgfSk7CiAgICAgIH0KICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHsKICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VPYmplY3RBc3luYyhzdGF0dXMsIHBhaXJzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gUGFyc2VTdGF0dXMubWVyZ2VPYmplY3RTeW5jKHN0YXR1cywgcGFpcnMpOwogICAgICB9CiAgICB9CiAgICBnZXQgZWxlbWVudCgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZVR5cGU7CiAgICB9CiAgICBzdGF0aWMgY3JlYXRlKGZpcnN0LCBzZWNvbmQsIHRoaXJkKSB7CiAgICAgIGlmIChzZWNvbmQgaW5zdGFuY2VvZiBab2RUeXBlKSB7CiAgICAgICAgcmV0dXJuIG5ldyBab2RSZWNvcmQoewogICAgICAgICAga2V5VHlwZTogZmlyc3QsCiAgICAgICAgICB2YWx1ZVR5cGU6IHNlY29uZCwKICAgICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kUmVjb3JkLAogICAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyh0aGlyZCkKICAgICAgICB9KTsKICAgICAgfQogICAgICByZXR1cm4gbmV3IFpvZFJlY29yZCh7CiAgICAgICAga2V5VHlwZTogWm9kU3RyaW5nLmNyZWF0ZSgpLAogICAgICAgIHZhbHVlVHlwZTogZmlyc3QsCiAgICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RSZWNvcmQsCiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhzZWNvbmQpCiAgICAgIH0pOwogICAgfQogIH0KICBjbGFzcyBab2RNYXAgZXh0ZW5kcyBab2RUeXBlIHsKICAgIGdldCBrZXlTY2hlbWEoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYua2V5VHlwZTsKICAgIH0KICAgIGdldCB2YWx1ZVNjaGVtYSgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZVR5cGU7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgaWYgKGN0eC5wYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm1hcCkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLm1hcCwKICAgICAgICAgIHJlY2VpdmVkOiBjdHgucGFyc2VkVHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGNvbnN0IGtleVR5cGUgPSB0aGlzLl9kZWYua2V5VHlwZTsKICAgICAgY29uc3QgdmFsdWVUeXBlID0gdGhpcy5fZGVmLnZhbHVlVHlwZTsKICAgICAgY29uc3QgcGFpcnMgPSBbLi4uY3R4LmRhdGEuZW50cmllcygpXS5tYXAoKFtrZXksIHZhbHVlXSwgaW5kZXgpID0+IHsKICAgICAgICByZXR1cm4gewogICAgICAgICAga2V5OiBrZXlUeXBlLl9wYXJzZShuZXcgUGFyc2VJbnB1dExhenlQYXRoKGN0eCwga2V5LCBjdHgucGF0aCwgW2luZGV4LCAia2V5Il0pKSwKICAgICAgICAgIHZhbHVlOiB2YWx1ZVR5cGUuX3BhcnNlKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCB2YWx1ZSwgY3R4LnBhdGgsIFtpbmRleCwgInZhbHVlIl0pKQogICAgICAgIH07CiAgICAgIH0pOwogICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykgewogICAgICAgIGNvbnN0IGZpbmFsTWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCkudGhlbihhc3luYyAoKSA9PiB7CiAgICAgICAgICBmb3IgKGNvbnN0IHBhaXIgb2YgcGFpcnMpIHsKICAgICAgICAgICAgY29uc3Qga2V5ID0gYXdhaXQgcGFpci5rZXk7CiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gYXdhaXQgcGFpci52YWx1ZTsKICAgICAgICAgICAgaWYgKGtleS5zdGF0dXMgPT09ICJhYm9ydGVkIiB8fCB2YWx1ZS5zdGF0dXMgPT09ICJhYm9ydGVkIikgewogICAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSAiZGlydHkiIHx8IHZhbHVlLnN0YXR1cyA9PT0gImRpcnR5IikgewogICAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZpbmFsTWFwLnNldChrZXkudmFsdWUsIHZhbHVlLnZhbHVlKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB7IHN0YXR1czogc3RhdHVzLnZhbHVlLCB2YWx1ZTogZmluYWxNYXAgfTsKICAgICAgICB9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb25zdCBmaW5hbE1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgICAgZm9yIChjb25zdCBwYWlyIG9mIHBhaXJzKSB7CiAgICAgICAgICBjb25zdCBrZXkgPSBwYWlyLmtleTsKICAgICAgICAgIGNvbnN0IHZhbHVlID0gcGFpci52YWx1ZTsKICAgICAgICAgIGlmIChrZXkuc3RhdHVzID09PSAiYWJvcnRlZCIgfHwgdmFsdWUuc3RhdHVzID09PSAiYWJvcnRlZCIpIHsKICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAoa2V5LnN0YXR1cyA9PT0gImRpcnR5IiB8fCB2YWx1ZS5zdGF0dXMgPT09ICJkaXJ0eSIpIHsKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICB9CiAgICAgICAgICBmaW5hbE1hcC5zZXQoa2V5LnZhbHVlLCB2YWx1ZS52YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiB7IHN0YXR1czogc3RhdHVzLnZhbHVlLCB2YWx1ZTogZmluYWxNYXAgfTsKICAgICAgfQogICAgfQogIH0KICBab2RNYXAuY3JlYXRlID0gKGtleVR5cGUsIHZhbHVlVHlwZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE1hcCh7CiAgICAgIHZhbHVlVHlwZSwKICAgICAga2V5VHlwZSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RNYXAsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RTZXQgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IHN0YXR1cywgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUuc2V0KSB7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF90eXBlLAogICAgICAgICAgZXhwZWN0ZWQ6IFpvZFBhcnNlZFR5cGUuc2V0LAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgY29uc3QgZGVmID0gdGhpcy5fZGVmOwogICAgICBpZiAoZGVmLm1pblNpemUgIT09IG51bGwpIHsKICAgICAgICBpZiAoY3R4LmRhdGEuc2l6ZSA8IGRlZi5taW5TaXplLnZhbHVlKSB7CiAgICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLnRvb19zbWFsbCwKICAgICAgICAgICAgbWluaW11bTogZGVmLm1pblNpemUudmFsdWUsCiAgICAgICAgICAgIHR5cGU6ICJzZXQiLAogICAgICAgICAgICBpbmNsdXNpdmU6IHRydWUsCiAgICAgICAgICAgIGV4YWN0OiBmYWxzZSwKICAgICAgICAgICAgbWVzc2FnZTogZGVmLm1pblNpemUubWVzc2FnZQogICAgICAgICAgfSk7CiAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGRlZi5tYXhTaXplICE9PSBudWxsKSB7CiAgICAgICAgaWYgKGN0eC5kYXRhLnNpemUgPiBkZWYubWF4U2l6ZS52YWx1ZSkgewogICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS50b29fYmlnLAogICAgICAgICAgICBtYXhpbXVtOiBkZWYubWF4U2l6ZS52YWx1ZSwKICAgICAgICAgICAgdHlwZTogInNldCIsCiAgICAgICAgICAgIGluY2x1c2l2ZTogdHJ1ZSwKICAgICAgICAgICAgZXhhY3Q6IGZhbHNlLAogICAgICAgICAgICBtZXNzYWdlOiBkZWYubWF4U2l6ZS5tZXNzYWdlCiAgICAgICAgICB9KTsKICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgIH0KICAgICAgfQogICAgICBjb25zdCB2YWx1ZVR5cGUgPSB0aGlzLl9kZWYudmFsdWVUeXBlOwogICAgICBmdW5jdGlvbiBmaW5hbGl6ZVNldChlbGVtZW50czIpIHsKICAgICAgICBjb25zdCBwYXJzZWRTZXQgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpOwogICAgICAgIGZvciAoY29uc3QgZWxlbWVudCBvZiBlbGVtZW50czIpIHsKICAgICAgICAgIGlmIChlbGVtZW50LnN0YXR1cyA9PT0gImFib3J0ZWQiKQogICAgICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgICAgIGlmIChlbGVtZW50LnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICBwYXJzZWRTZXQuYWRkKGVsZW1lbnQudmFsdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IHBhcnNlZFNldCB9OwogICAgICB9CiAgICAgIGNvbnN0IGVsZW1lbnRzID0gWy4uLmN0eC5kYXRhLnZhbHVlcygpXS5tYXAoKGl0ZW0sIGkyKSA9PiB2YWx1ZVR5cGUuX3BhcnNlKG5ldyBQYXJzZUlucHV0TGF6eVBhdGgoY3R4LCBpdGVtLCBjdHgucGF0aCwgaTIpKSk7CiAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKGVsZW1lbnRzKS50aGVuKChlbGVtZW50czIpID0+IGZpbmFsaXplU2V0KGVsZW1lbnRzMikpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBmaW5hbGl6ZVNldChlbGVtZW50cyk7CiAgICAgIH0KICAgIH0KICAgIG1pbihtaW5TaXplLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kU2V0KHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgbWluU2l6ZTogeyB2YWx1ZTogbWluU2l6ZSwgbWVzc2FnZTogZXJyb3JVdGlsLnRvU3RyaW5nKG1lc3NhZ2UpIH0KICAgICAgfSk7CiAgICB9CiAgICBtYXgobWF4U2l6ZSwgbWVzc2FnZSkgewogICAgICByZXR1cm4gbmV3IFpvZFNldCh7CiAgICAgICAgLi4udGhpcy5fZGVmLAogICAgICAgIG1heFNpemU6IHsgdmFsdWU6IG1heFNpemUsIG1lc3NhZ2U6IGVycm9yVXRpbC50b1N0cmluZyhtZXNzYWdlKSB9CiAgICAgIH0pOwogICAgfQogICAgc2l6ZShzaXplLCBtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLm1pbihzaXplLCBtZXNzYWdlKS5tYXgoc2l6ZSwgbWVzc2FnZSk7CiAgICB9CiAgICBub25lbXB0eShtZXNzYWdlKSB7CiAgICAgIHJldHVybiB0aGlzLm1pbigxLCBtZXNzYWdlKTsKICAgIH0KICB9CiAgWm9kU2V0LmNyZWF0ZSA9ICh2YWx1ZVR5cGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RTZXQoewogICAgICB2YWx1ZVR5cGUsCiAgICAgIG1pblNpemU6IG51bGwsCiAgICAgIG1heFNpemU6IG51bGwsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kU2V0LAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kRnVuY3Rpb24gZXh0ZW5kcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICBzdXBlciguLi5hcmd1bWVudHMpOwogICAgICB0aGlzLnZhbGlkYXRlID0gdGhpcy5pbXBsZW1lbnQ7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBjdHggfSA9IHRoaXMuX3Byb2Nlc3NJbnB1dFBhcmFtcyhpbnB1dCk7CiAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5mdW5jdGlvbikgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLmZ1bmN0aW9uLAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgZnVuY3Rpb24gbWFrZUFyZ3NJc3N1ZShhcmdzLCBlcnJvcikgewogICAgICAgIHJldHVybiBtYWtlSXNzdWUoewogICAgICAgICAgZGF0YTogYXJncywKICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgZXJyb3JNYXBzOiBbCiAgICAgICAgICAgIGN0eC5jb21tb24uY29udGV4dHVhbEVycm9yTWFwLAogICAgICAgICAgICBjdHguc2NoZW1hRXJyb3JNYXAsCiAgICAgICAgICAgIGdldEVycm9yTWFwKCksCiAgICAgICAgICAgIGVycm9yTWFwCiAgICAgICAgICBdLmZpbHRlcigoeCkgPT4gISF4KSwKICAgICAgICAgIGlzc3VlRGF0YTogewogICAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9hcmd1bWVudHMsCiAgICAgICAgICAgIGFyZ3VtZW50c0Vycm9yOiBlcnJvcgogICAgICAgICAgfQogICAgICAgIH0pOwogICAgICB9CiAgICAgIGZ1bmN0aW9uIG1ha2VSZXR1cm5zSXNzdWUocmV0dXJucywgZXJyb3IpIHsKICAgICAgICByZXR1cm4gbWFrZUlzc3VlKHsKICAgICAgICAgIGRhdGE6IHJldHVybnMsCiAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgIGVycm9yTWFwczogWwogICAgICAgICAgICBjdHguY29tbW9uLmNvbnRleHR1YWxFcnJvck1hcCwKICAgICAgICAgICAgY3R4LnNjaGVtYUVycm9yTWFwLAogICAgICAgICAgICBnZXRFcnJvck1hcCgpLAogICAgICAgICAgICBlcnJvck1hcAogICAgICAgICAgXS5maWx0ZXIoKHgpID0+ICEheCksCiAgICAgICAgICBpc3N1ZURhdGE6IHsKICAgICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfcmV0dXJuX3R5cGUsCiAgICAgICAgICAgIHJldHVyblR5cGVFcnJvcjogZXJyb3IKICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgfQogICAgICBjb25zdCBwYXJhbXMgPSB7IGVycm9yTWFwOiBjdHguY29tbW9uLmNvbnRleHR1YWxFcnJvck1hcCB9OwogICAgICBjb25zdCBmbiA9IGN0eC5kYXRhOwogICAgICBpZiAodGhpcy5fZGVmLnJldHVybnMgaW5zdGFuY2VvZiBab2RQcm9taXNlKSB7CiAgICAgICAgY29uc3QgbWUgPSB0aGlzOwogICAgICAgIHJldHVybiBPSyhhc3luYyBmdW5jdGlvbiguLi5hcmdzKSB7CiAgICAgICAgICBjb25zdCBlcnJvciA9IG5ldyBab2RFcnJvcihbXSk7CiAgICAgICAgICBjb25zdCBwYXJzZWRBcmdzID0gYXdhaXQgbWUuX2RlZi5hcmdzLnBhcnNlQXN5bmMoYXJncywgcGFyYW1zKS5jYXRjaCgoZTIpID0+IHsKICAgICAgICAgICAgZXJyb3IuYWRkSXNzdWUobWFrZUFyZ3NJc3N1ZShhcmdzLCBlMikpOwogICAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICAgIH0pOwogICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUmVmbGVjdC5hcHBseShmbiwgdGhpcywgcGFyc2VkQXJncyk7CiAgICAgICAgICBjb25zdCBwYXJzZWRSZXR1cm5zID0gYXdhaXQgbWUuX2RlZi5yZXR1cm5zLl9kZWYudHlwZS5wYXJzZUFzeW5jKHJlc3VsdCwgcGFyYW1zKS5jYXRjaCgoZTIpID0+IHsKICAgICAgICAgICAgZXJyb3IuYWRkSXNzdWUobWFrZVJldHVybnNJc3N1ZShyZXN1bHQsIGUyKSk7CiAgICAgICAgICAgIHRocm93IGVycm9yOwogICAgICAgICAgfSk7CiAgICAgICAgICByZXR1cm4gcGFyc2VkUmV0dXJuczsKICAgICAgICB9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb25zdCBtZSA9IHRoaXM7CiAgICAgICAgcmV0dXJuIE9LKGZ1bmN0aW9uKC4uLmFyZ3MpIHsKICAgICAgICAgIGNvbnN0IHBhcnNlZEFyZ3MgPSBtZS5fZGVmLmFyZ3Muc2FmZVBhcnNlKGFyZ3MsIHBhcmFtcyk7CiAgICAgICAgICBpZiAoIXBhcnNlZEFyZ3Muc3VjY2VzcykgewogICAgICAgICAgICB0aHJvdyBuZXcgWm9kRXJyb3IoW21ha2VBcmdzSXNzdWUoYXJncywgcGFyc2VkQXJncy5lcnJvcildKTsKICAgICAgICAgIH0KICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IFJlZmxlY3QuYXBwbHkoZm4sIHRoaXMsIHBhcnNlZEFyZ3MuZGF0YSk7CiAgICAgICAgICBjb25zdCBwYXJzZWRSZXR1cm5zID0gbWUuX2RlZi5yZXR1cm5zLnNhZmVQYXJzZShyZXN1bHQsIHBhcmFtcyk7CiAgICAgICAgICBpZiAoIXBhcnNlZFJldHVybnMuc3VjY2VzcykgewogICAgICAgICAgICB0aHJvdyBuZXcgWm9kRXJyb3IoW21ha2VSZXR1cm5zSXNzdWUocmVzdWx0LCBwYXJzZWRSZXR1cm5zLmVycm9yKV0pOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIHBhcnNlZFJldHVybnMuZGF0YTsKICAgICAgICB9KTsKICAgICAgfQogICAgfQogICAgcGFyYW1ldGVycygpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5hcmdzOwogICAgfQogICAgcmV0dXJuVHlwZSgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5yZXR1cm5zOwogICAgfQogICAgYXJncyguLi5pdGVtcykgewogICAgICByZXR1cm4gbmV3IFpvZEZ1bmN0aW9uKHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgYXJnczogWm9kVHVwbGUuY3JlYXRlKGl0ZW1zKS5yZXN0KFpvZFVua25vd24uY3JlYXRlKCkpCiAgICAgIH0pOwogICAgfQogICAgcmV0dXJucyhyZXR1cm5UeXBlKSB7CiAgICAgIHJldHVybiBuZXcgWm9kRnVuY3Rpb24oewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICByZXR1cm5zOiByZXR1cm5UeXBlCiAgICAgIH0pOwogICAgfQogICAgaW1wbGVtZW50KGZ1bmMpIHsKICAgICAgY29uc3QgdmFsaWRhdGVkRnVuYyA9IHRoaXMucGFyc2UoZnVuYyk7CiAgICAgIHJldHVybiB2YWxpZGF0ZWRGdW5jOwogICAgfQogICAgc3RyaWN0SW1wbGVtZW50KGZ1bmMpIHsKICAgICAgY29uc3QgdmFsaWRhdGVkRnVuYyA9IHRoaXMucGFyc2UoZnVuYyk7CiAgICAgIHJldHVybiB2YWxpZGF0ZWRGdW5jOwogICAgfQogICAgc3RhdGljIGNyZWF0ZShhcmdzLCByZXR1cm5zLCBwYXJhbXMpIHsKICAgICAgcmV0dXJuIG5ldyBab2RGdW5jdGlvbih7CiAgICAgICAgYXJnczogYXJncyA/IGFyZ3MgOiBab2RUdXBsZS5jcmVhdGUoW10pLnJlc3QoWm9kVW5rbm93bi5jcmVhdGUoKSksCiAgICAgICAgcmV0dXJuczogcmV0dXJucyB8fCBab2RVbmtub3duLmNyZWF0ZSgpLAogICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRnVuY3Rpb24sCiAgICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICAgIH0pOwogICAgfQogIH0KICBjbGFzcyBab2RMYXp5IGV4dGVuZHMgWm9kVHlwZSB7CiAgICBnZXQgc2NoZW1hKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmdldHRlcigpOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBjb25zdCBsYXp5U2NoZW1hID0gdGhpcy5fZGVmLmdldHRlcigpOwogICAgICByZXR1cm4gbGF6eVNjaGVtYS5fcGFyc2UoeyBkYXRhOiBjdHguZGF0YSwgcGF0aDogY3R4LnBhdGgsIHBhcmVudDogY3R4IH0pOwogICAgfQogIH0KICBab2RMYXp5LmNyZWF0ZSA9IChnZXR0ZXIsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RMYXp5KHsKICAgICAgZ2V0dGVyLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZExhenksCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RMaXRlcmFsIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgaWYgKGlucHV0LmRhdGEgIT09IHRoaXMuX2RlZi52YWx1ZSkgewogICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIHJlY2VpdmVkOiBjdHguZGF0YSwKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX2xpdGVyYWwsCiAgICAgICAgICBleHBlY3RlZDogdGhpcy5fZGVmLnZhbHVlCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgcmV0dXJuIHsgc3RhdHVzOiAidmFsaWQiLCB2YWx1ZTogaW5wdXQuZGF0YSB9OwogICAgfQogICAgZ2V0IHZhbHVlKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLnZhbHVlOwogICAgfQogIH0KICBab2RMaXRlcmFsLmNyZWF0ZSA9ICh2YWx1ZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZExpdGVyYWwoewogICAgICB2YWx1ZSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RMaXRlcmFsLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgZnVuY3Rpb24gY3JlYXRlWm9kRW51bSh2YWx1ZXMsIHBhcmFtcykgewogICAgcmV0dXJuIG5ldyBab2RFbnVtKHsKICAgICAgdmFsdWVzLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVudW0sCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfQogIGNsYXNzIFpvZEVudW0gZXh0ZW5kcyBab2RUeXBlIHsKICAgIGNvbnN0cnVjdG9yKCkgewogICAgICBzdXBlciguLi5hcmd1bWVudHMpOwogICAgICBfWm9kRW51bV9jYWNoZS5zZXQodGhpcywgdm9pZCAwKTsKICAgIH0KICAgIF9wYXJzZShpbnB1dCkgewogICAgICBpZiAodHlwZW9mIGlucHV0LmRhdGEgIT09ICJzdHJpbmciKSB7CiAgICAgICAgY29uc3QgY3R4ID0gdGhpcy5fZ2V0T3JSZXR1cm5DdHgoaW5wdXQpOwogICAgICAgIGNvbnN0IGV4cGVjdGVkVmFsdWVzID0gdGhpcy5fZGVmLnZhbHVlczsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGV4cGVjdGVkOiB1dGlsLmpvaW5WYWx1ZXMoZXhwZWN0ZWRWYWx1ZXMpLAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlLAogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfWm9kRW51bV9jYWNoZSkpIHsKICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9ab2RFbnVtX2NhY2hlLCBuZXcgU2V0KHRoaXMuX2RlZi52YWx1ZXMpKTsKICAgICAgfQogICAgICBpZiAoIV9fY2xhc3NQcml2YXRlRmllbGRHZXQodGhpcywgX1pvZEVudW1fY2FjaGUpLmhhcyhpbnB1dC5kYXRhKSkgewogICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBjb25zdCBleHBlY3RlZFZhbHVlcyA9IHRoaXMuX2RlZi52YWx1ZXM7CiAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCB7CiAgICAgICAgICByZWNlaXZlZDogY3R4LmRhdGEsCiAgICAgICAgICBjb2RlOiBab2RJc3N1ZUNvZGUuaW52YWxpZF9lbnVtX3ZhbHVlLAogICAgICAgICAgb3B0aW9uczogZXhwZWN0ZWRWYWx1ZXMKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICByZXR1cm4gT0soaW5wdXQuZGF0YSk7CiAgICB9CiAgICBnZXQgb3B0aW9ucygpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi52YWx1ZXM7CiAgICB9CiAgICBnZXQgZW51bSgpIHsKICAgICAgY29uc3QgZW51bVZhbHVlcyA9IHt9OwogICAgICBmb3IgKGNvbnN0IHZhbCBvZiB0aGlzLl9kZWYudmFsdWVzKSB7CiAgICAgICAgZW51bVZhbHVlc1t2YWxdID0gdmFsOwogICAgICB9CiAgICAgIHJldHVybiBlbnVtVmFsdWVzOwogICAgfQogICAgZ2V0IFZhbHVlcygpIHsKICAgICAgY29uc3QgZW51bVZhbHVlcyA9IHt9OwogICAgICBmb3IgKGNvbnN0IHZhbCBvZiB0aGlzLl9kZWYudmFsdWVzKSB7CiAgICAgICAgZW51bVZhbHVlc1t2YWxdID0gdmFsOwogICAgICB9CiAgICAgIHJldHVybiBlbnVtVmFsdWVzOwogICAgfQogICAgZ2V0IEVudW0oKSB7CiAgICAgIGNvbnN0IGVudW1WYWx1ZXMgPSB7fTsKICAgICAgZm9yIChjb25zdCB2YWwgb2YgdGhpcy5fZGVmLnZhbHVlcykgewogICAgICAgIGVudW1WYWx1ZXNbdmFsXSA9IHZhbDsKICAgICAgfQogICAgICByZXR1cm4gZW51bVZhbHVlczsKICAgIH0KICAgIGV4dHJhY3QodmFsdWVzLCBuZXdEZWYgPSB0aGlzLl9kZWYpIHsKICAgICAgcmV0dXJuIFpvZEVudW0uY3JlYXRlKHZhbHVlcywgewogICAgICAgIC4uLnRoaXMuX2RlZiwKICAgICAgICAuLi5uZXdEZWYKICAgICAgfSk7CiAgICB9CiAgICBleGNsdWRlKHZhbHVlcywgbmV3RGVmID0gdGhpcy5fZGVmKSB7CiAgICAgIHJldHVybiBab2RFbnVtLmNyZWF0ZSh0aGlzLm9wdGlvbnMuZmlsdGVyKChvcHQpID0+ICF2YWx1ZXMuaW5jbHVkZXMob3B0KSksIHsKICAgICAgICAuLi50aGlzLl9kZWYsCiAgICAgICAgLi4ubmV3RGVmCiAgICAgIH0pOwogICAgfQogIH0KICBfWm9kRW51bV9jYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOwogIFpvZEVudW0uY3JlYXRlID0gY3JlYXRlWm9kRW51bTsKICBjbGFzcyBab2ROYXRpdmVFbnVtIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgc3VwZXIoLi4uYXJndW1lbnRzKTsKICAgICAgX1pvZE5hdGl2ZUVudW1fY2FjaGUuc2V0KHRoaXMsIHZvaWQgMCk7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgbmF0aXZlRW51bVZhbHVlcyA9IHV0aWwuZ2V0VmFsaWRFbnVtVmFsdWVzKHRoaXMuX2RlZi52YWx1ZXMpOwogICAgICBjb25zdCBjdHggPSB0aGlzLl9nZXRPclJldHVybkN0eChpbnB1dCk7CiAgICAgIGlmIChjdHgucGFyc2VkVHlwZSAhPT0gWm9kUGFyc2VkVHlwZS5zdHJpbmcgJiYgY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUubnVtYmVyKSB7CiAgICAgICAgY29uc3QgZXhwZWN0ZWRWYWx1ZXMgPSB1dGlsLm9iamVjdFZhbHVlcyhuYXRpdmVFbnVtVmFsdWVzKTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGV4cGVjdGVkOiB1dGlsLmpvaW5WYWx1ZXMoZXhwZWN0ZWRWYWx1ZXMpLAogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5wYXJzZWRUeXBlLAogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZQogICAgICAgIH0pOwogICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICB9CiAgICAgIGlmICghX19jbGFzc1ByaXZhdGVGaWVsZEdldCh0aGlzLCBfWm9kTmF0aXZlRW51bV9jYWNoZSkpIHsKICAgICAgICBfX2NsYXNzUHJpdmF0ZUZpZWxkU2V0KHRoaXMsIF9ab2ROYXRpdmVFbnVtX2NhY2hlLCBuZXcgU2V0KHV0aWwuZ2V0VmFsaWRFbnVtVmFsdWVzKHRoaXMuX2RlZi52YWx1ZXMpKSk7CiAgICAgIH0KICAgICAgaWYgKCFfX2NsYXNzUHJpdmF0ZUZpZWxkR2V0KHRoaXMsIF9ab2ROYXRpdmVFbnVtX2NhY2hlKS5oYXMoaW5wdXQuZGF0YSkpIHsKICAgICAgICBjb25zdCBleHBlY3RlZFZhbHVlcyA9IHV0aWwub2JqZWN0VmFsdWVzKG5hdGl2ZUVudW1WYWx1ZXMpOwogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgcmVjZWl2ZWQ6IGN0eC5kYXRhLAogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfZW51bV92YWx1ZSwKICAgICAgICAgIG9wdGlvbnM6IGV4cGVjdGVkVmFsdWVzCiAgICAgICAgfSk7CiAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgIH0KICAgICAgcmV0dXJuIE9LKGlucHV0LmRhdGEpOwogICAgfQogICAgZ2V0IGVudW0oKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYudmFsdWVzOwogICAgfQogIH0KICBfWm9kTmF0aXZlRW51bV9jYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgV2Vha01hcCgpOwogIFpvZE5hdGl2ZUVudW0uY3JlYXRlID0gKHZhbHVlcywgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE5hdGl2ZUVudW0oewogICAgICB2YWx1ZXMsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTmF0aXZlRW51bSwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZFByb21pc2UgZXh0ZW5kcyBab2RUeXBlIHsKICAgIHVud3JhcCgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi50eXBlOwogICAgfQogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgIT09IFpvZFBhcnNlZFR5cGUucHJvbWlzZSAmJiBjdHguY29tbW9uLmFzeW5jID09PSBmYWxzZSkgewogICAgICAgIGFkZElzc3VlVG9Db250ZXh0KGN0eCwgewogICAgICAgICAgY29kZTogWm9kSXNzdWVDb2RlLmludmFsaWRfdHlwZSwKICAgICAgICAgIGV4cGVjdGVkOiBab2RQYXJzZWRUeXBlLnByb21pc2UsCiAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICBjb25zdCBwcm9taXNpZmllZCA9IGN0eC5wYXJzZWRUeXBlID09PSBab2RQYXJzZWRUeXBlLnByb21pc2UgPyBjdHguZGF0YSA6IFByb21pc2UucmVzb2x2ZShjdHguZGF0YSk7CiAgICAgIHJldHVybiBPSyhwcm9taXNpZmllZC50aGVuKChkYXRhKSA9PiB7CiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi50eXBlLnBhcnNlQXN5bmMoZGF0YSwgewogICAgICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgICAgICBlcnJvck1hcDogY3R4LmNvbW1vbi5jb250ZXh0dWFsRXJyb3JNYXAKICAgICAgICB9KTsKICAgICAgfSkpOwogICAgfQogIH0KICBab2RQcm9taXNlLmNyZWF0ZSA9IChzY2hlbWEsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RQcm9taXNlKHsKICAgICAgdHlwZTogc2NoZW1hLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZFByb21pc2UsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2RFZmZlY3RzIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBpbm5lclR5cGUoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYuc2NoZW1hOwogICAgfQogICAgc291cmNlVHlwZSgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5zY2hlbWEuX2RlZi50eXBlTmFtZSA9PT0gWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMgPyB0aGlzLl9kZWYuc2NoZW1hLnNvdXJjZVR5cGUoKSA6IHRoaXMuX2RlZi5zY2hlbWE7CiAgICB9CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgY29uc3QgZWZmZWN0ID0gdGhpcy5fZGVmLmVmZmVjdCB8fCBudWxsOwogICAgICBjb25zdCBjaGVja0N0eCA9IHsKICAgICAgICBhZGRJc3N1ZTogKGFyZykgPT4gewogICAgICAgICAgYWRkSXNzdWVUb0NvbnRleHQoY3R4LCBhcmcpOwogICAgICAgICAgaWYgKGFyZy5mYXRhbCkgewogICAgICAgICAgICBzdGF0dXMuYWJvcnQoKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN0YXR1cy5kaXJ0eSgpOwogICAgICAgICAgfQogICAgICAgIH0sCiAgICAgICAgZ2V0IHBhdGgoKSB7CiAgICAgICAgICByZXR1cm4gY3R4LnBhdGg7CiAgICAgICAgfQogICAgICB9OwogICAgICBjaGVja0N0eC5hZGRJc3N1ZSA9IGNoZWNrQ3R4LmFkZElzc3VlLmJpbmQoY2hlY2tDdHgpOwogICAgICBpZiAoZWZmZWN0LnR5cGUgPT09ICJwcmVwcm9jZXNzIikgewogICAgICAgIGNvbnN0IHByb2Nlc3NlZCA9IGVmZmVjdC50cmFuc2Zvcm0oY3R4LmRhdGEsIGNoZWNrQ3R4KTsKICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYykgewogICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShwcm9jZXNzZWQpLnRoZW4oYXN5bmMgKHByb2Nlc3NlZDIpID0+IHsKICAgICAgICAgICAgaWYgKHN0YXR1cy52YWx1ZSA9PT0gImFib3J0ZWQiKQogICAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLl9kZWYuc2NoZW1hLl9wYXJzZUFzeW5jKHsKICAgICAgICAgICAgICBkYXRhOiBwcm9jZXNzZWQyLAogICAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICAgIHBhcmVudDogY3R4CiAgICAgICAgICAgIH0pOwogICAgICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gImFib3J0ZWQiKQogICAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgICAgICByZXR1cm4gRElSVFkocmVzdWx0LnZhbHVlKTsKICAgICAgICAgICAgaWYgKHN0YXR1cy52YWx1ZSA9PT0gImRpcnR5IikKICAgICAgICAgICAgICByZXR1cm4gRElSVFkocmVzdWx0LnZhbHVlKTsKICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKICAgICAgICAgIH0pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAoc3RhdHVzLnZhbHVlID09PSAiYWJvcnRlZCIpCiAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VTeW5jKHsKICAgICAgICAgICAgZGF0YTogcHJvY2Vzc2VkLAogICAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgICAgcGFyZW50OiBjdHgKICAgICAgICAgIH0pOwogICAgICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09ICJhYm9ydGVkIikKICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgICAgcmV0dXJuIERJUlRZKHJlc3VsdC52YWx1ZSk7CiAgICAgICAgICBpZiAoc3RhdHVzLnZhbHVlID09PSAiZGlydHkiKQogICAgICAgICAgICByZXR1cm4gRElSVFkocmVzdWx0LnZhbHVlKTsKICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICAgICAgfQogICAgICB9CiAgICAgIGlmIChlZmZlY3QudHlwZSA9PT0gInJlZmluZW1lbnQiKSB7CiAgICAgICAgY29uc3QgZXhlY3V0ZVJlZmluZW1lbnQgPSAoYWNjKSA9PiB7CiAgICAgICAgICBjb25zdCByZXN1bHQgPSBlZmZlY3QucmVmaW5lbWVudChhY2MsIGNoZWNrQ3R4KTsKICAgICAgICAgIGlmIChjdHguY29tbW9uLmFzeW5jKSB7CiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUocmVzdWx0KTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBQcm9taXNlKSB7CiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiQXN5bmMgcmVmaW5lbWVudCBlbmNvdW50ZXJlZCBkdXJpbmcgc3luY2hyb25vdXMgcGFyc2Ugb3BlcmF0aW9uLiBVc2UgLnBhcnNlQXN5bmMgaW5zdGVhZC4iKTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiBhY2M7CiAgICAgICAgfTsKICAgICAgICBpZiAoY3R4LmNvbW1vbi5hc3luYyA9PT0gZmFsc2UpIHsKICAgICAgICAgIGNvbnN0IGlubmVyID0gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VTeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgfSk7CiAgICAgICAgICBpZiAoaW5uZXIuc3RhdHVzID09PSAiYWJvcnRlZCIpCiAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgaWYgKGlubmVyLnN0YXR1cyA9PT0gImRpcnR5IikKICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICBleGVjdXRlUmVmaW5lbWVudChpbm5lci52YWx1ZSk7CiAgICAgICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IGlubmVyLnZhbHVlIH07CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiB0aGlzLl9kZWYuc2NoZW1hLl9wYXJzZUFzeW5jKHsgZGF0YTogY3R4LmRhdGEsIHBhdGg6IGN0eC5wYXRoLCBwYXJlbnQ6IGN0eCB9KS50aGVuKChpbm5lcikgPT4gewogICAgICAgICAgICBpZiAoaW5uZXIuc3RhdHVzID09PSAiYWJvcnRlZCIpCiAgICAgICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgICAgIGlmIChpbm5lci5zdGF0dXMgPT09ICJkaXJ0eSIpCiAgICAgICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICAgIHJldHVybiBleGVjdXRlUmVmaW5lbWVudChpbm5lci52YWx1ZSkudGhlbigoKSA9PiB7CiAgICAgICAgICAgICAgcmV0dXJuIHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiBpbm5lci52YWx1ZSB9OwogICAgICAgICAgICB9KTsKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfQogICAgICBpZiAoZWZmZWN0LnR5cGUgPT09ICJ0cmFuc2Zvcm0iKSB7CiAgICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMgPT09IGZhbHNlKSB7CiAgICAgICAgICBjb25zdCBiYXNlID0gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VTeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgfSk7CiAgICAgICAgICBpZiAoIWlzVmFsaWQoYmFzZSkpCiAgICAgICAgICAgIHJldHVybiBiYXNlOwogICAgICAgICAgY29uc3QgcmVzdWx0ID0gZWZmZWN0LnRyYW5zZm9ybShiYXNlLnZhbHVlLCBjaGVja0N0eCk7CiAgICAgICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEFzeW5jaHJvbm91cyB0cmFuc2Zvcm0gZW5jb3VudGVyZWQgZHVyaW5nIHN5bmNocm9ub3VzIHBhcnNlIG9wZXJhdGlvbi4gVXNlIC5wYXJzZUFzeW5jIGluc3RlYWQuYCk7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4geyBzdGF0dXM6IHN0YXR1cy52YWx1ZSwgdmFsdWU6IHJlc3VsdCB9OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gdGhpcy5fZGVmLnNjaGVtYS5fcGFyc2VBc3luYyh7IGRhdGE6IGN0eC5kYXRhLCBwYXRoOiBjdHgucGF0aCwgcGFyZW50OiBjdHggfSkudGhlbigoYmFzZSkgPT4gewogICAgICAgICAgICBpZiAoIWlzVmFsaWQoYmFzZSkpCiAgICAgICAgICAgICAgcmV0dXJuIGJhc2U7CiAgICAgICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZWZmZWN0LnRyYW5zZm9ybShiYXNlLnZhbHVlLCBjaGVja0N0eCkpLnRoZW4oKHJlc3VsdCkgPT4gKHsgc3RhdHVzOiBzdGF0dXMudmFsdWUsIHZhbHVlOiByZXN1bHQgfSkpOwogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHV0aWwuYXNzZXJ0TmV2ZXIoZWZmZWN0KTsKICAgIH0KICB9CiAgWm9kRWZmZWN0cy5jcmVhdGUgPSAoc2NoZW1hLCBlZmZlY3QsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RFZmZlY3RzKHsKICAgICAgc2NoZW1hLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZEVmZmVjdHMsCiAgICAgIGVmZmVjdCwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIFpvZEVmZmVjdHMuY3JlYXRlV2l0aFByZXByb2Nlc3MgPSAocHJlcHJvY2Vzcywgc2NoZW1hLCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kRWZmZWN0cyh7CiAgICAgIHNjaGVtYSwKICAgICAgZWZmZWN0OiB7IHR5cGU6ICJwcmVwcm9jZXNzIiwgdHJhbnNmb3JtOiBwcmVwcm9jZXNzIH0sCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRWZmZWN0cywKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZE9wdGlvbmFsIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpOwogICAgICBpZiAocGFyc2VkVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS51bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4gT0sodm9pZCAwKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZS5fcGFyc2UoaW5wdXQpOwogICAgfQogICAgdW53cmFwKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZTsKICAgIH0KICB9CiAgWm9kT3B0aW9uYWwuY3JlYXRlID0gKHR5cGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RPcHRpb25hbCh7CiAgICAgIGlubmVyVHlwZTogdHlwZSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RPcHRpb25hbCwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGNsYXNzIFpvZE51bGxhYmxlIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgcGFyc2VkVHlwZSA9IHRoaXMuX2dldFR5cGUoaW5wdXQpOwogICAgICBpZiAocGFyc2VkVHlwZSA9PT0gWm9kUGFyc2VkVHlwZS5udWxsKSB7CiAgICAgICAgcmV0dXJuIE9LKG51bGwpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZShpbnB1dCk7CiAgICB9CiAgICB1bndyYXAoKSB7CiAgICAgIHJldHVybiB0aGlzLl9kZWYuaW5uZXJUeXBlOwogICAgfQogIH0KICBab2ROdWxsYWJsZS5jcmVhdGUgPSAodHlwZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE51bGxhYmxlKHsKICAgICAgaW5uZXJUeXBlOiB0eXBlLAogICAgICB0eXBlTmFtZTogWm9kRmlyc3RQYXJ0eVR5cGVLaW5kLlpvZE51bGxhYmxlLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kRGVmYXVsdCBleHRlbmRzIFpvZFR5cGUgewogICAgX3BhcnNlKGlucHV0KSB7CiAgICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzLl9wcm9jZXNzSW5wdXRQYXJhbXMoaW5wdXQpOwogICAgICBsZXQgZGF0YSA9IGN0eC5kYXRhOwogICAgICBpZiAoY3R4LnBhcnNlZFR5cGUgPT09IFpvZFBhcnNlZFR5cGUudW5kZWZpbmVkKSB7CiAgICAgICAgZGF0YSA9IHRoaXMuX2RlZi5kZWZhdWx0VmFsdWUoKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZS5fcGFyc2UoewogICAgICAgIGRhdGEsCiAgICAgICAgcGF0aDogY3R4LnBhdGgsCiAgICAgICAgcGFyZW50OiBjdHgKICAgICAgfSk7CiAgICB9CiAgICByZW1vdmVEZWZhdWx0KCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZTsKICAgIH0KICB9CiAgWm9kRGVmYXVsdC5jcmVhdGUgPSAodHlwZSwgcGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZERlZmF1bHQoewogICAgICBpbm5lclR5cGU6IHR5cGUsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kRGVmYXVsdCwKICAgICAgZGVmYXVsdFZhbHVlOiB0eXBlb2YgcGFyYW1zLmRlZmF1bHQgPT09ICJmdW5jdGlvbiIgPyBwYXJhbXMuZGVmYXVsdCA6ICgpID0+IHBhcmFtcy5kZWZhdWx0LAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY2xhc3MgWm9kQ2F0Y2ggZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgY29uc3QgbmV3Q3R4ID0gewogICAgICAgIC4uLmN0eCwKICAgICAgICBjb21tb246IHsKICAgICAgICAgIC4uLmN0eC5jb21tb24sCiAgICAgICAgICBpc3N1ZXM6IFtdCiAgICAgICAgfQogICAgICB9OwogICAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9kZWYuaW5uZXJUeXBlLl9wYXJzZSh7CiAgICAgICAgZGF0YTogbmV3Q3R4LmRhdGEsCiAgICAgICAgcGF0aDogbmV3Q3R4LnBhdGgsCiAgICAgICAgcGFyZW50OiB7CiAgICAgICAgICAuLi5uZXdDdHgKICAgICAgICB9CiAgICAgIH0pOwogICAgICBpZiAoaXNBc3luYyhyZXN1bHQpKSB7CiAgICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKChyZXN1bHQyKSA9PiB7CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICBzdGF0dXM6ICJ2YWxpZCIsCiAgICAgICAgICAgIHZhbHVlOiByZXN1bHQyLnN0YXR1cyA9PT0gInZhbGlkIiA/IHJlc3VsdDIudmFsdWUgOiB0aGlzLl9kZWYuY2F0Y2hWYWx1ZSh7CiAgICAgICAgICAgICAgZ2V0IGVycm9yKCkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBab2RFcnJvcihuZXdDdHguY29tbW9uLmlzc3Vlcyk7CiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICBpbnB1dDogbmV3Q3R4LmRhdGEKICAgICAgICAgICAgfSkKICAgICAgICAgIH07CiAgICAgICAgfSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIHN0YXR1czogInZhbGlkIiwKICAgICAgICAgIHZhbHVlOiByZXN1bHQuc3RhdHVzID09PSAidmFsaWQiID8gcmVzdWx0LnZhbHVlIDogdGhpcy5fZGVmLmNhdGNoVmFsdWUoewogICAgICAgICAgICBnZXQgZXJyb3IoKSB7CiAgICAgICAgICAgICAgcmV0dXJuIG5ldyBab2RFcnJvcihuZXdDdHguY29tbW9uLmlzc3Vlcyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGlucHV0OiBuZXdDdHguZGF0YQogICAgICAgICAgfSkKICAgICAgICB9OwogICAgICB9CiAgICB9CiAgICByZW1vdmVDYXRjaCgpIHsKICAgICAgcmV0dXJuIHRoaXMuX2RlZi5pbm5lclR5cGU7CiAgICB9CiAgfQogIFpvZENhdGNoLmNyZWF0ZSA9ICh0eXBlLCBwYXJhbXMpID0+IHsKICAgIHJldHVybiBuZXcgWm9kQ2F0Y2goewogICAgICBpbm5lclR5cGU6IHR5cGUsCiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kQ2F0Y2gsCiAgICAgIGNhdGNoVmFsdWU6IHR5cGVvZiBwYXJhbXMuY2F0Y2ggPT09ICJmdW5jdGlvbiIgPyBwYXJhbXMuY2F0Y2ggOiAoKSA9PiBwYXJhbXMuY2F0Y2gsCiAgICAgIC4uLnByb2Nlc3NDcmVhdGVQYXJhbXMocGFyYW1zKQogICAgfSk7CiAgfTsKICBjbGFzcyBab2ROYU4gZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCBwYXJzZWRUeXBlID0gdGhpcy5fZ2V0VHlwZShpbnB1dCk7CiAgICAgIGlmIChwYXJzZWRUeXBlICE9PSBab2RQYXJzZWRUeXBlLm5hbikgewogICAgICAgIGNvbnN0IGN0eCA9IHRoaXMuX2dldE9yUmV0dXJuQ3R4KGlucHV0KTsKICAgICAgICBhZGRJc3N1ZVRvQ29udGV4dChjdHgsIHsKICAgICAgICAgIGNvZGU6IFpvZElzc3VlQ29kZS5pbnZhbGlkX3R5cGUsCiAgICAgICAgICBleHBlY3RlZDogWm9kUGFyc2VkVHlwZS5uYW4sCiAgICAgICAgICByZWNlaXZlZDogY3R4LnBhcnNlZFR5cGUKICAgICAgICB9KTsKICAgICAgICByZXR1cm4gSU5WQUxJRDsKICAgICAgfQogICAgICByZXR1cm4geyBzdGF0dXM6ICJ2YWxpZCIsIHZhbHVlOiBpbnB1dC5kYXRhIH07CiAgICB9CiAgfQogIFpvZE5hTi5jcmVhdGUgPSAocGFyYW1zKSA9PiB7CiAgICByZXR1cm4gbmV3IFpvZE5hTih7CiAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kTmFOLAogICAgICAuLi5wcm9jZXNzQ3JlYXRlUGFyYW1zKHBhcmFtcykKICAgIH0pOwogIH07CiAgY29uc3QgQlJBTkQgPSBTeW1ib2woInpvZF9icmFuZCIpOwogIGNsYXNzIFpvZEJyYW5kZWQgZXh0ZW5kcyBab2RUeXBlIHsKICAgIF9wYXJzZShpbnB1dCkgewogICAgICBjb25zdCB7IGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgY29uc3QgZGF0YSA9IGN0eC5kYXRhOwogICAgICByZXR1cm4gdGhpcy5fZGVmLnR5cGUuX3BhcnNlKHsKICAgICAgICBkYXRhLAogICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgIHBhcmVudDogY3R4CiAgICAgIH0pOwogICAgfQogICAgdW53cmFwKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLnR5cGU7CiAgICB9CiAgfQogIGNsYXNzIFpvZFBpcGVsaW5lIGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgeyBzdGF0dXMsIGN0eCB9ID0gdGhpcy5fcHJvY2Vzc0lucHV0UGFyYW1zKGlucHV0KTsKICAgICAgaWYgKGN0eC5jb21tb24uYXN5bmMpIHsKICAgICAgICBjb25zdCBoYW5kbGVBc3luYyA9IGFzeW5jICgpID0+IHsKICAgICAgICAgIGNvbnN0IGluUmVzdWx0ID0gYXdhaXQgdGhpcy5fZGVmLmluLl9wYXJzZUFzeW5jKHsKICAgICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICAgIHBhdGg6IGN0eC5wYXRoLAogICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgfSk7CiAgICAgICAgICBpZiAoaW5SZXN1bHQuc3RhdHVzID09PSAiYWJvcnRlZCIpCiAgICAgICAgICAgIHJldHVybiBJTlZBTElEOwogICAgICAgICAgaWYgKGluUmVzdWx0LnN0YXR1cyA9PT0gImRpcnR5IikgewogICAgICAgICAgICBzdGF0dXMuZGlydHkoKTsKICAgICAgICAgICAgcmV0dXJuIERJUlRZKGluUmVzdWx0LnZhbHVlKTsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZWYub3V0Ll9wYXJzZUFzeW5jKHsKICAgICAgICAgICAgICBkYXRhOiBpblJlc3VsdC52YWx1ZSwKICAgICAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgICAgICBwYXJlbnQ6IGN0eAogICAgICAgICAgICB9KTsKICAgICAgICAgIH0KICAgICAgICB9OwogICAgICAgIHJldHVybiBoYW5kbGVBc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IGluUmVzdWx0ID0gdGhpcy5fZGVmLmluLl9wYXJzZVN5bmMoewogICAgICAgICAgZGF0YTogY3R4LmRhdGEsCiAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgIHBhcmVudDogY3R4CiAgICAgICAgfSk7CiAgICAgICAgaWYgKGluUmVzdWx0LnN0YXR1cyA9PT0gImFib3J0ZWQiKQogICAgICAgICAgcmV0dXJuIElOVkFMSUQ7CiAgICAgICAgaWYgKGluUmVzdWx0LnN0YXR1cyA9PT0gImRpcnR5IikgewogICAgICAgICAgc3RhdHVzLmRpcnR5KCk7CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICBzdGF0dXM6ICJkaXJ0eSIsCiAgICAgICAgICAgIHZhbHVlOiBpblJlc3VsdC52YWx1ZQogICAgICAgICAgfTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIHRoaXMuX2RlZi5vdXQuX3BhcnNlU3luYyh7CiAgICAgICAgICAgIGRhdGE6IGluUmVzdWx0LnZhbHVlLAogICAgICAgICAgICBwYXRoOiBjdHgucGF0aCwKICAgICAgICAgICAgcGFyZW50OiBjdHgKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgc3RhdGljIGNyZWF0ZShhMiwgYikgewogICAgICByZXR1cm4gbmV3IFpvZFBpcGVsaW5lKHsKICAgICAgICBpbjogYTIsCiAgICAgICAgb3V0OiBiLAogICAgICAgIHR5cGVOYW1lOiBab2RGaXJzdFBhcnR5VHlwZUtpbmQuWm9kUGlwZWxpbmUKICAgICAgfSk7CiAgICB9CiAgfQogIGNsYXNzIFpvZFJlYWRvbmx5IGV4dGVuZHMgWm9kVHlwZSB7CiAgICBfcGFyc2UoaW5wdXQpIHsKICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5fZGVmLmlubmVyVHlwZS5fcGFyc2UoaW5wdXQpOwogICAgICBjb25zdCBmcmVlemUgPSAoZGF0YSkgPT4gewogICAgICAgIGlmIChpc1ZhbGlkKGRhdGEpKSB7CiAgICAgICAgICBkYXRhLnZhbHVlID0gT2JqZWN0LmZyZWV6ZShkYXRhLnZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGRhdGE7CiAgICAgIH07CiAgICAgIHJldHVybiBpc0FzeW5jKHJlc3VsdCkgPyByZXN1bHQudGhlbigoZGF0YSkgPT4gZnJlZXplKGRhdGEpKSA6IGZyZWV6ZShyZXN1bHQpOwogICAgfQogICAgdW53cmFwKCkgewogICAgICByZXR1cm4gdGhpcy5fZGVmLmlubmVyVHlwZTsKICAgIH0KICB9CiAgWm9kUmVhZG9ubHkuY3JlYXRlID0gKHR5cGUsIHBhcmFtcykgPT4gewogICAgcmV0dXJuIG5ldyBab2RSZWFkb25seSh7CiAgICAgIGlubmVyVHlwZTogdHlwZSwKICAgICAgdHlwZU5hbWU6IFpvZEZpcnN0UGFydHlUeXBlS2luZC5ab2RSZWFkb25seSwKICAgICAgLi4ucHJvY2Vzc0NyZWF0ZVBhcmFtcyhwYXJhbXMpCiAgICB9KTsKICB9OwogIGZ1bmN0aW9uIGN1c3RvbShjaGVjaywgcGFyYW1zID0ge30sIGZhdGFsKSB7CiAgICBpZiAoY2hlY2spCiAgICAgIHJldHVybiBab2RBbnkuY3JlYXRlKCkuc3VwZXJSZWZpbmUoKGRhdGEsIGN0eCkgPT4gewogICAgICAgIHZhciBfYSwgX2I7CiAgICAgICAgaWYgKCFjaGVjayhkYXRhKSkgewogICAgICAgICAgY29uc3QgcCA9IHR5cGVvZiBwYXJhbXMgPT09ICJmdW5jdGlvbiIgPyBwYXJhbXMoZGF0YSkgOiB0eXBlb2YgcGFyYW1zID09PSAic3RyaW5nIiA/IHsgbWVzc2FnZTogcGFyYW1zIH0gOiBwYXJhbXM7CiAgICAgICAgICBjb25zdCBfZmF0YWwgPSAoX2IgPSAoX2EgPSBwLmZhdGFsKSAhPT0gbnVsbCAmJiBfYSAhPT0gdm9pZCAwID8gX2EgOiBmYXRhbCkgIT09IG51bGwgJiYgX2IgIT09IHZvaWQgMCA/IF9iIDogdHJ1ZTsKICAgICAgICAgIGNvbnN0IHAyID0gdHlwZW9mIHAgPT09ICJzdHJpbmciID8geyBtZXNzYWdlOiBwIH0gOiBwOwogICAgICAgICAgY3R4LmFkZElzc3VlKHsgY29kZTogImN1c3RvbSIsIC4uLnAyLCBmYXRhbDogX2ZhdGFsIH0pOwogICAgICAgIH0KICAgICAgfSk7CiAgICByZXR1cm4gWm9kQW55LmNyZWF0ZSgpOwogIH0KICBjb25zdCBsYXRlID0gewogICAgb2JqZWN0OiBab2RPYmplY3QubGF6eWNyZWF0ZQogIH07CiAgdmFyIFpvZEZpcnN0UGFydHlUeXBlS2luZDsKICAoZnVuY3Rpb24oWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMikgewogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kU3RyaW5nIl0gPSAiWm9kU3RyaW5nIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZE51bWJlciJdID0gIlpvZE51bWJlciI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2ROYU4iXSA9ICJab2ROYU4iOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kQmlnSW50Il0gPSAiWm9kQmlnSW50IjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZEJvb2xlYW4iXSA9ICJab2RCb29sZWFuIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZERhdGUiXSA9ICJab2REYXRlIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZFN5bWJvbCJdID0gIlpvZFN5bWJvbCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RVbmRlZmluZWQiXSA9ICJab2RVbmRlZmluZWQiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kTnVsbCJdID0gIlpvZE51bGwiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kQW55Il0gPSAiWm9kQW55IjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZFVua25vd24iXSA9ICJab2RVbmtub3duIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZE5ldmVyIl0gPSAiWm9kTmV2ZXIiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kVm9pZCJdID0gIlpvZFZvaWQiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kQXJyYXkiXSA9ICJab2RBcnJheSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RPYmplY3QiXSA9ICJab2RPYmplY3QiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kVW5pb24iXSA9ICJab2RVbmlvbiI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2REaXNjcmltaW5hdGVkVW5pb24iXSA9ICJab2REaXNjcmltaW5hdGVkVW5pb24iOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kSW50ZXJzZWN0aW9uIl0gPSAiWm9kSW50ZXJzZWN0aW9uIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZFR1cGxlIl0gPSAiWm9kVHVwbGUiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kUmVjb3JkIl0gPSAiWm9kUmVjb3JkIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZE1hcCJdID0gIlpvZE1hcCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RTZXQiXSA9ICJab2RTZXQiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kRnVuY3Rpb24iXSA9ICJab2RGdW5jdGlvbiI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RMYXp5Il0gPSAiWm9kTGF6eSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RMaXRlcmFsIl0gPSAiWm9kTGl0ZXJhbCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RFbnVtIl0gPSAiWm9kRW51bSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RFZmZlY3RzIl0gPSAiWm9kRWZmZWN0cyI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2ROYXRpdmVFbnVtIl0gPSAiWm9kTmF0aXZlRW51bSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RPcHRpb25hbCJdID0gIlpvZE9wdGlvbmFsIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZE51bGxhYmxlIl0gPSAiWm9kTnVsbGFibGUiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kRGVmYXVsdCJdID0gIlpvZERlZmF1bHQiOwogICAgWm9kRmlyc3RQYXJ0eVR5cGVLaW5kMlsiWm9kQ2F0Y2giXSA9ICJab2RDYXRjaCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RQcm9taXNlIl0gPSAiWm9kUHJvbWlzZSI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RCcmFuZGVkIl0gPSAiWm9kQnJhbmRlZCI7CiAgICBab2RGaXJzdFBhcnR5VHlwZUtpbmQyWyJab2RQaXBlbGluZSJdID0gIlpvZFBpcGVsaW5lIjsKICAgIFpvZEZpcnN0UGFydHlUeXBlS2luZDJbIlpvZFJlYWRvbmx5Il0gPSAiWm9kUmVhZG9ubHkiOwogIH0pKFpvZEZpcnN0UGFydHlUeXBlS2luZCB8fCAoWm9kRmlyc3RQYXJ0eVR5cGVLaW5kID0ge30pKTsKICBjb25zdCBpbnN0YW5jZU9mVHlwZSA9IChjbHMsIHBhcmFtcyA9IHsKICAgIG1lc3NhZ2U6IGBJbnB1dCBub3QgaW5zdGFuY2Ugb2YgJHtjbHMubmFtZX1gCiAgfSkgPT4gY3VzdG9tKChkYXRhKSA9PiBkYXRhIGluc3RhbmNlb2YgY2xzLCBwYXJhbXMpOwogIGNvbnN0IHN0cmluZ1R5cGUgPSBab2RTdHJpbmcuY3JlYXRlOwogIGNvbnN0IG51bWJlclR5cGUgPSBab2ROdW1iZXIuY3JlYXRlOwogIGNvbnN0IG5hblR5cGUgPSBab2ROYU4uY3JlYXRlOwogIGNvbnN0IGJpZ0ludFR5cGUgPSBab2RCaWdJbnQuY3JlYXRlOwogIGNvbnN0IGJvb2xlYW5UeXBlID0gWm9kQm9vbGVhbi5jcmVhdGU7CiAgY29uc3QgZGF0ZVR5cGUgPSBab2REYXRlLmNyZWF0ZTsKICBjb25zdCBzeW1ib2xUeXBlID0gWm9kU3ltYm9sLmNyZWF0ZTsKICBjb25zdCB1bmRlZmluZWRUeXBlID0gWm9kVW5kZWZpbmVkLmNyZWF0ZTsKICBjb25zdCBudWxsVHlwZSA9IFpvZE51bGwuY3JlYXRlOwogIGNvbnN0IGFueVR5cGUgPSBab2RBbnkuY3JlYXRlOwogIGNvbnN0IHVua25vd25UeXBlID0gWm9kVW5rbm93bi5jcmVhdGU7CiAgY29uc3QgbmV2ZXJUeXBlID0gWm9kTmV2ZXIuY3JlYXRlOwogIGNvbnN0IHZvaWRUeXBlID0gWm9kVm9pZC5jcmVhdGU7CiAgY29uc3QgYXJyYXlUeXBlID0gWm9kQXJyYXkuY3JlYXRlOwogIGNvbnN0IG9iamVjdFR5cGUgPSBab2RPYmplY3QuY3JlYXRlOwogIGNvbnN0IHN0cmljdE9iamVjdFR5cGUgPSBab2RPYmplY3Quc3RyaWN0Q3JlYXRlOwogIGNvbnN0IHVuaW9uVHlwZSA9IFpvZFVuaW9uLmNyZWF0ZTsKICBjb25zdCBkaXNjcmltaW5hdGVkVW5pb25UeXBlID0gWm9kRGlzY3JpbWluYXRlZFVuaW9uLmNyZWF0ZTsKICBjb25zdCBpbnRlcnNlY3Rpb25UeXBlID0gWm9kSW50ZXJzZWN0aW9uLmNyZWF0ZTsKICBjb25zdCB0dXBsZVR5cGUgPSBab2RUdXBsZS5jcmVhdGU7CiAgY29uc3QgcmVjb3JkVHlwZSA9IFpvZFJlY29yZC5jcmVhdGU7CiAgY29uc3QgbWFwVHlwZSA9IFpvZE1hcC5jcmVhdGU7CiAgY29uc3Qgc2V0VHlwZSA9IFpvZFNldC5jcmVhdGU7CiAgY29uc3QgZnVuY3Rpb25UeXBlID0gWm9kRnVuY3Rpb24uY3JlYXRlOwogIGNvbnN0IGxhenlUeXBlID0gWm9kTGF6eS5jcmVhdGU7CiAgY29uc3QgbGl0ZXJhbFR5cGUgPSBab2RMaXRlcmFsLmNyZWF0ZTsKICBjb25zdCBlbnVtVHlwZSA9IFpvZEVudW0uY3JlYXRlOwogIGNvbnN0IG5hdGl2ZUVudW1UeXBlID0gWm9kTmF0aXZlRW51bS5jcmVhdGU7CiAgY29uc3QgcHJvbWlzZVR5cGUgPSBab2RQcm9taXNlLmNyZWF0ZTsKICBjb25zdCBlZmZlY3RzVHlwZSA9IFpvZEVmZmVjdHMuY3JlYXRlOwogIGNvbnN0IG9wdGlvbmFsVHlwZSA9IFpvZE9wdGlvbmFsLmNyZWF0ZTsKICBjb25zdCBudWxsYWJsZVR5cGUgPSBab2ROdWxsYWJsZS5jcmVhdGU7CiAgY29uc3QgcHJlcHJvY2Vzc1R5cGUgPSBab2RFZmZlY3RzLmNyZWF0ZVdpdGhQcmVwcm9jZXNzOwogIGNvbnN0IHBpcGVsaW5lVHlwZSA9IFpvZFBpcGVsaW5lLmNyZWF0ZTsKICBjb25zdCBvc3RyaW5nID0gKCkgPT4gc3RyaW5nVHlwZSgpLm9wdGlvbmFsKCk7CiAgY29uc3Qgb251bWJlciA9ICgpID0+IG51bWJlclR5cGUoKS5vcHRpb25hbCgpOwogIGNvbnN0IG9ib29sZWFuID0gKCkgPT4gYm9vbGVhblR5cGUoKS5vcHRpb25hbCgpOwogIGNvbnN0IGNvZXJjZSA9IHsKICAgIHN0cmluZzogKGFyZykgPT4gWm9kU3RyaW5nLmNyZWF0ZSh7IC4uLmFyZywgY29lcmNlOiB0cnVlIH0pLAogICAgbnVtYmVyOiAoYXJnKSA9PiBab2ROdW1iZXIuY3JlYXRlKHsgLi4uYXJnLCBjb2VyY2U6IHRydWUgfSksCiAgICBib29sZWFuOiAoYXJnKSA9PiBab2RCb29sZWFuLmNyZWF0ZSh7CiAgICAgIC4uLmFyZywKICAgICAgY29lcmNlOiB0cnVlCiAgICB9KSwKICAgIGJpZ2ludDogKGFyZykgPT4gWm9kQmlnSW50LmNyZWF0ZSh7IC4uLmFyZywgY29lcmNlOiB0cnVlIH0pLAogICAgZGF0ZTogKGFyZykgPT4gWm9kRGF0ZS5jcmVhdGUoeyAuLi5hcmcsIGNvZXJjZTogdHJ1ZSB9KQogIH07CiAgY29uc3QgTkVWRVIgPSBJTlZBTElEOwogIHZhciB6JDEgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmZyZWV6ZSh7CiAgICBfX3Byb3RvX186IG51bGwsCiAgICBkZWZhdWx0RXJyb3JNYXA6IGVycm9yTWFwLAogICAgc2V0RXJyb3JNYXAsCiAgICBnZXRFcnJvck1hcCwKICAgIG1ha2VJc3N1ZSwKICAgIEVNUFRZX1BBVEgsCiAgICBhZGRJc3N1ZVRvQ29udGV4dCwKICAgIFBhcnNlU3RhdHVzLAogICAgSU5WQUxJRCwKICAgIERJUlRZLAogICAgT0ssCiAgICBpc0Fib3J0ZWQsCiAgICBpc0RpcnR5LAogICAgaXNWYWxpZCwKICAgIGlzQXN5bmMsCiAgICBnZXQgdXRpbCgpIHsKICAgICAgcmV0dXJuIHV0aWw7CiAgICB9LAogICAgZ2V0IG9iamVjdFV0aWwoKSB7CiAgICAgIHJldHVybiBvYmplY3RVdGlsOwogICAgfSwKICAgIFpvZFBhcnNlZFR5cGUsCiAgICBnZXRQYXJzZWRUeXBlLAogICAgWm9kVHlwZSwKICAgIGRhdGV0aW1lUmVnZXgsCiAgICBab2RTdHJpbmcsCiAgICBab2ROdW1iZXIsCiAgICBab2RCaWdJbnQsCiAgICBab2RCb29sZWFuLAogICAgWm9kRGF0ZSwKICAgIFpvZFN5bWJvbCwKICAgIFpvZFVuZGVmaW5lZCwKICAgIFpvZE51bGwsCiAgICBab2RBbnksCiAgICBab2RVbmtub3duLAogICAgWm9kTmV2ZXIsCiAgICBab2RWb2lkLAogICAgWm9kQXJyYXksCiAgICBab2RPYmplY3QsCiAgICBab2RVbmlvbiwKICAgIFpvZERpc2NyaW1pbmF0ZWRVbmlvbiwKICAgIFpvZEludGVyc2VjdGlvbiwKICAgIFpvZFR1cGxlLAogICAgWm9kUmVjb3JkLAogICAgWm9kTWFwLAogICAgWm9kU2V0LAogICAgWm9kRnVuY3Rpb24sCiAgICBab2RMYXp5LAogICAgWm9kTGl0ZXJhbCwKICAgIFpvZEVudW0sCiAgICBab2ROYXRpdmVFbnVtLAogICAgWm9kUHJvbWlzZSwKICAgIFpvZEVmZmVjdHMsCiAgICBab2RUcmFuc2Zvcm1lcjogWm9kRWZmZWN0cywKICAgIFpvZE9wdGlvbmFsLAogICAgWm9kTnVsbGFibGUsCiAgICBab2REZWZhdWx0LAogICAgWm9kQ2F0Y2gsCiAgICBab2ROYU4sCiAgICBCUkFORCwKICAgIFpvZEJyYW5kZWQsCiAgICBab2RQaXBlbGluZSwKICAgIFpvZFJlYWRvbmx5LAogICAgY3VzdG9tLAogICAgU2NoZW1hOiBab2RUeXBlLAogICAgWm9kU2NoZW1hOiBab2RUeXBlLAogICAgbGF0ZSwKICAgIGdldCBab2RGaXJzdFBhcnR5VHlwZUtpbmQoKSB7CiAgICAgIHJldHVybiBab2RGaXJzdFBhcnR5VHlwZUtpbmQ7CiAgICB9LAogICAgY29lcmNlLAogICAgYW55OiBhbnlUeXBlLAogICAgYXJyYXk6IGFycmF5VHlwZSwKICAgIGJpZ2ludDogYmlnSW50VHlwZSwKICAgIGJvb2xlYW46IGJvb2xlYW5UeXBlLAogICAgZGF0ZTogZGF0ZVR5cGUsCiAgICBkaXNjcmltaW5hdGVkVW5pb246IGRpc2NyaW1pbmF0ZWRVbmlvblR5cGUsCiAgICBlZmZlY3Q6IGVmZmVjdHNUeXBlLAogICAgImVudW0iOiBlbnVtVHlwZSwKICAgICJmdW5jdGlvbiI6IGZ1bmN0aW9uVHlwZSwKICAgICJpbnN0YW5jZW9mIjogaW5zdGFuY2VPZlR5cGUsCiAgICBpbnRlcnNlY3Rpb246IGludGVyc2VjdGlvblR5cGUsCiAgICBsYXp5OiBsYXp5VHlwZSwKICAgIGxpdGVyYWw6IGxpdGVyYWxUeXBlLAogICAgbWFwOiBtYXBUeXBlLAogICAgbmFuOiBuYW5UeXBlLAogICAgbmF0aXZlRW51bTogbmF0aXZlRW51bVR5cGUsCiAgICBuZXZlcjogbmV2ZXJUeXBlLAogICAgIm51bGwiOiBudWxsVHlwZSwKICAgIG51bGxhYmxlOiBudWxsYWJsZVR5cGUsCiAgICBudW1iZXI6IG51bWJlclR5cGUsCiAgICBvYmplY3Q6IG9iamVjdFR5cGUsCiAgICBvYm9vbGVhbiwKICAgIG9udW1iZXIsCiAgICBvcHRpb25hbDogb3B0aW9uYWxUeXBlLAogICAgb3N0cmluZywKICAgIHBpcGVsaW5lOiBwaXBlbGluZVR5cGUsCiAgICBwcmVwcm9jZXNzOiBwcmVwcm9jZXNzVHlwZSwKICAgIHByb21pc2U6IHByb21pc2VUeXBlLAogICAgcmVjb3JkOiByZWNvcmRUeXBlLAogICAgc2V0OiBzZXRUeXBlLAogICAgc3RyaWN0T2JqZWN0OiBzdHJpY3RPYmplY3RUeXBlLAogICAgc3RyaW5nOiBzdHJpbmdUeXBlLAogICAgc3ltYm9sOiBzeW1ib2xUeXBlLAogICAgdHJhbnNmb3JtZXI6IGVmZmVjdHNUeXBlLAogICAgdHVwbGU6IHR1cGxlVHlwZSwKICAgICJ1bmRlZmluZWQiOiB1bmRlZmluZWRUeXBlLAogICAgdW5pb246IHVuaW9uVHlwZSwKICAgIHVua25vd246IHVua25vd25UeXBlLAogICAgInZvaWQiOiB2b2lkVHlwZSwKICAgIE5FVkVSLAogICAgWm9kSXNzdWVDb2RlLAogICAgcXVvdGVsZXNzSnNvbiwKICAgIFpvZEVycm9yCiAgfSk7CiAgeiQxLm9iamVjdCh7CiAgICBudWNsZW90aWRlU2VxdWVuY2VzOiB6JDEuYXJyYXkoCiAgICAgIHokMS5vYmplY3QoewogICAgICAgIG5hbWU6IHokMS5zdHJpbmcoKSwKICAgICAgICBzZXF1ZW5jZTogeiQxLnN0cmluZygpCiAgICAgIH0pCiAgICApLAogICAgZ2VuZXM6IHokMS5hcnJheSgKICAgICAgeiQxLm9iamVjdCh7CiAgICAgICAgbmFtZTogeiQxLnN0cmluZygpLAogICAgICAgIHNlcXVlbmNlOiB6JDEuc3RyaW5nKCkKICAgICAgfSkKICAgICkKICB9KTsKICBjb25zdCBvcmRlckJ5VHlwZSA9IHokMS5lbnVtKFsiYXNjZW5kaW5nIiwgImRlc2NlbmRpbmciXSk7CiAgY29uc3Qgb3JkZXJCeSA9IHokMS5vYmplY3QoewogICAgZmllbGQ6IHokMS5zdHJpbmcoKSwKICAgIHR5cGU6IG9yZGVyQnlUeXBlCiAgfSk7CiAgY29uc3QgbGFwaXNCYXNlUmVxdWVzdCA9IHokMS5vYmplY3QoewogICAgbGltaXQ6IHokMS5udW1iZXIoKS5vcHRpb25hbCgpLAogICAgb2Zmc2V0OiB6JDEubnVtYmVyKCkub3B0aW9uYWwoKSwKICAgIGZpZWxkczogeiQxLmFycmF5KHokMS5zdHJpbmcoKSkub3B0aW9uYWwoKSwKICAgIG9yZGVyQnk6IHokMS5hcnJheShvcmRlckJ5KS5vcHRpb25hbCgpCiAgfSkuY2F0Y2hhbGwoeiQxLnVuaW9uKFt6JDEuYm9vbGVhbigpLCB6JDEudW5kZWZpbmVkKCksIHokMS5zdHJpbmcoKSwgeiQxLm51bWJlcigpLCB6JDEubnVsbCgpLCB6JDEuYXJyYXkoeiQxLnN0cmluZygpKV0pKTsKICBsYXBpc0Jhc2VSZXF1ZXN0LmV4dGVuZCh7IG1pblByb3BvcnRpb246IHokMS5udW1iZXIoKS5vcHRpb25hbCgpIH0pOwogIGNvbnN0IG11dGF0aW9uUHJvcG9ydGlvbkNvdW50ID0geiQxLm9iamVjdCh7CiAgICBtdXRhdGlvbjogeiQxLnN0cmluZygpLAogICAgcHJvcG9ydGlvbjogeiQxLm51bWJlcigpLAogICAgY291bnQ6IHokMS5udW1iZXIoKSwKICAgIHNlcXVlbmNlTmFtZTogeiQxLnVuaW9uKFt6JDEuc3RyaW5nKCksIHokMS5udWxsKCldKSwKICAgIG11dGF0aW9uRnJvbTogeiQxLnN0cmluZygpLAogICAgbXV0YXRpb25UbzogeiQxLnN0cmluZygpLAogICAgcG9zaXRpb246IHokMS5udW1iZXIoKQogIH0pOwogIGNvbnN0IG11dGF0aW9uc1Jlc3BvbnNlID0gbWFrZUxhcGlzUmVzcG9uc2UoeiQxLmFycmF5KG11dGF0aW9uUHJvcG9ydGlvbkNvdW50KSk7CiAgY29uc3QgaW5zZXJ0aW9uQ291bnQgPSB6JDEub2JqZWN0KHsKICAgIGluc2VydGlvbjogeiQxLnN0cmluZygpLAogICAgY291bnQ6IHokMS5udW1iZXIoKSwKICAgIGluc2VydGVkU3ltYm9sczogeiQxLnN0cmluZygpLAogICAgcG9zaXRpb246IHokMS5udW1iZXIoKSwKICAgIHNlcXVlbmNlTmFtZTogeiQxLnVuaW9uKFt6JDEuc3RyaW5nKCksIHokMS5udWxsKCldKQogIH0pOwogIG1ha2VMYXBpc1Jlc3BvbnNlKHokMS5hcnJheShpbnNlcnRpb25Db3VudCkpOwogIGNvbnN0IGFnZ3JlZ2F0ZWRJdGVtID0geiQxLm9iamVjdCh7IGNvdW50OiB6JDEubnVtYmVyKCkgfSkuY2F0Y2hhbGwoeiQxLnVuaW9uKFt6JDEuc3RyaW5nKCksIHokMS5udW1iZXIoKSwgeiQxLm51bGwoKV0pKTsKICBjb25zdCBhZ2dyZWdhdGVkUmVzcG9uc2UgPSBtYWtlTGFwaXNSZXNwb25zZSh6JDEuYXJyYXkoYWdncmVnYXRlZEl0ZW0pKTsKICBmdW5jdGlvbiBtYWtlTGFwaXNSZXNwb25zZShkYXRhKSB7CiAgICByZXR1cm4geiQxLm9iamVjdCh7CiAgICAgIGRhdGEKICAgIH0pOwogIH0KICBjb25zdCBwcm9ibGVtRGV0YWlsID0geiQxLm9iamVjdCh7CiAgICB0aXRsZTogeiQxLnN0cmluZygpLm9wdGlvbmFsKCksCiAgICBzdGF0dXM6IHokMS5udW1iZXIoKSwKICAgIGRldGFpbDogeiQxLnN0cmluZygpLm9wdGlvbmFsKCksCiAgICB0eXBlOiB6JDEuc3RyaW5nKCksCiAgICBpbnN0YW5jZTogeiQxLnN0cmluZygpLm9wdGlvbmFsKCkKICB9KTsKICBjb25zdCBsYXBpc0Vycm9yID0geiQxLm9iamVjdCh7CiAgICBlcnJvcjogcHJvYmxlbURldGFpbAogIH0pOwogIGNsYXNzIFVua25vd25MYXBpc0Vycm9yIGV4dGVuZHMgRXJyb3IgewogICAgY29uc3RydWN0b3IobWVzc2FnZSwgc3RhdHVzLCByZXF1ZXN0ZWREYXRhKSB7CiAgICAgIHN1cGVyKG1lc3NhZ2UpOwogICAgICB0aGlzLnN0YXR1cyA9IHN0YXR1czsKICAgICAgdGhpcy5yZXF1ZXN0ZWREYXRhID0gcmVxdWVzdGVkRGF0YTsKICAgICAgdGhpcy5uYW1lID0gIlVua25vd25MYXBpc0Vycm9yIjsKICAgIH0KICB9CiAgY2xhc3MgTGFwaXNFcnJvciBleHRlbmRzIEVycm9yIHsKICAgIGNvbnN0cnVjdG9yKG1lc3NhZ2UsIHN0YXR1cywgcHJvYmxlbURldGFpbDIsIHJlcXVlc3RlZERhdGEpIHsKICAgICAgc3VwZXIobWVzc2FnZSk7CiAgICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzOwogICAgICB0aGlzLnByb2JsZW1EZXRhaWwgPSBwcm9ibGVtRGV0YWlsMjsKICAgICAgdGhpcy5yZXF1ZXN0ZWREYXRhID0gcmVxdWVzdGVkRGF0YTsKICAgICAgdGhpcy5uYW1lID0gIkxhcGlzRXJyb3IiOwogICAgfQogIH0KICBhc3luYyBmdW5jdGlvbiBmZXRjaEFnZ3JlZ2F0ZWQobGFwaXNVcmwsIGJvZHksIHNpZ25hbCkgewogICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjYWxsTGFwaXMoCiAgICAgIGFnZ3JlZ2F0ZWRFbmRwb2ludChsYXBpc1VybCksCiAgICAgIHsKICAgICAgICBtZXRob2Q6ICJQT1NUIiwKICAgICAgICBoZWFkZXJzOiB7CiAgICAgICAgICAiQ29udGVudC1UeXBlIjogImFwcGxpY2F0aW9uL2pzb24iCiAgICAgICAgfSwKICAgICAgICBib2R5OiBKU09OLnN0cmluZ2lmeShib2R5KSwKICAgICAgICBzaWduYWwKICAgICAgfSwKICAgICAgImFnZ3JlZ2F0ZWQgZGF0YSIKICAgICk7CiAgICByZXR1cm4gYWdncmVnYXRlZFJlc3BvbnNlLnBhcnNlKGF3YWl0IHJlc3BvbnNlLmpzb24oKSk7CiAgfQogIGFzeW5jIGZ1bmN0aW9uIGZldGNoU3Vic3RpdHV0aW9uc09yRGVsZXRpb25zKGxhcGlzVXJsLCBib2R5LCBzZXF1ZW5jZVR5cGUsIHNpZ25hbCkgewogICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjYWxsTGFwaXMoCiAgICAgIHN1YnN0aXR1dGlvbnNPckRlbGV0aW9uc0VuZHBvaW50KGxhcGlzVXJsLCBzZXF1ZW5jZVR5cGUpLAogICAgICB7CiAgICAgICAgbWV0aG9kOiAiUE9TVCIsCiAgICAgICAgaGVhZGVyczogewogICAgICAgICAgIkNvbnRlbnQtVHlwZSI6ICJhcHBsaWNhdGlvbi9qc29uIgogICAgICAgIH0sCiAgICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoYm9keSksCiAgICAgICAgc2lnbmFsCiAgICAgIH0sCiAgICAgIGAke3NlcXVlbmNlVHlwZX0gbXV0YXRpb25zYAogICAgKTsKICAgIHJldHVybiBtdXRhdGlvbnNSZXNwb25zZS5wYXJzZShhd2FpdCByZXNwb25zZS5qc29uKCkpOwogIH0KICBhc3luYyBmdW5jdGlvbiBjYWxsTGFwaXMoaW5wdXQsIGluaXQsIHJlcXVlc3RlZERhdGFOYW1lKSB7CiAgICB0cnkgewogICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKGlucHV0LCBpbml0KTsKICAgICAgYXdhaXQgaGFuZGxlRXJyb3JzKHJlc3BvbnNlLCByZXF1ZXN0ZWREYXRhTmFtZSk7CiAgICAgIHJldHVybiByZXNwb25zZTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IGAke2Vycm9yfWA7CiAgICAgIHRocm93IG5ldyBVbmtub3duTGFwaXNFcnJvcihgRmFpbGVkIHRvIGNvbm5lY3QgdG8gTEFQSVM6ICR7bWVzc2FnZX1gLCA1MDAsIHJlcXVlc3RlZERhdGFOYW1lKTsKICAgIH0KICB9CiAgY29uc3QgaGFuZGxlRXJyb3JzID0gYXN5bmMgKHJlc3BvbnNlLCByZXF1ZXN0ZWREYXRhKSA9PiB7CiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7CiAgICAgIGlmIChyZXNwb25zZS5zdGF0dXMgPj0gNDAwICYmIHJlc3BvbnNlLnN0YXR1cyA8IDUwMCkgewogICAgICAgIGNvbnN0IGpzb24gPSBhd2FpdCByZXNwb25zZS5qc29uKCk7CiAgICAgICAgY29uc3QgbGFwaXNFcnJvclJlc3VsdCA9IGxhcGlzRXJyb3Iuc2FmZVBhcnNlKGpzb24pOwogICAgICAgIGlmIChsYXBpc0Vycm9yUmVzdWx0LnN1Y2Nlc3MpIHsKICAgICAgICAgIHRocm93IG5ldyBMYXBpc0Vycm9yKAogICAgICAgICAgICByZXNwb25zZS5zdGF0dXNUZXh0ICsgbGFwaXNFcnJvclJlc3VsdC5kYXRhLmVycm9yLmRldGFpbCwKICAgICAgICAgICAgcmVzcG9uc2Uuc3RhdHVzLAogICAgICAgICAgICBsYXBpc0Vycm9yUmVzdWx0LmRhdGEuZXJyb3IsCiAgICAgICAgICAgIHJlcXVlc3RlZERhdGEKICAgICAgICAgICk7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHByb2JsZW1EZXRhaWxSZXN1bHQgPSBwcm9ibGVtRGV0YWlsLnNhZmVQYXJzZShqc29uKTsKICAgICAgICBpZiAocHJvYmxlbURldGFpbFJlc3VsdC5zdWNjZXNzKSB7CiAgICAgICAgICB0aHJvdyBuZXcgTGFwaXNFcnJvcigKICAgICAgICAgICAgcmVzcG9uc2Uuc3RhdHVzVGV4dCArIHByb2JsZW1EZXRhaWxSZXN1bHQuZGF0YS5kZXRhaWwsCiAgICAgICAgICAgIHJlc3BvbnNlLnN0YXR1cywKICAgICAgICAgICAgcHJvYmxlbURldGFpbFJlc3VsdC5kYXRhLAogICAgICAgICAgICByZXF1ZXN0ZWREYXRhCiAgICAgICAgICApOwogICAgICAgIH0KICAgICAgICB0aHJvdyBuZXcgVW5rbm93bkxhcGlzRXJyb3IoCiAgICAgICAgICBgJHtyZXNwb25zZS5zdGF0dXNUZXh0fTogJHtKU09OLnN0cmluZ2lmeShqc29uKX1gLAogICAgICAgICAgcmVzcG9uc2Uuc3RhdHVzLAogICAgICAgICAgcmVxdWVzdGVkRGF0YQogICAgICAgICk7CiAgICAgIH0KICAgICAgdGhyb3cgbmV3IFVua25vd25MYXBpc0Vycm9yKGAke3Jlc3BvbnNlLnN0YXR1c1RleHR9OiAke3Jlc3BvbnNlLnN0YXR1c31gLCByZXNwb25zZS5zdGF0dXMsIHJlcXVlc3RlZERhdGEpOwogICAgfQogIH07CiAgY29uc3QgYWdncmVnYXRlZEVuZHBvaW50ID0gKGxhcGlzVXJsKSA9PiBgJHtsYXBpc1VybH0vc2FtcGxlL2FnZ3JlZ2F0ZWRgOwogIGNvbnN0IHN1YnN0aXR1dGlvbnNPckRlbGV0aW9uc0VuZHBvaW50ID0gKGxhcGlzVXJsLCBzZXF1ZW5jZVR5cGUpID0+IHsKICAgIHJldHVybiBzZXF1ZW5jZVR5cGUgPT09ICJhbWlubyBhY2lkIiA/IGAke2xhcGlzVXJsfS9zYW1wbGUvYW1pbm9BY2lkTXV0YXRpb25zYCA6IGAke2xhcGlzVXJsfS9zYW1wbGUvbnVjbGVvdGlkZU11dGF0aW9uc2A7CiAgfTsKICBjbGFzcyBGZXRjaEFnZ3JlZ2F0ZWRPcGVyYXRvciB7CiAgICBjb25zdHJ1Y3RvcihmaWx0ZXIsIGZpZWxkcyA9IFtdKSB7CiAgICAgIHRoaXMuZmlsdGVyID0gZmlsdGVyOwogICAgICB0aGlzLmZpZWxkcyA9IGZpZWxkczsKICAgIH0KICAgIGFzeW5jIGV2YWx1YXRlKGxhcGlzVXJsLCBzaWduYWwpIHsKICAgICAgY29uc3QgYWdncmVnYXRlZFJlc3BvbnNlMiA9IChhd2FpdCBmZXRjaEFnZ3JlZ2F0ZWQoCiAgICAgICAgbGFwaXNVcmwsCiAgICAgICAgewogICAgICAgICAgLi4udGhpcy5maWx0ZXIsCiAgICAgICAgICBmaWVsZHM6IHRoaXMuZmllbGRzCiAgICAgICAgfSwKICAgICAgICBzaWduYWwKICAgICAgKSkuZGF0YTsKICAgICAgaWYgKGlzRmllbGRzQXJyYXlXaXRoQ291bnQoYWdncmVnYXRlZFJlc3BvbnNlMikpIHsKICAgICAgICByZXR1cm4gewogICAgICAgICAgY29udGVudDogYWdncmVnYXRlZFJlc3BvbnNlMgogICAgICAgIH07CiAgICAgIH0KICAgICAgdGhyb3cgbmV3IEVycm9yKCJBZ2dyZWdhdGVkIHJlc3BvbnNlIGRvZXMgbm90IGhhdmUgY291bnQiKTsKICAgIH0KICB9CiAgZnVuY3Rpb24gaXNGaWVsZHNBcnJheVdpdGhDb3VudChkYXRhKSB7CiAgICByZXR1cm4gZGF0YS5ldmVyeSgoaXRlbSkgPT4gdHlwZW9mIGl0ZW0gPT09ICJvYmplY3QiICYmICJjb3VudCIgaW4gaXRlbSAmJiB0eXBlb2YgaXRlbS5jb3VudCA9PT0gIm51bWJlciIpOwogIH0KICBjbGFzcyBHcm91cEJ5T3BlcmF0b3IgewogICAgY29uc3RydWN0b3IoY2hpbGQsIGZpZWxkLCBhZ2dyZWdhdGUpIHsKICAgICAgdGhpcy5jaGlsZCA9IGNoaWxkOwogICAgICB0aGlzLmZpZWxkID0gZmllbGQ7CiAgICAgIHRoaXMuYWdncmVnYXRlID0gYWdncmVnYXRlOwogICAgfQogICAgYXN5bmMgZXZhbHVhdGUobGFwaXMsIHNpZ25hbCkgewogICAgICBjb25zdCBjaGlsZEV2YWx1YXRlZCA9IGF3YWl0IHRoaXMuY2hpbGQuZXZhbHVhdGUobGFwaXMsIHNpZ25hbCk7CiAgICAgIGNvbnN0IGdyb3VwZWQgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogICAgICBmb3IgKGNvbnN0IHJvdyBvZiBjaGlsZEV2YWx1YXRlZC5jb250ZW50KSB7CiAgICAgICAgY29uc3Qga2V5ID0gcm93W3RoaXMuZmllbGRdOwogICAgICAgIGlmICghZ3JvdXBlZC5oYXMoa2V5KSkgewogICAgICAgICAgZ3JvdXBlZC5zZXQoa2V5LCBbXSk7CiAgICAgICAgfQogICAgICAgIGdyb3VwZWQuZ2V0KGtleSkucHVzaChyb3cpOwogICAgICB9CiAgICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBBcnJheSgpOwogICAgICBmb3IgKGNvbnN0IFssIHZhbHVlc10gb2YgZ3JvdXBlZCkgewogICAgICAgIHJlc3VsdC5wdXNoKHRoaXMuYWdncmVnYXRlKHZhbHVlcykpOwogICAgICB9CiAgICAgIHJldHVybiB7CiAgICAgICAgY29udGVudDogcmVzdWx0CiAgICAgIH07CiAgICB9CiAgfQogIGNsYXNzIEdyb3VwQnlBbmRTdW1PcGVyYXRvciBleHRlbmRzIEdyb3VwQnlPcGVyYXRvciB7CiAgICBjb25zdHJ1Y3RvcihjaGlsZCwgZ3JvdXBCeUZpZWxkLCBzdW1GaWVsZCkgewogICAgICBzdXBlcihjaGlsZCwgZ3JvdXBCeUZpZWxkLCAodmFsdWVzKSA9PiB7CiAgICAgICAgbGV0IG4gPSAwOwogICAgICAgIGZvciAoY29uc3QgdmFsdWUgb2YgdmFsdWVzKSB7CiAgICAgICAgICBuICs9IHZhbHVlW3N1bUZpZWxkXTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIFtncm91cEJ5RmllbGRdOiB2YWx1ZXNbMF1bZ3JvdXBCeUZpZWxkXSwKICAgICAgICAgIFtzdW1GaWVsZF06IG4KICAgICAgICB9OwogICAgICB9KTsKICAgIH0KICB9CiAgY2xhc3MgTWFwT3BlcmF0b3IgewogICAgY29uc3RydWN0b3IoY2hpbGQsIGZ1bmMpIHsKICAgICAgdGhpcy5jaGlsZCA9IGNoaWxkOwogICAgICB0aGlzLmZ1bmMgPSBmdW5jOwogICAgfQogICAgYXN5bmMgZXZhbHVhdGUobGFwaXMsIHNpZ25hbCkgewogICAgICBjb25zdCBjaGlsZEV2YWx1YXRlZCA9IGF3YWl0IHRoaXMuY2hpbGQuZXZhbHVhdGUobGFwaXMsIHNpZ25hbCk7CiAgICAgIHJldHVybiB7CiAgICAgICAgY29udGVudDogY2hpbGRFdmFsdWF0ZWQuY29udGVudC5tYXAodGhpcy5mdW5jKQogICAgICB9OwogICAgfQogIH0KICBjbGFzcyBSZW5hbWVGaWVsZE9wZXJhdG9yIGV4dGVuZHMgTWFwT3BlcmF0b3IgewogICAgY29uc3RydWN0b3IoY2hpbGQsIG9sZEZpZWxkTmFtZSwgbmV3RmllbGROYW1lKSB7CiAgICAgIHN1cGVyKAogICAgICAgIGNoaWxkLAogICAgICAgICh2YWx1ZSkgPT4gKHsKICAgICAgICAgIC4uLnZhbHVlLAogICAgICAgICAgW25ld0ZpZWxkTmFtZV06IHZhbHVlW29sZEZpZWxkTmFtZV0KICAgICAgICB9KQogICAgICApOwogICAgfQogIH0KICBjbGFzcyBTb3J0T3BlcmF0b3IgewogICAgY29uc3RydWN0b3IoY2hpbGQsIGNvbXBhcmVGbikgewogICAgICB0aGlzLmNoaWxkID0gY2hpbGQ7CiAgICAgIHRoaXMuY29tcGFyZUZuID0gY29tcGFyZUZuOwogICAgfQogICAgYXN5bmMgZXZhbHVhdGUobGFwaXMsIHNpZ25hbCkgewogICAgICBjb25zdCBjaGlsZEV2YWx1YXRlZCA9IGF3YWl0IHRoaXMuY2hpbGQuZXZhbHVhdGUobGFwaXMsIHNpZ25hbCk7CiAgICAgIHJldHVybiB7CiAgICAgICAgY29udGVudDogY2hpbGRFdmFsdWF0ZWQuY29udGVudC5zb3J0KHRoaXMuY29tcGFyZUZuKQogICAgICB9OwogICAgfQogIH0KICB2YXIgU0VDT05EU19BX01JTlVURSA9IDYwOwogIHZhciBTRUNPTkRTX0FfSE9VUiA9IFNFQ09ORFNfQV9NSU5VVEUgKiA2MDsKICB2YXIgU0VDT05EU19BX0RBWSA9IFNFQ09ORFNfQV9IT1VSICogMjQ7CiAgdmFyIFNFQ09ORFNfQV9XRUVLID0gU0VDT05EU19BX0RBWSAqIDc7CiAgdmFyIE1JTExJU0VDT05EU19BX1NFQ09ORCA9IDFlMzsKICB2YXIgTUlMTElTRUNPTkRTX0FfTUlOVVRFID0gU0VDT05EU19BX01JTlVURSAqIE1JTExJU0VDT05EU19BX1NFQ09ORDsKICB2YXIgTUlMTElTRUNPTkRTX0FfSE9VUiA9IFNFQ09ORFNfQV9IT1VSICogTUlMTElTRUNPTkRTX0FfU0VDT05EOwogIHZhciBNSUxMSVNFQ09ORFNfQV9EQVkgPSBTRUNPTkRTX0FfREFZICogTUlMTElTRUNPTkRTX0FfU0VDT05EOwogIHZhciBNSUxMSVNFQ09ORFNfQV9XRUVLID0gU0VDT05EU19BX1dFRUsgKiBNSUxMSVNFQ09ORFNfQV9TRUNPTkQ7CiAgdmFyIE1TID0gIm1pbGxpc2Vjb25kIjsKICB2YXIgUyA9ICJzZWNvbmQiOwogIHZhciBNSU4gPSAibWludXRlIjsKICB2YXIgSCA9ICJob3VyIjsKICB2YXIgRCA9ICJkYXkiOwogIHZhciBXID0gIndlZWsiOwogIHZhciBNID0gIm1vbnRoIjsKICB2YXIgUSA9ICJxdWFydGVyIjsKICB2YXIgWSA9ICJ5ZWFyIjsKICB2YXIgREFURSA9ICJkYXRlIjsKICB2YXIgRk9STUFUX0RFRkFVTFQgPSAiWVlZWS1NTS1ERFRISDptbTpzc1oiOwogIHZhciBJTlZBTElEX0RBVEVfU1RSSU5HID0gIkludmFsaWQgRGF0ZSI7CiAgdmFyIFJFR0VYX1BBUlNFID0gL14oXGR7NH0pWy0vXT8oXGR7MSwyfSk/Wy0vXT8oXGR7MCwyfSlbVHRcc10qKFxkezEsMn0pPzo/KFxkezEsMn0pPzo/KFxkezEsMn0pP1suOl0/KFxkKyk/JC87CiAgdmFyIFJFR0VYX0ZPUk1BVCA9IC9cWyhbXlxdXSspXXxZezEsNH18TXsxLDR9fER7MSwyfXxkezEsNH18SHsxLDJ9fGh7MSwyfXxhfEF8bXsxLDJ9fHN7MSwyfXxaezEsMn18U1NTL2c7CiAgdmFyIGVuID0gewogICAgbmFtZTogImVuIiwKICAgIHdlZWtkYXlzOiAiU3VuZGF5X01vbmRheV9UdWVzZGF5X1dlZG5lc2RheV9UaHVyc2RheV9GcmlkYXlfU2F0dXJkYXkiLnNwbGl0KCJfIiksCiAgICBtb250aHM6ICJKYW51YXJ5X0ZlYnJ1YXJ5X01hcmNoX0FwcmlsX01heV9KdW5lX0p1bHlfQXVndXN0X1NlcHRlbWJlcl9PY3RvYmVyX05vdmVtYmVyX0RlY2VtYmVyIi5zcGxpdCgiXyIpLAogICAgb3JkaW5hbDogZnVuY3Rpb24gb3JkaW5hbChuKSB7CiAgICAgIHZhciBzMiA9IFsidGgiLCAic3QiLCAibmQiLCAicmQiXTsKICAgICAgdmFyIHYyID0gbiAlIDEwMDsKICAgICAgcmV0dXJuICJbIiArIG4gKyAoczJbKHYyIC0gMjApICUgMTBdIHx8IHMyW3YyXSB8fCBzMlswXSkgKyAiXSI7CiAgICB9CiAgfTsKICB2YXIgcGFkU3RhcnQgPSBmdW5jdGlvbiBwYWRTdGFydDIoc3RyaW5nLCBsZW5ndGgsIHBhZCkgewogICAgdmFyIHMyID0gU3RyaW5nKHN0cmluZyk7CiAgICBpZiAoIXMyIHx8IHMyLmxlbmd0aCA+PSBsZW5ndGgpIHJldHVybiBzdHJpbmc7CiAgICByZXR1cm4gIiIgKyBBcnJheShsZW5ndGggKyAxIC0gczIubGVuZ3RoKS5qb2luKHBhZCkgKyBzdHJpbmc7CiAgfTsKICB2YXIgcGFkWm9uZVN0ciA9IGZ1bmN0aW9uIHBhZFpvbmVTdHIyKGluc3RhbmNlKSB7CiAgICB2YXIgbmVnTWludXRlcyA9IC1pbnN0YW5jZS51dGNPZmZzZXQoKTsKICAgIHZhciBtaW51dGVzID0gTWF0aC5hYnMobmVnTWludXRlcyk7CiAgICB2YXIgaG91ck9mZnNldCA9IE1hdGguZmxvb3IobWludXRlcyAvIDYwKTsKICAgIHZhciBtaW51dGVPZmZzZXQgPSBtaW51dGVzICUgNjA7CiAgICByZXR1cm4gKG5lZ01pbnV0ZXMgPD0gMCA/ICIrIiA6ICItIikgKyBwYWRTdGFydChob3VyT2Zmc2V0LCAyLCAiMCIpICsgIjoiICsgcGFkU3RhcnQobWludXRlT2Zmc2V0LCAyLCAiMCIpOwogIH07CiAgdmFyIG1vbnRoRGlmZiA9IGZ1bmN0aW9uIG1vbnRoRGlmZjIoYTIsIGIpIHsKICAgIGlmIChhMi5kYXRlKCkgPCBiLmRhdGUoKSkgcmV0dXJuIC1tb250aERpZmYyKGIsIGEyKTsKICAgIHZhciB3aG9sZU1vbnRoRGlmZiA9IChiLnllYXIoKSAtIGEyLnllYXIoKSkgKiAxMiArIChiLm1vbnRoKCkgLSBhMi5tb250aCgpKTsKICAgIHZhciBhbmNob3IgPSBhMi5jbG9uZSgpLmFkZCh3aG9sZU1vbnRoRGlmZiwgTSk7CiAgICB2YXIgYzIgPSBiIC0gYW5jaG9yIDwgMDsKICAgIHZhciBhbmNob3IyID0gYTIuY2xvbmUoKS5hZGQod2hvbGVNb250aERpZmYgKyAoYzIgPyAtMSA6IDEpLCBNKTsKICAgIHJldHVybiArKC0od2hvbGVNb250aERpZmYgKyAoYiAtIGFuY2hvcikgLyAoYzIgPyBhbmNob3IgLSBhbmNob3IyIDogYW5jaG9yMiAtIGFuY2hvcikpIHx8IDApOwogIH07CiAgdmFyIGFic0Zsb29yID0gZnVuY3Rpb24gYWJzRmxvb3IyKG4pIHsKICAgIHJldHVybiBuIDwgMCA/IE1hdGguY2VpbChuKSB8fCAwIDogTWF0aC5mbG9vcihuKTsKICB9OwogIHZhciBwcmV0dHlVbml0ID0gZnVuY3Rpb24gcHJldHR5VW5pdDIodTIpIHsKICAgIHZhciBzcGVjaWFsID0gewogICAgICBNLAogICAgICB5OiBZLAogICAgICB3OiBXLAogICAgICBkOiBELAogICAgICBEOiBEQVRFLAogICAgICBoOiBILAogICAgICBtOiBNSU4sCiAgICAgIHM6IFMsCiAgICAgIG1zOiBNUywKICAgICAgUQogICAgfTsKICAgIHJldHVybiBzcGVjaWFsW3UyXSB8fCBTdHJpbmcodTIgfHwgIiIpLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvcyQvLCAiIik7CiAgfTsKICB2YXIgaXNVbmRlZmluZWQgPSBmdW5jdGlvbiBpc1VuZGVmaW5lZDIoczIpIHsKICAgIHJldHVybiBzMiA9PT0gdm9pZCAwOwogIH07CiAgdmFyIFUgPSB7CiAgICBzOiBwYWRTdGFydCwKICAgIHo6IHBhZFpvbmVTdHIsCiAgICBtOiBtb250aERpZmYsCiAgICBhOiBhYnNGbG9vciwKICAgIHA6IHByZXR0eVVuaXQsCiAgICB1OiBpc1VuZGVmaW5lZAogIH07CiAgdmFyIEwgPSAiZW4iOwogIHZhciBMcyA9IHt9OwogIExzW0xdID0gZW47CiAgdmFyIElTX0RBWUpTID0gIiRpc0RheWpzT2JqZWN0IjsKICB2YXIgaXNEYXlqcyA9IGZ1bmN0aW9uIGlzRGF5anMyKGQpIHsKICAgIHJldHVybiBkIGluc3RhbmNlb2YgRGF5anMgfHwgISEoZCAmJiBkW0lTX0RBWUpTXSk7CiAgfTsKICB2YXIgcGFyc2VMb2NhbGUgPSBmdW5jdGlvbiBwYXJzZUxvY2FsZTIocHJlc2V0LCBvYmplY3QsIGlzTG9jYWwpIHsKICAgIHZhciBsMjsKICAgIGlmICghcHJlc2V0KSByZXR1cm4gTDsKICAgIGlmICh0eXBlb2YgcHJlc2V0ID09PSAic3RyaW5nIikgewogICAgICB2YXIgcHJlc2V0TG93ZXIgPSBwcmVzZXQudG9Mb3dlckNhc2UoKTsKICAgICAgaWYgKExzW3ByZXNldExvd2VyXSkgewogICAgICAgIGwyID0gcHJlc2V0TG93ZXI7CiAgICAgIH0KICAgICAgaWYgKG9iamVjdCkgewogICAgICAgIExzW3ByZXNldExvd2VyXSA9IG9iamVjdDsKICAgICAgICBsMiA9IHByZXNldExvd2VyOwogICAgICB9CiAgICAgIHZhciBwcmVzZXRTcGxpdCA9IHByZXNldC5zcGxpdCgiLSIpOwogICAgICBpZiAoIWwyICYmIHByZXNldFNwbGl0Lmxlbmd0aCA+IDEpIHsKICAgICAgICByZXR1cm4gcGFyc2VMb2NhbGUyKHByZXNldFNwbGl0WzBdKTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgdmFyIG5hbWUgPSBwcmVzZXQubmFtZTsKICAgICAgTHNbbmFtZV0gPSBwcmVzZXQ7CiAgICAgIGwyID0gbmFtZTsKICAgIH0KICAgIGlmICghaXNMb2NhbCAmJiBsMikgTCA9IGwyOwogICAgcmV0dXJuIGwyIHx8ICFpc0xvY2FsICYmIEw7CiAgfTsKICB2YXIgZGF5anMgPSBmdW5jdGlvbiBkYXlqczIoZGF0ZSwgYzIpIHsKICAgIGlmIChpc0RheWpzKGRhdGUpKSB7CiAgICAgIHJldHVybiBkYXRlLmNsb25lKCk7CiAgICB9CiAgICB2YXIgY2ZnID0gdHlwZW9mIGMyID09PSAib2JqZWN0IiA/IGMyIDoge307CiAgICBjZmcuZGF0ZSA9IGRhdGU7CiAgICBjZmcuYXJncyA9IGFyZ3VtZW50czsKICAgIHJldHVybiBuZXcgRGF5anMoY2ZnKTsKICB9OwogIHZhciB3cmFwcGVyID0gZnVuY3Rpb24gd3JhcHBlcjIoZGF0ZSwgaW5zdGFuY2UpIHsKICAgIHJldHVybiBkYXlqcyhkYXRlLCB7CiAgICAgIGxvY2FsZTogaW5zdGFuY2UuJEwsCiAgICAgIHV0YzogaW5zdGFuY2UuJHUsCiAgICAgIHg6IGluc3RhbmNlLiR4LAogICAgICAkb2Zmc2V0OiBpbnN0YW5jZS4kb2Zmc2V0CiAgICAgIC8vIHRvZG86IHJlZmFjdG9yOyBkbyBub3QgdXNlIHRoaXMuJG9mZnNldCBpbiB5b3UgY29kZQogICAgfSk7CiAgfTsKICB2YXIgVXRpbHMgPSBVOwogIFV0aWxzLmwgPSBwYXJzZUxvY2FsZTsKICBVdGlscy5pID0gaXNEYXlqczsKICBVdGlscy53ID0gd3JhcHBlcjsKICB2YXIgcGFyc2VEYXRlID0gZnVuY3Rpb24gcGFyc2VEYXRlMihjZmcpIHsKICAgIHZhciBkYXRlID0gY2ZnLmRhdGUsIHV0YyA9IGNmZy51dGM7CiAgICBpZiAoZGF0ZSA9PT0gbnVsbCkgcmV0dXJuIC8qIEBfX1BVUkVfXyAqLyBuZXcgRGF0ZShOYU4pOwogICAgaWYgKFV0aWxzLnUoZGF0ZSkpIHJldHVybiAvKiBAX19QVVJFX18gKi8gbmV3IERhdGUoKTsKICAgIGlmIChkYXRlIGluc3RhbmNlb2YgRGF0ZSkgcmV0dXJuIG5ldyBEYXRlKGRhdGUpOwogICAgaWYgKHR5cGVvZiBkYXRlID09PSAic3RyaW5nIiAmJiAhL1okL2kudGVzdChkYXRlKSkgewogICAgICB2YXIgZCA9IGRhdGUubWF0Y2goUkVHRVhfUEFSU0UpOwogICAgICBpZiAoZCkgewogICAgICAgIHZhciBtMiA9IGRbMl0gLSAxIHx8IDA7CiAgICAgICAgdmFyIG1zID0gKGRbN10gfHwgIjAiKS5zdWJzdHJpbmcoMCwgMyk7CiAgICAgICAgaWYgKHV0YykgewogICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKERhdGUuVVRDKGRbMV0sIG0yLCBkWzNdIHx8IDEsIGRbNF0gfHwgMCwgZFs1XSB8fCAwLCBkWzZdIHx8IDAsIG1zKSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXcgRGF0ZShkWzFdLCBtMiwgZFszXSB8fCAxLCBkWzRdIHx8IDAsIGRbNV0gfHwgMCwgZFs2XSB8fCAwLCBtcyk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBuZXcgRGF0ZShkYXRlKTsKICB9OwogIHZhciBEYXlqcyA9IC8qIEBfX1BVUkVfXyAqLyBmdW5jdGlvbigpIHsKICAgIGZ1bmN0aW9uIERheWpzMihjZmcpIHsKICAgICAgdGhpcy4kTCA9IHBhcnNlTG9jYWxlKGNmZy5sb2NhbGUsIG51bGwsIHRydWUpOwogICAgICB0aGlzLnBhcnNlKGNmZyk7CiAgICAgIHRoaXMuJHggPSB0aGlzLiR4IHx8IGNmZy54IHx8IHt9OwogICAgICB0aGlzW0lTX0RBWUpTXSA9IHRydWU7CiAgICB9CiAgICB2YXIgX3Byb3RvID0gRGF5anMyLnByb3RvdHlwZTsKICAgIF9wcm90by5wYXJzZSA9IGZ1bmN0aW9uIHBhcnNlKGNmZykgewogICAgICB0aGlzLiRkID0gcGFyc2VEYXRlKGNmZyk7CiAgICAgIHRoaXMuaW5pdCgpOwogICAgfTsKICAgIF9wcm90by5pbml0ID0gZnVuY3Rpb24gaW5pdCgpIHsKICAgICAgdmFyICRkID0gdGhpcy4kZDsKICAgICAgdGhpcy4keSA9ICRkLmdldEZ1bGxZZWFyKCk7CiAgICAgIHRoaXMuJE0gPSAkZC5nZXRNb250aCgpOwogICAgICB0aGlzLiREID0gJGQuZ2V0RGF0ZSgpOwogICAgICB0aGlzLiRXID0gJGQuZ2V0RGF5KCk7CiAgICAgIHRoaXMuJEggPSAkZC5nZXRIb3VycygpOwogICAgICB0aGlzLiRtID0gJGQuZ2V0TWludXRlcygpOwogICAgICB0aGlzLiRzID0gJGQuZ2V0U2Vjb25kcygpOwogICAgICB0aGlzLiRtcyA9ICRkLmdldE1pbGxpc2Vjb25kcygpOwogICAgfTsKICAgIF9wcm90by4kdXRpbHMgPSBmdW5jdGlvbiAkdXRpbHMoKSB7CiAgICAgIHJldHVybiBVdGlsczsKICAgIH07CiAgICBfcHJvdG8uaXNWYWxpZCA9IGZ1bmN0aW9uIGlzVmFsaWQyKCkgewogICAgICByZXR1cm4gISh0aGlzLiRkLnRvU3RyaW5nKCkgPT09IElOVkFMSURfREFURV9TVFJJTkcpOwogICAgfTsKICAgIF9wcm90by5pc1NhbWUgPSBmdW5jdGlvbiBpc1NhbWUodGhhdCwgdW5pdHMpIHsKICAgICAgdmFyIG90aGVyID0gZGF5anModGhhdCk7CiAgICAgIHJldHVybiB0aGlzLnN0YXJ0T2YodW5pdHMpIDw9IG90aGVyICYmIG90aGVyIDw9IHRoaXMuZW5kT2YodW5pdHMpOwogICAgfTsKICAgIF9wcm90by5pc0FmdGVyID0gZnVuY3Rpb24gaXNBZnRlcih0aGF0LCB1bml0cykgewogICAgICByZXR1cm4gZGF5anModGhhdCkgPCB0aGlzLnN0YXJ0T2YodW5pdHMpOwogICAgfTsKICAgIF9wcm90by5pc0JlZm9yZSA9IGZ1bmN0aW9uIGlzQmVmb3JlKHRoYXQsIHVuaXRzKSB7CiAgICAgIHJldHVybiB0aGlzLmVuZE9mKHVuaXRzKSA8IGRheWpzKHRoYXQpOwogICAgfTsKICAgIF9wcm90by4kZyA9IGZ1bmN0aW9uICRnKGlucHV0LCBnZXQsIHNldCkgewogICAgICBpZiAoVXRpbHMudShpbnB1dCkpIHJldHVybiB0aGlzW2dldF07CiAgICAgIHJldHVybiB0aGlzLnNldChzZXQsIGlucHV0KTsKICAgIH07CiAgICBfcHJvdG8udW5peCA9IGZ1bmN0aW9uIHVuaXgoKSB7CiAgICAgIHJldHVybiBNYXRoLmZsb29yKHRoaXMudmFsdWVPZigpIC8gMWUzKTsKICAgIH07CiAgICBfcHJvdG8udmFsdWVPZiA9IGZ1bmN0aW9uIHZhbHVlT2YoKSB7CiAgICAgIHJldHVybiB0aGlzLiRkLmdldFRpbWUoKTsKICAgIH07CiAgICBfcHJvdG8uc3RhcnRPZiA9IGZ1bmN0aW9uIHN0YXJ0T2YodW5pdHMsIF9zdGFydE9mKSB7CiAgICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICAgIHZhciBpc1N0YXJ0T2YgPSAhVXRpbHMudShfc3RhcnRPZikgPyBfc3RhcnRPZiA6IHRydWU7CiAgICAgIHZhciB1bml0ID0gVXRpbHMucCh1bml0cyk7CiAgICAgIHZhciBpbnN0YW5jZUZhY3RvcnkgPSBmdW5jdGlvbiBpbnN0YW5jZUZhY3RvcnkyKGQsIG0yKSB7CiAgICAgICAgdmFyIGlucyA9IFV0aWxzLncoX3RoaXMuJHUgPyBEYXRlLlVUQyhfdGhpcy4keSwgbTIsIGQpIDogbmV3IERhdGUoX3RoaXMuJHksIG0yLCBkKSwgX3RoaXMpOwogICAgICAgIHJldHVybiBpc1N0YXJ0T2YgPyBpbnMgOiBpbnMuZW5kT2YoRCk7CiAgICAgIH07CiAgICAgIHZhciBpbnN0YW5jZUZhY3RvcnlTZXQgPSBmdW5jdGlvbiBpbnN0YW5jZUZhY3RvcnlTZXQyKG1ldGhvZCwgc2xpY2UpIHsKICAgICAgICB2YXIgYXJndW1lbnRTdGFydCA9IFswLCAwLCAwLCAwXTsKICAgICAgICB2YXIgYXJndW1lbnRFbmQgPSBbMjMsIDU5LCA1OSwgOTk5XTsKICAgICAgICByZXR1cm4gVXRpbHMudyhfdGhpcy50b0RhdGUoKVttZXRob2RdLmFwcGx5KAogICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbGluZSBwcmVmZXItc3ByZWFkCiAgICAgICAgICBfdGhpcy50b0RhdGUoInMiKSwKICAgICAgICAgIChpc1N0YXJ0T2YgPyBhcmd1bWVudFN0YXJ0IDogYXJndW1lbnRFbmQpLnNsaWNlKHNsaWNlKQogICAgICAgICksIF90aGlzKTsKICAgICAgfTsKICAgICAgdmFyICRXID0gdGhpcy4kVywgJE0gPSB0aGlzLiRNLCAkRCA9IHRoaXMuJEQ7CiAgICAgIHZhciB1dGNQYWQgPSAic2V0IiArICh0aGlzLiR1ID8gIlVUQyIgOiAiIik7CiAgICAgIHN3aXRjaCAodW5pdCkgewogICAgICAgIGNhc2UgWToKICAgICAgICAgIHJldHVybiBpc1N0YXJ0T2YgPyBpbnN0YW5jZUZhY3RvcnkoMSwgMCkgOiBpbnN0YW5jZUZhY3RvcnkoMzEsIDExKTsKICAgICAgICBjYXNlIE06CiAgICAgICAgICByZXR1cm4gaXNTdGFydE9mID8gaW5zdGFuY2VGYWN0b3J5KDEsICRNKSA6IGluc3RhbmNlRmFjdG9yeSgwLCAkTSArIDEpOwogICAgICAgIGNhc2UgVzogewogICAgICAgICAgdmFyIHdlZWtTdGFydCA9IHRoaXMuJGxvY2FsZSgpLndlZWtTdGFydCB8fCAwOwogICAgICAgICAgdmFyIGdhcCA9ICgkVyA8IHdlZWtTdGFydCA/ICRXICsgNyA6ICRXKSAtIHdlZWtTdGFydDsKICAgICAgICAgIHJldHVybiBpbnN0YW5jZUZhY3RvcnkoaXNTdGFydE9mID8gJEQgLSBnYXAgOiAkRCArICg2IC0gZ2FwKSwgJE0pOwogICAgICAgIH0KICAgICAgICBjYXNlIEQ6CiAgICAgICAgY2FzZSBEQVRFOgogICAgICAgICAgcmV0dXJuIGluc3RhbmNlRmFjdG9yeVNldCh1dGNQYWQgKyAiSG91cnMiLCAwKTsKICAgICAgICBjYXNlIEg6CiAgICAgICAgICByZXR1cm4gaW5zdGFuY2VGYWN0b3J5U2V0KHV0Y1BhZCArICJNaW51dGVzIiwgMSk7CiAgICAgICAgY2FzZSBNSU46CiAgICAgICAgICByZXR1cm4gaW5zdGFuY2VGYWN0b3J5U2V0KHV0Y1BhZCArICJTZWNvbmRzIiwgMik7CiAgICAgICAgY2FzZSBTOgogICAgICAgICAgcmV0dXJuIGluc3RhbmNlRmFjdG9yeVNldCh1dGNQYWQgKyAiTWlsbGlzZWNvbmRzIiwgMyk7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHJldHVybiB0aGlzLmNsb25lKCk7CiAgICAgIH0KICAgIH07CiAgICBfcHJvdG8uZW5kT2YgPSBmdW5jdGlvbiBlbmRPZihhcmcpIHsKICAgICAgcmV0dXJuIHRoaXMuc3RhcnRPZihhcmcsIGZhbHNlKTsKICAgIH07CiAgICBfcHJvdG8uJHNldCA9IGZ1bmN0aW9uICRzZXQodW5pdHMsIF9pbnQpIHsKICAgICAgdmFyIF9DJEQkQyREQVRFJEMkTSRDJFkkQzsKICAgICAgdmFyIHVuaXQgPSBVdGlscy5wKHVuaXRzKTsKICAgICAgdmFyIHV0Y1BhZCA9ICJzZXQiICsgKHRoaXMuJHUgPyAiVVRDIiA6ICIiKTsKICAgICAgdmFyIG5hbWUgPSAoX0MkRCRDJERBVEUkQyRNJEMkWSRDID0ge30sIF9DJEQkQyREQVRFJEMkTSRDJFkkQ1tEXSA9IHV0Y1BhZCArICJEYXRlIiwgX0MkRCRDJERBVEUkQyRNJEMkWSRDW0RBVEVdID0gdXRjUGFkICsgIkRhdGUiLCBfQyREJEMkREFURSRDJE0kQyRZJENbTV0gPSB1dGNQYWQgKyAiTW9udGgiLCBfQyREJEMkREFURSRDJE0kQyRZJENbWV0gPSB1dGNQYWQgKyAiRnVsbFllYXIiLCBfQyREJEMkREFURSRDJE0kQyRZJENbSF0gPSB1dGNQYWQgKyAiSG91cnMiLCBfQyREJEMkREFURSRDJE0kQyRZJENbTUlOXSA9IHV0Y1BhZCArICJNaW51dGVzIiwgX0MkRCRDJERBVEUkQyRNJEMkWSRDW1NdID0gdXRjUGFkICsgIlNlY29uZHMiLCBfQyREJEMkREFURSRDJE0kQyRZJENbTVNdID0gdXRjUGFkICsgIk1pbGxpc2Vjb25kcyIsIF9DJEQkQyREQVRFJEMkTSRDJFkkQylbdW5pdF07CiAgICAgIHZhciBhcmcgPSB1bml0ID09PSBEID8gdGhpcy4kRCArIChfaW50IC0gdGhpcy4kVykgOiBfaW50OwogICAgICBpZiAodW5pdCA9PT0gTSB8fCB1bml0ID09PSBZKSB7CiAgICAgICAgdmFyIGRhdGUgPSB0aGlzLmNsb25lKCkuc2V0KERBVEUsIDEpOwogICAgICAgIGRhdGUuJGRbbmFtZV0oYXJnKTsKICAgICAgICBkYXRlLmluaXQoKTsKICAgICAgICB0aGlzLiRkID0gZGF0ZS5zZXQoREFURSwgTWF0aC5taW4odGhpcy4kRCwgZGF0ZS5kYXlzSW5Nb250aCgpKSkuJGQ7CiAgICAgIH0gZWxzZSBpZiAobmFtZSkgdGhpcy4kZFtuYW1lXShhcmcpOwogICAgICB0aGlzLmluaXQoKTsKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9OwogICAgX3Byb3RvLnNldCA9IGZ1bmN0aW9uIHNldChzdHJpbmcsIF9pbnQyKSB7CiAgICAgIHJldHVybiB0aGlzLmNsb25lKCkuJHNldChzdHJpbmcsIF9pbnQyKTsKICAgIH07CiAgICBfcHJvdG8uZ2V0ID0gZnVuY3Rpb24gZ2V0KHVuaXQpIHsKICAgICAgcmV0dXJuIHRoaXNbVXRpbHMucCh1bml0KV0oKTsKICAgIH07CiAgICBfcHJvdG8uYWRkID0gZnVuY3Rpb24gYWRkKG51bWJlciwgdW5pdHMpIHsKICAgICAgdmFyIF90aGlzMiA9IHRoaXMsIF9DJE1JTiRDJEgkQyRTJHVuaXQ7CiAgICAgIG51bWJlciA9IE51bWJlcihudW1iZXIpOwogICAgICB2YXIgdW5pdCA9IFV0aWxzLnAodW5pdHMpOwogICAgICB2YXIgaW5zdGFuY2VGYWN0b3J5U2V0ID0gZnVuY3Rpb24gaW5zdGFuY2VGYWN0b3J5U2V0MihuKSB7CiAgICAgICAgdmFyIGQgPSBkYXlqcyhfdGhpczIpOwogICAgICAgIHJldHVybiBVdGlscy53KGQuZGF0ZShkLmRhdGUoKSArIE1hdGgucm91bmQobiAqIG51bWJlcikpLCBfdGhpczIpOwogICAgICB9OwogICAgICBpZiAodW5pdCA9PT0gTSkgewogICAgICAgIHJldHVybiB0aGlzLnNldChNLCB0aGlzLiRNICsgbnVtYmVyKTsKICAgICAgfQogICAgICBpZiAodW5pdCA9PT0gWSkgewogICAgICAgIHJldHVybiB0aGlzLnNldChZLCB0aGlzLiR5ICsgbnVtYmVyKTsKICAgICAgfQogICAgICBpZiAodW5pdCA9PT0gRCkgewogICAgICAgIHJldHVybiBpbnN0YW5jZUZhY3RvcnlTZXQoMSk7CiAgICAgIH0KICAgICAgaWYgKHVuaXQgPT09IFcpIHsKICAgICAgICByZXR1cm4gaW5zdGFuY2VGYWN0b3J5U2V0KDcpOwogICAgICB9CiAgICAgIHZhciBzdGVwID0gKF9DJE1JTiRDJEgkQyRTJHVuaXQgPSB7fSwgX0MkTUlOJEMkSCRDJFMkdW5pdFtNSU5dID0gTUlMTElTRUNPTkRTX0FfTUlOVVRFLCBfQyRNSU4kQyRIJEMkUyR1bml0W0hdID0gTUlMTElTRUNPTkRTX0FfSE9VUiwgX0MkTUlOJEMkSCRDJFMkdW5pdFtTXSA9IE1JTExJU0VDT05EU19BX1NFQ09ORCwgX0MkTUlOJEMkSCRDJFMkdW5pdClbdW5pdF0gfHwgMTsKICAgICAgdmFyIG5leHRUaW1lU3RhbXAgPSB0aGlzLiRkLmdldFRpbWUoKSArIG51bWJlciAqIHN0ZXA7CiAgICAgIHJldHVybiBVdGlscy53KG5leHRUaW1lU3RhbXAsIHRoaXMpOwogICAgfTsKICAgIF9wcm90by5zdWJ0cmFjdCA9IGZ1bmN0aW9uIHN1YnRyYWN0KG51bWJlciwgc3RyaW5nKSB7CiAgICAgIHJldHVybiB0aGlzLmFkZChudW1iZXIgKiAtMSwgc3RyaW5nKTsKICAgIH07CiAgICBfcHJvdG8uZm9ybWF0ID0gZnVuY3Rpb24gZm9ybWF0KGZvcm1hdFN0cikgewogICAgICB2YXIgX3RoaXMzID0gdGhpczsKICAgICAgdmFyIGxvY2FsZSA9IHRoaXMuJGxvY2FsZSgpOwogICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSByZXR1cm4gbG9jYWxlLmludmFsaWREYXRlIHx8IElOVkFMSURfREFURV9TVFJJTkc7CiAgICAgIHZhciBzdHIgPSBmb3JtYXRTdHIgfHwgRk9STUFUX0RFRkFVTFQ7CiAgICAgIHZhciB6b25lU3RyID0gVXRpbHMueih0aGlzKTsKICAgICAgdmFyICRIID0gdGhpcy4kSCwgJG0gPSB0aGlzLiRtLCAkTSA9IHRoaXMuJE07CiAgICAgIHZhciB3ZWVrZGF5cyA9IGxvY2FsZS53ZWVrZGF5cywgbW9udGhzID0gbG9jYWxlLm1vbnRocywgbWVyaWRpZW0gPSBsb2NhbGUubWVyaWRpZW07CiAgICAgIHZhciBnZXRTaG9ydCA9IGZ1bmN0aW9uIGdldFNob3J0MihhcnIsIGluZGV4LCBmdWxsLCBsZW5ndGgpIHsKICAgICAgICByZXR1cm4gYXJyICYmIChhcnJbaW5kZXhdIHx8IGFycihfdGhpczMsIHN0cikpIHx8IGZ1bGxbaW5kZXhdLnNsaWNlKDAsIGxlbmd0aCk7CiAgICAgIH07CiAgICAgIHZhciBnZXQkSCA9IGZ1bmN0aW9uIGdldCRIMihudW0pIHsKICAgICAgICByZXR1cm4gVXRpbHMucygkSCAlIDEyIHx8IDEyLCBudW0sICIwIik7CiAgICAgIH07CiAgICAgIHZhciBtZXJpZGllbUZ1bmMgPSBtZXJpZGllbSB8fCBmdW5jdGlvbihob3VyLCBtaW51dGUsIGlzTG93ZXJjYXNlKSB7CiAgICAgICAgdmFyIG0yID0gaG91ciA8IDEyID8gIkFNIiA6ICJQTSI7CiAgICAgICAgcmV0dXJuIGlzTG93ZXJjYXNlID8gbTIudG9Mb3dlckNhc2UoKSA6IG0yOwogICAgICB9OwogICAgICB2YXIgbWF0Y2hlcyA9IGZ1bmN0aW9uIG1hdGNoZXMyKG1hdGNoKSB7CiAgICAgICAgc3dpdGNoIChtYXRjaCkgewogICAgICAgICAgY2FzZSAiWVkiOgogICAgICAgICAgICByZXR1cm4gU3RyaW5nKF90aGlzMy4keSkuc2xpY2UoLTIpOwogICAgICAgICAgY2FzZSAiWVlZWSI6CiAgICAgICAgICAgIHJldHVybiBVdGlscy5zKF90aGlzMy4keSwgNCwgIjAiKTsKICAgICAgICAgIGNhc2UgIk0iOgogICAgICAgICAgICByZXR1cm4gJE0gKyAxOwogICAgICAgICAgY2FzZSAiTU0iOgogICAgICAgICAgICByZXR1cm4gVXRpbHMucygkTSArIDEsIDIsICIwIik7CiAgICAgICAgICBjYXNlICJNTU0iOgogICAgICAgICAgICByZXR1cm4gZ2V0U2hvcnQobG9jYWxlLm1vbnRoc1Nob3J0LCAkTSwgbW9udGhzLCAzKTsKICAgICAgICAgIGNhc2UgIk1NTU0iOgogICAgICAgICAgICByZXR1cm4gZ2V0U2hvcnQobW9udGhzLCAkTSk7CiAgICAgICAgICBjYXNlICJEIjoKICAgICAgICAgICAgcmV0dXJuIF90aGlzMy4kRDsKICAgICAgICAgIGNhc2UgIkREIjoKICAgICAgICAgICAgcmV0dXJuIFV0aWxzLnMoX3RoaXMzLiRELCAyLCAiMCIpOwogICAgICAgICAgY2FzZSAiZCI6CiAgICAgICAgICAgIHJldHVybiBTdHJpbmcoX3RoaXMzLiRXKTsKICAgICAgICAgIGNhc2UgImRkIjoKICAgICAgICAgICAgcmV0dXJuIGdldFNob3J0KGxvY2FsZS53ZWVrZGF5c01pbiwgX3RoaXMzLiRXLCB3ZWVrZGF5cywgMik7CiAgICAgICAgICBjYXNlICJkZGQiOgogICAgICAgICAgICByZXR1cm4gZ2V0U2hvcnQobG9jYWxlLndlZWtkYXlzU2hvcnQsIF90aGlzMy4kVywgd2Vla2RheXMsIDMpOwogICAgICAgICAgY2FzZSAiZGRkZCI6CiAgICAgICAgICAgIHJldHVybiB3ZWVrZGF5c1tfdGhpczMuJFddOwogICAgICAgICAgY2FzZSAiSCI6CiAgICAgICAgICAgIHJldHVybiBTdHJpbmcoJEgpOwogICAgICAgICAgY2FzZSAiSEgiOgogICAgICAgICAgICByZXR1cm4gVXRpbHMucygkSCwgMiwgIjAiKTsKICAgICAgICAgIGNhc2UgImgiOgogICAgICAgICAgICByZXR1cm4gZ2V0JEgoMSk7CiAgICAgICAgICBjYXNlICJoaCI6CiAgICAgICAgICAgIHJldHVybiBnZXQkSCgyKTsKICAgICAgICAgIGNhc2UgImEiOgogICAgICAgICAgICByZXR1cm4gbWVyaWRpZW1GdW5jKCRILCAkbSwgdHJ1ZSk7CiAgICAgICAgICBjYXNlICJBIjoKICAgICAgICAgICAgcmV0dXJuIG1lcmlkaWVtRnVuYygkSCwgJG0sIGZhbHNlKTsKICAgICAgICAgIGNhc2UgIm0iOgogICAgICAgICAgICByZXR1cm4gU3RyaW5nKCRtKTsKICAgICAgICAgIGNhc2UgIm1tIjoKICAgICAgICAgICAgcmV0dXJuIFV0aWxzLnMoJG0sIDIsICIwIik7CiAgICAgICAgICBjYXNlICJzIjoKICAgICAgICAgICAgcmV0dXJuIFN0cmluZyhfdGhpczMuJHMpOwogICAgICAgICAgY2FzZSAic3MiOgogICAgICAgICAgICByZXR1cm4gVXRpbHMucyhfdGhpczMuJHMsIDIsICIwIik7CiAgICAgICAgICBjYXNlICJTU1MiOgogICAgICAgICAgICByZXR1cm4gVXRpbHMucyhfdGhpczMuJG1zLCAzLCAiMCIpOwogICAgICAgICAgY2FzZSAiWiI6CiAgICAgICAgICAgIHJldHVybiB6b25lU3RyOwogICAgICAgIH0KICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgfTsKICAgICAgcmV0dXJuIHN0ci5yZXBsYWNlKFJFR0VYX0ZPUk1BVCwgZnVuY3Rpb24obWF0Y2gsICQxKSB7CiAgICAgICAgcmV0dXJuICQxIHx8IG1hdGNoZXMobWF0Y2gpIHx8IHpvbmVTdHIucmVwbGFjZSgiOiIsICIiKTsKICAgICAgfSk7CiAgICB9OwogICAgX3Byb3RvLnV0Y09mZnNldCA9IGZ1bmN0aW9uIHV0Y09mZnNldCgpIHsKICAgICAgcmV0dXJuIC1NYXRoLnJvdW5kKHRoaXMuJGQuZ2V0VGltZXpvbmVPZmZzZXQoKSAvIDE1KSAqIDE1OwogICAgfTsKICAgIF9wcm90by5kaWZmID0gZnVuY3Rpb24gZGlmZihpbnB1dCwgdW5pdHMsIF9mbG9hdCkgewogICAgICB2YXIgX3RoaXM0ID0gdGhpczsKICAgICAgdmFyIHVuaXQgPSBVdGlscy5wKHVuaXRzKTsKICAgICAgdmFyIHRoYXQgPSBkYXlqcyhpbnB1dCk7CiAgICAgIHZhciB6b25lRGVsdGEgPSAodGhhdC51dGNPZmZzZXQoKSAtIHRoaXMudXRjT2Zmc2V0KCkpICogTUlMTElTRUNPTkRTX0FfTUlOVVRFOwogICAgICB2YXIgZGlmZjIgPSB0aGlzIC0gdGhhdDsKICAgICAgdmFyIGdldE1vbnRoID0gZnVuY3Rpb24gZ2V0TW9udGgyKCkgewogICAgICAgIHJldHVybiBVdGlscy5tKF90aGlzNCwgdGhhdCk7CiAgICAgIH07CiAgICAgIHZhciByZXN1bHQ7CiAgICAgIHN3aXRjaCAodW5pdCkgewogICAgICAgIGNhc2UgWToKICAgICAgICAgIHJlc3VsdCA9IGdldE1vbnRoKCkgLyAxMjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgTToKICAgICAgICAgIHJlc3VsdCA9IGdldE1vbnRoKCk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFE6CiAgICAgICAgICByZXN1bHQgPSBnZXRNb250aCgpIC8gMzsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVzoKICAgICAgICAgIHJlc3VsdCA9IChkaWZmMiAtIHpvbmVEZWx0YSkgLyBNSUxMSVNFQ09ORFNfQV9XRUVLOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBEOgogICAgICAgICAgcmVzdWx0ID0gKGRpZmYyIC0gem9uZURlbHRhKSAvIE1JTExJU0VDT05EU19BX0RBWTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgSDoKICAgICAgICAgIHJlc3VsdCA9IGRpZmYyIC8gTUlMTElTRUNPTkRTX0FfSE9VUjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgTUlOOgogICAgICAgICAgcmVzdWx0ID0gZGlmZjIgLyBNSUxMSVNFQ09ORFNfQV9NSU5VVEU7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFM6CiAgICAgICAgICByZXN1bHQgPSBkaWZmMiAvIE1JTExJU0VDT05EU19BX1NFQ09ORDsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXN1bHQgPSBkaWZmMjsKICAgICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIHJldHVybiBfZmxvYXQgPyByZXN1bHQgOiBVdGlscy5hKHJlc3VsdCk7CiAgICB9OwogICAgX3Byb3RvLmRheXNJbk1vbnRoID0gZnVuY3Rpb24gZGF5c0luTW9udGgoKSB7CiAgICAgIHJldHVybiB0aGlzLmVuZE9mKE0pLiREOwogICAgfTsKICAgIF9wcm90by4kbG9jYWxlID0gZnVuY3Rpb24gJGxvY2FsZSgpIHsKICAgICAgcmV0dXJuIExzW3RoaXMuJExdOwogICAgfTsKICAgIF9wcm90by5sb2NhbGUgPSBmdW5jdGlvbiBsb2NhbGUocHJlc2V0LCBvYmplY3QpIHsKICAgICAgaWYgKCFwcmVzZXQpIHJldHVybiB0aGlzLiRMOwogICAgICB2YXIgdGhhdCA9IHRoaXMuY2xvbmUoKTsKICAgICAgdmFyIG5leHRMb2NhbGVOYW1lID0gcGFyc2VMb2NhbGUocHJlc2V0LCBvYmplY3QsIHRydWUpOwogICAgICBpZiAobmV4dExvY2FsZU5hbWUpIHRoYXQuJEwgPSBuZXh0TG9jYWxlTmFtZTsKICAgICAgcmV0dXJuIHRoYXQ7CiAgICB9OwogICAgX3Byb3RvLmNsb25lID0gZnVuY3Rpb24gY2xvbmUoKSB7CiAgICAgIHJldHVybiBVdGlscy53KHRoaXMuJGQsIHRoaXMpOwogICAgfTsKICAgIF9wcm90by50b0RhdGUgPSBmdW5jdGlvbiB0b0RhdGUoKSB7CiAgICAgIHJldHVybiBuZXcgRGF0ZSh0aGlzLnZhbHVlT2YoKSk7CiAgICB9OwogICAgX3Byb3RvLnRvSlNPTiA9IGZ1bmN0aW9uIHRvSlNPTigpIHsKICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZCgpID8gdGhpcy50b0lTT1N0cmluZygpIDogbnVsbDsKICAgIH07CiAgICBfcHJvdG8udG9JU09TdHJpbmcgPSBmdW5jdGlvbiB0b0lTT1N0cmluZygpIHsKICAgICAgcmV0dXJuIHRoaXMuJGQudG9JU09TdHJpbmcoKTsKICAgIH07CiAgICBfcHJvdG8udG9TdHJpbmcgPSBmdW5jdGlvbiB0b1N0cmluZygpIHsKICAgICAgcmV0dXJuIHRoaXMuJGQudG9VVENTdHJpbmcoKTsKICAgIH07CiAgICByZXR1cm4gRGF5anMyOwogIH0oKTsKICB2YXIgcHJvdG8gPSBEYXlqcy5wcm90b3R5cGU7CiAgZGF5anMucHJvdG90eXBlID0gcHJvdG87CiAgW1siJG1zIiwgTVNdLCBbIiRzIiwgU10sIFsiJG0iLCBNSU5dLCBbIiRIIiwgSF0sIFsiJFciLCBEXSwgWyIkTSIsIE1dLCBbIiR5IiwgWV0sIFsiJEQiLCBEQVRFXV0uZm9yRWFjaChmdW5jdGlvbihnKSB7CiAgICBwcm90b1tnWzFdXSA9IGZ1bmN0aW9uKGlucHV0KSB7CiAgICAgIHJldHVybiB0aGlzLiRnKGlucHV0LCBnWzBdLCBnWzFdKTsKICAgIH07CiAgfSk7CiAgZGF5anMuZXh0ZW5kID0gZnVuY3Rpb24ocGx1Z2luLCBvcHRpb24pIHsKICAgIGlmICghcGx1Z2luLiRpKSB7CiAgICAgIHBsdWdpbihvcHRpb24sIERheWpzLCBkYXlqcyk7CiAgICAgIHBsdWdpbi4kaSA9IHRydWU7CiAgICB9CiAgICByZXR1cm4gZGF5anM7CiAgfTsKICBkYXlqcy5sb2NhbGUgPSBwYXJzZUxvY2FsZTsKICBkYXlqcy5pc0RheWpzID0gaXNEYXlqczsKICBkYXlqcy51bml4ID0gZnVuY3Rpb24odGltZXN0YW1wKSB7CiAgICByZXR1cm4gZGF5anModGltZXN0YW1wICogMWUzKTsKICB9OwogIGRheWpzLmVuID0gTHNbTF07CiAgZGF5anMuTHMgPSBMczsKICBkYXlqcy5wID0ge307CiAgdmFyIGFkdmFuY2VkRm9ybWF0ID0gZnVuY3Rpb24obywgYzIpIHsKICAgIHZhciBwcm90bzIgPSBjMi5wcm90b3R5cGU7CiAgICB2YXIgb2xkRm9ybWF0ID0gcHJvdG8yLmZvcm1hdDsKICAgIHByb3RvMi5mb3JtYXQgPSBmdW5jdGlvbihmb3JtYXRTdHIpIHsKICAgICAgdmFyIF90aGlzID0gdGhpczsKICAgICAgdmFyIGxvY2FsZSA9IHRoaXMuJGxvY2FsZSgpOwogICAgICBpZiAoIXRoaXMuaXNWYWxpZCgpKSB7CiAgICAgICAgcmV0dXJuIG9sZEZvcm1hdC5iaW5kKHRoaXMpKGZvcm1hdFN0cik7CiAgICAgIH0KICAgICAgdmFyIHV0aWxzID0gdGhpcy4kdXRpbHMoKTsKICAgICAgdmFyIHN0ciA9IGZvcm1hdFN0ciB8fCBGT1JNQVRfREVGQVVMVDsKICAgICAgdmFyIHJlc3VsdCA9IHN0ci5yZXBsYWNlKC9cWyhbXlxdXSspXXxRfHdvfHd3fHd8V1d8V3x6enp8enxnZ2dnfEdHR0d8RG98WHx4fGt7MSwyfXxTL2csIGZ1bmN0aW9uKG1hdGNoKSB7CiAgICAgICAgc3dpdGNoIChtYXRjaCkgewogICAgICAgICAgY2FzZSAiUSI6CiAgICAgICAgICAgIHJldHVybiBNYXRoLmNlaWwoKF90aGlzLiRNICsgMSkgLyAzKTsKICAgICAgICAgIGNhc2UgIkRvIjoKICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS5vcmRpbmFsKF90aGlzLiREKTsKICAgICAgICAgIGNhc2UgImdnZ2ciOgogICAgICAgICAgICByZXR1cm4gX3RoaXMud2Vla1llYXIoKTsKICAgICAgICAgIGNhc2UgIkdHR0ciOgogICAgICAgICAgICByZXR1cm4gX3RoaXMuaXNvV2Vla1llYXIoKTsKICAgICAgICAgIGNhc2UgIndvIjoKICAgICAgICAgICAgcmV0dXJuIGxvY2FsZS5vcmRpbmFsKF90aGlzLndlZWsoKSwgIlciKTsKICAgICAgICAgIGNhc2UgInciOgogICAgICAgICAgY2FzZSAid3ciOgogICAgICAgICAgICByZXR1cm4gdXRpbHMucyhfdGhpcy53ZWVrKCksIG1hdGNoID09PSAidyIgPyAxIDogMiwgIjAiKTsKICAgICAgICAgIGNhc2UgIlciOgogICAgICAgICAgY2FzZSAiV1ciOgogICAgICAgICAgICByZXR1cm4gdXRpbHMucyhfdGhpcy5pc29XZWVrKCksIG1hdGNoID09PSAiVyIgPyAxIDogMiwgIjAiKTsKICAgICAgICAgIGNhc2UgImsiOgogICAgICAgICAgY2FzZSAia2siOgogICAgICAgICAgICByZXR1cm4gdXRpbHMucyhTdHJpbmcoX3RoaXMuJEggPT09IDAgPyAyNCA6IF90aGlzLiRIKSwgbWF0Y2ggPT09ICJrIiA/IDEgOiAyLCAiMCIpOwogICAgICAgICAgY2FzZSAiWCI6CiAgICAgICAgICAgIHJldHVybiBNYXRoLmZsb29yKF90aGlzLiRkLmdldFRpbWUoKSAvIDFlMyk7CiAgICAgICAgICBjYXNlICJ4IjoKICAgICAgICAgICAgcmV0dXJuIF90aGlzLiRkLmdldFRpbWUoKTsKICAgICAgICAgIGNhc2UgInoiOgogICAgICAgICAgICByZXR1cm4gIlsiICsgX3RoaXMub2Zmc2V0TmFtZSgpICsgIl0iOwogICAgICAgICAgY2FzZSAienp6IjoKICAgICAgICAgICAgcmV0dXJuICJbIiArIF90aGlzLm9mZnNldE5hbWUoImxvbmciKSArICJdIjsKICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBtYXRjaDsKICAgICAgICB9CiAgICAgIH0pOwogICAgICByZXR1cm4gb2xkRm9ybWF0LmJpbmQodGhpcykocmVzdWx0KTsKICAgIH07CiAgfTsKICB2YXIgaXNvV2Vla1ByZXR0eVVuaXQgPSAiaXNvd2VlayI7CiAgdmFyIGlzb1dlZWsgPSBmdW5jdGlvbihvLCBjMiwgZCkgewogICAgdmFyIGdldFllYXJGaXJzdFRodXJzZGF5ID0gZnVuY3Rpb24gZ2V0WWVhckZpcnN0VGh1cnNkYXkyKHllYXIsIGlzVXRjKSB7CiAgICAgIHZhciB5ZWFyRmlyc3REYXkgPSAoaXNVdGMgPyBkLnV0YyA6IGQpKCkueWVhcih5ZWFyKS5zdGFydE9mKFkpOwogICAgICB2YXIgYWRkRGlmZkRheXMgPSA0IC0geWVhckZpcnN0RGF5Lmlzb1dlZWtkYXkoKTsKICAgICAgaWYgKHllYXJGaXJzdERheS5pc29XZWVrZGF5KCkgPiA0KSB7CiAgICAgICAgYWRkRGlmZkRheXMgKz0gNzsKICAgICAgfQogICAgICByZXR1cm4geWVhckZpcnN0RGF5LmFkZChhZGREaWZmRGF5cywgRCk7CiAgICB9OwogICAgdmFyIGdldEN1cnJlbnRXZWVrVGh1cnNkYXkgPSBmdW5jdGlvbiBnZXRDdXJyZW50V2Vla1RodXJzZGF5MihpbnMpIHsKICAgICAgcmV0dXJuIGlucy5hZGQoNCAtIGlucy5pc29XZWVrZGF5KCksIEQpOwogICAgfTsKICAgIHZhciBwcm90bzIgPSBjMi5wcm90b3R5cGU7CiAgICBwcm90bzIuaXNvV2Vla1llYXIgPSBmdW5jdGlvbigpIHsKICAgICAgdmFyIG5vd1dlZWtUaHVyc2RheSA9IGdldEN1cnJlbnRXZWVrVGh1cnNkYXkodGhpcyk7CiAgICAgIHJldHVybiBub3dXZWVrVGh1cnNkYXkueWVhcigpOwogICAgfTsKICAgIHByb3RvMi5pc29XZWVrID0gZnVuY3Rpb24od2VlaykgewogICAgICBpZiAoIXRoaXMuJHV0aWxzKCkudSh3ZWVrKSkgewogICAgICAgIHJldHVybiB0aGlzLmFkZCgod2VlayAtIHRoaXMuaXNvV2VlaygpKSAqIDcsIEQpOwogICAgICB9CiAgICAgIHZhciBub3dXZWVrVGh1cnNkYXkgPSBnZXRDdXJyZW50V2Vla1RodXJzZGF5KHRoaXMpOwogICAgICB2YXIgZGlmZldlZWtUaHVyc2RheSA9IGdldFllYXJGaXJzdFRodXJzZGF5KHRoaXMuaXNvV2Vla1llYXIoKSwgdGhpcy4kdSk7CiAgICAgIHJldHVybiBub3dXZWVrVGh1cnNkYXkuZGlmZihkaWZmV2Vla1RodXJzZGF5LCBXKSArIDE7CiAgICB9OwogICAgcHJvdG8yLmlzb1dlZWtkYXkgPSBmdW5jdGlvbih3ZWVrKSB7CiAgICAgIGlmICghdGhpcy4kdXRpbHMoKS51KHdlZWspKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuZGF5KHRoaXMuZGF5KCkgJSA3ID8gd2VlayA6IHdlZWsgLSA3KTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy5kYXkoKSB8fCA3OwogICAgfTsKICAgIHZhciBvbGRTdGFydE9mID0gcHJvdG8yLnN0YXJ0T2Y7CiAgICBwcm90bzIuc3RhcnRPZiA9IGZ1bmN0aW9uKHVuaXRzLCBzdGFydE9mKSB7CiAgICAgIHZhciB1dGlscyA9IHRoaXMuJHV0aWxzKCk7CiAgICAgIHZhciBpc1N0YXJ0T2YgPSAhdXRpbHMudShzdGFydE9mKSA/IHN0YXJ0T2YgOiB0cnVlOwogICAgICB2YXIgdW5pdCA9IHV0aWxzLnAodW5pdHMpOwogICAgICBpZiAodW5pdCA9PT0gaXNvV2Vla1ByZXR0eVVuaXQpIHsKICAgICAgICByZXR1cm4gaXNTdGFydE9mID8gdGhpcy5kYXRlKHRoaXMuZGF0ZSgpIC0gKHRoaXMuaXNvV2Vla2RheSgpIC0gMSkpLnN0YXJ0T2YoImRheSIpIDogdGhpcy5kYXRlKHRoaXMuZGF0ZSgpIC0gMSAtICh0aGlzLmlzb1dlZWtkYXkoKSAtIDEpICsgNykuZW5kT2YoImRheSIpOwogICAgICB9CiAgICAgIHJldHVybiBvbGRTdGFydE9mLmJpbmQodGhpcykodW5pdHMsIHN0YXJ0T2YpOwogICAgfTsKICB9OwogIGRheWpzLmV4dGVuZChpc29XZWVrKTsKICBkYXlqcy5leHRlbmQoYWR2YW5jZWRGb3JtYXQpOwogIGNvbnN0IEZPUk1BVF9JU09fV0VFS19ZRUFSX1dFRUsgPSAiR0dHRy1bV11XVyI7CiAgY29uc3QgX1RlbXBvcmFsQ2FjaGUgPSBjbGFzcyBfVGVtcG9yYWxDYWNoZSB7CiAgICBjb25zdHJ1Y3RvcigpIHsKICAgICAgdGhpcy55ZWFyTW9udGhEYXlDYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgIHRoaXMueWVhcldlZWtDYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgIHRoaXMueWVhck1vbnRoQ2FjaGUgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogICAgICB0aGlzLnllYXJDYWNoZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICB9CiAgICBnZXRZZWFyTW9udGhEYXkoczIpIHsKICAgICAgaWYgKCF0aGlzLnllYXJNb250aERheUNhY2hlLmhhcyhzMikpIHsKICAgICAgICB0aGlzLnllYXJNb250aERheUNhY2hlLnNldChzMiwgWWVhck1vbnRoRGF5Q2xhc3MucGFyc2UoczIsIHRoaXMpKTsKICAgICAgfQogICAgICByZXR1cm4gdGhpcy55ZWFyTW9udGhEYXlDYWNoZS5nZXQoczIpOwogICAgfQogICAgZ2V0WWVhck1vbnRoKHMyKSB7CiAgICAgIGlmICghdGhpcy55ZWFyTW9udGhDYWNoZS5oYXMoczIpKSB7CiAgICAgICAgdGhpcy55ZWFyTW9udGhDYWNoZS5zZXQoczIsIFllYXJNb250aENsYXNzLnBhcnNlKHMyLCB0aGlzKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMueWVhck1vbnRoQ2FjaGUuZ2V0KHMyKTsKICAgIH0KICAgIGdldFllYXJXZWVrKHMyKSB7CiAgICAgIGlmICghdGhpcy55ZWFyV2Vla0NhY2hlLmhhcyhzMikpIHsKICAgICAgICB0aGlzLnllYXJXZWVrQ2FjaGUuc2V0KHMyLCBZZWFyV2Vla0NsYXNzLnBhcnNlKHMyLCB0aGlzKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMueWVhcldlZWtDYWNoZS5nZXQoczIpOwogICAgfQogICAgZ2V0WWVhcihzMikgewogICAgICBpZiAoIXRoaXMueWVhckNhY2hlLmhhcyhzMikpIHsKICAgICAgICB0aGlzLnllYXJDYWNoZS5zZXQoczIsIFllYXJDbGFzcy5wYXJzZShzMiwgdGhpcykpOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLnllYXJDYWNoZS5nZXQoczIpOwogICAgfQogICAgc3RhdGljIGdldEluc3RhbmNlKCkgewogICAgICByZXR1cm4gdGhpcy5pbnN0YW5jZTsKICAgIH0KICB9OwogIF9UZW1wb3JhbENhY2hlLmluc3RhbmNlID0gbmV3IF9UZW1wb3JhbENhY2hlKCk7CiAgbGV0IFRlbXBvcmFsQ2FjaGUgPSBfVGVtcG9yYWxDYWNoZTsKICBjbGFzcyBZZWFyTW9udGhEYXlDbGFzcyB7CiAgICBjb25zdHJ1Y3Rvcih5ZWFyTnVtYmVyLCBtb250aE51bWJlciwgZGF5TnVtYmVyLCBjYWNoZSkgewogICAgICB0aGlzLnllYXJOdW1iZXIgPSB5ZWFyTnVtYmVyOwogICAgICB0aGlzLm1vbnRoTnVtYmVyID0gbW9udGhOdW1iZXI7CiAgICAgIHRoaXMuZGF5TnVtYmVyID0gZGF5TnVtYmVyOwogICAgICB0aGlzLmNhY2hlID0gY2FjaGU7CiAgICAgIHRoaXMudHlwZSA9ICJZZWFyTW9udGhEYXkiOwogICAgICB0aGlzLmRhdGUgPSBuZXcgRGF0ZSh0aGlzLnllYXJOdW1iZXIsIHRoaXMubW9udGhOdW1iZXIgLSAxLCB0aGlzLmRheU51bWJlcik7CiAgICAgIHRoaXMuZGF5anMgPSBkYXlqcyh0aGlzLmRhdGUpOwogICAgICB0aGlzLmRhdGVTdHJpbmcgPSB0aGlzLnRvU3RyaW5nKCk7CiAgICB9CiAgICBnZXQgdGV4dCgpIHsKICAgICAgcmV0dXJuIHRoaXMuZGF5anMuZm9ybWF0KCJZWVlZLU1NLUREIik7CiAgICB9CiAgICB0b1N0cmluZygpIHsKICAgICAgcmV0dXJuIHRoaXMudGV4dDsKICAgIH0KICAgIGVuZ2xpc2hOYW1lKCkgewogICAgICByZXR1cm4gdGhpcy5kYXlqcy5mb3JtYXQoImRkZGQsIE1NTU0gRCwgWVlZWSIpOwogICAgfQogICAgZ2V0IGZpcnN0RGF5KCkgewogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIGdldCBsYXN0RGF5KCkgewogICAgICByZXR1cm4gdGhpczsKICAgIH0KICAgIGdldCB5ZWFyKCkgewogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyKGAke3RoaXMueWVhck51bWJlcn1gKTsKICAgIH0KICAgIGdldCBtb250aCgpIHsKICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0WWVhck1vbnRoKHRoaXMuZGF5anMuZm9ybWF0KCJZWVlZLU1NIikpOwogICAgfQogICAgZ2V0IHdlZWsoKSB7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXJXZWVrKHRoaXMuZGF5anMuZm9ybWF0KEZPUk1BVF9JU09fV0VFS19ZRUFSX1dFRUspKTsKICAgIH0KICAgIGFkZERheXMoZGF5cykgewogICAgICBjb25zdCBkYXRlID0gdGhpcy5kYXlqcy5hZGQoZGF5cywgImRheSIpOwogICAgICBjb25zdCBzMiA9IGRhdGUuZm9ybWF0KCJZWVlZLU1NLUREIik7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXJNb250aERheShzMik7CiAgICB9CiAgICBtaW51cyhvdGhlcikgewogICAgICByZXR1cm4gdGhpcy5kYXlqcy5kaWZmKG90aGVyLmRheWpzLCAiZGF5Iik7CiAgICB9CiAgICBzdGF0aWMgcGFyc2UoczIsIGNhY2hlKSB7CiAgICAgIGNvbnN0IFt5ZWFyLCBtb250aCwgZGF5XSA9IHMyLnNwbGl0KCItIikubWFwKChzMjIpID0+IHBhcnNlSW50KHMyMiwgMTApKTsKICAgICAgcmV0dXJuIG5ldyBZZWFyTW9udGhEYXlDbGFzcyh5ZWFyLCBtb250aCwgZGF5LCBjYWNoZSk7CiAgICB9CiAgfQogIGNsYXNzIFllYXJXZWVrQ2xhc3MgewogICAgY29uc3RydWN0b3IoaXNvWWVhck51bWJlciwgaXNvV2Vla051bWJlciwgY2FjaGUpIHsKICAgICAgdGhpcy5pc29ZZWFyTnVtYmVyID0gaXNvWWVhck51bWJlcjsKICAgICAgdGhpcy5pc29XZWVrTnVtYmVyID0gaXNvV2Vla051bWJlcjsKICAgICAgdGhpcy5jYWNoZSA9IGNhY2hlOwogICAgICB0aGlzLnR5cGUgPSAiWWVhcldlZWsiOwogICAgICB0aGlzLmRhdGVTdHJpbmcgPSB0aGlzLnRvU3RyaW5nKCk7CiAgICB9CiAgICBnZXQgdGV4dCgpIHsKICAgICAgcmV0dXJuIHRoaXMuZmlyc3REYXkuZGF5anMuZm9ybWF0KEZPUk1BVF9JU09fV0VFS19ZRUFSX1dFRUspOwogICAgfQogICAgdG9TdHJpbmcoKSB7CiAgICAgIHJldHVybiB0aGlzLnRleHQ7CiAgICB9CiAgICBlbmdsaXNoTmFtZSgpIHsKICAgICAgcmV0dXJuIGBXZWVrICR7dGhpcy5pc29XZWVrTnVtYmVyfSwgJHt0aGlzLmlzb1llYXJOdW1iZXJ9YDsKICAgIH0KICAgIGdldCBmaXJzdERheSgpIHsKICAgICAgY29uc3QgZmlyc3REYXkgPSBkYXlqcygpLnllYXIodGhpcy5pc29ZZWFyTnVtYmVyKS5tb250aCgxKS5kYXRlKDQpLmlzb1dlZWsodGhpcy5pc29XZWVrTnVtYmVyKS5zdGFydE9mKCJpc29XZWVrIik7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXJNb250aERheShmaXJzdERheS5mb3JtYXQoIllZWVktTU0tREQiKSk7CiAgICB9CiAgICBnZXQgbGFzdERheSgpIHsKICAgICAgY29uc3QgZmlyc3REYXkgPSBkYXlqcygpLnllYXIodGhpcy5pc29ZZWFyTnVtYmVyKS5zdGFydE9mKCJ5ZWFyIikuYWRkKCh0aGlzLmlzb1dlZWtOdW1iZXIgLSAxKSAqIDcsICJkYXkiKS5zdGFydE9mKCJ3ZWVrIikuYWRkKDEsICJkYXkiKTsKICAgICAgY29uc3QgbGFzdERheSA9IGZpcnN0RGF5LmFkZCg2LCAiZGF5Iik7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXJNb250aERheShsYXN0RGF5LmZvcm1hdCgiWVlZWS1NTS1ERCIpKTsKICAgIH0KICAgIGdldCB5ZWFyKCkgewogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyKGAke3RoaXMuaXNvWWVhck51bWJlcn1gKTsKICAgIH0KICAgIGFkZFdlZWtzKHdlZWtzKSB7CiAgICAgIGNvbnN0IGRhdGUgPSB0aGlzLmZpcnN0RGF5LmRheWpzLmFkZCh3ZWVrcywgIndlZWsiKTsKICAgICAgY29uc3QgczIgPSBkYXRlLmZvcm1hdChGT1JNQVRfSVNPX1dFRUtfWUVBUl9XRUVLKTsKICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0WWVhcldlZWsoczIpOwogICAgfQogICAgbWludXMob3RoZXIpIHsKICAgICAgcmV0dXJuIHRoaXMuZmlyc3REYXkuZGF5anMuZGlmZihvdGhlci5maXJzdERheS5kYXlqcywgIndlZWsiKTsKICAgIH0KICAgIHN0YXRpYyBwYXJzZShzMiwgY2FjaGUpIHsKICAgICAgY29uc3QgW3llYXIsIHdlZWtdID0gczIuc3BsaXQoIi1XIikubWFwKChzMjIpID0+IHBhcnNlSW50KHMyMiwgMTApKTsKICAgICAgcmV0dXJuIG5ldyBZZWFyV2Vla0NsYXNzKHllYXIsIHdlZWssIGNhY2hlKTsKICAgIH0KICB9CiAgY2xhc3MgWWVhck1vbnRoQ2xhc3MgewogICAgY29uc3RydWN0b3IoeWVhck51bWJlciwgbW9udGhOdW1iZXIsIGNhY2hlKSB7CiAgICAgIHRoaXMueWVhck51bWJlciA9IHllYXJOdW1iZXI7CiAgICAgIHRoaXMubW9udGhOdW1iZXIgPSBtb250aE51bWJlcjsKICAgICAgdGhpcy5jYWNoZSA9IGNhY2hlOwogICAgICB0aGlzLnR5cGUgPSAiWWVhck1vbnRoIjsKICAgICAgdGhpcy5kYXRlU3RyaW5nID0gdGhpcy50b1N0cmluZygpOwogICAgfQogICAgZ2V0IHRleHQoKSB7CiAgICAgIHJldHVybiB0aGlzLmZpcnN0RGF5LmRheWpzLmZvcm1hdCgiWVlZWS1NTSIpOwogICAgfQogICAgdG9TdHJpbmcoKSB7CiAgICAgIHJldHVybiB0aGlzLnRleHQ7CiAgICB9CiAgICBlbmdsaXNoTmFtZSgpIHsKICAgICAgcmV0dXJuIGAke21vbnRoTmFtZSh0aGlzLm1vbnRoTnVtYmVyKX0gJHt0aGlzLnllYXJOdW1iZXJ9YDsKICAgIH0KICAgIGdldCBmaXJzdERheSgpIHsKICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0WWVhck1vbnRoRGF5KGRheWpzKGAke3RoaXMueWVhck51bWJlcn0tJHt0aGlzLm1vbnRoTnVtYmVyfS0wMWApLmZvcm1hdCgiWVlZWS1NTS1ERCIpKTsKICAgIH0KICAgIGdldCBsYXN0RGF5KCkgewogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyTW9udGhEYXkoCiAgICAgICAgZGF5anMoYCR7dGhpcy55ZWFyTnVtYmVyfS0ke3RoaXMubW9udGhOdW1iZXJ9LTAxYCkuZW5kT2YoIm1vbnRoIikuZm9ybWF0KCJZWVlZLU1NLUREIikKICAgICAgKTsKICAgIH0KICAgIGdldCB5ZWFyKCkgewogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyKGAke3RoaXMueWVhck51bWJlcn1gKTsKICAgIH0KICAgIGFkZE1vbnRocyhtb250aHMpIHsKICAgICAgY29uc3QgZGF0ZSA9IHRoaXMuZmlyc3REYXkuZGF5anMuYWRkKG1vbnRocywgIm1vbnRoIik7CiAgICAgIGNvbnN0IHMyID0gZGF0ZS5mb3JtYXQoIllZWVktTU0iKTsKICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0WWVhck1vbnRoKHMyKTsKICAgIH0KICAgIG1pbnVzKG90aGVyKSB7CiAgICAgIHJldHVybiB0aGlzLmZpcnN0RGF5LmRheWpzLmRpZmYob3RoZXIuZmlyc3REYXkuZGF5anMsICJtb250aCIpOwogICAgfQogICAgc3RhdGljIHBhcnNlKHMyLCBjYWNoZSkgewogICAgICBjb25zdCBbeWVhciwgbW9udGhdID0gczIuc3BsaXQoIi0iKS5tYXAoKHMyMikgPT4gcGFyc2VJbnQoczIyLCAxMCkpOwogICAgICByZXR1cm4gbmV3IFllYXJNb250aENsYXNzKHllYXIsIG1vbnRoLCBjYWNoZSk7CiAgICB9CiAgfQogIGNsYXNzIFllYXJDbGFzcyB7CiAgICBjb25zdHJ1Y3Rvcih5ZWFyLCBjYWNoZSkgewogICAgICB0aGlzLnllYXIgPSB5ZWFyOwogICAgICB0aGlzLmNhY2hlID0gY2FjaGU7CiAgICAgIHRoaXMudHlwZSA9ICJZZWFyIjsKICAgICAgdGhpcy5kYXRlU3RyaW5nID0gdGhpcy50b1N0cmluZygpOwogICAgfQogICAgZ2V0IHRleHQoKSB7CiAgICAgIHJldHVybiB0aGlzLmZpcnN0RGF5LmRheWpzLmZvcm1hdCgiWVlZWSIpOwogICAgfQogICAgdG9TdHJpbmcoKSB7CiAgICAgIHJldHVybiB0aGlzLnRleHQ7CiAgICB9CiAgICBlbmdsaXNoTmFtZSgpIHsKICAgICAgcmV0dXJuIHRoaXMueWVhci50b1N0cmluZygpOwogICAgfQogICAgZ2V0IGZpcnN0TW9udGgoKSB7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXJNb250aChgJHt0aGlzLnllYXJ9LTAxYCk7CiAgICB9CiAgICBnZXQgbGFzdE1vbnRoKCkgewogICAgICByZXR1cm4gdGhpcy5jYWNoZS5nZXRZZWFyTW9udGgoYCR7dGhpcy55ZWFyfS0xMmApOwogICAgfQogICAgZ2V0IGZpcnN0RGF5KCkgewogICAgICByZXR1cm4gdGhpcy5maXJzdE1vbnRoLmZpcnN0RGF5OwogICAgfQogICAgZ2V0IGxhc3REYXkoKSB7CiAgICAgIHJldHVybiB0aGlzLmxhc3RNb250aC5sYXN0RGF5OwogICAgfQogICAgYWRkWWVhcnMoeWVhcnMpIHsKICAgICAgY29uc3QgZGF0ZSA9IHRoaXMuZmlyc3REYXkuZGF5anMuYWRkKHllYXJzLCAieWVhciIpOwogICAgICBjb25zdCBzMiA9IGRhdGUuZm9ybWF0KCJZWVlZIik7CiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldFllYXIoczIpOwogICAgfQogICAgbWludXMob3RoZXIpIHsKICAgICAgcmV0dXJuIHRoaXMuZmlyc3REYXkuZGF5anMuZGlmZihvdGhlci5maXJzdERheS5kYXlqcywgInllYXIiKTsKICAgIH0KICAgIHN0YXRpYyBwYXJzZShzMiwgY2FjaGUpIHsKICAgICAgY29uc3QgeWVhciA9IHBhcnNlSW50KHMyLCAxMCk7CiAgICAgIHJldHVybiBuZXcgWWVhckNsYXNzKHllYXIsIGNhY2hlKTsKICAgIH0KICB9CiAgZnVuY3Rpb24gbW9udGhOYW1lKG1vbnRoKSB7CiAgICByZXR1cm4gZGF5anMoKS5tb250aChtb250aCAtIDEpLmZvcm1hdCgiTU1NTSIpOwogIH0KICBmdW5jdGlvbiB0b1RlbXBvcmFsKHRlbXBvcmFsQ2xhc3MpIHsKICAgIHN3aXRjaCAodGVtcG9yYWxDbGFzcy50eXBlKSB7CiAgICAgIGNhc2UgIlllYXJNb250aERheSI6CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIHR5cGU6ICJZZWFyTW9udGhEYXkiLAogICAgICAgICAgeWVhck51bWJlcjogdGVtcG9yYWxDbGFzcy55ZWFyTnVtYmVyLAogICAgICAgICAgbW9udGhOdW1iZXI6IHRlbXBvcmFsQ2xhc3MubW9udGhOdW1iZXIsCiAgICAgICAgICBkYXlOdW1iZXI6IHRlbXBvcmFsQ2xhc3MuZGF5TnVtYmVyLAogICAgICAgICAgZGF0ZVN0cmluZzogdGVtcG9yYWxDbGFzcy5kYXRlU3RyaW5nCiAgICAgICAgfTsKICAgICAgY2FzZSAiWWVhcldlZWsiOgogICAgICAgIHJldHVybiB7CiAgICAgICAgICB0eXBlOiAiWWVhcldlZWsiLAogICAgICAgICAgaXNvWWVhck51bWJlcjogdGVtcG9yYWxDbGFzcy5pc29ZZWFyTnVtYmVyLAogICAgICAgICAgaXNvV2Vla051bWJlcjogdGVtcG9yYWxDbGFzcy5pc29XZWVrTnVtYmVyLAogICAgICAgICAgZGF0ZVN0cmluZzogdGVtcG9yYWxDbGFzcy5kYXRlU3RyaW5nCiAgICAgICAgfTsKICAgICAgY2FzZSAiWWVhck1vbnRoIjoKICAgICAgICByZXR1cm4gewogICAgICAgICAgdHlwZTogIlllYXJNb250aCIsCiAgICAgICAgICB5ZWFyTnVtYmVyOiB0ZW1wb3JhbENsYXNzLnllYXJOdW1iZXIsCiAgICAgICAgICBtb250aE51bWJlcjogdGVtcG9yYWxDbGFzcy5tb250aE51bWJlciwKICAgICAgICAgIGRhdGVTdHJpbmc6IHRlbXBvcmFsQ2xhc3MuZGF0ZVN0cmluZwogICAgICAgIH07CiAgICAgIGNhc2UgIlllYXIiOgogICAgICAgIHJldHVybiB7CiAgICAgICAgICB0eXBlOiAiWWVhciIsCiAgICAgICAgICB5ZWFyOiB0ZW1wb3JhbENsYXNzLnllYXIsCiAgICAgICAgICBkYXRlU3RyaW5nOiB0ZW1wb3JhbENsYXNzLmRhdGVTdHJpbmcKICAgICAgICB9OwogICAgfQogIH0KICBmdW5jdGlvbiBnZW5lcmF0ZUFsbERheXNJblJhbmdlKHN0YXJ0LCBlbmQpIHsKICAgIGNvbnN0IGRheXMgPSBbXTsKICAgIGNvbnN0IGRheXNJbkJldHdlZW4gPSBlbmQubWludXMoc3RhcnQpOwogICAgZm9yIChsZXQgaTIgPSAwOyBpMiA8PSBkYXlzSW5CZXR3ZWVuOyBpMisrKSB7CiAgICAgIGRheXMucHVzaChzdGFydC5hZGREYXlzKGkyKSk7CiAgICB9CiAgICByZXR1cm4gZGF5czsKICB9CiAgZnVuY3Rpb24gZ2VuZXJhdGVBbGxXZWVrc0luUmFuZ2Uoc3RhcnQsIGVuZCkgewogICAgY29uc3Qgd2Vla3MgPSBbXTsKICAgIGNvbnN0IHdlZWtzSW5CZXR3ZWVuID0gZW5kLm1pbnVzKHN0YXJ0KTsKICAgIGZvciAobGV0IGkyID0gMDsgaTIgPD0gd2Vla3NJbkJldHdlZW47IGkyKyspIHsKICAgICAgd2Vla3MucHVzaChzdGFydC5hZGRXZWVrcyhpMikpOwogICAgfQogICAgcmV0dXJuIHdlZWtzOwogIH0KICBmdW5jdGlvbiBnZW5lcmF0ZUFsbE1vbnRoc0luUmFuZ2Uoc3RhcnQsIGVuZCkgewogICAgY29uc3QgbW9udGhzID0gW107CiAgICBjb25zdCBtb250aHNJbkJldHdlZW4gPSBlbmQubWludXMoc3RhcnQpOwogICAgZm9yIChsZXQgaTIgPSAwOyBpMiA8PSBtb250aHNJbkJldHdlZW47IGkyKyspIHsKICAgICAgbW9udGhzLnB1c2goc3RhcnQuYWRkTW9udGhzKGkyKSk7CiAgICB9CiAgICByZXR1cm4gbW9udGhzOwogIH0KICBmdW5jdGlvbiBnZW5lcmF0ZUFsbFllYXJzSW5SYW5nZShzdGFydCwgZW5kKSB7CiAgICBjb25zdCB5ZWFycyA9IFtdOwogICAgY29uc3QgeWVhcnNJbkJldHdlZW4gPSBlbmQubWludXMoc3RhcnQpOwogICAgZm9yIChsZXQgaTIgPSAwOyBpMiA8PSB5ZWFyc0luQmV0d2VlbjsgaTIrKykgewogICAgICB5ZWFycy5wdXNoKHN0YXJ0LmFkZFllYXJzKGkyKSk7CiAgICB9CiAgICByZXR1cm4geWVhcnM7CiAgfQogIGZ1bmN0aW9uIGdlbmVyYXRlQWxsSW5SYW5nZShzdGFydCwgZW5kKSB7CiAgICBpZiAoc3RhcnQgPT09IG51bGwgfHwgZW5kID09PSBudWxsKSB7CiAgICAgIHJldHVybiBbXTsKICAgIH0KICAgIGlmIChzdGFydCBpbnN0YW5jZW9mIFllYXJNb250aERheUNsYXNzICYmIGVuZCBpbnN0YW5jZW9mIFllYXJNb250aERheUNsYXNzKSB7CiAgICAgIHJldHVybiBnZW5lcmF0ZUFsbERheXNJblJhbmdlKHN0YXJ0LCBlbmQpOwogICAgfQogICAgaWYgKHN0YXJ0IGluc3RhbmNlb2YgWWVhcldlZWtDbGFzcyAmJiBlbmQgaW5zdGFuY2VvZiBZZWFyV2Vla0NsYXNzKSB7CiAgICAgIHJldHVybiBnZW5lcmF0ZUFsbFdlZWtzSW5SYW5nZShzdGFydCwgZW5kKTsKICAgIH0KICAgIGlmIChzdGFydCBpbnN0YW5jZW9mIFllYXJNb250aENsYXNzICYmIGVuZCBpbnN0YW5jZW9mIFllYXJNb250aENsYXNzKSB7CiAgICAgIHJldHVybiBnZW5lcmF0ZUFsbE1vbnRoc0luUmFuZ2Uoc3RhcnQsIGVuZCk7CiAgICB9CiAgICBpZiAoc3RhcnQgaW5zdGFuY2VvZiBZZWFyQ2xhc3MgJiYgZW5kIGluc3RhbmNlb2YgWWVhckNsYXNzKSB7CiAgICAgIHJldHVybiBnZW5lcmF0ZUFsbFllYXJzSW5SYW5nZShzdGFydCwgZW5kKTsKICAgIH0KICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBhcmd1bWVudHM6IHN0YXJ0IGFuZCBlbmQgbXVzdCBiZSBvZiB0aGUgc2FtZSB0eXBlOiAke3N0YXJ0fSwgJHtlbmR9YCk7CiAgfQogIGZ1bmN0aW9uIG1pbnVzVGVtcG9yYWwoYTIsIGIpIHsKICAgIGlmIChhMiBpbnN0YW5jZW9mIFllYXJNb250aERheUNsYXNzICYmIGIgaW5zdGFuY2VvZiBZZWFyTW9udGhEYXlDbGFzcykgewogICAgICByZXR1cm4gYTIubWludXMoYik7CiAgICB9CiAgICBpZiAoYTIgaW5zdGFuY2VvZiBZZWFyV2Vla0NsYXNzICYmIGIgaW5zdGFuY2VvZiBZZWFyV2Vla0NsYXNzKSB7CiAgICAgIHJldHVybiBhMi5taW51cyhiKTsKICAgIH0KICAgIGlmIChhMiBpbnN0YW5jZW9mIFllYXJNb250aENsYXNzICYmIGIgaW5zdGFuY2VvZiBZZWFyTW9udGhDbGFzcykgewogICAgICByZXR1cm4gYTIubWludXMoYik7CiAgICB9CiAgICBpZiAoYTIgaW5zdGFuY2VvZiBZZWFyQ2xhc3MgJiYgYiBpbnN0YW5jZW9mIFllYXJDbGFzcykgewogICAgICByZXR1cm4gYTIubWludXMoYik7CiAgICB9CiAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjb21wYXJlICR7YTJ9IGFuZCAke2J9YCk7CiAgfQogIGZ1bmN0aW9uIGNvbXBhcmVUZW1wb3JhbChhMiwgYikgewogICAgaWYgKGEyID09PSBudWxsKSB7CiAgICAgIHJldHVybiAxOwogICAgfQogICAgaWYgKGIgPT09IG51bGwpIHsKICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgY29uc3QgZGlmZiA9IG1pbnVzVGVtcG9yYWwoYTIsIGIpOwogICAgaWYgKGRpZmYgPCAwKSB7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGlmIChkaWZmID4gMCkgewogICAgICByZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiAwOwogIH0KICBmdW5jdGlvbiBnZXRNaW5NYXhUZW1wb3JhbCh2YWx1ZXMpIHsKICAgIGxldCBtaW4gPSBudWxsOwogICAgbGV0IG1heCA9IG51bGw7CiAgICBmb3IgKGNvbnN0IHZhbHVlIG9mIHZhbHVlcykgewogICAgICBpZiAodmFsdWUgPT09IG51bGwpIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBpZiAobWluID09PSBudWxsIHx8IGNvbXBhcmVUZW1wb3JhbCh2YWx1ZSwgbWluKSA8IDApIHsKICAgICAgICBtaW4gPSB2YWx1ZTsKICAgICAgfQogICAgICBpZiAobWF4ID09PSBudWxsIHx8IGNvbXBhcmVUZW1wb3JhbCh2YWx1ZSwgbWF4KSA+IDApIHsKICAgICAgICBtYXggPSB2YWx1ZTsKICAgICAgfQogICAgfQogICAgaWYgKG1pbiA9PT0gbnVsbCB8fCBtYXggPT09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgbWluOiBudWxsLCBtYXg6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IG1pbiwgbWF4IH07CiAgfQogIGZ1bmN0aW9uIHBhcnNlRGF0ZVN0cmluZ1RvVGVtcG9yYWwoZGF0ZSwgZ3JhbnVsYXJpdHkpIHsKICAgIGNvbnN0IGNhY2hlID0gVGVtcG9yYWxDYWNoZS5nZXRJbnN0YW5jZSgpOwogICAgY29uc3QgZGF5ID0gY2FjaGUuZ2V0WWVhck1vbnRoRGF5KGRhdGUpOwogICAgc3dpdGNoIChncmFudWxhcml0eSkgewogICAgICBjYXNlICJkYXkiOgogICAgICAgIHJldHVybiBkYXk7CiAgICAgIGNhc2UgIndlZWsiOgogICAgICAgIHJldHVybiBkYXkud2VlazsKICAgICAgY2FzZSAibW9udGgiOgogICAgICAgIHJldHVybiBkYXkubW9udGg7CiAgICAgIGNhc2UgInllYXIiOgogICAgICAgIHJldHVybiBkYXkueWVhcjsKICAgIH0KICB9CiAgZnVuY3Rpb24gZGF0ZVJhbmdlQ29tcGFyZShhMiwgYikgewogICAgaWYgKGEyLmRhdGVSYW5nZSA9PT0gbnVsbCkgewogICAgICByZXR1cm4gMTsKICAgIH0KICAgIGlmIChiLmRhdGVSYW5nZSA9PT0gbnVsbCkgewogICAgICByZXR1cm4gLTE7CiAgICB9CiAgICByZXR1cm4gY29tcGFyZVRlbXBvcmFsKGEyLmRhdGVSYW5nZSwgYi5kYXRlUmFuZ2UpOwogIH0KICBmdW5jdGlvbiBtYXBEYXRlVG9HcmFudWxhcml0eVJhbmdlKGRhdGEsIGdyYW51bGFyaXR5KSB7CiAgICByZXR1cm4gewogICAgICBkYXRlUmFuZ2U6IGRhdGEuZGF0ZSA9PT0gbnVsbCA/IG51bGwgOiBwYXJzZURhdGVTdHJpbmdUb1RlbXBvcmFsKGRhdGEuZGF0ZSwgZ3JhbnVsYXJpdHkpLAogICAgICBjb3VudDogZGF0YS5jb3VudAogICAgfTsKICB9CiAgY29uc3Qgc3Vic3RpdHV0aW9uUmVnZXggPSAvXigoPzxzZWdtZW50PltBLVphLXowLTlfLV0rKSg/PTopOik/KD88dmFsdWVBdFJlZmVyZW5jZT5bQS1aYS16XSk/KD88cG9zaXRpb24+XGQrKSg/PHN1YnN0aXR1dGlvblZhbHVlPltBLVphLXouXSk/JC87CiAgY2xhc3MgU3Vic3RpdHV0aW9uQ2xhc3MgewogICAgY29uc3RydWN0b3Ioc2VnbWVudCwgdmFsdWVBdFJlZmVyZW5jZSwgc3Vic3RpdHV0aW9uVmFsdWUsIHBvc2l0aW9uKSB7CiAgICAgIHRoaXMuc2VnbWVudCA9IHNlZ21lbnQ7CiAgICAgIHRoaXMudmFsdWVBdFJlZmVyZW5jZSA9IHZhbHVlQXRSZWZlcmVuY2U7CiAgICAgIHRoaXMuc3Vic3RpdHV0aW9uVmFsdWUgPSBzdWJzdGl0dXRpb25WYWx1ZTsKICAgICAgdGhpcy5wb3NpdGlvbiA9IHBvc2l0aW9uOwogICAgICB0aGlzLnR5cGUgPSAic3Vic3RpdHV0aW9uIjsKICAgICAgY29uc3Qgc2VnbWVudFN0cmluZyA9IHRoaXMuc2VnbWVudCA/IGAke3RoaXMuc2VnbWVudH06YCA6ICIiOwogICAgICBjb25zdCB2YWx1ZUF0UmVmZXJlbmNlU3RyaW5nID0gdGhpcy52YWx1ZUF0UmVmZXJlbmNlID8gYCR7dGhpcy52YWx1ZUF0UmVmZXJlbmNlfWAgOiAiIjsKICAgICAgY29uc3Qgc3Vic3RpdHV0aW9uVmFsdWVTdHJpbmcgPSB0aGlzLnN1YnN0aXR1dGlvblZhbHVlID8gYCR7dGhpcy5zdWJzdGl0dXRpb25WYWx1ZX1gIDogIiI7CiAgICAgIHRoaXMuY29kZSA9IGAke3NlZ21lbnRTdHJpbmd9JHt2YWx1ZUF0UmVmZXJlbmNlU3RyaW5nfSR7dGhpcy5wb3NpdGlvbn0ke3N1YnN0aXR1dGlvblZhbHVlU3RyaW5nfWA7CiAgICB9CiAgICBlcXVhbHMob3RoZXIpIHsKICAgICAgaWYgKCEob3RoZXIgaW5zdGFuY2VvZiBTdWJzdGl0dXRpb25DbGFzcykpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMuc2VnbWVudCA9PT0gb3RoZXIuc2VnbWVudCAmJiB0aGlzLnZhbHVlQXRSZWZlcmVuY2UgPT09IG90aGVyLnZhbHVlQXRSZWZlcmVuY2UgJiYgdGhpcy5zdWJzdGl0dXRpb25WYWx1ZSA9PT0gb3RoZXIuc3Vic3RpdHV0aW9uVmFsdWUgJiYgdGhpcy5wb3NpdGlvbiA9PT0gb3RoZXIucG9zaXRpb247CiAgICB9CiAgICB0b1N0cmluZygpIHsKICAgICAgcmV0dXJuIHRoaXMuY29kZTsKICAgIH0KICAgIHN0YXRpYyBwYXJzZShtdXRhdGlvblN0cikgewogICAgICBjb25zdCBtYXRjaCA9IG11dGF0aW9uU3RyLm1hdGNoKHN1YnN0aXR1dGlvblJlZ2V4KTsKICAgICAgaWYgKG1hdGNoID09PSBudWxsIHx8IG1hdGNoLmdyb3VwcyA9PT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIG5ldyBTdWJzdGl0dXRpb25DbGFzcygKICAgICAgICBtYXRjaC5ncm91cHMuc2VnbWVudCwKICAgICAgICBtYXRjaC5ncm91cHMudmFsdWVBdFJlZmVyZW5jZSwKICAgICAgICBtYXRjaC5ncm91cHMuc3Vic3RpdHV0aW9uVmFsdWUsCiAgICAgICAgcGFyc2VJbnQobWF0Y2guZ3JvdXBzLnBvc2l0aW9uLCAxMCkKICAgICAgKTsKICAgIH0KICB9CiAgY29uc3QgZGVsZXRpb25SZWdleCA9IC9eKCg/PHNlZ21lbnQ+W0EtWmEtejAtOV8tXSspKD89Oik6KT8oPzx2YWx1ZUF0UmVmZXJlbmNlPltBLVphLXpdKT8oPzxwb3NpdGlvbj5cZCspKC0pJC87CiAgY2xhc3MgRGVsZXRpb25DbGFzcyB7CiAgICBjb25zdHJ1Y3RvcihzZWdtZW50LCB2YWx1ZUF0UmVmZXJlbmNlLCBwb3NpdGlvbikgewogICAgICB0aGlzLnNlZ21lbnQgPSBzZWdtZW50OwogICAgICB0aGlzLnZhbHVlQXRSZWZlcmVuY2UgPSB2YWx1ZUF0UmVmZXJlbmNlOwogICAgICB0aGlzLnBvc2l0aW9uID0gcG9zaXRpb247CiAgICAgIHRoaXMudHlwZSA9ICJkZWxldGlvbiI7CiAgICAgIGNvbnN0IHNlZ21lbnRTdHJpbmcgPSB0aGlzLnNlZ21lbnQgPyBgJHt0aGlzLnNlZ21lbnR9OmAgOiAiIjsKICAgICAgY29uc3QgdmFsdWVBdFJlZmVyZW5jZVN0cmluZyA9IHRoaXMudmFsdWVBdFJlZmVyZW5jZSA/IGAke3RoaXMudmFsdWVBdFJlZmVyZW5jZX1gIDogIiI7CiAgICAgIHRoaXMuY29kZSA9IGAke3NlZ21lbnRTdHJpbmd9JHt2YWx1ZUF0UmVmZXJlbmNlU3RyaW5nfSR7dGhpcy5wb3NpdGlvbn0tYDsKICAgIH0KICAgIGVxdWFscyhvdGhlcikgewogICAgICBpZiAoIShvdGhlciBpbnN0YW5jZW9mIERlbGV0aW9uQ2xhc3MpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9CiAgICAgIHJldHVybiB0aGlzLnNlZ21lbnQgPT09IG90aGVyLnNlZ21lbnQgJiYgdGhpcy52YWx1ZUF0UmVmZXJlbmNlID09PSBvdGhlci52YWx1ZUF0UmVmZXJlbmNlICYmIHRoaXMucG9zaXRpb24gPT09IG90aGVyLnBvc2l0aW9uOwogICAgfQogICAgdG9TdHJpbmcoKSB7CiAgICAgIHJldHVybiB0aGlzLmNvZGU7CiAgICB9CiAgICBzdGF0aWMgcGFyc2UobXV0YXRpb25TdHIpIHsKICAgICAgY29uc3QgbWF0Y2ggPSBtdXRhdGlvblN0ci5tYXRjaChkZWxldGlvblJlZ2V4KTsKICAgICAgaWYgKG1hdGNoID09PSBudWxsIHx8IG1hdGNoLmdyb3VwcyA9PT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIG51bGw7CiAgICAgIH0KICAgICAgcmV0dXJuIG5ldyBEZWxldGlvbkNsYXNzKAogICAgICAgIG1hdGNoLmdyb3Vwcy5zZWdtZW50LAogICAgICAgIG1hdGNoLmdyb3Vwcy52YWx1ZUF0UmVmZXJlbmNlLAogICAgICAgIHBhcnNlSW50KG1hdGNoLmdyb3Vwcy5wb3NpdGlvbiwgMTApCiAgICAgICk7CiAgICB9CiAgfQogIGZ1bmN0aW9uIHRvU3Vic3RpdHV0aW9uT3JEZWxldGlvbihtdXRhdGlvbikgewogICAgc3dpdGNoIChtdXRhdGlvbi50eXBlKSB7CiAgICAgIGNhc2UgInN1YnN0aXR1dGlvbiI6CiAgICAgICAgcmV0dXJuIHsKICAgICAgICAgIHR5cGU6ICJzdWJzdGl0dXRpb24iLAogICAgICAgICAgY29kZTogbXV0YXRpb24uY29kZSwKICAgICAgICAgIHNlZ21lbnQ6IG11dGF0aW9uLnNlZ21lbnQsCiAgICAgICAgICBwb3NpdGlvbjogbXV0YXRpb24ucG9zaXRpb24sCiAgICAgICAgICB2YWx1ZUF0UmVmZXJlbmNlOiBtdXRhdGlvbi52YWx1ZUF0UmVmZXJlbmNlLAogICAgICAgICAgc3Vic3RpdHV0aW9uVmFsdWU6IG11dGF0aW9uLnN1YnN0aXR1dGlvblZhbHVlCiAgICAgICAgfTsKICAgICAgY2FzZSAiZGVsZXRpb24iOgogICAgICAgIHJldHVybiB7CiAgICAgICAgICB0eXBlOiAiZGVsZXRpb24iLAogICAgICAgICAgY29kZTogbXV0YXRpb24uY29kZSwKICAgICAgICAgIHNlZ21lbnQ6IG11dGF0aW9uLnNlZ21lbnQsCiAgICAgICAgICBwb3NpdGlvbjogbXV0YXRpb24ucG9zaXRpb24sCiAgICAgICAgICB2YWx1ZUF0UmVmZXJlbmNlOiBtdXRhdGlvbi52YWx1ZUF0UmVmZXJlbmNlCiAgICAgICAgfTsKICAgIH0KICB9CiAgY2xhc3MgRmV0Y2hTdWJzdGl0dXRpb25zT3JEZWxldGlvbnNPcGVyYXRvciB7CiAgICBjb25zdHJ1Y3RvcihmaWx0ZXIsIHNlcXVlbmNlVHlwZSwgbWluUHJvcG9ydGlvbikgewogICAgICB0aGlzLmZpbHRlciA9IGZpbHRlcjsKICAgICAgdGhpcy5zZXF1ZW5jZVR5cGUgPSBzZXF1ZW5jZVR5cGU7CiAgICAgIHRoaXMubWluUHJvcG9ydGlvbiA9IG1pblByb3BvcnRpb247CiAgICB9CiAgICBhc3luYyBldmFsdWF0ZShsYXBpcywgc2lnbmFsKSB7CiAgICAgIGNvbnN0IG11dGF0aW9ucyA9IGF3YWl0IHRoaXMuZmV0Y2hNdXRhdGlvbnMobGFwaXMsIHNpZ25hbCk7CiAgICAgIGNvbnN0IGNvbnRlbnQgPSBtdXRhdGlvbnMubWFwKAogICAgICAgICh7IGNvdW50LCBwcm9wb3J0aW9uLCBtdXRhdGlvbkZyb20sIG11dGF0aW9uVG8sIHBvc2l0aW9uLCBzZXF1ZW5jZU5hbWUgfSkgPT4gewogICAgICAgICAgaWYgKG11dGF0aW9uVG8gPT09ICItIikgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgIHR5cGU6ICJkZWxldGlvbiIsCiAgICAgICAgICAgICAgbXV0YXRpb246IG5ldyBEZWxldGlvbkNsYXNzKHNlcXVlbmNlTmFtZSA/PyB2b2lkIDAsIG11dGF0aW9uRnJvbSwgcG9zaXRpb24pLAogICAgICAgICAgICAgIGNvdW50LAogICAgICAgICAgICAgIHByb3BvcnRpb24KICAgICAgICAgICAgfTsKICAgICAgICAgIH0KICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIHR5cGU6ICJzdWJzdGl0dXRpb24iLAogICAgICAgICAgICBtdXRhdGlvbjogbmV3IFN1YnN0aXR1dGlvbkNsYXNzKHNlcXVlbmNlTmFtZSA/PyB2b2lkIDAsIG11dGF0aW9uRnJvbSwgbXV0YXRpb25UbywgcG9zaXRpb24pLAogICAgICAgICAgICBjb3VudCwKICAgICAgICAgICAgcHJvcG9ydGlvbgogICAgICAgICAgfTsKICAgICAgICB9CiAgICAgICk7CiAgICAgIHJldHVybiB7IGNvbnRlbnQgfTsKICAgIH0KICAgIGFzeW5jIGZldGNoTXV0YXRpb25zKGxhcGlzLCBzaWduYWwpIHsKICAgICAgY29uc3QgZmlsdGVyID0gewogICAgICAgIC4uLnRoaXMuZmlsdGVyLAogICAgICAgIG1pblByb3BvcnRpb246IHRoaXMubWluUHJvcG9ydGlvbgogICAgICB9OwogICAgICByZXR1cm4gZmV0Y2hTdWJzdGl0dXRpb25zT3JEZWxldGlvbnMobGFwaXMsIGZpbHRlciwgdGhpcy5zZXF1ZW5jZVR5cGUsIHNpZ25hbCkudGhlbigKICAgICAgICAocmVzcG9uc2UpID0+IHJlc3BvbnNlLmRhdGEKICAgICAgKTsKICAgIH0KICB9CiAgdmFyIGwkMTsKICBsJDEgPSB7IF9fZTogZnVuY3Rpb24obiwgbDIsIHUyLCB0KSB7CiAgICBmb3IgKHZhciBpMiwgbywgcjI7IGwyID0gbDIuX187ICkgaWYgKChpMiA9IGwyLl9fYykgJiYgIWkyLl9fKSB0cnkgewogICAgICBpZiAoKG8gPSBpMi5jb25zdHJ1Y3RvcikgJiYgbnVsbCAhPSBvLmdldERlcml2ZWRTdGF0ZUZyb21FcnJvciAmJiAoaTIuc2V0U3RhdGUoby5nZXREZXJpdmVkU3RhdGVGcm9tRXJyb3IobikpLCByMiA9IGkyLl9fZCksIG51bGwgIT0gaTIuY29tcG9uZW50RGlkQ2F0Y2ggJiYgKGkyLmNvbXBvbmVudERpZENhdGNoKG4sIHQgfHwge30pLCByMiA9IGkyLl9fZCksIHIyKSByZXR1cm4gaTIuX19FID0gaTI7CiAgICB9IGNhdGNoIChsMykgewogICAgICBuID0gbDM7CiAgICB9CiAgICB0aHJvdyBuOwogIH0gfSwgImZ1bmN0aW9uIiA9PSB0eXBlb2YgUHJvbWlzZSA/IFByb21pc2UucHJvdG90eXBlLnRoZW4uYmluZChQcm9taXNlLnJlc29sdmUoKSkgOiBzZXRUaW1lb3V0OwogIHZhciByLCB1LCBpLCBmID0gW10sIGMgPSBsJDEsIGUgPSBjLl9fYiwgYSA9IGMuX19yLCB2ID0gYy5kaWZmZWQsIGwgPSBjLl9fYywgbSA9IGMudW5tb3VudCwgcyA9IGMuX187CiAgZnVuY3Rpb24gaigpIHsKICAgIGZvciAodmFyIG47IG4gPSBmLnNoaWZ0KCk7ICkgaWYgKG4uX19QICYmIG4uX19IKSB0cnkgewogICAgICBuLl9fSC5fX2guZm9yRWFjaCh6KSwgbi5fX0guX19oLmZvckVhY2goQiksIG4uX19ILl9faCA9IFtdOwogICAgfSBjYXRjaCAodCkgewogICAgICBuLl9fSC5fX2ggPSBbXSwgYy5fX2UodCwgbi5fX3YpOwogICAgfQogIH0KICBjLl9fYiA9IGZ1bmN0aW9uKG4pIHsKICAgIHIgPSBudWxsLCBlICYmIGUobik7CiAgfSwgYy5fXyA9IGZ1bmN0aW9uKG4sIHQpIHsKICAgIG4gJiYgdC5fX2sgJiYgdC5fX2suX19tICYmIChuLl9fbSA9IHQuX19rLl9fbSksIHMgJiYgcyhuLCB0KTsKICB9LCBjLl9fciA9IGZ1bmN0aW9uKG4pIHsKICAgIGEgJiYgYShuKTsKICAgIHZhciBpMiA9IChyID0gbi5fX2MpLl9fSDsKICAgIGkyICYmICh1ID09PSByID8gKGkyLl9faCA9IFtdLCByLl9faCA9IFtdLCBpMi5fXy5mb3JFYWNoKGZ1bmN0aW9uKG4yKSB7CiAgICAgIG4yLl9fTiAmJiAobjIuX18gPSBuMi5fX04pLCBuMi5pID0gbjIuX19OID0gdm9pZCAwOwogICAgfSkpIDogKGkyLl9faC5mb3JFYWNoKHopLCBpMi5fX2guZm9yRWFjaChCKSwgaTIuX19oID0gW10sIDApKSwgdSA9IHI7CiAgfSwgYy5kaWZmZWQgPSBmdW5jdGlvbihuKSB7CiAgICB2ICYmIHYobik7CiAgICB2YXIgdCA9IG4uX19jOwogICAgdCAmJiB0Ll9fSCAmJiAodC5fX0guX19oLmxlbmd0aCAmJiAoMSAhPT0gZi5wdXNoKHQpICYmIGkgPT09IGMucmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8ICgoaSA9IGMucmVxdWVzdEFuaW1hdGlvbkZyYW1lKSB8fCB3KShqKSksIHQuX19ILl9fLmZvckVhY2goZnVuY3Rpb24objIpIHsKICAgICAgbjIuaSAmJiAobjIuX19IID0gbjIuaSksIG4yLmkgPSB2b2lkIDA7CiAgICB9KSksIHUgPSByID0gbnVsbDsKICB9LCBjLl9fYyA9IGZ1bmN0aW9uKG4sIHQpIHsKICAgIHQuc29tZShmdW5jdGlvbihuMikgewogICAgICB0cnkgewogICAgICAgIG4yLl9faC5mb3JFYWNoKHopLCBuMi5fX2ggPSBuMi5fX2guZmlsdGVyKGZ1bmN0aW9uKG4zKSB7CiAgICAgICAgICByZXR1cm4gIW4zLl9fIHx8IEIobjMpOwogICAgICAgIH0pOwogICAgICB9IGNhdGNoIChyMikgewogICAgICAgIHQuc29tZShmdW5jdGlvbihuMykgewogICAgICAgICAgbjMuX19oICYmIChuMy5fX2ggPSBbXSk7CiAgICAgICAgfSksIHQgPSBbXSwgYy5fX2UocjIsIG4yLl9fdik7CiAgICAgIH0KICAgIH0pLCBsICYmIGwobiwgdCk7CiAgfSwgYy51bm1vdW50ID0gZnVuY3Rpb24obikgewogICAgbSAmJiBtKG4pOwogICAgdmFyIHQsIHIyID0gbi5fX2M7CiAgICByMiAmJiByMi5fX0ggJiYgKHIyLl9fSC5fXy5mb3JFYWNoKGZ1bmN0aW9uKG4yKSB7CiAgICAgIHRyeSB7CiAgICAgICAgeihuMik7CiAgICAgIH0gY2F0Y2ggKG4zKSB7CiAgICAgICAgdCA9IG4zOwogICAgICB9CiAgICB9KSwgcjIuX19IID0gdm9pZCAwLCB0ICYmIGMuX19lKHQsIHIyLl9fdikpOwogIH07CiAgdmFyIGsgPSAiZnVuY3Rpb24iID09IHR5cGVvZiByZXF1ZXN0QW5pbWF0aW9uRnJhbWU7CiAgZnVuY3Rpb24gdyhuKSB7CiAgICB2YXIgdCwgcjIgPSBmdW5jdGlvbigpIHsKICAgICAgY2xlYXJUaW1lb3V0KHUyKSwgayAmJiBjYW5jZWxBbmltYXRpb25GcmFtZSh0KSwgc2V0VGltZW91dChuKTsKICAgIH0sIHUyID0gc2V0VGltZW91dChyMiwgMTAwKTsKICAgIGsgJiYgKHQgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUocjIpKTsKICB9CiAgZnVuY3Rpb24geihuKSB7CiAgICB2YXIgdCA9IHIsIHUyID0gbi5fX2M7CiAgICAiZnVuY3Rpb24iID09IHR5cGVvZiB1MiAmJiAobi5fX2MgPSB2b2lkIDAsIHUyKCkpLCByID0gdDsKICB9CiAgZnVuY3Rpb24gQihuKSB7CiAgICB2YXIgdCA9IHI7CiAgICBuLl9fYyA9IG4uX18oKSwgciA9IHQ7CiAgfQogIGNsYXNzIFVzZXJGYWNpbmdFcnJvciBleHRlbmRzIEVycm9yIHsKICAgIGNvbnN0cnVjdG9yKGhlYWRsaW5lLCBtZXNzYWdlKSB7CiAgICAgIHN1cGVyKG1lc3NhZ2UpOwogICAgICB0aGlzLmhlYWRsaW5lID0gaGVhZGxpbmU7CiAgICAgIHRoaXMubmFtZSA9ICJVc2VyRmFjaW5nRXJyb3IiOwogICAgfQogIH0KICBjbGFzcyBNYXAyZEJhc2UgewogICAgY29uc3RydWN0b3Ioc2VyaWFsaXplRmlyc3RBeGlzLCBzZXJpYWxpemVTZWNvbmRBeGlzLCBpbml0aWFsQ29udGVudCkgewogICAgICB0aGlzLnNlcmlhbGl6ZUZpcnN0QXhpcyA9IHNlcmlhbGl6ZUZpcnN0QXhpczsKICAgICAgdGhpcy5zZXJpYWxpemVTZWNvbmRBeGlzID0gc2VyaWFsaXplU2Vjb25kQXhpczsKICAgICAgdGhpcy5kYXRhID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAgICAgdGhpcy5rZXlzRmlyc3RBeGlzID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAgICAgdGhpcy5rZXlzU2Vjb25kQXhpcyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgIGlmIChpbml0aWFsQ29udGVudCkgewogICAgICAgIHRoaXMua2V5c0ZpcnN0QXhpcyA9IG5ldyBNYXAoaW5pdGlhbENvbnRlbnQua2V5c0ZpcnN0QXhpcyk7CiAgICAgICAgdGhpcy5rZXlzU2Vjb25kQXhpcyA9IG5ldyBNYXAoaW5pdGlhbENvbnRlbnQua2V5c1NlY29uZEF4aXMpOwogICAgICAgIHRoaXMuZGF0YSA9IG5ldyBNYXAoaW5pdGlhbENvbnRlbnQuZGF0YSk7CiAgICAgIH0KICAgIH0KICAgIGdldChrZXlGaXJzdEF4aXMsIGtleVNlY29uZEF4aXMpIHsKICAgICAgdmFyIF9hOwogICAgICBjb25zdCBzZXJpYWxpemVkS2V5Rmlyc3RBeGlzID0gdGhpcy5zZXJpYWxpemVGaXJzdEF4aXMoa2V5Rmlyc3RBeGlzKTsKICAgICAgY29uc3Qgc2VyaWFsaXplZEtleVNlY29uZEF4aXMgPSB0aGlzLnNlcmlhbGl6ZVNlY29uZEF4aXMoa2V5U2Vjb25kQXhpcyk7CiAgICAgIHJldHVybiAoX2EgPSB0aGlzLmRhdGEuZ2V0KHNlcmlhbGl6ZWRLZXlGaXJzdEF4aXMpKSA9PSBudWxsID8gdm9pZCAwIDogX2EuZ2V0KHNlcmlhbGl6ZWRLZXlTZWNvbmRBeGlzKTsKICAgIH0KICAgIGdldFJvdyhrZXksIGZpbGxFbXB0eVdpdGgpIHsKICAgICAgY29uc3Qgc2VyaWFsaXplZEtleUZpcnN0QXhpcyA9IHRoaXMuc2VyaWFsaXplRmlyc3RBeGlzKGtleSk7CiAgICAgIGNvbnN0IHJvdyA9IHRoaXMuZGF0YS5nZXQoc2VyaWFsaXplZEtleUZpcnN0QXhpcyk7CiAgICAgIGlmIChyb3cgPT09IHZvaWQgMCkgewogICAgICAgIHJldHVybiBbXTsKICAgICAgfQogICAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmtleXNTZWNvbmRBeGlzLmtleXMoKSkubWFwKChrZXkyKSA9PiByb3cuZ2V0KGtleTIpID8/IGZpbGxFbXB0eVdpdGgpOwogICAgfQogICAgc2V0KGtleUZpcnN0QXhpcywga2V5U2Vjb25kQXhpcywgdmFsdWUpIHsKICAgICAgY29uc3Qgc2VyaWFsaXplZEtleUZpcnN0QXhpcyA9IHRoaXMuc2VyaWFsaXplRmlyc3RBeGlzKGtleUZpcnN0QXhpcyk7CiAgICAgIGNvbnN0IHNlcmlhbGl6ZWRLZXlTZWNvbmRBeGlzID0gdGhpcy5zZXJpYWxpemVTZWNvbmRBeGlzKGtleVNlY29uZEF4aXMpOwogICAgICBpZiAoIXRoaXMuZGF0YS5oYXMoc2VyaWFsaXplZEtleUZpcnN0QXhpcykpIHsKICAgICAgICB0aGlzLmRhdGEuc2V0KHNlcmlhbGl6ZWRLZXlGaXJzdEF4aXMsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpOwogICAgICB9CiAgICAgIHRoaXMuZGF0YS5nZXQoc2VyaWFsaXplZEtleUZpcnN0QXhpcykuc2V0KHNlcmlhbGl6ZWRLZXlTZWNvbmRBeGlzLCB2YWx1ZSk7CiAgICAgIHRoaXMua2V5c0ZpcnN0QXhpcy5zZXQoc2VyaWFsaXplZEtleUZpcnN0QXhpcywga2V5Rmlyc3RBeGlzKTsKICAgICAgdGhpcy5rZXlzU2Vjb25kQXhpcy5zZXQoc2VyaWFsaXplZEtleVNlY29uZEF4aXMsIGtleVNlY29uZEF4aXMpOwogICAgfQogICAgZGVsZXRlUm93KGtleSkgewogICAgICBjb25zdCBzZXJpYWxpemVkS2V5Rmlyc3RBeGlzID0gdGhpcy5zZXJpYWxpemVGaXJzdEF4aXMoa2V5KTsKICAgICAgdGhpcy5kYXRhLmRlbGV0ZShzZXJpYWxpemVkS2V5Rmlyc3RBeGlzKTsKICAgICAgdGhpcy5rZXlzRmlyc3RBeGlzLmRlbGV0ZShzZXJpYWxpemVkS2V5Rmlyc3RBeGlzKTsKICAgIH0KICAgIGdldEZpcnN0QXhpc0tleXMoKSB7CiAgICAgIHJldHVybiBBcnJheS5mcm9tKHRoaXMua2V5c0ZpcnN0QXhpcy52YWx1ZXMoKSk7CiAgICB9CiAgICBnZXRTZWNvbmRBeGlzS2V5cygpIHsKICAgICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5rZXlzU2Vjb25kQXhpcy52YWx1ZXMoKSk7CiAgICB9CiAgICBnZXRBc0FycmF5KGZpbGxFbXB0eVdpdGgpIHsKICAgICAgcmV0dXJuIHRoaXMuZ2V0Rmlyc3RBeGlzS2V5cygpLm1hcCgoZmlyc3RBeGlzS2V5KSA9PiB7CiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0U2Vjb25kQXhpc0tleXMoKS5tYXAoKHNlY29uZEF4aXNLZXkpID0+IHsKICAgICAgICAgIHJldHVybiB0aGlzLmdldChmaXJzdEF4aXNLZXksIHNlY29uZEF4aXNLZXkpID8/IGZpbGxFbXB0eVdpdGg7CiAgICAgICAgfSk7CiAgICAgIH0pOwogICAgfQogICAgZ2V0Q29udGVudHMoKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAga2V5c0ZpcnN0QXhpczogdGhpcy5rZXlzRmlyc3RBeGlzLAogICAgICAgIGtleXNTZWNvbmRBeGlzOiB0aGlzLmtleXNTZWNvbmRBeGlzLAogICAgICAgIGRhdGE6IHRoaXMuZGF0YQogICAgICB9OwogICAgfQogIH0KICBjbGFzcyBCYXNlTXV0YXRpb25PdmVyVGltZURhdGFNYXAgZXh0ZW5kcyBNYXAyZEJhc2UgewogICAgY29uc3RydWN0b3IoaW5pdGlhbENvbnRlbnQpIHsKICAgICAgc3VwZXIoc2VyaWFsaXplU3Vic3RpdHV0aW9uT3JEZWxldGlvbiwgc2VyaWFsaXplVGVtcG9yYWwsIGluaXRpYWxDb250ZW50KTsKICAgIH0KICB9CiAgY29uc3Qgc29ydFN1YnN0aXR1dGlvbnNBbmREZWxldGlvbnMgPSAoYTIsIGIpID0+IHsKICAgIGlmIChhMi5zZWdtZW50ICE9PSBiLnNlZ21lbnQpIHsKICAgICAgcmV0dXJuIGNvbXBhcmVTZWdtZW50cyhhMi5zZWdtZW50LCBiLnNlZ21lbnQpOwogICAgfQogICAgaWYgKGEyLnBvc2l0aW9uICE9PSBiLnBvc2l0aW9uKSB7CiAgICAgIHJldHVybiBjb21wYXJlUG9zaXRpb25zKGEyLnBvc2l0aW9uLCBiLnBvc2l0aW9uKTsKICAgIH0KICAgIGNvbnN0IGFJc0RlbGV0aW9uID0gYTIgaW5zdGFuY2VvZiBEZWxldGlvbkNsYXNzOwogICAgY29uc3QgYklzRGVsZXRpb24gPSBiIGluc3RhbmNlb2YgRGVsZXRpb25DbGFzczsKICAgIGlmIChhSXNEZWxldGlvbiAhPT0gYklzRGVsZXRpb24pIHsKICAgICAgcmV0dXJuIGFJc0RlbGV0aW9uID8gMSA6IC0xOwogICAgfQogICAgaWYgKCFhSXNEZWxldGlvbiAmJiAhYklzRGVsZXRpb24pIHsKICAgICAgaWYgKGEyLnN1YnN0aXR1dGlvblZhbHVlICE9PSBiLnN1YnN0aXR1dGlvblZhbHVlKSB7CiAgICAgICAgcmV0dXJuIGNvbXBhcmVTdWJzdGl0dXRpb25WYWx1ZXMoYTIuc3Vic3RpdHV0aW9uVmFsdWUsIGIuc3Vic3RpdHV0aW9uVmFsdWUpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gMDsKICB9OwogIGNvbnN0IGNvbXBhcmVTZWdtZW50cyA9IChhMiwgYikgPT4gewogICAgaWYgKGEyID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgaWYgKGIgPT09IHZvaWQgMCkgewogICAgICByZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiBhMi5sb2NhbGVDb21wYXJlKGIpOwogIH07CiAgY29uc3QgY29tcGFyZVBvc2l0aW9ucyA9IChhMiwgYikgPT4gewogICAgcmV0dXJuIGEyIC0gYjsKICB9OwogIGNvbnN0IGNvbXBhcmVTdWJzdGl0dXRpb25WYWx1ZXMgPSAoYTIsIGIpID0+IHsKICAgIGlmIChhMiA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGlmIChiID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gYTIubG9jYWxlQ29tcGFyZShiKTsKICB9OwogIGNvbnN0IE1BWF9OVU1CRVJfT0ZfR1JJRF9DT0xVTU5TID0gMjAwOwogIGFzeW5jIGZ1bmN0aW9uIHF1ZXJ5T3ZlcmFsbE11dGF0aW9uRGF0YSh7CiAgICBsYXBpc0ZpbHRlciwKICAgIHNlcXVlbmNlVHlwZSwKICAgIGxhcGlzLAogICAgZ3JhbnVsYXJpdHksCiAgICBsYXBpc0RhdGVGaWVsZCwKICAgIHNpZ25hbAogIH0pIHsKICAgIGNvbnN0IGFsbERhdGVzID0gYXdhaXQgZ2V0RGF0ZXNJbkRhdGFzZXQobGFwaXNGaWx0ZXIsIGxhcGlzLCBncmFudWxhcml0eSwgbGFwaXNEYXRlRmllbGQsIHNpZ25hbCk7CiAgICBpZiAoYWxsRGF0ZXMubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybiB7CiAgICAgICAgY29udGVudDogW10KICAgICAgfTsKICAgIH0KICAgIGNvbnN0IGZpbHRlciA9IHsKICAgICAgLi4ubGFwaXNGaWx0ZXIsCiAgICAgIFtgJHtsYXBpc0RhdGVGaWVsZH1Gcm9tYF06IGFsbERhdGVzWzBdLmZpcnN0RGF5LnRvU3RyaW5nKCksCiAgICAgIFtgJHtsYXBpc0RhdGVGaWVsZH1Ub2BdOiBhbGxEYXRlc1thbGxEYXRlcy5sZW5ndGggLSAxXS5sYXN0RGF5LnRvU3RyaW5nKCkKICAgIH07CiAgICByZXR1cm4gZmV0Y2hBbmRQcmVwYXJlU3Vic3RpdHV0aW9uc09yRGVsZXRpb25zKGZpbHRlciwgc2VxdWVuY2VUeXBlKS5ldmFsdWF0ZShsYXBpcywgc2lnbmFsKTsKICB9CiAgYXN5bmMgZnVuY3Rpb24gcXVlcnlNdXRhdGlvbnNPdmVyVGltZURhdGEoewogICAgbGFwaXNGaWx0ZXIsCiAgICBzZXF1ZW5jZVR5cGUsCiAgICBsYXBpcywKICAgIGxhcGlzRGF0ZUZpZWxkLAogICAgZ3JhbnVsYXJpdHksCiAgICBzaWduYWwKICB9KSB7CiAgICBjb25zdCBhbGxEYXRlcyA9IGF3YWl0IGdldERhdGVzSW5EYXRhc2V0KGxhcGlzRmlsdGVyLCBsYXBpcywgZ3JhbnVsYXJpdHksIGxhcGlzRGF0ZUZpZWxkLCBzaWduYWwpOwogICAgaWYgKGFsbERhdGVzLmxlbmd0aCA+IE1BWF9OVU1CRVJfT0ZfR1JJRF9DT0xVTU5TKSB7CiAgICAgIHRocm93IG5ldyBVc2VyRmFjaW5nRXJyb3IoCiAgICAgICAgIlRvbyBtYW55IGRhdGVzIiwKICAgICAgICBgVGhlIGRhdGFzZXQgd291bGQgY29udGFpbiAke2FsbERhdGVzLmxlbmd0aH0gZGF0ZSBpbnRlcnZhbHMuIFBsZWFzZSByZWR1Y2UgdGhlIG51bWJlciB0byBiZWxvdyAke01BWF9OVU1CRVJfT0ZfR1JJRF9DT0xVTU5TfSB0byBkaXNwbGF5IHRoZSBkYXRhLiBZb3UgY2FuIGFjaGlldmUgdGhpcyBieSBlaXRoZXIgbmFycm93aW5nIHRoZSBkYXRlIHJhbmdlIGluIHRoZSBwcm92aWRlZCBMQVBJUyBmaWx0ZXIgb3IgYnkgc2VsZWN0aW5nIGEgbGFyZ2VyIGdyYW51bGFyaXR5LmAKICAgICAgKTsKICAgIH0KICAgIGNvbnN0IHN1YlF1ZXJpZXMgPSBhbGxEYXRlcy5tYXAoYXN5bmMgKGRhdGUpID0+IHsKICAgICAgY29uc3QgZGF0ZUZyb20gPSBkYXRlLmZpcnN0RGF5LnRvU3RyaW5nKCk7CiAgICAgIGNvbnN0IGRhdGVUbyA9IGRhdGUubGFzdERheS50b1N0cmluZygpOwogICAgICBjb25zdCBmaWx0ZXIgPSB7CiAgICAgICAgLi4ubGFwaXNGaWx0ZXIsCiAgICAgICAgW2Ake2xhcGlzRGF0ZUZpZWxkfUZyb21gXTogZGF0ZUZyb20sCiAgICAgICAgW2Ake2xhcGlzRGF0ZUZpZWxkfVRvYF06IGRhdGVUbwogICAgICB9OwogICAgICBjb25zdCBkYXRhMiA9IGF3YWl0IGZldGNoQW5kUHJlcGFyZVN1YnN0aXR1dGlvbnNPckRlbGV0aW9ucyhmaWx0ZXIsIHNlcXVlbmNlVHlwZSkuZXZhbHVhdGUobGFwaXMsIHNpZ25hbCk7CiAgICAgIGNvbnN0IHRvdGFsQ291bnRRdWVyeSA9IGF3YWl0IGdldFRvdGFsTnVtYmVyT2ZTZXF1ZW5jZXNJbkRhdGVSYW5nZShmaWx0ZXIpLmV2YWx1YXRlKGxhcGlzLCBzaWduYWwpOwogICAgICByZXR1cm4gewogICAgICAgIGRhdGUsCiAgICAgICAgbXV0YXRpb25zOiBkYXRhMi5jb250ZW50LAogICAgICAgIHRvdGFsQ291bnQ6IHRvdGFsQ291bnRRdWVyeS5jb250ZW50WzBdLmNvdW50CiAgICAgIH07CiAgICB9KTsKICAgIGNvbnN0IGRhdGEgPSBhd2FpdCBQcm9taXNlLmFsbChzdWJRdWVyaWVzKTsKICAgIGNvbnN0IG92ZXJhbGxNdXRhdGlvbnNEYXRhID0gKGF3YWl0IHF1ZXJ5T3ZlcmFsbE11dGF0aW9uRGF0YSh7CiAgICAgIGxhcGlzRmlsdGVyLAogICAgICBzZXF1ZW5jZVR5cGUsCiAgICAgIGxhcGlzLAogICAgICBsYXBpc0RhdGVGaWVsZCwKICAgICAgZ3JhbnVsYXJpdHkKICAgIH0pKS5jb250ZW50OwogICAgcmV0dXJuIHsKICAgICAgbXV0YXRpb25PdmVyVGltZURhdGE6IGdyb3VwQnlNdXRhdGlvbihkYXRhLCBvdmVyYWxsTXV0YXRpb25zRGF0YSksCiAgICAgIG92ZXJhbGxNdXRhdGlvbkRhdGE6IG92ZXJhbGxNdXRhdGlvbnNEYXRhCiAgICB9OwogIH0KICBhc3luYyBmdW5jdGlvbiBnZXREYXRlc0luRGF0YXNldChsYXBpc0ZpbHRlciwgbGFwaXMsIGdyYW51bGFyaXR5LCBsYXBpc0RhdGVGaWVsZCwgc2lnbmFsKSB7CiAgICBjb25zdCB7IGNvbnRlbnQ6IGF2YWlsYWJsZURhdGVzIH0gPSBhd2FpdCBxdWVyeUF2YWlsYWJsZURhdGVzKAogICAgICBsYXBpc0ZpbHRlciwKICAgICAgbGFwaXMsCiAgICAgIGdyYW51bGFyaXR5LAogICAgICBsYXBpc0RhdGVGaWVsZCwKICAgICAgc2lnbmFsCiAgICApOwogICAgY29uc3QgeyBkYXRlRnJvbSwgZGF0ZVRvIH0gPSBnZXREYXRlUmFuZ2VGcm9tRmlsdGVyKGxhcGlzRmlsdGVyLCBsYXBpc0RhdGVGaWVsZCwgZ3JhbnVsYXJpdHkpOwogICAgY29uc3QgeyBtaW4sIG1heCB9ID0gZ2V0TWluTWF4VGVtcG9yYWwoYXZhaWxhYmxlRGF0ZXMpOwogICAgcmV0dXJuIGdlbmVyYXRlQWxsSW5SYW5nZShkYXRlRnJvbSA/PyBtaW4sIGRhdGVUbyA/PyBtYXgpOwogIH0KICBmdW5jdGlvbiBnZXREYXRlUmFuZ2VGcm9tRmlsdGVyKGxhcGlzRmlsdGVyLCBsYXBpc0RhdGVGaWVsZCwgZ3JhbnVsYXJpdHkpIHsKICAgIGNvbnN0IHZhbHVlRnJvbUZpbHRlciA9IGxhcGlzRmlsdGVyW2xhcGlzRGF0ZUZpZWxkXTsKICAgIGlmICh2YWx1ZUZyb21GaWx0ZXIpIHsKICAgICAgcmV0dXJuIHsKICAgICAgICBkYXRlRnJvbTogcGFyc2VEYXRlU3RyaW5nVG9UZW1wb3JhbCh2YWx1ZUZyb21GaWx0ZXIsIGdyYW51bGFyaXR5KSwKICAgICAgICBkYXRlVG86IHBhcnNlRGF0ZVN0cmluZ1RvVGVtcG9yYWwodmFsdWVGcm9tRmlsdGVyLCBncmFudWxhcml0eSkKICAgICAgfTsKICAgIH0KICAgIGNvbnN0IG1pbkZyb21GaWx0ZXIgPSBsYXBpc0ZpbHRlcltgJHtsYXBpc0RhdGVGaWVsZH1Gcm9tYF07CiAgICBjb25zdCBtYXhGcm9tRmlsdGVyID0gbGFwaXNGaWx0ZXJbYCR7bGFwaXNEYXRlRmllbGR9VG9gXTsKICAgIHJldHVybiB7CiAgICAgIGRhdGVGcm9tOiBtaW5Gcm9tRmlsdGVyID8gcGFyc2VEYXRlU3RyaW5nVG9UZW1wb3JhbChtaW5Gcm9tRmlsdGVyLCBncmFudWxhcml0eSkgOiBudWxsLAogICAgICBkYXRlVG86IG1heEZyb21GaWx0ZXIgPyBwYXJzZURhdGVTdHJpbmdUb1RlbXBvcmFsKG1heEZyb21GaWx0ZXIsIGdyYW51bGFyaXR5KSA6IG51bGwKICAgIH07CiAgfQogIGZ1bmN0aW9uIHF1ZXJ5QXZhaWxhYmxlRGF0ZXMobGFwaXNGaWx0ZXIsIGxhcGlzLCBncmFudWxhcml0eSwgbGFwaXNEYXRlRmllbGQsIHNpZ25hbCkgewogICAgcmV0dXJuIGZldGNoQW5kUHJlcGFyZURhdGVzKGxhcGlzRmlsdGVyLCBncmFudWxhcml0eSwgbGFwaXNEYXRlRmllbGQpLmV2YWx1YXRlKGxhcGlzLCBzaWduYWwpOwogIH0KICBmdW5jdGlvbiBmZXRjaEFuZFByZXBhcmVEYXRlcyhmaWx0ZXIsIGdyYW51bGFyaXR5LCBsYXBpc0RhdGVGaWVsZCkgewogICAgY29uc3QgZmV0Y2hEYXRhID0gbmV3IEZldGNoQWdncmVnYXRlZE9wZXJhdG9yKGZpbHRlciwgW2xhcGlzRGF0ZUZpZWxkXSk7CiAgICBjb25zdCBkYXRhV2l0aEZpeGVkRGF0ZUtleSA9IG5ldyBSZW5hbWVGaWVsZE9wZXJhdG9yKGZldGNoRGF0YSwgbGFwaXNEYXRlRmllbGQsICJkYXRlIik7CiAgICBjb25zdCBtYXBEYXRhID0gbmV3IE1hcE9wZXJhdG9yKGRhdGFXaXRoRml4ZWREYXRlS2V5LCAoZGF0YSkgPT4gbWFwRGF0ZVRvR3JhbnVsYXJpdHlSYW5nZShkYXRhLCBncmFudWxhcml0eSkpOwogICAgY29uc3QgZ3JvdXBCeURhdGEgPSBuZXcgR3JvdXBCeUFuZFN1bU9wZXJhdG9yKG1hcERhdGEsICJkYXRlUmFuZ2UiLCAiY291bnQiKTsKICAgIGNvbnN0IHNvcnREYXRhID0gbmV3IFNvcnRPcGVyYXRvcihncm91cEJ5RGF0YSwgZGF0ZVJhbmdlQ29tcGFyZSk7CiAgICByZXR1cm4gbmV3IE1hcE9wZXJhdG9yKHNvcnREYXRhLCAoZGF0YSkgPT4gZGF0YS5kYXRlUmFuZ2UpOwogIH0KICBmdW5jdGlvbiBmZXRjaEFuZFByZXBhcmVTdWJzdGl0dXRpb25zT3JEZWxldGlvbnMoZmlsdGVyLCBzZXF1ZW5jZVR5cGUpIHsKICAgIHJldHVybiBuZXcgRmV0Y2hTdWJzdGl0dXRpb25zT3JEZWxldGlvbnNPcGVyYXRvcihmaWx0ZXIsIHNlcXVlbmNlVHlwZSwgMWUtMyk7CiAgfQogIGZ1bmN0aW9uIHNlcmlhbGl6ZVN1YnN0aXR1dGlvbk9yRGVsZXRpb24obXV0YXRpb24pIHsKICAgIHJldHVybiBtdXRhdGlvbi5jb2RlOwogIH0KICBmdW5jdGlvbiBzZXJpYWxpemVUZW1wb3JhbChkYXRlKSB7CiAgICByZXR1cm4gZGF0ZS5kYXRlU3RyaW5nOwogIH0KICBmdW5jdGlvbiBncm91cEJ5TXV0YXRpb24oZGF0YSwgb3ZlcmFsbE11dGF0aW9uRGF0YSkgewogICAgY29uc3QgZGF0YUFycmF5ID0gbmV3IEJhc2VNdXRhdGlvbk92ZXJUaW1lRGF0YU1hcCgpOwogICAgY29uc3QgYWxsRGF0ZXMgPSBkYXRhLm1hcCgobXV0YXRpb25EYXRhKSA9PiBtdXRhdGlvbkRhdGEuZGF0ZSk7CiAgICBjb25zdCBzb3J0ZWRPdmVyYWxsTXV0YXRpb25EYXRhID0gb3ZlcmFsbE11dGF0aW9uRGF0YS5zb3J0KChhMiwgYikgPT4gc29ydFN1YnN0aXR1dGlvbnNBbmREZWxldGlvbnMoYTIubXV0YXRpb24sIGIubXV0YXRpb24pKS5tYXAoKGVudHJ5KSA9PiB7CiAgICAgIHJldHVybiB0b1N1YnN0aXR1dGlvbk9yRGVsZXRpb24oZW50cnkubXV0YXRpb24pOwogICAgfSk7CiAgICBjb25zdCBzb3J0ZWREYXRlcyA9IGFsbERhdGVzLnNvcnQoKGEyLCBiKSA9PiBjb21wYXJlVGVtcG9yYWwoYTIsIGIpKS5tYXAoKGRhdGUpID0+IHRvVGVtcG9yYWwoZGF0ZSkpOwogICAgc29ydGVkT3ZlcmFsbE11dGF0aW9uRGF0YS5mb3JFYWNoKChtdXRhdGlvbkRhdGEpID0+IHsKICAgICAgc29ydGVkRGF0ZXMuZm9yRWFjaCgoZGF0ZSkgPT4gewogICAgICAgIGRhdGFBcnJheS5zZXQobXV0YXRpb25EYXRhLCBkYXRlLCB7CiAgICAgICAgICBjb3VudDogMCwKICAgICAgICAgIHByb3BvcnRpb246IDAsCiAgICAgICAgICB0b3RhbENvdW50OiAwCiAgICAgICAgfSk7CiAgICAgIH0pOwogICAgfSk7CiAgICBkYXRhLmZvckVhY2goKG11dGF0aW9uRGF0YSkgPT4gewogICAgICBtdXRhdGlvbkRhdGEubXV0YXRpb25zLmZvckVhY2goKG11dGF0aW9uRW50cnkpID0+IHsKICAgICAgICBjb25zdCBtdXRhdGlvbiA9IHRvU3Vic3RpdHV0aW9uT3JEZWxldGlvbihtdXRhdGlvbkVudHJ5Lm11dGF0aW9uKTsKICAgICAgICBjb25zdCBkYXRlID0gdG9UZW1wb3JhbChtdXRhdGlvbkRhdGEuZGF0ZSk7CiAgICAgICAgaWYgKGRhdGFBcnJheS5nZXQobXV0YXRpb24sIGRhdGUpICE9PSB2b2lkIDApIHsKICAgICAgICAgIGRhdGFBcnJheS5zZXQobXV0YXRpb24sIGRhdGUsIHsKICAgICAgICAgICAgY291bnQ6IG11dGF0aW9uRW50cnkuY291bnQsCiAgICAgICAgICAgIHByb3BvcnRpb246IG11dGF0aW9uRW50cnkucHJvcG9ydGlvbiwKICAgICAgICAgICAgdG90YWxDb3VudDogbXV0YXRpb25EYXRhLnRvdGFsQ291bnQKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfSk7CiAgICB9KTsKICAgIHJldHVybiBkYXRhQXJyYXk7CiAgfQogIGZ1bmN0aW9uIGdldFRvdGFsTnVtYmVyT2ZTZXF1ZW5jZXNJbkRhdGVSYW5nZShmaWx0ZXIpIHsKICAgIHJldHVybiBuZXcgRmV0Y2hBZ2dyZWdhdGVkT3BlcmF0b3IoZmlsdGVyKTsKICB9CiAgYXN5bmMgZnVuY3Rpb24gd29ya2VyRnVuY3Rpb24ocXVlcnlGdW5jdGlvbikgewogICAgdHJ5IHsKICAgICAgcG9zdE1lc3NhZ2UoeyBzdGF0dXM6ICJsb2FkaW5nIiB9KTsKICAgICAgY29uc3Qgd29ya2VyUmVzcG9uc2UgPSBhd2FpdCBxdWVyeUZ1bmN0aW9uKCk7CiAgICAgIHBvc3RNZXNzYWdlKHsKICAgICAgICBzdGF0dXM6ICJzdWNjZXNzIiwKICAgICAgICBkYXRhOiB3b3JrZXJSZXNwb25zZQogICAgICB9KTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgIHBvc3RNZXNzYWdlKHsgc3RhdHVzOiAiZXJyb3IiLCBlcnJvciB9KTsKICAgIH0KICB9CiAgYXN5bmMgZnVuY3Rpb24gZ2V0TXV0YXRpb25PdmVyVGltZVdvcmtlckZ1bmN0aW9uKGV2ZW50KSB7CiAgICBjb25zdCBtdXRhdGlvbk92ZXJUaW1lRGF0YSA9IGF3YWl0IHF1ZXJ5TXV0YXRpb25zT3ZlclRpbWVEYXRhKGV2ZW50LmRhdGEpOwogICAgY29uc3Qgd29ya2VyUmVzcG9uc2UgPSB7CiAgICAgIG92ZXJhbGxNdXRhdGlvbkRhdGE6IG11dGF0aW9uT3ZlclRpbWVEYXRhLm92ZXJhbGxNdXRhdGlvbkRhdGEsCiAgICAgIG11dGF0aW9uT3ZlclRpbWVTZXJpYWxpemVkOiBtdXRhdGlvbk92ZXJUaW1lRGF0YS5tdXRhdGlvbk92ZXJUaW1lRGF0YS5nZXRDb250ZW50cygpCiAgICB9OwogICAgcmV0dXJuIHdvcmtlclJlc3BvbnNlOwogIH0KICBzZWxmLm9ubWVzc2FnZSA9IGFzeW5jIGZ1bmN0aW9uKGV2ZW50KSB7CiAgICBhd2FpdCB3b3JrZXJGdW5jdGlvbigoKSA9PiBnZXRNdXRhdGlvbk92ZXJUaW1lV29ya2VyRnVuY3Rpb24oZXZlbnQpKTsKICB9Owp9KSgpOwovLyMgc291cmNlTWFwcGluZ1VSTD1tdXRhdGlvbk92ZXJUaW1lV29ya2VyLWtqVVhrUm1uLmpzLm1hcAo=";
8477
8541
  const decodeBase64 = (base64) => Uint8Array.from(atob(base64), (c2) => c2.charCodeAt(0));
8478
8542
  const blob = typeof self !== "undefined" && self.Blob && new Blob([decodeBase64(encodedJs)], { type: "text/javascript;charset=utf-8" });
8479
8543
  function WorkerWrapper(options2) {
@@ -8748,6 +8812,7 @@ const MutationsOverTimeGrid = ({ data, colorScale }) => {
8748
8812
  allMutations.length,
8749
8813
  " mutations. You can narrow the filter to reduce the number of mutations."
8750
8814
  ] }),
8815
+ allMutations.length === 0 && /* @__PURE__ */ u$1("div", { className: "flex justify-center", children: "No data available for your filters." }),
8751
8816
  /* @__PURE__ */ u$1(
8752
8817
  "div",
8753
8818
  {
@@ -8932,9 +8997,9 @@ const MutationsOverTimeInner = (componentProps) => {
8932
8997
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
8933
8998
  }
8934
8999
  if (error !== void 0) {
8935
- return /* @__PURE__ */ u$1(ErrorDisplay, { error });
9000
+ throw error;
8936
9001
  }
8937
- if (data === null || data === void 0) {
9002
+ if (data === null || data === void 0 || data.overallMutationData.length === 0) {
8938
9003
  return /* @__PURE__ */ u$1(NoDataDisplay, {});
8939
9004
  }
8940
9005
  const { overallMutationData, mutationOverTimeSerialized } = data;
@@ -9050,8 +9115,15 @@ const Toolbar = ({
9050
9115
  const MutationsOverTimeInfo = ({ originalComponentProps }) => {
9051
9116
  const lapis = x(LapisUrlContext);
9052
9117
  return /* @__PURE__ */ u$1(Info, { children: [
9053
- /* @__PURE__ */ u$1(InfoHeadline1, { children: "Info for mutations over time" }),
9054
- /* @__PURE__ */ u$1(InfoParagraph, { children: "TODO: https://github.com/GenSpectrum/dashboard-components/issues/441" }),
9118
+ /* @__PURE__ */ u$1(InfoHeadline1, { children: "Mutations over time" }),
9119
+ /* @__PURE__ */ u$1(InfoParagraph, { children: [
9120
+ "This presents the proportions of ",
9121
+ originalComponentProps.sequenceType,
9122
+ " mutations per",
9123
+ " ",
9124
+ originalComponentProps.granularity,
9125
+ ". In the toolbar, you can configure which mutations are displayed by selecting the mutation type (substitution or deletion), choosing specific segments/genes (if the organism has multiple segments/genes), and applying a filter based on the proportion of the mutation's occurrence over the entire time range."
9126
+ ] }),
9055
9127
  /* @__PURE__ */ u$1(InfoComponentCode, { componentName: "mutations-over-time", params: originalComponentProps, lapisUrl: lapis })
9056
9128
  ] });
9057
9129
  };
@@ -9205,7 +9277,7 @@ const toYYYYMMDD = (date) => {
9205
9277
  const customOption = "Custom";
9206
9278
  const DateRangeSelector = ({ width, ...innerProps }) => {
9207
9279
  const size = { width, height: "3rem" };
9208
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1("div", { style: { width }, children: /* @__PURE__ */ u$1(DateRangeSelectorInner, { ...innerProps }) }) });
9280
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, layout: "horizontal", children: /* @__PURE__ */ u$1("div", { style: { width }, children: /* @__PURE__ */ u$1(DateRangeSelectorInner, { ...innerProps }) }) });
9209
9281
  };
9210
9282
  const DateRangeSelectorInner = ({
9211
9283
  dateRangeOptions,
@@ -9445,7 +9517,7 @@ function compareLocationEntries(fields) {
9445
9517
  }
9446
9518
  const LocationFilter = ({ width, ...innerProps }) => {
9447
9519
  const size = { width, height: "3rem" };
9448
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(LocationFilterInner, { ...innerProps }) }) });
9520
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, layout: "horizontal", children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(LocationFilterInner, { ...innerProps }) }) });
9449
9521
  };
9450
9522
  const LocationFilterInner = ({ initialValue, fields, placeholderText }) => {
9451
9523
  const lapis = x(LapisUrlContext);
@@ -9457,7 +9529,7 @@ const LocationFilterInner = ({ initialValue, fields, placeholderText }) => {
9457
9529
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
9458
9530
  }
9459
9531
  if (error) {
9460
- return /* @__PURE__ */ u$1(ErrorDisplay, { error });
9532
+ throw error;
9461
9533
  }
9462
9534
  const onInput = (event) => {
9463
9535
  var _a;
@@ -9565,7 +9637,7 @@ async function fetchAutocompleteList(lapis, field, signal) {
9565
9637
  }
9566
9638
  const TextInput = ({ width, ...innerProps }) => {
9567
9639
  const size = { width, height: "3rem" };
9568
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(TextInputInner, { ...innerProps }) }) });
9640
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, layout: "horizontal", children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(TextInputInner, { ...innerProps }) }) });
9569
9641
  };
9570
9642
  const TextInputInner = ({ lapisField, placeholderText, initialValue }) => {
9571
9643
  const lapis = x(LapisUrlContext);
@@ -9575,7 +9647,7 @@ const TextInputInner = ({ lapisField, placeholderText, initialValue }) => {
9575
9647
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
9576
9648
  }
9577
9649
  if (error !== null) {
9578
- return /* @__PURE__ */ u$1(ErrorDisplay, { error });
9650
+ throw error;
9579
9651
  }
9580
9652
  if (data === null) {
9581
9653
  return /* @__PURE__ */ u$1(NoDataDisplay, {});
@@ -9934,7 +10006,7 @@ const parseAndValidateMutation = (value, referenceGenome) => {
9934
10006
  return null;
9935
10007
  };
9936
10008
  const MutationFilter = ({ initialValue, width }) => {
9937
- return /* @__PURE__ */ u$1(ErrorBoundary, { size: { height: "3.375rem", width }, children: /* @__PURE__ */ u$1("div", { style: width, children: /* @__PURE__ */ u$1(MutationFilterInner, { initialValue }) }) });
10009
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size: { height: "3.375rem", width }, layout: "horizontal", children: /* @__PURE__ */ u$1("div", { style: width, children: /* @__PURE__ */ u$1(MutationFilterInner, { initialValue }) }) });
9938
10010
  };
9939
10011
  const MutationFilterInner = ({ initialValue }) => {
9940
10012
  const referenceGenome = x(ReferenceGenomeContext);
@@ -10202,7 +10274,7 @@ async function fetchLineageAutocompleteList(lapis, field, signal) {
10202
10274
  }
10203
10275
  const LineageFilter = ({ width, ...innerProps }) => {
10204
10276
  const size = { width, height: "3rem" };
10205
- return /* @__PURE__ */ u$1(ErrorBoundary, { size, children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(LineageFilterInner, { ...innerProps }) }) });
10277
+ return /* @__PURE__ */ u$1(ErrorBoundary, { size, layout: "horizontal", children: /* @__PURE__ */ u$1(ResizeContainer, { size, children: /* @__PURE__ */ u$1(LineageFilterInner, { ...innerProps }) }) });
10206
10278
  };
10207
10279
  const LineageFilterInner = ({
10208
10280
  lapisField,
@@ -10219,7 +10291,7 @@ const LineageFilterInner = ({
10219
10291
  return /* @__PURE__ */ u$1(LoadingDisplay, {});
10220
10292
  }
10221
10293
  if (error !== null) {
10222
- return /* @__PURE__ */ u$1(ErrorDisplay, { error });
10294
+ throw error;
10223
10295
  }
10224
10296
  if (data === null) {
10225
10297
  return /* @__PURE__ */ u$1(NoDataDisplay, {});