@cartanova/qgrid-cli 2.9.2 → 2.9.5

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 (77) hide show
  1. package/bundle/dist/application/qgrid/expired-token-reminder.js +6 -5
  2. package/bundle/dist/application/qgrid/qgrid-image-generation.js +12 -3
  3. package/bundle/dist/application/qgrid/qgrid-response-format.js +8 -6
  4. package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +2 -2
  5. package/bundle/dist/application/qgrid/qgrid.frame.js +4 -3
  6. package/bundle/dist/application/qgrid/qgrid.types.js +31 -4
  7. package/bundle/dist/application/qgrid/token-death.js +6 -22
  8. package/bundle/dist/application/qgrid/token-subscriber.js +2 -1
  9. package/bundle/dist/application/qgrid/tool-emulation.js +3 -2
  10. package/bundle/dist/application/setting/setting.model.js +8 -2
  11. package/bundle/dist/application/token/token.model.js +22 -17
  12. package/bundle/dist/utils/providers/common/model-cost.js +21 -13
  13. package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +1 -1
  14. package/bundle/dist/utils/providers/openai/openai-direct-client.js +39 -1
  15. package/bundle/dist/utils/providers/openai/openai-dispatcher.js +41 -20
  16. package/bundle/dist/utils/providers/openai/openai-image-generation.js +145 -0
  17. package/bundle/dist/utils/providers/openai/openai-quota.js +11 -3
  18. package/bundle/dist/utils/providers/openai/openai-refresh.js +7 -5
  19. package/bundle/dist/utils/slack-notify.js +8 -4
  20. package/bundle/src/application/qgrid/expired-token-reminder.test.ts +6 -1
  21. package/bundle/src/application/qgrid/expired-token-reminder.ts +10 -4
  22. package/bundle/src/application/qgrid/qgrid-image-generation.test.ts +53 -0
  23. package/bundle/src/application/qgrid/qgrid-image-generation.ts +32 -2
  24. package/bundle/src/application/qgrid/qgrid-response-format.test.ts +26 -0
  25. package/bundle/src/application/qgrid/qgrid-response-format.ts +21 -13
  26. package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +32 -0
  27. package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +1 -1
  28. package/bundle/src/application/qgrid/qgrid.frame.test.ts +20 -0
  29. package/bundle/src/application/qgrid/qgrid.frame.ts +3 -2
  30. package/bundle/src/application/qgrid/qgrid.types.ts +32 -0
  31. package/bundle/src/application/qgrid/token-death.test.ts +11 -10
  32. package/bundle/src/application/qgrid/token-death.ts +9 -21
  33. package/bundle/src/application/qgrid/token-subscriber.test.ts +5 -1
  34. package/bundle/src/application/qgrid/token-subscriber.ts +1 -0
  35. package/bundle/src/application/qgrid/tool-emulation.test.ts +18 -0
  36. package/bundle/src/application/qgrid/tool-emulation.ts +3 -0
  37. package/bundle/src/application/setting/setting.model.test.ts +20 -0
  38. package/bundle/src/application/setting/setting.model.ts +10 -2
  39. package/bundle/src/application/sonamu.generated.http +4 -2
  40. package/bundle/src/application/token/token.model.test.ts +24 -5
  41. package/bundle/src/application/token/token.model.ts +30 -23
  42. package/bundle/src/utils/providers/common/effort.test.ts +8 -0
  43. package/bundle/src/utils/providers/common/model-cost.test.ts +25 -12
  44. package/bundle/src/utils/providers/common/model-cost.ts +28 -14
  45. package/bundle/src/utils/providers/common/provider-dispatcher.ts +5 -1
  46. package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +9 -1
  47. package/bundle/src/utils/providers/openai/openai-direct-client.ts +48 -1
  48. package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +137 -2
  49. package/bundle/src/utils/providers/openai/openai-dispatcher.ts +44 -18
  50. package/bundle/src/utils/providers/openai/openai-image-generation.test.ts +135 -0
  51. package/bundle/src/utils/providers/openai/openai-image-generation.ts +177 -0
  52. package/bundle/src/utils/providers/openai/openai-quota.test.ts +32 -0
  53. package/bundle/src/utils/providers/openai/openai-quota.ts +15 -8
  54. package/bundle/src/utils/providers/openai/openai-refresh.test.ts +18 -0
  55. package/bundle/src/utils/providers/openai/openai-refresh.ts +11 -4
  56. package/bundle/src/utils/slack-notify.test.ts +14 -0
  57. package/bundle/src/utils/slack-notify.ts +19 -3
  58. package/bundle/web-dist/client/assets/{index-DH1n8kgG.js → index-BcCytvFf.js} +3 -3
  59. package/bundle/web-dist/client/assets/{logs-D36O-NET.js → logs-BkOilk5x.js} +1 -1
  60. package/bundle/web-dist/client/assets/{monit-DhZAaz9K.js → monit-8oCSLCdL.js} +1 -1
  61. package/bundle/web-dist/client/assets/{routes-C7q1CsSv.js → routes-DFIF4IoW.js} +2 -2
  62. package/bundle/web-dist/client/assets/{settings-M_jfoIAe.js → settings-nUI-DR3U.js} +1 -1
  63. package/bundle/web-dist/client/assets/{show-CORjMGQs.js → show-Bzx6Xkoc.js} +1 -1
  64. package/bundle/web-dist/client/assets/{tokens-C7-j4VXD.js → tokens-DFWCL7Ts.js} +1 -1
  65. package/bundle/web-dist/client/assets/{use-oauth-login-flow-Fi62xbBc.js → use-oauth-login-flow-B5MAjpVc.js} +1 -1
  66. package/bundle/web-dist/client/index.html +1 -1
  67. package/bundle/web-dist/server/assets/{routes-CxMHXfdH.js → routes-B408iqh1.js} +29 -14
  68. package/bundle/web-dist/server/entry-server.generated.js +3 -2
  69. package/package.json +2 -1
  70. package/skills/qgrid/SKILL.md +2 -1
  71. package/skills/qgrid/references/ai-sdk-provider-contract.md +2 -2
  72. package/skills/qgrid/references/decision-rationale.md +2 -2
  73. package/skills/qgrid/references/openai-codex-runtime.md +79 -0
  74. package/skills/qgrid/references/provider-runtime-differences.md +1 -1
  75. package/skills/qgrid/references/request-log-run-lifecycle.md +1 -1
  76. package/skills/qgrid/references/sonamu-api-web-flow.md +1 -1
  77. package/skills/qgrid/references/token-auth-quota-lifecycle.md +4 -3
@@ -203,7 +203,8 @@ var OpenAIDispatcher = class OpenAIDispatcher {
203
203
  imageAttempted = true;
204
204
  images.push({
205
205
  data: event.base64,
206
- revisedPrompt: event.revisedPrompt ?? null
206
+ revisedPrompt: event.revisedPrompt ?? null,
207
+ ...event.generation ? { generation: event.generation } : {}
207
208
  });
208
209
  } else if (event.type === "output-item" && event.item.type === "image_generation_call") imageAttempted = true;
