@cartanova/qgrid-cli 2.6.0 → 2.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.ko.md +2 -0
  2. package/README.md +2 -0
  3. package/bundle/dist/application/qgrid/oauth.js +22 -3
  4. package/bundle/dist/application/qgrid/qgrid.frame.js +104 -34
  5. package/bundle/dist/application/qgrid/qgrid.types.js +5 -2
  6. package/bundle/dist/application/qgrid/token-death.js +52 -0
  7. package/bundle/dist/application/queries.generated.js +2 -2
  8. package/bundle/dist/application/request-log/request-log.model.js +69 -27
  9. package/bundle/dist/application/sonamu.generated.js +20 -3
  10. package/bundle/dist/application/sonamu.generated.sso.js +18 -2
  11. package/bundle/dist/application/token/token.model.js +42 -1
  12. package/bundle/dist/migrations/20260807133553_manual__backfill_request_log_cost.js +49 -0
  13. package/bundle/dist/migrations/20260807145144_alter_request_logs_alter1.js +13 -0
  14. package/bundle/dist/utils/providers/openai/openai-refresh.js +12 -1
  15. package/bundle/dist/utils/slack-notify.js +65 -0
  16. package/bundle/src/application/qgrid/oauth.ts +23 -1
  17. package/bundle/src/application/qgrid/qgrid-oauth-redirect.test.ts +133 -27
  18. package/bundle/src/application/qgrid/qgrid.frame.ts +132 -66
  19. package/bundle/src/application/qgrid/qgrid.types.ts +3 -0
  20. package/bundle/src/application/qgrid/token-death.test.ts +120 -0
  21. package/bundle/src/application/qgrid/token-death.ts +67 -0
  22. package/bundle/src/application/queries.generated.ts +2 -2
  23. package/bundle/src/application/request-log/request-log.entity.json +20 -6
  24. package/bundle/src/application/request-log/request-log.model.test.ts +153 -42
  25. package/bundle/src/application/request-log/request-log.model.ts +86 -40
  26. package/bundle/src/application/sonamu.generated.http +22 -1
  27. package/bundle/src/application/sonamu.generated.sso.ts +16 -0
  28. package/bundle/src/application/sonamu.generated.ts +16 -1
  29. package/bundle/src/application/token/token.model.test.ts +39 -0
  30. package/bundle/src/application/token/token.model.ts +77 -0
  31. package/bundle/src/migrations/20260807133553_manual__backfill_request_log_cost.ts +110 -0
  32. package/bundle/src/migrations/20260807145144_alter_request_logs_alter1.ts +13 -0
  33. package/bundle/src/utils/providers/openai/openai-refresh.ts +17 -0
  34. package/bundle/src/utils/slack-notify.test.ts +97 -0
  35. package/bundle/src/utils/slack-notify.ts +74 -0
  36. package/bundle/web-dist/client/assets/index-2cAgaLOm.css +1 -0
  37. package/bundle/web-dist/client/assets/{index-YowQRE2y.js → index-BgWzzjvj.js} +3 -3
  38. package/bundle/web-dist/client/assets/logs-Lyv8OfHE.js +1 -0
  39. package/bundle/web-dist/client/assets/{monit-B51yXcqk.js → monit-BSa5lSZp.js} +1 -1
  40. package/bundle/web-dist/client/assets/{routes-BqaUiBc0.js → routes-Cp0re-Nn.js} +2 -2
  41. package/bundle/web-dist/client/assets/{services.generated-D3MH3EfY.js → services.generated-B-dMUtEu.js} +1 -1
  42. package/bundle/web-dist/client/assets/{show-LAFY13v6.js → show-C1jEPhuS.js} +1 -1
  43. package/bundle/web-dist/client/assets/tokens-1e66MAC0.js +1 -0
  44. package/bundle/web-dist/client/assets/{use-update-token-mutation-CLhv6SUL.js → use-update-token-mutation-DueEppqt.js} +1 -1
  45. package/bundle/web-dist/client/index.html +2 -2
  46. package/bundle/web-dist/server/assets/{logs-Dbk2Ig2z.js → logs-CwoOsveV.js} +11 -4
  47. package/bundle/web-dist/server/assets/{monit-Hm9dIPhx.js → monit-DIsEsDJN.js} +1 -1
  48. package/bundle/web-dist/server/assets/{routes-DztxeUjk.js → routes-Bts-KJ9W.js} +7 -3
  49. package/bundle/web-dist/server/assets/{services.generated-1Kcul41h.js → services.generated-Bh7Vs8Ds.js} +16 -7
  50. package/bundle/web-dist/server/assets/{show-BHUSw7qv.js → show-DJfaCNUw.js} +1 -1
  51. package/bundle/web-dist/server/assets/{tokens-DHU9lUT2.js → tokens-BA4vwDat.js} +215 -52
  52. package/bundle/web-dist/server/assets/{use-update-token-mutation-axqnye4L.js → use-update-token-mutation-BQRzEPy2.js} +1 -1
  53. package/bundle/web-dist/server/entry-server.generated.js +6 -6
  54. package/package.json +1 -1
  55. package/skills/qgrid/references/cli-env-and-server-boot.md +1 -1
  56. package/skills/qgrid/references/token-auth-quota-lifecycle.md +16 -1
  57. package/bundle/web-dist/client/assets/index-GA9b-zy4.css +0 -1
  58. package/bundle/web-dist/client/assets/logs-o8mm530D.js +0 -1
  59. package/bundle/web-dist/client/assets/tokens-B9Ig7-9Z.js +0 -1
package/README.ko.md CHANGED
@@ -90,6 +90,8 @@ CLI는 실행 시 npm의 최신 버전을 확인하고 patch를 포함해 설치
90
90
  | `QGRID_DB_USER` | `postgres` |
91
91
  | `QGRID_DB_PASSWORD` | `postgres` |
92
92
  | `QGRID_DB_NAME` | `qgrid` |
93
+ | `SLACK_BOT_TOKEN` | — (미설정 시 토큰 만료 알림 비활성) |
94
+ | `SLACK_CHANNEL_ID` | — |
93
95
 
94
96
  서버 동작 관련 환경변수:
95
97
 
package/README.md CHANGED
@@ -91,6 +91,8 @@ Without the `--db` flag, DB connection info is read from:
91
91
  | `QGRID_DB_USER` | `postgres` |
92
92
  | `QGRID_DB_PASSWORD` | `postgres` |
93
93
  | `QGRID_DB_NAME` | `qgrid` |
94
+ | `SLACK_BOT_TOKEN` | — (unset disables token-expiry notifications) |
95
+ | `SLACK_CHANNEL_ID` | — |
94
96
 
95
97
  Server behavior variables:
96
98
 
@@ -8,6 +8,7 @@ const logger = getLogger(["qgrid", "oauth"]);
8
8
  const CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
9
9
  const AUTHORIZE_URL = "https://claude.com/cai/oauth/authorize";
10
10
  const TOKEN_URL = "https://platform.claude.com/v1/oauth/token";
11
+ const CONSOLE_CALLBACK_URL = "https://console.anthropic.com/oauth/code/callback";
11
12
  const ALL_SCOPES = [
12
13
  "org:create_api_key",
13
14
  "user:profile",
@@ -73,6 +74,24 @@ async function exchangeCodeForTokens(code, codeVerifier, state, redirectUri) {
73
74
  emailAddress: data.account?.email_address
74
75
  };
75
76
  }