209
210
  else if (event.type === "completed" && event.usage) {
@@ -231,6 +232,7 @@ var OpenAIDispatcher = class OpenAIDispatcher {
231
232
  durationMs: Date.now() - startedAt,
232
233
  ttftMs: firstDeltaAt === void 0 ? null : firstDeltaAt - startedAt,
233
234
  model: servingModel,
235
+ ...servingModel !== req.model ? { requestedModel: req.model } : {},
234
236
  threadCoord: {
235
237
  workerId: selection.tokenId,
236
238
  threadId: req.promptCacheKey ?? "",
@@ -255,19 +257,7 @@ var OpenAIDispatcher = class OpenAIDispatcher {
255
257
  },
256
258
  transportKind: this.transportKind,
257
259
  fetch: this.fetchImpl,
258
- refreshCredentials: async () => {
259
- const refreshed = await handleChatgptAuthTokensRefresh(selection.tokenId);
260
- const current = this.tokenMetadata.get(selection.tokenId);
261
- if (current) current.credentials = {
262
- ...current.credentials,
263
- accessToken: refreshed.accessToken,
264
- accountId: refreshed.chatgptAccountId
265
- };
266
- return {
267
- accessToken: refreshed.accessToken,
268
- accountId: refreshed.chatgptAccountId
269
- };
270
- }
260
+ refreshCredentials: () => this.refreshCredentials(selection.tokenId)
271
261
  }, selection.tokenId);
272
262
  entry = {
273
263
  generation: metadata.generation,
@@ -371,13 +361,15 @@ var OpenAIDispatcher = class OpenAIDispatcher {
371
361
  async getRateLimitsByTokenId(tokenId, signal) {
372
362
  const token = this.tokenMetadata.get(tokenId);
373
363
  if (!token) throw new Error(`openai token ${tokenId} not found`);
364
+ const generation = token.generation;
374
365
  const cached = this.rateLimitsCache.get(tokenId);
375
366
  if (cached && cached.generation === token.generation && Date.now() - cached.cachedAt < OpenAIDispatcher.RATE_LIMITS_CACHE_TTL) return cached;
376
367
  const pending = this.pendingRateLimits.get(tokenId);
377
- if (pending) return pending;
368
+ if (pending?.token === token && pending.generation === generation) return pending.promise;
378
369
  const fetchPromise = (async () => {
379
370
  const result = await readOpenAIQuotaUsage({
380
371
  credentials: token.credentials,
372
+ refreshCredentials: () => this.refreshCredentials(tokenId),
381
373
  fetch: this.fetchImpl,
382
374
  ...signal ? { signal } : {}
383
375
  });
@@ -386,14 +378,43 @@ var OpenAIDispatcher = class OpenAIDispatcher {
386
378
  const entry = {
387
379
  data: result.raw,
388
380
  cachedAt: Date.now(),
389
- generation: token.generation
381
+ generation
390
382
  };
391
- if (this.tokenMetadata.get(tokenId) === token) this.rateLimitsCache.set(tokenId, entry);
383
+ if (this.tokenMetadata.get(tokenId) === token && token.generation === generation) this.rateLimitsCache.set(tokenId, entry);
392
384
  return entry;
393
- })().finally(() => this.pendingRateLimits.delete(tokenId));
394
- this.pendingRateLimits.set(tokenId, fetchPromise);
385
+ })().finally(() => {
386
+ if (this.pendingRateLimits.get(tokenId)?.promise === fetchPromise) this.pendingRateLimits.delete(tokenId);
387
+ });
388
+ this.pendingRateLimits.set(tokenId, {
389
+ token,
390
+ generation,
391
+ promise: fetchPromise
392
+ });
395
393
  return fetchPromise;
396
394
  }
395
+ async refreshCredentials(tokenId) {
396
+ const previous = this.tokenMetadata.get(tokenId);
397
+ const generation = previous?.generation;
398
+ const refreshed = await handleChatgptAuthTokensRefresh(tokenId);
399
+ const credentials = {
400
+ accessToken: refreshed.accessToken,
401
+ accountId: refreshed.chatgptAccountId
402
+ };
403
+ const current = this.tokenMetadata.get(tokenId);
404
+ if (!current?.active) throw new Error(`openai token ${tokenId} is no longer active`);
405
+ if (current === previous && current.generation === generation) {
406
+ current.credentials = {
407
+ ...current.credentials,
408
+ ...credentials
409
+ };
410
+ this.retireClient(tokenId);
411
+ this.invalidateRateLimitsCache(tokenId);
412
+ }
413
+ return {
414
+ accessToken: current.credentials.accessToken,
415
+ accountId: current.credentials.accountId
416
+ };
417
+ }
397
418
  async isQuotaEligible(id, token, signal) {
398
419
  if (token.quotaThreshold === null || token.quotaThreshold === void 0) return true;
399
420
  const generation = token.generation;
@@ -448,4 +469,4 @@ var OpenAIDispatcher = class OpenAIDispatcher {
448
469
  //#endregion
449
470
  export { ImageGenerationError, OpenAIDispatcher };
450
471
 
451
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLWRpc3BhdGNoZXIuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9vcGVuYWkvb3BlbmFpLWRpc3BhdGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcblxuaW1wb3J0IHsgUXVvdGFUaHJlc2hvbGRFeGNlZWRlZEVycm9yIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLnR5cGVzXCI7XG5pbXBvcnQgeyBUb2tlbk1vZGVsIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLm1vZGVsXCI7XG5pbXBvcnQgeyB0eXBlIE9wZW5BSUNyZWRlbnRpYWxzIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLnR5cGVzXCI7XG5pbXBvcnQgeyByZXNvbHZlT3BlbkFJRWZmb3J0IH0gZnJvbSBcIi4uL2NvbW1vbi9lZmZvcnRcIjtcbmltcG9ydCB7XG4gIHR5cGUgR2VuZXJhdGVSZXF1ZXN0LFxuICB0eXBlIEdlbmVyYXRlUmVzdWx0LFxuICB0eXBlIEdlbmVyYXRlU3RyZWFtQ2FsbGJhY2tzLFxuICB0eXBlIEdlbmVyYXRlZEltYWdlLFxuICB0eXBlIFByb3ZpZGVyRGlzcGF0Y2hlcixcbn0gZnJvbSBcIi4uL2NvbW1vbi9wcm92aWRlci1kaXNwYXRjaGVyXCI7XG5pbXBvcnQgeyBTbW9vdGhXZWlnaHRlZFJvdW5kUm9iaW4gfSBmcm9tIFwiLi4vY29tbW9uL3Ntb290aC13ZWlnaHRlZC1yb3VuZC1yb2JpblwiO1xuaW1wb3J0IHtcbiAgdHlwZSBKc29uVmFsdWUsXG4gIHR5cGUgT3BlbkFJUmVzcG9uc2VJdGVtLFxuICB0eXBlIE9wZW5BSVJlc3BvbnNlc09wdGlvbnMsXG59IGZyb20gXCIuL29wZW5haS1iYWNrZW5kLXByb3RvY29sXCI7XG5pbXBvcnQgeyBPcGVuQUlEaXJlY3RDbGllbnQsIHR5cGUgT3BlbkFJRGlyZWN0Q2xpZW50T3B0aW9ucyB9IGZyb20gXCIuL29wZW5haS1kaXJlY3QtY2xpZW50XCI7XG5pbXBvcnQgeyByZWFkT3BlbkFJUXVvdGFVc2FnZSwgdHlwZSBPcGVuQUlSYXRlTGltaXRzV2l0aE1ldGEgfSBmcm9tIFwiLi9vcGVuYWktcXVvdGFcIjtcbmltcG9ydCB7IGhhbmRsZUNoYXRncHRBdXRoVG9rZW5zUmVmcmVzaCB9IGZyb20gXCIuL29wZW5haS1yZWZyZXNoXCI7XG5pbXBvcnQgeyB0eXBlIE9wZW5BSVRyYW5zcG9ydEtpbmQsIHJlc29sdmVPcGVuQUlUcmFuc3BvcnRLaW5kIH0gZnJvbSBcIi4vb3BlbmFpLXRyYW5zcG9ydC1jb25maWdcIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwib3BlbmFpLWRpc3BhdGNoZXJcIl0pO1xuLy8g6rWQ7LK065CcIGNvZGV4IHdvcmtlciDqsIAg6rCV7KCc7ZWY642YIHdhdGNoZG9nLiDtmLjstpzsnpDqsIAgdGltZW91dE1zIOulvCDsg53rnrXtlbTrj4Qg7JqU7LKt7J20XG4vLyDsmIHsm5Dtnogg66ek64us66as7KeAIOyViuuPhOuhnSBkaXJlY3QgdHJhbnNwb3J0IOuPhCDsnKDtlZztlZwg6riw67O4IOyDge2VnOydhCDsnKDsp4DtlZzri6QuXG5jb25zdCBERUZBVUxUX1JFUVVFU1RfVElNRU9VVF9NUyA9IDYwMF8wMDA7XG5cbmV4cG9ydCB0eXBlIEltYWdlRmFpbHVyZUtpbmQgPSBcImdhdGVcIiB8IFwibm90X2NhbGxlZFwiIHwgXCJpbmNvbXBsZXRlXCI7XG5cbmV4cG9ydCBjbGFzcyBJbWFnZUdlbmVyYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcmVhZG9ubHkga2luZDogSW1hZ2VGYWlsdXJlS2luZCxcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiSW1hZ2VHZW5lcmF0aW9uRXJyb3JcIjtcbiAgfVxufVxuXG50eXBlIFRva2VuTWV0YWRhdGEgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzO1xuICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGw7XG4gIHdlaWdodDogbnVtYmVyO1xuICBhY3RpdmU6IGJvb2xlYW47XG4gIGdlbmVyYXRpb246IG51bWJlcjtcbn07XG5cbnR5cGUgVG9rZW5TZWxlY3Rpb24gPSB7IHRva2VuSWQ6IG51bWJlcjsgbWV0YWRhdGE6IFRva2VuTWV0YWRhdGEgfTtcblxuZXhwb3J0IHR5cGUgT3BlbkFJRGlyZWN0Q2xpZW50RmFjdG9yeSA9IChcbiAgb3B0aW9uczogT3BlbkFJRGlyZWN0Q2xpZW50T3B0aW9ucyxcbiAgdG9rZW5JZDogbnVtYmVyLFxuKSA9PiBQaWNrPE9wZW5BSURpcmVjdENsaWVudCwgXCJyZXNwb25zZXNcIj4gJiB7IGNsb3NlPzogKCkgPT4gdm9pZCB9O1xuXG50eXBlIENsaWVudEVudHJ5ID0ge1xuICBnZW5lcmF0aW9uOiBudW1iZXI7XG4gIGNsaWVudDogUGljazxPcGVuQUlEaXJlY3RDbGllbnQsIFwicmVzcG9uc2VzXCI+ICYgeyBjbG9zZT86ICgpID0+IHZvaWQgfTtcbiAgaW5GbGlnaHQ6IG51bWJlcjtcbiAgcmV0aXJlZDogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlbkFJRGlzcGF0Y2hlckRlcGVuZGVuY2llcyB7XG4gIGNsaWVudEZhY3Rvcnk/OiBPcGVuQUlEaXJlY3RDbGllbnRGYWN0b3J5O1xuICBmZXRjaD86IHR5cGVvZiBmZXRjaDtcbn1cblxuZnVuY3Rpb24gYWJvcnRFcnJvcihzaWduYWw6IEFib3J0U2lnbmFsKTogRXJyb3Ige1xuICBjb25zdCByZWFzb24gPSBzaWduYWwucmVhc29uO1xuICByZXR1cm4gcmVhc29uIGluc3RhbmNlb2YgRXJyb3IgPyByZWFzb24gOiBuZXcgRE9NRXhjZXB0aW9uKFwiQWJvcnRlZFwiLCBcIkFib3J0RXJyb3JcIik7XG59XG5cbmZ1bmN0aW9uIGFjdGl2ZVNpZ25hbChzaWduYWw/OiBBYm9ydFNpZ25hbCwgdGltZW91dE1zPzogbnVtYmVyKTogQWJvcnRTaWduYWwge1xuICBjb25zdCB0aW1lb3V0ID0gQWJvcnRTaWduYWwudGltZW91dCh0aW1lb3V0TXMgPz8gREVGQVVMVF9SRVFVRVNUX1RJTUVPVVRfTVMpO1xuICByZXR1cm4gc2lnbmFsID8gQWJvcnRTaWduYWwuYW55KFtzaWduYWwsIHRpbWVvdXRdKSA6IHRpbWVvdXQ7XG59XG5cbmZ1bmN0aW9uIHF1b3RhTWVzc2FnZShlbnRyaWVzOiBBcnJheTx7IG5hbWU6IHN0cmluZzsgdGhyZXNob2xkOiBudW1iZXIgfT4pOiBzdHJpbmcge1xuICBjb25zdCBkZXRhaWwgPSBlbnRyaWVzLm1hcCgoZSkgPT4gYCR7ZS5uYW1lfSAodGhyZXNob2xkICR7ZS50aHJlc2hvbGR9JSlgKS5qb2luKFwiLCBcIik7XG4gIHJldHVybiBkZXRhaWxcbiAgICA/IGBBbGwgb3BlbmFpIHRva2VucyBleGNlZWRlZCBxdW90YSB0aHJlc2hvbGQ6ICR7ZGV0YWlsfWBcbiAgICA6IFwiQWxsIG9wZW5haSB0b2tlbnMgZXhjZWVkZWQgcXVvdGEgdGhyZXNob2xkXCI7XG59XG5cbmZ1bmN0aW9uIGlucHV0SXRlbXMocmVxOiBHZW5lcmF0ZVJlcXVlc3QpOiBPcGVuQUlSZXNwb25zZUl0ZW1bXSB7XG4gIGNvbnN0IGhpc3RvcnkgPSAocmVxLmNvbGRIaXN0b3J5ID8/IFtdKSBhcyBPcGVuQUlSZXNwb25zZUl0ZW1bXTtcbiAgY29uc3QgY29udGVudDogT3BlbkFJUmVzcG9uc2VJdGVtW10gPSByZXEuY29sZElucHV0Lm1hcCgoaW5wdXQpID0+IHtcbiAgICBpZiAoaW5wdXQudHlwZSA9PT0gXCJ0ZXh0XCIpIHJldHVybiB7IHR5cGU6IFwiaW5wdXRfdGV4dFwiLCB0ZXh0OiBpbnB1dC50ZXh0IH07XG4gICAgaWYgKGlucHV0LnR5cGUgPT09IFwiaW1hZ2VcIikgcmV0dXJuIHsgdHlwZTogXCJpbnB1dF9pbWFnZVwiLCBpbWFnZV91cmw6IGlucHV0LnVybCB9O1xuICAgIGlmIChpbnB1dC50eXBlID09PSBcImxvY2FsSW1hZ2VcIikgcmV0dXJuIHsgdHlwZTogXCJpbnB1dF9pbWFnZVwiLCBpbWFnZV91cmw6IGlucHV0LnBhdGggfTtcbiAgICByZXR1cm4geyB0eXBlOiBcImlucHV0X3RleHRcIiwgdGV4dDogYCR7aW5wdXQubmFtZX06ICR7aW5wdXQucGF0aH1gIH07XG4gIH0pO1xuICByZXR1cm4gWy4uLmhpc3RvcnksIHsgdHlwZTogXCJtZXNzYWdlXCIsIHJvbGU6IFwidXNlclwiLCBjb250ZW50IH1dO1xufVxuXG5mdW5jdGlvbiBhc1JlYXNvbmluZyhyZXE6IEdlbmVyYXRlUmVxdWVzdCk6IE9wZW5BSVJlc3BvbnNlc09wdGlvbnNbXCJyZWFzb25pbmdcIl0gfCB1bmRlZmluZWQge1xuICBjb25zdCBzdW1tYXJ5ID1cbiAgICByZXEucmVhc29uaW5nU3VtbWFyeSAmJiByZXEucmVhc29uaW5nU3VtbWFyeSAhPT0gXCJub25lXCIgPyByZXEucmVhc29uaW5nU3VtbWFyeSA6IHVuZGVmaW5lZDtcbiAgLy8gQ29kZXgg7Ja07ZyYwrfrqqjrjbgg7IOB7ZWcIOuwluydmCBlZmZvcnQg64qUIOyXrOq4sOyEnCDsobDsmqntnogg67KE66aw64ukKOuwseyXlOuTnCDquLDrs7jqsJIg7KCB7JqpKS5cbiAgY29uc3QgZWZmb3J0ID0gcmVzb2x2ZU9wZW5BSUVmZm9ydChyZXEubW9kZWwgPz8gXCJcIiwgcmVxLmVmZm9ydCk7XG4gIGlmICghZWZmb3J0ICYmICFzdW1tYXJ5KSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4ge1xuICAgIC4uLihlZmZvcnQgPyB7IGVmZm9ydCB9IDoge30pLFxuICAgIC4uLihzdW1tYXJ5XG4gICAgICA/IHtcbiAgICAgICAgICBzdW1tYXJ5OiBzdW1tYXJ5IGFzIE5vbk51bGxhYmxlPE9wZW5BSVJlc3BvbnNlc09wdGlvbnNbXCJyZWFzb25pbmdcIl0+W1wic3VtbWFyeVwiXSxcbiAgICAgICAgfVxuICAgICAgOiB7fSksXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlcXVlc3RPcHRpb25zKHJlcTogR2VuZXJhdGVSZXF1ZXN0KTogT3BlbkFJUmVzcG9uc2VzT3B0aW9ucyB7XG4gIHJldHVybiB7XG4gICAgbW9kZWw6IHJlcS5tb2RlbCA/PyBcIlwiLFxuICAgIC4uLihyZXEuc3lzdGVtUHJvbXB0ID8geyBpbnN0cnVjdGlvbnM6IHJlcS5zeXN0ZW1Qcm9tcHQgfSA6IHt9KSxcbiAgICBoaXN0b3J5OiBpbnB1dEl0ZW1zKHJlcSksXG4gICAgLi4uKGFzUmVhc29uaW5nKHJlcSkgPyB7IHJlYXNvbmluZzogYXNSZWFzb25pbmcocmVxKSB9IDoge30pLFxuICAgIC4uLihyZXEudmVyYm9zaXR5ID8geyB2ZXJib3NpdHk6IHJlcS52ZXJib3NpdHkgYXMgT3BlbkFJUmVzcG9uc2VzT3B0aW9uc1tcInZlcmJvc2l0eVwiXSB9IDoge30pLFxuICAgIC4uLihyZXEuc2VydmljZVRpZXJcbiAgICAgID8geyBzZXJ2aWNlVGllcjogcmVxLnNlcnZpY2VUaWVyID09PSBcImZhc3RcIiA/IFwicHJpb3JpdHlcIiA6IHJlcS5zZXJ2aWNlVGllciB9XG4gICAgICA6IHt9KSxcbiAgICAuLi4ocmVxLnByb21wdENhY2hlS2V5ID8geyBwcm9tcHRDYWNoZUtleTogcmVxLnByb21wdENhY2hlS2V5IH0gOiB7fSksXG4gICAgLi4uKHJlcS5vdXRwdXRTY2hlbWEgPyB7IG91dHB1dFNjaGVtYTogeyBzY2hlbWE6IHJlcS5vdXRwdXRTY2hlbWEgYXMgSnNvblZhbHVlIH0gfSA6IHt9KSxcbiAgICAuLi4ocmVxLmltYWdlR2VuZXJhdGlvblxuICAgICAgPyB7IGltYWdlR2VuZXJhdGlvbjogcmVxLmltYWdlR2VuZXJhdGlvbk9wdGlvbnMgPyB7IC4uLnJlcS5pbWFnZUdlbmVyYXRpb25PcHRpb25zIH0gOiB0cnVlIH1cbiAgICAgIDoge30pLFxuICB9O1xufVxuXG4vKipcbiAqIERpcmVjdCBPcGVuQUkgZGlzcGF0Y2hlciDigJQgQW50aHJvcGljIOqzvCDrj5nsnbztlZwgc3RhdGVsZXNzIOyLpO2WiSDrqqjrjbguXG4gKlxuICog7JqU7LKtID0g7Yag7YGwIOyEoO2DnShxdW90YSBnYXRlICsgd2VpZ2h0ZWQgcm91bmQtcm9iaW4gKyBjYWNoZSBhZmZpbml0eSDshKDtmLgpIOKGkiBIVFRQUy9XU1xuICog7KCE7IahLiBwZXJtaXQv7YGQIOqwmeydgCDrj5nsi5zshLEg7IOB7ZWc7J2AIOuRkOyngCDslYrripTri6Q6IOyghOyGoeydgCBmZXRjaCDtlZwg67KI7J206528IOuhnOy7rCDsnpDsm5DsnbRcbiAqIO2drOyGjO2VmOyngCDslYrqs6AsIOyDgeulmCDsoJztlZzsnYAg67Cx7JeU65Oc7J2YIOydkeuLtSg0Mjkg65OxKeydtCDsp4Tsi6TsnbTri6QuIHdvcmtlciBwb29sIOyLnOygiOydmFxuICog7YGQIOydmOuvuOuhoChTRVJWRVJfQlVTWSwg7YGQIO2DgOyehOyVhOybgynsnYAg7J20IOyghO2ZmOycvOuhnCDsoJzqsbDrkJDri6QuXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuQUlEaXNwYXRjaGVyIGltcGxlbWVudHMgUHJvdmlkZXJEaXNwYXRjaGVyIHtcbiAgcmVhZG9ubHkgdG9rZW5NZXRhZGF0YSA9IG5ldyBNYXA8bnVtYmVyLCBUb2tlbk1ldGFkYXRhPigpO1xuICByZWFkb25seSB0cmFuc3BvcnRLaW5kOiBPcGVuQUlUcmFuc3BvcnRLaW5kO1xuICByZWFkb25seSByYXRlTGltaXRzQ2FjaGUgPSBuZXcgTWFwPG51bWJlciwgT3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhICYgeyBnZW5lcmF0aW9uOiBudW1iZXIgfT4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBwZW5kaW5nUmF0ZUxpbWl0cyA9IG5ldyBNYXA8XG4gICAgbnVtYmVyLFxuICAgIFByb21pc2U8T3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhICYgeyBnZW5lcmF0aW9uOiBudW1iZXIgfT5cbiAgPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudHMgPSBuZXcgTWFwPG51bWJlciwgQ2xpZW50RW50cnk+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmV0aXJlZENsaWVudHMgPSBuZXcgU2V0PENsaWVudEVudHJ5PigpO1xuICBzdGF0aWMgcmVhZG9ubHkgUkFURV9MSU1JVFNfQ0FDSEVfVFRMID0gNjBfMDAwO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgc2VsZWN0b3IgPSBuZXcgU21vb3RoV2VpZ2h0ZWRSb3VuZFJvYmluKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50RmFjdG9yeTogT3BlbkFJRGlyZWN0Q2xpZW50RmFjdG9yeTtcbiAgcHJpdmF0ZSByZWFkb25seSBmZXRjaEltcGw6IHR5cGVvZiBmZXRjaDtcbiAgcHJpdmF0ZSByZWFkb25seSBxdW90YUJsb2NrZWQgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgcHJpdmF0ZSBpbkZsaWdodENvdW50ID0gMDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICB0cmFuc3BvcnRLaW5kOiBPcGVuQUlUcmFuc3BvcnRLaW5kID0gcmVzb2x2ZU9wZW5BSVRyYW5zcG9ydEtpbmQoKSxcbiAgICBkZXBlbmRlbmNpZXM6IE9wZW5BSURpc3BhdGNoZXJEZXBlbmRlbmNpZXMgPSB7fSxcbiAgKSB7XG4gICAgdGhpcy50cmFuc3BvcnRLaW5kID0gdHJhbnNwb3J0S2luZDtcbiAgICB0aGlzLmNsaWVudEZhY3RvcnkgPVxuICAgICAgZGVwZW5kZW5jaWVzLmNsaWVudEZhY3RvcnkgPz8gKChvcHRpb25zKSA9PiBuZXcgT3BlbkFJRGlyZWN0Q2xpZW50KG9wdGlvbnMpKTtcbiAgICB0aGlzLmZldGNoSW1wbCA9IGRlcGVuZGVuY2llcy5mZXRjaCA/PyBmZXRjaDtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgcm93cyB9ID0gYXdhaXQgVG9rZW5Nb2RlbC5maW5kTWFueShcIkFcIik7XG4gICAgZm9yIChjb25zdCByb3cgb2Ygcm93cykge1xuICAgICAgaWYgKHJvdy5wcm92aWRlciAhPT0gXCJvcGVuYWlcIikgY29udGludWU7XG4gICAgICB0aGlzLnNldFRva2VuKFxuICAgICAgICByb3cuaWQsXG4gICAgICAgIHJvdy5uYW1lLFxuICAgICAgICByb3cuY3JlZGVudGlhbHMgYXMgT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgICAgIHJvdy5xdW90YV90aHJlc2hvbGQsXG4gICAgICAgIHJvdy53ZWlnaHQsXG4gICAgICAgIHJvdy5hY3RpdmUsXG4gICAgICApO1xuICAgIH1cbiAgICBsb2dnZXIuaW5mbyhgc3RhcnRlZCBkaXJlY3QgT3BlbkFJIHJ1bnRpbWUgd2l0aCAke3RoaXMudG9rZW5NZXRhZGF0YS5zaXplfSB0b2tlbnNgKTtcbiAgfVxuXG4gIGFzeW5jIHN0b3AoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgZm9yIChjb25zdCB7IGNsaWVudCB9IG9mIHRoaXMuY2xpZW50cy52YWx1ZXMoKSkgY2xpZW50LmNsb3NlPy4oKTtcbiAgICB0aGlzLmNsaWVudHMuY2xlYXIoKTtcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHRoaXMucmV0aXJlZENsaWVudHMpIGVudHJ5LmNsaWVudC5jbG9zZT8uKCk7XG4gICAgdGhpcy5yZXRpcmVkQ2xpZW50cy5jbGVhcigpO1xuICAgIHRoaXMudG9rZW5NZXRhZGF0YS5jbGVhcigpO1xuICAgIHRoaXMucmF0ZUxpbWl0c0NhY2hlLmNsZWFyKCk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWQuY2xlYXIoKTtcbiAgICB0aGlzLnNlbGVjdG9yLnJlc2V0U2NvcmVzKCk7XG4gIH1cblxuICBhc3luYyBvblRva2VuQWRkZWQoXG4gICAgaWQ6IG51bWJlcixcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgIHF1b3RhVGhyZXNob2xkPzogbnVtYmVyIHwgbnVsbCxcbiAgICB3ZWlnaHQgPSAxLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnNldFRva2VuKGlkLCBuYW1lLCBjcmVkZW50aWFscywgcXVvdGFUaHJlc2hvbGQsIHdlaWdodCwgdHJ1ZSk7XG4gIH1cblxuICBhc3luYyBvblRva2VuVXBkYXRlZChcbiAgICBpZDogbnVtYmVyLFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsLFxuICAgIHdlaWdodCA9IDEsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG9sZCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoaWQpO1xuICAgIHRoaXMuc2V0VG9rZW4oaWQsIG5hbWUsIGNyZWRlbnRpYWxzLCBxdW90YVRocmVzaG9sZCwgd2VpZ2h0LCBvbGQ/LmFjdGl2ZSA/PyB0cnVlKTtcbiAgfVxuXG4gIGFzeW5jIG9uVG9rZW5SZW1vdmVkKGlkOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnJldGlyZUNsaWVudChpZCk7XG4gICAgdGhpcy50b2tlbk1ldGFkYXRhLmRlbGV0ZShpZCk7XG4gICAgdGhpcy5zZWxlY3Rvci5yZW1vdmVUb2tlbihpZCk7XG4gICAgdGhpcy5pbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKGlkKTtcbiAgICB0aGlzLnF1b3RhQmxvY2tlZC5kZWxldGUoaWQpO1xuICB9XG5cbiAgb25Ub2tlbkRlYWN0aXZhdGVkKGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoaWQpO1xuICAgIGlmICh0b2tlbikgdG9rZW4uYWN0aXZlID0gZmFsc2U7XG4gICAgdGhpcy5zZWxlY3Rvci5yZXNldFNjb3JlcygpO1xuICB9XG5cbiAgb25Ub2tlbkFjdGl2YXRlZChpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICBpZiAodG9rZW4pIHRva2VuLmFjdGl2ZSA9IHRydWU7XG4gICAgdGhpcy5zZWxlY3Rvci5yZXNldFNjb3JlcygpO1xuICB9XG5cbiAgYXN5bmMgcmVwbGFjZVRva2VucyhcbiAgICByb3dzOiBBcnJheTx7XG4gICAgICBpZDogbnVtYmVyO1xuICAgICAgbmFtZTogc3RyaW5nO1xuICAgICAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzO1xuICAgICAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsO1xuICAgICAgd2VpZ2h0OiBudW1iZXI7XG4gICAgfT4sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGlkcyA9IG5ldyBTZXQocm93cy5tYXAoKHIpID0+IHIuaWQpKTtcbiAgICBmb3IgKGNvbnN0IGlkIG9mIHRoaXMudG9rZW5NZXRhZGF0YS5rZXlzKCkpIGlmICghaWRzLmhhcyhpZCkpIGF3YWl0IHRoaXMub25Ub2tlblJlbW92ZWQoaWQpO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpXG4gICAgICBhd2FpdCB0aGlzLm9uVG9rZW5VcGRhdGVkKHJvdy5pZCwgcm93Lm5hbWUsIHJvdy5jcmVkZW50aWFscywgcm93LnF1b3RhVGhyZXNob2xkLCByb3cud2VpZ2h0KTtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlKHJlcTogR2VuZXJhdGVSZXF1ZXN0KTogUHJvbWlzZTxHZW5lcmF0ZVJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnJ1bihyZXEpO1xuICB9XG5cbiAgYXN5bmMgZ2VuZXJhdGVTdHJlYW0ocmVxOiBHZW5lcmF0ZVJlcXVlc3QsIGNiOiBHZW5lcmF0ZVN0cmVhbUNhbGxiYWNrcyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmIChyZXEuaW1hZ2VHZW5lcmF0aW9uKVxuICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFxuICAgICAgICBcImdhdGVcIixcbiAgICAgICAgXCJpbWFnZSBnZW5lcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgb24gdGhlIHN0cmVhbWluZyBwYXRoXCIsXG4gICAgICApO1xuICAgIHRyeSB7XG4gICAgICBjYi5vbkNvbXBsZXRlKGF3YWl0IHRoaXMucnVuKHJlcSwgY2Iub25EZWx0YSkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjYi5vbkVycm9yKGVycm9yIGFzIEVycm9yKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8vIGdlbmVyYXRlL2dlbmVyYXRlU3RyZWFtIOqzte2GtSDsi6Ttlokg4oCUIO2GoO2BsCDshKDtg53qs7wgaW4tZmxpZ2h0IOynkeqzhOulvCDtlZwg6rOz7JeQIOuRlOuLpC5cbiAgcHJpdmF0ZSBhc3luYyBydW4oXG4gICAgcmVxOiBHZW5lcmF0ZVJlcXVlc3QsXG4gICAgb25EZWx0YT86ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQsXG4gICk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICBjb25zdCBzaWduYWwgPSBhY3RpdmVTaWduYWwocmVxLmFib3J0U2lnbmFsLCByZXEudGltZW91dE1zKTtcbiAgICBpZiAoc2lnbmFsLmFib3J0ZWQpIHRocm93IGFib3J0RXJyb3Ioc2lnbmFsKTtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSBhd2FpdCB0aGlzLnNlbGVjdFRva2VuKFxuICAgICAgcmVxLnByZWZlcnJlZFRva2VuSWQsXG4gICAgICByZXEucmVxdWlyZVByZWZlcnJlZFRva2VuID8/IGZhbHNlLFxuICAgICAgc2lnbmFsLFxuICAgICk7XG4gICAgdGhpcy5pbkZsaWdodENvdW50Kys7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChzaWduYWwuYWJvcnRlZCkgdGhyb3cgYWJvcnRFcnJvcihzaWduYWwpO1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucnVuRGlyZWN0KHNlbGVjdGlvbiwgeyAuLi5yZXEsIGFib3J0U2lnbmFsOiBzaWduYWwgfSwgb25EZWx0YSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuaW5GbGlnaHRDb3VudC0tO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcnVuRGlyZWN0KFxuICAgIHNlbGVjdGlvbjogVG9rZW5TZWxlY3Rpb24sXG4gICAgcmVxOiBHZW5lcmF0ZVJlcXVlc3QsXG4gICAgb25EZWx0YT86ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQsXG4gICk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICBjb25zdCBzdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuICAgIGxldCBmaXJzdERlbHRhQXQ6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICBsZXQgdGV4dCA9IFwiXCI7XG4gICAgbGV0IHVzYWdlID0ge1xuICAgICAgdG90YWxUb2tlbnM6IDAsXG4gICAgICBpbnB1dFRva2VuczogMCxcbiAgICAgIG91dHB1dFRva2VuczogMCxcbiAgICAgIGNhY2hlZElucHV0VG9rZW5zOiAwLFxuICAgICAgcmVhc29uaW5nT3V0cHV0VG9rZW5zOiAwLFxuICAgIH07XG4gICAgY29uc3QgaW1hZ2VzOiBHZW5lcmF0ZWRJbWFnZVtdID0gW107XG4gICAgbGV0IGltYWdlQXR0ZW1wdGVkID0gZmFsc2U7XG4gICAgbGV0IHNlcnZpbmdNb2RlbCA9IHJlcS5tb2RlbCA/PyBcIlwiO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gc2VsZWN0aW9uLm1ldGFkYXRhO1xuICAgIGNvbnN0IGNsaWVudEVudHJ5ID0gdGhpcy5hY3F1aXJlQ2xpZW50KHNlbGVjdGlvbik7XG4gICAgdHJ5IHtcbiAgICAgIGZvciBhd2FpdCAoY29uc3QgZXZlbnQgb2YgY2xpZW50RW50cnkuY2xpZW50LnJlc3BvbnNlcyhcbiAgICAgICAgcmVxdWVzdE9wdGlvbnMocmVxKSxcbiAgICAgICAgcmVxLmFib3J0U2lnbmFsLFxuICAgICAgKSkge1xuICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJ0ZXh0LWRlbHRhXCIpIHtcbiAgICAgICAgICBmaXJzdERlbHRhQXQgPz89IERhdGUubm93KCk7XG4gICAgICAgICAgdGV4dCArPSBldmVudC50ZXh0O1xuICAgICAgICAgIG9uRGVsdGE/LihldmVudC50ZXh0KTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSBcImltYWdlXCIpIHtcbiAgICAgICAgICBpbWFnZUF0dGVtcHRlZCA9IHRydWU7XG4gICAgICAgICAgaW1hZ2VzLnB1c2goeyBkYXRhOiBldmVudC5iYXNlNjQsIHJldmlzZWRQcm9tcHQ6IGV2ZW50LnJldmlzZWRQcm9tcHQgPz8gbnVsbCB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSBcIm91dHB1dC1pdGVtXCIgJiYgZXZlbnQuaXRlbS50eXBlID09PSBcImltYWdlX2dlbmVyYXRpb25fY2FsbFwiKSB7XG4gICAgICAgICAgaW1hZ2VBdHRlbXB0ZWQgPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwiY29tcGxldGVkXCIgJiYgZXZlbnQudXNhZ2UpIHtcbiAgICAgICAgICBzZXJ2aW5nTW9kZWwgPSBldmVudC5tb2RlbCA/PyBzZXJ2aW5nTW9kZWw7XG4gICAgICAgICAgdXNhZ2UgPSB7XG4gICAgICAgICAgICB0b3RhbFRva2VuczogZXZlbnQudXNhZ2UudG90YWxUb2tlbnMsXG4gICAgICAgICAgICBpbnB1dFRva2VuczogZXZlbnQudXNhZ2UuaW5wdXRUb2tlbnMsXG4gICAgICAgICAgICBvdXRwdXRUb2tlbnM6IGV2ZW50LnVzYWdlLm91dHB1dFRva2VucyxcbiAgICAgICAgICAgIGNhY2hlZElucHV0VG9rZW5zOiBldmVudC51c2FnZS5jYWNoZWRJbnB1dFRva2VucyxcbiAgICAgICAgICAgIHJlYXNvbmluZ091dHB1dFRva2VuczogZXZlbnQudXNhZ2UucmVhc29uaW5nVG9rZW5zLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gXCJjb21wbGV0ZWRcIikge1xuICAgICAgICAgIHNlcnZpbmdNb2RlbCA9IGV2ZW50Lm1vZGVsID8/IHNlcnZpbmdNb2RlbDtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSBcImVycm9yXCIpIHtcbiAgICAgICAgICBpZiAocmVxLmltYWdlR2VuZXJhdGlvbilcbiAgICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcImluY29tcGxldGVcIiwgZXZlbnQuZXJyb3IubWVzc2FnZSk7XG4gICAgICAgICAgdGhyb3cgZXZlbnQuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5yZWxlYXNlQ2xpZW50KGNsaWVudEVudHJ5KTtcbiAgICB9XG4gICAgaWYgKHJlcS5pbWFnZUdlbmVyYXRpb24gJiYgaW1hZ2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFxuICAgICAgICBpbWFnZUF0dGVtcHRlZCA/IFwiaW5jb21wbGV0ZVwiIDogXCJub3RfY2FsbGVkXCIsXG4gICAgICAgIGltYWdlQXR0ZW1wdGVkXG4gICAgICAgICAgPyBcImltYWdlIGdlbmVyYXRpb24gZGlkIG5vdCBjb21wbGV0ZVwiXG4gICAgICAgICAgOiBcIm1vZGVsIGRpZCBub3QgY2FsbCBpbWFnZSBnZW5lcmF0aW9uXCIsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgdGV4dCxcbiAgICAgIHRva2VuTmFtZTogbWV0YWRhdGEubmFtZSxcbiAgICAgIHVzYWdlLFxuICAgICAgZHVyYXRpb25NczogRGF0ZS5ub3coKSAtIHN0YXJ0ZWRBdCxcbiAgICAgIHR0ZnRNczogZmlyc3REZWx0YUF0ID09PSB1bmRlZmluZWQgPyBudWxsIDogZmlyc3REZWx0YUF0IC0gc3RhcnRlZEF0LFxuICAgICAgbW9kZWw6IHNlcnZpbmdNb2RlbCxcbiAgICAgIHRocmVhZENvb3JkOiB7IHdvcmtlcklkOiBzZWxlY3Rpb24udG9rZW5JZCwgdGhyZWFkSWQ6IHJlcS5wcm9tcHRDYWNoZUtleSA/PyBcIlwiLCBlcG9jaDogLTEgfSxcbiAgICAgIC4uLihpbWFnZXMubGVuZ3RoID8geyBpbWFnZXMgfSA6IHt9KSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIOyEuOuMgOqwgCDrsJTrgJAgY2xpZW50IOuKlCDsgqzsmqkg7KSR7J24IOyalOyyreydtCDrgZ3rgpwg65Kk7JeQIOuLq+uKlOuLpC4gKi9cbiAgcHJpdmF0ZSBhY3F1aXJlQ2xpZW50KHNlbGVjdGlvbjogVG9rZW5TZWxlY3Rpb24pOiBDbGllbnRFbnRyeSB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBzZWxlY3Rpb24ubWV0YWRhdGE7XG4gICAgbGV0IGVudHJ5ID0gdGhpcy5jbGllbnRzLmdldChzZWxlY3Rpb24udG9rZW5JZCk7XG4gICAgaWYgKGVudHJ5ICYmIGVudHJ5LmdlbmVyYXRpb24gIT09IG1ldGFkYXRhLmdlbmVyYXRpb24pIHtcbiAgICAgIHRoaXMucmV0aXJlQ2xpZW50KHNlbGVjdGlvbi50b2tlbklkKTtcbiAgICAgIGVudHJ5ID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBpZiAoIWVudHJ5KSB7XG4gICAgICBjb25zdCBjbGllbnQgPSB0aGlzLmNsaWVudEZhY3RvcnkoXG4gICAgICAgIHtcbiAgICAgICAgICBjcmVkZW50aWFsczoge1xuICAgICAgICAgICAgYWNjZXNzVG9rZW46IG1ldGFkYXRhLmNyZWRlbnRpYWxzLmFjY2Vzc1Rva2VuLFxuICAgICAgICAgICAgYWNjb3VudElkOiBtZXRhZGF0YS5jcmVkZW50aWFscy5hY2NvdW50SWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0cmFuc3BvcnRLaW5kOiB0aGlzLnRyYW5zcG9ydEtpbmQsXG4gICAgICAgICAgZmV0Y2g6IHRoaXMuZmV0Y2hJbXBsLFxuICAgICAgICAgIHJlZnJlc2hDcmVkZW50aWFsczogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVmcmVzaGVkID0gYXdhaXQgaGFuZGxlQ2hhdGdwdEF1dGhUb2tlbnNSZWZyZXNoKHNlbGVjdGlvbi50b2tlbklkKTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHNlbGVjdGlvbi50b2tlbklkKTtcbiAgICAgICAgICAgIGlmIChjdXJyZW50KVxuICAgICAgICAgICAgICBjdXJyZW50LmNyZWRlbnRpYWxzID0ge1xuICAgICAgICAgICAgICAgIC4uLmN1cnJlbnQuY3JlZGVudGlhbHMsXG4gICAgICAgICAgICAgICAgYWNjZXNzVG9rZW46IHJlZnJlc2hlZC5hY2Nlc3NUb2tlbixcbiAgICAgICAgICAgICAgICBhY2NvdW50SWQ6IHJlZnJlc2hlZC5jaGF0Z3B0QWNjb3VudElkLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgcmV0dXJuIHsgYWNjZXNzVG9rZW46IHJlZnJlc2hlZC5hY2Nlc3NUb2tlbiwgYWNjb3VudElkOiByZWZyZXNoZWQuY2hhdGdwdEFjY291bnRJZCB9O1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHNlbGVjdGlvbi50b2tlbklkLFxuICAgICAgKTtcbiAgICAgIGVudHJ5ID0geyBnZW5lcmF0aW9uOiBtZXRhZGF0YS5nZW5lcmF0aW9uLCBjbGllbnQsIGluRmxpZ2h0OiAwLCByZXRpcmVkOiBmYWxzZSB9O1xuICAgICAgdGhpcy5jbGllbnRzLnNldChzZWxlY3Rpb24udG9rZW5JZCwgZW50cnkpO1xuICAgIH1cbiAgICBlbnRyeS5pbkZsaWdodCsrO1xuICAgIHJldHVybiBlbnRyeTtcbiAgfVxuXG4gIHByaXZhdGUgcmVsZWFzZUNsaWVudChlbnRyeTogQ2xpZW50RW50cnkpOiB2b2lkIHtcbiAgICBlbnRyeS5pbkZsaWdodCA9IE1hdGgubWF4KDAsIGVudHJ5LmluRmxpZ2h0IC0gMSk7XG4gICAgaWYgKGVudHJ5LnJldGlyZWQgJiYgZW50cnkuaW5GbGlnaHQgPT09IDApIHtcbiAgICAgIHRoaXMucmV0aXJlZENsaWVudHMuZGVsZXRlKGVudHJ5KTtcbiAgICAgIGVudHJ5LmNsaWVudC5jbG9zZT8uKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIG1hcCDsl5DshJwg65a87Ja064K06rOgLCDsp4Ttlokg7KSR7J24IOyalOyyreydtCDsl4bsnYQg65WM66eMIOymieyLnCDri6vripTri6QuICovXG4gIHByaXZhdGUgcmV0aXJlQ2xpZW50KHRva2VuSWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5jbGllbnRzLmdldCh0b2tlbklkKTtcbiAgICBpZiAoIWVudHJ5KSByZXR1cm47XG4gICAgdGhpcy5jbGllbnRzLmRlbGV0ZSh0b2tlbklkKTtcbiAgICBlbnRyeS5yZXRpcmVkID0gdHJ1ZTtcbiAgICBpZiAoZW50cnkuaW5GbGlnaHQgPT09IDApIGVudHJ5LmNsaWVudC5jbG9zZT8uKCk7XG4gICAgZWxzZSB0aGlzLnJldGlyZWRDbGllbnRzLmFkZChlbnRyeSk7XG4gIH1cblxuICAvKipcbiAgICog7Yag7YGwIOyEoO2DnSDigJQgcXVvdGEgZ2F0ZSDrpbwg7Ya16rO87ZWcIGFjdGl2ZSDthqDtgbAg7KSR7JeQ7IScIOqzoOuluOuLpC4gY2FjaGUgYWZmaW5pdHkg7ISg7Zi4XG4gICAqIO2GoO2BsOydtCBlbGlnaWJsZSDtlZjrqbQg6re4IO2MkOygleunjOycvOuhnCDsponsi5wg6rKw7KCV7ZWY6rOgKOyghOyytCBzd2VlcCDsg53rnrUsIHdlaWdodGVkIOyDge2DnFxuICAgKiDruYTrs4Dqsr0pLCDslYTri4jrqbQg67OR66CsIHF1b3RhIO2MkOyglSDtm4Qgc21vb3RoIHdlaWdodGVkIHJvdW5kLXJvYmluLiDrj5nsi5zshLEg7IOB7ZWc7J20XG4gICAqIOyXhuycvOuvgOuhnCBcIuu5iCDsnpDrpqxcIiDqsJzrhZDrj4Qg7JeG64ukIOKAlCDshKDtg50g7KaJ7IucIOyLpO2WieydtOuLpC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc2VsZWN0VG9rZW4oXG4gICAgcHJlZmVycmVkVG9rZW5JZDogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICAgIHJlcXVpcmVQcmVmZXJyZWRUb2tlbjogYm9vbGVhbixcbiAgICBzaWduYWw6IEFib3J0U2lnbmFsLFxuICApOiBQcm9taXNlPFRva2VuU2VsZWN0aW9uPiB7XG4gICAgaWYgKHByZWZlcnJlZFRva2VuSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgcHJlZmVycmVkID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldChwcmVmZXJyZWRUb2tlbklkKTtcbiAgICAgIGlmIChwcmVmZXJyZWQ/LmFjdGl2ZSAmJiAoYXdhaXQgdGhpcy5pc1F1b3RhRWxpZ2libGUocHJlZmVycmVkVG9rZW5JZCwgcHJlZmVycmVkLCBzaWduYWwpKSkge1xuICAgICAgICByZXR1cm4geyB0b2tlbklkOiBwcmVmZXJyZWRUb2tlbklkLCBtZXRhZGF0YTogcHJlZmVycmVkIH07XG4gICAgICB9XG4gICAgICBpZiAocmVxdWlyZVByZWZlcnJlZFRva2VuKSB7XG4gICAgICAgIGlmICghcHJlZmVycmVkPy5hY3RpdmUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFByZWZlcnJlZCBvcGVuYWkgdG9rZW4gJHtwcmVmZXJyZWRUb2tlbklkfSBpcyBub3QgYXZhaWxhYmxlYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGhyZXNob2xkID0gcHJlZmVycmVkLnF1b3RhVGhyZXNob2xkO1xuICAgICAgICBpZiAodGhyZXNob2xkICE9PSBudWxsICYmIHRocmVzaG9sZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFF1b3RhVGhyZXNob2xkRXhjZWVkZWRFcnJvcihcbiAgICAgICAgICAgIHF1b3RhTWVzc2FnZShbeyBuYW1lOiBwcmVmZXJyZWQubmFtZSwgdGhyZXNob2xkIH1dKSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8g7Yag7YGw67OEIHF1b3RhIO2MkOygleydgCDshJzroZwg64+F66a97J206528IOuzkeugrOuhnCDigJQg7KeB66CsIOuMgOq4sOuKlCDsvZzrk5wg7LqQ7Iuc7JeQ7IScXG4gICAgLy8g7Yag7YGwIOyImCDDlyDsobDtmowg7KeA7Jew66eM7YG8IOyalOyyrSDsi5zsnpHsnYQg64qm7LaY64ukLlxuICAgIGNvbnN0IGNoZWNrcyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgWy4uLnRoaXMudG9rZW5NZXRhZGF0YS5lbnRyaWVzKCldXG4gICAgICAgIC5maWx0ZXIoKFssIHRva2VuXSkgPT4gdG9rZW4uYWN0aXZlKVxuICAgICAgICAubWFwKGFzeW5jIChbaWQsIHRva2VuXSkgPT4gKHtcbiAgICAgICAgICBpZCxcbiAgICAgICAgICB0b2tlbixcbiAgICAgICAgICBlbGlnaWJsZTogYXdhaXQgdGhpcy5pc1F1b3RhRWxpZ2libGUoaWQsIHRva2VuLCBzaWduYWwpLFxuICAgICAgICB9KSksXG4gICAgKTtcbiAgICBjb25zdCBlbGlnaWJsZSA9IG5ldyBTZXQoY2hlY2tzLmZpbHRlcigoYykgPT4gYy5lbGlnaWJsZSkubWFwKChjKSA9PiBjLmlkKSk7XG4gICAgaWYgKGVsaWdpYmxlLnNpemUgPT09IDApIHtcbiAgICAgIGNvbnN0IG92ZXIgPSBjaGVja3NcbiAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAoYykgPT5cbiAgICAgICAgICAgICFjLmVsaWdpYmxlICYmIGMudG9rZW4ucXVvdGFUaHJlc2hvbGQgIT09IG51bGwgJiYgYy50b2tlbi5xdW90YVRocmVzaG9sZCAhPT0gdW5kZWZpbmVkLFxuICAgICAgICApXG4gICAgICAgIC5tYXAoKGMpID0+ICh7IG5hbWU6IGMudG9rZW4ubmFtZSwgdGhyZXNob2xkOiBjLnRva2VuLnF1b3RhVGhyZXNob2xkIGFzIG51bWJlciB9KSk7XG4gICAgICBpZiAob3Zlci5sZW5ndGgpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oXCJxdW90YV90aHJlc2hvbGQgZ2F0ZTogYWxsX2V4Y2VlZGVkXCIsIHtcbiAgICAgICAgICBwcm92aWRlcjogXCJvcGVuYWlcIixcbiAgICAgICAgICBvdmVyVGhyZXNob2xkVG9rZW5zOiBvdmVyLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhyb3cgbmV3IFF1b3RhVGhyZXNob2xkRXhjZWVkZWRFcnJvcihxdW90YU1lc3NhZ2Uob3ZlcikpO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTk9fT1BFTkFJX1dPUktFUlNcIik7XG4gICAgfVxuICAgIGNvbnN0IHNlbGVjdGVkID0gdGhpcy5zZWxlY3Rvci5zZWxlY3QoZWxpZ2libGUpO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gc2VsZWN0ZWQgIT09IG51bGwgPyB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHNlbGVjdGVkKSA6IHVuZGVmaW5lZDtcbiAgICBpZiAoc2VsZWN0ZWQgPT09IG51bGwgfHwgIW1ldGFkYXRhKSB0aHJvdyBuZXcgRXJyb3IoXCJOT19PUEVOQUlfV09SS0VSU1wiKTtcbiAgICByZXR1cm4geyB0b2tlbklkOiBzZWxlY3RlZCwgbWV0YWRhdGEgfTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0VG9rZW4oXG4gICAgaWQ6IG51bWJlcixcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgIHF1b3RhVGhyZXNob2xkOiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkLFxuICAgIHdlaWdodDogbnVtYmVyLFxuICAgIGFjdGl2ZTogYm9vbGVhbixcbiAgKTogdm9pZCB7XG4gICAgY29uc3Qgb2xkID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldChpZCk7XG4gICAgaWYgKG9sZCkge1xuICAgICAgT2JqZWN0LmFzc2lnbihvbGQsIHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgY3JlZGVudGlhbHMsXG4gICAgICAgIHF1b3RhVGhyZXNob2xkLFxuICAgICAgICB3ZWlnaHQsXG4gICAgICAgIGFjdGl2ZSxcbiAgICAgICAgZ2VuZXJhdGlvbjogb2xkLmdlbmVyYXRpb24gKyAxLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudG9rZW5NZXRhZGF0YS5zZXQoaWQsIHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgY3JlZGVudGlhbHMsXG4gICAgICAgIHF1b3RhVGhyZXNob2xkLFxuICAgICAgICB3ZWlnaHQsXG4gICAgICAgIGFjdGl2ZSxcbiAgICAgICAgZ2VuZXJhdGlvbjogMSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLnNlbGVjdG9yLnNldFRva2VuKGlkLCB3ZWlnaHQpO1xuICAgIHRoaXMuaW52YWxpZGF0ZVJhdGVMaW1pdHNDYWNoZShpZCk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWQuZGVsZXRlKGlkKTtcbiAgfVxuXG4gIGFzeW5jIGdldFJhdGVMaW1pdHNCeVRva2VuSWQoXG4gICAgdG9rZW5JZDogbnVtYmVyLFxuICAgIHNpZ25hbD86IEFib3J0U2lnbmFsLFxuICApOiBQcm9taXNlPE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YT4ge1xuICAgIGNvbnN0IHRva2VuID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldCh0b2tlbklkKTtcbiAgICBpZiAoIXRva2VuKSB0aHJvdyBuZXcgRXJyb3IoYG9wZW5haSB0b2tlbiAke3Rva2VuSWR9IG5vdCBmb3VuZGApO1xuICAgIGNvbnN0IGNhY2hlZCA9IHRoaXMucmF0ZUxpbWl0c0NhY2hlLmdldCh0b2tlbklkKTtcbiAgICBpZiAoXG4gICAgICBjYWNoZWQgJiZcbiAgICAgIGNhY2hlZC5nZW5lcmF0aW9uID09PSB0b2tlbi5nZW5lcmF0aW9uICYmXG4gICAgICBEYXRlLm5vdygpIC0gY2FjaGVkLmNhY2hlZEF0IDwgT3BlbkFJRGlzcGF0Y2hlci5SQVRFX0xJTUlUU19DQUNIRV9UVExcbiAgICApXG4gICAgICByZXR1cm4gY2FjaGVkO1xuXG4gICAgLy8gc2luZ2xlLWZsaWdodDog64+Z7Iuc7ISxIOyDge2VnOydtCDsl4bslrTsp4Qg65Kk66GcIFRUTCDrp4zro4wg7Iic6rCEIOuPmeyLnCDsmpTssq0g7IiY66eM7YG8IOqwmeydgFxuICAgIC8vIOyhsO2ajOqwgCDrqrDrprQg7IiYIOyeiOuLpCDigJQg7KeE7ZaJIOykkeyduCBmZXRjaCDrpbwg6rO17Jyg7ZWc64ukLiDstZzstIgg7Zi47Lac7J6Q7J2YIGFib3J0IOuhnFxuICAgIC8vIOqzteycoCDsobDtmozqsIAg7Iuk7Yyo7ZW064+EIOyGjOu5hOyymChpc1F1b3RhRWxpZ2libGUp6rCAIGZhaWwtb3BlbiDsnLzroZwg7LKY66as7ZWc64ukLlxuICAgIGNvbnN0IHBlbmRpbmcgPSB0aGlzLnBlbmRpbmdSYXRlTGltaXRzLmdldCh0b2tlbklkKTtcbiAgICBpZiAocGVuZGluZykgcmV0dXJuIHBlbmRpbmc7XG4gICAgY29uc3QgZmV0Y2hQcm9taXNlID0gKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlYWRPcGVuQUlRdW90YVVzYWdlKHtcbiAgICAgICAgY3JlZGVudGlhbHM6IHRva2VuLmNyZWRlbnRpYWxzLFxuICAgICAgICBmZXRjaDogdGhpcy5mZXRjaEltcGwsXG4gICAgICAgIC4uLihzaWduYWwgPyB7IHNpZ25hbCB9IDoge30pLFxuICAgICAgfSk7XG4gICAgICBpZiAocmVzdWx0LmtpbmQgPT09IFwibG9va3VwX2ZhaWxlZFwiKSB0aHJvdyBuZXcgRXJyb3IocmVzdWx0LnJlYXNvbik7XG4gICAgICBpZiAoIXJlc3VsdC5yYXcpIHRocm93IG5ldyBFcnJvcihcIk9wZW5BSSBxdW90YSByZXNwb25zZSBtaXNzaW5nIHJhdyByYXRlIGxpbWl0c1wiKTtcbiAgICAgIGNvbnN0IGVudHJ5ID0geyBkYXRhOiByZXN1bHQucmF3LCBjYWNoZWRBdDogRGF0ZS5ub3coKSwgZ2VuZXJhdGlvbjogdG9rZW4uZ2VuZXJhdGlvbiB9O1xuICAgICAgaWYgKHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCkgPT09IHRva2VuKSB0aGlzLnJhdGVMaW1pdHNDYWNoZS5zZXQodG9rZW5JZCwgZW50cnkpO1xuICAgICAgcmV0dXJuIGVudHJ5O1xuICAgIH0pKCkuZmluYWxseSgoKSA9PiB0aGlzLnBlbmRpbmdSYXRlTGltaXRzLmRlbGV0ZSh0b2tlbklkKSk7XG4gICAgdGhpcy5wZW5kaW5nUmF0ZUxpbWl0cy5zZXQodG9rZW5JZCwgZmV0Y2hQcm9taXNlKTtcbiAgICByZXR1cm4gZmV0Y2hQcm9taXNlO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBpc1F1b3RhRWxpZ2libGUoXG4gICAgaWQ6IG51bWJlcixcbiAgICB0b2tlbjogVG9rZW5NZXRhZGF0YSxcbiAgICBzaWduYWw/OiBBYm9ydFNpZ25hbCxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKHRva2VuLnF1b3RhVGhyZXNob2xkID09PSBudWxsIHx8IHRva2VuLnF1b3RhVGhyZXNob2xkID09PSB1bmRlZmluZWQpIHJldHVybiB0cnVlO1xuICAgIGNvbnN0IGdlbmVyYXRpb24gPSB0b2tlbi5nZW5lcmF0aW9uO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHJlYWRPcGVuQUlRdW90YVVzYWdlKGFzeW5jICgpID0+IHRoaXMuZ2V0UmF0ZUxpbWl0c0J5VG9rZW5JZChpZCwgc2lnbmFsKSk7XG4gICAgaWYgKHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoaWQpICE9PSB0b2tlbiB8fCB0b2tlbi5nZW5lcmF0aW9uICE9PSBnZW5lcmF0aW9uKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKHJlc3VsdC5raW5kID09PSBcImxvb2t1cF9mYWlsZWRcIikge1xuICAgICAgdGhpcy5xdW90YUJsb2NrZWQuZGVsZXRlKGlkKTtcbiAgICAgIGxvZ2dlci53YXJuKFwicXVvdGFfdGhyZXNob2xkIGdhdGU6IGxvb2t1cF9mYWlsX29wZW5cIiwge1xuICAgICAgICB0b2tlbklkOiBpZCxcbiAgICAgICAgdG9rZW5OYW1lOiB0b2tlbi5uYW1lLFxuICAgICAgICBsb29rdXBSZWFzb246IHJlc3VsdC5yZWFzb24sXG4gICAgICB9KTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBpZiAocmVzdWx0LnV0aWxpemF0aW9uUGN0ID49IHRva2VuLnF1b3RhVGhyZXNob2xkKSB7XG4gICAgICBpZiAoIXRoaXMucXVvdGFCbG9ja2VkLmhhcyhpZCkpXG4gICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgIGBxdW90YV90aHJlc2hvbGQgZ2F0ZTogb3Zlcl90aHJlc2hvbGQgJHt0b2tlbi5uYW1lfVske2lkfV0gKCR7cmVzdWx0LnV0aWxpemF0aW9uUGN0fSUgPj0gJHt0b2tlbi5xdW90YVRocmVzaG9sZH0lKWAsXG4gICAgICAgICk7XG4gICAgICB0aGlzLnF1b3RhQmxvY2tlZC5hZGQoaWQpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBpZiAodGhpcy5xdW90YUJsb2NrZWQuZGVsZXRlKGlkKSlcbiAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICBgcXVvdGFfdGhyZXNob2xkIGdhdGU6IHJlY292ZXJlZCAke3Rva2VuLm5hbWV9WyR7aWR9XSAoJHtyZXN1bHQudXRpbGl6YXRpb25QY3R9JSA8ICR7dG9rZW4ucXVvdGFUaHJlc2hvbGR9JSlgLFxuICAgICAgKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHByaXZhdGUgaW52YWxpZGF0ZVJhdGVMaW1pdHNDYWNoZShpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5yYXRlTGltaXRzQ2FjaGUuZGVsZXRlKGlkKTtcbiAgfVxuXG4gIGdldCB0b2tlbkNvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIFsuLi50aGlzLnRva2VuTWV0YWRhdGEudmFsdWVzKCldLmZpbHRlcigodCkgPT4gdC5hY3RpdmUpLmxlbmd0aDtcbiAgfVxuICBnZXQgaW5GbGlnaHQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5pbkZsaWdodENvdW50O1xuICB9XG5cbiAgLyoqXG4gICAqIO2GoO2BsOuzhCDsv7zthLAg7Iqk64OF7IO3IOKAlCDsi6DshKDtlZwocmF0ZSBsaW1pdHMgVFRMIOuCtCkg7LqQ7Iuc66eMIOydveqzoCDsoIjrjIAgZmV0Y2gg7ZWY7KeAIOyViuuKlOuLpC5cbiAgICogbW9uaXQgdml0YWxzIOuKlCDroZzqt7gg7Y+066eB7JeQIO2OuOyKue2VmOuKlCDqsJLsnbTrnbwg7Jes6riw7IScIOuEpO2KuOybjO2BrOulvCDtg4DrqbQg7JWIIOuQnOuLpC5cbiAgICogdGhyZXNob2xkIOuvuOyEpOyglSDthqDtgbDsnYAg7L+87YSwIO2MkOygleydhCDrj4zsp4Ag7JWK7JWEIHVzZWRQZXJjZW50IOqwgCBudWxsIOuhnCDrgqjsnYQg7IiYIOyeiOuLpC5cbiAgICovXG4gIGdldCBxdW90YUJ5VG9rZW4oKTogQXJyYXk8e1xuICAgIG5hbWU6IHN0cmluZztcbiAgICB1c2VkUGVyY2VudDogbnVtYmVyIHwgbnVsbDtcbiAgICB0aHJlc2hvbGQ6IG51bWJlciB8IG51bGw7XG4gICAgYmxvY2tlZDogYm9vbGVhbjtcbiAgICByZXNldHNBdDogbnVtYmVyIHwgbnVsbDtcbiAgfT4ge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIFsuLi50aGlzLnRva2VuTWV0YWRhdGEuZW50cmllcygpXVxuICAgICAgLm1hcCgoW2lkLCB0XSkgPT4ge1xuICAgICAgICBjb25zdCBjYWNoZWQgPSB0aGlzLnJhdGVMaW1pdHNDYWNoZS5nZXQoaWQpO1xuICAgICAgICBjb25zdCBmcmVzaCA9XG4gICAgICAgICAgY2FjaGVkICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICBjYWNoZWQuZ2VuZXJhdGlvbiA9PT0gdC5nZW5lcmF0aW9uICYmXG4gICAgICAgICAgbm93IC0gY2FjaGVkLmNhY2hlZEF0IDwgT3BlbkFJRGlzcGF0Y2hlci5SQVRFX0xJTUlUU19DQUNIRV9UVEw7XG4gICAgICAgIGNvbnN0IHByaW1hcnkgPSBmcmVzaCA/IGNhY2hlZC5kYXRhLnJhdGVMaW1pdHM/LnByaW1hcnkgOiB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbmFtZTogdC5uYW1lLFxuICAgICAgICAgIHVzZWRQZXJjZW50OiBwcmltYXJ5Py51c2VkUGVyY2VudCA/PyBudWxsLFxuICAgICAgICAgIHRocmVzaG9sZDogdC5xdW90YVRocmVzaG9sZCA/PyBudWxsLFxuICAgICAgICAgIGJsb2NrZWQ6IHRoaXMucXVvdGFCbG9ja2VkLmhhcyhpZCksXG4gICAgICAgICAgLy8gd2hhbSDsnZggcmVzZXRzQXQg7J2AIHVuaXgg7LSIIOuLqOychOuLpChxZ3JpZC5mcmFtZSB1bml4U2Vjb25kc1RvSXNvIOyZgCDrj5nsnbwg6rec7JW9KS5cbiAgICAgICAgICAvLyDshozruYTsspjqsIAg64uo7JyE66W8IOy2lOy4oe2VmOyngCDslYrrj4TroZ0g7Jes6riw7IScIG1zIGVwb2NoIOycvOuhnCDsoJXqt5ztmZTtlZzri6QuXG4gICAgICAgICAgcmVzZXRzQXQ6XG4gICAgICAgICAgICBwcmltYXJ5Py5yZXNldHNBdCAhPT0gbnVsbCAmJiBwcmltYXJ5Py5yZXNldHNBdCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgID8gcHJpbWFyeS5yZXNldHNBdCAqIDEwMDBcbiAgICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICB9O1xuICAgICAgfSlcbiAgICAgIC50b1NvcnRlZCgoYSwgYikgPT4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5uYW1lKSk7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7OztBQXdCQSxNQUFNLFNBQVMsVUFBVSxDQUFDLFNBQVMsbUJBQW1CLENBQUM7QUFHdkQsTUFBTSw2QkFBNkI7QUFJbkMsSUFBYSx1QkFBYixjQUEwQyxNQUFNO0NBRW5DO0NBRFgsWUFDRSxNQUNBLFNBQ0E7RUFDQSxNQUFNLE9BQU87RUFISixLQUFBLE9BQUE7RUFJVCxLQUFLLE9BQU87Q0FDZDtBQUNGO0FBOEJBLFNBQVMsV0FBVyxRQUE0QjtDQUM5QyxNQUFNLFNBQVMsT0FBTztDQUN0QixPQUFPLGtCQUFrQixRQUFRLFNBQVMsSUFBSSxhQUFhLFdBQVcsWUFBWTtBQUNwRjtBQUVBLFNBQVMsYUFBYSxR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
472
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLWRpc3BhdGNoZXIuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9vcGVuYWkvb3BlbmFpLWRpc3BhdGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcblxuaW1wb3J0IHsgUXVvdGFUaHJlc2hvbGRFeGNlZWRlZEVycm9yIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLnR5cGVzXCI7XG5pbXBvcnQgeyBUb2tlbk1vZGVsIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLm1vZGVsXCI7XG5pbXBvcnQgeyB0eXBlIE9wZW5BSUNyZWRlbnRpYWxzIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLnR5cGVzXCI7XG5pbXBvcnQgeyByZXNvbHZlT3BlbkFJRWZmb3J0IH0gZnJvbSBcIi4uL2NvbW1vbi9lZmZvcnRcIjtcbmltcG9ydCB7XG4gIHR5cGUgR2VuZXJhdGVSZXF1ZXN0LFxuICB0eXBlIEdlbmVyYXRlUmVzdWx0LFxuICB0eXBlIEdlbmVyYXRlU3RyZWFtQ2FsbGJhY2tzLFxuICB0eXBlIEdlbmVyYXRlZEltYWdlLFxuICB0eXBlIFByb3ZpZGVyRGlzcGF0Y2hlcixcbn0gZnJvbSBcIi4uL2NvbW1vbi9wcm92aWRlci1kaXNwYXRjaGVyXCI7XG5pbXBvcnQgeyBTbW9vdGhXZWlnaHRlZFJvdW5kUm9iaW4gfSBmcm9tIFwiLi4vY29tbW9uL3Ntb290aC13ZWlnaHRlZC1yb3VuZC1yb2JpblwiO1xuaW1wb3J0IHtcbiAgdHlwZSBKc29uVmFsdWUsXG4gIHR5cGUgT3BlbkFJUmVzcG9uc2VJdGVtLFxuICB0eXBlIE9wZW5BSVJlc3BvbnNlc09wdGlvbnMsXG59IGZyb20gXCIuL29wZW5haS1iYWNrZW5kLXByb3RvY29sXCI7XG5pbXBvcnQgeyBPcGVuQUlEaXJlY3RDbGllbnQsIHR5cGUgT3BlbkFJRGlyZWN0Q2xpZW50T3B0aW9ucyB9IGZyb20gXCIuL29wZW5haS1kaXJlY3QtY2xpZW50XCI7XG5pbXBvcnQgeyByZWFkT3BlbkFJUXVvdGFVc2FnZSwgdHlwZSBPcGVuQUlSYXRlTGltaXRzV2l0aE1ldGEgfSBmcm9tIFwiLi9vcGVuYWktcXVvdGFcIjtcbmltcG9ydCB7IGhhbmRsZUNoYXRncHRBdXRoVG9rZW5zUmVmcmVzaCB9IGZyb20gXCIuL29wZW5haS1yZWZyZXNoXCI7XG5pbXBvcnQgeyB0eXBlIE9wZW5BSVRyYW5zcG9ydEtpbmQsIHJlc29sdmVPcGVuQUlUcmFuc3BvcnRLaW5kIH0gZnJvbSBcIi4vb3BlbmFpLXRyYW5zcG9ydC1jb25maWdcIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwib3BlbmFpLWRpc3BhdGNoZXJcIl0pO1xuLy8g6rWQ7LK065CcIGNvZGV4IHdvcmtlciDqsIAg6rCV7KCc7ZWY642YIHdhdGNoZG9nLiDtmLjstpzsnpDqsIAgdGltZW91dE1zIOulvCDsg53rnrXtlbTrj4Qg7JqU7LKt7J20XG4vLyDsmIHsm5Dtnogg66ek64us66as7KeAIOyViuuPhOuhnSBkaXJlY3QgdHJhbnNwb3J0IOuPhCDsnKDtlZztlZwg6riw67O4IOyDge2VnOydhCDsnKDsp4DtlZzri6QuXG5jb25zdCBERUZBVUxUX1JFUVVFU1RfVElNRU9VVF9NUyA9IDYwMF8wMDA7XG5cbmV4cG9ydCB0eXBlIEltYWdlRmFpbHVyZUtpbmQgPSBcImdhdGVcIiB8IFwibm90X2NhbGxlZFwiIHwgXCJpbmNvbXBsZXRlXCI7XG5cbmV4cG9ydCBjbGFzcyBJbWFnZUdlbmVyYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcmVhZG9ubHkga2luZDogSW1hZ2VGYWlsdXJlS2luZCxcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiSW1hZ2VHZW5lcmF0aW9uRXJyb3JcIjtcbiAgfVxufVxuXG50eXBlIFRva2VuTWV0YWRhdGEgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzO1xuICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGw7XG4gIHdlaWdodDogbnVtYmVyO1xuICBhY3RpdmU6IGJvb2xlYW47XG4gIGdlbmVyYXRpb246IG51bWJlcjtcbn07XG5cbnR5cGUgVG9rZW5TZWxlY3Rpb24gPSB7IHRva2VuSWQ6IG51bWJlcjsgbWV0YWRhdGE6IFRva2VuTWV0YWRhdGEgfTtcblxuZXhwb3J0IHR5cGUgT3BlbkFJRGlyZWN0Q2xpZW50RmFjdG9yeSA9IChcbiAgb3B0aW9uczogT3BlbkFJRGlyZWN0Q2xpZW50T3B0aW9ucyxcbiAgdG9rZW5JZDogbnVtYmVyLFxuKSA9PiBQaWNrPE9wZW5BSURpcmVjdENsaWVudCwgXCJyZXNwb25zZXNcIj4gJiB7IGNsb3NlPzogKCkgPT4gdm9pZCB9O1xuXG50eXBlIENsaWVudEVudHJ5ID0ge1xuICBnZW5lcmF0aW9uOiBudW1iZXI7XG4gIGNsaWVudDogUGljazxPcGVuQUlEaXJlY3RDbGllbnQsIFwicmVzcG9uc2VzXCI+ICYgeyBjbG9zZT86ICgpID0+IHZvaWQgfTtcbiAgaW5GbGlnaHQ6IG51bWJlcjtcbiAgcmV0aXJlZDogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlbkFJRGlzcGF0Y2hlckRlcGVuZGVuY2llcyB7XG4gIGNsaWVudEZhY3Rvcnk/OiBPcGVuQUlEaXJlY3RDbGllbnRGYWN0b3J5O1xuICBmZXRjaD86IHR5cGVvZiBmZXRjaDtcbn1cblxuZnVuY3Rpb24gYWJvcnRFcnJvcihzaWduYWw6IEFib3J0U2lnbmFsKTogRXJyb3Ige1xuICBjb25zdCByZWFzb24gPSBzaWduYWwucmVhc29uO1xuICByZXR1cm4gcmVhc29uIGluc3RhbmNlb2YgRXJyb3IgPyByZWFzb24gOiBuZXcgRE9NRXhjZXB0aW9uKFwiQWJvcnRlZFwiLCBcIkFib3J0RXJyb3JcIik7XG59XG5cbmZ1bmN0aW9uIGFjdGl2ZVNpZ25hbChzaWduYWw/OiBBYm9ydFNpZ25hbCwgdGltZW91dE1zPzogbnVtYmVyKTogQWJvcnRTaWduYWwge1xuICBjb25zdCB0aW1lb3V0ID0gQWJvcnRTaWduYWwudGltZW91dCh0aW1lb3V0TXMgPz8gREVGQVVMVF9SRVFVRVNUX1RJTUVPVVRfTVMpO1xuICByZXR1cm4gc2lnbmFsID8gQWJvcnRTaWduYWwuYW55KFtzaWduYWwsIHRpbWVvdXRdKSA6IHRpbWVvdXQ7XG59XG5cbmZ1bmN0aW9uIHF1b3RhTWVzc2FnZShlbnRyaWVzOiBBcnJheTx7IG5hbWU6IHN0cmluZzsgdGhyZXNob2xkOiBudW1iZXIgfT4pOiBzdHJpbmcge1xuICBjb25zdCBkZXRhaWwgPSBlbnRyaWVzLm1hcCgoZSkgPT4gYCR7ZS5uYW1lfSAodGhyZXNob2xkICR7ZS50aHJlc2hvbGR9JSlgKS5qb2luKFwiLCBcIik7XG4gIHJldHVybiBkZXRhaWxcbiAgICA/IGBBbGwgb3BlbmFpIHRva2VucyBleGNlZWRlZCBxdW90YSB0aHJlc2hvbGQ6ICR7ZGV0YWlsfWBcbiAgICA6IFwiQWxsIG9wZW5haSB0b2tlbnMgZXhjZWVkZWQgcXVvdGEgdGhyZXNob2xkXCI7XG59XG5cbmZ1bmN0aW9uIGlucHV0SXRlbXMocmVxOiBHZW5lcmF0ZVJlcXVlc3QpOiBPcGVuQUlSZXNwb25zZUl0ZW1bXSB7XG4gIGNvbnN0IGhpc3RvcnkgPSAocmVxLmNvbGRIaXN0b3J5ID8/IFtdKSBhcyBPcGVuQUlSZXNwb25zZUl0ZW1bXTtcbiAgY29uc3QgY29udGVudDogT3BlbkFJUmVzcG9uc2VJdGVtW10gPSByZXEuY29sZElucHV0Lm1hcCgoaW5wdXQpID0+IHtcbiAgICBpZiAoaW5wdXQudHlwZSA9PT0gXCJ0ZXh0XCIpIHJldHVybiB7IHR5cGU6IFwiaW5wdXRfdGV4dFwiLCB0ZXh0OiBpbnB1dC50ZXh0IH07XG4gICAgaWYgKGlucHV0LnR5cGUgPT09IFwiaW1hZ2VcIikgcmV0dXJuIHsgdHlwZTogXCJpbnB1dF9pbWFnZVwiLCBpbWFnZV91cmw6IGlucHV0LnVybCB9O1xuICAgIGlmIChpbnB1dC50eXBlID09PSBcImxvY2FsSW1hZ2VcIikgcmV0dXJuIHsgdHlwZTogXCJpbnB1dF9pbWFnZVwiLCBpbWFnZV91cmw6IGlucHV0LnBhdGggfTtcbiAgICByZXR1cm4geyB0eXBlOiBcImlucHV0X3RleHRcIiwgdGV4dDogYCR7aW5wdXQubmFtZX06ICR7aW5wdXQucGF0aH1gIH07XG4gIH0pO1xuICByZXR1cm4gWy4uLmhpc3RvcnksIHsgdHlwZTogXCJtZXNzYWdlXCIsIHJvbGU6IFwidXNlclwiLCBjb250ZW50IH1dO1xufVxuXG5mdW5jdGlvbiBhc1JlYXNvbmluZyhyZXE6IEdlbmVyYXRlUmVxdWVzdCk6IE9wZW5BSVJlc3BvbnNlc09wdGlvbnNbXCJyZWFzb25pbmdcIl0gfCB1bmRlZmluZWQge1xuICBjb25zdCBzdW1tYXJ5ID1cbiAgICByZXEucmVhc29uaW5nU3VtbWFyeSAmJiByZXEucmVhc29uaW5nU3VtbWFyeSAhPT0gXCJub25lXCIgPyByZXEucmVhc29uaW5nU3VtbWFyeSA6IHVuZGVmaW5lZDtcbiAgLy8gQ29kZXgg7Ja07ZyYwrfrqqjrjbgg7IOB7ZWcIOuwluydmCBlZmZvcnQg64qUIOyXrOq4sOyEnCDsobDsmqntnogg67KE66aw64ukKOuwseyXlOuTnCDquLDrs7jqsJIg7KCB7JqpKS5cbiAgY29uc3QgZWZmb3J0ID0gcmVzb2x2ZU9wZW5BSUVmZm9ydChyZXEubW9kZWwgPz8gXCJcIiwgcmVxLmVmZm9ydCk7XG4gIGlmICghZWZmb3J0ICYmICFzdW1tYXJ5KSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4ge1xuICAgIC4uLihlZmZvcnQgPyB7IGVmZm9ydCB9IDoge30pLFxuICAgIC4uLihzdW1tYXJ5XG4gICAgICA/IHtcbiAgICAgICAgICBzdW1tYXJ5OiBzdW1tYXJ5IGFzIE5vbk51bGxhYmxlPE9wZW5BSVJlc3BvbnNlc09wdGlvbnNbXCJyZWFzb25pbmdcIl0+W1wic3VtbWFyeVwiXSxcbiAgICAgICAgfVxuICAgICAgOiB7fSksXG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlcXVlc3RPcHRpb25zKHJlcTogR2VuZXJhdGVSZXF1ZXN0KTogT3BlbkFJUmVzcG9uc2VzT3B0aW9ucyB7XG4gIHJldHVybiB7XG4gICAgbW9kZWw6IHJlcS5tb2RlbCA/PyBcIlwiLFxuICAgIC4uLihyZXEuc3lzdGVtUHJvbXB0ID8geyBpbnN0cnVjdGlvbnM6IHJlcS5zeXN0ZW1Qcm9tcHQgfSA6IHt9KSxcbiAgICBoaXN0b3J5OiBpbnB1dEl0ZW1zKHJlcSksXG4gICAgLi4uKGFzUmVhc29uaW5nKHJlcSkgPyB7IHJlYXNvbmluZzogYXNSZWFzb25pbmcocmVxKSB9IDoge30pLFxuICAgIC4uLihyZXEudmVyYm9zaXR5ID8geyB2ZXJib3NpdHk6IHJlcS52ZXJib3NpdHkgYXMgT3BlbkFJUmVzcG9uc2VzT3B0aW9uc1tcInZlcmJvc2l0eVwiXSB9IDoge30pLFxuICAgIC4uLihyZXEuc2VydmljZVRpZXJcbiAgICAgID8geyBzZXJ2aWNlVGllcjogcmVxLnNlcnZpY2VUaWVyID09PSBcImZhc3RcIiA/IFwicHJpb3JpdHlcIiA6IHJlcS5zZXJ2aWNlVGllciB9XG4gICAgICA6IHt9KSxcbiAgICAuLi4ocmVxLnByb21wdENhY2hlS2V5ID8geyBwcm9tcHRDYWNoZUtleTogcmVxLnByb21wdENhY2hlS2V5IH0gOiB7fSksXG4gICAgLi4uKHJlcS5vdXRwdXRTY2hlbWEgPyB7IG91dHB1dFNjaGVtYTogeyBzY2hlbWE6IHJlcS5vdXRwdXRTY2hlbWEgYXMgSnNvblZhbHVlIH0gfSA6IHt9KSxcbiAgICAuLi4ocmVxLmltYWdlR2VuZXJhdGlvblxuICAgICAgPyB7IGltYWdlR2VuZXJhdGlvbjogcmVxLmltYWdlR2VuZXJhdGlvbk9wdGlvbnMgPyB7IC4uLnJlcS5pbWFnZUdlbmVyYXRpb25PcHRpb25zIH0gOiB0cnVlIH1cbiAgICAgIDoge30pLFxuICB9O1xufVxuXG4vKipcbiAqIERpcmVjdCBPcGVuQUkgZGlzcGF0Y2hlciDigJQgQW50aHJvcGljIOqzvCDrj5nsnbztlZwgc3RhdGVsZXNzIOyLpO2WiSDrqqjrjbguXG4gKlxuICog7JqU7LKtID0g7Yag7YGwIOyEoO2DnShxdW90YSBnYXRlICsgd2VpZ2h0ZWQgcm91bmQtcm9iaW4gKyBjYWNoZSBhZmZpbml0eSDshKDtmLgpIOKGkiBIVFRQUy9XU1xuICog7KCE7IahLiBwZXJtaXQv7YGQIOqwmeydgCDrj5nsi5zshLEg7IOB7ZWc7J2AIOuRkOyngCDslYrripTri6Q6IOyghOyGoeydgCBmZXRjaCDtlZwg67KI7J206528IOuhnOy7rCDsnpDsm5DsnbRcbiAqIO2drOyGjO2VmOyngCDslYrqs6AsIOyDgeulmCDsoJztlZzsnYAg67Cx7JeU65Oc7J2YIOydkeuLtSg0Mjkg65OxKeydtCDsp4Tsi6TsnbTri6QuIHdvcmtlciBwb29sIOyLnOygiOydmFxuICog7YGQIOydmOuvuOuhoChTRVJWRVJfQlVTWSwg7YGQIO2DgOyehOyVhOybgynsnYAg7J20IOyghO2ZmOycvOuhnCDsoJzqsbDrkJDri6QuXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuQUlEaXNwYXRjaGVyIGltcGxlbWVudHMgUHJvdmlkZXJEaXNwYXRjaGVyIHtcbiAgcmVhZG9ubHkgdG9rZW5NZXRhZGF0YSA9IG5ldyBNYXA8bnVtYmVyLCBUb2tlbk1ldGFkYXRhPigpO1xuICByZWFkb25seSB0cmFuc3BvcnRLaW5kOiBPcGVuQUlUcmFuc3BvcnRLaW5kO1xuICByZWFkb25seSByYXRlTGltaXRzQ2FjaGUgPSBuZXcgTWFwPG51bWJlciwgT3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhICYgeyBnZW5lcmF0aW9uOiBudW1iZXIgfT4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBwZW5kaW5nUmF0ZUxpbWl0cyA9IG5ldyBNYXA8XG4gICAgbnVtYmVyLFxuICAgIHsgdG9rZW46IFRva2VuTWV0YWRhdGE7IGdlbmVyYXRpb246IG51bWJlcjsgcHJvbWlzZTogUHJvbWlzZTxPcGVuQUlSYXRlTGltaXRzV2l0aE1ldGE+IH1cbiAgPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudHMgPSBuZXcgTWFwPG51bWJlciwgQ2xpZW50RW50cnk+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmV0aXJlZENsaWVudHMgPSBuZXcgU2V0PENsaWVudEVudHJ5PigpO1xuICBzdGF0aWMgcmVhZG9ubHkgUkFURV9MSU1JVFNfQ0FDSEVfVFRMID0gNjBfMDAwO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgc2VsZWN0b3IgPSBuZXcgU21vb3RoV2VpZ2h0ZWRSb3VuZFJvYmluKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50RmFjdG9yeTogT3BlbkFJRGlyZWN0Q2xpZW50RmFjdG9yeTtcbiAgcHJpdmF0ZSByZWFkb25seSBmZXRjaEltcGw6IHR5cGVvZiBmZXRjaDtcbiAgcHJpdmF0ZSByZWFkb25seSBxdW90YUJsb2NrZWQgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgcHJpdmF0ZSBpbkZsaWdodENvdW50ID0gMDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICB0cmFuc3BvcnRLaW5kOiBPcGVuQUlUcmFuc3BvcnRLaW5kID0gcmVzb2x2ZU9wZW5BSVRyYW5zcG9ydEtpbmQoKSxcbiAgICBkZXBlbmRlbmNpZXM6IE9wZW5BSURpc3BhdGNoZXJEZXBlbmRlbmNpZXMgPSB7fSxcbiAgKSB7XG4gICAgdGhpcy50cmFuc3BvcnRLaW5kID0gdHJhbnNwb3J0S2luZDtcbiAgICB0aGlzLmNsaWVudEZhY3RvcnkgPVxuICAgICAgZGVwZW5kZW5jaWVzLmNsaWVudEZhY3RvcnkgPz8gKChvcHRpb25zKSA9PiBuZXcgT3BlbkFJRGlyZWN0Q2xpZW50KG9wdGlvbnMpKTtcbiAgICB0aGlzLmZldGNoSW1wbCA9IGRlcGVuZGVuY2llcy5mZXRjaCA/PyBmZXRjaDtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgcm93cyB9ID0gYXdhaXQgVG9rZW5Nb2RlbC5maW5kTWFueShcIkFcIik7XG4gICAgZm9yIChjb25zdCByb3cgb2Ygcm93cykge1xuICAgICAgaWYgKHJvdy5wcm92aWRlciAhPT0gXCJvcGVuYWlcIikgY29udGludWU7XG4gICAgICB0aGlzLnNldFRva2VuKFxuICAgICAgICByb3cuaWQsXG4gICAgICAgIHJvdy5uYW1lLFxuICAgICAgICByb3cuY3JlZGVudGlhbHMgYXMgT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgICAgIHJvdy5xdW90YV90aHJlc2hvbGQsXG4gICAgICAgIHJvdy53ZWlnaHQsXG4gICAgICAgIHJvdy5hY3RpdmUsXG4gICAgICApO1xuICAgIH1cbiAgICBsb2dnZXIuaW5mbyhgc3RhcnRlZCBkaXJlY3QgT3BlbkFJIHJ1bnRpbWUgd2l0aCAke3RoaXMudG9rZW5NZXRhZGF0YS5zaXplfSB0b2tlbnNgKTtcbiAgfVxuXG4gIGFzeW5jIHN0b3AoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgZm9yIChjb25zdCB7IGNsaWVudCB9IG9mIHRoaXMuY2xpZW50cy52YWx1ZXMoKSkgY2xpZW50LmNsb3NlPy4oKTtcbiAgICB0aGlzLmNsaWVudHMuY2xlYXIoKTtcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHRoaXMucmV0aXJlZENsaWVudHMpIGVudHJ5LmNsaWVudC5jbG9zZT8uKCk7XG4gICAgdGhpcy5yZXRpcmVkQ2xpZW50cy5jbGVhcigpO1xuICAgIHRoaXMudG9rZW5NZXRhZGF0YS5jbGVhcigpO1xuICAgIHRoaXMucmF0ZUxpbWl0c0NhY2hlLmNsZWFyKCk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWQuY2xlYXIoKTtcbiAgICB0aGlzLnNlbGVjdG9yLnJlc2V0U2NvcmVzKCk7XG4gIH1cblxuICBhc3luYyBvblRva2VuQWRkZWQoXG4gICAgaWQ6IG51bWJlcixcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgIHF1b3RhVGhyZXNob2xkPzogbnVtYmVyIHwgbnVsbCxcbiAgICB3ZWlnaHQgPSAxLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnNldFRva2VuKGlkLCBuYW1lLCBjcmVkZW50aWFscywgcXVvdGFUaHJlc2hvbGQsIHdlaWdodCwgdHJ1ZSk7XG4gIH1cblxuICBhc3luYyBvblRva2VuVXBkYXRlZChcbiAgICBpZDogbnVtYmVyLFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsLFxuICAgIHdlaWdodCA9IDEsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IG9sZCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoaWQpO1xuICAgIHRoaXMuc2V0VG9rZW4oaWQsIG5hbWUsIGNyZWRlbnRpYWxzLCBxdW90YVRocmVzaG9sZCwgd2VpZ2h0LCBvbGQ/LmFjdGl2ZSA/PyB0cnVlKTtcbiAgfVxuXG4gIGFzeW5jIG9uVG9rZW5SZW1vdmVkKGlkOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnJldGlyZUNsaWVudChpZCk7XG4gICAgdGhpcy50b2tlbk1ldGFkYXRhLmRlbGV0ZShpZCk7XG4gICAgdGhpcy5zZWxlY3Rvci5yZW1vdmVUb2tlbihpZCk7XG4gICAgdGhpcy5pbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKGlkKTtcbiAgICB0aGlzLnF1b3RhQmxvY2tlZC5kZWxldGUoaWQpO1xuICB9XG5cbiAgb25Ub2tlbkRlYWN0aXZhdGVkKGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoaWQpO1xuICAgIGlmICh0b2tlbikgdG9rZW4uYWN0aXZlID0gZmFsc2U7XG4gICAgdGhpcy5zZWxlY3Rvci5yZXNldFNjb3JlcygpO1xuICB9XG5cbiAgb25Ub2tlbkFjdGl2YXRlZChpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICBpZiAodG9rZW4pIHRva2VuLmFjdGl2ZSA9IHRydWU7XG4gICAgdGhpcy5zZWxlY3Rvci5yZXNldFNjb3JlcygpO1xuICB9XG5cbiAgYXN5bmMgcmVwbGFjZVRva2VucyhcbiAgICByb3dzOiBBcnJheTx7XG4gICAgICBpZDogbnVtYmVyO1xuICAgICAgbmFtZTogc3RyaW5nO1xuICAgICAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzO1xuICAgICAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsO1xuICAgICAgd2VpZ2h0OiBudW1iZXI7XG4gICAgfT4sXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGlkcyA9IG5ldyBTZXQocm93cy5tYXAoKHIpID0+IHIuaWQpKTtcbiAgICBmb3IgKGNvbnN0IGlkIG9mIHRoaXMudG9rZW5NZXRhZGF0YS5rZXlzKCkpIGlmICghaWRzLmhhcyhpZCkpIGF3YWl0IHRoaXMub25Ub2tlblJlbW92ZWQoaWQpO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpXG4gICAgICBhd2FpdCB0aGlzLm9uVG9rZW5VcGRhdGVkKHJvdy5pZCwgcm93Lm5hbWUsIHJvdy5jcmVkZW50aWFscywgcm93LnF1b3RhVGhyZXNob2xkLCByb3cud2VpZ2h0KTtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlKHJlcTogR2VuZXJhdGVSZXF1ZXN0KTogUHJvbWlzZTxHZW5lcmF0ZVJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnJ1bihyZXEpO1xuICB9XG5cbiAgYXN5bmMgZ2VuZXJhdGVTdHJlYW0ocmVxOiBHZW5lcmF0ZVJlcXVlc3QsIGNiOiBHZW5lcmF0ZVN0cmVhbUNhbGxiYWNrcyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmIChyZXEuaW1hZ2VHZW5lcmF0aW9uKVxuICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFxuICAgICAgICBcImdhdGVcIixcbiAgICAgICAgXCJpbWFnZSBnZW5lcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgb24gdGhlIHN0cmVhbWluZyBwYXRoXCIsXG4gICAgICApO1xuICAgIHRyeSB7XG4gICAgICBjYi5vbkNvbXBsZXRlKGF3YWl0IHRoaXMucnVuKHJlcSwgY2Iub25EZWx0YSkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjYi5vbkVycm9yKGVycm9yIGFzIEVycm9yKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8vIGdlbmVyYXRlL2dlbmVyYXRlU3RyZWFtIOqzte2GtSDsi6Ttlokg4oCUIO2GoO2BsCDshKDtg53qs7wgaW4tZmxpZ2h0IOynkeqzhOulvCDtlZwg6rOz7JeQIOuRlOuLpC5cbiAgcHJpdmF0ZSBhc3luYyBydW4oXG4gICAgcmVxOiBHZW5lcmF0ZVJlcXVlc3QsXG4gICAgb25EZWx0YT86ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQsXG4gICk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICBjb25zdCBzaWduYWwgPSBhY3RpdmVTaWduYWwocmVxLmFib3J0U2lnbmFsLCByZXEudGltZW91dE1zKTtcbiAgICBpZiAoc2lnbmFsLmFib3J0ZWQpIHRocm93IGFib3J0RXJyb3Ioc2lnbmFsKTtcbiAgICBjb25zdCBzZWxlY3Rpb24gPSBhd2FpdCB0aGlzLnNlbGVjdFRva2VuKFxuICAgICAgcmVxLnByZWZlcnJlZFRva2VuSWQsXG4gICAgICByZXEucmVxdWlyZVByZWZlcnJlZFRva2VuID8/IGZhbHNlLFxuICAgICAgc2lnbmFsLFxuICAgICk7XG4gICAgdGhpcy5pbkZsaWdodENvdW50Kys7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChzaWduYWwuYWJvcnRlZCkgdGhyb3cgYWJvcnRFcnJvcihzaWduYWwpO1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucnVuRGlyZWN0KHNlbGVjdGlvbiwgeyAuLi5yZXEsIGFib3J0U2lnbmFsOiBzaWduYWwgfSwgb25EZWx0YSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuaW5GbGlnaHRDb3VudC0tO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcnVuRGlyZWN0KFxuICAgIHNlbGVjdGlvbjogVG9rZW5TZWxlY3Rpb24sXG4gICAgcmVxOiBHZW5lcmF0ZVJlcXVlc3QsXG4gICAgb25EZWx0YT86ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQsXG4gICk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICBjb25zdCBzdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuICAgIGxldCBmaXJzdERlbHRhQXQ6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICBsZXQgdGV4dCA9IFwiXCI7XG4gICAgbGV0IHVzYWdlID0ge1xuICAgICAgdG90YWxUb2tlbnM6IDAsXG4gICAgICBpbnB1dFRva2VuczogMCxcbiAgICAgIG91dHB1dFRva2VuczogMCxcbiAgICAgIGNhY2hlZElucHV0VG9rZW5zOiAwLFxuICAgICAgcmVhc29uaW5nT3V0cHV0VG9rZW5zOiAwLFxuICAgIH07XG4gICAgY29uc3QgaW1hZ2VzOiBHZW5lcmF0ZWRJbWFnZVtdID0gW107XG4gICAgbGV0IGltYWdlQXR0ZW1wdGVkID0gZmFsc2U7XG4gICAgbGV0IHNlcnZpbmdNb2RlbCA9IHJlcS5tb2RlbCA/PyBcIlwiO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gc2VsZWN0aW9uLm1ldGFkYXRhO1xuICAgIGNvbnN0IGNsaWVudEVudHJ5ID0gdGhpcy5hY3F1aXJlQ2xpZW50KHNlbGVjdGlvbik7XG4gICAgdHJ5IHtcbiAgICAgIGZvciBhd2FpdCAoY29uc3QgZXZlbnQgb2YgY2xpZW50RW50cnkuY2xpZW50LnJlc3BvbnNlcyhcbiAgICAgICAgcmVxdWVzdE9wdGlvbnMocmVxKSxcbiAgICAgICAgcmVxLmFib3J0U2lnbmFsLFxuICAgICAgKSkge1xuICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJ0ZXh0LWRlbHRhXCIpIHtcbiAgICAgICAgICBmaXJzdERlbHRhQXQgPz89IERhdGUubm93KCk7XG4gICAgICAgICAgdGV4dCArPSBldmVudC50ZXh0O1xuICAgICAgICAgIG9uRGVsdGE/LihldmVudC50ZXh0KTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSBcImltYWdlXCIpIHtcbiAgICAgICAgICBpbWFnZUF0dGVtcHRlZCA9IHRydWU7XG4gICAgICAgICAgaW1hZ2VzLnB1c2goe1xuICAgICAgICAgICAgZGF0YTogZXZlbnQuYmFzZTY0LFxuICAgICAgICAgICAgcmV2aXNlZFByb21wdDogZXZlbnQucmV2aXNlZFByb21wdCA/PyBudWxsLFxuICAgICAgICAgICAgLi4uKGV2ZW50LmdlbmVyYXRpb24gPyB7IGdlbmVyYXRpb246IGV2ZW50LmdlbmVyYXRpb24gfSA6IHt9KSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSBcIm91dHB1dC1pdGVtXCIgJiYgZXZlbnQuaXRlbS50eXBlID09PSBcImltYWdlX2dlbmVyYXRpb25fY2FsbFwiKSB7XG4gICAgICAgICAgaW1hZ2VBdHRlbXB0ZWQgPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwiY29tcGxldGVkXCIgJiYgZXZlbnQudXNhZ2UpIHtcbiAgICAgICAgICBzZXJ2aW5nTW9kZWwgPSBldmVudC5tb2RlbCA/PyBzZXJ2aW5nTW9kZWw7XG4gICAgICAgICAgdXNhZ2UgPSB7XG4gICAgICAgICAgICB0b3RhbFRva2VuczogZXZlbnQudXNhZ2UudG90YWxUb2tlbnMsXG4gICAgICAgICAgICBpbnB1dFRva2VuczogZXZlbnQudXNhZ2UuaW5wdXRUb2tlbnMsXG4gICAgICAgICAgICBvdXRwdXRUb2tlbnM6IGV2ZW50LnVzYWdlLm91dHB1dFRva2VucyxcbiAgICAgICAgICAgIGNhY2hlZElucHV0VG9rZW5zOiBldmVudC51c2FnZS5jYWNoZWRJbnB1dFRva2VucyxcbiAgICAgICAgICAgIHJlYXNvbmluZ091dHB1dFRva2VuczogZXZlbnQudXNhZ2UucmVhc29uaW5nVG9rZW5zLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gXCJjb21wbGV0ZWRcIikge1xuICAgICAgICAgIHNlcnZpbmdNb2RlbCA9IGV2ZW50Lm1vZGVsID8/IHNlcnZpbmdNb2RlbDtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSBcImVycm9yXCIpIHtcbiAgICAgICAgICBpZiAocmVxLmltYWdlR2VuZXJhdGlvbilcbiAgICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcImluY29tcGxldGVcIiwgZXZlbnQuZXJyb3IubWVzc2FnZSk7XG4gICAgICAgICAgdGhyb3cgZXZlbnQuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5yZWxlYXNlQ2xpZW50KGNsaWVudEVudHJ5KTtcbiAgICB9XG4gICAgaWYgKHJlcS5pbWFnZUdlbmVyYXRpb24gJiYgaW1hZ2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFxuICAgICAgICBpbWFnZUF0dGVtcHRlZCA/IFwiaW5jb21wbGV0ZVwiIDogXCJub3RfY2FsbGVkXCIsXG4gICAgICAgIGltYWdlQXR0ZW1wdGVkXG4gICAgICAgICAgPyBcImltYWdlIGdlbmVyYXRpb24gZGlkIG5vdCBjb21wbGV0ZVwiXG4gICAgICAgICAgOiBcIm1vZGVsIGRpZCBub3QgY2FsbCBpbWFnZSBnZW5lcmF0aW9uXCIsXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgdGV4dCxcbiAgICAgIHRva2VuTmFtZTogbWV0YWRhdGEubmFtZSxcbiAgICAgIHVzYWdlLFxuICAgICAgZHVyYXRpb25NczogRGF0ZS5ub3coKSAtIHN0YXJ0ZWRBdCxcbiAgICAgIHR0ZnRNczogZmlyc3REZWx0YUF0ID09PSB1bmRlZmluZWQgPyBudWxsIDogZmlyc3REZWx0YUF0IC0gc3RhcnRlZEF0LFxuICAgICAgbW9kZWw6IHNlcnZpbmdNb2RlbCxcbiAgICAgIC4uLihzZXJ2aW5nTW9kZWwgIT09IHJlcS5tb2RlbCA/IHsgcmVxdWVzdGVkTW9kZWw6IHJlcS5tb2RlbCB9IDoge30pLFxuICAgICAgdGhyZWFkQ29vcmQ6IHsgd29ya2VySWQ6IHNlbGVjdGlvbi50b2tlbklkLCB0aHJlYWRJZDogcmVxLnByb21wdENhY2hlS2V5ID8/IFwiXCIsIGVwb2NoOiAtMSB9LFxuICAgICAgLi4uKGltYWdlcy5sZW5ndGggPyB7IGltYWdlcyB9IDoge30pLFxuICAgIH07XG4gIH1cblxuICAvKiog7IS464yA6rCAIOuwlOuAkCBjbGllbnQg64qUIOyCrOyaqSDspJHsnbgg7JqU7LKt7J20IOuBneuCnCDrkqTsl5Ag64ur64qU64ukLiAqL1xuICBwcml2YXRlIGFjcXVpcmVDbGllbnQoc2VsZWN0aW9uOiBUb2tlblNlbGVjdGlvbik6IENsaWVudEVudHJ5IHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHNlbGVjdGlvbi5tZXRhZGF0YTtcbiAgICBsZXQgZW50cnkgPSB0aGlzLmNsaWVudHMuZ2V0KHNlbGVjdGlvbi50b2tlbklkKTtcbiAgICBpZiAoZW50cnkgJiYgZW50cnkuZ2VuZXJhdGlvbiAhPT0gbWV0YWRhdGEuZ2VuZXJhdGlvbikge1xuICAgICAgdGhpcy5yZXRpcmVDbGllbnQoc2VsZWN0aW9uLnRva2VuSWQpO1xuICAgICAgZW50cnkgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGlmICghZW50cnkpIHtcbiAgICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xpZW50RmFjdG9yeShcbiAgICAgICAge1xuICAgICAgICAgIGNyZWRlbnRpYWxzOiB7XG4gICAgICAgICAgICBhY2Nlc3NUb2tlbjogbWV0YWRhdGEuY3JlZGVudGlhbHMuYWNjZXNzVG9rZW4sXG4gICAgICAgICAgICBhY2NvdW50SWQ6IG1ldGFkYXRhLmNyZWRlbnRpYWxzLmFjY291bnRJZCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRyYW5zcG9ydEtpbmQ6IHRoaXMudHJhbnNwb3J0S2luZCxcbiAgICAgICAgICBmZXRjaDogdGhpcy5mZXRjaEltcGwsXG4gICAgICAgICAgcmVmcmVzaENyZWRlbnRpYWxzOiAoKSA9PiB0aGlzLnJlZnJlc2hDcmVkZW50aWFscyhzZWxlY3Rpb24udG9rZW5JZCksXG4gICAgICAgIH0sXG4gICAgICAgIHNlbGVjdGlvbi50b2tlbklkLFxuICAgICAgKTtcbiAgICAgIGVudHJ5ID0geyBnZW5lcmF0aW9uOiBtZXRhZGF0YS5nZW5lcmF0aW9uLCBjbGllbnQsIGluRmxpZ2h0OiAwLCByZXRpcmVkOiBmYWxzZSB9O1xuICAgICAgdGhpcy5jbGllbnRzLnNldChzZWxlY3Rpb24udG9rZW5JZCwgZW50cnkpO1xuICAgIH1cbiAgICBlbnRyeS5pbkZsaWdodCsrO1xuICAgIHJldHVybiBlbnRyeTtcbiAgfVxuXG4gIHByaXZhdGUgcmVsZWFzZUNsaWVudChlbnRyeTogQ2xpZW50RW50cnkpOiB2b2lkIHtcbiAgICBlbnRyeS5pbkZsaWdodCA9IE1hdGgubWF4KDAsIGVudHJ5LmluRmxpZ2h0IC0gMSk7XG4gICAgaWYgKGVudHJ5LnJldGlyZWQgJiYgZW50cnkuaW5GbGlnaHQgPT09IDApIHtcbiAgICAgIHRoaXMucmV0aXJlZENsaWVudHMuZGVsZXRlKGVudHJ5KTtcbiAgICAgIGVudHJ5LmNsaWVudC5jbG9zZT8uKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIG1hcCDsl5DshJwg65a87Ja064K06rOgLCDsp4Ttlokg7KSR7J24IOyalOyyreydtCDsl4bsnYQg65WM66eMIOymieyLnCDri6vripTri6QuICovXG4gIHByaXZhdGUgcmV0aXJlQ2xpZW50KHRva2VuSWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGVudHJ5ID0gdGhpcy5jbGllbnRzLmdldCh0b2tlbklkKTtcbiAgICBpZiAoIWVudHJ5KSByZXR1cm47XG4gICAgdGhpcy5jbGllbnRzLmRlbGV0ZSh0b2tlbklkKTtcbiAgICBlbnRyeS5yZXRpcmVkID0gdHJ1ZTtcbiAgICBpZiAoZW50cnkuaW5GbGlnaHQgPT09IDApIGVudHJ5LmNsaWVudC5jbG9zZT8uKCk7XG4gICAgZWxzZSB0aGlzLnJldGlyZWRDbGllbnRzLmFkZChlbnRyeSk7XG4gIH1cblxuICAvKipcbiAgICog7Yag7YGwIOyEoO2DnSDigJQgcXVvdGEgZ2F0ZSDrpbwg7Ya16rO87ZWcIGFjdGl2ZSDthqDtgbAg7KSR7JeQ7IScIOqzoOuluOuLpC4gY2FjaGUgYWZmaW5pdHkg7ISg7Zi4XG4gICAqIO2GoO2BsOydtCBlbGlnaWJsZSDtlZjrqbQg6re4IO2MkOygleunjOycvOuhnCDsponsi5wg6rKw7KCV7ZWY6rOgKOyghOyytCBzd2VlcCDsg53rnrUsIHdlaWdodGVkIOyDge2DnFxuICAgKiDruYTrs4Dqsr0pLCDslYTri4jrqbQg67OR66CsIHF1b3RhIO2MkOyglSDtm4Qgc21vb3RoIHdlaWdodGVkIHJvdW5kLXJvYmluLiDrj5nsi5zshLEg7IOB7ZWc7J20XG4gICAqIOyXhuycvOuvgOuhnCBcIuu5iCDsnpDrpqxcIiDqsJzrhZDrj4Qg7JeG64ukIOKAlCDshKDtg50g7KaJ7IucIOyLpO2WieydtOuLpC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc2VsZWN0VG9rZW4oXG4gICAgcHJlZmVycmVkVG9rZW5JZDogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICAgIHJlcXVpcmVQcmVmZXJyZWRUb2tlbjogYm9vbGVhbixcbiAgICBzaWduYWw6IEFib3J0U2lnbmFsLFxuICApOiBQcm9taXNlPFRva2VuU2VsZWN0aW9uPiB7XG4gICAgaWYgKHByZWZlcnJlZFRva2VuSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgcHJlZmVycmVkID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldChwcmVmZXJyZWRUb2tlbklkKTtcbiAgICAgIGlmIChwcmVmZXJyZWQ/LmFjdGl2ZSAmJiAoYXdhaXQgdGhpcy5pc1F1b3RhRWxpZ2libGUocHJlZmVycmVkVG9rZW5JZCwgcHJlZmVycmVkLCBzaWduYWwpKSkge1xuICAgICAgICByZXR1cm4geyB0b2tlbklkOiBwcmVmZXJyZWRUb2tlbklkLCBtZXRhZGF0YTogcHJlZmVycmVkIH07XG4gICAgICB9XG4gICAgICBpZiAocmVxdWlyZVByZWZlcnJlZFRva2VuKSB7XG4gICAgICAgIGlmICghcHJlZmVycmVkPy5hY3RpdmUpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFByZWZlcnJlZCBvcGVuYWkgdG9rZW4gJHtwcmVmZXJyZWRUb2tlbklkfSBpcyBub3QgYXZhaWxhYmxlYCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGhyZXNob2xkID0gcHJlZmVycmVkLnF1b3RhVGhyZXNob2xkO1xuICAgICAgICBpZiAodGhyZXNob2xkICE9PSBudWxsICYmIHRocmVzaG9sZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFF1b3RhVGhyZXNob2xkRXhjZWVkZWRFcnJvcihcbiAgICAgICAgICAgIHF1b3RhTWVzc2FnZShbeyBuYW1lOiBwcmVmZXJyZWQubmFtZSwgdGhyZXNob2xkIH1dKSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8g7Yag7YGw67OEIHF1b3RhIO2MkOygleydgCDshJzroZwg64+F66a97J206528IOuzkeugrOuhnCDigJQg7KeB66CsIOuMgOq4sOuKlCDsvZzrk5wg7LqQ7Iuc7JeQ7IScXG4gICAgLy8g7Yag7YGwIOyImCDDlyDsobDtmowg7KeA7Jew66eM7YG8IOyalOyyrSDsi5zsnpHsnYQg64qm7LaY64ukLlxuICAgIGNvbnN0IGNoZWNrcyA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgWy4uLnRoaXMudG9rZW5NZXRhZGF0YS5lbnRyaWVzKCldXG4gICAgICAgIC5maWx0ZXIoKFssIHRva2VuXSkgPT4gdG9rZW4uYWN0aXZlKVxuICAgICAgICAubWFwKGFzeW5jIChbaWQsIHRva2VuXSkgPT4gKHtcbiAgICAgICAgICBpZCxcbiAgICAgICAgICB0b2tlbixcbiAgICAgICAgICBlbGlnaWJsZTogYXdhaXQgdGhpcy5pc1F1b3RhRWxpZ2libGUoaWQsIHRva2VuLCBzaWduYWwpLFxuICAgICAgICB9KSksXG4gICAgKTtcbiAgICBjb25zdCBlbGlnaWJsZSA9IG5ldyBTZXQoY2hlY2tzLmZpbHRlcigoYykgPT4gYy5lbGlnaWJsZSkubWFwKChjKSA9PiBjLmlkKSk7XG4gICAgaWYgKGVsaWdpYmxlLnNpemUgPT09IDApIHtcbiAgICAgIGNvbnN0IG92ZXIgPSBjaGVja3NcbiAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAoYykgPT5cbiAgICAgICAgICAgICFjLmVsaWdpYmxlICYmIGMudG9rZW4ucXVvdGFUaHJlc2hvbGQgIT09IG51bGwgJiYgYy50b2tlbi5xdW90YVRocmVzaG9sZCAhPT0gdW5kZWZpbmVkLFxuICAgICAgICApXG4gICAgICAgIC5tYXAoKGMpID0+ICh7IG5hbWU6IGMudG9rZW4ubmFtZSwgdGhyZXNob2xkOiBjLnRva2VuLnF1b3RhVGhyZXNob2xkIGFzIG51bWJlciB9KSk7XG4gICAgICBpZiAob3Zlci5sZW5ndGgpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oXCJxdW90YV90aHJlc2hvbGQgZ2F0ZTogYWxsX2V4Y2VlZGVkXCIsIHtcbiAgICAgICAgICBwcm92aWRlcjogXCJvcGVuYWlcIixcbiAgICAgICAgICBvdmVyVGhyZXNob2xkVG9rZW5zOiBvdmVyLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhyb3cgbmV3IFF1b3RhVGhyZXNob2xkRXhjZWVkZWRFcnJvcihxdW90YU1lc3NhZ2Uob3ZlcikpO1xuICAgICAgfVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTk9fT1BFTkFJX1dPUktFUlNcIik7XG4gICAgfVxuICAgIGNvbnN0IHNlbGVjdGVkID0gdGhpcy5zZWxlY3Rvci5zZWxlY3QoZWxpZ2libGUpO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gc2VsZWN0ZWQgIT09IG51bGwgPyB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHNlbGVjdGVkKSA6IHVuZGVmaW5lZDtcbiAgICBpZiAoc2VsZWN0ZWQgPT09IG51bGwgfHwgIW1ldGFkYXRhKSB0aHJvdyBuZXcgRXJyb3IoXCJOT19PUEVOQUlfV09SS0VSU1wiKTtcbiAgICByZXR1cm4geyB0b2tlbklkOiBzZWxlY3RlZCwgbWV0YWRhdGEgfTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0VG9rZW4oXG4gICAgaWQ6IG51bWJlcixcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgIHF1b3RhVGhyZXNob2xkOiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkLFxuICAgIHdlaWdodDogbnVtYmVyLFxuICAgIGFjdGl2ZTogYm9vbGVhbixcbiAgKTogdm9pZCB7XG4gICAgY29uc3Qgb2xkID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldChpZCk7XG4gICAgaWYgKG9sZCkge1xuICAgICAgT2JqZWN0LmFzc2lnbihvbGQsIHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgY3JlZGVudGlhbHMsXG4gICAgICAgIHF1b3RhVGhyZXNob2xkLFxuICAgICAgICB3ZWlnaHQsXG4gICAgICAgIGFjdGl2ZSxcbiAgICAgICAgZ2VuZXJhdGlvbjogb2xkLmdlbmVyYXRpb24gKyAxLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudG9rZW5NZXRhZGF0YS5zZXQoaWQsIHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgY3JlZGVudGlhbHMsXG4gICAgICAgIHF1b3RhVGhyZXNob2xkLFxuICAgICAgICB3ZWlnaHQsXG4gICAgICAgIGFjdGl2ZSxcbiAgICAgICAgZ2VuZXJhdGlvbjogMSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLnNlbGVjdG9yLnNldFRva2VuKGlkLCB3ZWlnaHQpO1xuICAgIHRoaXMuaW52YWxpZGF0ZVJhdGVMaW1pdHNDYWNoZShpZCk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWQuZGVsZXRlKGlkKTtcbiAgfVxuXG4gIGFzeW5jIGdldFJhdGVMaW1pdHNCeVRva2VuSWQoXG4gICAgdG9rZW5JZDogbnVtYmVyLFxuICAgIHNpZ25hbD86IEFib3J0U2lnbmFsLFxuICApOiBQcm9taXNlPE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YT4ge1xuICAgIGNvbnN0IHRva2VuID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldCh0b2tlbklkKTtcbiAgICBpZiAoIXRva2VuKSB0aHJvdyBuZXcgRXJyb3IoYG9wZW5haSB0b2tlbiAke3Rva2VuSWR9IG5vdCBmb3VuZGApO1xuICAgIGNvbnN0IGdlbmVyYXRpb24gPSB0b2tlbi5nZW5lcmF0aW9uO1xuICAgIGNvbnN0IGNhY2hlZCA9IHRoaXMucmF0ZUxpbWl0c0NhY2hlLmdldCh0b2tlbklkKTtcbiAgICBpZiAoXG4gICAgICBjYWNoZWQgJiZcbiAgICAgIGNhY2hlZC5nZW5lcmF0aW9uID09PSB0b2tlbi5nZW5lcmF0aW9uICYmXG4gICAgICBEYXRlLm5vdygpIC0gY2FjaGVkLmNhY2hlZEF0IDwgT3BlbkFJRGlzcGF0Y2hlci5SQVRFX0xJTUlUU19DQUNIRV9UVExcbiAgICApXG4gICAgICByZXR1cm4gY2FjaGVkO1xuXG4gICAgLy8gc2luZ2xlLWZsaWdodDog64+Z7Iuc7ISxIOyDge2VnOydtCDsl4bslrTsp4Qg65Kk66GcIFRUTCDrp4zro4wg7Iic6rCEIOuPmeyLnCDsmpTssq0g7IiY66eM7YG8IOqwmeydgFxuICAgIC8vIOyhsO2ajOqwgCDrqrDrprQg7IiYIOyeiOuLpCDigJQg7KeE7ZaJIOykkeyduCBmZXRjaCDrpbwg6rO17Jyg7ZWc64ukLiDstZzstIgg7Zi47Lac7J6Q7J2YIGFib3J0IOuhnFxuICAgIC8vIOqzteycoCDsobDtmozqsIAg7Iuk7Yyo7ZW064+EIOyGjOu5hOyymChpc1F1b3RhRWxpZ2libGUp6rCAIGZhaWwtb3BlbiDsnLzroZwg7LKY66as7ZWc64ukLlxuICAgIGNvbnN0IHBlbmRpbmcgPSB0aGlzLnBlbmRpbmdSYXRlTGltaXRzLmdldCh0b2tlbklkKTtcbiAgICBpZiAocGVuZGluZz8udG9rZW4gPT09IHRva2VuICYmIHBlbmRpbmcuZ2VuZXJhdGlvbiA9PT0gZ2VuZXJhdGlvbikgcmV0dXJuIHBlbmRpbmcucHJvbWlzZTtcbiAgICBjb25zdCBmZXRjaFByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVhZE9wZW5BSVF1b3RhVXNhZ2Uoe1xuICAgICAgICBjcmVkZW50aWFsczogdG9rZW4uY3JlZGVudGlhbHMsXG4gICAgICAgIHJlZnJlc2hDcmVkZW50aWFsczogKCkgPT4gdGhpcy5yZWZyZXNoQ3JlZGVudGlhbHModG9rZW5JZCksXG4gICAgICAgIGZldGNoOiB0aGlzLmZldGNoSW1wbCxcbiAgICAgICAgLi4uKHNpZ25hbCA/IHsgc2lnbmFsIH0gOiB7fSksXG4gICAgICB9KTtcbiAgICAgIGlmIChyZXN1bHQua2luZCA9PT0gXCJsb29rdXBfZmFpbGVkXCIpIHRocm93IG5ldyBFcnJvcihyZXN1bHQucmVhc29uKTtcbiAgICAgIGlmICghcmVzdWx0LnJhdykgdGhyb3cgbmV3IEVycm9yKFwiT3BlbkFJIHF1b3RhIHJlc3BvbnNlIG1pc3NpbmcgcmF3IHJhdGUgbGltaXRzXCIpO1xuICAgICAgY29uc3QgZW50cnkgPSB7IGRhdGE6IHJlc3VsdC5yYXcsIGNhY2hlZEF0OiBEYXRlLm5vdygpLCBnZW5lcmF0aW9uIH07XG4gICAgICBpZiAodGhpcy50b2tlbk1ldGFkYXRhLmdldCh0b2tlbklkKSA9PT0gdG9rZW4gJiYgdG9rZW4uZ2VuZXJhdGlvbiA9PT0gZ2VuZXJhdGlvbikge1xuICAgICAgICB0aGlzLnJhdGVMaW1pdHNDYWNoZS5zZXQodG9rZW5JZCwgZW50cnkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGVudHJ5O1xuICAgIH0pKCkuZmluYWxseSgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5wZW5kaW5nUmF0ZUxpbWl0cy5nZXQodG9rZW5JZCk/LnByb21pc2UgPT09IGZldGNoUHJvbWlzZSkge1xuICAgICAgICB0aGlzLnBlbmRpbmdSYXRlTGltaXRzLmRlbGV0ZSh0b2tlbklkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLnBlbmRpbmdSYXRlTGltaXRzLnNldCh0b2tlbklkLCB7IHRva2VuLCBnZW5lcmF0aW9uLCBwcm9taXNlOiBmZXRjaFByb21pc2UgfSk7XG4gICAgcmV0dXJuIGZldGNoUHJvbWlzZTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVmcmVzaENyZWRlbnRpYWxzKHRva2VuSWQ6IG51bWJlcikge1xuICAgIGNvbnN0IHByZXZpb3VzID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldCh0b2tlbklkKTtcbiAgICBjb25zdCBnZW5lcmF0aW9uID0gcHJldmlvdXM/LmdlbmVyYXRpb247XG4gICAgY29uc3QgcmVmcmVzaGVkID0gYXdhaXQgaGFuZGxlQ2hhdGdwdEF1dGhUb2tlbnNSZWZyZXNoKHRva2VuSWQpO1xuICAgIGNvbnN0IGNyZWRlbnRpYWxzID0ge1xuICAgICAgYWNjZXNzVG9rZW46IHJlZnJlc2hlZC5hY2Nlc3NUb2tlbixcbiAgICAgIGFjY291bnRJZDogcmVmcmVzaGVkLmNoYXRncHRBY2NvdW50SWQsXG4gICAgfTtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldCh0b2tlbklkKTtcbiAgICBpZiAoIWN1cnJlbnQ/LmFjdGl2ZSkgdGhyb3cgbmV3IEVycm9yKGBvcGVuYWkgdG9rZW4gJHt0b2tlbklkfSBpcyBubyBsb25nZXIgYWN0aXZlYCk7XG4gICAgLy8gQSBzdWJzY3JpYmVyIHVwZGF0ZSBtYXkgYWxyZWFkeSBjb250YWluIG5ld2VyIGNyZWRlbnRpYWxzLiBOZXZlciBvdmVyd3JpdGUgaXRcbiAgICAvLyB3aXRoIHRoZSByZXN1bHQgb2YgYSByZWZyZXNoIHRoYXQgc3RhcnRlZCBhZ2FpbnN0IGFuIG9sZGVyIGdlbmVyYXRpb24uXG4gICAgaWYgKGN1cnJlbnQgPT09IHByZXZpb3VzICYmIGN1cnJlbnQuZ2VuZXJhdGlvbiA9PT0gZ2VuZXJhdGlvbikge1xuICAgICAgY3VycmVudC5jcmVkZW50aWFscyA9IHsgLi4uY3VycmVudC5jcmVkZW50aWFscywgLi4uY3JlZGVudGlhbHMgfTtcbiAgICAgIHRoaXMucmV0aXJlQ2xpZW50KHRva2VuSWQpO1xuICAgICAgdGhpcy5pbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKHRva2VuSWQpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgYWNjZXNzVG9rZW46IGN1cnJlbnQuY3JlZGVudGlhbHMuYWNjZXNzVG9rZW4sXG4gICAgICBhY2NvdW50SWQ6IGN1cnJlbnQuY3JlZGVudGlhbHMuYWNjb3VudElkLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGlzUXVvdGFFbGlnaWJsZShcbiAgICBpZDogbnVtYmVyLFxuICAgIHRva2VuOiBUb2tlbk1ldGFkYXRhLFxuICAgIHNpZ25hbD86IEFib3J0U2lnbmFsLFxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAodG9rZW4ucXVvdGFUaHJlc2hvbGQgPT09IG51bGwgfHwgdG9rZW4ucXVvdGFUaHJlc2hvbGQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHRydWU7XG4gICAgY29uc3QgZ2VuZXJhdGlvbiA9IHRva2VuLmdlbmVyYXRpb247XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVhZE9wZW5BSVF1b3RhVXNhZ2UoYXN5bmMgKCkgPT4gdGhpcy5nZXRSYXRlTGltaXRzQnlUb2tlbklkKGlkLCBzaWduYWwpKTtcbiAgICBpZiAodGhpcy50b2tlbk1ldGFkYXRhLmdldChpZCkgIT09IHRva2VuIHx8IHRva2VuLmdlbmVyYXRpb24gIT09IGdlbmVyYXRpb24pIHJldHVybiBmYWxzZTtcbiAgICBpZiAocmVzdWx0LmtpbmQgPT09IFwibG9va3VwX2ZhaWxlZFwiKSB7XG4gICAgICB0aGlzLnF1b3RhQmxvY2tlZC5kZWxldGUoaWQpO1xuICAgICAgbG9nZ2VyLndhcm4oXCJxdW90YV90aHJlc2hvbGQgZ2F0ZTogbG9va3VwX2ZhaWxfb3BlblwiLCB7XG4gICAgICAgIHRva2VuSWQ6IGlkLFxuICAgICAgICB0b2tlbk5hbWU6IHRva2VuLm5hbWUsXG4gICAgICAgIGxvb2t1cFJlYXNvbjogcmVzdWx0LnJlYXNvbixcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChyZXN1bHQudXRpbGl6YXRpb25QY3QgPj0gdG9rZW4ucXVvdGFUaHJlc2hvbGQpIHtcbiAgICAgIGlmICghdGhpcy5xdW90YUJsb2NrZWQuaGFzKGlkKSlcbiAgICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgICAgYHF1b3RhX3RocmVzaG9sZCBnYXRlOiBvdmVyX3RocmVzaG9sZCAke3Rva2VuLm5hbWV9WyR7aWR9XSAoJHtyZXN1bHQudXRpbGl6YXRpb25QY3R9JSA+PSAke3Rva2VuLnF1b3RhVGhyZXNob2xkfSUpYCxcbiAgICAgICAgKTtcbiAgICAgIHRoaXMucXVvdGFCbG9ja2VkLmFkZChpZCk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0aGlzLnF1b3RhQmxvY2tlZC5kZWxldGUoaWQpKVxuICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgIGBxdW90YV90aHJlc2hvbGQgZ2F0ZTogcmVjb3ZlcmVkICR7dG9rZW4ubmFtZX1bJHtpZH1dICgke3Jlc3VsdC51dGlsaXphdGlvblBjdH0lIDwgJHt0b2tlbi5xdW90YVRocmVzaG9sZH0lKWAsXG4gICAgICApO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnJhdGVMaW1pdHNDYWNoZS5kZWxldGUoaWQpO1xuICB9XG5cbiAgZ2V0IHRva2VuQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gWy4uLnRoaXMudG9rZW5NZXRhZGF0YS52YWx1ZXMoKV0uZmlsdGVyKCh0KSA9PiB0LmFjdGl2ZSkubGVuZ3RoO1xuICB9XG4gIGdldCBpbkZsaWdodCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmluRmxpZ2h0Q291bnQ7XG4gIH1cblxuICAvKipcbiAgICog7Yag7YGw67OEIOy/vO2EsCDsiqTrg4Xsg7cg4oCUIOyLoOyEoO2VnChyYXRlIGxpbWl0cyBUVEwg64K0KSDsupDsi5zrp4wg7J296rOgIOygiOuMgCBmZXRjaCDtlZjsp4Ag7JWK64qU64ukLlxuICAgKiBtb25pdCB2aXRhbHMg64qUIOuhnOq3uCDtj7Trp4Hsl5Ag7Y647Iq57ZWY64qUIOqwkuydtOudvCDsl6zquLDshJwg64Sk7Yq47JuM7YGs66W8IO2DgOuptCDslYgg65Cc64ukLlxuICAgKiB0aHJlc2hvbGQg66+47ISk7KCVIO2GoO2BsOydgCDsv7zthLAg7YyQ7KCV7J2EIOuPjOyngCDslYrslYQgdXNlZFBlcmNlbnQg6rCAIG51bGwg66GcIOuCqOydhCDsiJgg7J6I64ukLlxuICAgKi9cbiAgZ2V0IHF1b3RhQnlUb2tlbigpOiBBcnJheTx7XG4gICAgbmFtZTogc3RyaW5nO1xuICAgIHVzZWRQZXJjZW50OiBudW1iZXIgfCBudWxsO1xuICAgIHRocmVzaG9sZDogbnVtYmVyIHwgbnVsbDtcbiAgICBibG9ja2VkOiBib29sZWFuO1xuICAgIHJlc2V0c0F0OiBudW1iZXIgfCBudWxsO1xuICB9PiB7XG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICByZXR1cm4gWy4uLnRoaXMudG9rZW5NZXRhZGF0YS5lbnRyaWVzKCldXG4gICAgICAubWFwKChbaWQsIHRdKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhY2hlZCA9IHRoaXMucmF0ZUxpbWl0c0NhY2hlLmdldChpZCk7XG4gICAgICAgIGNvbnN0IGZyZXNoID1cbiAgICAgICAgICBjYWNoZWQgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgIGNhY2hlZC5nZW5lcmF0aW9uID09PSB0LmdlbmVyYXRpb24gJiZcbiAgICAgICAgICBub3cgLSBjYWNoZWQuY2FjaGVkQXQgPCBPcGVuQUlEaXNwYXRjaGVyLlJBVEVfTElNSVRTX0NBQ0hFX1RUTDtcbiAgICAgICAgY29uc3QgcHJpbWFyeSA9IGZyZXNoID8gY2FjaGVkLmRhdGEucmF0ZUxpbWl0cz8ucHJpbWFyeSA6IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBuYW1lOiB0Lm5hbWUsXG4gICAgICAgICAgdXNlZFBlcmNlbnQ6IHByaW1hcnk/LnVzZWRQZXJjZW50ID8/IG51bGwsXG4gICAgICAgICAgdGhyZXNob2xkOiB0LnF1b3RhVGhyZXNob2xkID8/IG51bGwsXG4gICAgICAgICAgYmxvY2tlZDogdGhpcy5xdW90YUJsb2NrZWQuaGFzKGlkKSxcbiAgICAgICAgICAvLyB3aGFtIOydmCByZXNldHNBdCDsnYAgdW5peCDstIgg64uo7JyE64ukKHFncmlkLmZyYW1lIHVuaXhTZWNvbmRzVG9Jc28g7JmAIOuPmeydvCDqt5zslb0pLlxuICAgICAgICAgIC8vIOyGjOu5hOyymOqwgCDri6jsnITrpbwg7LaU7Lih7ZWY7KeAIOyViuuPhOuhnSDsl6zquLDshJwgbXMgZXBvY2gg7Jy866GcIOygleq3nO2ZlO2VnOuLpC5cbiAgICAgICAgICByZXNldHNBdDpcbiAgICAgICAgICAgIHByaW1hcnk/LnJlc2V0c0F0ICE9PSBudWxsICYmIHByaW1hcnk/LnJlc2V0c0F0ICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgPyBwcmltYXJ5LnJlc2V0c0F0ICogMTAwMFxuICAgICAgICAgICAgICA6IG51bGwsXG4gICAgICAgIH07XG4gICAgICB9KVxuICAgICAgLnRvU29ydGVkKChhLCBiKSA9PiBhLm5hbWUubG9jYWxlQ29tcGFyZShiLm5hbWUpKTtcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBd0JBLE1BQU0sU0FBUyxVQUFVLENBQUMsU0FBUyxtQkFBbUIsQ0FBQztBQUd2RCxNQUFNLDZCQUE2QjtB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
@@ -0,0 +1,145 @@
1
+ import { ImageGenerationMetadata } from "../../../application/qgrid/qgrid.types.js";
2
+ import { CHATGPT_CODEX_RESPONSES_URL, OpenAIProtocolError } from "./openai-backend-protocol.js";
3
+ import { z } from "zod";
4
+ import { PNG } from "pngjs";
5
+ //#region src/utils/providers/openai/openai-image-generation.ts
6
+ const MAX_PNG_BYTES = 32 * 1024 * 1024;
7
+ const MAX_IMAGE_PIXELS = 4096 * 4096;
8
+ const MAX_RESPONSE_BYTES = 64 * 1024 * 1024;
9
+ const PNG_SIGNATURE = Buffer.from([
10
+ 137,
11
+ 80,
12
+ 78,
13
+ 71,
14
+ 13,
15
+ 10,
16
+ 26,
17
+ 10
18
+ ]);
19
+ function buildStandaloneImageRequest(options) {
20
+ if (options.outputSchema || options.tools?.length) throw new OpenAIProtocolError("Transparent image generation does not support tools or structured output");
21
+ const controls = options.imageGeneration;
22
+ if (!controls || controls === true || controls.background !== "transparent") throw new OpenAIProtocolError("Standalone images require an explicit transparent background request");
23
+ const text = [];
24
+ const images = [];
25
+ if (options.instructions) text.push(`System instructions:\n${options.instructions}`);
26
+ for (const item of options.history) {
27
+ if (item.type === "reasoning") continue;
28
+ if (item.type === "image_generation_call" && typeof item.result === "string") {
29
+ images.push({ image_url: `data:image/png;base64,${item.result}` });
30
+ continue;
31
+ }
32
+ if (item.type !== "message" && typeof item.role !== "string") throw new OpenAIProtocolError("Unsupported conversation item for transparent image generation");
33
+ if (typeof item.content === "string") {
34
+ text.push(`${item.role ?? "user"}:\n${item.content}`);
35
+ continue;
36
+ }
37
+ if (!Array.isArray(item.content)) throw new OpenAIProtocolError("Unsupported message content for transparent image generation");
38
+ for (const part of item.content) {
39
+ if (!part || typeof part !== "object") throw new OpenAIProtocolError("Unsupported message part for transparent image generation");
40
+ if ([
41
+ "input_text",
42
+ "output_text",
43
+ "text"
44
+ ].includes(part.type) && typeof part.text === "string") text.push(`${item.role ?? "user"}:\n${part.text}`);
45
+ else if (part.type === "input_image" || part.type === "image_url") {
46
+ const url = typeof part.image_url === "string" ? part.image_url : part.image_url?.url;
47
+ if (typeof url !== "string" || !/^(https:\/\/|data:image\/)/i.test(url)) throw new OpenAIProtocolError("Image references must be HTTPS URLs or image data URLs");
48
+ images.push({ image_url: url });
49
+ } else throw new OpenAIProtocolError("Unsupported message part for transparent image generation");
50
+ }
51
+ }
52
+ if (images.length > 5) throw new OpenAIProtocolError("Transparent image editing supports at most 5 reference images");
53
+ if (!text.some((part) => part.trim())) throw new OpenAIProtocolError("Image prompt is empty");
54
+ return {
55
+ url: CHATGPT_CODEX_RESPONSES_URL.replace(/\/responses$/, `/images/${images.length ? "edits" : "generations"}`),
56
+ body: {
57
+ model: "gpt-image-2",
58
+ prompt: text.join("\n\n"),
59
+ background: "transparent",
60
+ ...controls.quality ? { quality: controls.quality } : {},
61
+ ...controls.size ? { size: controls.size } : {},
62
+ ...images.length ? { images } : {}
63
+ }
64
+ };
65
+ }
66
+ function inspectTransparentPng(base64) {
67
+ if (base64.length > Math.ceil(MAX_PNG_BYTES / 3) * 4 || !/^[A-Za-z0-9+/]+={0,2}$/.test(base64)) throw new OpenAIProtocolError("Invalid or oversized generated PNG");
68
+ const bytes = Buffer.from(base64, "base64");
69
+ if (bytes.length < 33 || !bytes.subarray(0, 8).equals(PNG_SIGNATURE) || bytes.toString("ascii", 12, 16) !== "IHDR") throw new OpenAIProtocolError("Image generation did not return a PNG");
70
+ const width = bytes.readUInt32BE(16);
71
+ const height = bytes.readUInt32BE(20);
72
+ if (!width || !height || width * height > MAX_IMAGE_PIXELS) throw new OpenAIProtocolError("Generated PNG dimensions exceed the decoding limit");
73
+ let image;
74
+ try {
75
+ image = PNG.sync.read(bytes);
76
+ } catch {
77
+ throw new OpenAIProtocolError("Image generation returned an invalid PNG");
78
+ }
79
+ let transparent = false;
80
+ let visible = false;
81
+ for (let i = 3; i < image.data.length; i += 4) {
82
+ transparent ||= image.data[i] === 0;
83
+ visible ||= image.data[i] > 0;
84
+ if (transparent && visible) return {
85
+ width: image.width,
86
+ height: image.height
87
+ };
88
+ }
89
+ throw new OpenAIProtocolError("Image generation did not return visible content on a transparent background");
90
+ }
91
+ async function readStandaloneImageResponse(response) {
92
+ if (!response.body) throw new OpenAIProtocolError("Image response had no body");
93
+ const reader = response.body.getReader();
94
+ const chunks = [];
95
+ let size = 0;
96
+ try {
97
+ while (true) {
98
+ const { done, value } = await reader.read();
99
+ if (done) break;
100
+ size += value.byteLength;
101
+ if (size > MAX_RESPONSE_BYTES) {
102
+ await reader.cancel();
103
+ throw new OpenAIProtocolError("Image response exceeded the size limit");
104
+ }
105
+ chunks.push(value);
106
+ }
107
+ } finally {
108
+ reader.releaseLock();
109
+ }
110
+ const schema = z.object({
111
+ data: z.array(z.object({
112
+ b64_json: z.string().min(1),
113
+ revised_prompt: z.string().nullish()
114
+ })).min(1).max(16),
115
+ quality: z.string().optional(),
116
+ usage: ImageGenerationMetadata.shape.usage
117
+ });
118
+ let parsed;
119
+ try {
120
+ parsed = schema.parse(JSON.parse(Buffer.concat(chunks).toString("utf8")));
121
+ } catch {
122
+ throw new OpenAIProtocolError("Invalid standalone image response");
123
+ }
124
+ return parsed.data.map((item, index) => {
125
+ const dimensions = inspectTransparentPng(item.b64_json);
126
+ return {
127
+ type: "image",
128
+ base64: item.b64_json,
129
+ mimeType: "image/png",
130
+ ...item.revised_prompt ? { revisedPrompt: item.revised_prompt } : {},
131
+ generation: {
132
+ route: "codex-images",
133
+ model: "gpt-image-2",
134
+ background: "transparent",
135
+ size: `${dimensions.width}x${dimensions.height}`,
136
+ ...parsed.quality ? { quality: parsed.quality } : {},
137
+ ...index === 0 && parsed.usage ? { usage: parsed.usage } : {}
138
+ }
139
+ };
140
+ });
141
+ }
142
+ //#endregion
143
+ export { buildStandaloneImageRequest, inspectTransparentPng, readStandaloneImageResponse };
144
+
145
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLWltYWdlLWdlbmVyYXRpb24uanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9vcGVuYWkvb3BlbmFpLWltYWdlLWdlbmVyYXRpb24udHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUE5HIH0gZnJvbSBcInBuZ2pzXCI7XG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiO1xuXG5pbXBvcnQgeyBJbWFnZUdlbmVyYXRpb25NZXRhZGF0YSB9IGZyb20gXCIuLi8uLi8uLi9hcHBsaWNhdGlvbi9xZ3JpZC9xZ3JpZC50eXBlc1wiO1xuaW1wb3J0IHtcbiAgQ0hBVEdQVF9DT0RFWF9SRVNQT05TRVNfVVJMLFxuICBPcGVuQUlQcm90b2NvbEVycm9yLFxuICB0eXBlIE9wZW5BSU5vcm1hbGl6ZWRFdmVudCxcbiAgdHlwZSBPcGVuQUlSZXNwb25zZXNPcHRpb25zLFxufSBmcm9tIFwiLi9vcGVuYWktYmFja2VuZC1wcm90b2NvbFwiO1xuXG5jb25zdCBNQVhfUE5HX0JZVEVTID0gMzIgKiAxMDI0ICogMTAyNDtcbmNvbnN0IE1BWF9JTUFHRV9QSVhFTFMgPSA0MDk2ICogNDA5NjtcbmNvbnN0IE1BWF9SRVNQT05TRV9CWVRFUyA9IDY0ICogMTAyNCAqIDEwMjQ7XG5jb25zdCBQTkdfU0lHTkFUVVJFID0gQnVmZmVyLmZyb20oWzEzNywgODAsIDc4LCA3MSwgMTMsIDEwLCAyNiwgMTBdKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkU3RhbmRhbG9uZUltYWdlUmVxdWVzdChvcHRpb25zOiBPcGVuQUlSZXNwb25zZXNPcHRpb25zKSB7XG4gIGlmIChvcHRpb25zLm91dHB1dFNjaGVtYSB8fCBvcHRpb25zLnRvb2xzPy5sZW5ndGgpIHtcbiAgICB0aHJvdyBuZXcgT3BlbkFJUHJvdG9jb2xFcnJvcihcbiAgICAgIFwiVHJhbnNwYXJlbnQgaW1hZ2UgZ2VuZXJhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IHRvb2xzIG9yIHN0cnVjdHVyZWQgb3V0cHV0XCIsXG4gICAgKTtcbiAgfVxuICBjb25zdCBjb250cm9scyA9IG9wdGlvbnMuaW1hZ2VHZW5lcmF0aW9uO1xuICBpZiAoIWNvbnRyb2xzIHx8IGNvbnRyb2xzID09PSB0cnVlIHx8IGNvbnRyb2xzLmJhY2tncm91bmQgIT09IFwidHJhbnNwYXJlbnRcIikge1xuICAgIHRocm93IG5ldyBPcGVuQUlQcm90b2NvbEVycm9yKFxuICAgICAgXCJTdGFuZGFsb25lIGltYWdlcyByZXF1aXJlIGFuIGV4cGxpY2l0IHRyYW5zcGFyZW50IGJhY2tncm91bmQgcmVxdWVzdFwiLFxuICAgICk7XG4gIH1cbiAgY29uc3QgdGV4dDogc3RyaW5nW10gPSBbXTtcbiAgY29uc3QgaW1hZ2VzOiBBcnJheTx7IGltYWdlX3VybDogc3RyaW5nIH0+ID0gW107XG4gIGlmIChvcHRpb25zLmluc3RydWN0aW9ucykgdGV4dC5wdXNoKGBTeXN0ZW0gaW5zdHJ1Y3Rpb25zOlxcbiR7b3B0aW9ucy5pbnN0cnVjdGlvbnN9YCk7XG4gIGZvciAoY29uc3QgaXRlbSBvZiBvcHRpb25zLmhpc3RvcnkpIHtcbiAgICBpZiAoaXRlbS50eXBlID09PSBcInJlYXNvbmluZ1wiKSBjb250aW51ZTtcbiAgICBpZiAoaXRlbS50eXBlID09PSBcImltYWdlX2dlbmVyYXRpb25fY2FsbFwiICYmIHR5cGVvZiBpdGVtLnJlc3VsdCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgaW1hZ2VzLnB1c2goeyBpbWFnZV91cmw6IGBkYXRhOmltYWdlL3BuZztiYXNlNjQsJHtpdGVtLnJlc3VsdH1gIH0pO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGlmIChpdGVtLnR5cGUgIT09IFwibWVzc2FnZVwiICYmIHR5cGVvZiBpdGVtLnJvbGUgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgIHRocm93IG5ldyBPcGVuQUlQcm90b2NvbEVycm9yKFxuICAgICAgICBcIlVuc3VwcG9ydGVkIGNvbnZlcnNhdGlvbiBpdGVtIGZvciB0cmFuc3BhcmVudCBpbWFnZSBnZW5lcmF0aW9uXCIsXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGl0ZW0uY29udGVudCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdGV4dC5wdXNoKGAke2l0ZW0ucm9sZSA/PyBcInVzZXJcIn06XFxuJHtpdGVtLmNvbnRlbnR9YCk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGl0ZW0uY29udGVudCkpIHtcbiAgICAgIHRocm93IG5ldyBPcGVuQUlQcm90b2NvbEVycm9yKFwiVW5zdXBwb3J0ZWQgbWVzc2FnZSBjb250ZW50IGZvciB0cmFuc3BhcmVudCBpbWFnZSBnZW5lcmF0aW9uXCIpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHBhcnQgb2YgaXRlbS5jb250ZW50KSB7XG4gICAgICBpZiAoIXBhcnQgfHwgdHlwZW9mIHBhcnQgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IE9wZW5BSVByb3RvY29sRXJyb3IoXCJVbnN1cHBvcnRlZCBtZXNzYWdlIHBhcnQgZm9yIHRyYW5zcGFyZW50IGltYWdlIGdlbmVyYXRpb25cIik7XG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgIFtcImlucHV0X3RleHRcIiwgXCJvdXRwdXRfdGV4dFwiLCBcInRleHRcIl0uaW5jbHVkZXMocGFydC50eXBlKSAmJlxuICAgICAgICB0eXBlb2YgcGFydC50ZXh0ID09PSBcInN0cmluZ1wiXG4gICAgICApIHtcbiAgICAgICAgdGV4dC5wdXNoKGAke2l0ZW0ucm9sZSA/PyBcInVzZXJcIn06XFxuJHtwYXJ0LnRleHR9YCk7XG4gICAgICB9IGVsc2UgaWYgKHBhcnQudHlwZSA9PT0gXCJpbnB1dF9pbWFnZVwiIHx8IHBhcnQudHlwZSA9PT0gXCJpbWFnZV91cmxcIikge1xuICAgICAgICBjb25zdCB1cmwgPSB0eXBlb2YgcGFydC5pbWFnZV91cmwgPT09IFwic3RyaW5nXCIgPyBwYXJ0LmltYWdlX3VybCA6IHBhcnQuaW1hZ2VfdXJsPy51cmw7XG4gICAgICAgIGlmICh0eXBlb2YgdXJsICE9PSBcInN0cmluZ1wiIHx8ICEvXihodHRwczpcXC9cXC98ZGF0YTppbWFnZVxcLykvaS50ZXN0KHVybCkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgT3BlbkFJUHJvdG9jb2xFcnJvcihcIkltYWdlIHJlZmVyZW5jZXMgbXVzdCBiZSBIVFRQUyBVUkxzIG9yIGltYWdlIGRhdGEgVVJMc1wiKTtcbiAgICAgICAgfVxuICAgICAgICBpbWFnZXMucHVzaCh7IGltYWdlX3VybDogdXJsIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IE9wZW5BSVByb3RvY29sRXJyb3IoXCJVbnN1cHBvcnRlZCBtZXNzYWdlIHBhcnQgZm9yIHRyYW5zcGFyZW50IGltYWdlIGdlbmVyYXRpb25cIik7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmIChpbWFnZXMubGVuZ3RoID4gNSlcbiAgICB0aHJvdyBuZXcgT3BlbkFJUHJvdG9jb2xFcnJvcihcIlRyYW5zcGFyZW50IGltYWdlIGVkaXRpbmcgc3VwcG9ydHMgYXQgbW9zdCA1IHJlZmVyZW5jZSBpbWFnZXNcIik7XG4gIGlmICghdGV4dC5zb21lKChwYXJ0KSA9PiBwYXJ0LnRyaW0oKSkpIHRocm93IG5ldyBPcGVuQUlQcm90b2NvbEVycm9yKFwiSW1hZ2UgcHJvbXB0IGlzIGVtcHR5XCIpO1xuICByZXR1cm4ge1xuICAgIHVybDogQ0hBVEdQVF9DT0RFWF9SRVNQT05TRVNfVVJMLnJlcGxhY2UoXG4gICAgICAvXFwvcmVzcG9uc2VzJC8sXG4gICAgICBgL2ltYWdlcy8ke2ltYWdlcy5sZW5ndGggPyBcImVkaXRzXCIgOiBcImdlbmVyYXRpb25zXCJ9YCxcbiAgICApLFxuICAgIGJvZHk6IHtcbiAgICAgIG1vZGVsOiBcImdwdC1pbWFnZS0yXCIsXG4gICAgICBwcm9tcHQ6IHRleHQuam9pbihcIlxcblxcblwiKSxcbiAgICAgIGJhY2tncm91bmQ6IFwidHJhbnNwYXJlbnRcIixcbiAgICAgIC4uLihjb250cm9scy5xdWFsaXR5ID8geyBxdWFsaXR5OiBjb250cm9scy5xdWFsaXR5IH0gOiB7fSksXG4gICAgICAuLi4oY29udHJvbHMuc2l6ZSA/IHsgc2l6ZTogY29udHJvbHMuc2l6ZSB9IDoge30pLFxuICAgICAgLi4uKGltYWdlcy5sZW5ndGggPyB7IGltYWdlcyB9IDoge30pLFxuICAgIH0sXG4gIH07XG59XG5cbi8vIERlY29kZSBiZWZvcmUgYWNjZXB0aW5nIHRoZSByZXN1bHQ6IGFuIGFscGhhIGNoYW5uZWwgYWxvbmUgY2FuIHN0aWxsIGJlIGZ1bGx5IG9wYXF1ZS5cbmV4cG9ydCBmdW5jdGlvbiBpbnNwZWN0VHJhbnNwYXJlbnRQbmcoYmFzZTY0OiBzdHJpbmcpOiB7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0ge1xuICBpZiAoYmFzZTY0Lmxlbmd0aCA+IE1hdGguY2VpbChNQVhfUE5HX0JZVEVTIC8gMykgKiA0IHx8ICEvXltBLVphLXowLTkrL10rPXswLDJ9JC8udGVzdChiYXNlNjQpKSB7XG4gICAgdGhyb3cgbmV3IE9wZW5BSVByb3RvY29sRXJyb3IoXCJJbnZhbGlkIG9yIG92ZXJzaXplZCBnZW5lcmF0ZWQgUE5HXCIpO1xuICB9XG4gIGNvbnN0IGJ5dGVzID0gQnVmZmVyLmZyb20oYmFzZTY0LCBcImJhc2U2NFwiKTtcbiAgaWYgKFxuICAgIGJ5dGVzLmxlbmd0aCA8IDMzIHx8XG4gICAgIWJ5dGVzLnN1YmFycmF5KDAsIDgpLmVxdWFscyhQTkdfU0lHTkFUVVJFKSB8fFxuICAgIGJ5dGVzLnRvU3RyaW5nKFwiYXNjaWlcIiwgMTIsIDE2KSAhPT0gXCJJSERSXCJcbiAgKSB7XG4gICAgdGhyb3cgbmV3IE9wZW5BSVByb3RvY29sRXJyb3IoXCJJbWFnZSBnZW5lcmF0aW9uIGRpZCBub3QgcmV0dXJuIGEgUE5HXCIpO1xuICB9XG4gIGNvbnN0IHdpZHRoID0gYnl0ZXMucmVhZFVJbnQzMkJFKDE2KTtcbiAgY29uc3QgaGVpZ2h0ID0gYnl0ZXMucmVhZFVJbnQzMkJFKDIwKTtcbiAgaWYgKCF3aWR0aCB8fCAhaGVpZ2h0IHx8IHdpZHRoICogaGVpZ2h0ID4gTUFYX0lNQUdFX1BJWEVMUykge1xuICAgIHRocm93IG5ldyBPcGVuQUlQcm90b2NvbEVycm9yKFwiR2VuZXJhdGVkIFBORyBkaW1lbnNpb25zIGV4Y2VlZCB0aGUgZGVjb2RpbmcgbGltaXRcIik7XG4gIH1cbiAgbGV0IGltYWdlOiBQTkc7XG4gIHRyeSB7XG4gICAgaW1hZ2UgPSBQTkcuc3luYy5yZWFkKGJ5dGVzKTtcbiAgfSBjYXRjaCB7XG4gICAgdGhyb3cgbmV3IE9wZW5BSVByb3RvY29sRXJyb3IoXCJJbWFnZSBnZW5lcmF0aW9uIHJldHVybmVkIGFuIGludmFsaWQgUE5HXCIpO1xuICB9XG4gIGxldCB0cmFuc3BhcmVudCA9IGZhbHNlO1xuICBsZXQgdmlzaWJsZSA9IGZhbHNlO1xuICBmb3IgKGxldCBpID0gMzsgaSA8IGltYWdlLmRhdGEubGVuZ3RoOyBpICs9IDQpIHtcbiAgICB0cmFuc3BhcmVudCB8fD0gaW1hZ2UuZGF0YVtpXSA9PT0gMDtcbiAgICB2aXNpYmxlIHx8PSBpbWFnZS5kYXRhW2ldISA+IDA7XG4gICAgaWYgKHRyYW5zcGFyZW50ICYmIHZpc2libGUpIHJldHVybiB7IHdpZHRoOiBpbWFnZS53aWR0aCwgaGVpZ2h0OiBpbWFnZS5oZWlnaHQgfTtcbiAgfVxuICB0aHJvdyBuZXcgT3BlbkFJUHJvdG9jb2xFcnJvcihcbiAgICBcIkltYWdlIGdlbmVyYXRpb24gZGlkIG5vdCByZXR1cm4gdmlzaWJsZSBjb250ZW50IG9uIGEgdHJhbnNwYXJlbnQgYmFja2dyb3VuZFwiLFxuICApO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVhZFN0YW5kYWxvbmVJbWFnZVJlc3BvbnNlKFxuICByZXNwb25zZTogUmVzcG9uc2UsXG4pOiBQcm9taXNlPE9wZW5BSU5vcm1hbGl6ZWRFdmVudFtdPiB7XG4gIGlmICghcmVzcG9uc2UuYm9keSkgdGhyb3cgbmV3IE9wZW5BSVByb3RvY29sRXJyb3IoXCJJbWFnZSByZXNwb25zZSBoYWQgbm8gYm9keVwiKTtcbiAgY29uc3QgcmVhZGVyID0gcmVzcG9uc2UuYm9keS5nZXRSZWFkZXIoKTtcbiAgY29uc3QgY2h1bmtzOiBVaW50OEFycmF5W10gPSBbXTtcbiAgbGV0IHNpemUgPSAwO1xuICB0cnkge1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBjb25zdCB7IGRvbmUsIHZhbHVlIH0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuICAgICAgaWYgKGRvbmUpIGJyZWFrO1xuICAgICAgc2l6ZSArPSB2YWx1ZS5ieXRlTGVuZ3RoO1xuICAgICAgaWYgKHNpemUgPiBNQVhfUkVTUE9OU0VfQllURVMpIHtcbiAgICAgICAgYXdhaXQgcmVhZGVyLmNhbmNlbCgpO1xuICAgICAgICB0aHJvdyBuZXcgT3BlbkFJUHJvdG9jb2xFcnJvcihcIkltYWdlIHJlc3BvbnNlIGV4Y2VlZGVkIHRoZSBzaXplIGxpbWl0XCIpO1xuICAgICAgfVxuICAgICAgY2h1bmtzLnB1c2godmFsdWUpO1xuICAgIH1cbiAgfSBmaW5hbGx5IHtcbiAgICByZWFkZXIucmVsZWFzZUxvY2soKTtcbiAgfVxuICBjb25zdCBzY2hlbWEgPSB6Lm9iamVjdCh7XG4gICAgZGF0YTogelxuICAgICAgLmFycmF5KHoub2JqZWN0KHsgYjY0X2pzb246IHouc3RyaW5nKCkubWluKDEpLCByZXZpc2VkX3Byb21wdDogei5zdHJpbmcoKS5udWxsaXNoKCkgfSkpXG4gICAgICAubWluKDEpXG4gICAgICAubWF4KDE2KSxcbiAgICBxdWFsaXR5OiB6LnN0cmluZygpLm9wdGlvbmFsKCksXG4gICAgdXNhZ2U6IEltYWdlR2VuZXJhdGlvbk1ldGFkYXRhLnNoYXBlLnVzYWdlLFxuICB9KTtcbiAgbGV0IHBhcnNlZDogei5pbmZlcjx0eXBlb2Ygc2NoZW1hPjtcbiAgdHJ5IHtcbiAgICBwYXJzZWQgPSBzY2hlbWEucGFyc2UoSlNPTi5wYXJzZShCdWZmZXIuY29uY2F0KGNodW5rcykudG9TdHJpbmcoXCJ1dGY4XCIpKSk7XG4gIH0gY2F0Y2gge1xuICAgIHRocm93IG5ldyBPcGVuQUlQcm90b2NvbEVycm9yKFwiSW52YWxpZCBzdGFuZGFsb25lIGltYWdlIHJlc3BvbnNlXCIpO1xuICB9XG4gIHJldHVybiBwYXJzZWQuZGF0YS5tYXAoKGl0ZW0sIGluZGV4KSA9PiB7XG4gICAgY29uc3QgZGltZW5zaW9ucyA9IGluc3BlY3RUcmFuc3BhcmVudFBuZyhpdGVtLmI2NF9qc29uKTtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogXCJpbWFnZVwiLFxuICAgICAgYmFzZTY0OiBpdGVtLmI2NF9qc29uLFxuICAgICAgbWltZVR5cGU6IFwiaW1hZ2UvcG5nXCIsXG4gICAgICAuLi4oaXRlbS5yZXZpc2VkX3Byb21wdCA/IHsgcmV2aXNlZFByb21wdDogaXRlbS5yZXZpc2VkX3Byb21wdCB9IDoge30pLFxuICAgICAgZ2VuZXJhdGlvbjoge1xuICAgICAgICByb3V0ZTogXCJjb2RleC1pbWFnZXNcIixcbiAgICAgICAgbW9kZWw6IFwiZ3B0LWltYWdlLTJcIixcbiAgICAgICAgYmFja2dyb3VuZDogXCJ0cmFuc3BhcmVudFwiLFxuICAgICAgICBzaXplOiBgJHtkaW1lbnNpb25zLndpZHRofXgke2RpbWVuc2lvbnMuaGVpZ2h0fWAsXG4gICAgICAgIC4uLihwYXJzZWQucXVhbGl0eSA/IHsgcXVhbGl0eTogcGFyc2VkLnF1YWxpdHkgfSA6IHt9KSxcbiAgICAgICAgLi4uKGluZGV4ID09PSAwICYmIHBhcnNlZC51c2FnZSA/IHsgdXNhZ2U6IHBhcnNlZC51c2FnZSB9IDoge30pLFxuICAgICAgfSxcbiAgICB9O1xuICB9KTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFXQSxNQUFNLGdCQUFnQixLQUFLLE9BQU87QUFDbEMsTUFBTSxtQkFBbUIsT0FBTztBQUNoQyxNQUFNLHFCQUFxQixLQUFLLE9BQU87QUFDdkMsTUFBTSxnQkFBZ0IsT0FBTyxLQUFLO0NBQUM7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
@@ -2,11 +2,19 @@ import { buildCodexIdentityHeaders } from "./openai-backend-protocol.js";
2
2
  //#region src/utils/providers/openai/openai-quota.ts
3
3
  const CHATGPT_WHAM_USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
4
4
  async function readDirect(options) {
5
- const response = await (options.fetch ?? fetch)(CHATGPT_WHAM_USAGE_URL, {
5
+ const read = (credentials) => (options.fetch ?? fetch)(CHATGPT_WHAM_USAGE_URL, {
6
6
  method: "GET",
7
- headers: buildCodexIdentityHeaders(options.credentials.accessToken, options.credentials.accountId),
7
+ headers: buildCodexIdentityHeaders(credentials.accessToken, credentials.accountId),
8
8
  ...options.signal ? { signal: options.signal } : {}
9
9
  });
10
+ let response = await read(options.credentials);
11
+ if (response.status === 401 && options.refreshCredentials) {
12
+ await response.body?.cancel();
13
+ options.signal?.throwIfAborted();
14
+ const credentials = await options.refreshCredentials();
15
+ options.signal?.throwIfAborted();
16
+ response = await read(credentials);
17
+ }
10
18
  if (!response.ok) throw new Error(`OpenAI quota lookup failed: HTTP ${response.status}`);
11
19
  return {
12
20
  data: normalizeWhamUsage(await response.json()),
@@ -98,4 +106,4 @@ async function readOpenAIQuotaUsage(source) {
98
106
  //#endregion
99
107
  export { CHATGPT_WHAM_USAGE_URL, readOpenAIQuotaUsage };
100
108
 
101
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLXF1b3RhLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy91dGlscy9wcm92aWRlcnMvb3BlbmFpL29wZW5haS1xdW90YS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB0eXBlIE9wZW5BSUNyZWRlbnRpYWxzIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLnR5cGVzXCI7XG5pbXBvcnQgeyB0eXBlIFF1b3RhUmF0ZUxpbWl0cywgdHlwZSBRdW90YVJhdGVMaW1pdFNuYXBzaG90IH0gZnJvbSBcIi4uL2NvbW1vbi9wcm92aWRlci10eXBlc1wiO1xuaW1wb3J0IHsgYnVpbGRDb2RleElkZW50aXR5SGVhZGVycyB9IGZyb20gXCIuL29wZW5haS1iYWNrZW5kLXByb3RvY29sXCI7XG5cbmV4cG9ydCBjb25zdCBDSEFUR1BUX1dIQU1fVVNBR0VfVVJMID0gXCJodHRwczovL2NoYXRncHQuY29tL2JhY2tlbmQtYXBpL3doYW0vdXNhZ2VcIiBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgT3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhID0ge1xuICBkYXRhOiBRdW90YVJhdGVMaW1pdHM7XG4gIGNhY2hlZEF0OiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBPcGVuQUlRdW90YVVzYWdlUmVzdWx0ID1cbiAgfCB7XG4gICAgICBraW5kOiBcIm9rXCI7XG4gICAgICB1dGlsaXphdGlvblBjdDogbnVtYmVyO1xuICAgICAgY2FjaGVBZ2VNczogbnVtYmVyO1xuICAgICAgd2luZG93RHVyYXRpb25NaW5zOiBudW1iZXIgfCBudWxsO1xuICAgICAgcmVzZXRzQXQ6IG51bWJlciB8IG51bGw7XG4gICAgICBsaW1pdElkOiBzdHJpbmcgfCBudWxsO1xuICAgICAgcmF3PzogUXVvdGFSYXRlTGltaXRzO1xuICAgIH1cbiAgfCB7IGtpbmQ6IFwibG9va3VwX2ZhaWxlZFwiOyByZWFzb246IHN0cmluZyB9O1xuXG5leHBvcnQgaW50ZXJmYWNlIE9wZW5BSVF1b3RhSHR0cE9wdGlvbnMge1xuICBjcmVkZW50aWFsczogUGljazxPcGVuQUlDcmVkZW50aWFscywgXCJhY2Nlc3NUb2tlblwiIHwgXCJhY2NvdW50SWRcIj47XG4gIGZldGNoPzogdHlwZW9mIGZldGNoO1xuICBzaWduYWw/OiBBYm9ydFNpZ25hbDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVhZERpcmVjdChvcHRpb25zOiBPcGVuQUlRdW90YUh0dHBPcHRpb25zKTogUHJvbWlzZTxPcGVuQUlSYXRlTGltaXRzV2l0aE1ldGE+IHtcbiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCAob3B0aW9ucy5mZXRjaCA/PyBmZXRjaCkoQ0hBVEdQVF9XSEFNX1VTQUdFX1VSTCwge1xuICAgIG1ldGhvZDogXCJHRVRcIixcbiAgICBoZWFkZXJzOiBidWlsZENvZGV4SWRlbnRpdHlIZWFkZXJzKFxuICAgICAgb3B0aW9ucy5jcmVkZW50aWFscy5hY2Nlc3NUb2tlbixcbiAgICAgIG9wdGlvbnMuY3JlZGVudGlhbHMuYWNjb3VudElkLFxuICAgICksXG4gICAgLi4uKG9wdGlvbnMuc2lnbmFsID8geyBzaWduYWw6IG9wdGlvbnMuc2lnbmFsIH0gOiB7fSksXG4gIH0pO1xuICBpZiAoIXJlc3BvbnNlLm9rKSB0aHJvdyBuZXcgRXJyb3IoYE9wZW5BSSBxdW90YSBsb29rdXAgZmFpbGVkOiBIVFRQICR7cmVzcG9uc2Uuc3RhdHVzfWApO1xuICBjb25zdCBib2R5ID0gKGF3YWl0IHJlc3BvbnNlLmpzb24oKSkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGNvbnN0IGRhdGEgPSBub3JtYWxpemVXaGFtVXNhZ2UoYm9keSk7XG4gIHJldHVybiB7IGRhdGEsIGNhY2hlZEF0OiBEYXRlLm5vdygpIH07XG59XG5cbmZ1bmN0aW9uIHdpbmRvd0Zyb20odmFsdWU6IHVua25vd24pIHtcbiAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIpIHJldHVybiBudWxsO1xuICBjb25zdCBzb3VyY2UgPSB2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgY29uc3QgdXNlZFBlcmNlbnQgPSBOdW1iZXIoc291cmNlLnVzZWRQZXJjZW50ID8/IHNvdXJjZS51c2VkX3BlcmNlbnQpO1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZSh1c2VkUGVyY2VudCkpIHJldHVybiBudWxsO1xuICBjb25zdCBkdXJhdGlvbk1pbnMgPSBzb3VyY2Uud2luZG93RHVyYXRpb25NaW5zID8/IHNvdXJjZS53aW5kb3dfbWludXRlcztcbiAgY29uc3QgZHVyYXRpb25TZWNvbmRzID0gc291cmNlLmxpbWl0V2luZG93U2Vjb25kcyA/PyBzb3VyY2UubGltaXRfd2luZG93X3NlY29uZHM7XG4gIGNvbnN0IHJlc2V0cyA9IHNvdXJjZS5yZXNldHNBdCA/PyBzb3VyY2UucmVzZXRfYXQ7XG4gIHJldHVybiB7XG4gICAgdXNlZFBlcmNlbnQsXG4gICAgd2luZG93RHVyYXRpb25NaW5zOlxuICAgICAgZHVyYXRpb25NaW5zICE9PSBudWxsICYmIGR1cmF0aW9uTWlucyAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gTnVtYmVyKGR1cmF0aW9uTWlucylcbiAgICAgICAgOiBkdXJhdGlvblNlY29uZHMgIT09IG51bGwgJiYgZHVyYXRpb25TZWNvbmRzICE9PSB1bmRlZmluZWRcbiAgICAgICAgICA/IE51bWJlcihkdXJhdGlvblNlY29uZHMpIC8gNjBcbiAgICAgICAgICA6IG51bGwsXG4gICAgcmVzZXRzQXQ6IHJlc2V0cyA9PT0gbnVsbCB8fCByZXNldHMgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBOdW1iZXIocmVzZXRzKSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gc25hcHNob3RGcm9tKHZhbHVlOiB1bmtub3duKTogUXVvdGFSYXRlTGltaXRTbmFwc2hvdCB7XG4gIGNvbnN0IHNvdXJjZSA9ICh2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgPyB2YWx1ZSA6IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgY29uc3QgbGltaXRJZCA9IHNvdXJjZS5saW1pdElkID8/IHNvdXJjZS5saW1pdF9pZDtcbiAgY29uc3QgbGltaXROYW1lID0gc291cmNlLmxpbWl0TmFtZSA/PyBzb3VyY2UubGltaXRfbmFtZTtcbiAgcmV0dXJuIHtcbiAgICBsaW1pdElkOiB0eXBlb2YgbGltaXRJZCA9PT0gXCJzdHJpbmdcIiA/IGxpbWl0SWQgOiBudWxsLFxuICAgIGxpbWl0TmFtZTogdHlwZW9mIGxpbWl0TmFtZSA9PT0gXCJzdHJpbmdcIiA/IGxpbWl0TmFtZSA6IG51bGwsXG4gICAgcHJpbWFyeTogd2luZG93RnJvbShzb3VyY2UucHJpbWFyeSA/PyBzb3VyY2UucHJpbWFyeV93aW5kb3cpLFxuICAgIHNlY29uZGFyeTogd2luZG93RnJvbShzb3VyY2Uuc2Vjb25kYXJ5ID8/IHNvdXJjZS5zZWNvbmRhcnlfd2luZG93KSxcbiAgICBjcmVkaXRzOiAoc291cmNlLmNyZWRpdHMgPz8gbnVsbCkgYXMgUXVvdGFSYXRlTGltaXRTbmFwc2hvdFtcImNyZWRpdHNcIl0sXG4gICAgcGxhblR5cGU6XG4gICAgICB0eXBlb2YgKHNvdXJjZS5wbGFuVHlwZSA/PyBzb3VyY2UucGxhbl90eXBlKSA9PT0gXCJzdHJpbmdcIlxuICAgICAgICA/IFN0cmluZyhzb3VyY2UucGxhblR5cGUgPz8gc291cmNlLnBsYW5fdHlwZSlcbiAgICAgICAgOiBudWxsLFxuICAgIHJhdGVMaW1pdFJlYWNoZWRUeXBlOlxuICAgICAgdHlwZW9mIChzb3VyY2UucmF0ZUxpbWl0UmVhY2hlZFR5cGUgPz8gc291cmNlLnJhdGVfbGltaXRfcmVhY2hlZCkgPT09IFwic3RyaW5nXCJcbiAgICAgICAgPyBTdHJpbmcoc291cmNlLnJhdGVMaW1pdFJlYWNoZWRUeXBlID8/IHNvdXJjZS5yYXRlX2xpbWl0X3JlYWNoZWQpXG4gICAgICAgIDogbnVsbCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplV2hhbVVzYWdlKGJvZHk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogUXVvdGFSYXRlTGltaXRzIHtcbiAgaWYgKGJvZHkucmF0ZUxpbWl0cyAmJiB0eXBlb2YgYm9keS5yYXRlTGltaXRzID09PSBcIm9iamVjdFwiKSB7XG4gICAgcmV0dXJuIGJvZHkgYXMgUXVvdGFSYXRlTGltaXRzO1xuICB9XG4gIGNvbnN0IGNvbnRhaW5lciA9XG4gICAgYm9keS5yYXRlX2xpbWl0cyAmJiB0eXBlb2YgYm9keS5yYXRlX2xpbWl0cyA9PT0gXCJvYmplY3RcIlxuICAgICAgPyAoYm9keS5yYXRlX2xpbWl0cyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilcbiAgICAgIDogYm9keTtcbiAgY29uc3Qgc2hhcmVkID0ge1xuICAgIHBsYW5fdHlwZTogYm9keS5wbGFuX3R5cGUgPz8gY29udGFpbmVyLnBsYW5fdHlwZSxcbiAgICBjcmVkaXRzOiBib2R5LmNyZWRpdHMgPz8gY29udGFpbmVyLmNyZWRpdHMsXG4gICAgcmF0ZV9saW1pdF9yZWFjaGVkOiBib2R5LnJhdGVfbGltaXRfcmVhY2hlZCA/PyBjb250YWluZXIucmF0ZV9saW1pdF9yZWFjaGVkLFxuICB9O1xuICBjb25zdCBwcmltYXJ5ID0gc25hcHNob3RGcm9tKHtcbiAgICAuLi5zaGFyZWQsXG4gICAgLi4uKChjb250YWluZXIucmF0ZV9saW1pdCA/PyBjb250YWluZXIpIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSxcbiAgfSk7XG4gIGNvbnN0IGFkZGl0aW9uYWwgPSBBcnJheS5pc0FycmF5KGNvbnRhaW5lci5hZGRpdGlvbmFsX3JhdGVfbGltaXRzKVxuICAgID8gY29udGFpbmVyLmFkZGl0aW9uYWxfcmF0ZV9saW1pdHNcbiAgICA6IEFycmF5LmlzQXJyYXkoYm9keS5hZGRpdGlvbmFsX3JhdGVfbGltaXRzKVxuICAgICAgPyBib2R5LmFkZGl0aW9uYWxfcmF0ZV9saW1pdHNcbiAgICAgIDogW107XG4gIGNvbnN0IGJ5SWQ6IFJlY29yZDxzdHJpbmcsIFF1b3RhUmF0ZUxpbWl0U25hcHNob3Q+ID0ge307XG4gIGZvciAoY29uc3QgZW50cnkgb2YgYWRkaXRpb25hbCkge1xuICAgIGlmICghZW50cnkgfHwgdHlwZW9mIGVudHJ5ICE9PSBcIm9iamVjdFwiKSBjb250aW51ZTtcbiAgICBjb25zdCB3cmFwcGVyID0gZW50cnkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgY29uc3Qgc25hcHNob3QgPSBzbmFwc2hvdEZyb20oe1xuICAgICAgLi4uc2hhcmVkLFxuICAgICAgLi4uKCh3cmFwcGVyLnJhdGVfbGltaXQgPz8gd3JhcHBlcikgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLFxuICAgIH0pO1xuICAgIGlmIChzbmFwc2hvdC5saW1pdElkKSBieUlkW3NuYXBzaG90LmxpbWl0SWRdID0gc25hcHNob3Q7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICByYXRlTGltaXRzOiBwcmltYXJ5LFxuICAgIHJhdGVMaW1pdHNCeUxpbWl0SWQ6IE9iamVjdC5rZXlzKGJ5SWQpLmxlbmd0aCA/IGJ5SWQgOiBudWxsLFxuICB9O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVhZE9wZW5BSVF1b3RhVXNhZ2UoXG4gIHNvdXJjZTogKCgpID0+IFByb21pc2U8T3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhPikgfCBPcGVuQUlRdW90YUh0dHBPcHRpb25zLFxuKTogUHJvbWlzZTxPcGVuQUlRdW90YVVzYWdlUmVzdWx0PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgZGlyZWN0ID0gdHlwZW9mIHNvdXJjZSAhPT0gXCJmdW5jdGlvblwiO1xuICAgIGNvbnN0IHsgZGF0YSwgY2FjaGVkQXQgfSA9IGF3YWl0ICh0eXBlb2Ygc291cmNlID09PSBcImZ1bmN0aW9uXCIgPyBzb3VyY2UoKSA6IHJlYWREaXJlY3Qoc291cmNlKSk7XG4gICAgY29uc3QgcmF0ZUxpbWl0cyA9IGRhdGEucmF0ZUxpbWl0cztcbiAgICBjb25zdCBwcmltYXJ5ID0gcmF0ZUxpbWl0cz8ucHJpbWFyeTtcblxuICAgIGlmIChcbiAgICAgICFwcmltYXJ5IHx8XG4gICAgICB0eXBlb2YgcHJpbWFyeS51c2VkUGVyY2VudCAhPT0gXCJudW1iZXJcIiB8fFxuICAgICAgIU51bWJlci5pc0Zpbml0ZShwcmltYXJ5LnVzZWRQZXJjZW50KVxuICAgICkge1xuICAgICAgcmV0dXJuIHsga2luZDogXCJsb29rdXBfZmFpbGVkXCIsIHJlYXNvbjogXCJwcmltYXJ5IHVzZWRQZXJjZW50IHVuYXZhaWxhYmxlXCIgfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAga2luZDogXCJva1wiLFxuICAgICAgdXRpbGl6YXRpb25QY3Q6IHByaW1hcnkudXNlZFBlcmNlbnQsXG4gICAgICBjYWNoZUFnZU1zOiBNYXRoLm1heChEYXRlLm5vdygpIC0gY2FjaGVkQXQsIDApLFxuICAgICAgd2luZG93RHVyYXRpb25NaW5zOiBwcmltYXJ5LndpbmRvd0R1cmF0aW9uTWlucyxcbiAgICAgIHJlc2V0c0F0OiBwcmltYXJ5LnJlc2V0c0F0LFxuICAgICAgbGltaXRJZDogcmF0ZUxpbWl0cy5saW1pdElkLFxuICAgICAgLi4uKGRpcmVjdCA/IHsgcmF3OiBkYXRhIH0gOiB7fSksXG4gICAgfTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiB7IGtpbmQ6IFwibG9va3VwX2ZhaWxlZFwiLCByZWFzb246IChlIGFzIEVycm9yKS5tZXNzYWdlIH07XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7QUFJQSxNQUFhLHlCQUF5QjtBQXlCdEMsZUFBZSxXQUFXLFNBQW9FO0NBQzVGLE1BQU0sV0FBVyxPQUFPLFFBQVEsU0FBUyxNQUFBLENBQU8sd0JBQXdCO0VBQ3RFLFFBQVE7RUFDUixTQUFTLDBCQUNQLFFBQVEsWUFBWSxhQUNwQixRQUFRLFlBQVksU0FDdEI7RUFDQSxHQUFJLFFBQVEsU0FBUyxFQUFFLFFBQVEsUUFBUSxPQUFPLElBQUksQ0FBQztDQUNyRCxDQUFDO0NBQ0QsSUFBSSxDQUFDLFNB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
109
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLXF1b3RhLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy91dGlscy9wcm92aWRlcnMvb3BlbmFpL29wZW5haS1xdW90YS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB0eXBlIE9wZW5BSUNyZWRlbnRpYWxzIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLnR5cGVzXCI7XG5pbXBvcnQgeyB0eXBlIFF1b3RhUmF0ZUxpbWl0cywgdHlwZSBRdW90YVJhdGVMaW1pdFNuYXBzaG90IH0gZnJvbSBcIi4uL2NvbW1vbi9wcm92aWRlci10eXBlc1wiO1xuaW1wb3J0IHsgYnVpbGRDb2RleElkZW50aXR5SGVhZGVycyB9IGZyb20gXCIuL29wZW5haS1iYWNrZW5kLXByb3RvY29sXCI7XG5cbmV4cG9ydCBjb25zdCBDSEFUR1BUX1dIQU1fVVNBR0VfVVJMID0gXCJodHRwczovL2NoYXRncHQuY29tL2JhY2tlbmQtYXBpL3doYW0vdXNhZ2VcIiBhcyBjb25zdDtcblxuZXhwb3J0IHR5cGUgT3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhID0ge1xuICBkYXRhOiBRdW90YVJhdGVMaW1pdHM7XG4gIGNhY2hlZEF0OiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBPcGVuQUlRdW90YVVzYWdlUmVzdWx0ID1cbiAgfCB7XG4gICAgICBraW5kOiBcIm9rXCI7XG4gICAgICB1dGlsaXphdGlvblBjdDogbnVtYmVyO1xuICAgICAgY2FjaGVBZ2VNczogbnVtYmVyO1xuICAgICAgd2luZG93RHVyYXRpb25NaW5zOiBudW1iZXIgfCBudWxsO1xuICAgICAgcmVzZXRzQXQ6IG51bWJlciB8IG51bGw7XG4gICAgICBsaW1pdElkOiBzdHJpbmcgfCBudWxsO1xuICAgICAgcmF3PzogUXVvdGFSYXRlTGltaXRzO1xuICAgIH1cbiAgfCB7IGtpbmQ6IFwibG9va3VwX2ZhaWxlZFwiOyByZWFzb246IHN0cmluZyB9O1xuXG5leHBvcnQgaW50ZXJmYWNlIE9wZW5BSVF1b3RhSHR0cE9wdGlvbnMge1xuICBjcmVkZW50aWFsczogUGljazxPcGVuQUlDcmVkZW50aWFscywgXCJhY2Nlc3NUb2tlblwiIHwgXCJhY2NvdW50SWRcIj47XG4gIHJlZnJlc2hDcmVkZW50aWFscz86ICgpID0+IFByb21pc2U8UGljazxPcGVuQUlDcmVkZW50aWFscywgXCJhY2Nlc3NUb2tlblwiIHwgXCJhY2NvdW50SWRcIj4+O1xuICBmZXRjaD86IHR5cGVvZiBmZXRjaDtcbiAgc2lnbmFsPzogQWJvcnRTaWduYWw7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlYWREaXJlY3Qob3B0aW9uczogT3BlbkFJUXVvdGFIdHRwT3B0aW9ucyk6IFByb21pc2U8T3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhPiB7XG4gIGNvbnN0IHJlYWQgPSAoY3JlZGVudGlhbHM6IE9wZW5BSVF1b3RhSHR0cE9wdGlvbnNbXCJjcmVkZW50aWFsc1wiXSkgPT5cbiAgICAob3B0aW9ucy5mZXRjaCA/PyBmZXRjaCkoQ0hBVEdQVF9XSEFNX1VTQUdFX1VSTCwge1xuICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgaGVhZGVyczogYnVpbGRDb2RleElkZW50aXR5SGVhZGVycyhjcmVkZW50aWFscy5hY2Nlc3NUb2tlbiwgY3JlZGVudGlhbHMuYWNjb3VudElkKSxcbiAgICAgIC4uLihvcHRpb25zLnNpZ25hbCA/IHsgc2lnbmFsOiBvcHRpb25zLnNpZ25hbCB9IDoge30pLFxuICAgIH0pO1xuICBsZXQgcmVzcG9uc2UgPSBhd2FpdCByZWFkKG9wdGlvbnMuY3JlZGVudGlhbHMpO1xuICBpZiAocmVzcG9uc2Uuc3RhdHVzID09PSA0MDEgJiYgb3B0aW9ucy5yZWZyZXNoQ3JlZGVudGlhbHMpIHtcbiAgICBhd2FpdCByZXNwb25zZS5ib2R5Py5jYW5jZWwoKTtcbiAgICBvcHRpb25zLnNpZ25hbD8udGhyb3dJZkFib3J0ZWQoKTtcbiAgICBjb25zdCBjcmVkZW50aWFscyA9IGF3YWl0IG9wdGlvbnMucmVmcmVzaENyZWRlbnRpYWxzKCk7XG4gICAgb3B0aW9ucy5zaWduYWw/LnRocm93SWZBYm9ydGVkKCk7XG4gICAgcmVzcG9uc2UgPSBhd2FpdCByZWFkKGNyZWRlbnRpYWxzKTtcbiAgfVxuICBpZiAoIXJlc3BvbnNlLm9rKSB0aHJvdyBuZXcgRXJyb3IoYE9wZW5BSSBxdW90YSBsb29rdXAgZmFpbGVkOiBIVFRQICR7cmVzcG9uc2Uuc3RhdHVzfWApO1xuICBjb25zdCBib2R5ID0gKGF3YWl0IHJlc3BvbnNlLmpzb24oKSkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGNvbnN0IGRhdGEgPSBub3JtYWxpemVXaGFtVXNhZ2UoYm9keSk7XG4gIHJldHVybiB7IGRhdGEsIGNhY2hlZEF0OiBEYXRlLm5vdygpIH07XG59XG5cbmZ1bmN0aW9uIHdpbmRvd0Zyb20odmFsdWU6IHVua25vd24pIHtcbiAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIpIHJldHVybiBudWxsO1xuICBjb25zdCBzb3VyY2UgPSB2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgY29uc3QgdXNlZFBlcmNlbnQgPSBOdW1iZXIoc291cmNlLnVzZWRQZXJjZW50ID8/IHNvdXJjZS51c2VkX3BlcmNlbnQpO1xuICBpZiAoIU51bWJlci5pc0Zpbml0ZSh1c2VkUGVyY2VudCkpIHJldHVybiBudWxsO1xuICBjb25zdCBkdXJhdGlvbk1pbnMgPSBzb3VyY2Uud2luZG93RHVyYXRpb25NaW5zID8/IHNvdXJjZS53aW5kb3dfbWludXRlcztcbiAgY29uc3QgZHVyYXRpb25TZWNvbmRzID0gc291cmNlLmxpbWl0V2luZG93U2Vjb25kcyA/PyBzb3VyY2UubGltaXRfd2luZG93X3NlY29uZHM7XG4gIGNvbnN0IHJlc2V0cyA9IHNvdXJjZS5yZXNldHNBdCA/PyBzb3VyY2UucmVzZXRfYXQ7XG4gIHJldHVybiB7XG4gICAgdXNlZFBlcmNlbnQsXG4gICAgd2luZG93RHVyYXRpb25NaW5zOlxuICAgICAgZHVyYXRpb25NaW5zICE9PSBudWxsICYmIGR1cmF0aW9uTWlucyAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8gTnVtYmVyKGR1cmF0aW9uTWlucylcbiAgICAgICAgOiBkdXJhdGlvblNlY29uZHMgIT09IG51bGwgJiYgZHVyYXRpb25TZWNvbmRzICE9PSB1bmRlZmluZWRcbiAgICAgICAgICA/IE51bWJlcihkdXJhdGlvblNlY29uZHMpIC8gNjBcbiAgICAgICAgICA6IG51bGwsXG4gICAgcmVzZXRzQXQ6IHJlc2V0cyA9PT0gbnVsbCB8fCByZXNldHMgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBOdW1iZXIocmVzZXRzKSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gc25hcHNob3RGcm9tKHZhbHVlOiB1bmtub3duKTogUXVvdGFSYXRlTGltaXRTbmFwc2hvdCB7XG4gIGNvbnN0IHNvdXJjZSA9ICh2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgPyB2YWx1ZSA6IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgY29uc3QgbGltaXRJZCA9IHNvdXJjZS5saW1pdElkID8/IHNvdXJjZS5saW1pdF9pZDtcbiAgY29uc3QgbGltaXROYW1lID0gc291cmNlLmxpbWl0TmFtZSA/PyBzb3VyY2UubGltaXRfbmFtZTtcbiAgcmV0dXJuIHtcbiAgICBsaW1pdElkOiB0eXBlb2YgbGltaXRJZCA9PT0gXCJzdHJpbmdcIiA/IGxpbWl0SWQgOiBudWxsLFxuICAgIGxpbWl0TmFtZTogdHlwZW9mIGxpbWl0TmFtZSA9PT0gXCJzdHJpbmdcIiA/IGxpbWl0TmFtZSA6IG51bGwsXG4gICAgcHJpbWFyeTogd2luZG93RnJvbShzb3VyY2UucHJpbWFyeSA/PyBzb3VyY2UucHJpbWFyeV93aW5kb3cpLFxuICAgIHNlY29uZGFyeTogd2luZG93RnJvbShzb3VyY2Uuc2Vjb25kYXJ5ID8/IHNvdXJjZS5zZWNvbmRhcnlfd2luZG93KSxcbiAgICBjcmVkaXRzOiAoc291cmNlLmNyZWRpdHMgPz8gbnVsbCkgYXMgUXVvdGFSYXRlTGltaXRTbmFwc2hvdFtcImNyZWRpdHNcIl0sXG4gICAgcGxhblR5cGU6XG4gICAgICB0eXBlb2YgKHNvdXJjZS5wbGFuVHlwZSA/PyBzb3VyY2UucGxhbl90eXBlKSA9PT0gXCJzdHJpbmdcIlxuICAgICAgICA/IFN0cmluZyhzb3VyY2UucGxhblR5cGUgPz8gc291cmNlLnBsYW5fdHlwZSlcbiAgICAgICAgOiBudWxsLFxuICAgIHJhdGVMaW1pdFJlYWNoZWRUeXBlOlxuICAgICAgdHlwZW9mIChzb3VyY2UucmF0ZUxpbWl0UmVhY2hlZFR5cGUgPz8gc291cmNlLnJhdGVfbGltaXRfcmVhY2hlZCkgPT09IFwic3RyaW5nXCJcbiAgICAgICAgPyBTdHJpbmcoc291cmNlLnJhdGVMaW1pdFJlYWNoZWRUeXBlID8/IHNvdXJjZS5yYXRlX2xpbWl0X3JlYWNoZWQpXG4gICAgICAgIDogbnVsbCxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplV2hhbVVzYWdlKGJvZHk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+KTogUXVvdGFSYXRlTGltaXRzIHtcbiAgaWYgKGJvZHkucmF0ZUxpbWl0cyAmJiB0eXBlb2YgYm9keS5yYXRlTGltaXRzID09PSBcIm9iamVjdFwiKSB7XG4gICAgcmV0dXJuIGJvZHkgYXMgUXVvdGFSYXRlTGltaXRzO1xuICB9XG4gIGNvbnN0IGNvbnRhaW5lciA9XG4gICAgYm9keS5yYXRlX2xpbWl0cyAmJiB0eXBlb2YgYm9keS5yYXRlX2xpbWl0cyA9PT0gXCJvYmplY3RcIlxuICAgICAgPyAoYm9keS5yYXRlX2xpbWl0cyBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilcbiAgICAgIDogYm9keTtcbiAgY29uc3Qgc2hhcmVkID0ge1xuICAgIHBsYW5fdHlwZTogYm9keS5wbGFuX3R5cGUgPz8gY29udGFpbmVyLnBsYW5fdHlwZSxcbiAgICBjcmVkaXRzOiBib2R5LmNyZWRpdHMgPz8gY29udGFpbmVyLmNyZWRpdHMsXG4gICAgcmF0ZV9saW1pdF9yZWFjaGVkOiBib2R5LnJhdGVfbGltaXRfcmVhY2hlZCA/PyBjb250YWluZXIucmF0ZV9saW1pdF9yZWFjaGVkLFxuICB9O1xuICBjb25zdCBwcmltYXJ5ID0gc25hcHNob3RGcm9tKHtcbiAgICAuLi5zaGFyZWQsXG4gICAgLi4uKChjb250YWluZXIucmF0ZV9saW1pdCA/PyBjb250YWluZXIpIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KSxcbiAgfSk7XG4gIGNvbnN0IGFkZGl0aW9uYWwgPSBBcnJheS5pc0FycmF5KGNvbnRhaW5lci5hZGRpdGlvbmFsX3JhdGVfbGltaXRzKVxuICAgID8gY29udGFpbmVyLmFkZGl0aW9uYWxfcmF0ZV9saW1pdHNcbiAgICA6IEFycmF5LmlzQXJyYXkoYm9keS5hZGRpdGlvbmFsX3JhdGVfbGltaXRzKVxuICAgICAgPyBib2R5LmFkZGl0aW9uYWxfcmF0ZV9saW1pdHNcbiAgICAgIDogW107XG4gIGNvbnN0IGJ5SWQ6IFJlY29yZDxzdHJpbmcsIFF1b3RhUmF0ZUxpbWl0U25hcHNob3Q+ID0ge307XG4gIGZvciAoY29uc3QgZW50cnkgb2YgYWRkaXRpb25hbCkge1xuICAgIGlmICghZW50cnkgfHwgdHlwZW9mIGVudHJ5ICE9PSBcIm9iamVjdFwiKSBjb250aW51ZTtcbiAgICBjb25zdCB3cmFwcGVyID0gZW50cnkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgY29uc3Qgc25hcHNob3QgPSBzbmFwc2hvdEZyb20oe1xuICAgICAgLi4uc2hhcmVkLFxuICAgICAgLi4uKCh3cmFwcGVyLnJhdGVfbGltaXQgPz8gd3JhcHBlcikgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLFxuICAgIH0pO1xuICAgIGlmIChzbmFwc2hvdC5saW1pdElkKSBieUlkW3NuYXBzaG90LmxpbWl0SWRdID0gc25hcHNob3Q7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICByYXRlTGltaXRzOiBwcmltYXJ5LFxuICAgIHJhdGVMaW1pdHNCeUxpbWl0SWQ6IE9iamVjdC5rZXlzKGJ5SWQpLmxlbmd0aCA/IGJ5SWQgOiBudWxsLFxuICB9O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVhZE9wZW5BSVF1b3RhVXNhZ2UoXG4gIHNvdXJjZTogKCgpID0+IFByb21pc2U8T3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhPikgfCBPcGVuQUlRdW90YUh0dHBPcHRpb25zLFxuKTogUHJvbWlzZTxPcGVuQUlRdW90YVVzYWdlUmVzdWx0PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgZGlyZWN0ID0gdHlwZW9mIHNvdXJjZSAhPT0gXCJmdW5jdGlvblwiO1xuICAgIGNvbnN0IHsgZGF0YSwgY2FjaGVkQXQgfSA9IGF3YWl0ICh0eXBlb2Ygc291cmNlID09PSBcImZ1bmN0aW9uXCIgPyBzb3VyY2UoKSA6IHJlYWREaXJlY3Qoc291cmNlKSk7XG4gICAgY29uc3QgcmF0ZUxpbWl0cyA9IGRhdGEucmF0ZUxpbWl0cztcbiAgICBjb25zdCBwcmltYXJ5ID0gcmF0ZUxpbWl0cz8ucHJpbWFyeTtcblxuICAgIGlmIChcbiAgICAgICFwcmltYXJ5IHx8XG4gICAgICB0eXBlb2YgcHJpbWFyeS51c2VkUGVyY2VudCAhPT0gXCJudW1iZXJcIiB8fFxuICAgICAgIU51bWJlci5pc0Zpbml0ZShwcmltYXJ5LnVzZWRQZXJjZW50KVxuICAgICkge1xuICAgICAgcmV0dXJuIHsga2luZDogXCJsb29rdXBfZmFpbGVkXCIsIHJlYXNvbjogXCJwcmltYXJ5IHVzZWRQZXJjZW50IHVuYXZhaWxhYmxlXCIgfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAga2luZDogXCJva1wiLFxuICAgICAgdXRpbGl6YXRpb25QY3Q6IHByaW1hcnkudXNlZFBlcmNlbnQsXG4gICAgICBjYWNoZUFnZU1zOiBNYXRoLm1heChEYXRlLm5vdygpIC0gY2FjaGVkQXQsIDApLFxuICAgICAgd2luZG93RHVyYXRpb25NaW5zOiBwcmltYXJ5LndpbmRvd0R1cmF0aW9uTWlucyxcbiAgICAgIHJlc2V0c0F0OiBwcmltYXJ5LnJlc2V0c0F0LFxuICAgICAgbGltaXRJZDogcmF0ZUxpbWl0cy5saW1pdElkLFxuICAgICAgLi4uKGRpcmVjdCA/IHsgcmF3OiBkYXRhIH0gOiB7fSksXG4gICAgfTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiB7IGtpbmQ6IFwibG9va3VwX2ZhaWxlZFwiLCByZWFzb246IChlIGFzIEVycm9yKS5tZXNzYWdlIH07XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7QUFJQSxNQUFhLHlCQUF5QjtBQTBCdEMsZUFBZSxXQUFXLFNBQW9FO0NBQzVGLE1BQU0sUUFBUSxpQkFDWCxRQUFRLFNBQVMsTUFBQSxDQUFPLHdCQUF3QjtFQUMvQyxRQUFRO0VBQ1IsU0FBUywwQkFBMEIsWUFBWSxhQUFhLFlBQVksU0FBUztFQUNqRixHQUFJLFFBQVEsU0FBUyxFQUFFLFFBQVEsUUFBUSxPQUFPLElBQUksQ0FBQztDQUNyRCxDQUFDO0NBQ0gsSUFBSSxXQUFXLE1BQU0sS0FBSyxRQUFRLFdBQVc7Q0FDN0MsSUFBSSxTQUFTLFdBQVcsT0FBTyxRQUFRLG9CQUFvQjtFQUN6RCxNQUFNLFNBQVMsTUFBTSxPQUFPO0VBQzVCLFFBQVEsUUFBUSxlQUFlO0VBQy9CLE1BQU0sY0FBYyxNQUFNLFFBQVEsbUJBQW1CO0VBQ3JELFFBQVEsUUFBUSxlQUFlO0VBQy9CLFdBQVcsTUFBTSxLQUFLLFdBQVc7Q0FDbkM7Q0FDQSxJQUFJLENBQUMsU0FBUyxJQUFJLE1BQU0sSUFBSSxNQUFNLG9DQUFvQyxTQUFTLFFBQVE7Q0FHdkYsT0FBTztFQUFFLE1BREksbUJBQW1CLE1BRFosU0FBUyxLQUFLLENBRXpCO0VBQU0sVUFBVSxLQUFLLElBQUk7Q0FBRTtBQUN0QztBQUVBLFNBQVMsV0FBVyxPQUFnQjtDQUNsQyxJQUFJLENBQUMsU0FBUyxPQUFPLFVBQVUsVUFBVSxPQUFPO0NBQ2hELE1BQU0sU0FBUztDQUNmLE1BQU0sY0FBYyxPQUFPLE9BQU8sZUFBZSxPQUFPLFlBQVk7Q0FDcEUsSUFB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