77
+ /**
78
+ * refresh 실패를 status 와 함께 전달한다. 호출부가 문자열 메시지를 파싱하지 않고
79
+ * 영구 실패(400/401)를 판별할 수 있어야 하기 때문이다.
80
+ */
81
+ var RefreshFailedError = class extends Error {
82
+ status;
83
+ body;
84
+ name = "RefreshFailedError";
85
+ constructor(status, body) {
86
+ super(`Token refresh failed (${status}): ${body}`);
87
+ this.status = status;
88
+ this.body = body;
89
+ }
90
+ /** 재로그인 외 복구 불가한 인증 실패인지. 일시 오류(5xx·네트워크)는 제외된다. */
91
+ get isAuthDead() {
92
+ return this.status === 400 || this.status === 401;
93
+ }
94
+ };
76
95
  async function refreshAccessToken(refreshToken) {
77
96
  const res = await fetch(TOKEN_URL, {
78
97
  method: "POST",
@@ -86,7 +105,7 @@ async function refreshAccessToken(refreshToken) {
86
105
  });
87
106
  if (!res.ok) {
88
107
  const text = await res.text();
89
- throw new Error(`Token refresh failed (${res.status}): ${text}`);
108
+ throw new RefreshFailedError(res.status, text);
90
109
  }
91
110
  const data = await res.json();
92
111
  return {
@@ -136,6 +155,6 @@ async function fetchUsageWithMeta(accessToken) {
136
155
  return entry;
137
156
  }
138
157
  //#endregion
139
- export { buildAuthUrl, exchangeCodeForTokens, fetchUsage, fetchUsageWithMeta, generatePKCE, refreshAccessToken };
158
+ export { CONSOLE_CALLBACK_URL, RefreshFailedError, buildAuthUrl, exchangeCodeForTokens, fetchUsage, fetchUsageWithMeta, generatePKCE, refreshAccessToken };
140
159
 
141
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2F1dGguanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL29hdXRoLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogT0F1dGgg7Jyg7Yu4IOKAlCBDbGF1ZGUgQ29kZSDshozsiqTsnZggT0F1dGgg7ZSM66Gc7JqwIOq3uOuMgOuhnCDsnqztmIRcbiAqL1xuaW1wb3J0IHsgY3JlYXRlSGFzaCwgcmFuZG9tQnl0ZXMgfSBmcm9tIFwibm9kZTpjcnlwdG9cIjtcblxuaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcblxuZXhwb3J0IHR5cGUgQW50aHJvcGljVXNhZ2VSYXcgPSB7XG4gIGVycm9yPzogc3RyaW5nO1xuICBmaXZlX2hvdXI/OiB7IHV0aWxpemF0aW9uOiBudW1iZXIgfCBudWxsOyByZXNldHNfYXQ6IHN0cmluZyB8IG51bGwgfSB8IG51bGw7XG4gIHNldmVuX2RheT86IHsgdXRpbGl6YXRpb246IG51bWJlciB8IG51bGw7IHJlc2V0c19hdDogc3RyaW5nIHwgbnVsbCB9IHwgbnVsbDtcbn07XG5leHBvcnQgdHlwZSBBbnRocm9waWNVc2FnZVdpdGhNZXRhID0ge1xuICBkYXRhOiBBbnRocm9waWNVc2FnZVJhdztcbiAgY2FjaGVkQXQ6IG51bWJlcjtcbn07XG5cbmNvbnN0IGxvZ2dlciA9IGdldExvZ2dlcihbXCJxZ3JpZFwiLCBcIm9hdXRoXCJdKTtcblxuY29uc3QgQ0xJRU5UX0lEID0gXCI5ZDFjMjUwYS1lNjFiLTQ0ZDktODhlZC01OTQ0ZDE5NjJmNWVcIjtcbmNvbnN0IEFVVEhPUklaRV9VUkwgPSBcImh0dHBzOi8vY2xhdWRlLmNvbS9jYWkvb2F1dGgvYXV0aG9yaXplXCI7XG5jb25zdCBUT0tFTl9VUkwgPSBcImh0dHBzOi8vcGxhdGZvcm0uY2xhdWRlLmNvbS92MS9vYXV0aC90b2tlblwiO1xuXG4vLyBsb2dpbiDsi5wg7IKs7JqpIChhdXRob3JpemUgVVJMKVxuY29uc3QgQUxMX1NDT1BFUyA9IFtcbiAgXCJvcmc6Y3JlYXRlX2FwaV9rZXlcIixcbiAgXCJ1c2VyOnByb2ZpbGVcIixcbiAgXCJ1c2VyOmluZmVyZW5jZVwiLFxuICBcInVzZXI6c2Vzc2lvbnM6Y2xhdWRlX2NvZGVcIixcbiAgXCJ1c2VyOm1jcF9zZXJ2ZXJzXCIsXG4gIFwidXNlcjpmaWxlX3VwbG9hZFwiLFxuXTtcblxuLy8gcmVmcmVzaCDsi5wg7IKs7JqpIChvcmc6Y3JlYXRlX2FwaV9rZXkg7KCc7Jm4KVxuY29uc3QgUkVGUkVTSF9TQ09QRVMgPSBbXG4gIFwidXNlcjpwcm9maWxlXCIsXG4gIFwidXNlcjppbmZlcmVuY2VcIixcbiAgXCJ1c2VyOnNlc3Npb25zOmNsYXVkZV9jb2RlXCIsXG4gIFwidXNlcjptY3Bfc2VydmVyc1wiLFxuICBcInVzZXI6ZmlsZV91cGxvYWRcIixcbl07XG5cbmZ1bmN0aW9uIGJhc2U2NFVSTEVuY29kZShidWZmZXI6IEJ1ZmZlcik6IHN0cmluZyB7XG4gIHJldHVybiBidWZmZXIudG9TdHJpbmcoXCJiYXNlNjRcIikucmVwbGFjZSgvXFwrL2csIFwiLVwiKS5yZXBsYWNlKC9cXC8vZywgXCJfXCIpLnJlcGxhY2UoLz0vZywgXCJcIik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVBLQ0UoKTogeyBjb2RlVmVyaWZpZXI6IHN0cmluZzsgY29kZUNoYWxsZW5nZTogc3RyaW5nOyBzdGF0ZTogc3RyaW5nIH0ge1xuICBjb25zdCBjb2RlVmVyaWZpZXIgPSBiYXNlNjRVUkxFbmNvZGUocmFuZG9tQnl0ZXMoMzIpKTtcbiAgY29uc3QgY29kZUNoYWxsZW5nZSA9IGJhc2U2NFVSTEVuY29kZShjcmVhdGVIYXNoKFwic2hhMjU2XCIpLnVwZGF0ZShjb2RlVmVyaWZpZXIpLmRpZ2VzdCgpKTtcbiAgY29uc3Qgc3RhdGUgPSBiYXNlNjRVUkxFbmNvZGUocmFuZG9tQnl0ZXMoMzIpKTtcbiAgcmV0dXJuIHsgY29kZVZlcmlmaWVyLCBjb2RlQ2hhbGxlbmdlLCBzdGF0ZSB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRBdXRoVXJsKGNvZGVDaGFsbGVuZ2U6IHN0cmluZywgc3RhdGU6IHN0cmluZywgcmVkaXJlY3RVcmk6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHVybCA9IG5ldyBVUkwoQVVUSE9SSVpFX1VSTCk7XG4gIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKFwiY29kZVwiLCBcInRydWVcIik7XG4gIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKFwiY2xpZW50X2lkXCIsIENMSUVOVF9JRCk7XG4gIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKFwicmVzcG9uc2VfdHlwZVwiLCBcImNvZGVcIik7XG4gIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKFwicmVkaXJlY3RfdXJpXCIsIHJlZGlyZWN0VXJpKTtcbiAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJzY29wZVwiLCBBTExfU0NPUEVTLmpvaW4oXCIgXCIpKTtcbiAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJjb2RlX2NoYWxsZW5nZVwiLCBjb2RlQ2hhbGxlbmdlKTtcbiAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJjb2RlX2NoYWxsZW5nZV9tZXRob2RcIiwgXCJTMjU2XCIpO1xuICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcInN0YXRlXCIsIHN0YXRlKTtcbiAgcmV0dXJuIHVybC50b1N0cmluZygpO1xufVxuXG5leHBvcnQgdHlwZSBPQXV0aFRva2VucyA9IHtcbiAgYWNjZXNzVG9rZW46IHN0cmluZztcbiAgcmVmcmVzaFRva2VuOiBzdHJpbmc7XG4gIGV4cGlyZXNBdDogbnVtYmVyO1xuICBzY29wZTogc3RyaW5nO1xuICBhY2NvdW50VXVpZD86IHN0cmluZztcbiAgZW1haWxBZGRyZXNzPzogc3RyaW5nO1xufTtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGV4Y2hhbmdlQ29kZUZvclRva2VucyhcbiAgY29kZTogc3RyaW5nLFxuICBjb2RlVmVyaWZpZXI6IHN0cmluZyxcbiAgc3RhdGU6IHN0cmluZyxcbiAgcmVkaXJlY3RVcmk6IHN0cmluZyxcbik6IFByb21pc2U8T0F1dGhUb2tlbnM+IHtcbiAgY29uc3QgcmVzID0gYXdhaXQgZmV0Y2goVE9LRU5fVVJMLCB7XG4gICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICBoZWFkZXJzOiB7IFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiIH0sXG4gICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgZ3JhbnRfdHlwZTogXCJhdXRob3JpemF0aW9uX2NvZGVcIixcbiAgICAgIGNvZGUsXG4gICAgICByZWRpcmVjdF91cmk6IHJlZGlyZWN0VXJpLFxuICAgICAgY2xpZW50X2lkOiBDTElFTlRfSUQsXG4gICAgICBjb2RlX3ZlcmlmaWVyOiBjb2RlVmVyaWZpZXIsXG4gICAgICBzdGF0ZSxcbiAgICB9KSxcbiAgfSk7XG4gIGlmICghcmVzLm9rKSB7XG4gICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlcy50ZXh0KCk7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBUb2tlbiBleGNoYW5nZSBmYWlsZWQgKCR7cmVzLnN0YXR1c30pOiAke3RleHR9YCk7XG4gIH1cblxuICBjb25zdCBkYXRhID0gKGF3YWl0IHJlcy5qc29uKCkpIGFzIHtcbiAgICBhY2Nlc3NfdG9rZW46IHN0cmluZztcbiAgICByZWZyZXNoX3Rva2VuOiBzdHJpbmc7XG4gICAgZXhwaXJlc19pbjogbnVtYmVyO1xuICAgIHNjb3BlOiBzdHJpbmc7XG4gICAgYWNjb3VudD86IHsgdXVpZDogc3RyaW5nOyBlbWFpbF9hZGRyZXNzOiBzdHJpbmcgfTtcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIGFjY2Vzc1Rva2VuOiBkYXRhLmFjY2Vzc190b2tlbixcbiAgICByZWZyZXNoVG9rZW46IGRhdGEucmVmcmVzaF90b2tlbixcbiAgICBleHBpcmVzQXQ6IERhdGUubm93KCkgKyBkYXRhLmV4cGlyZXNfaW4gKiAxMDAwLFxuICAgIHNjb3BlOiBkYXRhLnNjb3BlLFxuICAgIGFjY291bnRVdWlkOiBkYXRhLmFjY291bnQ/LnV1aWQsXG4gICAgZW1haWxBZGRyZXNzOiBkYXRhLmFjY291bnQ/LmVtYWlsX2FkZHJlc3MsXG4gIH07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWZyZXNoQWNjZXNzVG9rZW4ocmVmcmVzaFRva2VuOiBzdHJpbmcpOiBQcm9taXNlPE9BdXRoVG9rZW5zPiB7XG4gIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKFRPS0VOX1VSTCwge1xuICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgaGVhZGVyczogeyBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIiB9LFxuICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGdyYW50X3R5cGU6IFwicmVmcmVzaF90b2tlblwiLFxuICAgICAgcmVmcmVzaF90b2tlbjogcmVmcmVzaFRva2VuLFxuICAgICAgY2xpZW50X2lkOiBDTElFTlRfSUQsXG4gICAgICBzY29wZTogUkVGUkVTSF9TQ09QRVMuam9pbihcIiBcIiksXG4gICAgfSksXG4gIH0pO1xuICBpZiAoIXJlcy5vaykge1xuICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZXMudGV4dCgpO1xuICAgIHRocm93IG5ldyBFcnJvcihgVG9rZW4gcmVmcmVzaCBmYWlsZWQgKCR7cmVzLnN0YXR1c30pOiAke3RleHR9YCk7XG4gIH1cbiAgY29uc3QgZGF0YSA9IChhd2FpdCByZXMuanNvbigpKSBhcyB7XG4gICAgYWNjZXNzX3Rva2VuOiBzdHJpbmc7XG4gICAgcmVmcmVzaF90b2tlbjogc3RyaW5nO1xuICAgIGV4cGlyZXNfaW46IG51bWJlcjtcbiAgICBzY29wZTogc3RyaW5nO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgYWNjZXNzVG9rZW46IGRhdGEuYWNjZXNzX3Rva2VuLFxuICAgIHJlZnJlc2hUb2tlbjogZGF0YS5yZWZyZXNoX3Rva2VuID8/IHJlZnJlc2hUb2tlbixcbiAgICBleHBpcmVzQXQ6IERhdGUubm93KCkgKyBkYXRhLmV4cGlyZXNfaW4gKiAxMDAwLFxuICAgIHNjb3BlOiBkYXRhLnNjb3BlLFxuICB9O1xufVxuXG5jb25zdCB1c2FnZUNhY2hlOiBSZWNvcmQ8c3RyaW5nLCBBbnRocm9waWNVc2FnZVdpdGhNZXRhPiA9IHt9O1xuY29uc3QgVVNBR0VfQVBJX0NBQ0hFX1RUTCA9IDYwXzAwMDsgLy8gMeu2hFxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmV0Y2hVc2FnZShhY2Nlc3NUb2tlbjogc3RyaW5nKTogUHJvbWlzZTxBbnRocm9waWNVc2FnZVJhdz4ge1xuICByZXR1cm4gKGF3YWl0IGZldGNoVXNhZ2VXaXRoTWV0YShhY2Nlc3NUb2tlbikpLmRhdGE7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBmZXRjaFVzYWdlV2l0aE1ldGEoYWNjZXNzVG9rZW46IHN0cmluZyk6IFByb21pc2U8QW50aHJvcGljVXNhZ2VXaXRoTWV0YT4ge1xuICBjb25zdCBjYWNoZUtleSA9IGFjY2Vzc1Rva2VuLnNsaWNlKC0xMCk7XG4gIGNvbnN0IGNhY2hlZCA9IHVzYWdlQ2FjaGVbY2FjaGVLZXldO1xuICBpZiAoY2FjaGVkICYmIERhdGUubm93KCkgLSBjYWNoZWQuY2FjaGVkQXQgPCBVU0FHRV9BUElfQ0FDSEVfVFRMKSB7XG4gICAgcmV0dXJuIGNhY2hlZDtcbiAgfVxuXG4gIGNvbnN0IHJlcyA9IGF3YWl0IGZldGNoKFwiaHR0cHM6Ly9hcGkuYW50aHJvcGljLmNvbS9hcGkvb2F1dGgvdXNhZ2VcIiwge1xuICAgIGhlYWRlcnM6IHtcbiAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHthY2Nlc3NUb2tlbn1gLFxuICAgICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgICBcImFudGhyb3BpYy1iZXRhXCI6IFwib2F1dGgtMjAyNS0wNC0yMFwiLFxuICAgIH0sXG4gICAgc2lnbmFsOiBBYm9ydFNpZ25hbC50aW1lb3V0KDUwMDApLFxuICB9KTtcbiAgaWYgKCFyZXMub2spIHtcbiAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVzLnRleHQoKTtcblxuICAgIC8vIO2MjOyLsSDsi5zrj4TtlbTshJwg7JeQ65+sIOuplOyLnOyngCDstpTstpxcbiAgICBsZXQgZXJyb3JNZXNzYWdlID0gYEVycm9yICR7cmVzLnN0YXR1c31gO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKHRleHQpO1xuICAgICAgZXJyb3JNZXNzYWdlID0gcGFyc2VkLmVycm9yPy5tZXNzYWdlID8/IGVycm9yTWVzc2FnZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIO2MjOyLsSDslYgg65CY66m0IOq4sOuzuCDrqZTsi5zsp4BcbiAgICB9XG5cbiAgICBsb2dnZXIud2FybihgJHtyZXMuc3RhdHVzfTogJHtlcnJvck1lc3NhZ2V9YCk7XG5cbiAgICAvLyDsnbTsoIQg7ISx6rO1IOy6kOyLnCDsnojsnLzrqbQg7Jyg7KeAXG4gICAgaWYgKGNhY2hlZD8uZGF0YSAmJiAhY2FjaGVkLmRhdGEuZXJyb3IpIHJldHVybiBjYWNoZWQ7XG5cbiAgICAvLyDsi6TtjKjrj4Qg7LqQ7IucICjrsJjrs7Ug7Zi47LacIOuwqeyngClcbiAgICBjb25zdCBlcnJvclJlc3VsdCA9IHsgZXJyb3I6IGVycm9yTWVzc2FnZSB9O1xuICAgIGNvbnN0IGVudHJ5ID0geyBkYXRhOiBlcnJvclJlc3VsdCwgY2FjaGVkQXQ6IERhdGUubm93KCkgfTtcbiAgICB1c2FnZUNhY2hlW2NhY2hlS2V5XSA9IGVudHJ5O1xuICAgIHJldHVybiBlbnRyeTtcbiAgfVxuXG4gIGNvbnN0IGRhdGEgPSAoYXdhaXQgcmVzLmpzb24oKSkgYXMgQW50aHJvcGljVXNhZ2VSYXc7XG4gIC8vIGNhY2hlIGludmFsaWRhdGVcbiAgY29uc3QgZW50cnkgPSB7IGRhdGEsIGNhY2hlZEF0OiBEYXRlLm5vdygpIH07XG4gIHVzYWdlQ2FjaGVbY2FjaGVLZXldID0gZW50cnk7XG4gIHJldHVy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
160
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2F1dGguanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL29hdXRoLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogT0F1dGgg7Jyg7Yu4IOKAlCBDbGF1ZGUgQ29kZSDshozsiqTsnZggT0F1dGgg7ZSM66Gc7JqwIOq3uOuMgOuhnCDsnqztmIRcbiAqL1xuaW1wb3J0IHsgY3JlYXRlSGFzaCwgcmFuZG9tQnl0ZXMgfSBmcm9tIFwibm9kZTpjcnlwdG9cIjtcblxuaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcblxuZXhwb3J0IHR5cGUgQW50aHJvcGljVXNhZ2VSYXcgPSB7XG4gIGVycm9yPzogc3RyaW5nO1xuICBmaXZlX2hvdXI/OiB7IHV0aWxpemF0aW9uOiBudW1iZXIgfCBudWxsOyByZXNldHNfYXQ6IHN0cmluZyB8IG51bGwgfSB8IG51bGw7XG4gIHNldmVuX2RheT86IHsgdXRpbGl6YXRpb246IG51bWJlciB8IG51bGw7IHJlc2V0c19hdDogc3RyaW5nIHwgbnVsbCB9IHwgbnVsbDtcbn07XG5leHBvcnQgdHlwZSBBbnRocm9waWNVc2FnZVdpdGhNZXRhID0ge1xuICBkYXRhOiBBbnRocm9waWNVc2FnZVJhdztcbiAgY2FjaGVkQXQ6IG51bWJlcjtcbn07XG5cbmNvbnN0IGxvZ2dlciA9IGdldExvZ2dlcihbXCJxZ3JpZFwiLCBcIm9hdXRoXCJdKTtcblxuY29uc3QgQ0xJRU5UX0lEID0gXCI5ZDFjMjUwYS1lNjFiLTQ0ZDktODhlZC01OTQ0ZDE5NjJmNWVcIjtcbmNvbnN0IEFVVEhPUklaRV9VUkwgPSBcImh0dHBzOi8vY2xhdWRlLmNvbS9jYWkvb2F1dGgvYXV0aG9yaXplXCI7XG5jb25zdCBUT0tFTl9VUkwgPSBcImh0dHBzOi8vcGxhdGZvcm0uY2xhdWRlLmNvbS92MS9vYXV0aC90b2tlblwiO1xuLy8gY2xpZW50IO2XiOyaqSDrqqnroZ3sl5Ag7J6I64qUIOy9mOyGlCDsvZzrsLEuIOyduOymnSDtm4Qg7L2Y7IaUIO2OmOydtOyngOqwgCBgY29kZSNzdGF0ZWDrpbwg7ZGc7Iuc7ZWY6rOgXG4vLyDsgqzsmqnsnpDqsIAg67aZ7Jes64Sj64qUIOy9lOuTnCDtlIzroZzsmrAoQ2xhdWRlIENvZGUgQ0xJ7JmAIOuPmeydvCnsl5Ag7IKs7Jqp7ZWc64ukLlxuZXhwb3J0IGNvbnN0IENPTlNPTEVfQ0FMTEJBQ0tfVVJMID0gXCJodHRwczovL2NvbnNvbGUuYW50aHJvcGljLmNvbS9vYXV0aC9jb2RlL2NhbGxiYWNrXCI7XG5cbi8vIGxvZ2luIOyLnCDsgqzsmqkgKGF1dGhvcml6ZSBVUkwpXG5jb25zdCBBTExfU0NPUEVTID0gW1xuICBcIm9yZzpjcmVhdGVfYXBpX2tleVwiLFxuICBcInVzZXI6cHJvZmlsZVwiLFxuICBcInVzZXI6aW5mZXJlbmNlXCIsXG4gIFwidXNlcjpzZXNzaW9uczpjbGF1ZGVfY29kZVwiLFxuICBcInVzZXI6bWNwX3NlcnZlcnNcIixcbiAgXCJ1c2VyOmZpbGVfdXBsb2FkXCIsXG5dO1xuXG4vLyByZWZyZXNoIOyLnCDsgqzsmqkgKG9yZzpjcmVhdGVfYXBpX2tleSDsoJzsmbgpXG5jb25zdCBSRUZSRVNIX1NDT1BFUyA9IFtcbiAgXCJ1c2VyOnByb2ZpbGVcIixcbiAgXCJ1c2VyOmluZmVyZW5jZVwiLFxuICBcInVzZXI6c2Vzc2lvbnM6Y2xhdWRlX2NvZGVcIixcbiAgXCJ1c2VyOm1jcF9zZXJ2ZXJzXCIsXG4gIFwidXNlcjpmaWxlX3VwbG9hZFwiLFxuXTtcblxuZnVuY3Rpb24gYmFzZTY0VVJMRW5jb2RlKGJ1ZmZlcjogQnVmZmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIGJ1ZmZlci50b1N0cmluZyhcImJhc2U2NFwiKS5yZXBsYWNlKC9cXCsvZywgXCItXCIpLnJlcGxhY2UoL1xcLy9nLCBcIl9cIikucmVwbGFjZSgvPS9nLCBcIlwiKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlUEtDRSgpOiB7IGNvZGVWZXJpZmllcjogc3RyaW5nOyBjb2RlQ2hhbGxlbmdlOiBzdHJpbmc7IHN0YXRlOiBzdHJpbmcgfSB7XG4gIGNvbnN0IGNvZGVWZXJpZmllciA9IGJhc2U2NFVSTEVuY29kZShyYW5kb21CeXRlcygzMikpO1xuICBjb25zdCBjb2RlQ2hhbGxlbmdlID0gYmFzZTY0VVJMRW5jb2RlKGNyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKGNvZGVWZXJpZmllcikuZGlnZXN0KCkpO1xuICBjb25zdCBzdGF0ZSA9IGJhc2U2NFVSTEVuY29kZShyYW5kb21CeXRlcygzMikpO1xuICByZXR1cm4geyBjb2RlVmVyaWZpZXIsIGNvZGVDaGFsbGVuZ2UsIHN0YXRlIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEF1dGhVcmwoY29kZUNoYWxsZW5nZTogc3RyaW5nLCBzdGF0ZTogc3RyaW5nLCByZWRpcmVjdFVyaTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgdXJsID0gbmV3IFVSTChBVVRIT1JJWkVfVVJMKTtcbiAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJjb2RlXCIsIFwidHJ1ZVwiKTtcbiAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJjbGllbnRfaWRcIiwgQ0xJRU5UX0lEKTtcbiAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJyZXNwb25zZV90eXBlXCIsIFwiY29kZVwiKTtcbiAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoXCJyZWRpcmVjdF91cmlcIiwgcmVkaXJlY3RVcmkpO1xuICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcInNjb3BlXCIsIEFMTF9TQ09QRVMuam9pbihcIiBcIikpO1xuICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcImNvZGVfY2hhbGxlbmdlXCIsIGNvZGVDaGFsbGVuZ2UpO1xuICB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChcImNvZGVfY2hhbGxlbmdlX21ldGhvZFwiLCBcIlMyNTZcIik7XG4gIHVybC5zZWFyY2hQYXJhbXMuYXBwZW5kKFwic3RhdGVcIiwgc3RhdGUpO1xuICByZXR1cm4gdXJsLnRvU3RyaW5nKCk7XG59XG5cbmV4cG9ydCB0eXBlIE9BdXRoVG9rZW5zID0ge1xuICBhY2Nlc3NUb2tlbjogc3RyaW5nO1xuICByZWZyZXNoVG9rZW46IHN0cmluZztcbiAgZXhwaXJlc0F0OiBudW1iZXI7XG4gIHNjb3BlOiBzdHJpbmc7XG4gIGFjY291bnRVdWlkPzogc3RyaW5nO1xuICBlbWFpbEFkZHJlc3M/OiBzdHJpbmc7XG59O1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZXhjaGFuZ2VDb2RlRm9yVG9rZW5zKFxuICBjb2RlOiBzdHJpbmcsXG4gIGNvZGVWZXJpZmllcjogc3RyaW5nLFxuICBzdGF0ZTogc3RyaW5nLFxuICByZWRpcmVjdFVyaTogc3RyaW5nLFxuKTogUHJvbWlzZTxPQXV0aFRva2Vucz4ge1xuICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaChUT0tFTl9VUkwsIHtcbiAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgIGhlYWRlcnM6IHsgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIgfSxcbiAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBncmFudF90eXBlOiBcImF1dGhvcml6YXRpb25fY29kZVwiLFxuICAgICAgY29kZSxcbiAgICAgIHJlZGlyZWN0X3VyaTogcmVkaXJlY3RVcmksXG4gICAgICBjbGllbnRfaWQ6IENMSUVOVF9JRCxcbiAgICAgIGNvZGVfdmVyaWZpZXI6IGNvZGVWZXJpZmllcixcbiAgICAgIHN0YXRlLFxuICAgIH0pLFxuICB9KTtcbiAgaWYgKCFyZXMub2spIHtcbiAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVzLnRleHQoKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFRva2VuIGV4Y2hhbmdlIGZhaWxlZCAoJHtyZXMuc3RhdHVzfSk6ICR7dGV4dH1gKTtcbiAgfVxuXG4gIGNvbnN0IGRhdGEgPSAoYXdhaXQgcmVzLmpzb24oKSkgYXMge1xuICAgIGFjY2Vzc190b2tlbjogc3RyaW5nO1xuICAgIHJlZnJlc2hfdG9rZW46IHN0cmluZztcbiAgICBleHBpcmVzX2luOiBudW1iZXI7XG4gICAgc2NvcGU6IHN0cmluZztcbiAgICBhY2NvdW50PzogeyB1dWlkOiBzdHJpbmc7IGVtYWlsX2FkZHJlc3M6IHN0cmluZyB9O1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgYWNjZXNzVG9rZW46IGRhdGEuYWNjZXNzX3Rva2VuLFxuICAgIHJlZnJlc2hUb2tlbjogZGF0YS5yZWZyZXNoX3Rva2VuLFxuICAgIGV4cGlyZXNBdDogRGF0ZS5ub3coKSArIGRhdGEuZXhwaXJlc19pbiAqIDEwMDAsXG4gICAgc2NvcGU6IGRhdGEuc2NvcGUsXG4gICAgYWNjb3VudFV1aWQ6IGRhdGEuYWNjb3VudD8udXVpZCxcbiAgICBlbWFpbEFkZHJlc3M6IGRhdGEuYWNjb3VudD8uZW1haWxfYWRkcmVzcyxcbiAgfTtcbn1cblxuLyoqXG4gKiByZWZyZXNoIOyLpO2MqOulvCBzdGF0dXMg7JmAIO2VqOq7mCDsoITri6ztlZzri6QuIO2YuOy2nOu2gOqwgCDrrLjsnpDsl7Qg66mU7Iuc7KeA66W8IO2MjOyLse2VmOyngCDslYrqs6BcbiAqIOyYgeq1rCDsi6TtjKgoNDAwLzQwMSnrpbwg7YyQ67OE7ZWgIOyImCDsnojslrTslbwg7ZWY6riwIOuVjOusuOydtOuLpC5cbiAqL1xuZXhwb3J0IGNsYXNzIFJlZnJlc2hGYWlsZWRFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgb3ZlcnJpZGUgcmVhZG9ubHkgbmFtZSA9IFwiUmVmcmVzaEZhaWxlZEVycm9yXCI7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHJlYWRvbmx5IHN0YXR1czogbnVtYmVyLFxuICAgIHJlYWRvbmx5IGJvZHk6IHN0cmluZyxcbiAgKSB7XG4gICAgc3VwZXIoYFRva2VuIHJlZnJlc2ggZmFpbGVkICgke3N0YXR1c30pOiAke2JvZHl9YCk7XG4gIH1cblxuICAvKiog7J6s66Gc6re47J24IOyZuCDrs7Xqtawg67aI6rCA7ZWcIOyduOymnSDsi6TtjKjsnbjsp4AuIOydvOyLnCDsmKTrpZgoNXh4wrfrhKTtirjsm4ztgawp64qUIOygnOyZuOuQnOuLpC4gKi9cbiAgZ2V0IGlzQXV0aERlYWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdHVzID09PSA0MDAgfHwgdGhpcy5zdGF0dXMgPT09IDQwMTtcbiAgfVxufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVmcmVzaEFjY2Vzc1Rva2VuKHJlZnJlc2hUb2tlbjogc3RyaW5nKTogUHJvbWlzZTxPQXV0aFRva2Vucz4ge1xuICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaChUT0tFTl9VUkwsIHtcbiAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgIGhlYWRlcnM6IHsgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIgfSxcbiAgICBib2R5OiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBncmFudF90eXBlOiBcInJlZnJlc2hfdG9rZW5cIixcbiAgICAgIHJlZnJlc2hfdG9rZW46IHJlZnJlc2hUb2tlbixcbiAgICAgIGNsaWVudF9pZDogQ0xJRU5UX0lELFxuICAgICAgc2NvcGU6IFJFRlJFU0hfU0NPUEVTLmpvaW4oXCIgXCIpLFxuICAgIH0pLFxuICB9KTtcbiAgaWYgKCFyZXMub2spIHtcbiAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVzLnRleHQoKTtcbiAgICB0aHJvdyBuZXcgUmVmcmVzaEZhaWxlZEVycm9yKHJlcy5zdGF0dXMsIHRleHQpO1xuICB9XG4gIGNvbnN0IGRhdGEgPSAoYXdhaXQgcmVzLmpzb24oKSkgYXMge1xuICAgIGFjY2Vzc190b2tlbjogc3RyaW5nO1xuICAgIHJlZnJlc2hfdG9rZW46IHN0cmluZztcbiAgICBleHBpcmVzX2luOiBudW1iZXI7XG4gICAgc2NvcGU6IHN0cmluZztcbiAgfTtcblxuICByZXR1cm4ge1xuICAgIGFjY2Vzc1Rva2VuOiBkYXRhLmFjY2Vzc190b2tlbixcbiAgICByZWZyZXNoVG9rZW46IGRhdGEucmVmcmVzaF90b2tlbiA/PyByZWZyZXNoVG9rZW4sXG4gICAgZXhwaXJlc0F0OiBEYXRlLm5vdygpICsgZGF0YS5leHBpcmVzX2luICogMTAwMCxcbiAgICBzY29wZTogZGF0YS5zY29wZSxcbiAgfTtcbn1cblxuY29uc3QgdXNhZ2VDYWNoZTogUmVjb3JkPHN0cmluZywgQW50aHJvcGljVXNhZ2VXaXRoTWV0YT4gPSB7fTtcbmNvbnN0IFVTQUdFX0FQSV9DQUNIRV9UVEwgPSA2MF8wMDA7IC8vIDHrtoRcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGZldGNoVXNhZ2UoYWNjZXNzVG9rZW46IHN0cmluZyk6IFByb21pc2U8QW50aHJvcGljVXNhZ2VSYXc+IHtcbiAgcmV0dXJuIChhd2FpdCBmZXRjaFVzYWdlV2l0aE1ldGEoYWNjZXNzVG9rZW4pKS5kYXRhO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZmV0Y2hVc2FnZVdpdGhNZXRhKGFjY2Vzc1Rva2VuOiBzdHJpbmcpOiBQcm9taXNlPEFudGhyb3BpY1VzYWdlV2l0aE1ldGE+IHtcbiAgY29uc3QgY2FjaGVLZXkgPSBhY2Nlc3NUb2tlbi5zbGljZSgtMTApO1xuICBjb25zdCBjYWNoZWQgPSB1c2FnZUNhY2hlW2NhY2hlS2V5XTtcbiAgaWYgKGNhY2hlZCAmJiBEYXRlLm5vdygpIC0gY2FjaGVkLmNhY2hlZEF0IDwgVVNBR0VfQVBJX0NBQ0hFX1RUTCkge1xuICAgIHJldHVybiBjYWNoZWQ7XG4gIH1cblxuICBjb25zdCByZXMgPSBhd2FpdCBmZXRjaChcImh0dHBzOi8vYXBpLmFudGhyb3BpYy5jb20vYXBpL29hdXRoL3VzYWdlXCIsIHtcbiAgICBoZWFkZXJzOiB7XG4gICAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7YWNjZXNzVG9rZW59YCxcbiAgICAgIFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgXCJhbnRocm9waWMtYmV0YVwiOiBcIm9hdXRoLTIwMjUtMDQtMjBcIixcbiAgICB9LFxuICAgIHNpZ25hbDogQWJvcnRTaWduYWwudGltZW91dCg1MDAwKSxcbiAgfSk7XG4gIGlmICghcmVzLm9rKSB7XG4gICAgY29uc3QgdGV4dCA9IGF3YWl0IHJlcy50ZXh0KCk7XG5cbiAgICAvLyDtjIzsi7Eg7Iuc64+E7ZW07IScIOyXkOufrCDrqZTsi5zsp4Ag7LaU7LacXG4gICAgbGV0IGVycm9yTWVzc2FnZSA9IGBFcnJvciAke3Jlcy5zdGF0dXN9YDtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZSh0ZXh0KTtcbiAgICAgIGVycm9yTWVzc2FnZSA9IHBhcnNlZC5lcnJvcj8ubWVzc2FnZSA/PyBlcnJvck1lc3NhZ2U7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyDtjIzsi7Eg7JWIIOuQmOuptCDquLDrs7gg66mU7Iuc7KeAXG4gICAgfVxuXG4gICAgbG9nZ2VyLndhcm4oYCR7cmVzLnN0YXR1c306ICR7ZXJyb3JNZXNzYWdlfWApO1xuXG4gICAgLy8g7J207KCEIOyEseqztSDsupDsi5wg7J6I7Jy866m0IOycoOyngFxuICAgIGlmIChjYWNoZWQ/LmRhdGEgJiYgIWNhY2hlZC5kYXRhLmVycm9yKSByZXR1cm4gY2FjaGVkO1xuXG4gICAgLy8g7Iuk7Yyo64+EIOy6kOyLnCAo67CY67O1IO2YuOy2nCDrsKnsp4ApXG4gICAgY29uc3QgZXJyb3JSZXN1bHQgPSB7IGVycm9yOiBlcnJvck1lc3NhZ2UgfTtcbiAgICBjb25zdCBlbnRyeSA9IHsgZGF0YTogZXJyb3JSZXN1bHQsIGNhY2hlZEF0OiBEYXRlLm5vdygpIH07XG4gICAgdXNhZ2VDYWNoZVtjYWNoZUtleV0gPSBlbnRyeTtcbiAgICByZXR1cm4gZW50cnk7XG4gIH1cblxuICBjb25zdCBkYXRhID0gKGF3YWl0IHJlcy5qc29uKCkpIGFzIEFudGhyb3BpY1VzYWdlUmF3O1xuICAvLyBjYWNoZSBpbnZhbGlkYXRlXG4gIGNvbnN0IGVudHJ5ID0geyBkYXRhLCBjYWNoZWRBdDogRGF0ZS5ub3coKSB9O1xuICB1c2FnZUNhY2hl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
@@ -5,11 +5,12 @@ import { ToolSchemaCompositionError } from "./tool-emulation-schema.js";
5
5
  import { QgridDispatcher, buildAndValidateStrictOutputSchema } from "./qgrid.dispatcher.js";
6
6
  import __decorateMetadata from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorateMetadata.js";
7
7
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.140.0/helpers/esm/decorate.js";
8
- import { buildAuthUrl, exchangeCodeForTokens, fetchUsage, generatePKCE, refreshAccessToken } from "./oauth.js";
8
+ import { CONSOLE_CALLBACK_URL, RefreshFailedError, buildAuthUrl, exchangeCodeForTokens, fetchUsage, generatePKCE, refreshAccessToken } from "./oauth.js";
9
9
  import { MICRO_USD, RequestLogModel } from "../request-log/request-log.model.js";
10
10
  import { afterQuery, beforeQuery, finishRunAborted, finishRunWithError } from "./qgrid-run-lifecycle.js";
11
11
  import { TokenModel } from "../token/token.model.js";
12
12
  import { TokenCredentials } from "../token/token.types.js";
13
+ import { deactivateAuthDeadToken, notifyTokenAdded } from "./token-death.js";
13
14
  import { BadRequestException, BaseFrameClass, Sonamu, api, stream } from "sonamu";
14
15
  import crypto from "node:crypto";
15
16
  import { getLogger } from "@logtape/logtape";
@@ -42,19 +43,43 @@ async function deleteOAuthState(state) {
42
43
  if (!cache) return;
43
44
  await cache.delete({ key: `${OAUTH_STATE_PREFIX}${state}` });
44
45
  }
45
- function getOAuthRedirectUri() {
46
+ function deriveRequestBaseUrl() {
46
47
  try {
47
48
  const { headers, request } = Sonamu.getContext();
48
49
  const origin = headers.origin;
49
- if (typeof origin === "string" && /^https?:\/\//.test(origin)) return `${origin.replace(/\/+$/, "")}/callback`;
50
+ if (typeof origin === "string" && /^https?:\/\//.test(origin)) return origin.replace(/\/+$/, "");
50
51
  const forwardedHost = headers["x-forwarded-host"];
51
52
  const host = (Array.isArray(forwardedHost) ? forwardedHost[0] : forwardedHost) ?? headers.host;
52
53
  if (host) {
53
54
  const forwardedProto = headers["x-forwarded-proto"];
54
- return `${(Array.isArray(forwardedProto) ? forwardedProto[0] : forwardedProto)?.split(",")[0] ?? request.protocol}://${host}/callback`;
55
+ return `${(Array.isArray(forwardedProto) ? forwardedProto[0] : forwardedProto)?.split(",")[0] ?? request.protocol}://${host}`;
55
56
  }
56
57
  } catch {}
57
- return `http://localhost:${process.env.PORT ?? "44900"}/callback`;
58
+ return null;
59
+ }
60
+ const LOOPBACK_HOSTNAMES = /* @__PURE__ */ new Set([
61
+ "localhost",
62
+ "127.0.0.1",
63
+ "[::1]",
64
+ "::1"
65
+ ]);
66
+ function isLoopbackBase(base) {
67
+ try {
68
+ return LOOPBACK_HOSTNAMES.has(new URL(base).hostname);
69
+ } catch {
70
+ return false;
71
+ }
72
+ }
73
+ function resolveOAuthRedirect() {
74
+ const base = deriveRequestBaseUrl();
75
+ if (base && !isLoopbackBase(base)) return {
76
+ redirectUri: CONSOLE_CALLBACK_URL,
77
+ mode: "code"
78
+ };
79
+ return {
80
+ redirectUri: `${base ?? `http://localhost:${process.env.PORT ?? "44900"}`}/callback`,
81
+ mode: "redirect"
82
+ };
58
83
  }
59
84
  function rejectImageGenerationStream(args) {
60
85
  if (!args.imageGeneration) return;
@@ -96,6 +121,7 @@ function createHttpDisconnectHandle() {
96
121
  }
97
122
  const logger = getLogger(["qgrid"]);
98
123
  const oauthLogger = getLogger(["qgrid", "oauth"]);
124
+ const inflightAnthropicRefresh = /* @__PURE__ */ new Map();
99
125
  var QgridFrameClass = class extends BaseFrameClass {
100
126
  constructor() {
101
127
  super("Qgrid");
@@ -296,8 +322,8 @@ var QgridFrameClass = class extends BaseFrameClass {
296
322
  async stats() {
297
323
  return QgridDispatcher.getStats();
298
324
  }
299
- async totalCost(tokenName) {
300
- return { usd: await RequestLogModel.totalCost({ token_name: tokenName }) };
325
+ async totalCost(params) {
326
+ return { usd: await RequestLogModel.totalCost(params) };
301
327
  }
302
328
  async projectNames() {
303
329
  return { names: await RequestLogModel.distinctProjectNames() };
@@ -344,14 +370,46 @@ var QgridFrameClass = class extends BaseFrameClass {
344
370
  }
345
371
  async oauthStart(name) {
346
372
  const { codeVerifier, codeChallenge, state } = generatePKCE();
347
- const redirectUri = getOAuthRedirectUri();
373
+ const { redirectUri, mode } = resolveOAuthRedirect();
348
374
  const authUrl = buildAuthUrl(codeChallenge, state, redirectUri);
349
375
  await setOAuthState(state, {
350
376
  codeVerifier,
351
377
  name,
352
378
  redirectUri
353
379
  });
354
- return { authUrl };
380
+ return {
381
+ authUrl,
382
+ mode
383
+ };
384
+ }
385
+ async oauthComplete(pastedCode) {
386
+ const trimmed = pastedCode.trim();
387
+ const separatorAt = trimmed.indexOf("#");
388
+ const code = separatorAt > 0 ? trimmed.slice(0, separatorAt) : "";
389
+ const state = separatorAt > 0 ? trimmed.slice(separatorAt + 1) : "";
390
+ if (!code || !state) throw new BadRequestException("expected the code shown after login, in code#state form");
391
+ const pending = await getOAuthState(state);
392
+ if (!pending) throw new BadRequestException("login session not found or expired — start the login again");
393
+ await deleteOAuthState(state);
394
+ await this.completeAnthropicLogin(code, state, pending);
395
+ return {
396
+ added: true,
397
+ name: pending.name
398
+ };
399
+ }
400
+ async completeAnthropicLogin(code, state, pending) {
401
+ const tokens = await exchangeCodeForTokens(code, pending.codeVerifier, state, pending.redirectUri);
402
+ const { isNew } = await TokenModel.replaceByAccount("anthropic", tokens.accountUuid, {
403
+ provider: "anthropic",
404
+ credentials: {
405
+ accessToken: tokens.accessToken,
406
+ refreshToken: tokens.refreshToken,
407
+ expiresAt: tokens.expiresAt ?? 0,
408
+ accountUuid: tokens.accountUuid ?? ""
409
+ },
410
+ name: pending.name
411
+ });
412
+ if (isNew) notifyTokenAdded(pending.name, "anthropic");
355
413
  }
356
414
  async handleOAuthCallback(code, state, reply) {
357
415
  const pending = await getOAuthState(state);
@@ -361,21 +419,7 @@ var QgridFrameClass = class extends BaseFrameClass {
361
419
  }
362
420
  await deleteOAuthState(state);
363
421
  try {
364
- const tokens = await exchangeCodeForTokens(code, pending.codeVerifier, state, pending.redirectUri);
365
- if (tokens.accountUuid) {
366
- const oldEntries = await TokenModel.findByAccountIdentifier("A", "anthropic", tokens.accountUuid);
367
- if (oldEntries.length > 0) await TokenModel.del(oldEntries.map((o) => o.id));
368
- }
369
- await TokenModel.save([{
370
- provider: "anthropic",
371
- credentials: {
372
- accessToken: tokens.accessToken,
373
- refreshToken: tokens.refreshToken,
374
- expiresAt: tokens.expiresAt ?? 0,
375
- accountUuid: tokens.accountUuid ?? ""
376
- },
377
- name: pending.name
378
- }]);
422
+ await this.completeAnthropicLogin(code, state, pending);
379
423
  return reply.redirect(`/?oauth=success&name=${encodeURIComponent(pending.name)}`);
380
424
  } catch (e) {
381
425
  return reply.redirect(`/?oauth=error&reason=${encodeURIComponent(e.message)}`);
@@ -385,11 +429,7 @@ var QgridFrameClass = class extends BaseFrameClass {
385
429
  if (!QgridDispatcher.openaiDispatcher) throw new Error("OpenAI dispatcher not initialized");
386
430
  const { authUrl } = await QgridDispatcher.openaiDispatcher.startBrowserLogin(name);
387
431
  QgridDispatcher.openaiDispatcher.completeBrowserLogin().then(async (creds) => {
388
- if (creds.accountId) {
389
- const oldEntries = await TokenModel.findByAccountIdentifier("A", "openai", creds.accountId);
390
- if (oldEntries.length > 0) await TokenModel.del(oldEntries.map((o) => o.id));
391
- }
392
- await TokenModel.save([{
432
+ const { isNew } = await TokenModel.replaceByAccount("openai", creds.accountId, {
393
433
  provider: "openai",
394
434
  credentials: {
395
435
  accessToken: creds.accessToken,
@@ -399,12 +439,16 @@ var QgridFrameClass = class extends BaseFrameClass {
399
439
  accountId: creds.accountId
400
440
  },
401
441
  name
402
- }]);
442
+ });
403
443
  logger.info(`OpenAI token saved for ${name}`);
444
+ if (isNew) notifyTokenAdded(name, "openai");
404
445
  }).catch((e) => {
405
446
  logger.warn(`OpenAI browser login failed: ${e.message}`);
406
447
  });
407
- return { authUrl };
448
+ return {
449
+ authUrl,
450
+ mode: "redirect"
451
+ };
408
452
  }
409
453
  async usage(tokenId) {
410
454
  const { rows: allTokens } = await TokenModel.findMany("A");
@@ -457,10 +501,27 @@ var QgridFrameClass = class extends BaseFrameClass {
457
501
  return convertAnthropicUsage(raw);
458
502
  }
459
503
  async refreshToken(token) {
504
+ const inflight = inflightAnthropicRefresh.get(token.id);
505
+ if (inflight) return inflight;
506
+ const promise = this.doRefreshToken(token);
507
+ inflightAnthropicRefresh.set(token.id, promise);
508
+ try {
509
+ return await promise;
510
+ } finally {
511
+ inflightAnthropicRefresh.delete(token.id);
512
+ }
513
+ }
514
+ async doRefreshToken(token) {
460
515
  const creds = token.credentials;
461
516
  const rt = getRefreshToken(creds);
462
517
  if (!rt) throw new Error("No refresh token");
463
- const refreshed = await refreshAccessToken(rt);
518
+ let refreshed;
519
+ try {
520
+ refreshed = await refreshAccessToken(rt);
521
+ } catch (e) {
522
+ if (e instanceof RefreshFailedError && e.isAuthDead) await deactivateAuthDeadToken(token, rt, `anthropic:${e.status}`);
523
+ throw e;
524
+ }
464
525
  const updated = TokenCredentials.parse({
465
526
  ...creds,
466
527
  accessToken: refreshed.accessToken,
@@ -552,7 +613,7 @@ __decorate([
552
613
  clients: ["axios", "tanstack-query"]
553
614
  }),
554
615
  __decorateMetadata("design:type", Function),
555
- __decorateMetadata("design:paramtypes", [String]),
616
+ __decorateMetadata("design:paramtypes", [Object]),
556
617
  __decorateMetadata("design:returntype", Promise)
557
618
  ], QgridFrameClass.prototype, "totalCost", null);
558
619
  __decorate([
@@ -618,6 +679,15 @@ __decorate([
618
679
  __decorateMetadata("design:paramtypes", [String]),
619
680
  __decorateMetadata("design:returntype", Promise)
620
681
  ], QgridFrameClass.prototype, "oauthStart", null);
682
+ __decorate([
683
+ api({
684
+ httpMethod: "POST",
685
+ clients: ["axios", "tanstack-mutation"]
686
+ }),
687
+ __decorateMetadata("design:type", Function),
688
+ __decorateMetadata("design:paramtypes", [String]),
689
+ __decorateMetadata("design:returntype", Promise)
690
+ ], QgridFrameClass.prototype, "oauthComplete", null);
621
691
  __decorate([
622
692
  api({
623
693
  httpMethod: "POST",
@@ -662,4 +732,4 @@ function convertAnthropicUsage(raw) {
662
732
  //#endregion
663
733
  export { QgridFrame };
664
734
 
665
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicWdyaWQuZnJhbWUuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLmZyYW1lLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjcnlwdG8gZnJvbSBcIm5vZGU6Y3J5cHRvXCI7XG5cbmltcG9ydCB7IGdldExvZ2dlciB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5pbXBvcnQgeyB0eXBlIEZhc3RpZnlSZXBseSwgdHlwZSBGYXN0aWZ5UmVxdWVzdCB9IGZyb20gXCJmYXN0aWZ5XCI7XG5pbXBvcnQgeyBhcGksIEJhZFJlcXVlc3RFeGNlcHRpb24sIEJhc2VGcmFtZUNsYXNzLCBTb25hbXUsIHN0cmVhbSB9IGZyb20gXCJzb25hbXVcIjtcbmltcG9ydCB7IGdldENhY2hlTWFuYWdlclJlZiB9IGZyb20gXCJzb25hbXUvY2FjaGVcIjtcblxuaW1wb3J0IHsgdHlwZSBMb2NhbGl6ZWRTdHJpbmcgfSBmcm9tIFwiLi4vLi4vaTE4bi9zZC5nZW5lcmF0ZWRcIjtcbmltcG9ydCB7XG4gIGdldEFjY2Vzc1Rva2VuLFxuICBnZXRFeHBpcmVzQXQsXG4gIGdldFJlZnJlc2hUb2tlbixcbn0gZnJvbSBcIi4uLy4uL3V0aWxzL3Byb3ZpZGVycy9jb21tb24vY3JlZGVudGlhbHNcIjtcbmltcG9ydCB7IENhbGxlclNjaGVtYVZhbGlkYXRpb25FcnJvciB9IGZyb20gXCIuLi8uLi91dGlscy9wcm92aWRlcnMvY29tbW9uL3NjaGVtYS12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBNSUNST19VU0QsIFJlcXVlc3RMb2dNb2RlbCB9IGZyb20gXCIuLi9yZXF1ZXN0LWxvZy9yZXF1ZXN0LWxvZy5tb2RlbFwiO1xuaW1wb3J0IHsgdHlwZSBUb2tlblN1YnNldEEgfSBmcm9tIFwiLi4vc29uYW11LmdlbmVyYXRlZFwiO1xuaW1wb3J0IHsgVG9rZW5Nb2RlbCwgdHlwZSBUb2tlblVwZGF0ZUZpZWxkcyB9IGZyb20gXCIuLi90b2tlbi90b2tlbi5tb2RlbFwiO1xuaW1wb3J0IHsgVG9rZW5DcmVkZW50aWFscyB9IGZyb20gXCIuLi90b2tlbi90b2tlbi50eXBlc1wiO1xuaW1wb3J0IHtcbiAgdHlwZSBBbnRocm9waWNVc2FnZVJhdyxcbiAgYnVpbGRBdXRoVXJsLFxuICBleGNoYW5nZUNvZGVGb3JUb2tlbnMsXG4gIGZldGNoVXNhZ2UsXG4gIGdlbmVyYXRlUEtDRSxcbiAgcmVmcmVzaEFjY2Vzc1Rva2VuLFxufSBmcm9tIFwiLi9vYXV0aFwiO1xuaW1wb3J0IHtcbiAgYWZ0ZXJRdWVyeSxcbiAgYmVmb3JlUXVlcnksXG4gIGZpbmlzaFJ1bkFib3J0ZWQsXG4gIGZpbmlzaFJ1bldpdGhFcnJvcixcbn0gZnJvbSBcIi4vcWdyaWQtcnVuLWxpZmVjeWNsZVwiO1xuaW1wb3J0IHsgYnVpbGRBbmRWYWxpZGF0ZVN0cmljdE91dHB1dFNjaGVtYSwgUWdyaWREaXNwYXRjaGVyIH0gZnJvbSBcIi4vcWdyaWQuZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHtcbiAgdHlwZSBRdWVyeUlucHV0LFxuICB0eXBlIEFwcGVuZFN0ZXBJbnB1dCxcbiAgdHlwZSBDcmVhdGVSdW5JbnB1dCxcbiAgdHlwZSBGaW5pc2hSdW5JbnB1dCxcbiAgdHlwZSBIZWFsdGhSZXNwb25zZSxcbiAgdHlwZSBPQXV0aFN0YXJ0UmVzdWx0LFxuICB0eXBlIFF1ZXJ5T3V0cHV0LFxuICB0eXBlIFFncmlkUnVuQ29udGV4dCxcbiAgU3RyZWFtRXZlbnRzLFxuICB0eXBlIFRva2VuU3RhdHMsXG4gIHR5cGUgVXNhZ2VSZXNwb25zZSxcbn0gZnJvbSBcIi4vcWdyaWQudHlwZXNcIjtcbmltcG9ydCB7IFRvb2xTY2hlbWFDb21wb3NpdGlvbkVycm9yIH0gZnJvbSBcIi4vdG9vbC1lbXVsYXRpb24tc2NoZW1hXCI7XG5cbmNvbnN0IHBlbmRpbmdTdHJlYW1zID0gbmV3IE1hcDxzdHJpbmcsIFF1ZXJ5SW5wdXQ+KCk7XG5cbnR5cGUgUGVuZGluZ09BdXRoID0geyBjb2RlVmVyaWZpZXI6IHN0cmluZzsgbmFtZTogc3RyaW5nOyByZWRpcmVjdFVyaTogc3RyaW5nIH07XG5jb25zdCBPQVVUSF9TVEFURV9QUkVGSVggPSBcIm9hdXRoOnN0YXRlOlwiO1xuY29uc3QgT0FVVEhfU1RBVEVfVFRMID0gXCI1bVwiO1xuXG5mdW5jdGlvbiB1bml4U2Vjb25kc1RvSXNvKHNlY29uZHM6IG51bWJlciB8IG51bGwgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCBudWxsIHtcbiAgcmV0dXJuIHR5cGVvZiBzZWNvbmRzID09PSBcIm51bWJlclwiID8gbmV3IERhdGUoc2Vjb25kcyAqIDEwMDApLnRvSVNPU3RyaW5nKCkgOiBudWxsO1xufVxuXG5hc3luYyBmdW5jdGlvbiBzZXRPQXV0aFN0YXRlKHN0YXRlOiBzdHJpbmcsIGRhdGE6IFBlbmRpbmdPQXV0aCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBjYWNoZSA9IGdldENhY2hlTWFuYWdlclJlZigpO1xuICBpZiAoIWNhY2hlKSB0aHJvdyBuZXcgRXJyb3IoXCJDYWNoZU1hbmFnZXIgbm90IGluaXRpYWxpemVkXCIpO1xuICBhd2FpdCBjYWNoZS5zZXQoe1xuICAgIGtleTogYCR7T0FVVEhfU1RBVEVfUFJFRklYfSR7c3RhdGV9YCxcbiAgICB2YWx1ZTogSlNPTi5zdHJpbmdpZnkoZGF0YSksXG4gICAgdHRsOiBPQVVUSF9TVEFURV9UVEwsXG4gIH0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRPQXV0aFN0YXRlKHN0YXRlOiBzdHJpbmcpOiBQcm9taXNlPFBlbmRpbmdPQXV0aCB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBjYWNoZSA9IGdldENhY2hlTWFuYWdlclJlZigpO1xuICBpZiAoIWNhY2hlKSB0aHJvdyBuZXcgRXJyb3IoXCJDYWNoZU1hbmFnZXIgbm90IGluaXRpYWxpemVkXCIpO1xuICBjb25zdCByYXcgPSBhd2FpdCBjYWNoZS5nZXQ8c3RyaW5nPih7IGtleTogYCR7T0FVVEhfU1RBVEVfUFJFRklYfSR7c3RhdGV9YCB9KTtcbiAgaWYgKCFyYXcpIHJldHVybiB1bmRlZmluZWQ7XG4gIHJldHVybiBKU09OLnBhcnNlKHJhdykgYXMgUGVuZGluZ09BdXRoO1xufVxuXG5hc3luYyBmdW5jdGlvbiBkZWxldGVPQXV0aFN0YXRlKHN0YXRlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgY2FjaGUgPSBnZXRDYWNoZU1hbmFnZXJSZWYoKTtcbiAgaWYgKCFjYWNoZSkgcmV0dXJuO1xuICBhd2FpdCBjYWNoZS5kZWxldGUoeyBrZXk6IGAke09BVVRIX1NUQVRFX1BSRUZJWH0ke3N0YXRlfWAgfSk7XG59XG5cbi8vIE9BdXRoIGNhbGxiYWNrIOydgCDrjIDsi5zrs7Trk5zqsIAg7KCR7IaN7ZWcIHFncmlkIOyjvOyGjOuhnCDrj4zslYTsmKjri6QuIOu4jOudvOyasOyggOqwgCDrs7Trgrhcbi8vIE9yaWdpbijsmrDshKApIOuYkOuKlCBIb3N0IO2XpOuNlOyXkOyEnCBiYXNlIFVSTCDsnYQg7YyM7IOd7ZWY66+A66GcIOuzhOuPhCBlbnYg7ISk7KCV7J20IO2VhOyalCDsl4bri6QuXG4vLyBIVFRQIGNvbnRleHQg6rCAIOyXhuuKlCDsp4HsoJEg7Zi47LacKO2FjOyKpO2KuCDrk7Ep66eMIGxvY2FsaG9zdCDroZwg7Y+067Cx7ZWc64ukLlxuZnVuY3Rpb24gZ2V0T0F1dGhSZWRpcmVjdFVyaSgpOiBzdHJpbmcge1xuICB0cnkge1xuICAgIGNvbnN0IHsgaGVhZGVycywgcmVxdWVzdCB9ID0gU29uYW11LmdldENvbnRleHQoKTtcbiAgICBjb25zdCBvcmlnaW4gPSBoZWFkZXJzLm9yaWdpbjtcbiAgICBpZiAodHlwZW9mIG9yaWdpbiA9PT0gXCJzdHJpbmdcIiAmJiAvXmh0dHBzPzpcXC9cXC8vLnRlc3Qob3JpZ2luKSkge1xuICAgICAgcmV0dXJuIGAke29yaWdpbi5yZXBsYWNlKC9cXC8rJC8sIFwiXCIpfS9jYWxsYmFja2A7XG4gICAgfVxuICAgIGNvbnN0IGZvcndhcmRlZEhvc3QgPSBoZWFkZXJzW1wieC1mb3J3YXJkZWQtaG9zdFwiXTtcbiAgICBjb25zdCBob3N0ID0gKEFycmF5LmlzQXJyYXkoZm9yd2FyZGVkSG9zdCkgPyBmb3J3YXJkZWRIb3N0WzBdIDogZm9yd2FyZGVkSG9zdCkgPz8gaGVhZGVycy5ob3N0O1xuICAgIGlmIChob3N0KSB7XG4gICAgICBjb25zdCBmb3J3YXJkZWRQcm90byA9IGhlYWRlcnNbXCJ4LWZvcndhcmRlZC1wcm90b1wiXTtcbiAgICAgIGNvbnN0IHByb3RvID1cbiAgICAgICAgKEFycmF5LmlzQXJyYXkoZm9yd2FyZGVkUHJvdG8pID8gZm9yd2FyZGVkUHJvdG9bMF0gOiBmb3J3YXJkZWRQcm90byk/LnNwbGl0KFwiLFwiKVswXSA/P1xuICAgICAgICByZXF1ZXN0LnByb3RvY29sO1xuICAgICAgcmV0dXJuIGAke3Byb3RvfTovLyR7aG9zdH0vY2FsbGJhY2tgO1xuICAgIH1cbiAgfSBjYXRjaCB7XG4gICAgLy8gZGlyZWN0IGZyYW1lIGNhbGwg4oCUIEhUVFAgY29udGV4dCDsl4bsnYxcbiAgfVxuICByZXR1cm4gYGh0dHA6Ly9sb2NhbGhvc3Q6JHtwcm9jZXNzLmVudi5QT1JUID8/IFwiNDQ5MDBcIn0vY2FsbGJhY2tgO1xufVxuXG5mdW5jdGlvbiByZWplY3RJbWFnZUdlbmVyYXRpb25TdHJlYW0oYXJnczogUXVlcnlJbnB1dCk6IHZvaWQge1xuICBpZiAoIWFyZ3MuaW1hZ2VHZW5lcmF0aW9uKSByZXR1cm47XG4gIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFxuICAgIFwicWdyaWQ6IGltYWdlR2VuZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIHdpdGggc3RyZWFtaW5nOyB1c2UgcXVlcnkvZ2VuZXJhdGVUZXh0IGluc3RlYWQuXCIgYXMgTG9jYWxpemVkU3RyaW5nLFxuICApO1xufVxuXG5mdW5jdGlvbiByZWplY3RJbnZhbGlkQ2FsbGVyU2NoZW1hcyhhcmdzOiBRdWVyeUlucHV0KTogdm9pZCB7XG4gIGlmIChhcmdzLmpzb25TY2hlbWEgPT09IHVuZGVmaW5lZCAmJiAhYXJncy50b29scz8ubGVuZ3RoKSByZXR1cm47XG5cbiAgdHJ5IHtcbiAgICBidWlsZEFuZFZhbGlkYXRlU3RyaWN0T3V0cHV0U2NoZW1hKGFyZ3MpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChcbiAgICAgIGVycm9yIGluc3RhbmNlb2YgQ2FsbGVyU2NoZW1hVmFsaWRhdGlvbkVycm9yIHx8XG4gICAgICBlcnJvciBpbnN0YW5jZW9mIFRvb2xTY2hlbWFDb21wb3NpdGlvbkVycm9yXG4gICAgKSB7XG4gICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihlcnJvci5tZXNzYWdlIGFzIExvY2FsaXplZFN0cmluZyk7XG4gICAgfVxuICAgIC8vIOyemOuqu+uQnCBrZXl3b3JkIO2Yle2DnChhbnlPZiDrpbwg6rCd7LK066GcIOuztOuCtOuKlCDrk7Ep64qUIO2MjOydtO2UhOudvOyduOyXkOyEnCB1bnR5cGVkIOyYpOulmOuhnCDrgpjsmKTrr4DroZwsXG4gICAgLy8g7YOA7J6FIOyige2eiOq4sCDrjIDsi6AgRXJyb3Ig7KCE7LK066W8IGNhbGxlci1mYXVsdCA0MDAg7Jy866GcIOunpO2Vke2VnOuLpCjqs4Tslb0g7YWM7Iqk7Yq466GcIOqzoOygleuQqCkuXG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIHtcbiAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFxuICAgICAgICBgcWdyaWQ6IGNhbGxlciBzY2hlbWEgY2Fubm90IGJlIG5vcm1hbGl6ZWQ6ICR7ZXJyb3IubWVzc2FnZX1gIGFzIExvY2FsaXplZFN0cmluZyxcbiAgICAgICk7XG4gICAgfVxuICAgIHRocm93IGVycm9yO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUh0dHBEaXNjb25uZWN0SGFuZGxlKCk6IHtcbiAgc2lnbmFsOiBBYm9ydFNpZ25hbDtcbiAgZGlzcG9zZTogKCkgPT4gdm9pZDtcbn0ge1xuICBjb25zdCBhYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gIGxldCByZXF1ZXN0UmF3OiBGYXN0aWZ5UmVxdWVzdFtcInJhd1wiXSB8IHVuZGVmaW5lZDtcbiAgbGV0IHJlc3BvbnNlUmF3OiBGYXN0aWZ5UmVwbHlbXCJyYXdcIl0gfCB1bmRlZmluZWQ7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBjdHggPSBTb25hbXUuZ2V0Q29udGV4dCgpO1xuICAgIHJlcXVlc3RSYXcgPSBjdHgucmVxdWVzdD8ucmF3O1xuICAgIGlmIChjdHgudHJhbnNwb3J0ID09PSBcImh0dHBcIikgcmVzcG9uc2VSYXcgPSBjdHgucmVwbHkucmF3O1xuICB9IGNhdGNoIHtcbiAgICAvLyBEaXJlY3QgZnJhbWUgY2FsbHMgKGZvciBleGFtcGxlIHVuaXQgdGVzdHMpIGRvIG5vdCBoYXZlIGFuIEhUVFAgY29udGV4dC5cbiAgfVxuXG4gIGNvbnN0IGFib3J0ID0gKCkgPT4gYWJvcnRDb250cm9sbGVyLmFib3J0KCk7XG4gIGNvbnN0IGFib3J0T25JbmNvbXBsZXRlUmVzcG9uc2VDbG9zZSA9ICgpID0+IHtcbiAgICBpZiAoIXJlc3BvbnNlUmF3Py53cml0YWJsZUVuZGVkKSBhYm9ydCgpO1xuICB9O1xuXG4gIHJlcXVlc3RSYXc/Lm9uY2UoXCJhYm9ydGVkXCIsIGFib3J0KTtcbiAgcmVzcG9uc2VSYXc/Lm9uY2UoXCJjbG9zZVwiLCBhYm9ydE9uSW5jb21wbGV0ZVJlc3BvbnNlQ2xvc2UpO1xuXG4gIGlmIChyZXF1ZXN0UmF3Py5hYm9ydGVkIHx8IChyZXNwb25zZVJhdz8uZGVzdHJveWVkICYmICFyZXNwb25zZVJhdy53cml0YWJsZUVuZGVkKSkge1xuICAgIGFib3J0KCk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHNpZ25hbDogYWJvcnRDb250cm9sbGVyLnNpZ25hbCxcbiAgICBkaXNwb3NlOiAoKSA9PiB7XG4gICAgICByZXF1ZXN0UmF3Py5yZW1vdmVMaXN0ZW5lcihcImFib3J0ZWRcIiwgYWJvcnQpO1xuICAgICAgcmVzcG9uc2VSYXc/LnJlbW92ZUxpc3RlbmVyKFwiY2xvc2VcIiwgYWJvcnRPbkluY29tcGxldGVSZXNwb25zZUNsb3NlKTtcbiAgICB9LFxuICB9O1xufVxuXG5jb25zdCBsb2dnZXIgPSBnZXRMb2dnZXIoW1wicWdyaWRcIl0pO1xuY29uc3Qgb2F1dGhMb2dnZXIgPSBnZXRMb2dnZXIoW1wicWdyaWRcIiwgXCJvYXV0aFwiXSk7XG5cbmNsYXNzIFFncmlkRnJhbWVDbGFzcyBleHRlbmRzIEJhc2VGcmFtZUNsYXNzIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoXCJRZ3JpZFwiKTtcbiAgfVxuXG4gIEBhcGkoeyBodHRwTWV0aG9kOiBcIlBPU1RcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1tdXRhdGlvblwiXSB9KVxuICBhc3luYyBxdWVyeShhcmdzOiBRdWVyeUlucHV0KTogUHJvbWlzZTxRdWVyeU91dHB1dD4ge1xuICAgIHJlamVjdEludmFsaWRDYWxsZXJTY2hlbWFzKGFyZ3MpO1xuICAgIGNvbnN0IGRpc2Nvbm5lY3QgPSBjcmVhdGVIdHRwRGlzY29ubmVjdEhhbmRsZSgpO1xuICAgIHRyeSB7XG4gICAgICBpZiAoYXJncy5sb2dnZXIgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBRZ3JpZERpc3BhdGNoZXIucXVlcnkoYXJncywgZGlzY29ubmVjdC5zaWduYWwpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IHJlcXVlc3RMb2dJZCwgc3RlcEluZGV4IH0gPSBhd2FpdCBiZWZvcmVRdWVyeShhcmdzKTtcbiAgICAgIGxldCByZXN1bHQ6IFF1ZXJ5T3V0cHV0O1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVzdWx0ID0gYXdhaXQgUWdyaWREaXNwYXRjaGVyLnF1ZXJ5KGFyZ3MsIGRpc2Nvbm5lY3Quc2lnbmFsKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKGRpc2Nvbm5lY3Quc2lnbmFsLmFib3J0ZWQpIHtcbiAgICAgICAgICBhd2FpdCBmaW5pc2hSdW5BYm9ydGVkKHJlcXVlc3RMb2dJZCwgYXJncyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYXdhaXQgZmluaXNoUnVuV2l0aEVycm9yKHJlcXVlc3RMb2dJZCwgKGUgYXMgRXJyb3IpLm1lc3NhZ2UsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGxpZmVjeWNsZSA9IGF3YWl0IGFmdGVyUXVlcnkocmVxdWVzdExvZ0lkLCBzdGVwSW5kZXgsIGFyZ3MsIHJlc3VsdCk7XG4gICAgICAgIGlmIChkaXNjb25uZWN0LnNpZ25hbC5hYm9ydGVkKSB7XG4gICAgICAgICAgYXdhaXQgZmluaXNoUnVuQWJvcnRlZChyZXF1ZXN0TG9nSWQsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHRvb2wtY2FsbCByZXF1ZXN0TG9nSWTsmYAgcHJvdmlkZXIgdGhyZWFkQ29vcmTripQg7ISc66GcIOuPheumveyggeycvOuhnCDsnKDsp4DtlZzri6QuXG4gICAgICAgIGNvbnN0IHRocmVhZENvb3JkID0gcmVzdWx0LnJ1bkNvbnRleHQ/LnRocmVhZENvb3JkO1xuICAgICAgICBjb25zdCBydW5Db250ZXh0ID1cbiAgICAgICAgICBsaWZlY3ljbGUucnVuQ29udGV4dCB8fCB0aHJlYWRDb29yZFxuICAgICAgICAgICAgPyB7IC4uLmxpZmVjeWNsZS5ydW5Db250ZXh0LCAuLi4odGhyZWFkQ29vcmQgPyB7IHRocmVhZENvb3JkIH0gOiB7fSkgfVxuICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB7IC4uLnJlc3VsdCwgcnVuQ29udGV4dCB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBsb2dnZXIuZXJyb3IoYHF1ZXJ5IGFmdGVyUXVlcnkgZmFpbGVkOiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWApO1xuICAgICAgICBpZiAoZGlzY29ubmVjdC5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgICAgIGF3YWl0IGZpbmlzaFJ1bkFib3J0ZWQocmVxdWVzdExvZ0lkLCBhcmdzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhd2FpdCBmaW5pc2hSdW5XaXRoRXJyb3IocmVxdWVzdExvZ0lkLCAoZSBhcyBFcnJvcikubWVzc2FnZSwgYXJncyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcHJvdmlkZXIg7J2R64u17J2AIOyEseqzte2WiOycvOuvgOuhnCDroZzquYUg7J6l7JWg6rCAIOyDneyEsSDqsrDqs7zrpbwg642u7Ja07JOw7KeAIOyViuuKlOuLpC5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgZGlzY29ubmVjdC5kaXNwb3NlKCk7XG4gICAgfVxuICB9XG5cbiAgQGFwaSh7IGh0dHBNZXRob2Q6IFwiUE9TVFwiLCBjbGllbnRzOiBbXCJheGlvc1wiLCBcInRhbnN0YWNrLW11dGF0aW9uXCJdIH0pXG4gIGFzeW5jIHByZXBhcmVTdHJlYW0oYXJnczogUXVlcnlJbnB1dCk6IFByb21pc2U8eyBzdHJlYW1JZDogc3RyaW5nIH0+IHtcbiAgICByZWplY3RJbWFnZUdlbmVyYXRpb25TdHJlYW0oYXJncyk7XG4gICAgcmVqZWN0SW52YWxpZENhbGxlclNjaGVtYXMoYXJncyk7XG4gICAgY29uc3Qgc3RyZWFtSWQgPSBjcnlwdG8ucmFuZG9tVVVJRCgpO1xuICAgIHBlbmRpbmdTdHJlYW1zLnNldChzdHJlYW1JZCwgYXJncyk7XG4gICAgY29uc3QgZXhwaXJ5ID0gc2V0VGltZW91dCgoKSA9PiBwZW5kaW5nU3RyZWFtcy5kZWxldGUoc3RyZWFtSWQpLCAzMF8wMDApO1xuICAgIGV4cGlyeS51bnJlZj8uKCk7XG4gICAgcmV0dXJuIHsgc3RyZWFtSWQgfTtcbiAgfVxuXG4gIEBzdHJlYW0oeyB0eXBlOiBcInNzZVwiLCBldmVudHM6IFN0cmVhbUV2ZW50cyB9KVxuICBhc3luYyBxdWVyeVN0cmVhbShzdHJlYW1JZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgYXJncyA9IHBlbmRpbmdTdHJlYW1zLmdldChzdHJlYW1JZCk7XG4gICAgcGVuZGluZ1N0cmVhbXMuZGVsZXRlKHN0cmVhbUlkKTtcbiAgICBpZiAoIWFyZ3MpIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgb3IgZXhwaXJlZCBzdHJlYW1JZFwiKTtcbiAgICByZWplY3RJbWFnZUdlbmVyYXRpb25TdHJlYW0oYXJncyk7XG5cbiAgICBjb25zdCBjdHggPSBTb25hbXUuZ2V0Q29udGV4dCgpO1xuICAgIGNvbnN0IHNzZSA9IGN0eC5jcmVhdGVTU0UoU3RyZWFtRXZlbnRzKTtcbiAgICBsZXQgdGhyZWFkSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBsZXQgdHVybklkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgbGV0IHN0cmVhbVJlc3VsdDogUXVlcnlPdXRwdXQgfCB1bmRlZmluZWQ7XG4gICAgbGV0IHN0cmVhbUVycm9yOiBFcnJvciB8IHVuZGVmaW5lZDtcbiAgICBsZXQgY2xpZW50Q2xvc2VkID0gZmFsc2U7XG4gICAgY29uc3QgYWJvcnRDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuXG4gICAgY29uc3QgaW50ZXJydXB0T3BlbkFJID0gKCkgPT4ge1xuICAgICAgaWYgKHRocmVhZElkICYmIHR1cm5JZCkge1xuICAgICAgICBRZ3JpZERpc3BhdGNoZXIub3BlbmFpRGlzcGF0Y2hlcj8uaW50ZXJydXB0V29ya2VyVHVybih0aHJlYWRJZCwgdHVybklkKS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIHNzZS5vbkNsb3NlKCgpID0+IHtcbiAgICAgIGNsaWVudENsb3NlZCA9IHRydWU7XG4gICAgICBhYm9ydENvbnRyb2xsZXIuYWJvcnQoKTtcbiAgICAgIGludGVycnVwdE9wZW5BSSgpO1xuICAgIH0pO1xuXG4gICAgbGV0IHJ1bkluZm86IHsgcmVxdWVzdExvZ0lkOiBudW1iZXI7IHN0ZXBJbmRleDogbnVtYmVyIH0gfCB1bmRlZmluZWQ7XG4gICAgaWYgKGFyZ3MubG9nZ2VyICE9PSBmYWxzZSkge1xuICAgICAgLy8gcHJvdmlkZXIg7Iuk7ZaJIOyghCBydW5uaW5nIHJvdyDsg53shLHsl5Ag7Iuk7Yyo7ZWY66m0IGxvZ2dlZCDsmpTssq3snLzroZwg7KeE7ZaJ7ZWY7KeAIOyViuuKlOuLpC5cbiAgICAgIHJ1bkluZm8gPSBhd2FpdCBiZWZvcmVRdWVyeShhcmdzKTtcbiAgICB9XG5cbiAgICAvLyBiZWZvcmVRdWVyeSBEQiDsnpHsl4Ug7KSRIGNsb3Nl66W8IOuGk+y5mOyngCDslYrqs6AgcHJvdmlkZXIg7Iuk7ZaJIOyghOyXkCDrp4jqsJDtlZzri6QuXG4gICAgaWYgKGNsaWVudENsb3NlZCB8fCBzc2UuY2xvc2VkKSB7XG4gICAgICBpZiAocnVuSW5mbykgYXdhaXQgZmluaXNoUnVuQWJvcnRlZChydW5JbmZvLnJlcXVlc3RMb2dJZCwgYXJncyk7XG4gICAgICBhd2FpdCBzc2UuZW5kKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IFFncmlkRGlzcGF0Y2hlci5xdWVyeVN0cmVhbShcbiAgICAgICAgYXJncyxcbiAgICAgICAge1xuICAgICAgICAgIG9uRGVsdGE6ICh0ZXh0KSA9PiB7XG4gICAgICAgICAgICBpZiAoIWNsaWVudENsb3NlZCAmJiAhc3NlLmNsb3NlZCkgc3NlLnB1Ymxpc2goXCJkZWx0YVwiLCB7IHRleHQgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBvblRocmVhZElkOiAoaWQpID0+IHtcbiAgICAgICAgICAgIHRocmVhZElkID0gaWQ7XG4gICAgICAgICAgICBpZiAoKGNsaWVudENsb3NlZCB8fCBzc2UuY2xvc2VkKSAmJiB0dXJuSWQpIHtcbiAgICAgICAgICAgICAgaW50ZXJydXB0T3BlbkFJKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgICBvblR1cm5JZDogKGlkKSA9PiB7XG4gICAgICAgICAgICB0dXJuSWQgPSBpZDtcbiAgICAgICAgICAgIGlmICgoY2xpZW50Q2xvc2VkIHx8IHNzZS5jbG9zZWQpICYmIHRocmVhZElkKSB7XG4gICAgICAgICAgICAgIGludGVycnVwdE9wZW5BSSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgb25Db21wbGV0ZTogKHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgc3RyZWFtUmVzdWx0ID0gcmVzdWx0O1xuICAgICAgICAgIH0sXG4gICAgICAgICAgb25FcnJvcjogKGVycikgPT4ge1xuICAgICAgICAgICAgc3RyZWFtRXJyb3IgPSBlcnI7XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgYWJvcnRDb250cm9sbGVyLnNpZ25hbCxcbiAgICAgICk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc3RyZWFtRXJyb3IgPSBlIGFzIEVycm9yO1xuICAgIH1cblxuICAgIC8vIHByb3ZpZGVyIOqysOqzvOqwgCDsl4bripQgY2xvc2XripQg7KaJ7IucIGFib3J0ZWTroZwg66eI6rCQ7ZWc64ukLlxuICAgIGlmIChjbGllbnRDbG9zZWQgJiYgIXN0cmVhbVJlc3VsdCkge1xuICAgICAgaWYgKHJ1bkluZm8pIGF3YWl0IGZpbmlzaFJ1bkFib3J0ZWQocnVuSW5mby5yZXF1ZXN0TG9nSWQsIGFyZ3MpO1xuICAgICAgYXdhaXQgc3NlLmVuZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGRpc3BhdGNoZXIg7JmE66OMIO2bhCBsaWZlY3ljbGUg7LKY66asIChhd2FpdCDslYjsoIQpXG4gICAgaWYgKHN0cmVhbVJlc3VsdCkge1xuICAgICAgLy8gZGlzcGF0Y2hlciDqsIAg7Iuk7J2AIHRocmVhZCDsnqzsgqzsmqkg7KKM7ZGc64qUIGxvZ2dlciDshKTsoJXqs7wg66y06rSA7ZWY6rKMIO2ajOyGoe2VnOuLpC5cbiAgICAgIGNvbnN0IHRocmVhZENvb3JkID0gc3RyZWFtUmVzdWx0LnJ1bkNvbnRleHQ/LnRocmVhZENvb3JkO1xuICAgICAgbGV0IHJ1bkNvbnRleHQ6IFFncmlkUnVuQ29udGV4dCB8IHVuZGVmaW5lZCA9XG4gICAgICAgIHRocmVhZENvb3JkICE9PSB1bmRlZmluZWQgPyB7IHRocmVhZENvb3JkIH0gOiB1bmRlZmluZWQ7XG4gICAgICBpZiAocnVuSW5mbykge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIGNsb3NlIO2bhCDrj4TssKntlZwg6rKw6rO864+EIHN0ZXAvdXNhZ2XripQg64Ko6riw65CYLCDslYTrnpjsl5DshJwg7LWc7KKFIHN0YXR1c+ulvCBhYm9ydGVk66GcIOuNruyWtOyTtOuLpC5cbiAgICAgICAgICBjb25zdCBsaWZlY3ljbGUgPSBhd2FpdCBhZnRlclF1ZXJ5KFxuICAgICAgICAgICAgcnVuSW5mby5yZXF1ZXN0TG9nSWQsXG4gICAgICAgICAgICBydW5JbmZvLnN0ZXBJbmRleCxcbiAgICAgICAgICAgIGFyZ3MsXG4gICAgICAgICAgICBzdHJlYW1SZXN1bHQsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBydW5Db250ZXh0ID1cbiAgICAgICAgICAgIGxpZmVjeWNsZS5ydW5Db250ZXh0IHx8IHRocmVhZENvb3JkXG4gICAgICAgICAgICAgID8geyAuLi5saWZlY3ljbGUucnVuQ29udGV4dCwgLi4uKHRocmVhZENvb3JkID8geyB0aHJlYWRDb29yZCB9IDoge30pIH1cbiAgICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgICAvLyBhZnRlclF1ZXJ56rCAIOynhO2WieuQmOuKlCDsgqzsnbQgY2xpZW506rCAIOuLq+2ejCDqsr3smrAg7JmE66OMIOyDge2DnOulvCBhYm9ydGVk66GcIOuQmOuPjOumsOuLpC5cbiAgICAgICAgICBpZiAoY2xpZW50Q2xvc2VkKSB7XG4gICAgICAgICAgICBhd2FpdCBmaW5pc2hSdW5BYm9ydGVkKHJ1bkluZm8ucmVxdWVzdExvZ0lkLCBhcmdzKTtcbiAgICAgICAgICAgIGF3YWl0IHNzZS5lbmQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBsb2dnZXIuZXJyb3IoYHN0cmVhbSBhZnRlclF1ZXJ5IGZhaWxlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgICBhd2FpdCBmaW5pc2hSdW5XaXRoRXJyb3IocnVuSW5mby5yZXF1ZXN0TG9nSWQsIChlIGFzIEVycm9yKS5tZXNzYWdlLCBhcmdzKTtcblxuICAgICAgICAgIGlmIChjbGllbnRDbG9zZWQpIHtcbiAgICAgICAgICAgIGF3YWl0IGZpbmlzaFJ1bkFib3J0ZWQocnVuSW5mby5yZXF1ZXN0TG9nSWQsIGFyZ3MpO1xuICAgICAgICAgICAgYXdhaXQgc3NlLmVuZCgpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKCFjbGllbnRDbG9zZWQgJiYgIXNzZS5jbG9zZWQpIHNzZS5wdWJsaXNoKFwiZG9uZVwiLCB7IC4uLnN0cmVhbVJlc3VsdCwgcnVuQ29udGV4dCB9KTtcbiAgICB9IGVsc2UgaWYgKHN0cmVhbUVycm9yKSB7XG4gICAgICBpZiAocnVuSW5mbykgYXdhaXQgZmluaXNoUnVuV2l0aEVycm9yKHJ1bkluZm8ucmVxdWVzdExvZ0lkLCBzdHJlYW1FcnJvci5tZXNzYWdlLCBhcmdzKTtcbiAgICAgIGlmICghY2xpZW50Q2xvc2VkICYmICFzc2UuY2xvc2VkKSBzc2UucHVibGlzaChcImVycm9yXCIsIHsgbWVzc2FnZTogc3RyZWFtRXJyb3IubWVzc2FnZSB9KTtcbiAgICB9IGVsc2UgaWYgKChjbGllbnRDbG9zZWQgfHwgc3NlLmNsb3NlZCkgJiYgcnVuSW5mbykge1xuICAgICAgYXdhaXQgZmluaXNoUnVuQWJvcnRlZChydW5JbmZvLnJlcXVlc3RMb2dJZCwgYXJncyk7XG4gICAgfVxuXG4gICAgYXdhaXQgc3NlLmVuZCgpO1xuICB9XG5cbiAgQGFwaSh7IGh0dHBNZXRob2Q6IFwiUE9TVFwiLCBjbGllbnRzOiBbXCJheGlvc1wiLCBcInRhbnN0YWNrLW11dGF0aW9uXCJdIH0pXG4gIGFzeW5jIGNyZWF0ZVJ1bihpbnB1dDogQ3JlYXRlUnVuSW5wdXQpOiBQcm9taXNlPHsgcmVxdWVzdExvZ0lkOiBudW1iZXIgfT4ge1xuICAgIGNvbnN0IHJlcXVlc3RMb2dJZCA9IGF3YWl0IFJlcXVlc3RMb2dNb2RlbC5jcmVhdGVSdW4oe1xuICAgICAgdXNlcl9wcm9tcHQ6IGlucHV0LnVzZXJQcm9tcHQsXG4gICAgICByZXF1ZXN0ZWRfbW9kZWxfbmFtZTogaW5wdXQubW9kZWxOYW1lLFxuICAgICAgZWZmb3J0OiBpbnB1dC5lZmZvcnQsXG4gICAgICBwcm9qZWN0X25hbWU6IGlucHV0LnByb2plY3ROYW1lLFxuICAgICAgc3lzdGVtX3Byb21wdDogaW5wdXQuc3lzdGVtUHJvbXB0LFxuICAgICAgaGlzdG9yeTogaW5wdXQuaGlzdG9yeSA/IEpTT04ucGFyc2UoaW5wdXQuaGlzdG9yeSkgOiB1bmRlZmluZWQsXG4gICAgfSk7XG4gICAgcmV0dXJuIHsgcmVxdWVzdExvZ0lkIH07XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJQT1NUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stbXV0YXRpb25cIl0gfSlcbiAgYXN5bmMgYXBwZW5kU3RlcChpbnB1dDogQXBwZW5kU3RlcElucHV0KTogUHJvbWlzZTx7IHN0ZXBJZDogbnVtYmVyIH0+IHtcbiAgICBjb25zdCBzdGVwSWQgPSBhd2FpdCBSZXF1ZXN0TG9nTW9kZWwuYXBwZW5kU3RlcChpbnB1dC5yZXF1ZXN0TG9nSWQsIHtcbiAgICAgIHN0ZXBfaW5kZXg6IGlucHV0LnN0ZXBJbmRleCxcbiAgICAgIHR5cGU6IGlucHV0LnR5cGUsXG4gICAgICBtb2RlbF9uYW1lOiBpbnB1dC5tb2RlbE5hbWUsXG4gICAgICByZXF1ZXN0ZWRfbW9kZWxfbmFtZTogaW5wdXQucmVxdWVzdGVkTW9kZWxOYW1lLFxuICAgICAgZmFsbGJhY2tfY291bnQ6IGlucHV0LmZhbGxiYWNrQ291bnQsXG4gICAgICBpbnB1dF90b2tlbnM6IGlucHV0LmlucHV0VG9rZW5zLFxuICAgICAgb3V0cHV0X3Rva2VuczogaW5wdXQub3V0cHV0VG9rZW5zLFxuICAgICAgY2FjaGVfcmVhZF90b2tlbnM6IGlucHV0LmNhY2hlUmVhZFRva2VucyxcbiAgICAgIGNhY2hlX2NyZWF0aW9uX3Rva2VuczogaW5wdXQuY2FjaGVDcmVhdGlvblRva2VucyxcbiAgICAgIGNhY2hlX2NyZWF0aW9uXzVtX3Rva2VuczogaW5wdXQuY2FjaGVDcmVhdGlvbjVtVG9rZW5zLFxuICAgICAgY2FjaGVfY3JlYXRpb25fMWhfdG9rZW5zOiBpbnB1dC5jYWNoZUNyZWF0aW9uMWhUb2tlbnMsXG4gICAgICBjb3N0X3VzZDogaW5wdXQuY29zdFVzZCA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogTWF0aC5yb3VuZChpbnB1dC5jb3N0VXNkICogTUlDUk9fVVNEKSxcbiAgICAgIGNvc3Rfc291cmNlOiBpbnB1dC5jb3N0U291cmNlLFxuICAgICAgZHVyYXRpb25fbXM6IGlucHV0LmR1cmF0aW9uTXMsXG4gICAgICB0dGZ0X21zOiBpbnB1dC50dGZ0TXMgPz8gbnVsbCxcbiAgICAgIGZpbmlzaF9yZWFzb246IGlucHV0LmZpbmlzaFJlYXNvbixcbiAgICAgIHJlYXNvbmluZ190ZXh0OiBpbnB1dC5yZWFzb25pbmdUZXh0LFxuICAgICAgcmVhc29uaW5nX3Rva2VuczogaW5wdXQucmVhc29uaW5nVG9rZW5zLFxuICAgICAgdG9vbF9jYWxsX2luZGV4OiBpbnB1dC50b29sQ2FsbEluZGV4LFxuICAgICAgdG9vbF9jYWxsX2lkOiBpbnB1dC50b29sQ2FsbElkLFxuICAgICAgdG9vbF9uYW1lOiBpbnB1dC50b29sTmFtZSxcbiAgICAgIHRvb2xfYXJnczogaW5wdXQudG9vbEFyZ3MsXG4gICAgICB0b29sX3Jlc3VsdDogaW5wdXQudG9vbFJlc3VsdCxcbiAgICAgIHRvb2xfZHVyYXRpb25fbXM6IGlucHV0LnRvb2xEdXJhdGlvbk1zLFxuICAgICAgZXJyb3I6IGlucHV0LmVycm9yLFxuICAgIH0pO1xuICAgIHJldHVybiB7IHN0ZXBJZCB9O1xuICB9XG5cbiAgQGFwaSh7IGh0dHBNZXRob2Q6IFwiUE9TVFwiLCBjbGllbnRzOiBbXCJheGlvc1wiLCBcInRhbnN0YWNrLW11dGF0aW9uXCJdIH0pXG4gIGFzeW5jIGZpbmlzaFJ1bihpbnB1dDogRmluaXNoUnVuSW5wdXQpOiBQcm9taXNlPHsgb2s6IGJvb2xlYW4gfT4ge1xuICAgIGF3YWl0IFJlcXVlc3RMb2dNb2RlbC5maW5pc2hSdW4oaW5wdXQucmVxdWVzdExvZ0lkLCB7XG4gICAgICBzdGF0dXM6IGlucHV0LnN0YXR1cyxcbiAgICAgIHJlc3BvbnNlOiBpbnB1dC5yZXNwb25zZSxcbiAgICAgIHRva2VuX25hbWU6IGlucHV0LnRva2VuTmFtZSxcbiAgICAgIG1vZGVsX25hbWU6IGlucHV0Lm1vZGVsTmFtZSxcbiAgICAgIHJlcXVlc3RlZF9tb2RlbF9uYW1lOiBpbnB1dC5yZXF1ZXN0ZWRNb2RlbE5hbWUsXG4gICAgICBmYWxsYmFja19jb3VudDogaW5wdXQuZmFsbGJhY2tDb3VudCxcbiAgICAgIGlucHV0X3Rva2VuczogaW5wdXQudG90YWxJbnB1dFRva2VucyxcbiAgICAgIG91dHB1dF90b2tlbnM6IGlucHV0LnRvdGFsT3V0cHV0VG9rZW5zLFxuICAgICAgY2FjaGVfcmVhZF90b2tlbnM6IGlucHV0LnRvdGFsQ2FjaGVSZWFkVG9rZW5zLFxuICAgICAgY2FjaGVfY3JlYXRpb25fdG9rZW5zOiBpbnB1dC50b3RhbENhY2hlQ3JlYXRpb25Ub2tlbnMsXG4gICAgICBjYWNoZV9jcmVhdGlvbl81bV90b2tlbnM6IGlucHV0LnRvdGFsQ2FjaGVDcmVhdGlvbjVtVG9rZW5zLFxuICAgICAgY2FjaGVfY3JlYXRpb25fMWhfdG9rZW5zOiBpbnB1dC50b3RhbENhY2hlQ3JlYXRpb24xaFRva2VucyxcbiAgICAgIGNvc3RfdXNkOiBpbnB1dC5jb3N0VXNkID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBNYXRoLnJvdW5kKGlucHV0LmNvc3RVc2QgKiBNSUNST19VU0QpLFxuICAgICAgY29zdF9zb3VyY2U6IGlucHV0LmNvc3RTb3VyY2UsXG4gICAgICBkdXJhdGlvbl9tczogaW5wdXQudG90YWxEdXJhdGlvbk1zLFxuICAgICAgaGlzdG9yeTogaW5wdXQuaGlzdG9yeSA/IEpTT04ucGFyc2UoaW5wdXQuaGlzdG9yeSkgOiB1bmRlZmluZWQsXG4gICAgICBlcnJvcl9tZXNzYWdlOiBpbnB1dC5lcnJvck1lc3NhZ2UsXG4gICAgfSk7XG4gICAgcmV0dXJuIHsgb2s6IHRydWUgfTtcbiAgfVxuXG4gIEBhcGkoeyBodHRwTWV0aG9kOiBcIkdFVFwiLCBjbGllbnRzOiBbXCJheGlvc1wiLCBcInRhbnN0YWNrLXF1ZXJ5XCJdIH0pXG4gIGFzeW5jIHN0YXRzKCk6IFByb21pc2U8VG9rZW5TdGF0c1tdPiB7XG4gICAgcmV0dXJuIFFncmlkRGlzcGF0Y2hlci5nZXRTdGF0cygpO1xuICB9XG5cbiAgQGFwaSh7IGh0dHBNZXRob2Q6IFwiR0VUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stcXVlcnlcIl0gfSlcbiAgYXN5bmMgdG90YWxDb3N0KHRva2VuTmFtZT86IHN0cmluZyk6IFByb21pc2U8eyB1c2Q6IG51bWJlciB9PiB7XG4gICAgcmV0dXJuIHsgdXNkOiBhd2FpdCBSZXF1ZXN0TG9nTW9kZWwudG90YWxDb3N0KHsgdG9rZW5fbmFtZTogdG9rZW5OYW1lIH0pIH07XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJHRVRcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1xdWVyeVwiXSB9KVxuICBhc3luYyBwcm9qZWN0TmFtZXMoKTogUHJvbWlzZTx7IG5hbWVzOiBzdHJpbmdbXSB9PiB7XG4gICAgcmV0dXJuIHsgbmFtZXM6IGF3YWl0IFJlcXVlc3RMb2dNb2RlbC5kaXN0aW5jdFByb2plY3ROYW1lcygpIH07XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJQT1NUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stbXV0YXRpb25cIl0gfSlcbiAgYXN5bmMgYWRkVG9rZW4oXG4gICAgcHJvdmlkZXI6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogVG9rZW5DcmVkZW50aWFscyxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICk6IFByb21pc2U8eyBhZGRlZDogYm9vbGVhbiB9PiB7XG4gICAgYXdhaXQgVG9rZW5Nb2RlbC5zYXZlKFtcbiAgICAgIHtcbiAgICAgICAgcHJvdmlkZXIsXG4gICAgICAgIGNyZWRlbnRpYWxzLFxuICAgICAgICBuYW1lLFxuICAgICAgfSxcbiAgICBdKTtcbiAgICByZXR1cm4geyBhZGRlZDogdHJ1ZSB9O1xuICB9XG5cbiAgQGFwaSh7IGh0dHBNZXRob2Q6IFwiUE9TVFwiLCBjbGllbnRzOiBbXCJheGlvc1wiXSB9KVxuICBhc3luYyB1cGRhdGVUb2tlbihcbiAgICBpZDogbnVtYmVyLFxuICAgIG5hbWU/OiBzdHJpbmcsXG4gICAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsLFxuICAgIHdlaWdodD86IG51bWJlcixcbiAgKTogUHJvbWlzZTx7IHVwZGF0ZWQ6IGJvb2xlYW4gfT4ge1xuICAgIGlmIChcbiAgICAgIHF1b3RhVGhyZXNob2xkICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIHF1b3RhVGhyZXNob2xkICE9PSBudWxsICYmXG4gICAgICAoIU51bWJlci5pc0ludGVnZXIocXVvdGFUaHJlc2hvbGQpIHx8IHF1b3RhVGhyZXNob2xkIDwgMSB8fCBxdW90YVRocmVzaG9sZCA+IDEwMClcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFxuICAgICAgICBcInF1b3RhVGhyZXNob2xkIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kIDEwMCwgb3IgbnVsbFwiIGFzIExvY2FsaXplZFN0cmluZyxcbiAgICAgICk7XG4gICAgfVxuICAgIGlmICh3ZWlnaHQgIT09IHVuZGVmaW5lZCAmJiAoIU51bWJlci5pc0ludGVnZXIod2VpZ2h0KSB8fCB3ZWlnaHQgPCAxIHx8IHdlaWdodCA+IDEwMCkpIHtcbiAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFxuICAgICAgICBcIndlaWdodCBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAxIGFuZCAxMDBcIiBhcyBMb2NhbGl6ZWRTdHJpbmcsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHBhdGNoOiBUb2tlblVwZGF0ZUZpZWxkcyA9IHt9O1xuICAgIGlmIChuYW1lICE9PSB1bmRlZmluZWQpIHBhdGNoLm5hbWUgPSBuYW1lO1xuICAgIGlmIChxdW90YVRocmVzaG9sZCAhPT0gdW5kZWZpbmVkKSBwYXRjaC5xdW90YV90aHJlc2hvbGQgPSBxdW90YVRocmVzaG9sZDtcbiAgICBpZiAod2VpZ2h0ICE9PSB1bmRlZmluZWQpIHBhdGNoLndlaWdodCA9IHdlaWdodDtcbiAgICBpZiAoT2JqZWN0LmtleXMocGF0Y2gpLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHsgdXBkYXRlZDogZmFsc2UgfTtcblxuICAgIGNvbnN0IHVwZGF0ZWQgPSBhd2FpdCBUb2tlbk1vZGVsLnVwZGF0ZUZpZWxkcyhpZCwgcGF0Y2gpO1xuICAgIHJldHVybiB7IHVwZGF0ZWQ6IHVwZGF0ZWQgPiAwIH07XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJQT1NUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stbXV0YXRpb25cIl0gfSlcbiAgYXN5bmMgcmVtb3ZlVG9rZW4oaWQ6IG51bWJlcik6IFByb21pc2U8eyByZW1vdmVkOiBib29sZWFuIH0+IHtcbiAgICBjb25zdCBlbnRyeSA9IGF3YWl0IFRva2VuTW9kZWwuZmluZE9uZShcIkFcIiwgeyBpZCB9KTtcbiAgICBpZiAoIWVudHJ5KSByZXR1cm4geyByZW1vdmVkOiBmYWxzZSB9O1xuICAgIGF3YWl0IFRva2VuTW9kZWwuZGVsKFtlbnRyeS5pZF0pO1xuICAgIHJldHVybiB7IHJlbW92ZWQ6IHRydWUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDthqDtgbAg7Zmc7ISx7ZmUL+u5hO2ZnOyEse2ZlCDthqDquIAgRELsnZggYWN0aXZlIO2VhOuTnCDsl4XrjbDsnbTtirhcbiAgICovXG4gIEBhcGkoeyBodHRwTWV0aG9kOiBcIlBPU1RcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1tdXRhdGlvblwiXSB9KVxuICBhc3luYyB0b2dnbGVUb2tlbihpZDogbnVtYmVyKTogUHJvbWlzZTx7IGFjdGl2ZTogYm9vbGVhbiB9PiB7XG4gICAgY29uc3QgZW50cnkgPSBhd2FpdCBUb2tlbk1vZGVsLmZpbmRPbmUoXCJBXCIsIHsgaWQgfSk7XG4gICAgaWYgKCFlbnRyeSkgcmV0dXJuIHsgYWN0aXZlOiBmYWxzZSB9O1xuXG4gICAgY29uc3QgbmV3QWN0aXZlID0gIWVudHJ5LmFjdGl2ZTtcbiAgICBhd2FpdCBUb2tlbk1vZGVsLnNhdmUoW1xuICAgICAge1xuICAgICAgICBpZCxcbiAgICAgICAgcHJvdmlkZXI6IGVudHJ5LnByb3ZpZGVyLFxuICAgICAgICBjcmVkZW50aWFsczogZW50cnkuY3JlZGVudGlhbHMsXG4gICAgICAgIGFjdGl2ZTogbmV3QWN0aXZlLFxuICAgICAgICBuYW1lOiBlbnRyeS5uYW1lLFxuICAgICAgfSxcbiAgICBdKTtcbiAgICByZXR1cm4geyBhY3RpdmU6IG5ld0FjdGl2ZSB9O1xuICB9XG5cbiAgQGFwaSh7IGh0dHBNZXRob2Q6IFwiUE9TVFwiLCBjbGllbnRzOiBbXCJheGlvc1wiLCBcInRhbnN0YWNrLW11dGF0aW9uXCJdIH0pXG4gIGFzeW5jIG9hdXRoU3RhcnQobmFtZTogc3RyaW5nKTogUHJvbWlzZTxPQXV0aFN0YXJ0UmVzdWx0PiB7XG4gICAgY29uc3QgeyBjb2RlVmVyaWZpZXIsIGNvZGVDaGFsbGVuZ2UsIHN0YXRlIH0gPSBnZW5lcmF0ZVBLQ0UoKTtcblxuICAgIGNvbnN0IHJlZGlyZWN0VXJpID0gZ2V0T0F1dGhSZWRpcmVjdFVyaSgpO1xuICAgIGNvbnN0IGF1dGhVcmwgPSBidWlsZEF1dGhVcmwoY29kZUNoYWxsZW5nZSwgc3RhdGUsIHJlZGlyZWN0VXJpKTtcblxuICAgIGF3YWl0IHNldE9BdXRoU3RhdGUoc3RhdGUsIHsgY29kZVZlcmlmaWVyLCBuYW1lLCByZWRpcmVjdFVyaSB9KTtcblxuICAgIHJldHVybiB7IGF1dGhVcmwgfTtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZU9BdXRoQ2FsbGJhY2soY29kZTogc3RyaW5nLCBzdGF0ZTogc3RyaW5nLCByZXBseTogRmFzdGlmeVJlcGx5KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcGVuZGluZyA9IGF3YWl0IGdldE9BdXRoU3RhdGUoc3RhdGUpO1xuICAgIGlmICghcGVuZGluZykge1xuICAgICAgbG9nZ2VyLndhcm4oXCJvYXV0aCBjYWxsYmFjazogaW52YWxpZF9zdGF0ZVwiKTtcbiAgICAgIHJldHVybiByZXBseS5yZWRpcmVjdChcIi8/b2F1dGg9ZXJyb3ImcmVhc29uPWludmFsaWRfc3RhdGVcIik7XG4gICAgfVxuICAgIGF3YWl0IGRlbGV0ZU9BdXRoU3RhdGUoc3RhdGUpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRva2VucyA9IGF3YWl0IGV4Y2hhbmdlQ29kZUZvclRva2VucyhcbiAgICAgICAgY29kZSxcbiAgICAgICAgcGVuZGluZy5jb2RlVmVyaWZpZXIsXG4gICAgICAgIHN0YXRlLFxuICAgICAgICBwZW5kaW5nLnJlZGlyZWN0VXJpLFxuICAgICAgKTtcblxuICAgICAgaWYgKHRva2Vucy5hY2NvdW50VXVpZCkge1xuICAgICAgICBjb25zdCBvbGRFbnRyaWVzID0gYXdhaXQgVG9rZW5Nb2RlbC5maW5kQnlBY2NvdW50SWRlbnRpZmllcihcbiAgICAgICAgICBcIkFcIixcbiAgICAgICAgICBcImFudGhyb3BpY1wiLFxuICAgICAgICAgIHRva2Vucy5hY2NvdW50VXVpZCxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKG9sZEVudHJpZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGF3YWl0IFRva2VuTW9kZWwuZGVsKG9sZEVudHJpZXMubWFwKChvKSA9PiBvLmlkKSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgYXdhaXQgVG9rZW5Nb2RlbC5zYXZlKFtcbiAgICAgICAge1xuICAgICAgICAgIHByb3ZpZGVyOiBcImFudGhyb3BpY1wiLFxuICAgICAgICAgIGNyZWRlbnRpYWxzOiB7XG4gICAgICAgICAgICBhY2Nlc3NUb2tlbjogdG9rZW5zLmFjY2Vzc1Rva2VuLFxuICAgICAgICAgICAgcmVmcmVzaFRva2VuOiB0b2tlbnMucmVmcmVzaFRva2VuLFxuICAgICAgICAgICAgZXhwaXJlc0F0OiB0b2tlbnMuZXhwaXJlc0F0ID8/IDAsXG4gICAgICAgICAgICBhY2NvdW50VXVpZDogdG9rZW5zLmFjY291bnRVdWlkID8/IFwiXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICBuYW1lOiBwZW5kaW5nLm5hbWUsXG4gICAgICAgIH0sXG4gICAgICBdKTtcblxuICAgICAgcmV0dXJuIHJlcGx5LnJlZGlyZWN0KGAvP29hdXRoPXN1Y2Nlc3MmbmFtZT0ke2VuY29kZVVSSUNvbXBvbmVudChwZW5kaW5nLm5hbWUpfWApO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHJldHVybiByZXBseS5yZWRpcmVjdChgLz9vYXV0aD1lcnJvciZyZWFzb249JHtlbmNvZGVVUklDb21wb25lbnQoKGUgYXMgRXJyb3IpLm1lc3NhZ2UpfWApO1xuICAgIH1cbiAgfVxuXG4gIEBhcGkoeyBodHRwTWV0aG9kOiBcIlBPU1RcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1tdXRhdGlvblwiXSB9KVxuICBhc3luYyBvYXV0aFN0YXJ0T3BlbkFJKG5hbWU6IHN0cmluZyk6IFByb21pc2U8T0F1dGhTdGFydFJlc3VsdD4ge1xuICAgIGlmICghUWdyaWREaXNwYXRjaGVyLm9wZW5haURpc3BhdGNoZXIpIHRocm93IG5ldyBFcnJvcihcIk9wZW5BSSBkaXNwYXRjaGVyIG5vdCBpbml0aWFsaXplZFwiKTtcbiAgICBjb25zdCB7IGF1dGhVcmwgfSA9IGF3YWl0IFFncmlkRGlzcGF0Y2hlci5vcGVuYWlEaXNwYXRjaGVyLnN0YXJ0QnJvd3NlckxvZ2luKG5hbWUpO1xuXG4gICAgLy8gZmlyZS1hbmQtZm9yZ2V0OiBjb2RleCBsb2dpbiDsmYTro4wg64yA6riwIOKGkiDthqDtgbAg7KCA7J6lXG4gICAgUWdyaWREaXNwYXRjaGVyLm9wZW5haURpc3BhdGNoZXJcbiAgICAgIC5jb21wbGV0ZUJyb3dzZXJMb2dpbigpXG4gICAgICAudGhlbihhc3luYyAoY3JlZHMpID0+IHtcbiAgICAgICAgaWYgKGNyZWRzLmFjY291bnRJZCkge1xuICAgICAgICAgIGNvbnN0IG9sZEVudHJpZXMgPSBhd2FpdCBUb2tlbk1vZGVsLmZpbmRCeUFjY291bnRJZGVudGlmaWVyKFxuICAgICAgICAgICAgXCJBXCIsXG4gICAgICAgICAgICBcIm9wZW5haVwiLFxuICAgICAgICAgICAgY3JlZHMuYWNjb3VudElkLFxuICAgICAgICAgICk7XG4gICAgICAgICAgaWYgKG9sZEVudHJpZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgYXdhaXQgVG9rZW5Nb2RlbC5kZWwob2xkRW50cmllcy5tYXAoKG8pID0+IG8uaWQpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgVG9rZW5Nb2RlbC5zYXZlKFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBwcm92aWRlcjogXCJvcGVuYWlcIixcbiAgICAgICAgICAgIGNyZWRlbnRpYWxzOiB7XG4gICAgICAgICAgICAgIGFjY2Vzc1Rva2VuOiBjcmVkcy5hY2Nlc3NUb2tlbixcbiAgICAgICAgICAgICAgcmVmcmVzaFRva2VuOiBjcmVkcy5yZWZyZXNoVG9rZW4sXG4gICAgICAgICAgICAgIGlkVG9rZW46IGNyZWRzLmlkVG9rZW4sXG4gICAgICAgICAgICAgIGFjY2Vzc1Rva2VuRXhwaXJlc0F0OiBEYXRlLm5vdygpICsgMTAgKiAyNCAqIDM2MDAgKiAxMDAwLFxuICAgICAgICAgICAgICBhY2NvdW50SWQ6IGNyZWRzLmFjY291bnRJZCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBuYW1lLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0pO1xuICAgICAgICBsb2dnZXIuaW5mbyhgT3BlbkFJIHRva2VuIHNhdmVkIGZvciAke25hbWV9YCk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKChlKSA9PiB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBPcGVuQUkgYnJvd3NlciBsb2dpbiBmYWlsZWQ6ICR7KGUgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG4gICAgICB9KTtcblxuICAgIHJldHVybiB7IGF1dGhVcmwgfTtcbiAgfVxuXG4gIEBhcGkoeyBodHRwTWV0aG9kOiBcIkdFVFwiLCBjbGllbnRzOiBbXCJheGlvc1wiLCBcInRhbnN0YWNrLXF1ZXJ5XCJdIH0pXG4gIGFzeW5jIHVzYWdlKHRva2VuSWQ/OiBudW1iZXIpOiBQcm9taXNlPFVzYWdlUmVzcG9uc2U+IHtcbiAgICBjb25zdCB7IHJvd3M6IGFsbFRva2VucyB9ID0gYXdhaXQgVG9rZW5Nb2RlbC5maW5kTWFueShcIkFcIik7XG4gICAgY29uc3QgZW50cnkgPSB0b2tlbklkXG4gICAgICA/IGFsbFRva2Vucy5maW5kKChlKSA9PiBlLmlkID09PSB0b2tlbklkKVxuICAgICAgOiBhbGxUb2tlbnMuZmluZExhc3QoKGUpID0+IGUuYWN0aXZlICYmIGUucHJvdmlkZXIgPT09IFwiYW50aHJvcGljXCIpO1xuXG4gICAgaWYgKCFlbnRyeSkgcmV0dXJuIHsgZXJyb3I6IFwiTk9UX0ZPVU5EXCIgfTtcblxuICAgIGlmIChlbnRyeS5wcm92aWRlciA9PT0gXCJvcGVuYWlcIikge1xuICAgICAgaWYgKCFlbnRyeS5hY3RpdmUpIHtcbiAgICAgICAgcmV0dXJuIHsgcHJvdmlkZXI6IFwib3BlbmFpXCIsIGZpdmVIb3VyOiBudWxsLCBzZXZlbkRheTogbnVsbCB9O1xuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByYXcgPSBhd2FpdCBRZ3JpZERpc3BhdGNoZXIub3BlbmFpRGlzcGF0Y2hlcj8uZ2V0UmF0ZUxpbWl0c0J5VG9rZW5JZChlbnRyeS5pZCk7XG4gICAgICAgIGNvbnN0IHJsID0gcmF3Py5kYXRhLnJhdGVMaW1pdHM7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgcHJvdmlkZXI6IFwib3BlbmFpXCIsXG4gICAgICAgICAgZml2ZUhvdXI6IHJsPy5wcmltYXJ5XG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICB1dGlsaXphdGlvbjogcmwucHJpbWFyeS51c2VkUGVyY2VudCxcbiAgICAgICAgICAgICAgICByZXNldHNBdDogdW5peFNlY29uZHNUb0lzbyhybC5wcmltYXJ5LnJlc2V0c0F0KSxcbiAgICAgICAgICAgICAgICB3aW5kb3dEdXJhdGlvbk1pbnM6IHJsLnByaW1hcnkud2luZG93RHVyYXRpb25NaW5zLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IG51bGwsXG4gICAgICAgICAgc2V2ZW5EYXk6IHJsPy5zZWNvbmRhcnlcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIHV0aWxpemF0aW9uOiBybC5zZWNvbmRhcnkudXNlZFBlcmNlbnQsXG4gICAgICAgICAgICAgICAgcmVzZXRzQXQ6IHVuaXhTZWNvbmRzVG9Jc28ocmwuc2Vjb25kYXJ5LnJlc2V0c0F0KSxcbiAgICAgICAgICAgICAgICB3aW5kb3dEdXJhdGlvbk1pbnM6IHJsLnNlY29uZGFyeS53aW5kb3dEdXJhdGlvbk1pbnMsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDogbnVsbCxcbiAgICAgICAgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIHsgZXJyb3I6IGBPcGVuQUkgdXNhZ2UgZmFpbGVkOiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZW50cnkucHJvdmlkZXIgIT09IFwiYW50aHJvcGljXCIpIHtcbiAgICAgIHJldHVybiB7IGVycm9yOiBgdXNhZ2UgQVBJIG5vdCBzdXBwb3J0ZWQgZm9yIHByb3ZpZGVyOiAke2VudHJ5LnByb3ZpZGVyfWAgfTtcbiAgICB9XG5cbiAgICBsZXQgYWNjZXNzVG9rZW4gPSBnZXRBY2Nlc3NUb2tlbihlbnRyeS5jcmVkZW50aWFscyk7XG4gICAgY29uc3QgaXNFeHBpcmVkID0gZ2V0RXhwaXJlc0F0KGVudHJ5LmNyZWRlbnRpYWxzKSA8IERhdGUubm93KCk7XG5cbiAgICBpZiAoaXNFeHBpcmVkICYmIGdldFJlZnJlc2hUb2tlbihlbnRyeS5jcmVkZW50aWFscykpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGFjY2Vzc1Rva2VuID0gYXdhaXQgdGhpcy5yZWZyZXNoVG9rZW4oZW50cnkpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBvYXV0aExvZ2dlci53YXJuKGByZWZyZXNoIGZhaWxlZCBmb3IgJHtlbnRyeS5uYW1lfTogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgcmV0dXJuIHsgZXJyb3I6IFwicmUtbG9naW4gcmVxdWlyZWRcIiB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHJhdyA9IGF3YWl0IGZldGNoVXNhZ2UoYWNjZXNzVG9rZW4pO1xuICAgIGlmIChyYXcuZXJyb3IgJiYgZ2V0UmVmcmVzaFRva2VuKGVudHJ5LmNyZWRlbnRpYWxzKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYWNjZXNzVG9rZW4gPSBhd2FpdCB0aGlzLnJlZnJlc2hUb2tlbihlbnRyeSk7XG4gICAgICAgIGNvbnN0IHJldHJpZWQgPSBhd2FpdCBmZXRjaFVzYWdlKGFjY2Vzc1Rva2VuKTtcbiAgICAgICAgaWYgKHJldHJpZWQuZXJyb3IpIHJldHVybiB7IGVycm9yOiByZXRyaWVkLmVycm9yIH07XG4gICAgICAgIHJldHVybiBjb252ZXJ0QW50aHJvcGljVXNhZ2UocmV0cmllZCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIG9hdXRoTG9nZ2VyLndhcm4oYHJlZnJlc2ggZmFpbGVkIGZvciAke2VudHJ5Lm5hbWV9OiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWApO1xuICAgICAgICByZXR1cm4geyBlcnJvcjogXCJyZS1sb2dpbiByZXF1aXJlZFwiIH07XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChyYXcuZXJyb3IpIHJldHVybiB7IGVycm9yOiByYXcuZXJyb3IgfTtcbiAgICByZXR1cm4gY29udmVydEFudGhyb3BpY1VzYWdlKHJhdyk7XG4gIH1cblxuICBhc3luYyByZWZyZXNoVG9rZW4odG9rZW46IFRva2VuU3Vic2V0QSk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgY3JlZHMgPSB0b2tlbi5jcmVkZW50aWFscztcbiAgICBjb25zdCBydCA9IGdldFJlZnJlc2hUb2tlbihjcmVkcyk7XG4gICAgaWYgKCFydCkgdGhyb3cgbmV3IEVycm9yKFwiTm8gcmVmcmVzaCB0b2tlblwiKTtcbiAgICBjb25zdCByZWZyZXNoZWQgPSBhd2FpdCByZWZyZXNoQWNjZXNzVG9rZW4ocnQpO1xuICAgIGNvbnN0IHVwZGF0ZWQgPSBUb2tlbkNyZWRlbnRpYWxzLnBhcnNlKHtcbiAgICAgIC4uLmNyZWRzLFxuICAgICAgYWNjZXNzVG9rZW46IHJlZnJlc2hlZC5hY2Nlc3NUb2tlbixcbiAgICAgIHJlZnJlc2hUb2tlbjogcmVmcmVzaGVkLnJlZnJlc2hUb2tlbixcbiAgICAgIGV4cGlyZXNBdDogcmVmcmVzaGVkLmV4cGlyZXNBdCxcbiAgICB9KTtcbiAgICBhd2FpdCBUb2tlbk1vZGVsLnNhdmUoW1xuICAgICAge1xuICAgICAgICBpZDogdG9rZW4uaWQsXG4gICAgICAgIHByb3ZpZGVyOiB0b2tlbi5wcm92aWRlcixcbiAgICAgICAgY3JlZGVudGlhbHM6IHVwZGF0ZWQsXG4gICAgICAgIG5hbWU6IHRva2VuLm5hbWUsXG4gICAgICB9LFxuICAgIF0pO1xuICAgIHJldHVybiByZWZyZXNoZWQuYWNjZXNzVG9rZW47XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJHRVRcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1xdWVyeVwiXSB9KVxuICBhc3luYyBoZWFsdGgoKTogUHJvbWlzZTxIZWFsdGhSZXNwb25zZT4ge1xuICAgIHJldHVybiB7XG4gICAgICBzdGF0dXM6IFwib2tcIixcbiAgICAgIGFjdGl2ZVRva2VuczogUWdyaWREaXNwYXRjaGVyLnRva2Vucy5zaXplLFxuICAgICAgc3Vic2NyaWJlcjogUWdyaWREaXNwYXRjaGVyLnN1YnNjcmliZXI/LnN0YXR1cygpID8/IG51bGwsXG4gICAgfTtcbiAgfVxufVxuXG5leHBvcnQgY29uc3QgUWdyaWRGcmFtZSA9IG5ldyBRZ3JpZEZyYW1lQ2xhc3MoKTtcblxuZnVuY3Rpb24gY29udmVydEFudGhyb3BpY1VzYWdlKHJhdzogQW50aHJvcGljVXNhZ2VSYXcpOiBVc2FnZVJlc3BvbnNlIHtcbiAgcmV0dXJuIHtcbiAgICBwcm92aWRlcjogXCJhbnRocm9waWNcIixcbiAgICBmaXZlSG91cjogcmF3LmZpdmVfaG91clxuICAgICAgPyB7IHV0aWxpemF0aW9uOiByYXcuZml2ZV9ob3VyLnV0aWxpemF0aW9uLCByZXNldHNBdDogcmF3LmZpdmVfaG91ci5yZXNldHNfYXQgfVxuICAgICAgOiBudWxsLFxuICAgIHNldmVuRGF5OiByYXcuc2V2ZW5fZGF5XG4gICAgICA/IHsgdXRpbGl6YXRpb246IHJhdy5zZXZlbl9kYXkudXRpbGl6YXRpb24sIHJlc2V0c0F0OiByYXcuc2V2ZW5fZGF5LnJlc2V0c19hdCB9XG4gICAgICA6IG51bGwsXG4gIH07XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0RBLE1BQU0saUNBQWlCLElBQUksSUFBd0I7QUFHbkQs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
735
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicWdyaWQuZnJhbWUuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLmZyYW1lLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjcnlwdG8gZnJvbSBcIm5vZGU6Y3J5cHRvXCI7XG5cbmltcG9ydCB7IGdldExvZ2dlciB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5pbXBvcnQgeyB0eXBlIEZhc3RpZnlSZXBseSwgdHlwZSBGYXN0aWZ5UmVxdWVzdCB9IGZyb20gXCJmYXN0aWZ5XCI7XG5pbXBvcnQgeyBhcGksIEJhZFJlcXVlc3RFeGNlcHRpb24sIEJhc2VGcmFtZUNsYXNzLCBTb25hbXUsIHN0cmVhbSB9IGZyb20gXCJzb25hbXVcIjtcbmltcG9ydCB7IGdldENhY2hlTWFuYWdlclJlZiB9IGZyb20gXCJzb25hbXUvY2FjaGVcIjtcblxuaW1wb3J0IHsgdHlwZSBMb2NhbGl6ZWRTdHJpbmcgfSBmcm9tIFwiLi4vLi4vaTE4bi9zZC5nZW5lcmF0ZWRcIjtcbmltcG9ydCB7XG4gIGdldEFjY2Vzc1Rva2VuLFxuICBnZXRFeHBpcmVzQXQsXG4gIGdldFJlZnJlc2hUb2tlbixcbn0gZnJvbSBcIi4uLy4uL3V0aWxzL3Byb3ZpZGVycy9jb21tb24vY3JlZGVudGlhbHNcIjtcbmltcG9ydCB7IENhbGxlclNjaGVtYVZhbGlkYXRpb25FcnJvciB9IGZyb20gXCIuLi8uLi91dGlscy9wcm92aWRlcnMvY29tbW9uL3NjaGVtYS12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBNSUNST19VU0QsIFJlcXVlc3RMb2dNb2RlbCB9IGZyb20gXCIuLi9yZXF1ZXN0LWxvZy9yZXF1ZXN0LWxvZy5tb2RlbFwiO1xuaW1wb3J0IHsgdHlwZSBSZXF1ZXN0TG9nTGlzdFBhcmFtcyB9IGZyb20gXCIuLi9yZXF1ZXN0LWxvZy9yZXF1ZXN0LWxvZy50eXBlc1wiO1xuaW1wb3J0IHsgdHlwZSBUb2tlblN1YnNldEEgfSBmcm9tIFwiLi4vc29uYW11LmdlbmVyYXRlZFwiO1xuaW1wb3J0IHsgVG9rZW5Nb2RlbCwgdHlwZSBUb2tlblVwZGF0ZUZpZWxkcyB9IGZyb20gXCIuLi90b2tlbi90b2tlbi5tb2RlbFwiO1xuaW1wb3J0IHsgVG9rZW5DcmVkZW50aWFscyB9IGZyb20gXCIuLi90b2tlbi90b2tlbi50eXBlc1wiO1xuaW1wb3J0IHtcbiAgdHlwZSBBbnRocm9waWNVc2FnZVJhdyxcbiAgYnVpbGRBdXRoVXJsLFxuICBDT05TT0xFX0NBTExCQUNLX1VSTCxcbiAgZXhjaGFuZ2VDb2RlRm9yVG9rZW5zLFxuICBmZXRjaFVzYWdlLFxuICBnZW5lcmF0ZVBLQ0UsXG4gIHJlZnJlc2hBY2Nlc3NUb2tlbixcbiAgUmVmcmVzaEZhaWxlZEVycm9yLFxufSBmcm9tIFwiLi9vYXV0aFwiO1xuaW1wb3J0IHtcbiAgYWZ0ZXJRdWVyeSxcbiAgYmVmb3JlUXVlcnksXG4gIGZpbmlzaFJ1bkFib3J0ZWQsXG4gIGZpbmlzaFJ1bldpdGhFcnJvcixcbn0gZnJvbSBcIi4vcWdyaWQtcnVuLWxpZmVjeWNsZVwiO1xuaW1wb3J0IHsgYnVpbGRBbmRWYWxpZGF0ZVN0cmljdE91dHB1dFNjaGVtYSwgUWdyaWREaXNwYXRjaGVyIH0gZnJvbSBcIi4vcWdyaWQuZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHtcbiAgdHlwZSBRdWVyeUlucHV0LFxuICB0eXBlIEFwcGVuZFN0ZXBJbnB1dCxcbiAgdHlwZSBDcmVhdGVSdW5JbnB1dCxcbiAgdHlwZSBGaW5pc2hSdW5JbnB1dCxcbiAgdHlwZSBIZWFsdGhSZXNwb25zZSxcbiAgdHlwZSBPQXV0aFN0YXJ0UmVzdWx0LFxuICB0eXBlIFF1ZXJ5T3V0cHV0LFxuICB0eXBlIFFncmlkUnVuQ29udGV4dCxcbiAgU3RyZWFtRXZlbnRzLFxuICB0eXBlIFRva2VuU3RhdHMsXG4gIHR5cGUgVXNhZ2VSZXNwb25zZSxcbn0gZnJvbSBcIi4vcWdyaWQudHlwZXNcIjtcbmltcG9ydCB7IGRlYWN0aXZhdGVBdXRoRGVhZFRva2VuLCBub3RpZnlUb2tlbkFkZGVkIH0gZnJvbSBcIi4vdG9rZW4tZGVhdGhcIjtcbmltcG9ydCB7IFRvb2xTY2hlbWFDb21wb3NpdGlvbkVycm9yIH0gZnJvbSBcIi4vdG9vbC1lbXVsYXRpb24tc2NoZW1hXCI7XG5cbmNvbnN0IHBlbmRpbmdTdHJlYW1zID0gbmV3IE1hcDxzdHJpbmcsIFF1ZXJ5SW5wdXQ+KCk7XG5cbnR5cGUgUGVuZGluZ09BdXRoID0geyBjb2RlVmVyaWZpZXI6IHN0cmluZzsgbmFtZTogc3RyaW5nOyByZWRpcmVjdFVyaTogc3RyaW5nIH07XG5jb25zdCBPQVVUSF9TVEFURV9QUkVGSVggPSBcIm9hdXRoOnN0YXRlOlwiO1xuY29uc3QgT0FVVEhfU1RBVEVfVFRMID0gXCI1bVwiO1xuXG5mdW5jdGlvbiB1bml4U2Vjb25kc1RvSXNvKHNlY29uZHM6IG51bWJlciB8IG51bGwgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCBudWxsIHtcbiAgcmV0dXJuIHR5cGVvZiBzZWNvbmRzID09PSBcIm51bWJlclwiID8gbmV3IERhdGUoc2Vjb25kcyAqIDEwMDApLnRvSVNPU3RyaW5nKCkgOiBudWxsO1xufVxuXG5hc3luYyBmdW5jdGlvbiBzZXRPQXV0aFN0YXRlKHN0YXRlOiBzdHJpbmcsIGRhdGE6IFBlbmRpbmdPQXV0aCk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBjYWNoZSA9IGdldENhY2hlTWFuYWdlclJlZigpO1xuICBpZiAoIWNhY2hlKSB0aHJvdyBuZXcgRXJyb3IoXCJDYWNoZU1hbmFnZXIgbm90IGluaXRpYWxpemVkXCIpO1xuICBhd2FpdCBjYWNoZS5zZXQoe1xuICAgIGtleTogYCR7T0FVVEhfU1RBVEVfUFJFRklYfSR7c3RhdGV9YCxcbiAgICB2YWx1ZTogSlNPTi5zdHJpbmdpZnkoZGF0YSksXG4gICAgdHRsOiBPQVVUSF9TVEFURV9UVEwsXG4gIH0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiBnZXRPQXV0aFN0YXRlKHN0YXRlOiBzdHJpbmcpOiBQcm9taXNlPFBlbmRpbmdPQXV0aCB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBjYWNoZSA9IGdldENhY2hlTWFuYWdlclJlZigpO1xuICBpZiAoIWNhY2hlKSB0aHJvdyBuZXcgRXJyb3IoXCJDYWNoZU1hbmFnZXIgbm90IGluaXRpYWxpemVkXCIpO1xuICBjb25zdCByYXcgPSBhd2FpdCBjYWNoZS5nZXQ8c3RyaW5nPih7IGtleTogYCR7T0FVVEhfU1RBVEVfUFJFRklYfSR7c3RhdGV9YCB9KTtcbiAgaWYgKCFyYXcpIHJldHVybiB1bmRlZmluZWQ7XG4gIHJldHVybiBKU09OLnBhcnNlKHJhdykgYXMgUGVuZGluZ09BdXRoO1xufVxuXG5hc3luYyBmdW5jdGlvbiBkZWxldGVPQXV0aFN0YXRlKHN0YXRlOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgY2FjaGUgPSBnZXRDYWNoZU1hbmFnZXJSZWYoKTtcbiAgaWYgKCFjYWNoZSkgcmV0dXJuO1xuICBhd2FpdCBjYWNoZS5kZWxldGUoeyBrZXk6IGAke09BVVRIX1NUQVRFX1BSRUZJWH0ke3N0YXRlfWAgfSk7XG59XG5cbi8vIE9BdXRoIOygkeyGjSDso7zshozripQg67iM65287Jqw7KCA6rCAIOuztOuCuCBPcmlnaW4o7Jqw7ISgKSDrmJDripQgSG9zdCDtl6TrjZTsl5DshJwg7YyM7IOd7ZWc64ukLlxuLy8gSFRUUCBjb250ZXh0IOqwgCDsl4bripQg7KeB7KCRIO2YuOy2nCjthYzsiqTtirgg65OxKeydgCBudWxsIOydhCDrsJjtmZjtlZzri6QuXG5mdW5jdGlvbiBkZXJpdmVSZXF1ZXN0QmFzZVVybCgpOiBzdHJpbmcgfCBudWxsIHtcbiAgdHJ5IHtcbiAgICBjb25zdCB7IGhlYWRlcnMsIHJlcXVlc3QgfSA9IFNvbmFtdS5nZXRDb250ZXh0KCk7XG4gICAgY29uc3Qgb3JpZ2luID0gaGVhZGVycy5vcmlnaW47XG4gICAgaWYgKHR5cGVvZiBvcmlnaW4gPT09IFwic3RyaW5nXCIgJiYgL15odHRwcz86XFwvXFwvLy50ZXN0KG9yaWdpbikpIHtcbiAgICAgIHJldHVybiBvcmlnaW4ucmVwbGFjZSgvXFwvKyQvLCBcIlwiKTtcbiAgICB9XG4gICAgY29uc3QgZm9yd2FyZGVkSG9zdCA9IGhlYWRlcnNbXCJ4LWZvcndhcmRlZC1ob3N0XCJdO1xuICAgIGNvbnN0IGhvc3QgPSAoQXJyYXkuaXNBcnJheShmb3J3YXJkZWRIb3N0KSA/IGZvcndhcmRlZEhvc3RbMF0gOiBmb3J3YXJkZWRIb3N0KSA/PyBoZWFkZXJzLmhvc3Q7XG4gICAgaWYgKGhvc3QpIHtcbiAgICAgIGNvbnN0IGZvcndhcmRlZFByb3RvID0gaGVhZGVyc1tcIngtZm9yd2FyZGVkLXByb3RvXCJdO1xuICAgICAgY29uc3QgcHJvdG8gPVxuICAgICAgICAoQXJyYXkuaXNBcnJheShmb3J3YXJkZWRQcm90bykgPyBmb3J3YXJkZWRQcm90b1swXSA6IGZvcndhcmRlZFByb3RvKT8uc3BsaXQoXCIsXCIpWzBdID8/XG4gICAgICAgIHJlcXVlc3QucHJvdG9jb2w7XG4gICAgICByZXR1cm4gYCR7cHJvdG99Oi8vJHtob3N0fWA7XG4gICAgfVxuICB9IGNhdGNoIHtcbiAgICAvLyBkaXJlY3QgZnJhbWUgY2FsbCDigJQgSFRUUCBjb250ZXh0IOyXhuydjFxuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5jb25zdCBMT09QQkFDS19IT1NUTkFNRVMgPSBuZXcgU2V0KFtcImxvY2FsaG9zdFwiLCBcIjEyNy4wLjAuMVwiLCBcIls6OjFdXCIsIFwiOjoxXCJdKTtcblxuZnVuY3Rpb24gaXNMb29wYmFja0Jhc2UoYmFzZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIExPT1BCQUNLX0hPU1ROQU1FUy5oYXMobmV3IFVSTChiYXNlKS5ob3N0bmFtZSk7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuXG4vLyBBbnRocm9waWMgT0F1dGggY2xpZW50IOuKlCByZWRpcmVjdF91cmkg7ZeI7JqpIOuqqeuhneydhCDqsJXsoJztlZzri6Q6IOujqO2UhOuwsShsb2NhbGhvc3Qp6rO8XG4vLyDsvZjshpQg7L2c67Cx66eMIO2XiOyaqeuQnOuLpC4g65Sw65287IScIOujqO2UhOuwsSDsoJHsho3snYAg7J6Q64+ZIOumrOuLpOydtOugie2KuCDtlIzroZzsmrDrpbwsXG4vLyDsm5Dqsqkg7KCR7IaN7J2AIOy9mOyGlCDsvZzrsLEgKyDsvZTrk5wg67aZ7Jes64Sj6riwIO2UjOuhnOyasChDbGF1ZGUgQ29kZSBDTEkg7JmAIOuPmeydvCnrpbwg7JO064ukLlxuZnVuY3Rpb24gcmVzb2x2ZU9BdXRoUmVkaXJlY3QoKTogeyByZWRpcmVjdFVyaTogc3RyaW5nOyBtb2RlOiBcInJlZGlyZWN0XCIgfCBcImNvZGVcIiB9IHtcbiAgY29uc3QgYmFzZSA9IGRlcml2ZVJlcXVlc3RCYXNlVXJsKCk7XG4gIGlmIChiYXNlICYmICFpc0xvb3BiYWNrQmFzZShiYXNlKSkge1xuICAgIHJldHVybiB7IHJlZGlyZWN0VXJpOiBDT05TT0xFX0NBTExCQUNLX1VSTCwgbW9kZTogXCJjb2RlXCIgfTtcbiAgfVxuICBjb25zdCBsb29wYmFja0Jhc2UgPSBiYXNlID8/IGBodHRwOi8vbG9jYWxob3N0OiR7cHJvY2Vzcy5lbnYuUE9SVCA/PyBcIjQ0OTAwXCJ9YDtcbiAgcmV0dXJuIHsgcmVkaXJlY3RVcmk6IGAke2xvb3BiYWNrQmFzZX0vY2FsbGJhY2tgLCBtb2RlOiBcInJlZGlyZWN0XCIgfTtcbn1cblxuZnVuY3Rpb24gcmVqZWN0SW1hZ2VHZW5lcmF0aW9uU3RyZWFtKGFyZ3M6IFF1ZXJ5SW5wdXQpOiB2b2lkIHtcbiAgaWYgKCFhcmdzLmltYWdlR2VuZXJhdGlvbikgcmV0dXJuO1xuICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihcbiAgICBcInFncmlkOiBpbWFnZUdlbmVyYXRpb24gaXMgbm90IHN1cHBvcnRlZCB3aXRoIHN0cmVhbWluZzsgdXNlIHF1ZXJ5L2dlbmVyYXRlVGV4dCBpbnN0ZWFkLlwiIGFzIExvY2FsaXplZFN0cmluZyxcbiAgKTtcbn1cblxuZnVuY3Rpb24gcmVqZWN0SW52YWxpZENhbGxlclNjaGVtYXMoYXJnczogUXVlcnlJbnB1dCk6IHZvaWQge1xuICBpZiAoYXJncy5qc29uU2NoZW1hID09PSB1bmRlZmluZWQgJiYgIWFyZ3MudG9vbHM/Lmxlbmd0aCkgcmV0dXJuO1xuXG4gIHRyeSB7XG4gICAgYnVpbGRBbmRWYWxpZGF0ZVN0cmljdE91dHB1dFNjaGVtYShhcmdzKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoXG4gICAgICBlcnJvciBpbnN0YW5jZW9mIENhbGxlclNjaGVtYVZhbGlkYXRpb25FcnJvciB8fFxuICAgICAgZXJyb3IgaW5zdGFuY2VvZiBUb29sU2NoZW1hQ29tcG9zaXRpb25FcnJvclxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oZXJyb3IubWVzc2FnZSBhcyBMb2NhbGl6ZWRTdHJpbmcpO1xuICAgIH1cbiAgICAvLyDsnpjrqrvrkJwga2V5d29yZCDtmJXtg5woYW55T2Yg66W8IOqwneyytOuhnCDrs7TrgrTripQg65OxKeuKlCDtjIzsnbTtlITrnbzsnbjsl5DshJwgdW50eXBlZCDsmKTrpZjroZwg64KY7Jik66+A66GcLFxuICAgIC8vIO2DgOyehSDsooHtnojquLAg64yA7IugIEVycm9yIOyghOyytOulvCBjYWxsZXItZmF1bHQgNDAwIOycvOuhnCDrp6TtlZHtlZzri6Qo6rOE7JW9IO2FjOyKpO2KuOuhnCDqs6DsoJXrkKgpLlxuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihcbiAgICAgICAgYHFncmlkOiBjYWxsZXIgc2NoZW1hIGNhbm5vdCBiZSBub3JtYWxpemVkOiAke2Vycm9yLm1lc3NhZ2V9YCBhcyBMb2NhbGl6ZWRTdHJpbmcsXG4gICAgICApO1xuICAgIH1cbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVIdHRwRGlzY29ubmVjdEhhbmRsZSgpOiB7XG4gIHNpZ25hbDogQWJvcnRTaWduYWw7XG4gIGRpc3Bvc2U6ICgpID0+IHZvaWQ7XG59IHtcbiAgY29uc3QgYWJvcnRDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICBsZXQgcmVxdWVzdFJhdzogRmFzdGlmeVJlcXVlc3RbXCJyYXdcIl0gfCB1bmRlZmluZWQ7XG4gIGxldCByZXNwb25zZVJhdzogRmFzdGlmeVJlcGx5W1wicmF3XCJdIHwgdW5kZWZpbmVkO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgY3R4ID0gU29uYW11LmdldENvbnRleHQoKTtcbiAgICByZXF1ZXN0UmF3ID0gY3R4LnJlcXVlc3Q/LnJhdztcbiAgICBpZiAoY3R4LnRyYW5zcG9ydCA9PT0gXCJodHRwXCIpIHJlc3BvbnNlUmF3ID0gY3R4LnJlcGx5LnJhdztcbiAgfSBjYXRjaCB7XG4gICAgLy8gRGlyZWN0IGZyYW1lIGNhbGxzIChmb3IgZXhhbXBsZSB1bml0IHRlc3RzKSBkbyBub3QgaGF2ZSBhbiBIVFRQIGNvbnRleHQuXG4gIH1cblxuICBjb25zdCBhYm9ydCA9ICgpID0+IGFib3J0Q29udHJvbGxlci5hYm9ydCgpO1xuICBjb25zdCBhYm9ydE9uSW5jb21wbGV0ZVJlc3BvbnNlQ2xvc2UgPSAoKSA9PiB7XG4gICAgaWYgKCFyZXNwb25zZVJhdz8ud3JpdGFibGVFbmRlZCkgYWJvcnQoKTtcbiAgfTtcblxuICByZXF1ZXN0UmF3Py5vbmNlKFwiYWJvcnRlZFwiLCBhYm9ydCk7XG4gIHJlc3BvbnNlUmF3Py5vbmNlKFwiY2xvc2VcIiwgYWJvcnRPbkluY29tcGxldGVSZXNwb25zZUNsb3NlKTtcblxuICBpZiAocmVxdWVzdFJhdz8uYWJvcnRlZCB8fCAocmVzcG9uc2VSYXc/LmRlc3Ryb3llZCAmJiAhcmVzcG9uc2VSYXcud3JpdGFibGVFbmRlZCkpIHtcbiAgICBhYm9ydCgpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBzaWduYWw6IGFib3J0Q29udHJvbGxlci5zaWduYWwsXG4gICAgZGlzcG9zZTogKCkgPT4ge1xuICAgICAgcmVxdWVzdFJhdz8ucmVtb3ZlTGlzdGVuZXIoXCJhYm9ydGVkXCIsIGFib3J0KTtcbiAgICAgIHJlc3BvbnNlUmF3Py5yZW1vdmVMaXN0ZW5lcihcImNsb3NlXCIsIGFib3J0T25JbmNvbXBsZXRlUmVzcG9uc2VDbG9zZSk7XG4gICAgfSxcbiAgfTtcbn1cblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCJdKTtcbmNvbnN0IG9hdXRoTG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwib2F1dGhcIl0pO1xuXG4vLyBwZXItdG9rZW4gcmVmcmVzaCBkZWR1cCDigJQg7ZqM7KCEIOqyuey5qOycvOuhnCDsnbjtlZwg7IKs66edIOyYpO2MkOydhCDrp4nripTri6QuXG5jb25zdCBpbmZsaWdodEFudGhyb3BpY1JlZnJlc2ggPSBuZXcgTWFwPG51bWJlciwgUHJvbWlzZTxzdHJpbmc+PigpO1xuXG5jbGFzcyBRZ3JpZEZyYW1lQ2xhc3MgZXh0ZW5kcyBCYXNlRnJhbWVDbGFzcyB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKFwiUWdyaWRcIik7XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJQT1NUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stbXV0YXRpb25cIl0gfSlcbiAgYXN5bmMgcXVlcnkoYXJnczogUXVlcnlJbnB1dCk6IFByb21pc2U8UXVlcnlPdXRwdXQ+IHtcbiAgICByZWplY3RJbnZhbGlkQ2FsbGVyU2NoZW1hcyhhcmdzKTtcbiAgICBjb25zdCBkaXNjb25uZWN0ID0gY3JlYXRlSHR0cERpc2Nvbm5lY3RIYW5kbGUoKTtcbiAgICB0cnkge1xuICAgICAgaWYgKGFyZ3MubG9nZ2VyID09PSBmYWxzZSkge1xuICAgICAgICByZXR1cm4gYXdhaXQgUWdyaWREaXNwYXRjaGVyLnF1ZXJ5KGFyZ3MsIGRpc2Nvbm5lY3Quc2lnbmFsKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyByZXF1ZXN0TG9nSWQsIHN0ZXBJbmRleCB9ID0gYXdhaXQgYmVmb3JlUXVlcnkoYXJncyk7XG4gICAgICBsZXQgcmVzdWx0OiBRdWVyeU91dHB1dDtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJlc3VsdCA9IGF3YWl0IFFncmlkRGlzcGF0Y2hlci5xdWVyeShhcmdzLCBkaXNjb25uZWN0LnNpZ25hbCk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChkaXNjb25uZWN0LnNpZ25hbC5hYm9ydGVkKSB7XG4gICAgICAgICAgYXdhaXQgZmluaXNoUnVuQWJvcnRlZChyZXF1ZXN0TG9nSWQsIGFyZ3MpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGF3YWl0IGZpbmlzaFJ1bldpdGhFcnJvcihyZXF1ZXN0TG9nSWQsIChlIGFzIEVycm9yKS5tZXNzYWdlLCBhcmdzKTtcbiAgICAgICAgfVxuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBsaWZlY3ljbGUgPSBhd2FpdCBhZnRlclF1ZXJ5KHJlcXVlc3RMb2dJZCwgc3RlcEluZGV4LCBhcmdzLCByZXN1bHQpO1xuICAgICAgICBpZiAoZGlzY29ubmVjdC5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgICAgIGF3YWl0IGZpbmlzaFJ1bkFib3J0ZWQocmVxdWVzdExvZ0lkLCBhcmdzKTtcbiAgICAgICAgfVxuICAgICAgICAvLyB0b29sLWNhbGwgcmVxdWVzdExvZ0lk7JmAIHByb3ZpZGVyIHRocmVhZENvb3Jk64qUIOyEnOuhnCDrj4Xrpr3soIHsnLzroZwg7Jyg7KeA7ZWc64ukLlxuICAgICAgICBjb25zdCB0aHJlYWRDb29yZCA9IHJlc3VsdC5ydW5Db250ZXh0Py50aHJlYWRDb29yZDtcbiAgICAgICAgY29uc3QgcnVuQ29udGV4dCA9XG4gICAgICAgICAgbGlmZWN5Y2xlLnJ1bkNvbnRleHQgfHwgdGhyZWFkQ29vcmRcbiAgICAgICAgICAgID8geyAuLi5saWZlY3ljbGUucnVuQ29udGV4dCwgLi4uKHRocmVhZENvb3JkID8geyB0aHJlYWRDb29yZCB9IDoge30pIH1cbiAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4geyAuLi5yZXN1bHQsIHJ1bkNvbnRleHQgfTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKGBxdWVyeSBhZnRlclF1ZXJ5IGZhaWxlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgaWYgKGRpc2Nvbm5lY3Quc2lnbmFsLmFib3J0ZWQpIHtcbiAgICAgICAgICBhd2FpdCBmaW5pc2hSdW5BYm9ydGVkKHJlcXVlc3RMb2dJZCwgYXJncyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYXdhaXQgZmluaXNoUnVuV2l0aEVycm9yKHJlcXVlc3RMb2dJZCwgKGUgYXMgRXJyb3IpLm1lc3NhZ2UsIGFyZ3MpO1xuICAgICAgICB9XG4gICAgICAgIC8vIHByb3ZpZGVyIOydkeuLteydgCDshLHqs7XtlojsnLzrr4DroZwg66Gc6rmFIOyepeyVoOqwgCDsg53shLEg6rKw6rO866W8IOuNruyWtOyTsOyngCDslYrripTri6QuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGRpc2Nvbm5lY3QuZGlzcG9zZSgpO1xuICAgIH1cbiAgfVxuXG4gIEBhcGkoeyBodHRwTWV0aG9kOiBcIlBPU1RcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1tdXRhdGlvblwiXSB9KVxuICBhc3luYyBwcmVwYXJlU3RyZWFtKGFyZ3M6IFF1ZXJ5SW5wdXQpOiBQcm9taXNlPHsgc3RyZWFtSWQ6IHN0cmluZyB9PiB7XG4gICAgcmVqZWN0SW1hZ2VHZW5lcmF0aW9uU3RyZWFtKGFyZ3MpO1xuICAgIHJlamVjdEludmFsaWRDYWxsZXJTY2hlbWFzKGFyZ3MpO1xuICAgIGNvbnN0IHN0cmVhbUlkID0gY3J5cHRvLnJhbmRvbVVVSUQoKTtcbiAgICBwZW5kaW5nU3RyZWFtcy5zZXQoc3RyZWFtSWQsIGFyZ3MpO1xuICAgIGNvbnN0IGV4cGlyeSA9IHNldFRpbWVvdXQoKCkgPT4gcGVuZGluZ1N0cmVhbXMuZGVsZXRlKHN0cmVhbUlkKSwgMzBfMDAwKTtcbiAgICBleHBpcnkudW5yZWY/LigpO1xuICAgIHJldHVybiB7IHN0cmVhbUlkIH07XG4gIH1cblxuICBAc3RyZWFtKHsgdHlwZTogXCJzc2VcIiwgZXZlbnRzOiBTdHJlYW1FdmVudHMgfSlcbiAgYXN5bmMgcXVlcnlTdHJlYW0oc3RyZWFtSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGFyZ3MgPSBwZW5kaW5nU3RyZWFtcy5nZXQoc3RyZWFtSWQpO1xuICAgIHBlbmRpbmdTdHJlYW1zLmRlbGV0ZShzdHJlYW1JZCk7XG4gICAgaWYgKCFhcmdzKSB0aHJvdyBuZXcgRXJyb3IoXCJpbnZhbGlkIG9yIGV4cGlyZWQgc3RyZWFtSWRcIik7XG4gICAgcmVqZWN0SW1hZ2VHZW5lcmF0aW9uU3RyZWFtKGFyZ3MpO1xuXG4gICAgY29uc3QgY3R4ID0gU29uYW11LmdldENvbnRleHQoKTtcbiAgICBjb25zdCBzc2UgPSBjdHguY3JlYXRlU1NFKFN0cmVhbUV2ZW50cyk7XG4gICAgbGV0IHRocmVhZElkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgbGV0IHR1cm5JZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGxldCBzdHJlYW1SZXN1bHQ6IFF1ZXJ5T3V0cHV0IHwgdW5kZWZpbmVkO1xuICAgIGxldCBzdHJlYW1FcnJvcjogRXJyb3IgfCB1bmRlZmluZWQ7XG4gICAgbGV0IGNsaWVudENsb3NlZCA9IGZhbHNlO1xuICAgIGNvbnN0IGFib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcblxuICAgIGNvbnN0IGludGVycnVwdE9wZW5BSSA9ICgpID0+IHtcbiAgICAgIGlmICh0aHJlYWRJZCAmJiB0dXJuSWQpIHtcbiAgICAgICAgUWdyaWREaXNwYXRjaGVyLm9wZW5haURpc3BhdGNoZXI/LmludGVycnVwdFdvcmtlclR1cm4odGhyZWFkSWQsIHR1cm5JZCkuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgfVxuICAgIH07XG5cbiAgICBzc2Uub25DbG9zZSgoKSA9PiB7XG4gICAgICBjbGllbnRDbG9zZWQgPSB0cnVlO1xuICAgICAgYWJvcnRDb250cm9sbGVyLmFib3J0KCk7XG4gICAgICBpbnRlcnJ1cHRPcGVuQUkoKTtcbiAgICB9KTtcblxuICAgIGxldCBydW5JbmZvOiB7IHJlcXVlc3RMb2dJZDogbnVtYmVyOyBzdGVwSW5kZXg6IG51bWJlciB9IHwgdW5kZWZpbmVkO1xuICAgIGlmIChhcmdzLmxvZ2dlciAhPT0gZmFsc2UpIHtcbiAgICAgIC8vIHByb3ZpZGVyIOyLpO2WiSDsoIQgcnVubmluZyByb3cg7IOd7ISx7JeQIOyLpO2MqO2VmOuptCBsb2dnZWQg7JqU7LKt7Jy866GcIOynhO2Wie2VmOyngCDslYrripTri6QuXG4gICAgICBydW5JbmZvID0gYXdhaXQgYmVmb3JlUXVlcnkoYXJncyk7XG4gICAgfVxuXG4gICAgLy8gYmVmb3JlUXVlcnkgREIg7J6R7JeFIOykkSBjbG9zZeulvCDrhpPsuZjsp4Ag7JWK6rOgIHByb3ZpZGVyIOyLpO2WiSDsoITsl5Ag66eI6rCQ7ZWc64ukLlxuICAgIGlmIChjbGllbnRDbG9zZWQgfHwgc3NlLmNsb3NlZCkge1xuICAgICAgaWYgKHJ1bkluZm8pIGF3YWl0IGZpbmlzaFJ1bkFib3J0ZWQocnVuSW5mby5yZXF1ZXN0TG9nSWQsIGFyZ3MpO1xuICAgICAgYXdhaXQgc3NlLmVuZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBRZ3JpZERpc3BhdGNoZXIucXVlcnlTdHJlYW0oXG4gICAgICAgIGFyZ3MsXG4gICAgICAgIHtcbiAgICAgICAgICBvbkRlbHRhOiAodGV4dCkgPT4ge1xuICAgICAgICAgICAgaWYgKCFjbGllbnRDbG9zZWQgJiYgIXNzZS5jbG9zZWQpIHNzZS5wdWJsaXNoKFwiZGVsdGFcIiwgeyB0ZXh0IH0pO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgb25UaHJlYWRJZDogKGlkKSA9PiB7XG4gICAgICAgICAgICB0aHJlYWRJZCA9IGlkO1xuICAgICAgICAgICAgaWYgKChjbGllbnRDbG9zZWQgfHwgc3NlLmNsb3NlZCkgJiYgdHVybklkKSB7XG4gICAgICAgICAgICAgIGludGVycnVwdE9wZW5BSSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0sXG4gICAgICAgICAgb25UdXJuSWQ6IChpZCkgPT4ge1xuICAgICAgICAgICAgdHVybklkID0gaWQ7XG4gICAgICAgICAgICBpZiAoKGNsaWVudENsb3NlZCB8fCBzc2UuY2xvc2VkKSAmJiB0aHJlYWRJZCkge1xuICAgICAgICAgICAgICBpbnRlcnJ1cHRPcGVuQUkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICAgIG9uQ29tcGxldGU6IChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgIHN0cmVhbVJlc3VsdCA9IHJlc3VsdDtcbiAgICAgICAgICB9LFxuICAgICAgICAgIG9uRXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgICAgIHN0cmVhbUVycm9yID0gZXJyO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICAgIGFib3J0Q29udHJvbGxlci5zaWduYWwsXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHN0cmVhbUVycm9yID0gZSBhcyBFcnJvcjtcbiAgICB9XG5cbiAgICAvLyBwcm92aWRlciDqsrDqs7zqsIAg7JeG64qUIGNsb3Nl64qUIOymieyLnCBhYm9ydGVk66GcIOuniOqwkO2VnOuLpC5cbiAgICBpZiAoY2xpZW50Q2xvc2VkICYmICFzdHJlYW1SZXN1bHQpIHtcbiAgICAgIGlmIChydW5JbmZvKSBhd2FpdCBmaW5pc2hSdW5BYm9ydGVkKHJ1bkluZm8ucmVxdWVzdExvZ0lkLCBhcmdzKTtcbiAgICAgIGF3YWl0IHNzZS5lbmQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBkaXNwYXRjaGVyIOyZhOujjCDtm4QgbGlmZWN5Y2xlIOyymOumrCAoYXdhaXQg7JWI7KCEKVxuICAgIGlmIChzdHJlYW1SZXN1bHQpIHtcbiAgICAgIC8vIGRpc3BhdGNoZXIg6rCAIOyLpOydgCB0aHJlYWQg7J6s7IKs7JqpIOyijO2RnOuKlCBsb2dnZXIg7ISk7KCV6rO8IOustOq0gO2VmOqyjCDtmozshqHtlZzri6QuXG4gICAgICBjb25zdCB0aHJlYWRDb29yZCA9IHN0cmVhbVJlc3VsdC5ydW5Db250ZXh0Py50aHJlYWRDb29yZDtcbiAgICAgIGxldCBydW5Db250ZXh0OiBRZ3JpZFJ1bkNvbnRleHQgfCB1bmRlZmluZWQgPVxuICAgICAgICB0aHJlYWRDb29yZCAhPT0gdW5kZWZpbmVkID8geyB0aHJlYWRDb29yZCB9IDogdW5kZWZpbmVkO1xuICAgICAgaWYgKHJ1bkluZm8pIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBjbG9zZSDtm4Qg64+E7LCp7ZWcIOqysOqzvOuPhCBzdGVwL3VzYWdl64qUIOuCqOq4sOuQmCwg7JWE656Y7JeQ7IScIOy1nOyihSBzdGF0dXPrpbwgYWJvcnRlZOuhnCDrja7slrTsk7Tri6QuXG4gICAgICAgICAgY29uc3QgbGlmZWN5Y2xlID0gYXdhaXQgYWZ0ZXJRdWVyeShcbiAgICAgICAgICAgIHJ1bkluZm8ucmVxdWVzdExvZ0lkLFxuICAgICAgICAgICAgcnVuSW5mby5zdGVwSW5kZXgsXG4gICAgICAgICAgICBhcmdzLFxuICAgICAgICAgICAgc3RyZWFtUmVzdWx0LFxuICAgICAgICAgICk7XG4gICAgICAgICAgcnVuQ29udGV4dCA9XG4gICAgICAgICAgICBsaWZlY3ljbGUucnVuQ29udGV4dCB8fCB0aHJlYWRDb29yZFxuICAgICAgICAgICAgICA/IHsgLi4ubGlmZWN5Y2xlLnJ1bkNvbnRleHQsIC4uLih0aHJlYWRDb29yZCA/IHsgdGhyZWFkQ29vcmQgfSA6IHt9KSB9XG4gICAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuXG4gICAgICAgICAgLy8gYWZ0ZXJRdWVyeeqwgCDsp4TtlonrkJjripQg7IKs7J20IGNsaWVudOqwgCDri6vtnowg6rK97JqwIOyZhOujjCDsg4Htg5zrpbwgYWJvcnRlZOuhnCDrkJjrj4zrprDri6QuXG4gICAgICAgICAgaWYgKGNsaWVudENsb3NlZCkge1xuICAgICAgICAgICAgYXdhaXQgZmluaXNoUnVuQWJvcnRlZChydW5JbmZvLnJlcXVlc3RMb2dJZCwgYXJncyk7XG4gICAgICAgICAgICBhd2FpdCBzc2UuZW5kKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKGBzdHJlYW0gYWZ0ZXJRdWVyeSBmYWlsZWQ6ICR7KGUgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG4gICAgICAgICAgYXdhaXQgZmluaXNoUnVuV2l0aEVycm9yKHJ1bkluZm8ucmVxdWVzdExvZ0lkLCAoZSBhcyBFcnJvcikubWVzc2FnZSwgYXJncyk7XG5cbiAgICAgICAgICBpZiAoY2xpZW50Q2xvc2VkKSB7XG4gICAgICAgICAgICBhd2FpdCBmaW5pc2hSdW5BYm9ydGVkKHJ1bkluZm8ucmVxdWVzdExvZ0lkLCBhcmdzKTtcbiAgICAgICAgICAgIGF3YWl0IHNzZS5lbmQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghY2xpZW50Q2xvc2VkICYmICFzc2UuY2xvc2VkKSBzc2UucHVibGlzaChcImRvbmVcIiwgeyAuLi5zdHJlYW1SZXN1bHQsIHJ1bkNvbnRleHQgfSk7XG4gICAgfSBlbHNlIGlmIChzdHJlYW1FcnJvcikge1xuICAgICAgaWYgKHJ1bkluZm8pIGF3YWl0IGZpbmlzaFJ1bldpdGhFcnJvcihydW5JbmZvLnJlcXVlc3RMb2dJZCwgc3RyZWFtRXJyb3IubWVzc2FnZSwgYXJncyk7XG4gICAgICBpZiAoIWNsaWVudENsb3NlZCAmJiAhc3NlLmNsb3NlZCkgc3NlLnB1Ymxpc2goXCJlcnJvclwiLCB7IG1lc3NhZ2U6IHN0cmVhbUVycm9yLm1lc3NhZ2UgfSk7XG4gICAgfSBlbHNlIGlmICgoY2xpZW50Q2xvc2VkIHx8IHNzZS5jbG9zZWQpICYmIHJ1bkluZm8pIHtcbiAgICAgIGF3YWl0IGZpbmlzaFJ1bkFib3J0ZWQocnVuSW5mby5yZXF1ZXN0TG9nSWQsIGFyZ3MpO1xuICAgIH1cblxuICAgIGF3YWl0IHNzZS5lbmQoKTtcbiAgfVxuXG4gIEBhcGkoeyBodHRwTWV0aG9kOiBcIlBPU1RcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1tdXRhdGlvblwiXSB9KVxuICBhc3luYyBjcmVhdGVSdW4oaW5wdXQ6IENyZWF0ZVJ1bklucHV0KTogUHJvbWlzZTx7IHJlcXVlc3RMb2dJZDogbnVtYmVyIH0+IHtcbiAgICBjb25zdCByZXF1ZXN0TG9nSWQgPSBhd2FpdCBSZXF1ZXN0TG9nTW9kZWwuY3JlYXRlUnVuKHtcbiAgICAgIHVzZXJfcHJvbXB0OiBpbnB1dC51c2VyUHJvbXB0LFxuICAgICAgcmVxdWVzdGVkX21vZGVsX25hbWU6IGlucHV0Lm1vZGVsTmFtZSxcbiAgICAgIGVmZm9ydDogaW5wdXQuZWZmb3J0LFxuICAgICAgcHJvamVjdF9uYW1lOiBpbnB1dC5wcm9qZWN0TmFtZSxcbiAgICAgIHN5c3RlbV9wcm9tcHQ6IGlucHV0LnN5c3RlbVByb21wdCxcbiAgICAgIGhpc3Rvcnk6IGlucHV0Lmhpc3RvcnkgPyBKU09OLnBhcnNlKGlucHV0Lmhpc3RvcnkpIDogdW5kZWZpbmVkLFxuICAgIH0pO1xuICAgIHJldHVybiB7IHJlcXVlc3RMb2dJZCB9O1xuICB9XG5cbiAgQGFwaSh7IGh0dHBNZXRob2Q6IFwiUE9TVFwiLCBjbGllbnRzOiBbXCJheGlvc1wiLCBcInRhbnN0YWNrLW11dGF0aW9uXCJdIH0pXG4gIGFzeW5jIGFwcGVuZFN0ZXAoaW5wdXQ6IEFwcGVuZFN0ZXBJbnB1dCk6IFByb21pc2U8eyBzdGVwSWQ6IG51bWJlciB9PiB7XG4gICAgY29uc3Qgc3RlcElkID0gYXdhaXQgUmVxdWVzdExvZ01vZGVsLmFwcGVuZFN0ZXAoaW5wdXQucmVxdWVzdExvZ0lkLCB7XG4gICAgICBzdGVwX2luZGV4OiBpbnB1dC5zdGVwSW5kZXgsXG4gICAgICB0eXBlOiBpbnB1dC50eXBlLFxuICAgICAgbW9kZWxfbmFtZTogaW5wdXQubW9kZWxOYW1lLFxuICAgICAgcmVxdWVzdGVkX21vZGVsX25hbWU6IGlucHV0LnJlcXVlc3RlZE1vZGVsTmFtZSxcbiAgICAgIGZhbGxiYWNrX2NvdW50OiBpbnB1dC5mYWxsYmFja0NvdW50LFxuICAgICAgaW5wdXRfdG9rZW5zOiBpbnB1dC5pbnB1dFRva2VucyxcbiAgICAgIG91dHB1dF90b2tlbnM6IGlucHV0Lm91dHB1dFRva2VucyxcbiAgICAgIGNhY2hlX3JlYWRfdG9rZW5zOiBpbnB1dC5jYWNoZVJlYWRUb2tlbnMsXG4gICAgICBjYWNoZV9jcmVhdGlvbl90b2tlbnM6IGlucHV0LmNhY2hlQ3JlYXRpb25Ub2tlbnMsXG4gICAgICBjYWNoZV9jcmVhdGlvbl81bV90b2tlbnM6IGlucHV0LmNhY2hlQ3JlYXRpb241bVRva2VucyxcbiAgICAgIGNhY2hlX2NyZWF0aW9uXzFoX3Rva2VuczogaW5wdXQuY2FjaGVDcmVhdGlvbjFoVG9rZW5zLFxuICAgICAgY29zdF91c2Q6IGlucHV0LmNvc3RVc2QgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IE1hdGgucm91bmQoaW5wdXQuY29zdFVzZCAqIE1JQ1JPX1VTRCksXG4gICAgICBjb3N0X3NvdXJjZTogaW5wdXQuY29zdFNvdXJjZSxcbiAgICAgIGR1cmF0aW9uX21zOiBpbnB1dC5kdXJhdGlvbk1zLFxuICAgICAgdHRmdF9tczogaW5wdXQudHRmdE1zID8/IG51bGwsXG4gICAgICBmaW5pc2hfcmVhc29uOiBpbnB1dC5maW5pc2hSZWFzb24sXG4gICAgICByZWFzb25pbmdfdGV4dDogaW5wdXQucmVhc29uaW5nVGV4dCxcbiAgICAgIHJlYXNvbmluZ190b2tlbnM6IGlucHV0LnJlYXNvbmluZ1Rva2VucyxcbiAgICAgIHRvb2xfY2FsbF9pbmRleDogaW5wdXQudG9vbENhbGxJbmRleCxcbiAgICAgIHRvb2xfY2FsbF9pZDogaW5wdXQudG9vbENhbGxJZCxcbiAgICAgIHRvb2xfbmFtZTogaW5wdXQudG9vbE5hbWUsXG4gICAgICB0b29sX2FyZ3M6IGlucHV0LnRvb2xBcmdzLFxuICAgICAgdG9vbF9yZXN1bHQ6IGlucHV0LnRvb2xSZXN1bHQsXG4gICAgICB0b29sX2R1cmF0aW9uX21zOiBpbnB1dC50b29sRHVyYXRpb25NcyxcbiAgICAgIGVycm9yOiBpbnB1dC5lcnJvcixcbiAgICB9KTtcbiAgICByZXR1cm4geyBzdGVwSWQgfTtcbiAgfVxuXG4gIEBhcGkoeyBodHRwTWV0aG9kOiBcIlBPU1RcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1tdXRhdGlvblwiXSB9KVxuICBhc3luYyBmaW5pc2hSdW4oaW5wdXQ6IEZpbmlzaFJ1bklucHV0KTogUHJvbWlzZTx7IG9rOiBib29sZWFuIH0+IHtcbiAgICBhd2FpdCBSZXF1ZXN0TG9nTW9kZWwuZmluaXNoUnVuKGlucHV0LnJlcXVlc3RMb2dJZCwge1xuICAgICAgc3RhdHVzOiBpbnB1dC5zdGF0dXMsXG4gICAgICByZXNwb25zZTogaW5wdXQucmVzcG9uc2UsXG4gICAgICB0b2tlbl9uYW1lOiBpbnB1dC50b2tlbk5hbWUsXG4gICAgICBtb2RlbF9uYW1lOiBpbnB1dC5tb2RlbE5hbWUsXG4gICAgICByZXF1ZXN0ZWRfbW9kZWxfbmFtZTogaW5wdXQucmVxdWVzdGVkTW9kZWxOYW1lLFxuICAgICAgZmFsbGJhY2tfY291bnQ6IGlucHV0LmZhbGxiYWNrQ291bnQsXG4gICAgICBpbnB1dF90b2tlbnM6IGlucHV0LnRvdGFsSW5wdXRUb2tlbnMsXG4gICAgICBvdXRwdXRfdG9rZW5zOiBpbnB1dC50b3RhbE91dHB1dFRva2VucyxcbiAgICAgIGNhY2hlX3JlYWRfdG9rZW5zOiBpbnB1dC50b3RhbENhY2hlUmVhZFRva2VucyxcbiAgICAgIGNhY2hlX2NyZWF0aW9uX3Rva2VuczogaW5wdXQudG90YWxDYWNoZUNyZWF0aW9uVG9rZW5zLFxuICAgICAgY2FjaGVfY3JlYXRpb25fNW1fdG9rZW5zOiBpbnB1dC50b3RhbENhY2hlQ3JlYXRpb241bVRva2VucyxcbiAgICAgIGNhY2hlX2NyZWF0aW9uXzFoX3Rva2VuczogaW5wdXQudG90YWxDYWNoZUNyZWF0aW9uMWhUb2tlbnMsXG4gICAgICBjb3N0X3VzZDogaW5wdXQuY29zdFVzZCA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogTWF0aC5yb3VuZChpbnB1dC5jb3N0VXNkICogTUlDUk9fVVNEKSxcbiAgICAgIGNvc3Rfc291cmNlOiBpbnB1dC5jb3N0U291cmNlLFxuICAgICAgZHVyYXRpb25fbXM6IGlucHV0LnRvdGFsRHVyYXRpb25NcyxcbiAgICAgIGhpc3Rvcnk6IGlucHV0Lmhpc3RvcnkgPyBKU09OLnBhcnNlKGlucHV0Lmhpc3RvcnkpIDogdW5kZWZpbmVkLFxuICAgICAgZXJyb3JfbWVzc2FnZTogaW5wdXQuZXJyb3JNZXNzYWdlLFxuICAgIH0pO1xuICAgIHJldHVybiB7IG9rOiB0cnVlIH07XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJHRVRcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1xdWVyeVwiXSB9KVxuICBhc3luYyBzdGF0cygpOiBQcm9taXNlPFRva2VuU3RhdHNbXT4ge1xuICAgIHJldHVybiBRZ3JpZERpc3BhdGNoZXIuZ2V0U3RhdHMoKTtcbiAgfVxuXG4gIC8vIO2ZlOuptOydmCDrqqnroZ0g7ZWE7YSw66W8IOq3uOuMgOuhnCDrsJvslYQg6rCZ7J2AIOyhsOqxtOydmCDtlanqs4Trpbwg64+M66Ck7KSA64ukIOKAlCDrqqnroZ3qs7wg67mE7Jqp7J20XG4gIC8vIOyEnOuhnCDri6Trpbgg66qo7IiY66W8IOuztOuptCDsgqzsmqnsnpDsl5DqsozripQg7Iir7J6Q6rCAIOyWtOq4i+uCnCDqsoPsnLzroZwg7J297Z6M64ukLlxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJHRVRcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1xdWVyeVwiXSB9KVxuICBhc3luYyB0b3RhbENvc3QocGFyYW1zPzogUmVxdWVzdExvZ0xpc3RQYXJhbXMpOiBQcm9taXNlPHsgdXNkOiBudW1iZXIgfT4ge1xuICAgIHJldHVybiB7IHVzZDogYXdhaXQgUmVxdWVzdExvZ01vZGVsLnRvdGFsQ29zdChwYXJhbXMpIH07XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJHRVRcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1xdWVyeVwiXSB9KVxuICBhc3luYyBwcm9qZWN0TmFtZXMoKTogUHJvbWlzZTx7IG5hbWVzOiBzdHJpbmdbXSB9PiB7XG4gICAgcmV0dXJuIHsgbmFtZXM6IGF3YWl0IFJlcXVlc3RMb2dNb2RlbC5kaXN0aW5jdFByb2plY3ROYW1lcygpIH07XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJQT1NUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stbXV0YXRpb25cIl0gfSlcbiAgYXN5bmMgYWRkVG9rZW4oXG4gICAgcHJvdmlkZXI6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogVG9rZW5DcmVkZW50aWFscyxcbiAgICBuYW1lOiBzdHJpbmcsXG4gICk6IFByb21pc2U8eyBhZGRlZDogYm9vbGVhbiB9PiB7XG4gICAgYXdhaXQgVG9rZW5Nb2RlbC5zYXZlKFtcbiAgICAgIHtcbiAgICAgICAgcHJvdmlkZXIsXG4gICAgICAgIGNyZWRlbnRpYWxzLFxuICAgICAgICBuYW1lLFxuICAgICAgfSxcbiAgICBdKTtcbiAgICByZXR1cm4geyBhZGRlZDogdHJ1ZSB9O1xuICB9XG5cbiAgQGFwaSh7IGh0dHBNZXRob2Q6IFwiUE9TVFwiLCBjbGllbnRzOiBbXCJheGlvc1wiXSB9KVxuICBhc3luYyB1cGRhdGVUb2tlbihcbiAgICBpZDogbnVtYmVyLFxuICAgIG5hbWU/OiBzdHJpbmcsXG4gICAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsLFxuICAgIHdlaWdodD86IG51bWJlcixcbiAgKTogUHJvbWlzZTx7IHVwZGF0ZWQ6IGJvb2xlYW4gfT4ge1xuICAgIGlmIChcbiAgICAgIHF1b3RhVGhyZXNob2xkICE9PSB1bmRlZmluZWQgJiZcbiAgICAgIHF1b3RhVGhyZXNob2xkICE9PSBudWxsICYmXG4gICAgICAoIU51bWJlci5pc0ludGVnZXIocXVvdGFUaHJlc2hvbGQpIHx8IHF1b3RhVGhyZXNob2xkIDwgMSB8fCBxdW90YVRocmVzaG9sZCA+IDEwMClcbiAgICApIHtcbiAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFxuICAgICAgICBcInF1b3RhVGhyZXNob2xkIG11c3QgYmUgYW4gaW50ZWdlciBiZXR3ZWVuIDEgYW5kIDEwMCwgb3IgbnVsbFwiIGFzIExvY2FsaXplZFN0cmluZyxcbiAgICAgICk7XG4gICAgfVxuICAgIGlmICh3ZWlnaHQgIT09IHVuZGVmaW5lZCAmJiAoIU51bWJlci5pc0ludGVnZXIod2VpZ2h0KSB8fCB3ZWlnaHQgPCAxIHx8IHdlaWdodCA+IDEwMCkpIHtcbiAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFxuICAgICAgICBcIndlaWdodCBtdXN0IGJlIGFuIGludGVnZXIgYmV0d2VlbiAxIGFuZCAxMDBcIiBhcyBMb2NhbGl6ZWRTdHJpbmcsXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHBhdGNoOiBUb2tlblVwZGF0ZUZpZWxkcyA9IHt9O1xuICAgIGlmIChuYW1lICE9PSB1bmRlZmluZWQpIHBhdGNoLm5hbWUgPSBuYW1lO1xuICAgIGlmIChxdW90YVRocmVzaG9sZCAhPT0gdW5kZWZpbmVkKSBwYXRjaC5xdW90YV90aHJlc2hvbGQgPSBxdW90YVRocmVzaG9sZDtcbiAgICBpZiAod2VpZ2h0ICE9PSB1bmRlZmluZWQpIHBhdGNoLndlaWdodCA9IHdlaWdodDtcbiAgICBpZiAoT2JqZWN0LmtleXMocGF0Y2gpLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHsgdXBkYXRlZDogZmFsc2UgfTtcblxuICAgIGNvbnN0IHVwZGF0ZWQgPSBhd2FpdCBUb2tlbk1vZGVsLnVwZGF0ZUZpZWxkcyhpZCwgcGF0Y2gpO1xuICAgIHJldHVybiB7IHVwZGF0ZWQ6IHVwZGF0ZWQgPiAwIH07XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJQT1NUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stbXV0YXRpb25cIl0gfSlcbiAgYXN5bmMgcmVtb3ZlVG9rZW4oaWQ6IG51bWJlcik6IFByb21pc2U8eyByZW1vdmVkOiBib29sZWFuIH0+IHtcbiAgICBjb25zdCBlbnRyeSA9IGF3YWl0IFRva2VuTW9kZWwuZmluZE9uZShcIkFcIiwgeyBpZCB9KTtcbiAgICBpZiAoIWVudHJ5KSByZXR1cm4geyByZW1vdmVkOiBmYWxzZSB9O1xuICAgIGF3YWl0IFRva2VuTW9kZWwuZGVsKFtlbnRyeS5pZF0pO1xuICAgIHJldHVybiB7IHJlbW92ZWQ6IHRydWUgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDthqDtgbAg7Zmc7ISx7ZmUL+u5hO2ZnOyEse2ZlCDthqDquIAgRELsnZggYWN0aXZlIO2VhOuTnCDsl4XrjbDsnbTtirhcbiAgICovXG4gIEBhcGkoeyBodHRwTWV0aG9kOiBcIlBPU1RcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1tdXRhdGlvblwiXSB9KVxuICBhc3luYyB0b2dnbGVUb2tlbihpZDogbnVtYmVyKTogUHJvbWlzZTx7IGFjdGl2ZTogYm9vbGVhbiB9PiB7XG4gICAgY29uc3QgZW50cnkgPSBhd2FpdCBUb2tlbk1vZGVsLmZpbmRPbmUoXCJBXCIsIHsgaWQgfSk7XG4gICAgaWYgKCFlbnRyeSkgcmV0dXJuIHsgYWN0aXZlOiBmYWxzZSB9O1xuXG4gICAgY29uc3QgbmV3QWN0aXZlID0gIWVudHJ5LmFjdGl2ZTtcbiAgICBhd2FpdCBUb2tlbk1vZGVsLnNhdmUoW1xuICAgICAge1xuICAgICAgICBpZCxcbiAgICAgICAgcHJvdmlkZXI6IGVudHJ5LnByb3ZpZGVyLFxuICAgICAgICBjcmVkZW50aWFsczogZW50cnkuY3JlZGVudGlhbHMsXG4gICAgICAgIGFjdGl2ZTogbmV3QWN0aXZlLFxuICAgICAgICBuYW1lOiBlbnRyeS5uYW1lLFxuICAgICAgfSxcbiAgICBdKTtcbiAgICByZXR1cm4geyBhY3RpdmU6IG5ld0FjdGl2ZSB9O1xuICB9XG5cbiAgQGFwaSh7IGh0dHBNZXRob2Q6IFwiUE9TVFwiLCBjbGllbnRzOiBbXCJheGlvc1wiLCBcInRhbnN0YWNrLW11dGF0aW9uXCJdIH0pXG4gIGFzeW5jIG9hdXRoU3RhcnQobmFtZTogc3RyaW5nKTogUHJvbWlzZTxPQXV0aFN0YXJ0UmVzdWx0PiB7XG4gICAgY29uc3QgeyBjb2RlVmVyaWZpZXIsIGNvZGVDaGFsbGVuZ2UsIHN0YXRlIH0gPSBnZW5lcmF0ZVBLQ0UoKTtcblxuICAgIGNvbnN0IHsgcmVkaXJlY3RVcmksIG1vZGUgfSA9IHJlc29sdmVPQXV0aFJlZGlyZWN0KCk7XG4gICAgY29uc3QgYXV0aFVybCA9IGJ1aWxkQXV0aFVybChjb2RlQ2hhbGxlbmdlLCBzdGF0ZSwgcmVkaXJlY3RVcmkpO1xuXG4gICAgYXdhaXQgc2V0T0F1dGhTdGF0ZShzdGF0ZSwgeyBjb2RlVmVyaWZpZXIsIG5hbWUsIHJlZGlyZWN0VXJpIH0pO1xuXG4gICAgcmV0dXJuIHsgYXV0aFVybCwgbW9kZSB9O1xuICB9XG5cbiAgLy8g7L2U65OcIOu2meyXrOuEo+q4sCDtlIzroZzsmrAo7JuQ6rKpIOygkeyGjSk6IOy9mOyGlCDsvZzrsLHsnbQg7ZGc7Iuc7ZWcIGBjb2RlI3N0YXRlYCDrpbwg67Cb7JWEIOq1kO2ZmO2VnOuLpC5cbiAgQGFwaSh7IGh0dHBNZXRob2Q6IFwiUE9TVFwiLCBjbGllbnRzOiBbXCJheGlvc1wiLCBcInRhbnN0YWNrLW11dGF0aW9uXCJdIH0pXG4gIGFzeW5jIG9hdXRoQ29tcGxldGUocGFzdGVkQ29kZTogc3RyaW5nKTogUHJvbWlzZTx7IGFkZGVkOiBib29sZWFuOyBuYW1lOiBzdHJpbmcgfT4ge1xuICAgIGNvbnN0IHRyaW1tZWQgPSBwYXN0ZWRDb2RlLnRyaW0oKTtcbiAgICBjb25zdCBzZXBhcmF0b3JBdCA9IHRyaW1tZWQuaW5kZXhPZihcIiNcIik7XG4gICAgY29uc3QgY29kZSA9IHNlcGFyYXRvckF0ID4gMCA/IHRyaW1tZWQuc2xpY2UoMCwgc2VwYXJhdG9yQXQpIDogXCJcIjtcbiAgICBjb25zdCBzdGF0ZSA9IHNlcGFyYXRvckF0ID4gMCA/IHRyaW1tZWQuc2xpY2Uoc2VwYXJhdG9yQXQgKyAxKSA6IFwiXCI7XG4gICAgaWYgKCFjb2RlIHx8ICFzdGF0ZSkge1xuICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oXG4gICAgICAgIFwiZXhwZWN0ZWQgdGhlIGNvZGUgc2hvd24gYWZ0ZXIgbG9naW4sIGluIGNvZGUjc3RhdGUgZm9ybVwiIGFzIExvY2FsaXplZFN0cmluZyxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgcGVuZGluZyA9IGF3YWl0IGdldE9BdXRoU3RhdGUoc3RhdGUpO1xuICAgIGlmICghcGVuZGluZykge1xuICAgICAgdGhyb3cgbmV3IEJhZFJlcXVlc3RFeGNlcHRpb24oXG4gICAgICAgIFwibG9naW4gc2Vzc2lvbiBub3QgZm91bmQgb3IgZXhwaXJlZCDigJQgc3RhcnQgdGhlIGxvZ2luIGFnYWluXCIgYXMgTG9jYWxpemVkU3RyaW5nLFxuICAgICAgKTtcbiAgICB9XG4gICAgYXdhaXQgZGVsZXRlT0F1dGhTdGF0ZShzdGF0ZSk7XG5cbiAgICBhd2FpdCB0aGlzLmNvbXBsZXRlQW50aHJvcGljTG9naW4oY29kZSwgc3RhdGUsIHBlbmRpbmcpO1xuICAgIHJldHVybiB7IGFkZGVkOiB0cnVlLCBuYW1lOiBwZW5kaW5nLm5hbWUgfTtcbiAgfVxuXG4gIC8vIOq1kO2ZmCArIOqzhOyglSDspJHrs7Ug7KCc6rGwICsg7KCA7J6lIOKAlCByZWRpcmVjdCDsvZzrsLHqs7wg7L2U65OcIOu2meyXrOuEo+q4sCDtlIzroZzsmrDqsIAg6rO17Jyg7ZWc64ukLlxuICBwcml2YXRlIGFzeW5jIGNvbXBsZXRlQW50aHJvcGljTG9naW4oXG4gICAgY29kZTogc3RyaW5nLFxuICAgIHN0YXRlOiBzdHJpbmcsXG4gICAgcGVuZGluZzogUGVuZGluZ09BdXRoLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB0b2tlbnMgPSBhd2FpdCBleGNoYW5nZUNvZGVGb3JUb2tlbnMoXG4gICAgICBjb2RlLFxuICAgICAgcGVuZGluZy5jb2RlVmVyaWZpZXIsXG4gICAgICBzdGF0ZSxcbiAgICAgIHBlbmRpbmcucmVkaXJlY3RVcmksXG4gICAgKTtcblxuICAgIGNvbnN0IHsgaXNOZXcgfSA9IGF3YWl0IFRva2VuTW9kZWwucmVwbGFjZUJ5QWNjb3VudChcImFudGhyb3BpY1wiLCB0b2tlbnMuYWNjb3VudFV1aWQsIHtcbiAgICAgIHByb3ZpZGVyOiBcImFudGhyb3BpY1wiLFxuICAgICAgY3JlZGVudGlhbHM6IHtcbiAgICAgICAgYWNjZXNzVG9rZW46IHRva2Vucy5hY2Nlc3NUb2tlbixcbiAgICAgICAgcmVmcmVzaFRva2VuOiB0b2tlbnMucmVmcmVzaFRva2VuLFxuICAgICAgICBleHBpcmVzQXQ6IHRva2Vucy5leHBpcmVzQXQgPz8gMCxcbiAgICAgICAgYWNjb3VudFV1aWQ6IHRva2Vucy5hY2NvdW50VXVpZCA/PyBcIlwiLFxuICAgICAgfSxcbiAgICAgIG5hbWU6IHBlbmRpbmcubmFtZSxcbiAgICB9KTtcblxuICAgIGlmIChpc05ldykgbm90aWZ5VG9rZW5BZGRlZChwZW5kaW5nLm5hbWUsIFwiYW50aHJvcGljXCIpO1xuICB9XG5cbiAgYXN5bmMgaGFuZGxlT0F1dGhDYWxsYmFjayhjb2RlOiBzdHJpbmcsIHN0YXRlOiBzdHJpbmcsIHJlcGx5OiBGYXN0aWZ5UmVwbHkpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBwZW5kaW5nID0gYXdhaXQgZ2V0T0F1dGhTdGF0ZShzdGF0ZSk7XG4gICAgaWYgKCFwZW5kaW5nKSB7XG4gICAgICBsb2dnZXIud2FybihcIm9hdXRoIGNhbGxiYWNrOiBpbnZhbGlkX3N0YXRlXCIpO1xuICAgICAgcmV0dXJuIHJlcGx5LnJlZGlyZWN0KFwiLz9vYXV0aD1lcnJvciZyZWFzb249aW52YWxpZF9zdGF0ZVwiKTtcbiAgICB9XG4gICAgYXdhaXQgZGVsZXRlT0F1dGhTdGF0ZShzdGF0ZSk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5jb21wbGV0ZUFudGhyb3BpY0xvZ2luKGNvZGUsIHN0YXRlLCBwZW5kaW5nKTtcbiAgICAgIHJldHVybiByZXBseS5yZWRpcmVjdChgLz9vYXV0aD1zdWNjZXNzJm5hbWU9JHtlbmNvZGVVUklDb21wb25lbnQocGVuZGluZy5uYW1lKX1gKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gcmVwbHkucmVkaXJlY3QoYC8/b2F1dGg9ZXJyb3ImcmVhc29uPSR7ZW5jb2RlVVJJQ29tcG9uZW50KChlIGFzIEVycm9yKS5tZXNzYWdlKX1gKTtcbiAgICB9XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJQT1NUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stbXV0YXRpb25cIl0gfSlcbiAgYXN5bmMgb2F1dGhTdGFydE9wZW5BSShuYW1lOiBzdHJpbmcpOiBQcm9taXNlPE9BdXRoU3RhcnRSZXN1bHQ+IHtcbiAgICBpZiAoIVFncmlkRGlzcGF0Y2hlci5vcGVuYWlEaXNwYXRjaGVyKSB0aHJvdyBuZXcgRXJyb3IoXCJPcGVuQUkgZGlzcGF0Y2hlciBub3QgaW5pdGlhbGl6ZWRcIik7XG4gICAgY29uc3QgeyBhdXRoVXJsIH0gPSBhd2FpdCBRZ3JpZERpc3BhdGNoZXIub3BlbmFpRGlzcGF0Y2hlci5zdGFydEJyb3dzZXJMb2dpbihuYW1lKTtcblxuICAgIC8vIGZpcmUtYW5kLWZvcmdldDogY29kZXggbG9naW4g7JmE66OMIOuMgOq4sCDihpIg7Yag7YGwIOyggOyepVxuICAgIFFncmlkRGlzcGF0Y2hlci5vcGVuYWlEaXNwYXRjaGVyXG4gICAgICAuY29tcGxldGVCcm93c2VyTG9naW4oKVxuICAgICAgLnRoZW4oYXN5bmMgKGNyZWRzKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgaXNOZXcgfSA9IGF3YWl0IFRva2VuTW9kZWwucmVwbGFjZUJ5QWNjb3VudChcIm9wZW5haVwiLCBjcmVkcy5hY2NvdW50SWQsIHtcbiAgICAgICAgICBwcm92aWRlcjogXCJvcGVuYWlcIixcbiAgICAgICAgICBjcmVkZW50aWFsczoge1xuICAgICAgICAgICAgYWNjZXNzVG9rZW46IGNyZWRzLmFjY2Vzc1Rva2VuLFxuICAgICAgICAgICAgcmVmcmVzaFRva2VuOiBjcmVkcy5yZWZyZXNoVG9rZW4sXG4gICAgICAgICAgICBpZFRva2VuOiBjcmVkcy5pZFRva2VuLFxuICAgICAgICAgICAgYWNjZXNzVG9rZW5FeHBpcmVzQXQ6IERhdGUubm93KCkgKyAxMCAqIDI0ICogMzYwMCAqIDEwMDAsXG4gICAgICAgICAgICBhY2NvdW50SWQ6IGNyZWRzLmFjY291bnRJZCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG5hbWUsXG4gICAgICAgIH0pO1xuICAgICAgICBsb2dnZXIuaW5mbyhgT3BlbkFJIHRva2VuIHNhdmVkIGZvciAke25hbWV9YCk7XG4gICAgICAgIGlmIChpc05ldykgbm90aWZ5VG9rZW5BZGRlZChuYW1lLCBcIm9wZW5haVwiKTtcbiAgICAgIH0pXG4gICAgICAuY2F0Y2goKGUpID0+IHtcbiAgICAgICAgbG9nZ2VyLndhcm4oYE9wZW5BSSBicm93c2VyIGxvZ2luIGZhaWxlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgIH0pO1xuXG4gICAgcmV0dXJuIHsgYXV0aFVybCwgbW9kZTogXCJyZWRpcmVjdFwiIH07XG4gIH1cblxuICBAYXBpKHsgaHR0cE1ldGhvZDogXCJHRVRcIiwgY2xpZW50czogW1wiYXhpb3NcIiwgXCJ0YW5zdGFjay1xdWVyeVwiXSB9KVxuICBhc3luYyB1c2FnZSh0b2tlbklkPzogbnVtYmVyKTogUHJvbWlzZTxVc2FnZVJlc3BvbnNlPiB7XG4gICAgY29uc3QgeyByb3dzOiBhbGxUb2tlbnMgfSA9IGF3YWl0IFRva2VuTW9kZWwuZmluZE1hbnkoXCJBXCIpO1xuICAgIGNvbnN0IGVudHJ5ID0gdG9rZW5JZFxuICAgICAgPyBhbGxUb2tlbnMuZmluZCgoZSkgPT4gZS5pZCA9PT0gdG9rZW5JZClcbiAgICAgIDogYWxsVG9rZW5zLmZpbmRMYXN0KChlKSA9PiBlLmFjdGl2ZSAmJiBlLnByb3ZpZGVyID09PSBcImFudGhyb3BpY1wiKTtcblxuICAgIGlmICghZW50cnkpIHJldHVybiB7IGVycm9yOiBcIk5PVF9GT1VORFwiIH07XG5cbiAgICBpZiAoZW50cnkucHJvdmlkZXIgPT09IFwib3BlbmFpXCIpIHtcbiAgICAgIGlmICghZW50cnkuYWN0aXZlKSB7XG4gICAgICAgIHJldHVybiB7IHByb3ZpZGVyOiBcIm9wZW5haVwiLCBmaXZlSG91cjogbnVsbCwgc2V2ZW5EYXk6IG51bGwgfTtcbiAgICAgIH1cblxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmF3ID0gYXdhaXQgUWdyaWREaXNwYXRjaGVyLm9wZW5haURpc3BhdGNoZXI/LmdldFJhdGVMaW1pdHNCeVRva2VuSWQoZW50cnkuaWQpO1xuICAgICAgICBjb25zdCBybCA9IHJhdz8uZGF0YS5yYXRlTGltaXRzO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHByb3ZpZGVyOiBcIm9wZW5haVwiLFxuICAgICAgICAgIGZpdmVIb3VyOiBybD8ucHJpbWFyeVxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgdXRpbGl6YXRpb246IHJsLnByaW1hcnkudXNlZFBlcmNlbnQsXG4gICAgICAgICAgICAgICAgcmVzZXRzQXQ6IHVuaXhTZWNvbmRzVG9Jc28ocmwucHJpbWFyeS5yZXNldHNBdCksXG4gICAgICAgICAgICAgICAgd2luZG93RHVyYXRpb25NaW5zOiBybC5wcmltYXJ5LndpbmRvd0R1cmF0aW9uTWlucyxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICAgIHNldmVuRGF5OiBybD8uc2Vjb25kYXJ5XG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICB1dGlsaXphdGlvbjogcmwuc2Vjb25kYXJ5LnVzZWRQZXJjZW50LFxuICAgICAgICAgICAgICAgIHJlc2V0c0F0OiB1bml4U2Vjb25kc1RvSXNvKHJsLnNlY29uZGFyeS5yZXNldHNBdCksXG4gICAgICAgICAgICAgICAgd2luZG93RHVyYXRpb25NaW5zOiBybC5zZWNvbmRhcnkud2luZG93RHVyYXRpb25NaW5zLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IG51bGwsXG4gICAgICAgIH07XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiB7IGVycm9yOiBgT3BlbkFJIHVzYWdlIGZhaWxlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVudHJ5LnByb3ZpZGVyICE9PSBcImFudGhyb3BpY1wiKSB7XG4gICAgICByZXR1cm4geyBlcnJvcjogYHVzYWdlIEFQSSBub3Qgc3VwcG9ydGVkIGZvciBwcm92aWRlcjogJHtlbnRyeS5wcm92aWRlcn1gIH07XG4gICAgfVxuXG4gICAgbGV0IGFjY2Vzc1Rva2VuID0gZ2V0QWNjZXNzVG9rZW4oZW50cnkuY3JlZGVudGlhbHMpO1xuICAgIGNvbnN0IGlzRXhwaXJlZCA9IGdldEV4cGlyZXNBdChlbnRyeS5jcmVkZW50aWFscykgPCBEYXRlLm5vdygpO1xuXG4gICAgaWYgKGlzRXhwaXJlZCAmJiBnZXRSZWZyZXNoVG9rZW4oZW50cnkuY3JlZGVudGlhbHMpKSB7XG4gICAgICB0cnkge1xuICAgICAgICBhY2Nlc3NUb2tlbiA9IGF3YWl0IHRoaXMucmVmcmVzaFRva2VuKGVudHJ5KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgb2F1dGhMb2dnZXIud2FybihgcmVmcmVzaCBmYWlsZWQgZm9yICR7ZW50cnkubmFtZX06ICR7KGUgYXMgRXJyb3IpLm1lc3NhZ2V9YCk7XG4gICAgICAgIHJldHVybiB7IGVycm9yOiBcInJlLWxvZ2luIHJlcXVpcmVkXCIgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCByYXcgPSBhd2FpdCBmZXRjaFVzYWdlKGFjY2Vzc1Rva2VuKTtcbiAgICBpZiAocmF3LmVycm9yICYmIGdldFJlZnJlc2hUb2tlbihlbnRyeS5jcmVkZW50aWFscykpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGFjY2Vzc1Rva2VuID0gYXdhaXQgdGhpcy5yZWZyZXNoVG9rZW4oZW50cnkpO1xuICAgICAgICBjb25zdCByZXRyaWVkID0gYXdhaXQgZmV0Y2hVc2FnZShhY2Nlc3NUb2tlbik7XG4gICAgICAgIGlmIChyZXRyaWVkLmVycm9yKSByZXR1cm4geyBlcnJvcjogcmV0cmllZC5lcnJvciB9O1xuICAgICAgICByZXR1cm4gY29udmVydEFudGhyb3BpY1VzYWdlKHJldHJpZWQpO1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICBvYXV0aExvZ2dlci53YXJuKGByZWZyZXNoIGZhaWxlZCBmb3IgJHtlbnRyeS5uYW1lfTogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgICAgcmV0dXJuIHsgZXJyb3I6IFwicmUtbG9naW4gcmVxdWlyZWRcIiB9O1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAocmF3LmVycm9yKSByZXR1cm4geyBlcnJvcjogcmF3LmVycm9yIH07XG4gICAgcmV0dXJuIGNvbnZlcnRBbnRocm9waWNVc2FnZShyYXcpO1xuICB9XG5cbiAgLy8g64+Z7IucIHJlZnJlc2gg6rCAIO2ajOyghOydhCDqsrnsuZjrqbQg65Kk64qm7J2AIO2YuOy2nOydtCDsnbTrr7gg7Y+Q6riw65CcIHJlZnJlc2ggdG9rZW4g7J2EIOyTsOqyjCDrkJjslrRcbiAgLy8g66mA7Kmh7ZWcIO2GoO2BsOydtCDsgqzrp53snLzroZwg7Jik7YyQ65Cc64ukLiBvcGVuYWktcmVmcmVzaC50cyDsmYAg6rCZ7J2AIHBlci10b2tlbiBkZWR1cCDsnYQg65GU64ukLlxuICBhc3luYyByZWZyZXNoVG9rZW4odG9rZW46IFRva2VuU3Vic2V0QSk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgaW5mbGlnaHQgPSBpbmZsaWdodEFudGhyb3BpY1JlZnJlc2guZ2V0KHRva2VuLmlkKTtcbiAgICBpZiAoaW5mbGlnaHQpIHJldHVybiBpbmZsaWdodDtcblxuICAgIGNvbnN0IHByb21pc2UgPSB0aGlzLmRvUmVmcmVzaFRva2VuKHRva2VuKTtcbiAgICBpbmZsaWdodEFudGhyb3BpY1JlZnJlc2guc2V0KHRva2VuLmlkLCBwcm9taXNlKTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IHByb21pc2U7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGluZmxpZ2h0QW50aHJvcGljUmVmcmVzaC5kZWxldGUodG9rZW4uaWQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZG9SZWZyZXNoVG9rZW4odG9rZW46IFRva2VuU3Vic2V0QSk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgY3JlZHMgPSB0b2tlbi5jcmVkZW50aWFscztcbiAgICBjb25zdCBydCA9IGdldFJlZnJlc2hUb2tlbihjcmVkcyk7XG4gICAgaWYgKCFydCkgdGhyb3cgbmV3IEVycm9yKFwiTm8gcmVmcmVzaCB0b2tlblwiKTtcblxuICAgIGxldCByZWZyZXNoZWQ7XG4gICAgdHJ5IHtcbiAgICAgIHJlZnJlc2hlZCA9IGF3YWl0IHJlZnJlc2hBY2Nlc3NUb2tlbihydCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUgaW5zdGFuY2VvZiBSZWZyZXNoRmFpbGVkRXJyb3IgJiYgZS5pc0F1dGhEZWFkKSB7XG4gICAgICAgIGF3YWl0IGRlYWN0aXZhdGVBdXRoRGVhZFRva2VuKHRva2VuLCBydCwgYGFudGhyb3BpYzoke2Uuc3RhdHVzfWApO1xuICAgICAgfVxuICAgICAgdGhyb3cgZTtcbiAgICB9XG5cbiAgICBjb25zdCB1cGRhdGVkID0gVG9rZW5DcmVkZW50aWFscy5wYXJzZSh7XG4gICAgICAuLi5jcmVkcyxcbiAgICAgIGFjY2Vzc1Rva2VuOiByZWZyZXNoZWQuYWNjZXNzVG9rZW4sXG4gICAgICByZWZyZXNoVG9rZW46IHJlZnJlc2hlZC5yZWZyZXNoVG9rZW4sXG4gICAgICBleHBpcmVzQXQ6IHJlZnJlc2hlZC5leHBpcmVzQXQsXG4gICAgfSk7XG4gICAgYXdhaXQgVG9rZW5Nb2RlbC5zYXZlKFtcbiAgICAgIHtcbiAgICAgICAgaWQ6IHRva2VuLmlkLFxuICAgICAgICBwcm92aWRlcjogdG9rZW4ucHJvdmlkZXIsXG4gICAgICAgIGNyZWRlbnRpYWxzOiB1cGRhdGVkLFxuICAgICAgICBuYW1lOiB0b2tlbi5uYW1lLFxuICAgICAgfSxcbiAgICBdKTtcbiAgICByZXR1cm4gcmVmcmVzaGVkLmFjY2Vzc1Rva2VuO1xuICB9XG5cbiAgQGFwaSh7IGh0dHBNZXRob2Q6IFwiR0VUXCIsIGNsaWVudHM6IFtcImF4aW9zXCIsIFwidGFuc3RhY2stcXVlcnlcIl0gfSlcbiAgYXN5bmMgaGVhbHRoKCk6IFByb21pc2U8SGVhbHRoUmVzcG9uc2U+IHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdHVzOiBcIm9rXCIsXG4gICAgICBhY3RpdmVUb2tlbnM6IFFncmlkRGlzcGF0Y2hlci50b2tlbnMuc2l6ZSxcbiAgICAgIHN1YnNjcmliZXI6IFFncmlkRGlzcGF0Y2hlci5zdWJzY3JpYmVyPy5zdGF0dXMoKSA/PyBudWxsLFxuICAgIH07XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IFFncmlkRnJhbWUgPSBuZXcgUWdyaWRGcmFtZUNsYXNzKCk7XG5cbmZ1bmN0aW9uIGNvbnZlcnRBbnRocm9waWNVc2FnZShyYXc6IEFudGhyb3BpY1VzYWdlUmF3KTogVXNhZ2VSZXNwb25zZSB7XG4gIHJldHVybiB7XG4gICAgcHJvdmlkZXI6IFwiYW50aHJvcGljXCIsXG4gICAgZml2ZUhvdXI6IHJhdy5maXZlX2hvdXJcbiAgICAgID8geyB1dGlsaXphdGlvbjogcmF3LmZpdmVfaG91ci51dGlsaXphdGlvbiwgcmVzZXRzQXQ6IHJhdy5maXZlX2hvdXIucmVzZXRzX2F0IH1cbiAgICAgIDogbnVsbCxcbiAgICBzZXZlbkRheTogcmF3LnNldmVuX2RheVxuICAgICAgPyB7IHV0aWxpemF0aW9uOiByYXcuc2V2ZW5fZGF5LnV0aWxpemF0aW9uLCByZXNldHNBdDogcmF3LnNldmVuX2RheS5yZXNldHNfYXQgfVxuICAgICAgOiBudWxsLFxuICB9O1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFvREEsTUFBTSxpQ0FBaUIsSUFBSSxJQUF3QjtBQUduRCxNQUFNLHFCQUFxQjtBQUMzQixNQUFNLGtCQUFrQjtBQUV4QixTQUFTLGlCQUFpQixTQUFtRDtDQUMzRSxPQUFPLE9BQU8sWUFBWSw0QkFBVyxJQUFJLEtBQUssVUFBVSxHQUFJLEVBQUMsQ0FBQyxZQUFZLElBQUk7QUFDaEY7QUFFQSxlQUFlLGNBQWMsT0FBZSxNQUFtQztDQUM3RSxNQUFNLFFBQVEsbUJBQW1CO0NBQ2pDLElBQUksQ0FBQyxPQUFPLE1BQU0sSUFBSSxNQUFNLDhCQUE4QjtDQUMxRCxNQUFNLE1BQU0sSUFBSTtFQUNkLEtBQUssR0FBRyxxQkFBcUI7RUFDN0IsT0FBTyxLQUFLLFVBQVUsSUFBSTtFQUMxQixLQUFLO0NBQ1AsQ0FBQztBQUNIO0FBRUEsZUFBZSxjQUFjLE9BQWtEO0NBQzdFLE1BQU0sUUFBUSxtQkFBbUI7Q0FDakMsSUFBSSxDQUFDLE9BQU8sTUFBTSxJQUFJLE1BQU0sOEJBQThCO0NBQzFELE1BQU0sTUFBTSxNQUFNLE1BQU0sSUFBWSxFQUFFLEtBQUssR0FBRyxxQkFBcUIsUUFBUSxDQUFDO0NBQzVFLElBQUksQ0FBQyxLQUFLLE9B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