@cartanova/qgrid-cli 2.7.1 → 2.7.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 (1212) hide show
  1. package/README.ko.md +3 -2
  2. package/README.md +3 -2
  3. package/bundle/dist/application/monit/monit.frame.js +27 -14
  4. package/bundle/dist/application/monit/monit.types.js +22 -13
  5. package/bundle/dist/application/qgrid/conv-routing.js +21 -11
  6. package/bundle/dist/application/qgrid/oauth.js +1 -1
  7. package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +15 -4
  8. package/bundle/dist/application/qgrid/qgrid.dispatcher.js +18 -9
  9. package/bundle/dist/application/qgrid/qgrid.frame.js +50 -73
  10. package/bundle/dist/application/qgrid/qgrid.types.js +4 -1
  11. package/bundle/dist/application/qgrid/token-subscriber.js +5 -5
  12. package/bundle/dist/application/qgrid/tool-emulation-schema.js +13 -1
  13. package/bundle/dist/application/qgrid/tool-emulation.js +1 -1
  14. package/bundle/dist/application/queries.generated.js +3 -1
  15. package/bundle/dist/application/request-log/json-schema-type-text.js +55 -0
  16. package/bundle/dist/application/request-log/request-log.model.js +85 -3
  17. package/bundle/dist/application/request-log/request-log.types.js +3 -2
  18. package/bundle/dist/application/request-log/zod-code-format.js +71 -0
  19. package/bundle/dist/application/setting/setting.constant.js +2 -62
  20. package/bundle/dist/application/setting/setting.model.js +3 -3
  21. package/bundle/dist/application/setting/setting.store.js +2 -2
  22. package/bundle/dist/application/sonamu.generated.js +11 -4
  23. package/bundle/dist/application/sonamu.generated.sso.js +7 -3
  24. package/bundle/dist/i18n/sd.generated.js +5 -2
  25. package/bundle/dist/migrations/20260814130113_alter_request_logs_add1_alter1.js +15 -0
  26. package/bundle/dist/migrations/20260814131051_alter_request_logs_add1_alter1.js +15 -0
  27. package/bundle/dist/migrations/20260814134846_alter_request_logs_add1_alter1.js +15 -0
  28. package/bundle/dist/migrations/20260814140759_alter_request_logs_alter1.js +13 -0
  29. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930}/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +2 -2
  30. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930}/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +2 -2
  31. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930}/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +2 -2
  32. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930}/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +2 -2
  33. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930}/node_modules/vitest/dist/chunks/index.DdgEv5B1.js +2 -2
  34. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930}/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +2 -2
  35. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930}/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js +2 -2
  36. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930}/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +2 -2
  37. package/bundle/dist/node_modules/.pnpm/{vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_vi_3892b4338df694f79f7d384fad23d930}/node_modules/vitest/dist/index.js +1 -1
  38. package/bundle/dist/sonamu.config.js +10 -9
  39. package/bundle/dist/testing/setup-mocks.js +2 -2
  40. package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +14 -2
  41. package/bundle/dist/utils/providers/anthropic/claude-session.js +1 -1
  42. package/bundle/dist/utils/providers/anthropic/stream-json-adapter.js +1 -1
  43. package/bundle/dist/utils/providers/common/model-cost.js +1 -1
  44. package/bundle/dist/utils/providers/common/schema-validation.js +1 -1
  45. package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +144 -0
  46. package/bundle/dist/utils/providers/openai/openai-constants.js +4 -2
  47. package/bundle/dist/utils/providers/openai/openai-direct-client.js +327 -0
  48. package/bundle/dist/utils/providers/openai/openai-dispatcher.js +358 -781
  49. package/bundle/dist/utils/providers/openai/openai-oauth.js +84 -0
  50. package/bundle/dist/utils/providers/openai/openai-quota.js +76 -5
  51. package/bundle/dist/utils/providers/openai/openai-refresh.js +3 -3
  52. package/bundle/dist/utils/providers/openai/openai-sse.js +72 -0
  53. package/bundle/dist/utils/providers/openai/openai-transport-config.js +14 -0
  54. package/bundle/src/application/monit/monit.frame.test.ts +14 -17
  55. package/bundle/src/application/monit/monit.frame.ts +23 -12
  56. package/bundle/src/application/monit/monit.types.ts +40 -11
  57. package/bundle/src/application/qgrid/conv-routing.test.ts +67 -0
  58. package/bundle/src/application/qgrid/conv-routing.ts +46 -12
  59. package/bundle/src/application/qgrid/qgrid-oauth-redirect.test.ts +92 -2
  60. package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +3 -0
  61. package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +15 -1
  62. package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +36 -6
  63. package/bundle/src/application/qgrid/qgrid.dispatcher.ts +22 -9
  64. package/bundle/src/application/qgrid/qgrid.frame.ts +55 -94
  65. package/bundle/src/application/qgrid/qgrid.types.ts +11 -4
  66. package/bundle/src/application/qgrid/token-subscriber.ts +4 -4
  67. package/bundle/src/application/qgrid/tool-emulation-schema.ts +1 -1
  68. package/bundle/src/application/qgrid/tool-emulation.test.ts +1 -0
  69. package/bundle/src/application/queries.generated.ts +6 -0
  70. package/bundle/src/application/request-log/json-schema-type-text.test.ts +96 -0
  71. package/bundle/src/application/request-log/json-schema-type-text.ts +83 -0
  72. package/bundle/src/application/request-log/request-log.entity.json +147 -21
  73. package/bundle/src/application/request-log/request-log.model.ts +108 -0
  74. package/bundle/src/application/request-log/request-log.types.ts +2 -0
  75. package/bundle/src/application/request-log/zod-code-format.test.ts +31 -0
  76. package/bundle/src/application/request-log/zod-code-format.ts +73 -0
  77. package/bundle/src/application/setting/setting.constant.test.ts +22 -24
  78. package/bundle/src/application/setting/setting.constant.ts +2 -63
  79. package/bundle/src/application/setting/setting.entity.json +1 -1
  80. package/bundle/src/application/setting/setting.store.ts +1 -1
  81. package/bundle/src/application/sonamu.generated.http +20 -1
  82. package/bundle/src/application/sonamu.generated.sso.ts +4 -0
  83. package/bundle/src/application/sonamu.generated.ts +10 -0
  84. package/bundle/src/i18n/sd.generated.ts +6 -1
  85. package/bundle/src/migrations/20260814130113_alter_request_logs_add1_alter1.ts +15 -0
  86. package/bundle/src/migrations/20260814131051_alter_request_logs_add1_alter1.ts +15 -0
  87. package/bundle/src/migrations/20260814134846_alter_request_logs_add1_alter1.ts +15 -0
  88. package/bundle/src/migrations/20260814140759_alter_request_logs_alter1.ts +13 -0
  89. package/bundle/src/sonamu.config.ts +9 -13
  90. package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +17 -2
  91. package/bundle/src/utils/providers/anthropic/claude-session.ts +1 -3
  92. package/bundle/src/utils/providers/anthropic/stream-json-adapter.test.ts +1 -2
  93. package/bundle/src/utils/providers/anthropic/stream-json-adapter.ts +2 -3
  94. package/bundle/src/utils/providers/common/model-cost.ts +4 -9
  95. package/bundle/src/utils/providers/common/provider-dispatcher.ts +10 -8
  96. package/bundle/src/utils/providers/common/provider-types.ts +48 -0
  97. package/bundle/src/utils/providers/common/schema-validation.ts +1 -1
  98. package/bundle/src/utils/providers/openai/openai-backend-protocol.test.ts +106 -0
  99. package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +255 -0
  100. package/bundle/src/utils/providers/openai/openai-constants.ts +2 -0
  101. package/bundle/src/utils/providers/openai/openai-direct-client.test.ts +610 -0
  102. package/bundle/src/utils/providers/openai/openai-direct-client.ts +478 -0
  103. package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +336 -1723
  104. package/bundle/src/utils/providers/openai/openai-dispatcher.ts +458 -1175
  105. package/bundle/src/utils/providers/openai/openai-oauth.test.ts +95 -0
  106. package/bundle/src/utils/providers/openai/openai-oauth.ts +141 -0
  107. package/bundle/src/utils/providers/openai/openai-quota.test.ts +80 -7
  108. package/bundle/src/utils/providers/openai/openai-quota.ts +105 -4
  109. package/bundle/src/utils/providers/openai/openai-refresh.test.ts +120 -0
  110. package/bundle/src/utils/providers/openai/openai-refresh.ts +3 -1
  111. package/bundle/src/utils/providers/openai/openai-sse.test.ts +52 -0
  112. package/bundle/src/utils/providers/openai/openai-sse.ts +79 -0
  113. package/bundle/src/utils/providers/openai/openai-transport-config.ts +17 -0
  114. package/bundle/web-dist/client/assets/index-BldeEvAK.css +1 -0
  115. package/bundle/web-dist/client/assets/index-DkAXPF9q.js +106 -0
  116. package/bundle/web-dist/client/assets/logs-DlI6OojL.js +1 -0
  117. package/bundle/web-dist/client/assets/monit-qap66dhi.js +1 -0
  118. package/bundle/web-dist/client/assets/{routes-J4bnHVfl.js → routes-CV07Pzde.js} +1 -1
  119. package/bundle/web-dist/client/assets/{services.generated-jGypfumC.js → services.generated-CSW8bhCP.js} +4 -4
  120. package/bundle/web-dist/client/assets/settings-CdYub4yo.js +1 -0
  121. package/bundle/web-dist/client/assets/show-DA1L8DVD.js +2 -0
  122. package/bundle/web-dist/client/assets/{tokens-DDrATjGA.js → tokens-Dt3gfkwP.js} +1 -1
  123. package/bundle/web-dist/client/assets/{use-oauth-login-flow-CptleCFM.js → use-oauth-login-flow-Cwi0HtJY.js} +1 -1
  124. package/bundle/web-dist/client/index.html +3 -3
  125. package/bundle/web-dist/server/assets/{lazyRouteComponent-DOc8TV-P.js → lazyRouteComponent-0y-znAfz.js} +2 -2
  126. package/bundle/web-dist/server/assets/{logs-CfF3nmLM.js → logs-CJBbHM3_.js} +35 -5
  127. package/bundle/web-dist/server/assets/{monit-BSaKhh5D.js → monit-8WAsPETB.js} +144 -51
  128. package/bundle/web-dist/server/assets/{plus-DLFUHsfx.js → plus-9das21ju.js} +1 -1
  129. package/bundle/web-dist/server/assets/{react-dom-BotjLnTK.js → react-dom-zmEq8BVp.js} +1 -1
  130. package/bundle/web-dist/server/assets/{routes-CHMxrTT0.js → routes-B6bX3o41.js} +3 -3
  131. package/bundle/web-dist/server/assets/{services.generated-D3Q3FYot.js → services.generated-DyPeBI00.js} +76 -2
  132. package/bundle/web-dist/server/assets/{settings-DOQjV28c.js → settings-D1u5WdpP.js} +2 -3
  133. package/bundle/web-dist/server/assets/{show-Cn_C6Qvl.js → show-Cr7vwR0l.js} +93 -8
  134. package/bundle/web-dist/server/assets/{tokens-c0EN3iCx.js → tokens-BumM0gnH.js} +3 -3
  135. package/bundle/web-dist/server/assets/{use-oauth-login-flow-B68AbMDE.js → use-oauth-login-flow-DmsHGOlx.js} +1 -1
  136. package/bundle/web-dist/server/entry-server.generated.js +12 -12
  137. package/dist/cli.d.ts +10 -1
  138. package/dist/cli.js +1 -6
  139. package/package.json +3 -2
  140. package/skills/qgrid/SKILL.md +5 -5
  141. package/skills/qgrid/references/ai-sdk-provider-contract.md +16 -10
  142. package/skills/qgrid/references/cli-env-and-server-boot.md +6 -13
  143. package/skills/qgrid/references/decision-rationale.md +15 -23
  144. package/skills/qgrid/references/docs-workflow.md +1 -1
  145. package/skills/qgrid/references/openai-codex-runtime.md +39 -156
  146. package/skills/qgrid/references/prompt-cache-and-usage.md +35 -71
  147. package/skills/qgrid/references/provider-runtime-differences.md +17 -17
  148. package/skills/qgrid/references/repo-map.md +2 -2
  149. package/skills/qgrid/references/request-log-run-lifecycle.md +12 -2
  150. package/skills/qgrid/references/sonamu-api-web-flow.md +4 -0
  151. package/skills/qgrid/references/token-auth-quota-lifecycle.md +14 -24
  152. package/skills/qgrid/references/tool-calling-and-multiturn.md +3 -3
  153. package/skills/qgrid/references/verification-and-debugging.md +17 -15
  154. package/bundle/dist/codex-protocol/AgentPath.js +0 -1
  155. package/bundle/dist/codex-protocol/ApplyPatchApprovalParams.js +0 -1
  156. package/bundle/dist/codex-protocol/ApplyPatchApprovalResponse.js +0 -1
  157. package/bundle/dist/codex-protocol/AuthMode.js +0 -1
  158. package/bundle/dist/codex-protocol/ClientInfo.js +0 -1
  159. package/bundle/dist/codex-protocol/ClientNotification.js +0 -1
  160. package/bundle/dist/codex-protocol/ClientRequest.js +0 -1
  161. package/bundle/dist/codex-protocol/CollaborationMode.js +0 -1
  162. package/bundle/dist/codex-protocol/ContentItem.js +0 -1
  163. package/bundle/dist/codex-protocol/ConversationGitInfo.js +0 -1
  164. package/bundle/dist/codex-protocol/ConversationSummary.js +0 -1
  165. package/bundle/dist/codex-protocol/ExecCommandApprovalParams.js +0 -1
  166. package/bundle/dist/codex-protocol/ExecCommandApprovalResponse.js +0 -1
  167. package/bundle/dist/codex-protocol/ExecPolicyAmendment.js +0 -1
  168. package/bundle/dist/codex-protocol/FileChange.js +0 -1
  169. package/bundle/dist/codex-protocol/ForcedLoginMethod.js +0 -1
  170. package/bundle/dist/codex-protocol/FunctionCallOutputBody.js +0 -1
  171. package/bundle/dist/codex-protocol/FunctionCallOutputContentItem.js +0 -1
  172. package/bundle/dist/codex-protocol/FuzzyFileSearchMatchType.js +0 -1
  173. package/bundle/dist/codex-protocol/FuzzyFileSearchParams.js +0 -1
  174. package/bundle/dist/codex-protocol/FuzzyFileSearchResponse.js +0 -1
  175. package/bundle/dist/codex-protocol/FuzzyFileSearchResult.js +0 -1
  176. package/bundle/dist/codex-protocol/FuzzyFileSearchSessionCompletedNotification.js +0 -1
  177. package/bundle/dist/codex-protocol/FuzzyFileSearchSessionUpdatedNotification.js +0 -1
  178. package/bundle/dist/codex-protocol/GetAuthStatusParams.js +0 -1
  179. package/bundle/dist/codex-protocol/GetAuthStatusResponse.js +0 -1
  180. package/bundle/dist/codex-protocol/GetConversationSummaryParams.js +0 -1
  181. package/bundle/dist/codex-protocol/GetConversationSummaryResponse.js +0 -1
  182. package/bundle/dist/codex-protocol/GitDiffToRemoteParams.js +0 -1
  183. package/bundle/dist/codex-protocol/GitDiffToRemoteResponse.js +0 -1
  184. package/bundle/dist/codex-protocol/GitSha.js +0 -1
  185. package/bundle/dist/codex-protocol/ImageDetail.js +0 -1
  186. package/bundle/dist/codex-protocol/InitializeCapabilities.js +0 -1
  187. package/bundle/dist/codex-protocol/InitializeParams.js +0 -1
  188. package/bundle/dist/codex-protocol/InitializeResponse.js +0 -1
  189. package/bundle/dist/codex-protocol/InputModality.js +0 -1
  190. package/bundle/dist/codex-protocol/InternalSessionSource.js +0 -1
  191. package/bundle/dist/codex-protocol/LocalShellAction.js +0 -1
  192. package/bundle/dist/codex-protocol/LocalShellExecAction.js +0 -1
  193. package/bundle/dist/codex-protocol/LocalShellStatus.js +0 -1
  194. package/bundle/dist/codex-protocol/MessagePhase.js +0 -1
  195. package/bundle/dist/codex-protocol/ModeKind.js +0 -1
  196. package/bundle/dist/codex-protocol/NetworkPolicyAmendment.js +0 -1
  197. package/bundle/dist/codex-protocol/NetworkPolicyRuleAction.js +0 -1
  198. package/bundle/dist/codex-protocol/ParsedCommand.js +0 -1
  199. package/bundle/dist/codex-protocol/Personality.js +0 -1
  200. package/bundle/dist/codex-protocol/PlanType.js +0 -1
  201. package/bundle/dist/codex-protocol/RealtimeConversationVersion.js +0 -1
  202. package/bundle/dist/codex-protocol/RealtimeOutputModality.js +0 -1
  203. package/bundle/dist/codex-protocol/RealtimeVoice.js +0 -1
  204. package/bundle/dist/codex-protocol/RealtimeVoicesList.js +0 -1
  205. package/bundle/dist/codex-protocol/ReasoningEffort.js +0 -1
  206. package/bundle/dist/codex-protocol/ReasoningItemContent.js +0 -1
  207. package/bundle/dist/codex-protocol/ReasoningItemReasoningSummary.js +0 -1
  208. package/bundle/dist/codex-protocol/ReasoningSummary.js +0 -1
  209. package/bundle/dist/codex-protocol/RequestId.js +0 -1
  210. package/bundle/dist/codex-protocol/Resource.js +0 -1
  211. package/bundle/dist/codex-protocol/ResourceContent.js +0 -1
  212. package/bundle/dist/codex-protocol/ResourceTemplate.js +0 -1
  213. package/bundle/dist/codex-protocol/ResponseItem.js +0 -1
  214. package/bundle/dist/codex-protocol/ReviewDecision.js +0 -1
  215. package/bundle/dist/codex-protocol/ServerNotification.js +0 -1
  216. package/bundle/dist/codex-protocol/ServerRequest.js +0 -1
  217. package/bundle/dist/codex-protocol/SessionSource.js +0 -1
  218. package/bundle/dist/codex-protocol/Settings.js +0 -1
  219. package/bundle/dist/codex-protocol/SubAgentSource.js +0 -1
  220. package/bundle/dist/codex-protocol/ThreadId.js +0 -1
  221. package/bundle/dist/codex-protocol/ThreadMemoryMode.js +0 -1
  222. package/bundle/dist/codex-protocol/Tool.js +0 -1
  223. package/bundle/dist/codex-protocol/Verbosity.js +0 -1
  224. package/bundle/dist/codex-protocol/WebSearchAction.js +0 -1
  225. package/bundle/dist/codex-protocol/WebSearchContextSize.js +0 -1
  226. package/bundle/dist/codex-protocol/WebSearchLocation.js +0 -1
  227. package/bundle/dist/codex-protocol/WebSearchMode.js +0 -1
  228. package/bundle/dist/codex-protocol/WebSearchToolConfig.js +0 -1
  229. package/bundle/dist/codex-protocol/index.js +0 -2
  230. package/bundle/dist/codex-protocol/serde_json/JsonValue.js +0 -1
  231. package/bundle/dist/codex-protocol/v2/Account.js +0 -1
  232. package/bundle/dist/codex-protocol/v2/AccountLoginCompletedNotification.js +0 -1
  233. package/bundle/dist/codex-protocol/v2/AccountRateLimitsUpdatedNotification.js +0 -1
  234. package/bundle/dist/codex-protocol/v2/AccountUpdatedNotification.js +0 -1
  235. package/bundle/dist/codex-protocol/v2/ActivePermissionProfile.js +0 -1
  236. package/bundle/dist/codex-protocol/v2/ActivePermissionProfileModification.js +0 -1
  237. package/bundle/dist/codex-protocol/v2/AddCreditsNudgeCreditType.js +0 -1
  238. package/bundle/dist/codex-protocol/v2/AddCreditsNudgeEmailStatus.js +0 -1
  239. package/bundle/dist/codex-protocol/v2/AdditionalFileSystemPermissions.js +0 -1
  240. package/bundle/dist/codex-protocol/v2/AdditionalNetworkPermissions.js +0 -1
  241. package/bundle/dist/codex-protocol/v2/AdditionalPermissionProfile.js +0 -1
  242. package/bundle/dist/codex-protocol/v2/AgentMessageDeltaNotification.js +0 -1
  243. package/bundle/dist/codex-protocol/v2/AnalyticsConfig.js +0 -1
  244. package/bundle/dist/codex-protocol/v2/AppBranding.js +0 -1
  245. package/bundle/dist/codex-protocol/v2/AppInfo.js +0 -1
  246. package/bundle/dist/codex-protocol/v2/AppListUpdatedNotification.js +0 -1
  247. package/bundle/dist/codex-protocol/v2/AppMetadata.js +0 -1
  248. package/bundle/dist/codex-protocol/v2/AppReview.js +0 -1
  249. package/bundle/dist/codex-protocol/v2/AppScreenshot.js +0 -1
  250. package/bundle/dist/codex-protocol/v2/AppSummary.js +0 -1
  251. package/bundle/dist/codex-protocol/v2/AppToolApproval.js +0 -1
  252. package/bundle/dist/codex-protocol/v2/AppToolsConfig.js +0 -1
  253. package/bundle/dist/codex-protocol/v2/ApprovalsReviewer.js +0 -1
  254. package/bundle/dist/codex-protocol/v2/AppsConfig.js +0 -1
  255. package/bundle/dist/codex-protocol/v2/AppsDefaultConfig.js +0 -1
  256. package/bundle/dist/codex-protocol/v2/AppsListParams.js +0 -1
  257. package/bundle/dist/codex-protocol/v2/AppsListResponse.js +0 -1
  258. package/bundle/dist/codex-protocol/v2/AskForApproval.js +0 -1
  259. package/bundle/dist/codex-protocol/v2/AutoReviewDecisionSource.js +0 -1
  260. package/bundle/dist/codex-protocol/v2/ByteRange.js +0 -1
  261. package/bundle/dist/codex-protocol/v2/CancelLoginAccountParams.js +0 -1
  262. package/bundle/dist/codex-protocol/v2/CancelLoginAccountResponse.js +0 -1
  263. package/bundle/dist/codex-protocol/v2/CancelLoginAccountStatus.js +0 -1
  264. package/bundle/dist/codex-protocol/v2/ChatgptAuthTokensRefreshParams.js +0 -1
  265. package/bundle/dist/codex-protocol/v2/ChatgptAuthTokensRefreshReason.js +0 -1
  266. package/bundle/dist/codex-protocol/v2/ChatgptAuthTokensRefreshResponse.js +0 -1
  267. package/bundle/dist/codex-protocol/v2/CodexErrorInfo.js +0 -1
  268. package/bundle/dist/codex-protocol/v2/CollabAgentState.js +0 -1
  269. package/bundle/dist/codex-protocol/v2/CollabAgentStatus.js +0 -1
  270. package/bundle/dist/codex-protocol/v2/CollabAgentTool.js +0 -1
  271. package/bundle/dist/codex-protocol/v2/CollabAgentToolCallStatus.js +0 -1
  272. package/bundle/dist/codex-protocol/v2/CollaborationModeMask.js +0 -1
  273. package/bundle/dist/codex-protocol/v2/CommandAction.js +0 -1
  274. package/bundle/dist/codex-protocol/v2/CommandExecOutputDeltaNotification.js +0 -1
  275. package/bundle/dist/codex-protocol/v2/CommandExecOutputStream.js +0 -1
  276. package/bundle/dist/codex-protocol/v2/CommandExecParams.js +0 -1
  277. package/bundle/dist/codex-protocol/v2/CommandExecResizeParams.js +0 -1
  278. package/bundle/dist/codex-protocol/v2/CommandExecResizeResponse.js +0 -1
  279. package/bundle/dist/codex-protocol/v2/CommandExecResponse.js +0 -1
  280. package/bundle/dist/codex-protocol/v2/CommandExecTerminalSize.js +0 -1
  281. package/bundle/dist/codex-protocol/v2/CommandExecTerminateParams.js +0 -1
  282. package/bundle/dist/codex-protocol/v2/CommandExecTerminateResponse.js +0 -1
  283. package/bundle/dist/codex-protocol/v2/CommandExecWriteParams.js +0 -1
  284. package/bundle/dist/codex-protocol/v2/CommandExecWriteResponse.js +0 -1
  285. package/bundle/dist/codex-protocol/v2/CommandExecutionApprovalDecision.js +0 -1
  286. package/bundle/dist/codex-protocol/v2/CommandExecutionOutputDeltaNotification.js +0 -1
  287. package/bundle/dist/codex-protocol/v2/CommandExecutionRequestApprovalParams.js +0 -1
  288. package/bundle/dist/codex-protocol/v2/CommandExecutionRequestApprovalResponse.js +0 -1
  289. package/bundle/dist/codex-protocol/v2/CommandExecutionSource.js +0 -1
  290. package/bundle/dist/codex-protocol/v2/CommandExecutionStatus.js +0 -1
  291. package/bundle/dist/codex-protocol/v2/CommandMigration.js +0 -1
  292. package/bundle/dist/codex-protocol/v2/Config.js +0 -1
  293. package/bundle/dist/codex-protocol/v2/ConfigBatchWriteParams.js +0 -1
  294. package/bundle/dist/codex-protocol/v2/ConfigEdit.js +0 -1
  295. package/bundle/dist/codex-protocol/v2/ConfigLayer.js +0 -1
  296. package/bundle/dist/codex-protocol/v2/ConfigLayerMetadata.js +0 -1
  297. package/bundle/dist/codex-protocol/v2/ConfigLayerSource.js +0 -1
  298. package/bundle/dist/codex-protocol/v2/ConfigReadParams.js +0 -1
  299. package/bundle/dist/codex-protocol/v2/ConfigReadResponse.js +0 -1
  300. package/bundle/dist/codex-protocol/v2/ConfigRequirements.js +0 -1
  301. package/bundle/dist/codex-protocol/v2/ConfigRequirementsReadResponse.js +0 -1
  302. package/bundle/dist/codex-protocol/v2/ConfigValueWriteParams.js +0 -1
  303. package/bundle/dist/codex-protocol/v2/ConfigWarningNotification.js +0 -1
  304. package/bundle/dist/codex-protocol/v2/ConfigWriteResponse.js +0 -1
  305. package/bundle/dist/codex-protocol/v2/ConfiguredHookHandler.js +0 -1
  306. package/bundle/dist/codex-protocol/v2/ConfiguredHookMatcherGroup.js +0 -1
  307. package/bundle/dist/codex-protocol/v2/ContextCompactedNotification.js +0 -1
  308. package/bundle/dist/codex-protocol/v2/CreditsSnapshot.js +0 -1
  309. package/bundle/dist/codex-protocol/v2/DeprecationNoticeNotification.js +0 -1
  310. package/bundle/dist/codex-protocol/v2/DynamicToolCallOutputContentItem.js +0 -1
  311. package/bundle/dist/codex-protocol/v2/DynamicToolCallParams.js +0 -1
  312. package/bundle/dist/codex-protocol/v2/DynamicToolCallResponse.js +0 -1
  313. package/bundle/dist/codex-protocol/v2/DynamicToolCallStatus.js +0 -1
  314. package/bundle/dist/codex-protocol/v2/DynamicToolSpec.js +0 -1
  315. package/bundle/dist/codex-protocol/v2/ErrorNotification.js +0 -1
  316. package/bundle/dist/codex-protocol/v2/ExecPolicyAmendment.js +0 -1
  317. package/bundle/dist/codex-protocol/v2/ExperimentalFeature.js +0 -1
  318. package/bundle/dist/codex-protocol/v2/ExperimentalFeatureEnablementSetParams.js +0 -1
  319. package/bundle/dist/codex-protocol/v2/ExperimentalFeatureEnablementSetResponse.js +0 -1
  320. package/bundle/dist/codex-protocol/v2/ExperimentalFeatureListParams.js +0 -1
  321. package/bundle/dist/codex-protocol/v2/ExperimentalFeatureListResponse.js +0 -1
  322. package/bundle/dist/codex-protocol/v2/ExperimentalFeatureStage.js +0 -1
  323. package/bundle/dist/codex-protocol/v2/ExternalAgentConfigDetectParams.js +0 -1
  324. package/bundle/dist/codex-protocol/v2/ExternalAgentConfigDetectResponse.js +0 -1
  325. package/bundle/dist/codex-protocol/v2/ExternalAgentConfigImportCompletedNotification.js +0 -1
  326. package/bundle/dist/codex-protocol/v2/ExternalAgentConfigImportParams.js +0 -1
  327. package/bundle/dist/codex-protocol/v2/ExternalAgentConfigImportResponse.js +0 -1
  328. package/bundle/dist/codex-protocol/v2/ExternalAgentConfigMigrationItem.js +0 -1
  329. package/bundle/dist/codex-protocol/v2/ExternalAgentConfigMigrationItemType.js +0 -1
  330. package/bundle/dist/codex-protocol/v2/FeedbackUploadParams.js +0 -1
  331. package/bundle/dist/codex-protocol/v2/FeedbackUploadResponse.js +0 -1
  332. package/bundle/dist/codex-protocol/v2/FileChangeApprovalDecision.js +0 -1
  333. package/bundle/dist/codex-protocol/v2/FileChangeOutputDeltaNotification.js +0 -1
  334. package/bundle/dist/codex-protocol/v2/FileChangePatchUpdatedNotification.js +0 -1
  335. package/bundle/dist/codex-protocol/v2/FileChangeRequestApprovalParams.js +0 -1
  336. package/bundle/dist/codex-protocol/v2/FileChangeRequestApprovalResponse.js +0 -1
  337. package/bundle/dist/codex-protocol/v2/FileSystemAccessMode.js +0 -1
  338. package/bundle/dist/codex-protocol/v2/FileSystemPath.js +0 -1
  339. package/bundle/dist/codex-protocol/v2/FileSystemSandboxEntry.js +0 -1
  340. package/bundle/dist/codex-protocol/v2/FileSystemSpecialPath.js +0 -1
  341. package/bundle/dist/codex-protocol/v2/FileUpdateChange.js +0 -1
  342. package/bundle/dist/codex-protocol/v2/FsChangedNotification.js +0 -1
  343. package/bundle/dist/codex-protocol/v2/FsCopyParams.js +0 -1
  344. package/bundle/dist/codex-protocol/v2/FsCopyResponse.js +0 -1
  345. package/bundle/dist/codex-protocol/v2/FsCreateDirectoryParams.js +0 -1
  346. package/bundle/dist/codex-protocol/v2/FsCreateDirectoryResponse.js +0 -1
  347. package/bundle/dist/codex-protocol/v2/FsGetMetadataParams.js +0 -1
  348. package/bundle/dist/codex-protocol/v2/FsGetMetadataResponse.js +0 -1
  349. package/bundle/dist/codex-protocol/v2/FsReadDirectoryEntry.js +0 -1
  350. package/bundle/dist/codex-protocol/v2/FsReadDirectoryParams.js +0 -1
  351. package/bundle/dist/codex-protocol/v2/FsReadDirectoryResponse.js +0 -1
  352. package/bundle/dist/codex-protocol/v2/FsReadFileParams.js +0 -1
  353. package/bundle/dist/codex-protocol/v2/FsReadFileResponse.js +0 -1
  354. package/bundle/dist/codex-protocol/v2/FsRemoveParams.js +0 -1
  355. package/bundle/dist/codex-protocol/v2/FsRemoveResponse.js +0 -1
  356. package/bundle/dist/codex-protocol/v2/FsUnwatchParams.js +0 -1
  357. package/bundle/dist/codex-protocol/v2/FsUnwatchResponse.js +0 -1
  358. package/bundle/dist/codex-protocol/v2/FsWatchParams.js +0 -1
  359. package/bundle/dist/codex-protocol/v2/FsWatchResponse.js +0 -1
  360. package/bundle/dist/codex-protocol/v2/FsWriteFileParams.js +0 -1
  361. package/bundle/dist/codex-protocol/v2/FsWriteFileResponse.js +0 -1
  362. package/bundle/dist/codex-protocol/v2/GetAccountParams.js +0 -1
  363. package/bundle/dist/codex-protocol/v2/GetAccountRateLimitsResponse.js +0 -1
  364. package/bundle/dist/codex-protocol/v2/GetAccountResponse.js +0 -1
  365. package/bundle/dist/codex-protocol/v2/GitInfo.js +0 -1
  366. package/bundle/dist/codex-protocol/v2/GrantedPermissionProfile.js +0 -1
  367. package/bundle/dist/codex-protocol/v2/GuardianApprovalReview.js +0 -1
  368. package/bundle/dist/codex-protocol/v2/GuardianApprovalReviewAction.js +0 -1
  369. package/bundle/dist/codex-protocol/v2/GuardianApprovalReviewStatus.js +0 -1
  370. package/bundle/dist/codex-protocol/v2/GuardianCommandSource.js +0 -1
  371. package/bundle/dist/codex-protocol/v2/GuardianRiskLevel.js +0 -1
  372. package/bundle/dist/codex-protocol/v2/GuardianUserAuthorization.js +0 -1
  373. package/bundle/dist/codex-protocol/v2/GuardianWarningNotification.js +0 -1
  374. package/bundle/dist/codex-protocol/v2/HookCompletedNotification.js +0 -1
  375. package/bundle/dist/codex-protocol/v2/HookErrorInfo.js +0 -1
  376. package/bundle/dist/codex-protocol/v2/HookEventName.js +0 -1
  377. package/bundle/dist/codex-protocol/v2/HookExecutionMode.js +0 -1
  378. package/bundle/dist/codex-protocol/v2/HookHandlerType.js +0 -1
  379. package/bundle/dist/codex-protocol/v2/HookMetadata.js +0 -1
  380. package/bundle/dist/codex-protocol/v2/HookMigration.js +0 -1
  381. package/bundle/dist/codex-protocol/v2/HookOutputEntry.js +0 -1
  382. package/bundle/dist/codex-protocol/v2/HookOutputEntryKind.js +0 -1
  383. package/bundle/dist/codex-protocol/v2/HookPromptFragment.js +0 -1
  384. package/bundle/dist/codex-protocol/v2/HookRunStatus.js +0 -1
  385. package/bundle/dist/codex-protocol/v2/HookRunSummary.js +0 -1
  386. package/bundle/dist/codex-protocol/v2/HookScope.js +0 -1
  387. package/bundle/dist/codex-protocol/v2/HookSource.js +0 -1
  388. package/bundle/dist/codex-protocol/v2/HookStartedNotification.js +0 -1
  389. package/bundle/dist/codex-protocol/v2/HookTrustStatus.js +0 -1
  390. package/bundle/dist/codex-protocol/v2/HooksListEntry.js +0 -1
  391. package/bundle/dist/codex-protocol/v2/HooksListParams.js +0 -1
  392. package/bundle/dist/codex-protocol/v2/HooksListResponse.js +0 -1
  393. package/bundle/dist/codex-protocol/v2/ItemCompletedNotification.js +0 -1
  394. package/bundle/dist/codex-protocol/v2/ItemGuardianApprovalReviewCompletedNotification.js +0 -1
  395. package/bundle/dist/codex-protocol/v2/ItemGuardianApprovalReviewStartedNotification.js +0 -1
  396. package/bundle/dist/codex-protocol/v2/ItemStartedNotification.js +0 -1
  397. package/bundle/dist/codex-protocol/v2/ListMcpServerStatusParams.js +0 -1
  398. package/bundle/dist/codex-protocol/v2/ListMcpServerStatusResponse.js +0 -1
  399. package/bundle/dist/codex-protocol/v2/LoginAccountParams.js +0 -1
  400. package/bundle/dist/codex-protocol/v2/LoginAccountResponse.js +0 -1
  401. package/bundle/dist/codex-protocol/v2/LogoutAccountResponse.js +0 -1
  402. package/bundle/dist/codex-protocol/v2/ManagedHooksRequirements.js +0 -1
  403. package/bundle/dist/codex-protocol/v2/MarketplaceAddParams.js +0 -1
  404. package/bundle/dist/codex-protocol/v2/MarketplaceAddResponse.js +0 -1
  405. package/bundle/dist/codex-protocol/v2/MarketplaceInterface.js +0 -1
  406. package/bundle/dist/codex-protocol/v2/MarketplaceLoadErrorInfo.js +0 -1
  407. package/bundle/dist/codex-protocol/v2/MarketplaceRemoveParams.js +0 -1
  408. package/bundle/dist/codex-protocol/v2/MarketplaceRemoveResponse.js +0 -1
  409. package/bundle/dist/codex-protocol/v2/MarketplaceUpgradeErrorInfo.js +0 -1
  410. package/bundle/dist/codex-protocol/v2/MarketplaceUpgradeParams.js +0 -1
  411. package/bundle/dist/codex-protocol/v2/MarketplaceUpgradeResponse.js +0 -1
  412. package/bundle/dist/codex-protocol/v2/McpAuthStatus.js +0 -1
  413. package/bundle/dist/codex-protocol/v2/McpElicitationArrayType.js +0 -1
  414. package/bundle/dist/codex-protocol/v2/McpElicitationBooleanSchema.js +0 -1
  415. package/bundle/dist/codex-protocol/v2/McpElicitationBooleanType.js +0 -1
  416. package/bundle/dist/codex-protocol/v2/McpElicitationConstOption.js +0 -1
  417. package/bundle/dist/codex-protocol/v2/McpElicitationEnumSchema.js +0 -1
  418. package/bundle/dist/codex-protocol/v2/McpElicitationLegacyTitledEnumSchema.js +0 -1
  419. package/bundle/dist/codex-protocol/v2/McpElicitationMultiSelectEnumSchema.js +0 -1
  420. package/bundle/dist/codex-protocol/v2/McpElicitationNumberSchema.js +0 -1
  421. package/bundle/dist/codex-protocol/v2/McpElicitationNumberType.js +0 -1
  422. package/bundle/dist/codex-protocol/v2/McpElicitationObjectType.js +0 -1
  423. package/bundle/dist/codex-protocol/v2/McpElicitationPrimitiveSchema.js +0 -1
  424. package/bundle/dist/codex-protocol/v2/McpElicitationSchema.js +0 -1
  425. package/bundle/dist/codex-protocol/v2/McpElicitationSingleSelectEnumSchema.js +0 -1
  426. package/bundle/dist/codex-protocol/v2/McpElicitationStringFormat.js +0 -1
  427. package/bundle/dist/codex-protocol/v2/McpElicitationStringSchema.js +0 -1
  428. package/bundle/dist/codex-protocol/v2/McpElicitationStringType.js +0 -1
  429. package/bundle/dist/codex-protocol/v2/McpElicitationTitledEnumItems.js +0 -1
  430. package/bundle/dist/codex-protocol/v2/McpElicitationTitledMultiSelectEnumSchema.js +0 -1
  431. package/bundle/dist/codex-protocol/v2/McpElicitationTitledSingleSelectEnumSchema.js +0 -1
  432. package/bundle/dist/codex-protocol/v2/McpElicitationUntitledEnumItems.js +0 -1
  433. package/bundle/dist/codex-protocol/v2/McpElicitationUntitledMultiSelectEnumSchema.js +0 -1
  434. package/bundle/dist/codex-protocol/v2/McpElicitationUntitledSingleSelectEnumSchema.js +0 -1
  435. package/bundle/dist/codex-protocol/v2/McpResourceReadParams.js +0 -1
  436. package/bundle/dist/codex-protocol/v2/McpResourceReadResponse.js +0 -1
  437. package/bundle/dist/codex-protocol/v2/McpServerElicitationAction.js +0 -1
  438. package/bundle/dist/codex-protocol/v2/McpServerElicitationRequestParams.js +0 -1
  439. package/bundle/dist/codex-protocol/v2/McpServerElicitationRequestResponse.js +0 -1
  440. package/bundle/dist/codex-protocol/v2/McpServerMigration.js +0 -1
  441. package/bundle/dist/codex-protocol/v2/McpServerOauthLoginCompletedNotification.js +0 -1
  442. package/bundle/dist/codex-protocol/v2/McpServerOauthLoginParams.js +0 -1
  443. package/bundle/dist/codex-protocol/v2/McpServerOauthLoginResponse.js +0 -1
  444. package/bundle/dist/codex-protocol/v2/McpServerRefreshResponse.js +0 -1
  445. package/bundle/dist/codex-protocol/v2/McpServerStartupState.js +0 -1
  446. package/bundle/dist/codex-protocol/v2/McpServerStatus.js +0 -1
  447. package/bundle/dist/codex-protocol/v2/McpServerStatusDetail.js +0 -1
  448. package/bundle/dist/codex-protocol/v2/McpServerStatusUpdatedNotification.js +0 -1
  449. package/bundle/dist/codex-protocol/v2/McpServerToolCallParams.js +0 -1
  450. package/bundle/dist/codex-protocol/v2/McpServerToolCallResponse.js +0 -1
  451. package/bundle/dist/codex-protocol/v2/McpToolCallError.js +0 -1
  452. package/bundle/dist/codex-protocol/v2/McpToolCallProgressNotification.js +0 -1
  453. package/bundle/dist/codex-protocol/v2/McpToolCallResult.js +0 -1
  454. package/bundle/dist/codex-protocol/v2/McpToolCallStatus.js +0 -1
  455. package/bundle/dist/codex-protocol/v2/MemoryCitation.js +0 -1
  456. package/bundle/dist/codex-protocol/v2/MemoryCitationEntry.js +0 -1
  457. package/bundle/dist/codex-protocol/v2/MergeStrategy.js +0 -1
  458. package/bundle/dist/codex-protocol/v2/MigrationDetails.js +0 -1
  459. package/bundle/dist/codex-protocol/v2/Model.js +0 -1
  460. package/bundle/dist/codex-protocol/v2/ModelAvailabilityNux.js +0 -1
  461. package/bundle/dist/codex-protocol/v2/ModelListParams.js +0 -1
  462. package/bundle/dist/codex-protocol/v2/ModelListResponse.js +0 -1
  463. package/bundle/dist/codex-protocol/v2/ModelProviderCapabilitiesReadParams.js +0 -1
  464. package/bundle/dist/codex-protocol/v2/ModelProviderCapabilitiesReadResponse.js +0 -1
  465. package/bundle/dist/codex-protocol/v2/ModelRerouteReason.js +0 -1
  466. package/bundle/dist/codex-protocol/v2/ModelReroutedNotification.js +0 -1
  467. package/bundle/dist/codex-protocol/v2/ModelServiceTier.js +0 -1
  468. package/bundle/dist/codex-protocol/v2/ModelUpgradeInfo.js +0 -1
  469. package/bundle/dist/codex-protocol/v2/ModelVerification.js +0 -1
  470. package/bundle/dist/codex-protocol/v2/ModelVerificationNotification.js +0 -1
  471. package/bundle/dist/codex-protocol/v2/NetworkAccess.js +0 -1
  472. package/bundle/dist/codex-protocol/v2/NetworkApprovalContext.js +0 -1
  473. package/bundle/dist/codex-protocol/v2/NetworkApprovalProtocol.js +0 -1
  474. package/bundle/dist/codex-protocol/v2/NetworkDomainPermission.js +0 -1
  475. package/bundle/dist/codex-protocol/v2/NetworkPolicyAmendment.js +0 -1
  476. package/bundle/dist/codex-protocol/v2/NetworkPolicyRuleAction.js +0 -1
  477. package/bundle/dist/codex-protocol/v2/NetworkRequirements.js +0 -1
  478. package/bundle/dist/codex-protocol/v2/NetworkUnixSocketPermission.js +0 -1
  479. package/bundle/dist/codex-protocol/v2/NonSteerableTurnKind.js +0 -1
  480. package/bundle/dist/codex-protocol/v2/OverriddenMetadata.js +0 -1
  481. package/bundle/dist/codex-protocol/v2/PatchApplyStatus.js +0 -1
  482. package/bundle/dist/codex-protocol/v2/PatchChangeKind.js +0 -1
  483. package/bundle/dist/codex-protocol/v2/PermissionGrantScope.js +0 -1
  484. package/bundle/dist/codex-protocol/v2/PermissionProfile.js +0 -1
  485. package/bundle/dist/codex-protocol/v2/PermissionProfileFileSystemPermissions.js +0 -1
  486. package/bundle/dist/codex-protocol/v2/PermissionProfileModificationParams.js +0 -1
  487. package/bundle/dist/codex-protocol/v2/PermissionProfileNetworkPermissions.js +0 -1
  488. package/bundle/dist/codex-protocol/v2/PermissionProfileSelectionParams.js +0 -1
  489. package/bundle/dist/codex-protocol/v2/PermissionsRequestApprovalParams.js +0 -1
  490. package/bundle/dist/codex-protocol/v2/PermissionsRequestApprovalResponse.js +0 -1
  491. package/bundle/dist/codex-protocol/v2/PlanDeltaNotification.js +0 -1
  492. package/bundle/dist/codex-protocol/v2/PluginAuthPolicy.js +0 -1
  493. package/bundle/dist/codex-protocol/v2/PluginAvailability.js +0 -1
  494. package/bundle/dist/codex-protocol/v2/PluginDetail.js +0 -1
  495. package/bundle/dist/codex-protocol/v2/PluginHookSummary.js +0 -1
  496. package/bundle/dist/codex-protocol/v2/PluginInstallParams.js +0 -1
  497. package/bundle/dist/codex-protocol/v2/PluginInstallPolicy.js +0 -1
  498. package/bundle/dist/codex-protocol/v2/PluginInstallResponse.js +0 -1
  499. package/bundle/dist/codex-protocol/v2/PluginInterface.js +0 -1
  500. package/bundle/dist/codex-protocol/v2/PluginListMarketplaceKind.js +0 -1
  501. package/bundle/dist/codex-protocol/v2/PluginListParams.js +0 -1
  502. package/bundle/dist/codex-protocol/v2/PluginListResponse.js +0 -1
  503. package/bundle/dist/codex-protocol/v2/PluginMarketplaceEntry.js +0 -1
  504. package/bundle/dist/codex-protocol/v2/PluginReadParams.js +0 -1
  505. package/bundle/dist/codex-protocol/v2/PluginReadResponse.js +0 -1
  506. package/bundle/dist/codex-protocol/v2/PluginShareContext.js +0 -1
  507. package/bundle/dist/codex-protocol/v2/PluginShareDeleteParams.js +0 -1
  508. package/bundle/dist/codex-protocol/v2/PluginShareDeleteResponse.js +0 -1
  509. package/bundle/dist/codex-protocol/v2/PluginShareDiscoverability.js +0 -1
  510. package/bundle/dist/codex-protocol/v2/PluginShareListItem.js +0 -1
  511. package/bundle/dist/codex-protocol/v2/PluginShareListParams.js +0 -1
  512. package/bundle/dist/codex-protocol/v2/PluginShareListResponse.js +0 -1
  513. package/bundle/dist/codex-protocol/v2/PluginSharePrincipal.js +0 -1
  514. package/bundle/dist/codex-protocol/v2/PluginSharePrincipalType.js +0 -1
  515. package/bundle/dist/codex-protocol/v2/PluginShareSaveParams.js +0 -1
  516. package/bundle/dist/codex-protocol/v2/PluginShareSaveResponse.js +0 -1
  517. package/bundle/dist/codex-protocol/v2/PluginShareTarget.js +0 -1
  518. package/bundle/dist/codex-protocol/v2/PluginShareUpdateDiscoverability.js +0 -1
  519. package/bundle/dist/codex-protocol/v2/PluginShareUpdateTargetsParams.js +0 -1
  520. package/bundle/dist/codex-protocol/v2/PluginShareUpdateTargetsResponse.js +0 -1
  521. package/bundle/dist/codex-protocol/v2/PluginSkillReadParams.js +0 -1
  522. package/bundle/dist/codex-protocol/v2/PluginSkillReadResponse.js +0 -1
  523. package/bundle/dist/codex-protocol/v2/PluginSource.js +0 -1
  524. package/bundle/dist/codex-protocol/v2/PluginSummary.js +0 -1
  525. package/bundle/dist/codex-protocol/v2/PluginUninstallParams.js +0 -1
  526. package/bundle/dist/codex-protocol/v2/PluginUninstallResponse.js +0 -1
  527. package/bundle/dist/codex-protocol/v2/PluginsMigration.js +0 -1
  528. package/bundle/dist/codex-protocol/v2/ProcessExitedNotification.js +0 -1
  529. package/bundle/dist/codex-protocol/v2/ProcessOutputDeltaNotification.js +0 -1
  530. package/bundle/dist/codex-protocol/v2/ProcessOutputStream.js +0 -1
  531. package/bundle/dist/codex-protocol/v2/ProcessTerminalSize.js +0 -1
  532. package/bundle/dist/codex-protocol/v2/ProfileV2.js +0 -1
  533. package/bundle/dist/codex-protocol/v2/RateLimitReachedType.js +0 -1
  534. package/bundle/dist/codex-protocol/v2/RateLimitSnapshot.js +0 -1
  535. package/bundle/dist/codex-protocol/v2/RateLimitWindow.js +0 -1
  536. package/bundle/dist/codex-protocol/v2/RawResponseItemCompletedNotification.js +0 -1
  537. package/bundle/dist/codex-protocol/v2/ReasoningEffortOption.js +0 -1
  538. package/bundle/dist/codex-protocol/v2/ReasoningSummaryPartAddedNotification.js +0 -1
  539. package/bundle/dist/codex-protocol/v2/ReasoningSummaryTextDeltaNotification.js +0 -1
  540. package/bundle/dist/codex-protocol/v2/ReasoningTextDeltaNotification.js +0 -1
  541. package/bundle/dist/codex-protocol/v2/RemoteControlConnectionStatus.js +0 -1
  542. package/bundle/dist/codex-protocol/v2/RemoteControlStatusChangedNotification.js +0 -1
  543. package/bundle/dist/codex-protocol/v2/RequestPermissionProfile.js +0 -1
  544. package/bundle/dist/codex-protocol/v2/ResidencyRequirement.js +0 -1
  545. package/bundle/dist/codex-protocol/v2/ReviewDelivery.js +0 -1
  546. package/bundle/dist/codex-protocol/v2/ReviewStartParams.js +0 -1
  547. package/bundle/dist/codex-protocol/v2/ReviewStartResponse.js +0 -1
  548. package/bundle/dist/codex-protocol/v2/ReviewTarget.js +0 -1
  549. package/bundle/dist/codex-protocol/v2/SandboxMode.js +0 -1
  550. package/bundle/dist/codex-protocol/v2/SandboxPolicy.js +0 -1
  551. package/bundle/dist/codex-protocol/v2/SandboxWorkspaceWrite.js +0 -1
  552. package/bundle/dist/codex-protocol/v2/SendAddCreditsNudgeEmailParams.js +0 -1
  553. package/bundle/dist/codex-protocol/v2/SendAddCreditsNudgeEmailResponse.js +0 -1
  554. package/bundle/dist/codex-protocol/v2/ServerRequestResolvedNotification.js +0 -1
  555. package/bundle/dist/codex-protocol/v2/SessionMigration.js +0 -1
  556. package/bundle/dist/codex-protocol/v2/SessionSource.js +0 -1
  557. package/bundle/dist/codex-protocol/v2/SkillDependencies.js +0 -1
  558. package/bundle/dist/codex-protocol/v2/SkillErrorInfo.js +0 -1
  559. package/bundle/dist/codex-protocol/v2/SkillInterface.js +0 -1
  560. package/bundle/dist/codex-protocol/v2/SkillMetadata.js +0 -1
  561. package/bundle/dist/codex-protocol/v2/SkillScope.js +0 -1
  562. package/bundle/dist/codex-protocol/v2/SkillSummary.js +0 -1
  563. package/bundle/dist/codex-protocol/v2/SkillToolDependency.js +0 -1
  564. package/bundle/dist/codex-protocol/v2/SkillsChangedNotification.js +0 -1
  565. package/bundle/dist/codex-protocol/v2/SkillsConfigWriteParams.js +0 -1
  566. package/bundle/dist/codex-protocol/v2/SkillsConfigWriteResponse.js +0 -1
  567. package/bundle/dist/codex-protocol/v2/SkillsListEntry.js +0 -1
  568. package/bundle/dist/codex-protocol/v2/SkillsListParams.js +0 -1
  569. package/bundle/dist/codex-protocol/v2/SkillsListResponse.js +0 -1
  570. package/bundle/dist/codex-protocol/v2/SortDirection.js +0 -1
  571. package/bundle/dist/codex-protocol/v2/SubagentMigration.js +0 -1
  572. package/bundle/dist/codex-protocol/v2/TerminalInteractionNotification.js +0 -1
  573. package/bundle/dist/codex-protocol/v2/TextElement.js +0 -1
  574. package/bundle/dist/codex-protocol/v2/TextPosition.js +0 -1
  575. package/bundle/dist/codex-protocol/v2/TextRange.js +0 -1
  576. package/bundle/dist/codex-protocol/v2/Thread.js +0 -1
  577. package/bundle/dist/codex-protocol/v2/ThreadActiveFlag.js +0 -1
  578. package/bundle/dist/codex-protocol/v2/ThreadApproveGuardianDeniedActionParams.js +0 -1
  579. package/bundle/dist/codex-protocol/v2/ThreadApproveGuardianDeniedActionResponse.js +0 -1
  580. package/bundle/dist/codex-protocol/v2/ThreadArchiveParams.js +0 -1
  581. package/bundle/dist/codex-protocol/v2/ThreadArchiveResponse.js +0 -1
  582. package/bundle/dist/codex-protocol/v2/ThreadArchivedNotification.js +0 -1
  583. package/bundle/dist/codex-protocol/v2/ThreadClosedNotification.js +0 -1
  584. package/bundle/dist/codex-protocol/v2/ThreadCompactStartParams.js +0 -1
  585. package/bundle/dist/codex-protocol/v2/ThreadCompactStartResponse.js +0 -1
  586. package/bundle/dist/codex-protocol/v2/ThreadForkParams.js +0 -1
  587. package/bundle/dist/codex-protocol/v2/ThreadForkResponse.js +0 -1
  588. package/bundle/dist/codex-protocol/v2/ThreadGoal.js +0 -1
  589. package/bundle/dist/codex-protocol/v2/ThreadGoalClearedNotification.js +0 -1
  590. package/bundle/dist/codex-protocol/v2/ThreadGoalStatus.js +0 -1
  591. package/bundle/dist/codex-protocol/v2/ThreadGoalUpdatedNotification.js +0 -1
  592. package/bundle/dist/codex-protocol/v2/ThreadInjectItemsParams.js +0 -1
  593. package/bundle/dist/codex-protocol/v2/ThreadInjectItemsResponse.js +0 -1
  594. package/bundle/dist/codex-protocol/v2/ThreadItem.js +0 -1
  595. package/bundle/dist/codex-protocol/v2/ThreadListParams.js +0 -1
  596. package/bundle/dist/codex-protocol/v2/ThreadListResponse.js +0 -1
  597. package/bundle/dist/codex-protocol/v2/ThreadLoadedListParams.js +0 -1
  598. package/bundle/dist/codex-protocol/v2/ThreadLoadedListResponse.js +0 -1
  599. package/bundle/dist/codex-protocol/v2/ThreadMetadataGitInfoUpdateParams.js +0 -1
  600. package/bundle/dist/codex-protocol/v2/ThreadMetadataUpdateParams.js +0 -1
  601. package/bundle/dist/codex-protocol/v2/ThreadMetadataUpdateResponse.js +0 -1
  602. package/bundle/dist/codex-protocol/v2/ThreadNameUpdatedNotification.js +0 -1
  603. package/bundle/dist/codex-protocol/v2/ThreadReadParams.js +0 -1
  604. package/bundle/dist/codex-protocol/v2/ThreadReadResponse.js +0 -1
  605. package/bundle/dist/codex-protocol/v2/ThreadRealtimeAudioChunk.js +0 -1
  606. package/bundle/dist/codex-protocol/v2/ThreadRealtimeClosedNotification.js +0 -1
  607. package/bundle/dist/codex-protocol/v2/ThreadRealtimeErrorNotification.js +0 -1
  608. package/bundle/dist/codex-protocol/v2/ThreadRealtimeItemAddedNotification.js +0 -1
  609. package/bundle/dist/codex-protocol/v2/ThreadRealtimeOutputAudioDeltaNotification.js +0 -1
  610. package/bundle/dist/codex-protocol/v2/ThreadRealtimeSdpNotification.js +0 -1
  611. package/bundle/dist/codex-protocol/v2/ThreadRealtimeStartTransport.js +0 -1
  612. package/bundle/dist/codex-protocol/v2/ThreadRealtimeStartedNotification.js +0 -1
  613. package/bundle/dist/codex-protocol/v2/ThreadRealtimeTranscriptDeltaNotification.js +0 -1
  614. package/bundle/dist/codex-protocol/v2/ThreadRealtimeTranscriptDoneNotification.js +0 -1
  615. package/bundle/dist/codex-protocol/v2/ThreadResumeParams.js +0 -1
  616. package/bundle/dist/codex-protocol/v2/ThreadResumeResponse.js +0 -1
  617. package/bundle/dist/codex-protocol/v2/ThreadRollbackParams.js +0 -1
  618. package/bundle/dist/codex-protocol/v2/ThreadRollbackResponse.js +0 -1
  619. package/bundle/dist/codex-protocol/v2/ThreadSetNameParams.js +0 -1
  620. package/bundle/dist/codex-protocol/v2/ThreadSetNameResponse.js +0 -1
  621. package/bundle/dist/codex-protocol/v2/ThreadShellCommandParams.js +0 -1
  622. package/bundle/dist/codex-protocol/v2/ThreadShellCommandResponse.js +0 -1
  623. package/bundle/dist/codex-protocol/v2/ThreadSortKey.js +0 -1
  624. package/bundle/dist/codex-protocol/v2/ThreadSource.js +0 -1
  625. package/bundle/dist/codex-protocol/v2/ThreadSourceKind.js +0 -1
  626. package/bundle/dist/codex-protocol/v2/ThreadStartParams.js +0 -1
  627. package/bundle/dist/codex-protocol/v2/ThreadStartResponse.js +0 -1
  628. package/bundle/dist/codex-protocol/v2/ThreadStartSource.js +0 -1
  629. package/bundle/dist/codex-protocol/v2/ThreadStartedNotification.js +0 -1
  630. package/bundle/dist/codex-protocol/v2/ThreadStatus.js +0 -1
  631. package/bundle/dist/codex-protocol/v2/ThreadStatusChangedNotification.js +0 -1
  632. package/bundle/dist/codex-protocol/v2/ThreadTokenUsage.js +0 -1
  633. package/bundle/dist/codex-protocol/v2/ThreadTokenUsageUpdatedNotification.js +0 -1
  634. package/bundle/dist/codex-protocol/v2/ThreadUnarchiveParams.js +0 -1
  635. package/bundle/dist/codex-protocol/v2/ThreadUnarchiveResponse.js +0 -1
  636. package/bundle/dist/codex-protocol/v2/ThreadUnarchivedNotification.js +0 -1
  637. package/bundle/dist/codex-protocol/v2/ThreadUnsubscribeParams.js +0 -1
  638. package/bundle/dist/codex-protocol/v2/ThreadUnsubscribeResponse.js +0 -1
  639. package/bundle/dist/codex-protocol/v2/ThreadUnsubscribeStatus.js +0 -1
  640. package/bundle/dist/codex-protocol/v2/TokenUsageBreakdown.js +0 -1
  641. package/bundle/dist/codex-protocol/v2/ToolRequestUserInputAnswer.js +0 -1
  642. package/bundle/dist/codex-protocol/v2/ToolRequestUserInputOption.js +0 -1
  643. package/bundle/dist/codex-protocol/v2/ToolRequestUserInputParams.js +0 -1
  644. package/bundle/dist/codex-protocol/v2/ToolRequestUserInputQuestion.js +0 -1
  645. package/bundle/dist/codex-protocol/v2/ToolRequestUserInputResponse.js +0 -1
  646. package/bundle/dist/codex-protocol/v2/ToolsV2.js +0 -1
  647. package/bundle/dist/codex-protocol/v2/Turn.js +0 -1
  648. package/bundle/dist/codex-protocol/v2/TurnCompletedNotification.js +0 -1
  649. package/bundle/dist/codex-protocol/v2/TurnDiffUpdatedNotification.js +0 -1
  650. package/bundle/dist/codex-protocol/v2/TurnEnvironmentParams.js +0 -1
  651. package/bundle/dist/codex-protocol/v2/TurnError.js +0 -1
  652. package/bundle/dist/codex-protocol/v2/TurnInterruptParams.js +0 -1
  653. package/bundle/dist/codex-protocol/v2/TurnInterruptResponse.js +0 -1
  654. package/bundle/dist/codex-protocol/v2/TurnItemsView.js +0 -1
  655. package/bundle/dist/codex-protocol/v2/TurnPlanStep.js +0 -1
  656. package/bundle/dist/codex-protocol/v2/TurnPlanStepStatus.js +0 -1
  657. package/bundle/dist/codex-protocol/v2/TurnPlanUpdatedNotification.js +0 -1
  658. package/bundle/dist/codex-protocol/v2/TurnStartParams.js +0 -1
  659. package/bundle/dist/codex-protocol/v2/TurnStartResponse.js +0 -1
  660. package/bundle/dist/codex-protocol/v2/TurnStartedNotification.js +0 -1
  661. package/bundle/dist/codex-protocol/v2/TurnStatus.js +0 -1
  662. package/bundle/dist/codex-protocol/v2/TurnSteerParams.js +0 -1
  663. package/bundle/dist/codex-protocol/v2/TurnSteerResponse.js +0 -1
  664. package/bundle/dist/codex-protocol/v2/UserInput.js +0 -1
  665. package/bundle/dist/codex-protocol/v2/WarningNotification.js +0 -1
  666. package/bundle/dist/codex-protocol/v2/WebSearchAction.js +0 -1
  667. package/bundle/dist/codex-protocol/v2/WindowsSandboxReadiness.js +0 -1
  668. package/bundle/dist/codex-protocol/v2/WindowsSandboxReadinessResponse.js +0 -1
  669. package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupCompletedNotification.js +0 -1
  670. package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupMode.js +0 -1
  671. package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupStartParams.js +0 -1
  672. package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupStartResponse.js +0 -1
  673. package/bundle/dist/codex-protocol/v2/WindowsWorldWritableWarningNotification.js +0 -1
  674. package/bundle/dist/codex-protocol/v2/WriteStatus.js +0 -1
  675. package/bundle/dist/codex-protocol/v2/index.js +0 -7
  676. package/bundle/dist/utils/providers/openai/codex-rpc.js +0 -153
  677. package/bundle/dist/utils/providers/openai/codex-worker.js +0 -642
  678. package/bundle/dist/utils/providers/openai/openai-worker-pool-config.js +0 -51
  679. package/bundle/src/codex-protocol/AbsolutePathBuf.ts +0 -14
  680. package/bundle/src/codex-protocol/AgentPath.ts +0 -5
  681. package/bundle/src/codex-protocol/ApplyPatchApprovalParams.ts +0 -24
  682. package/bundle/src/codex-protocol/ApplyPatchApprovalResponse.ts +0 -6
  683. package/bundle/src/codex-protocol/AuthMode.ts +0 -8
  684. package/bundle/src/codex-protocol/ClientInfo.ts +0 -5
  685. package/bundle/src/codex-protocol/ClientNotification.ts +0 -5
  686. package/bundle/src/codex-protocol/ClientRequest.ts +0 -176
  687. package/bundle/src/codex-protocol/CollaborationMode.ts +0 -10
  688. package/bundle/src/codex-protocol/ContentItem.ts +0 -9
  689. package/bundle/src/codex-protocol/ConversationGitInfo.ts +0 -9
  690. package/bundle/src/codex-protocol/ConversationSummary.ts +0 -19
  691. package/bundle/src/codex-protocol/ExecCommandApprovalParams.ts +0 -22
  692. package/bundle/src/codex-protocol/ExecCommandApprovalResponse.ts +0 -6
  693. package/bundle/src/codex-protocol/ExecPolicyAmendment.ts +0 -12
  694. package/bundle/src/codex-protocol/FileChange.ts +0 -8
  695. package/bundle/src/codex-protocol/ForcedLoginMethod.ts +0 -5
  696. package/bundle/src/codex-protocol/FunctionCallOutputBody.ts +0 -6
  697. package/bundle/src/codex-protocol/FunctionCallOutputContentItem.ts +0 -12
  698. package/bundle/src/codex-protocol/FuzzyFileSearchMatchType.ts +0 -5
  699. package/bundle/src/codex-protocol/FuzzyFileSearchParams.ts +0 -9
  700. package/bundle/src/codex-protocol/FuzzyFileSearchResponse.ts +0 -6
  701. package/bundle/src/codex-protocol/FuzzyFileSearchResult.ts +0 -16
  702. package/bundle/src/codex-protocol/FuzzyFileSearchSessionCompletedNotification.ts +0 -5
  703. package/bundle/src/codex-protocol/FuzzyFileSearchSessionUpdatedNotification.ts +0 -10
  704. package/bundle/src/codex-protocol/GetAuthStatusParams.ts +0 -5
  705. package/bundle/src/codex-protocol/GetAuthStatusResponse.ts +0 -10
  706. package/bundle/src/codex-protocol/GetConversationSummaryParams.ts +0 -6
  707. package/bundle/src/codex-protocol/GetConversationSummaryResponse.ts +0 -6
  708. package/bundle/src/codex-protocol/GitDiffToRemoteParams.ts +0 -5
  709. package/bundle/src/codex-protocol/GitDiffToRemoteResponse.ts +0 -6
  710. package/bundle/src/codex-protocol/GitSha.ts +0 -5
  711. package/bundle/src/codex-protocol/ImageDetail.ts +0 -5
  712. package/bundle/src/codex-protocol/InitializeCapabilities.ts +0 -18
  713. package/bundle/src/codex-protocol/InitializeParams.ts +0 -10
  714. package/bundle/src/codex-protocol/InitializeResponse.ts +0 -22
  715. package/bundle/src/codex-protocol/InputModality.ts +0 -8
  716. package/bundle/src/codex-protocol/InternalSessionSource.ts +0 -5
  717. package/bundle/src/codex-protocol/LocalShellAction.ts +0 -6
  718. package/bundle/src/codex-protocol/LocalShellExecAction.ts +0 -11
  719. package/bundle/src/codex-protocol/LocalShellStatus.ts +0 -5
  720. package/bundle/src/codex-protocol/MessagePhase.ts +0 -11
  721. package/bundle/src/codex-protocol/ModeKind.ts +0 -8
  722. package/bundle/src/codex-protocol/NetworkPolicyAmendment.ts +0 -6
  723. package/bundle/src/codex-protocol/NetworkPolicyRuleAction.ts +0 -5
  724. package/bundle/src/codex-protocol/ParsedCommand.ts +0 -20
  725. package/bundle/src/codex-protocol/Personality.ts +0 -5
  726. package/bundle/src/codex-protocol/PlanType.ts +0 -17
  727. package/bundle/src/codex-protocol/RealtimeConversationVersion.ts +0 -5
  728. package/bundle/src/codex-protocol/RealtimeOutputModality.ts +0 -5
  729. package/bundle/src/codex-protocol/RealtimeVoice.ts +0 -24
  730. package/bundle/src/codex-protocol/RealtimeVoicesList.ts +0 -11
  731. package/bundle/src/codex-protocol/ReasoningEffort.ts +0 -8
  732. package/bundle/src/codex-protocol/ReasoningItemContent.ts +0 -7
  733. package/bundle/src/codex-protocol/ReasoningItemReasoningSummary.ts +0 -5
  734. package/bundle/src/codex-protocol/ReasoningSummary.ts +0 -10
  735. package/bundle/src/codex-protocol/RequestId.ts +0 -5
  736. package/bundle/src/codex-protocol/Resource.ts +0 -19
  737. package/bundle/src/codex-protocol/ResourceContent.ts +0 -27
  738. package/bundle/src/codex-protocol/ResourceTemplate.ts +0 -16
  739. package/bundle/src/codex-protocol/ResponseItem.ts +0 -63
  740. package/bundle/src/codex-protocol/ReviewDecision.ts +0 -17
  741. package/bundle/src/codex-protocol/ServerNotification.ts +0 -154
  742. package/bundle/src/codex-protocol/ServerRequest.ts +0 -47
  743. package/bundle/src/codex-protocol/SessionSource.ts +0 -15
  744. package/bundle/src/codex-protocol/Settings.ts +0 -13
  745. package/bundle/src/codex-protocol/SubAgentSource.ts +0 -20
  746. package/bundle/src/codex-protocol/ThreadId.ts +0 -5
  747. package/bundle/src/codex-protocol/ThreadMemoryMode.ts +0 -5
  748. package/bundle/src/codex-protocol/Tool.ts +0 -18
  749. package/bundle/src/codex-protocol/Verbosity.ts +0 -9
  750. package/bundle/src/codex-protocol/WebSearchAction.ts +0 -9
  751. package/bundle/src/codex-protocol/WebSearchContextSize.ts +0 -5
  752. package/bundle/src/codex-protocol/WebSearchLocation.ts +0 -10
  753. package/bundle/src/codex-protocol/WebSearchMode.ts +0 -5
  754. package/bundle/src/codex-protocol/WebSearchToolConfig.ts +0 -11
  755. package/bundle/src/codex-protocol/index.ts +0 -79
  756. package/bundle/src/codex-protocol/serde_json/JsonValue.ts +0 -11
  757. package/bundle/src/codex-protocol/v2/Account.ts +0 -9
  758. package/bundle/src/codex-protocol/v2/AccountLoginCompletedNotification.ts +0 -9
  759. package/bundle/src/codex-protocol/v2/AccountRateLimitsUpdatedNotification.ts +0 -6
  760. package/bundle/src/codex-protocol/v2/AccountUpdatedNotification.ts +0 -7
  761. package/bundle/src/codex-protocol/v2/ActivePermissionProfile.ts +0 -22
  762. package/bundle/src/codex-protocol/v2/ActivePermissionProfileModification.ts +0 -9
  763. package/bundle/src/codex-protocol/v2/AddCreditsNudgeCreditType.ts +0 -5
  764. package/bundle/src/codex-protocol/v2/AddCreditsNudgeEmailStatus.ts +0 -5
  765. package/bundle/src/codex-protocol/v2/AdditionalFileSystemPermissions.ts +0 -18
  766. package/bundle/src/codex-protocol/v2/AdditionalNetworkPermissions.ts +0 -5
  767. package/bundle/src/codex-protocol/v2/AdditionalPermissionProfile.ts +0 -13
  768. package/bundle/src/codex-protocol/v2/AgentMessageDeltaNotification.ts +0 -10
  769. package/bundle/src/codex-protocol/v2/AnalyticsConfig.ts +0 -14
  770. package/bundle/src/codex-protocol/v2/AppBranding.ts +0 -15
  771. package/bundle/src/codex-protocol/v2/AppInfo.ts +0 -32
  772. package/bundle/src/codex-protocol/v2/AppListUpdatedNotification.ts +0 -9
  773. package/bundle/src/codex-protocol/v2/AppMetadata.ts +0 -20
  774. package/bundle/src/codex-protocol/v2/AppReview.ts +0 -5
  775. package/bundle/src/codex-protocol/v2/AppScreenshot.ts +0 -5
  776. package/bundle/src/codex-protocol/v2/AppSummary.ts +0 -14
  777. package/bundle/src/codex-protocol/v2/AppToolApproval.ts +0 -5
  778. package/bundle/src/codex-protocol/v2/AppToolsConfig.ts +0 -8
  779. package/bundle/src/codex-protocol/v2/ApprovalsReviewer.ts +0 -12
  780. package/bundle/src/codex-protocol/v2/AppsConfig.ts +0 -17
  781. package/bundle/src/codex-protocol/v2/AppsDefaultConfig.ts +0 -9
  782. package/bundle/src/codex-protocol/v2/AppsListParams.ts +0 -25
  783. package/bundle/src/codex-protocol/v2/AppsListResponse.ts +0 -16
  784. package/bundle/src/codex-protocol/v2/AskForApproval.ts +0 -18
  785. package/bundle/src/codex-protocol/v2/AutoReviewDecisionSource.ts +0 -8
  786. package/bundle/src/codex-protocol/v2/ByteRange.ts +0 -5
  787. package/bundle/src/codex-protocol/v2/CancelLoginAccountParams.ts +0 -5
  788. package/bundle/src/codex-protocol/v2/CancelLoginAccountResponse.ts +0 -6
  789. package/bundle/src/codex-protocol/v2/CancelLoginAccountStatus.ts +0 -5
  790. package/bundle/src/codex-protocol/v2/ChatgptAuthTokensRefreshParams.ts +0 -18
  791. package/bundle/src/codex-protocol/v2/ChatgptAuthTokensRefreshReason.ts +0 -5
  792. package/bundle/src/codex-protocol/v2/ChatgptAuthTokensRefreshResponse.ts +0 -9
  793. package/bundle/src/codex-protocol/v2/CodexErrorInfo.ts +0 -27
  794. package/bundle/src/codex-protocol/v2/CollabAgentState.ts +0 -6
  795. package/bundle/src/codex-protocol/v2/CollabAgentStatus.ts +0 -12
  796. package/bundle/src/codex-protocol/v2/CollabAgentTool.ts +0 -5
  797. package/bundle/src/codex-protocol/v2/CollabAgentToolCallStatus.ts +0 -5
  798. package/bundle/src/codex-protocol/v2/CollaborationModeMask.ts +0 -15
  799. package/bundle/src/codex-protocol/v2/CommandAction.ts +0 -10
  800. package/bundle/src/codex-protocol/v2/CommandExecOutputDeltaNotification.ts +0 -31
  801. package/bundle/src/codex-protocol/v2/CommandExecOutputStream.ts +0 -8
  802. package/bundle/src/codex-protocol/v2/CommandExecParams.ts +0 -87
  803. package/bundle/src/codex-protocol/v2/CommandExecResizeParams.ts +0 -19
  804. package/bundle/src/codex-protocol/v2/CommandExecResizeResponse.ts +0 -8
  805. package/bundle/src/codex-protocol/v2/CommandExecResponse.ts +0 -25
  806. package/bundle/src/codex-protocol/v2/CommandExecTerminalSize.ts +0 -17
  807. package/bundle/src/codex-protocol/v2/CommandExecTerminateParams.ts +0 -14
  808. package/bundle/src/codex-protocol/v2/CommandExecTerminateResponse.ts +0 -8
  809. package/bundle/src/codex-protocol/v2/CommandExecWriteParams.ts +0 -23
  810. package/bundle/src/codex-protocol/v2/CommandExecWriteResponse.ts +0 -8
  811. package/bundle/src/codex-protocol/v2/CommandExecutionApprovalDecision.ts +0 -13
  812. package/bundle/src/codex-protocol/v2/CommandExecutionOutputDeltaNotification.ts +0 -10
  813. package/bundle/src/codex-protocol/v2/CommandExecutionRequestApprovalParams.ts +0 -47
  814. package/bundle/src/codex-protocol/v2/CommandExecutionRequestApprovalResponse.ts +0 -8
  815. package/bundle/src/codex-protocol/v2/CommandExecutionSource.ts +0 -9
  816. package/bundle/src/codex-protocol/v2/CommandExecutionStatus.ts +0 -5
  817. package/bundle/src/codex-protocol/v2/CommandMigration.ts +0 -5
  818. package/bundle/src/codex-protocol/v2/Config.ts +0 -53
  819. package/bundle/src/codex-protocol/v2/ConfigBatchWriteParams.ts +0 -17
  820. package/bundle/src/codex-protocol/v2/ConfigEdit.ts +0 -7
  821. package/bundle/src/codex-protocol/v2/ConfigLayer.ts +0 -12
  822. package/bundle/src/codex-protocol/v2/ConfigLayerMetadata.ts +0 -6
  823. package/bundle/src/codex-protocol/v2/ConfigLayerSource.ts +0 -27
  824. package/bundle/src/codex-protocol/v2/ConfigReadParams.ts +0 -13
  825. package/bundle/src/codex-protocol/v2/ConfigReadResponse.ts +0 -12
  826. package/bundle/src/codex-protocol/v2/ConfigRequirements.ts +0 -15
  827. package/bundle/src/codex-protocol/v2/ConfigRequirementsReadResponse.ts +0 -11
  828. package/bundle/src/codex-protocol/v2/ConfigValueWriteParams.ts +0 -16
  829. package/bundle/src/codex-protocol/v2/ConfigWarningNotification.ts +0 -23
  830. package/bundle/src/codex-protocol/v2/ConfigWriteResponse.ts +0 -16
  831. package/bundle/src/codex-protocol/v2/ConfiguredHookHandler.ts +0 -14
  832. package/bundle/src/codex-protocol/v2/ConfiguredHookMatcherGroup.ts +0 -9
  833. package/bundle/src/codex-protocol/v2/ContextCompactedNotification.ts +0 -8
  834. package/bundle/src/codex-protocol/v2/CreditsSnapshot.ts +0 -5
  835. package/bundle/src/codex-protocol/v2/DeprecationNoticeNotification.ts +0 -14
  836. package/bundle/src/codex-protocol/v2/DynamicToolCallOutputContentItem.ts +0 -7
  837. package/bundle/src/codex-protocol/v2/DynamicToolCallParams.ts +0 -13
  838. package/bundle/src/codex-protocol/v2/DynamicToolCallResponse.ts +0 -9
  839. package/bundle/src/codex-protocol/v2/DynamicToolCallStatus.ts +0 -5
  840. package/bundle/src/codex-protocol/v2/DynamicToolSpec.ts +0 -12
  841. package/bundle/src/codex-protocol/v2/ErrorNotification.ts +0 -11
  842. package/bundle/src/codex-protocol/v2/ExecPolicyAmendment.ts +0 -5
  843. package/bundle/src/codex-protocol/v2/ExperimentalFeature.ts +0 -38
  844. package/bundle/src/codex-protocol/v2/ExperimentalFeatureEnablementSetParams.ts +0 -13
  845. package/bundle/src/codex-protocol/v2/ExperimentalFeatureEnablementSetResponse.ts +0 -10
  846. package/bundle/src/codex-protocol/v2/ExperimentalFeatureListParams.ts +0 -14
  847. package/bundle/src/codex-protocol/v2/ExperimentalFeatureListResponse.ts +0 -13
  848. package/bundle/src/codex-protocol/v2/ExperimentalFeatureStage.ts +0 -10
  849. package/bundle/src/codex-protocol/v2/ExternalAgentConfigDetectParams.ts +0 -14
  850. package/bundle/src/codex-protocol/v2/ExternalAgentConfigDetectResponse.ts +0 -6
  851. package/bundle/src/codex-protocol/v2/ExternalAgentConfigImportCompletedNotification.ts +0 -5
  852. package/bundle/src/codex-protocol/v2/ExternalAgentConfigImportParams.ts +0 -8
  853. package/bundle/src/codex-protocol/v2/ExternalAgentConfigImportResponse.ts +0 -5
  854. package/bundle/src/codex-protocol/v2/ExternalAgentConfigMigrationItem.ts +0 -15
  855. package/bundle/src/codex-protocol/v2/ExternalAgentConfigMigrationItemType.ts +0 -14
  856. package/bundle/src/codex-protocol/v2/FeedbackUploadParams.ts +0 -12
  857. package/bundle/src/codex-protocol/v2/FeedbackUploadResponse.ts +0 -5
  858. package/bundle/src/codex-protocol/v2/FileChangeApprovalDecision.ts +0 -5
  859. package/bundle/src/codex-protocol/v2/FileChangeOutputDeltaNotification.ts +0 -15
  860. package/bundle/src/codex-protocol/v2/FileChangePatchUpdatedNotification.ts +0 -11
  861. package/bundle/src/codex-protocol/v2/FileChangeRequestApprovalParams.ts +0 -22
  862. package/bundle/src/codex-protocol/v2/FileChangeRequestApprovalResponse.ts +0 -6
  863. package/bundle/src/codex-protocol/v2/FileSystemAccessMode.ts +0 -5
  864. package/bundle/src/codex-protocol/v2/FileSystemPath.ts +0 -10
  865. package/bundle/src/codex-protocol/v2/FileSystemSandboxEntry.ts +0 -7
  866. package/bundle/src/codex-protocol/v2/FileSystemSpecialPath.ts +0 -11
  867. package/bundle/src/codex-protocol/v2/FileUpdateChange.ts +0 -6
  868. package/bundle/src/codex-protocol/v2/FsChangedNotification.ts +0 -18
  869. package/bundle/src/codex-protocol/v2/FsCopyParams.ts +0 -22
  870. package/bundle/src/codex-protocol/v2/FsCopyResponse.ts +0 -8
  871. package/bundle/src/codex-protocol/v2/FsCreateDirectoryParams.ts +0 -18
  872. package/bundle/src/codex-protocol/v2/FsCreateDirectoryResponse.ts +0 -8
  873. package/bundle/src/codex-protocol/v2/FsGetMetadataParams.ts +0 -14
  874. package/bundle/src/codex-protocol/v2/FsGetMetadataResponse.ts +0 -29
  875. package/bundle/src/codex-protocol/v2/FsReadDirectoryEntry.ts +0 -21
  876. package/bundle/src/codex-protocol/v2/FsReadDirectoryParams.ts +0 -14
  877. package/bundle/src/codex-protocol/v2/FsReadDirectoryResponse.ts +0 -14
  878. package/bundle/src/codex-protocol/v2/FsReadFileParams.ts +0 -14
  879. package/bundle/src/codex-protocol/v2/FsReadFileResponse.ts +0 -13
  880. package/bundle/src/codex-protocol/v2/FsRemoveParams.ts +0 -22
  881. package/bundle/src/codex-protocol/v2/FsRemoveResponse.ts +0 -8
  882. package/bundle/src/codex-protocol/v2/FsUnwatchParams.ts +0 -13
  883. package/bundle/src/codex-protocol/v2/FsUnwatchResponse.ts +0 -8
  884. package/bundle/src/codex-protocol/v2/FsWatchParams.ts +0 -18
  885. package/bundle/src/codex-protocol/v2/FsWatchResponse.ts +0 -14
  886. package/bundle/src/codex-protocol/v2/FsWriteFileParams.ts +0 -18
  887. package/bundle/src/codex-protocol/v2/FsWriteFileResponse.ts +0 -8
  888. package/bundle/src/codex-protocol/v2/GetAccountParams.ts +0 -14
  889. package/bundle/src/codex-protocol/v2/GetAccountRateLimitsResponse.ts +0 -15
  890. package/bundle/src/codex-protocol/v2/GetAccountResponse.ts +0 -6
  891. package/bundle/src/codex-protocol/v2/GitInfo.ts +0 -5
  892. package/bundle/src/codex-protocol/v2/GrantedPermissionProfile.ts +0 -10
  893. package/bundle/src/codex-protocol/v2/GuardianApprovalReview.ts +0 -18
  894. package/bundle/src/codex-protocol/v2/GuardianApprovalReviewAction.ts +0 -34
  895. package/bundle/src/codex-protocol/v2/GuardianApprovalReviewStatus.ts +0 -13
  896. package/bundle/src/codex-protocol/v2/GuardianCommandSource.ts +0 -5
  897. package/bundle/src/codex-protocol/v2/GuardianRiskLevel.ts +0 -8
  898. package/bundle/src/codex-protocol/v2/GuardianUserAuthorization.ts +0 -8
  899. package/bundle/src/codex-protocol/v2/GuardianWarningNotification.ts +0 -14
  900. package/bundle/src/codex-protocol/v2/HookCompletedNotification.ts +0 -10
  901. package/bundle/src/codex-protocol/v2/HookErrorInfo.ts +0 -5
  902. package/bundle/src/codex-protocol/v2/HookEventName.ts +0 -13
  903. package/bundle/src/codex-protocol/v2/HookExecutionMode.ts +0 -5
  904. package/bundle/src/codex-protocol/v2/HookHandlerType.ts +0 -5
  905. package/bundle/src/codex-protocol/v2/HookMetadata.ts +0 -26
  906. package/bundle/src/codex-protocol/v2/HookMigration.ts +0 -5
  907. package/bundle/src/codex-protocol/v2/HookOutputEntry.ts +0 -6
  908. package/bundle/src/codex-protocol/v2/HookOutputEntryKind.ts +0 -5
  909. package/bundle/src/codex-protocol/v2/HookPromptFragment.ts +0 -5
  910. package/bundle/src/codex-protocol/v2/HookRunStatus.ts +0 -5
  911. package/bundle/src/codex-protocol/v2/HookRunSummary.ts +0 -28
  912. package/bundle/src/codex-protocol/v2/HookScope.ts +0 -5
  913. package/bundle/src/codex-protocol/v2/HookSource.ts +0 -15
  914. package/bundle/src/codex-protocol/v2/HookStartedNotification.ts +0 -10
  915. package/bundle/src/codex-protocol/v2/HookTrustStatus.ts +0 -5
  916. package/bundle/src/codex-protocol/v2/HooksListEntry.ts +0 -12
  917. package/bundle/src/codex-protocol/v2/HooksListParams.ts +0 -10
  918. package/bundle/src/codex-protocol/v2/HooksListResponse.ts +0 -6
  919. package/bundle/src/codex-protocol/v2/ItemCompletedNotification.ts +0 -14
  920. package/bundle/src/codex-protocol/v2/ItemGuardianApprovalReviewCompletedNotification.ts +0 -44
  921. package/bundle/src/codex-protocol/v2/ItemGuardianApprovalReviewStartedNotification.ts +0 -38
  922. package/bundle/src/codex-protocol/v2/ItemStartedNotification.ts +0 -14
  923. package/bundle/src/codex-protocol/v2/ListMcpServerStatusParams.ts +0 -20
  924. package/bundle/src/codex-protocol/v2/ListMcpServerStatusResponse.ts +0 -13
  925. package/bundle/src/codex-protocol/v2/LoginAccountParams.ts +0 -27
  926. package/bundle/src/codex-protocol/v2/LoginAccountResponse.ts +0 -27
  927. package/bundle/src/codex-protocol/v2/LogoutAccountResponse.ts +0 -5
  928. package/bundle/src/codex-protocol/v2/ManagedHooksRequirements.ts +0 -17
  929. package/bundle/src/codex-protocol/v2/MarketplaceAddParams.ts +0 -9
  930. package/bundle/src/codex-protocol/v2/MarketplaceAddResponse.ts +0 -10
  931. package/bundle/src/codex-protocol/v2/MarketplaceInterface.ts +0 -5
  932. package/bundle/src/codex-protocol/v2/MarketplaceLoadErrorInfo.ts +0 -6
  933. package/bundle/src/codex-protocol/v2/MarketplaceRemoveParams.ts +0 -5
  934. package/bundle/src/codex-protocol/v2/MarketplaceRemoveResponse.ts +0 -9
  935. package/bundle/src/codex-protocol/v2/MarketplaceUpgradeErrorInfo.ts +0 -5
  936. package/bundle/src/codex-protocol/v2/MarketplaceUpgradeParams.ts +0 -5
  937. package/bundle/src/codex-protocol/v2/MarketplaceUpgradeResponse.ts +0 -11
  938. package/bundle/src/codex-protocol/v2/McpAuthStatus.ts +0 -5
  939. package/bundle/src/codex-protocol/v2/McpElicitationArrayType.ts +0 -5
  940. package/bundle/src/codex-protocol/v2/McpElicitationBooleanSchema.ts +0 -11
  941. package/bundle/src/codex-protocol/v2/McpElicitationBooleanType.ts +0 -5
  942. package/bundle/src/codex-protocol/v2/McpElicitationConstOption.ts +0 -5
  943. package/bundle/src/codex-protocol/v2/McpElicitationEnumSchema.ts +0 -11
  944. package/bundle/src/codex-protocol/v2/McpElicitationLegacyTitledEnumSchema.ts +0 -13
  945. package/bundle/src/codex-protocol/v2/McpElicitationMultiSelectEnumSchema.ts +0 -9
  946. package/bundle/src/codex-protocol/v2/McpElicitationNumberSchema.ts +0 -13
  947. package/bundle/src/codex-protocol/v2/McpElicitationNumberType.ts +0 -5
  948. package/bundle/src/codex-protocol/v2/McpElicitationObjectType.ts +0 -5
  949. package/bundle/src/codex-protocol/v2/McpElicitationPrimitiveSchema.ts +0 -13
  950. package/bundle/src/codex-protocol/v2/McpElicitationSchema.ts +0 -18
  951. package/bundle/src/codex-protocol/v2/McpElicitationSingleSelectEnumSchema.ts +0 -9
  952. package/bundle/src/codex-protocol/v2/McpElicitationStringFormat.ts +0 -5
  953. package/bundle/src/codex-protocol/v2/McpElicitationStringSchema.ts +0 -15
  954. package/bundle/src/codex-protocol/v2/McpElicitationStringType.ts +0 -5
  955. package/bundle/src/codex-protocol/v2/McpElicitationTitledEnumItems.ts +0 -6
  956. package/bundle/src/codex-protocol/v2/McpElicitationTitledMultiSelectEnumSchema.ts +0 -15
  957. package/bundle/src/codex-protocol/v2/McpElicitationTitledSingleSelectEnumSchema.ts +0 -13
  958. package/bundle/src/codex-protocol/v2/McpElicitationUntitledEnumItems.ts +0 -9
  959. package/bundle/src/codex-protocol/v2/McpElicitationUntitledMultiSelectEnumSchema.ts +0 -15
  960. package/bundle/src/codex-protocol/v2/McpElicitationUntitledSingleSelectEnumSchema.ts +0 -12
  961. package/bundle/src/codex-protocol/v2/McpResourceReadParams.ts +0 -5
  962. package/bundle/src/codex-protocol/v2/McpResourceReadResponse.ts +0 -6
  963. package/bundle/src/codex-protocol/v2/McpServerElicitationAction.ts +0 -5
  964. package/bundle/src/codex-protocol/v2/McpServerElicitationRequestParams.ts +0 -27
  965. package/bundle/src/codex-protocol/v2/McpServerElicitationRequestResponse.ts +0 -19
  966. package/bundle/src/codex-protocol/v2/McpServerMigration.ts +0 -5
  967. package/bundle/src/codex-protocol/v2/McpServerOauthLoginCompletedNotification.ts +0 -9
  968. package/bundle/src/codex-protocol/v2/McpServerOauthLoginParams.ts +0 -9
  969. package/bundle/src/codex-protocol/v2/McpServerOauthLoginResponse.ts +0 -5
  970. package/bundle/src/codex-protocol/v2/McpServerRefreshResponse.ts +0 -5
  971. package/bundle/src/codex-protocol/v2/McpServerStartupState.ts +0 -5
  972. package/bundle/src/codex-protocol/v2/McpServerStatus.ts +0 -15
  973. package/bundle/src/codex-protocol/v2/McpServerStatusDetail.ts +0 -5
  974. package/bundle/src/codex-protocol/v2/McpServerStatusUpdatedNotification.ts +0 -10
  975. package/bundle/src/codex-protocol/v2/McpServerToolCallParams.ts +0 -12
  976. package/bundle/src/codex-protocol/v2/McpServerToolCallResponse.ts +0 -11
  977. package/bundle/src/codex-protocol/v2/McpToolCallError.ts +0 -5
  978. package/bundle/src/codex-protocol/v2/McpToolCallProgressNotification.ts +0 -10
  979. package/bundle/src/codex-protocol/v2/McpToolCallResult.ts +0 -10
  980. package/bundle/src/codex-protocol/v2/McpToolCallStatus.ts +0 -5
  981. package/bundle/src/codex-protocol/v2/MemoryCitation.ts +0 -6
  982. package/bundle/src/codex-protocol/v2/MemoryCitationEntry.ts +0 -10
  983. package/bundle/src/codex-protocol/v2/MergeStrategy.ts +0 -5
  984. package/bundle/src/codex-protocol/v2/MigrationDetails.ts +0 -18
  985. package/bundle/src/codex-protocol/v2/Model.ts +0 -30
  986. package/bundle/src/codex-protocol/v2/ModelAvailabilityNux.ts +0 -5
  987. package/bundle/src/codex-protocol/v2/ModelListParams.ts +0 -18
  988. package/bundle/src/codex-protocol/v2/ModelListResponse.ts +0 -13
  989. package/bundle/src/codex-protocol/v2/ModelProviderCapabilitiesReadParams.ts +0 -5
  990. package/bundle/src/codex-protocol/v2/ModelProviderCapabilitiesReadResponse.ts +0 -9
  991. package/bundle/src/codex-protocol/v2/ModelRerouteReason.ts +0 -5
  992. package/bundle/src/codex-protocol/v2/ModelReroutedNotification.ts +0 -12
  993. package/bundle/src/codex-protocol/v2/ModelServiceTier.ts +0 -5
  994. package/bundle/src/codex-protocol/v2/ModelUpgradeInfo.ts +0 -10
  995. package/bundle/src/codex-protocol/v2/ModelVerification.ts +0 -5
  996. package/bundle/src/codex-protocol/v2/ModelVerificationNotification.ts +0 -10
  997. package/bundle/src/codex-protocol/v2/NetworkAccess.ts +0 -5
  998. package/bundle/src/codex-protocol/v2/NetworkApprovalContext.ts +0 -6
  999. package/bundle/src/codex-protocol/v2/NetworkApprovalProtocol.ts +0 -5
  1000. package/bundle/src/codex-protocol/v2/NetworkDomainPermission.ts +0 -5
  1001. package/bundle/src/codex-protocol/v2/NetworkPolicyAmendment.ts +0 -6
  1002. package/bundle/src/codex-protocol/v2/NetworkPolicyRuleAction.ts +0 -5
  1003. package/bundle/src/codex-protocol/v2/NetworkRequirements.ts +0 -40
  1004. package/bundle/src/codex-protocol/v2/NetworkUnixSocketPermission.ts +0 -5
  1005. package/bundle/src/codex-protocol/v2/NonSteerableTurnKind.ts +0 -5
  1006. package/bundle/src/codex-protocol/v2/OverriddenMetadata.ts +0 -11
  1007. package/bundle/src/codex-protocol/v2/PatchApplyStatus.ts +0 -5
  1008. package/bundle/src/codex-protocol/v2/PatchChangeKind.ts +0 -8
  1009. package/bundle/src/codex-protocol/v2/PermissionGrantScope.ts +0 -5
  1010. package/bundle/src/codex-protocol/v2/PermissionProfile.ts +0 -14
  1011. package/bundle/src/codex-protocol/v2/PermissionProfileFileSystemPermissions.ts +0 -8
  1012. package/bundle/src/codex-protocol/v2/PermissionProfileModificationParams.ts +0 -9
  1013. package/bundle/src/codex-protocol/v2/PermissionProfileNetworkPermissions.ts +0 -5
  1014. package/bundle/src/codex-protocol/v2/PermissionProfileSelectionParams.ts +0 -10
  1015. package/bundle/src/codex-protocol/v2/PermissionsRequestApprovalParams.ts +0 -18
  1016. package/bundle/src/codex-protocol/v2/PermissionsRequestApprovalResponse.ts +0 -14
  1017. package/bundle/src/codex-protocol/v2/PlanDeltaNotification.ts +0 -14
  1018. package/bundle/src/codex-protocol/v2/PluginAuthPolicy.ts +0 -5
  1019. package/bundle/src/codex-protocol/v2/PluginAvailability.ts +0 -5
  1020. package/bundle/src/codex-protocol/v2/PluginDetail.ts +0 -19
  1021. package/bundle/src/codex-protocol/v2/PluginHookSummary.ts +0 -6
  1022. package/bundle/src/codex-protocol/v2/PluginInstallParams.ts +0 -10
  1023. package/bundle/src/codex-protocol/v2/PluginInstallPolicy.ts +0 -5
  1024. package/bundle/src/codex-protocol/v2/PluginInstallResponse.ts +0 -10
  1025. package/bundle/src/codex-protocol/v2/PluginInterface.ts +0 -46
  1026. package/bundle/src/codex-protocol/v2/PluginListMarketplaceKind.ts +0 -5
  1027. package/bundle/src/codex-protocol/v2/PluginListParams.ts +0 -18
  1028. package/bundle/src/codex-protocol/v2/PluginListResponse.ts +0 -11
  1029. package/bundle/src/codex-protocol/v2/PluginMarketplaceEntry.ts +0 -17
  1030. package/bundle/src/codex-protocol/v2/PluginReadParams.ts +0 -10
  1031. package/bundle/src/codex-protocol/v2/PluginReadResponse.ts +0 -6
  1032. package/bundle/src/codex-protocol/v2/PluginShareContext.ts +0 -12
  1033. package/bundle/src/codex-protocol/v2/PluginShareDeleteParams.ts +0 -5
  1034. package/bundle/src/codex-protocol/v2/PluginShareDeleteResponse.ts +0 -5
  1035. package/bundle/src/codex-protocol/v2/PluginShareDiscoverability.ts +0 -5
  1036. package/bundle/src/codex-protocol/v2/PluginShareListItem.ts +0 -11
  1037. package/bundle/src/codex-protocol/v2/PluginShareListParams.ts +0 -5
  1038. package/bundle/src/codex-protocol/v2/PluginShareListResponse.ts +0 -6
  1039. package/bundle/src/codex-protocol/v2/PluginSharePrincipal.ts +0 -10
  1040. package/bundle/src/codex-protocol/v2/PluginSharePrincipalType.ts +0 -5
  1041. package/bundle/src/codex-protocol/v2/PluginShareSaveParams.ts +0 -13
  1042. package/bundle/src/codex-protocol/v2/PluginShareSaveResponse.ts +0 -5
  1043. package/bundle/src/codex-protocol/v2/PluginShareTarget.ts +0 -6
  1044. package/bundle/src/codex-protocol/v2/PluginShareUpdateDiscoverability.ts +0 -5
  1045. package/bundle/src/codex-protocol/v2/PluginShareUpdateTargetsParams.ts +0 -11
  1046. package/bundle/src/codex-protocol/v2/PluginShareUpdateTargetsResponse.ts +0 -10
  1047. package/bundle/src/codex-protocol/v2/PluginSkillReadParams.ts +0 -9
  1048. package/bundle/src/codex-protocol/v2/PluginSkillReadResponse.ts +0 -5
  1049. package/bundle/src/codex-protocol/v2/PluginSource.ts +0 -9
  1050. package/bundle/src/codex-protocol/v2/PluginSummary.ts +0 -29
  1051. package/bundle/src/codex-protocol/v2/PluginUninstallParams.ts +0 -5
  1052. package/bundle/src/codex-protocol/v2/PluginUninstallResponse.ts +0 -5
  1053. package/bundle/src/codex-protocol/v2/PluginsMigration.ts +0 -5
  1054. package/bundle/src/codex-protocol/v2/ProcessExitedNotification.ts +0 -43
  1055. package/bundle/src/codex-protocol/v2/ProcessOutputDeltaNotification.ts +0 -27
  1056. package/bundle/src/codex-protocol/v2/ProcessOutputStream.ts +0 -8
  1057. package/bundle/src/codex-protocol/v2/ProcessTerminalSize.ts +0 -17
  1058. package/bundle/src/codex-protocol/v2/ProfileV2.ts +0 -37
  1059. package/bundle/src/codex-protocol/v2/RateLimitReachedType.ts +0 -10
  1060. package/bundle/src/codex-protocol/v2/RateLimitSnapshot.ts +0 -17
  1061. package/bundle/src/codex-protocol/v2/RateLimitWindow.ts +0 -9
  1062. package/bundle/src/codex-protocol/v2/RawResponseItemCompletedNotification.ts +0 -10
  1063. package/bundle/src/codex-protocol/v2/ReasoningEffortOption.ts +0 -6
  1064. package/bundle/src/codex-protocol/v2/ReasoningSummaryPartAddedNotification.ts +0 -10
  1065. package/bundle/src/codex-protocol/v2/ReasoningSummaryTextDeltaNotification.ts +0 -11
  1066. package/bundle/src/codex-protocol/v2/ReasoningTextDeltaNotification.ts +0 -11
  1067. package/bundle/src/codex-protocol/v2/RemoteControlConnectionStatus.ts +0 -5
  1068. package/bundle/src/codex-protocol/v2/RemoteControlStatusChangedNotification.ts +0 -12
  1069. package/bundle/src/codex-protocol/v2/RequestPermissionProfile.ts +0 -10
  1070. package/bundle/src/codex-protocol/v2/ResidencyRequirement.ts +0 -5
  1071. package/bundle/src/codex-protocol/v2/ReviewDelivery.ts +0 -5
  1072. package/bundle/src/codex-protocol/v2/ReviewStartParams.ts +0 -15
  1073. package/bundle/src/codex-protocol/v2/ReviewStartResponse.ts +0 -15
  1074. package/bundle/src/codex-protocol/v2/ReviewTarget.ts +0 -16
  1075. package/bundle/src/codex-protocol/v2/SandboxMode.ts +0 -5
  1076. package/bundle/src/codex-protocol/v2/SandboxPolicy.ts +0 -17
  1077. package/bundle/src/codex-protocol/v2/SandboxWorkspaceWrite.ts +0 -10
  1078. package/bundle/src/codex-protocol/v2/SendAddCreditsNudgeEmailParams.ts +0 -6
  1079. package/bundle/src/codex-protocol/v2/SendAddCreditsNudgeEmailResponse.ts +0 -6
  1080. package/bundle/src/codex-protocol/v2/ServerRequestResolvedNotification.ts +0 -6
  1081. package/bundle/src/codex-protocol/v2/SessionMigration.ts +0 -5
  1082. package/bundle/src/codex-protocol/v2/SessionSource.ts +0 -13
  1083. package/bundle/src/codex-protocol/v2/SkillDependencies.ts +0 -6
  1084. package/bundle/src/codex-protocol/v2/SkillErrorInfo.ts +0 -5
  1085. package/bundle/src/codex-protocol/v2/SkillInterface.ts +0 -13
  1086. package/bundle/src/codex-protocol/v2/SkillMetadata.ts +0 -21
  1087. package/bundle/src/codex-protocol/v2/SkillScope.ts +0 -5
  1088. package/bundle/src/codex-protocol/v2/SkillSummary.ts +0 -14
  1089. package/bundle/src/codex-protocol/v2/SkillToolDependency.ts +0 -12
  1090. package/bundle/src/codex-protocol/v2/SkillsChangedNotification.ts +0 -11
  1091. package/bundle/src/codex-protocol/v2/SkillsConfigWriteParams.ts +0 -16
  1092. package/bundle/src/codex-protocol/v2/SkillsConfigWriteResponse.ts +0 -5
  1093. package/bundle/src/codex-protocol/v2/SkillsListEntry.ts +0 -11
  1094. package/bundle/src/codex-protocol/v2/SkillsListParams.ts +0 -14
  1095. package/bundle/src/codex-protocol/v2/SkillsListResponse.ts +0 -6
  1096. package/bundle/src/codex-protocol/v2/SortDirection.ts +0 -5
  1097. package/bundle/src/codex-protocol/v2/SubagentMigration.ts +0 -5
  1098. package/bundle/src/codex-protocol/v2/TerminalInteractionNotification.ts +0 -11
  1099. package/bundle/src/codex-protocol/v2/TextElement.ts +0 -15
  1100. package/bundle/src/codex-protocol/v2/TextPosition.ts +0 -14
  1101. package/bundle/src/codex-protocol/v2/TextRange.ts +0 -6
  1102. package/bundle/src/codex-protocol/v2/Thread.ts +0 -88
  1103. package/bundle/src/codex-protocol/v2/ThreadActiveFlag.ts +0 -5
  1104. package/bundle/src/codex-protocol/v2/ThreadApproveGuardianDeniedActionParams.ts +0 -12
  1105. package/bundle/src/codex-protocol/v2/ThreadApproveGuardianDeniedActionResponse.ts +0 -5
  1106. package/bundle/src/codex-protocol/v2/ThreadArchiveParams.ts +0 -5
  1107. package/bundle/src/codex-protocol/v2/ThreadArchiveResponse.ts +0 -5
  1108. package/bundle/src/codex-protocol/v2/ThreadArchivedNotification.ts +0 -5
  1109. package/bundle/src/codex-protocol/v2/ThreadClosedNotification.ts +0 -5
  1110. package/bundle/src/codex-protocol/v2/ThreadCompactStartParams.ts +0 -5
  1111. package/bundle/src/codex-protocol/v2/ThreadCompactStartResponse.ts +0 -5
  1112. package/bundle/src/codex-protocol/v2/ThreadForkParams.ts +0 -40
  1113. package/bundle/src/codex-protocol/v2/ThreadForkResponse.ts +0 -30
  1114. package/bundle/src/codex-protocol/v2/ThreadGoal.ts +0 -15
  1115. package/bundle/src/codex-protocol/v2/ThreadGoalClearedNotification.ts +0 -5
  1116. package/bundle/src/codex-protocol/v2/ThreadGoalStatus.ts +0 -5
  1117. package/bundle/src/codex-protocol/v2/ThreadGoalUpdatedNotification.ts +0 -10
  1118. package/bundle/src/codex-protocol/v2/ThreadInjectItemsParams.ts +0 -12
  1119. package/bundle/src/codex-protocol/v2/ThreadInjectItemsResponse.ts +0 -5
  1120. package/bundle/src/codex-protocol/v2/ThreadItem.ts +0 -156
  1121. package/bundle/src/codex-protocol/v2/ThreadListParams.ts +0 -55
  1122. package/bundle/src/codex-protocol/v2/ThreadListResponse.ts +0 -20
  1123. package/bundle/src/codex-protocol/v2/ThreadLoadedListParams.ts +0 -14
  1124. package/bundle/src/codex-protocol/v2/ThreadLoadedListResponse.ts +0 -15
  1125. package/bundle/src/codex-protocol/v2/ThreadMetadataGitInfoUpdateParams.ts +0 -21
  1126. package/bundle/src/codex-protocol/v2/ThreadMetadataUpdateParams.ts +0 -14
  1127. package/bundle/src/codex-protocol/v2/ThreadMetadataUpdateResponse.ts +0 -6
  1128. package/bundle/src/codex-protocol/v2/ThreadNameUpdatedNotification.ts +0 -5
  1129. package/bundle/src/codex-protocol/v2/ThreadReadParams.ts +0 -11
  1130. package/bundle/src/codex-protocol/v2/ThreadReadResponse.ts +0 -6
  1131. package/bundle/src/codex-protocol/v2/ThreadRealtimeAudioChunk.ts +0 -14
  1132. package/bundle/src/codex-protocol/v2/ThreadRealtimeClosedNotification.ts +0 -8
  1133. package/bundle/src/codex-protocol/v2/ThreadRealtimeErrorNotification.ts +0 -8
  1134. package/bundle/src/codex-protocol/v2/ThreadRealtimeItemAddedNotification.ts +0 -9
  1135. package/bundle/src/codex-protocol/v2/ThreadRealtimeOutputAudioDeltaNotification.ts +0 -12
  1136. package/bundle/src/codex-protocol/v2/ThreadRealtimeSdpNotification.ts +0 -8
  1137. package/bundle/src/codex-protocol/v2/ThreadRealtimeStartTransport.ts +0 -17
  1138. package/bundle/src/codex-protocol/v2/ThreadRealtimeStartedNotification.ts +0 -13
  1139. package/bundle/src/codex-protocol/v2/ThreadRealtimeTranscriptDeltaNotification.ts +0 -16
  1140. package/bundle/src/codex-protocol/v2/ThreadRealtimeTranscriptDoneNotification.ts +0 -16
  1141. package/bundle/src/codex-protocol/v2/ThreadResumeParams.ts +0 -39
  1142. package/bundle/src/codex-protocol/v2/ThreadResumeResponse.ts +0 -30
  1143. package/bundle/src/codex-protocol/v2/ThreadRollbackParams.ts +0 -14
  1144. package/bundle/src/codex-protocol/v2/ThreadRollbackResponse.ts +0 -15
  1145. package/bundle/src/codex-protocol/v2/ThreadSetNameParams.ts +0 -5
  1146. package/bundle/src/codex-protocol/v2/ThreadSetNameResponse.ts +0 -5
  1147. package/bundle/src/codex-protocol/v2/ThreadShellCommandParams.ts +0 -14
  1148. package/bundle/src/codex-protocol/v2/ThreadShellCommandResponse.ts +0 -5
  1149. package/bundle/src/codex-protocol/v2/ThreadSortKey.ts +0 -5
  1150. package/bundle/src/codex-protocol/v2/ThreadSource.ts +0 -5
  1151. package/bundle/src/codex-protocol/v2/ThreadSourceKind.ts +0 -15
  1152. package/bundle/src/codex-protocol/v2/ThreadStartParams.ts +0 -33
  1153. package/bundle/src/codex-protocol/v2/ThreadStartResponse.ts +0 -30
  1154. package/bundle/src/codex-protocol/v2/ThreadStartSource.ts +0 -5
  1155. package/bundle/src/codex-protocol/v2/ThreadStartedNotification.ts +0 -6
  1156. package/bundle/src/codex-protocol/v2/ThreadStatus.ts +0 -10
  1157. package/bundle/src/codex-protocol/v2/ThreadStatusChangedNotification.ts +0 -6
  1158. package/bundle/src/codex-protocol/v2/ThreadTokenUsage.ts +0 -10
  1159. package/bundle/src/codex-protocol/v2/ThreadTokenUsageUpdatedNotification.ts +0 -10
  1160. package/bundle/src/codex-protocol/v2/ThreadUnarchiveParams.ts +0 -5
  1161. package/bundle/src/codex-protocol/v2/ThreadUnarchiveResponse.ts +0 -6
  1162. package/bundle/src/codex-protocol/v2/ThreadUnarchivedNotification.ts +0 -5
  1163. package/bundle/src/codex-protocol/v2/ThreadUnsubscribeParams.ts +0 -5
  1164. package/bundle/src/codex-protocol/v2/ThreadUnsubscribeResponse.ts +0 -6
  1165. package/bundle/src/codex-protocol/v2/ThreadUnsubscribeStatus.ts +0 -5
  1166. package/bundle/src/codex-protocol/v2/TokenUsageBreakdown.ts +0 -11
  1167. package/bundle/src/codex-protocol/v2/ToolRequestUserInputAnswer.ts +0 -8
  1168. package/bundle/src/codex-protocol/v2/ToolRequestUserInputOption.ts +0 -8
  1169. package/bundle/src/codex-protocol/v2/ToolRequestUserInputParams.ts +0 -14
  1170. package/bundle/src/codex-protocol/v2/ToolRequestUserInputQuestion.ts +0 -16
  1171. package/bundle/src/codex-protocol/v2/ToolRequestUserInputResponse.ts +0 -11
  1172. package/bundle/src/codex-protocol/v2/ToolsV2.ts +0 -6
  1173. package/bundle/src/codex-protocol/v2/Turn.ts +0 -36
  1174. package/bundle/src/codex-protocol/v2/TurnCompletedNotification.ts +0 -6
  1175. package/bundle/src/codex-protocol/v2/TurnDiffUpdatedNotification.ts +0 -9
  1176. package/bundle/src/codex-protocol/v2/TurnEnvironmentParams.ts +0 -6
  1177. package/bundle/src/codex-protocol/v2/TurnError.ts +0 -10
  1178. package/bundle/src/codex-protocol/v2/TurnInterruptParams.ts +0 -5
  1179. package/bundle/src/codex-protocol/v2/TurnInterruptResponse.ts +0 -5
  1180. package/bundle/src/codex-protocol/v2/TurnItemsView.ts +0 -5
  1181. package/bundle/src/codex-protocol/v2/TurnPlanStep.ts +0 -6
  1182. package/bundle/src/codex-protocol/v2/TurnPlanStepStatus.ts +0 -5
  1183. package/bundle/src/codex-protocol/v2/TurnPlanUpdatedNotification.ts +0 -11
  1184. package/bundle/src/codex-protocol/v2/TurnStartParams.ts +0 -48
  1185. package/bundle/src/codex-protocol/v2/TurnStartResponse.ts +0 -6
  1186. package/bundle/src/codex-protocol/v2/TurnStartedNotification.ts +0 -6
  1187. package/bundle/src/codex-protocol/v2/TurnStatus.ts +0 -5
  1188. package/bundle/src/codex-protocol/v2/TurnSteerParams.ts +0 -13
  1189. package/bundle/src/codex-protocol/v2/TurnSteerResponse.ts +0 -5
  1190. package/bundle/src/codex-protocol/v2/UserInput.ts +0 -18
  1191. package/bundle/src/codex-protocol/v2/WarningNotification.ts +0 -14
  1192. package/bundle/src/codex-protocol/v2/WebSearchAction.ts +0 -9
  1193. package/bundle/src/codex-protocol/v2/WindowsSandboxReadiness.ts +0 -5
  1194. package/bundle/src/codex-protocol/v2/WindowsSandboxReadinessResponse.ts +0 -6
  1195. package/bundle/src/codex-protocol/v2/WindowsSandboxSetupCompletedNotification.ts +0 -10
  1196. package/bundle/src/codex-protocol/v2/WindowsSandboxSetupMode.ts +0 -5
  1197. package/bundle/src/codex-protocol/v2/WindowsSandboxSetupStartParams.ts +0 -10
  1198. package/bundle/src/codex-protocol/v2/WindowsSandboxSetupStartResponse.ts +0 -5
  1199. package/bundle/src/codex-protocol/v2/WindowsWorldWritableWarningNotification.ts +0 -9
  1200. package/bundle/src/codex-protocol/v2/WriteStatus.ts +0 -5
  1201. package/bundle/src/codex-protocol/v2/index.ts +0 -446
  1202. package/bundle/src/utils/providers/openai/codex-rpc.ts +0 -238
  1203. package/bundle/src/utils/providers/openai/codex-worker.test.ts +0 -1006
  1204. package/bundle/src/utils/providers/openai/codex-worker.ts +0 -927
  1205. package/bundle/src/utils/providers/openai/openai-worker-pool-config.ts +0 -112
  1206. package/bundle/web-dist/client/assets/index-C0594sjh.js +0 -106
  1207. package/bundle/web-dist/client/assets/index-CcMEpCgt.css +0 -1
  1208. package/bundle/web-dist/client/assets/logs-BotUcOEB.js +0 -1
  1209. package/bundle/web-dist/client/assets/monit-kk3vnGvu.js +0 -1
  1210. package/bundle/web-dist/client/assets/settings-CAAQSIyg.js +0 -1
  1211. package/bundle/web-dist/client/assets/show-BryNvjUT.js +0 -2
  1212. /package/bundle/dist/{codex-protocol/AbsolutePathBuf.js → utils/providers/common/provider-types.js} +0 -0
@@ -1,23 +1,14 @@
1
- import { estimateOpenAIWorkerRssGiB, resolveOpenAIWorkerPoolConfig } from "./openai-worker-pool-config.js";
1
+ import { resolveOpenAITransportKind } from "./openai-transport-config.js";
2
2
  import { QuotaThresholdExceededError } from "../../../application/qgrid/qgrid.types.js";
3
3
  import { TokenModel } from "../../../application/token/token.model.js";
4
4
  import { SmoothWeightedRoundRobin } from "../common/smooth-weighted-round-robin.js";
5
- import { CodexAppServerWorker } from "./codex-worker.js";
5
+ import { OpenAIDirectClient } from "./openai-direct-client.js";
6
6
  import { readOpenAIQuotaUsage } from "./openai-quota.js";
7
7
  import { handleChatgptAuthTokensRefresh } from "./openai-refresh.js";
8
8
  import { getLogger } from "@logtape/logtape";
9
- import { readFileSync } from "node:fs";
10
- import { freemem } from "node:os";
11
9
  //#region src/utils/providers/openai/openai-dispatcher.ts
12
- /**
13
- * OpenAIDispatcher — codex app-server worker pool + 토큰 라우팅.
14
- *
15
- * - 토큰당 CodexAppServerWorker 자동 확장 (기본 1~3, hard cap 20)
16
- * - idle worker round-robin 선택 + 큐 대기 (전부 busy 시)
17
- * - TokenSubscriber 이벤트로 worker pool 동기화
18
- * - backpressure: 큐 full 또는 timeout 시 SERVER_BUSY
19
- */
20
10
  const logger = getLogger(["qgrid", "openai-dispatcher"]);
11
+ const DEFAULT_REQUEST_TIMEOUT_MS = 6e5;
21
12
  var ImageGenerationError = class extends Error {
22
13
  kind;
23
14
  constructor(kind, message) {
@@ -26,839 +17,425 @@ var ImageGenerationError = class extends Error {
26
17
  this.name = "ImageGenerationError";
27
18
  }
28
19
  };
29
- const DEFAULT_EFFORT = "low";
30
- const QUEUE_TIMEOUT_MS = 6e4;
31
- const MAX_QUEUE_SIZE = 50;
32
- const SPAWN_INTERVAL_MS = 500;
33
- function readHostAvailableGiB() {
34
- try {
35
- const match = readFileSync("/proc/meminfo", "utf8").match(/^MemAvailable:\s+(\d+)\s+kB$/m);
36
- if (match?.[1]) return Number(match[1]) / 1024 / 1024;
37
- } catch {}
38
- return freemem() / 1024 / 1024 / 1024;
20
+ function abortError(signal) {
21
+ const reason = signal.reason;
22
+ return reason instanceof Error ? reason : new DOMException("Aborted", "AbortError");
39
23
  }
40
- const THREAD_REUSE_ENABLED = process.env.QGRID_OPENAI_THREAD_REUSE !== "false";
41
- const REUSE_WORKER_WAIT_MS = 5e3;
42
- const REUSE_WORKER_POLL_MS = 50;
43
- const OPENAI_WORKER_ID_STRIDE = 100;
44
- function makeOpenAIWorkerId(tokenId, workerIndex) {
45
- return tokenId * OPENAI_WORKER_ID_STRIDE + workerIndex;
24
+ function activeSignal(signal, timeoutMs) {
25
+ const timeout = AbortSignal.timeout(timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS);
26
+ return signal ? AbortSignal.any([signal, timeout]) : timeout;
46
27
  }
47
- function sleep(ms) {
48
- return new Promise((resolve) => setTimeout(resolve, ms));
28
+ function quotaMessage(entries) {
29
+ const detail = entries.map((e) => `${e.name} (threshold ${e.threshold}%)`).join(", ");
30
+ return detail ? `All openai tokens exceeded quota threshold: ${detail}` : "All openai tokens exceeded quota threshold";
49
31
  }
50
- function quotaThresholdExceededMessage(provider, tokens) {
51
- const details = tokens.map((token) => `${token.tokenName} (threshold ${token.threshold}%)`).join(", ");
52
- return details.length > 0 ? `All ${provider} tokens exceeded quota threshold: ${details}` : `All ${provider} tokens exceeded quota threshold`;
32
+ function inputItems(req) {
33
+ const history = req.coldHistory ?? [];
34
+ const content = req.coldInput.map((input) => {
35
+ if (input.type === "text") return {
36
+ type: "input_text",
37
+ text: input.text
38
+ };
39
+ if (input.type === "image") return {
40
+ type: "input_image",
41
+ image_url: input.url
42
+ };
43
+ if (input.type === "localImage") return {
44
+ type: "input_image",
45
+ image_url: input.path
46
+ };
47
+ return {
48
+ type: "input_text",
49
+ text: `${input.name}: ${input.path}`
50
+ };
51
+ });
52
+ return [...history, {
53
+ type: "message",
54
+ role: "user",
55
+ content
56
+ }];
57
+ }
58
+ function asReasoning(req) {
59
+ const summary = req.reasoningSummary && req.reasoningSummary !== "none" ? req.reasoningSummary : void 0;
60
+ if (!req.effort && !summary) return void 0;
61
+ return {
62
+ ...req.effort ? { effort: req.effort } : {},
63
+ ...summary ? { summary } : {}
64
+ };
53
65
  }
66
+ function requestOptions(req) {
67
+ return {
68
+ model: req.model ?? "",
69
+ ...req.systemPrompt ? { instructions: req.systemPrompt } : {},
70
+ history: inputItems(req),
71
+ ...asReasoning(req) ? { reasoning: asReasoning(req) } : {},
72
+ ...req.verbosity ? { verbosity: req.verbosity } : {},
73
+ ...req.serviceTier ? { serviceTier: req.serviceTier === "fast" ? "priority" : req.serviceTier } : {},
74
+ ...req.promptCacheKey ? { promptCacheKey: req.promptCacheKey } : {},
75
+ ...req.outputSchema ? { outputSchema: { schema: req.outputSchema } } : {},
76
+ ...req.imageGeneration ? { imageGeneration: req.imageGenerationOptions ? { ...req.imageGenerationOptions } : true } : {}
77
+ };
78
+ }
79
+ /**
80
+ * Direct OpenAI dispatcher — Anthropic 과 동일한 stateless 실행 모델.
81
+ *
82
+ * 요청 = 토큰 선택(quota gate + weighted round-robin + cache affinity 선호) → HTTPS/WS
83
+ * 전송. permit/큐 같은 동시성 상한은 두지 않는다: 전송은 fetch 한 번이라 로컬 자원이
84
+ * 희소하지 않고, 상류 제한은 백엔드의 응답(429 등)이 진실이다. worker pool 시절의
85
+ * 큐 의미론(SERVER_BUSY, 큐 타임아웃)은 이 전환으로 제거됐다.
86
+ */
54
87
  var OpenAIDispatcher = class OpenAIDispatcher {
55
- workerPool = /* @__PURE__ */ new Map();
56
88
  tokenMetadata = /* @__PURE__ */ new Map();
57
- queue = [];
58
- poolConfig;
59
- quotaBlockedTokenIds = /* @__PURE__ */ new Set();
60
- startingTokenIds = /* @__PURE__ */ new Set();
61
- rateLimitsGenerationByToken = /* @__PURE__ */ new Map();
62
- weightedSelector = new SmoothWeightedRoundRobin();
63
- workerCursorByToken = /* @__PURE__ */ new Map();
64
- getHostAvailableGiB;
65
- draining = false;
66
- drainAgain = false;
67
- scalerTimer = null;
68
- scalingPromise = null;
69
- lastRequestAt = Date.now();
70
- stopped = false;
71
- constructor(poolConfig = resolveOpenAIWorkerPoolConfig(), getHostAvailableGiB = readHostAvailableGiB) {
72
- this.poolConfig = poolConfig;
73
- this.getHostAvailableGiB = getHostAvailableGiB;
89
+ transportKind;
90
+ rateLimitsCache = /* @__PURE__ */ new Map();
91
+ pendingRateLimits = /* @__PURE__ */ new Map();
92
+ clients = /* @__PURE__ */ new Map();
93
+ retiredClients = /* @__PURE__ */ new Set();
94
+ static RATE_LIMITS_CACHE_TTL = 6e4;
95
+ selector = new SmoothWeightedRoundRobin();
96
+ clientFactory;
97
+ fetchImpl;
98
+ quotaBlocked = /* @__PURE__ */ new Set();
99
+ inFlightCount = 0;
100
+ constructor(transportKind = resolveOpenAITransportKind(), dependencies = {}) {
101
+ this.transportKind = transportKind;
102
+ this.clientFactory = dependencies.clientFactory ?? ((options) => new OpenAIDirectClient(options));
103
+ this.fetchImpl = dependencies.fetch ?? fetch;
74
104
  }
75
105
  async start() {
76
- this.stopped = false;
77
106
  const { rows } = await TokenModel.findMany("A");
78
- const openaiTokens = rows.filter((t) => t.provider === "openai");
79
- logger.info(this.poolConfig.autoscale ? `starting ${openaiTokens.length} openai tokens (${this.poolConfig.minWorkersPerToken}-${this.poolConfig.maxWorkersPerToken} workers each, autoscale)` : `starting ${openaiTokens.length} openai tokens (${this.poolConfig.minWorkersPerToken} workers each)`);
80
- await Promise.allSettled(openaiTokens.map(async (t) => {
81
- await this.spawnWorkers(t.id, t.name, t.credentials, t.quota_threshold, t.weight);
82
- if (!t.active) this.onTokenDeactivated(t.id);
83
- }));
84
- this.scalerTimer = setInterval(() => this.requestAutoscaleEvaluation(), this.poolConfig.scaleIntervalMs);
85
- this.scalerTimer.unref?.();
107
+ for (const row of rows) {
108
+ if (row.provider !== "openai") continue;
109
+ this.setToken(row.id, row.name, row.credentials, row.quota_threshold, row.weight, row.active);
110
+ }
111
+ logger.info(`started direct OpenAI runtime with ${this.tokenMetadata.size} tokens`);
86
112
  }
87
113
  async stop() {
88
- this.stopped = true;
89
- if (this.scalerTimer) {
90
- clearInterval(this.scalerTimer);
91
- this.scalerTimer = null;
92
- }
93
- await this.scalingPromise?.catch(() => {});
94
- this.rejectAllQueued("DISPATCHER_SHUTDOWN");
95
- const kills = [...this.workerPool.values()].flat().map((w) => w.kill());
96
- await Promise.allSettled(kills);
97
- for (const id of this.tokenMetadata.keys()) this.weightedSelector.removeToken(id);
98
- this.workerPool.clear();
114
+ for (const { client } of this.clients.values()) client.close?.();
115
+ this.clients.clear();
116
+ for (const entry of this.retiredClients) entry.client.close?.();
117
+ this.retiredClients.clear();
99
118
  this.tokenMetadata.clear();
100
- this.workerCursorByToken.clear();
101
- this.weightedSelector.resetScores();
102
119
  this.rateLimitsCache.clear();
103
- this.rateLimitsGenerationByToken.clear();
104
- this.quotaBlockedTokenIds.clear();
105
- this.startingTokenIds.clear();
120
+ this.quotaBlocked.clear();
121
+ this.selector.resetScores();
106
122
  }
107
123
  async onTokenAdded(id, name, credentials, quotaThreshold, weight = 1) {
108
- this.quotaBlockedTokenIds.delete(id);
109
- this.invalidateRateLimitsCache(id);
110
- this.setTokenMetadata(id, name, credentials, quotaThreshold, weight);
111
- if (this.workerPool.has(id)) return;
112
- await this.spawnWorkers(id, name, credentials, quotaThreshold, weight);
124
+ this.setToken(id, name, credentials, quotaThreshold, weight, true);
125
+ }
126
+ async onTokenUpdated(id, name, credentials, quotaThreshold, weight = 1) {
127
+ const old = this.tokenMetadata.get(id);
128
+ this.setToken(id, name, credentials, quotaThreshold, weight, old?.active ?? true);
113
129
  }
114
130
  async onTokenRemoved(id) {
115
- const workers = this.workerPool.get(id) ?? [];
116
- const tokenName = workers[0]?.tokenName;
117
- this.workerPool.delete(id);
131
+ this.retireClient(id);
118
132
  this.tokenMetadata.delete(id);
119
- this.weightedSelector.removeToken(id);
120
- this.workerCursorByToken.delete(id);
133
+ this.selector.removeToken(id);
121
134
  this.invalidateRateLimitsCache(id);
122
- this.quotaBlockedTokenIds.delete(id);
123
- await Promise.allSettled(workers.map((w) => w.kill()));
124
- if (!this.hasActiveTokenCandidate(/* @__PURE__ */ new Set())) this.rejectAllQueued("NO_OPENAI_WORKERS");
125
- if (workers.length > 0) {
126
- const label = tokenName ?? `token ${id}`;
127
- logger.info(`workers removed: ${label} (${workers.length})`);
128
- }
129
- }
130
- async onTokenUpdated(id, name, credentials, quotaThreshold, weight = 1) {
131
- const existing = this.workerPool.get(id) ?? [];
132
- if (this.getQuotaThreshold(id) !== quotaThreshold) this.quotaBlockedTokenIds.delete(id);
133
- this.setTokenMetadata(id, name, credentials, quotaThreshold, weight);
134
- if (existing.length === 0) {
135
- this.invalidateRateLimitsCache(id);
136
- await this.spawnWorkers(id, name, credentials, quotaThreshold, weight);
137
- return;
138
- }
139
- if (existing.every((w) => w.canReuseForToken(name, credentials))) {
140
- existing.forEach((w) => w.updateTokenState(name, credentials));
141
- logger.info(`workers updated in-place: ${name}`);
142
- this.requestDrainQueue();
143
- return;
144
- }
145
- this.workerPool.delete(id);
146
- this.invalidateRateLimitsCache(id);
147
- this.quotaBlockedTokenIds.delete(id);
148
- await Promise.allSettled(existing.map((w) => w.kill()));
149
- await this.spawnWorkers(id, name, credentials, quotaThreshold, weight);
135
+ this.quotaBlocked.delete(id);
150
136
  }
151
137
  onTokenDeactivated(id) {
152
- const workers = this.workerPool.get(id) ?? [];
153
- const tokenName = workers[0]?.tokenName;
154
- const metadata = this.tokenMetadata.get(id);
155
- if (metadata?.active) this.tokenMetadata.set(id, {
156
- ...metadata,
157
- active: false
158
- });
159
- this.quotaBlockedTokenIds.delete(id);
160
- const changed = workers.some((worker) => worker.active);
161
- workers.forEach((w) => {
162
- w.active = false;
163
- });
164
- if (changed) this.weightedSelector.resetScores();
165
- if (!this.hasActiveTokenCandidate(/* @__PURE__ */ new Set())) this.rejectAllQueued("NO_ACTIVE_WORKERS");
166
- const label = tokenName ?? `token ${id}`;
167
- logger.info(`workers deactivated: ${label}`);
138
+ const token = this.tokenMetadata.get(id);
139
+ if (token) token.active = false;
140
+ this.selector.resetScores();
168
141
  }
169
142
  onTokenActivated(id) {
170
- const workers = this.workerPool.get(id) ?? [];
171
- const tokenName = workers[0]?.tokenName;
172
- const metadata = this.tokenMetadata.get(id);
173
- if (metadata && !metadata.active) this.tokenMetadata.set(id, {
174
- ...metadata,
175
- active: true
176
- });
177
- const changed = workers.some((worker) => !worker.active);
178
- workers.forEach((w) => {
179
- w.active = true;
180
- });
181
- if (changed) this.weightedSelector.resetScores();
182
- this.requestDrainQueue();
183
- const label = tokenName ?? `token ${id}`;
184
- logger.info(`workers activated: ${label}`);
143
+ const token = this.tokenMetadata.get(id);
144
+ if (token) token.active = true;
145
+ this.selector.resetScores();
185
146
  }
186
147
  async replaceTokens(rows) {
187
- const next = new Set(rows.map((r) => r.id));
188
- for (const id of Array.from(this.workerPool.keys())) if (!next.has(id)) await this.onTokenRemoved(id);
189
- for (const row of rows) {
190
- if (this.workerPool.has(row.id)) await this.onTokenUpdated(row.id, row.name, row.credentials, row.quotaThreshold, row.weight);
191
- else await this.onTokenAdded(row.id, row.name, row.credentials, row.quotaThreshold, row.weight);
192
- this.onTokenActivated(row.id);
193
- }
148
+ const ids = new Set(rows.map((r) => r.id));
149
+ for (const id of this.tokenMetadata.keys()) if (!ids.has(id)) await this.onTokenRemoved(id);
150
+ for (const row of rows) await this.onTokenUpdated(row.id, row.name, row.credentials, row.quotaThreshold, row.weight);
194
151
  }
195
152
  async generate(req) {
196
- this.lastRequestAt = Date.now();
197
- const excludedTokenIds = /* @__PURE__ */ new Set();
198
- const reuseWorker = await this.acquireReuseWorker(req, excludedTokenIds);
199
- if (reuseWorker) {
200
- logger.info(`↻ ${reuseWorker.tokenName}[${reuseWorker.tokenId}] (reuse thread, ${req.model})`);
201
- return this.executeAndRelease(reuseWorker, (w) => this.executeTurn(w, req, req.reuse.threadId));
202
- }
203
- const worker = await this.acquireIdleWorker(excludedTokenIds);
204
- if (worker) {
205
- logger.info(`→ ${worker.tokenName}[${worker.tokenId}] (model: ${req.model})`);
206
- return this.executeAndRelease(worker, (w) => this.executeTurn(w, req));
207
- }
208
- return this.enqueue((w) => {
209
- logger.info(`→ ${w.tokenName}[${w.tokenId}] (model: ${req.model}, queued)`);
210
- return this.executeTurn(w, req);
211
- }, excludedTokenIds);
153
+ return this.run(req);
212
154
  }
213
155
  async generateStream(req, cb) {
214
- this.lastRequestAt = Date.now();
215
156
  if (req.imageGeneration) throw new ImageGenerationError("gate", "image generation is not supported on the streaming path");
216
- const excludedTokenIds = /* @__PURE__ */ new Set();
217
- const reuseWorker = await this.acquireReuseWorker(req, excludedTokenIds);
218
- if (reuseWorker) {
219
- logger.info(`↻ ${reuseWorker.tokenName}[${reuseWorker.tokenId}] (reuse thread, [stream])`);
220
- return this.executeAndRelease(reuseWorker, (w) => this.executeStreamTurn(w, req, cb, req.reuse.threadId));
221
- }
222
- const worker = await this.acquireIdleWorker(excludedTokenIds);
223
- if (worker) {
224
- logger.info(`→ ${worker.tokenName}[${worker.tokenId}] (model: ${req.model}, [stream])`);
225
- return this.executeAndRelease(worker, (w) => this.executeStreamTurn(w, req, cb));
226
- }
227
- return this.enqueue((w) => {
228
- logger.info(`→ ${w.tokenName}[${w.tokenId}] (model: ${req.model}, [stream], queued)`);
229
- return this.executeStreamTurn(w, req, cb);
230
- }, excludedTokenIds);
231
- }
232
- async acquireReuseWorker(req, excludedTokenIds = /* @__PURE__ */ new Set()) {
233
- if (req.imageGeneration) return null;
234
- if (!THREAD_REUSE_ENABLED || !req.reuse) return null;
235
- const { workerId, threadId, epoch } = req.reuse;
236
- const worker = this.findWorkerById(workerId);
237
- if (!worker || !worker.isReady || !worker.active) return null;
238
- if (worker.epoch !== epoch) return null;
239
- if (!worker.hasThread(threadId)) return null;
240
- const quotaMetadata = this.tokenMetadata.get(worker.tokenId);
241
- if (!await this.isTokenQuotaEligible(worker.tokenId, worker.tokenName, excludedTokenIds)) return null;
242
- if (!worker.isReady || !worker.active || this.tokenMetadata.get(worker.tokenId) !== quotaMetadata || this.quotaBlockedTokenIds.has(worker.tokenId)) {
243
- if (this.quotaBlockedTokenIds.has(worker.tokenId)) excludedTokenIds.add(worker.tokenId);
244
- return null;
245
- }
246
- const deadline = Date.now() + REUSE_WORKER_WAIT_MS;
247
- for (;;) {
248
- if (!worker.isReady || !worker.active || worker.epoch !== epoch || !worker.hasThread(threadId) || this.tokenMetadata.get(worker.tokenId) !== quotaMetadata || this.quotaBlockedTokenIds.has(worker.tokenId)) {
249
- if (this.quotaBlockedTokenIds.has(worker.tokenId)) excludedTokenIds.add(worker.tokenId);
250
- return null;
251
- }
252
- if (worker.tryAcquireTurn()) return worker;
253
- if (Date.now() >= deadline) return null;
254
- await sleep(REUSE_WORKER_POLL_MS);
255
- }
256
- }
257
- findWorkerById(workerId) {
258
- for (const workers of this.workerPool.values()) for (const w of workers) if (makeOpenAIWorkerId(w.tokenId, w.workerIndex) === workerId) return w;
259
- return null;
260
- }
261
- async interruptWorkerTurn(threadId, turnId) {
262
- const allWorkers = [...this.workerPool.values()].flat().filter((w) => w.isReady);
263
- await Promise.allSettled(allWorkers.map((w) => w.interruptTurn(threadId, turnId)));
264
- }
265
- async acquireIdleWorker(excludedTokenIds = /* @__PURE__ */ new Set()) {
266
- const eligibility = await this.resolveTokenEligibility(excludedTokenIds);
267
- if (eligibility.readyActiveTokenIds.size === 0) return null;
268
- if (eligibility.eligibleTokenIds.size === 0) this.throwQuotaThresholdExceeded(eligibility);
269
- const workersByToken = /* @__PURE__ */ new Map();
270
- for (const worker of this.getAllReadyActiveWorkers()) {
271
- if (!eligibility.eligibleTokenIds.has(worker.tokenId) || !worker.hasCapacity) continue;
272
- const workers = workersByToken.get(worker.tokenId) ?? [];
273
- workers.push(worker);
274
- workersByToken.set(worker.tokenId, workers);
275
- }
276
- const selectedTokenId = this.weightedSelector.select(new Set(workersByToken.keys()));
277
- if (selectedTokenId === null) return null;
278
- const workers = workersByToken.get(selectedTokenId);
279
- const cursor = this.workerCursorByToken.get(selectedTokenId) ?? 0;
280
- for (let offset = 0; offset < workers.length; offset++) {
281
- const index = (cursor + offset) % workers.length;
282
- const worker = workers[index];
283
- if (worker.tryAcquireTurn()) {
284
- this.workerCursorByToken.set(selectedTokenId, (index + 1) % workers.length);
285
- return worker;
286
- }
287
- }
288
- throw new Error(`weighted token ${selectedTokenId} lost idle capacity during synchronous acquire`);
289
- }
290
- getAllReadyActiveWorkers() {
291
- return [...this.workerPool.values()].flat().filter((w) => w.isReady && w.active);
292
- }
293
- async enqueue(execute, excludedTokenIds = /* @__PURE__ */ new Set()) {
294
- const eligibility = await this.resolveTokenEligibility(excludedTokenIds);
295
- if (eligibility.readyActiveTokenIds.size === 0 && !this.hasActiveTokenCandidate(excludedTokenIds)) throw new Error("NO_OPENAI_WORKERS");
296
- if (eligibility.readyActiveTokenIds.size > 0 && eligibility.eligibleTokenIds.size === 0) this.throwQuotaThresholdExceeded(eligibility);
297
- if (this.queue.length >= MAX_QUEUE_SIZE) throw new Error("SERVER_BUSY");
298
- return new Promise((resolve, reject) => {
299
- const item = {
300
- resolve: (worker) => {
301
- clearTimeout(item.timer);
302
- item.abortCleanup?.();
303
- Promise.resolve().then(() => this.executeAndRelease(worker, execute)).then(resolve, reject);
304
- },
305
- reject: (err) => {
306
- clearTimeout(item.timer);
307
- item.abortCleanup?.();
308
- reject(err);
309
- },
310
- timer: setTimeout(() => {
311
- this.removeFromQueue(item);
312
- reject(/* @__PURE__ */ new Error("SERVER_BUSY"));
313
- }, QUEUE_TIMEOUT_MS),
314
- excludedTokenIds: new Set(excludedTokenIds)
315
- };
316
- this.queue.push(item);
317
- this.requestDrainQueue();
318
- this.requestAutoscaleEvaluation();
319
- });
320
- }
321
- removeFromQueue(item) {
322
- clearTimeout(item.timer);
323
- item.abortCleanup?.();
324
- const idx = this.queue.indexOf(item);
325
- if (idx !== -1) this.queue.splice(idx, 1);
326
- }
327
- rejectAllQueued(reason) {
328
- const err = new Error(reason);
329
- this.queue.forEach((item) => {
330
- clearTimeout(item.timer);
331
- item.abortCleanup?.();
332
- item.reject(err);
333
- });
334
- this.queue = [];
335
- }
336
- async drainQueue() {
337
- if (this.draining) {
338
- this.drainAgain = true;
339
- return;
340
- }
341
- this.draining = true;
342
157
  try {
343
- do {
344
- this.drainAgain = false;
345
- await this.drainQueueOnce();
346
- } while (this.drainAgain);
347
- } catch (e) {
348
- logger.warn(`drainQueue failed: ${e.message}`);
349
- } finally {
350
- this.draining = false;
351
- }
352
- }
353
- async drainQueueOnce() {
354
- while (this.queue.length > 0) {
355
- const next = this.queue[0];
356
- let worker;
357
- try {
358
- worker = await this.acquireIdleWorker(next.excludedTokenIds);
359
- } catch (e) {
360
- if (e instanceof QuotaThresholdExceededError) {
361
- this.queue.shift();
362
- next.reject(e);
363
- continue;
364
- }
365
- throw e;
366
- }
367
- if (!worker) break;
368
- this.queue.shift();
369
- next.resolve(worker);
158
+ cb.onComplete(await this.run(req, cb.onDelta));
159
+ } catch (error) {
160
+ cb.onError(error);
161
+ throw error;
370
162
  }
371
163
  }
372
- async executeAndRelease(worker, execute) {
164
+ async run(req, onDelta) {
165
+ const signal = activeSignal(req.abortSignal, req.timeoutMs);
166
+ if (signal.aborted) throw abortError(signal);
167
+ const selection = await this.selectToken(req.preferredTokenId, signal);
168
+ this.inFlightCount++;
373
169
  try {
374
- return await execute(worker);
170
+ if (signal.aborted) throw abortError(signal);
171
+ return await this.runDirect(selection, {
172
+ ...req,
173
+ abortSignal: signal
174
+ }, onDelta);
375
175
  } finally {
376
- worker.releaseTurn();
377
- this.requestDrainQueue();
176
+ this.inFlightCount--;
378
177
  }
379
178
  }
380
- buildTurnRequest(req, reuseThreadId) {
381
- const reusing = reuseThreadId !== void 0;
382
- return {
383
- input: reusing && req.reuseInput ? req.reuseInput : req.coldInput,
384
- history: reusing ? void 0 : req.coldHistory,
385
- developerInstructions: req.systemPrompt,
386
- outputSchema: req.outputSchema,
387
- effort: req.effort ?? DEFAULT_EFFORT,
388
- model: req.model,
389
- verbosity: req.verbosity,
390
- reasoningSummary: req.reasoningSummary,
391
- serviceTier: req.serviceTier,
392
- imageGeneration: req.imageGeneration,
393
- imageGenerationOptions: req.imageGenerationOptions
179
+ async runDirect(selection, req, onDelta) {
180
+ const startedAt = Date.now();
181
+ let firstDeltaAt;
182
+ let text = "";
183
+ let usage = {
184
+ totalTokens: 0,
185
+ inputTokens: 0,
186
+ outputTokens: 0,
187
+ cachedInputTokens: 0,
188
+ reasoningOutputTokens: 0
394
189
  };
395
- }
396
- async executeTurn(worker, req, reuseThreadId) {
397
- if (req.imageGeneration) {
398
- const reason = await worker.checkImageGenerationSupport(req.model);
399
- if (reason) throw new ImageGenerationError("gate", reason);
190
+ const images = [];
191
+ let imageAttempted = false;
192
+ let servingModel = req.model ?? "";
193
+ const metadata = selection.metadata;
194
+ const clientEntry = this.acquireClient(selection);
195
+ try {
196
+ for await (const event of clientEntry.client.responses(requestOptions(req), req.abortSignal)) if (event.type === "text-delta") {
197
+ firstDeltaAt ??= Date.now();
198
+ text += event.text;
199
+ onDelta?.(event.text);
200
+ } else if (event.type === "image") {
201
+ imageAttempted = true;
202
+ images.push({
203
+ data: event.base64,
204
+ revisedPrompt: event.revisedPrompt ?? null
205
+ });
206
+ } else if (event.type === "output-item" && event.item.type === "image_generation_call") imageAttempted = true;
207
+ else if (event.type === "completed" && event.usage) {
208
+ servingModel = event.model ?? servingModel;
209
+ usage = {
210
+ totalTokens: event.usage.totalTokens,
211
+ inputTokens: event.usage.inputTokens,
212
+ outputTokens: event.usage.outputTokens,
213
+ cachedInputTokens: event.usage.cachedInputTokens,
214
+ reasoningOutputTokens: event.usage.reasoningTokens
215
+ };
216
+ } else if (event.type === "completed") servingModel = event.model ?? servingModel;
217
+ else if (event.type === "error") {
218
+ if (req.imageGeneration) throw new ImageGenerationError("incomplete", event.error.message);
219
+ throw event.error;
220
+ }
221
+ } finally {
222
+ this.releaseClient(clientEntry);
400
223
  }
401
- const turnReq = this.buildTurnRequest(req, reuseThreadId);
402
- const result = await worker.executeTurn(turnReq, reuseThreadId);
403
- if (req.imageGeneration && (!result.images || result.images.length === 0)) throw result.imageAttempted ? new ImageGenerationError("incomplete", "image tool ran but produced no completed image") : new ImageGenerationError("not_called", "model did not call the image_generation tool");
224
+ if (req.imageGeneration && images.length === 0) throw new ImageGenerationError(imageAttempted ? "incomplete" : "not_called", imageAttempted ? "image generation did not complete" : "model did not call image generation");
404
225
  return {
405
- text: result.text,
406
- tokenName: worker.tokenName,
407
- usage: result.usage,
408
- durationMs: result.durationMs,
409
- ttftMs: result.ttftMs,
410
- model: result.model,
226
+ text,
227
+ tokenName: metadata.name,
228
+ usage,
229
+ durationMs: Date.now() - startedAt,
230
+ ttftMs: firstDeltaAt === void 0 ? null : firstDeltaAt - startedAt,
231
+ model: servingModel,
411
232
  threadCoord: {
412
- workerId: makeOpenAIWorkerId(worker.tokenId, worker.workerIndex),
413
- threadId: result.threadId,
414
- epoch: worker.epoch
233
+ workerId: selection.tokenId,
234
+ threadId: req.promptCacheKey ?? "",
235
+ epoch: -1
415
236
  },
416
- images: result.images
237
+ ...images.length ? { images } : {}
417
238
  };
418
239
  }
419
- async executeStreamTurn(worker, req, cb, reuseThreadId) {
420
- const turnReq = this.buildTurnRequest(req, reuseThreadId);
421
- let resolvedThreadId = reuseThreadId ?? "";
422
- const wrappedCb = {
423
- ...cb,
424
- onThreadId: (threadId) => {
425
- resolvedThreadId = threadId;
426
- cb.onThreadId?.(threadId);
427
- },
428
- onComplete: (result) => {
429
- cb.onComplete({
430
- ...result,
431
- tokenName: worker.tokenName,
432
- threadCoord: {
433
- workerId: makeOpenAIWorkerId(worker.tokenId, worker.workerIndex),
434
- threadId: resolvedThreadId,
435
- epoch: worker.epoch
436
- }
437
- });
438
- }
439
- };
440
- await worker.executeTurnStream(turnReq, wrappedCb, reuseThreadId);
441
- }
442
- async spawnWorkers(tokenId, tokenName, credentials, quotaThreshold, weight = 1) {
443
- if (this.startingTokenIds.has(tokenId)) return;
444
- this.startingTokenIds.add(tokenId);
445
- this.setTokenMetadata(tokenId, tokenName, credentials, quotaThreshold, weight);
446
- const expectedMetadata = this.tokenMetadata.get(tokenId);
447
- const workers = [];
448
- try {
449
- for (let i = 0; i < this.poolConfig.minWorkersPerToken; i++) {
450
- if (i > 0) await sleep(SPAWN_INTERVAL_MS);
451
- const worker = await this.spawnSingleWorker(tokenId, tokenName, credentials, i);
452
- if (worker) workers.push(worker);
453
- }
454
- if (!this.stopped && expectedMetadata?.active && this.tokenMetadata.get(tokenId) === expectedMetadata && !this.workerPool.has(tokenId)) {
455
- if (workers.length > 0) this.workerPool.set(tokenId, workers);
456
- } else await Promise.allSettled(workers.map((worker) => worker.kill()));
457
- } finally {
458
- this.startingTokenIds.delete(tokenId);
240
+ /** 세대가 바뀐 client 는 사용 중인 요청이 끝난 뒤에 닫는다. */
241
+ acquireClient(selection) {
242
+ const metadata = selection.metadata;
243
+ let entry = this.clients.get(selection.tokenId);
244
+ if (entry && entry.generation !== metadata.generation) {
245
+ this.retireClient(selection.tokenId);
246
+ entry = void 0;
459
247
  }
460
- }
461
- async spawnSingleWorker(tokenId, tokenName, credentials, workerIndex) {
462
- const worker = new CodexAppServerWorker({
463
- tokenId,
464
- tokenName,
465
- accessToken: credentials.accessToken,
466
- accountId: credentials.accountId,
467
- planType: credentials.planType,
468
- workerIndex
469
- });
470
- worker.onReady = () => this.requestDrainQueue();
471
- worker.onTerminalFailure = () => {
472
- this.handleWorkerTerminalFailure(worker).catch((e) => logger.warn(`terminal worker cleanup failed: ${tokenName}[${workerIndex}]: ${e.message}`));
473
- };
474
- worker.setServerRequestHandler(async (method) => {
475
- if (method === "account/chatgptAuthTokens/refresh") return handleChatgptAuthTokensRefresh(tokenId);
476
- throw new Error(`unhandled server-request: ${method}`);
477
- });
478
- try {
479
- await worker.initialize();
480
- logger.info(`worker spawned: ${tokenName}[${workerIndex}]`);
481
- return worker;
482
- } catch (e) {
483
- logger.warn(`worker spawn failed: ${tokenName}[${workerIndex}]: ${e.message}`);
484
- await worker.kill().catch(() => {});
485
- return null;
248
+ if (!entry) {
249
+ const client = this.clientFactory({
250
+ credentials: {
251
+ accessToken: metadata.credentials.accessToken,
252
+ accountId: metadata.credentials.accountId
253
+ },
254
+ transportKind: this.transportKind,
255
+ fetch: this.fetchImpl,
256
+ refreshCredentials: async () => {
257
+ const refreshed = await handleChatgptAuthTokensRefresh(selection.tokenId);
258
+ const current = this.tokenMetadata.get(selection.tokenId);
259
+ if (current) current.credentials = {
260
+ ...current.credentials,
261
+ accessToken: refreshed.accessToken,
262
+ accountId: refreshed.chatgptAccountId
263
+ };
264
+ return {
265
+ accessToken: refreshed.accessToken,
266
+ accountId: refreshed.chatgptAccountId
267
+ };
268
+ }
269
+ }, selection.tokenId);
270
+ entry = {
271
+ generation: metadata.generation,
272
+ client,
273
+ inFlight: 0,
274
+ retired: false
275
+ };
276
+ this.clients.set(selection.tokenId, entry);
486
277
  }
487
- }
488
- async evaluateAutoscaling() {
489
- if (this.stopped) return;
490
- this.sweepIdleWorkerThreads();
491
- const minimumDeficitTokenIds = await this.ensureMinimumWorkersOneStep();
492
- if (!this.poolConfig.autoscale || this.stopped) return;
493
- if (this.queue.length > 0) {
494
- await this.scaleUpOneStep(minimumDeficitTokenIds);
495
- return;
278
+ entry.inFlight++;
279
+ return entry;
280
+ }
281
+ releaseClient(entry) {
282
+ entry.inFlight = Math.max(0, entry.inFlight - 1);
283
+ if (entry.retired && entry.inFlight === 0) {
284
+ this.retiredClients.delete(entry);
285
+ entry.client.close?.();
496
286
  }
497
- if (Date.now() - this.lastRequestAt >= this.poolConfig.scaleDownIdleMs) await this.scaleDownOneStep();
498
287
  }
499
- async scaleUpOneStep(excludedTokenIds = /* @__PURE__ */ new Set()) {
500
- if (!this.poolConfig.autoscale || this.stopped) return;
501
- await this.runScaling(async () => {
502
- const candidates = [...this.tokenMetadata.entries()].filter(([tokenId, metadata]) => {
503
- if (!metadata.active || this.startingTokenIds.has(tokenId) || excludedTokenIds.has(tokenId) || this.quotaBlockedTokenIds.has(tokenId)) return false;
504
- return (this.workerPool.get(tokenId)?.length ?? 0) < this.poolConfig.maxWorkersPerToken;
505
- });
506
- if (candidates.length === 0) return;
507
- const projectedRssGiB = estimateOpenAIWorkerRssGiB(this.workerCount + candidates.length);
508
- if (projectedRssGiB > this.poolConfig.maxEstimatedRssGiB) {
509
- logger.warn(`openai autoscale blocked: estimated RSS ${projectedRssGiB.toFixed(2)}GiB exceeds ${this.poolConfig.maxEstimatedRssGiB.toFixed(2)}GiB`);
510
- return;
511
- }
512
- const hostAvailableGiB = this.getHostAvailableGiB();
513
- if (hostAvailableGiB < this.poolConfig.minHostAvailableGiB) {
514
- logger.warn(`openai autoscale blocked: host available ${hostAvailableGiB.toFixed(2)}GiB below ${this.poolConfig.minHostAvailableGiB.toFixed(2)}GiB`);
515
- return;
516
- }
517
- const added = (await Promise.all(candidates.map(([tokenId, metadata]) => this.spawnAndCommitWorker(tokenId, metadata, true)))).filter((worker) => worker !== null).length;
518
- if (added > 0) {
519
- logger.info(`openai autoscale up: +${added} workers (${this.workerCount} total, queue ${this.queue.length})`);
520
- this.requestDrainQueue();
521
- if (this.queue.length > 0) setTimeout(() => this.requestAutoscaleEvaluation(), Math.min(this.poolConfig.scaleIntervalMs, 1e3)).unref?.();
522
- }
523
- });
524
- }
525
- async ensureMinimumWorkersOneStep() {
526
- const minimumDeficitTokenIds = /* @__PURE__ */ new Set();
527
- if (this.stopped) return minimumDeficitTokenIds;
528
- await this.runScaling(async () => {
529
- const candidates = [...this.tokenMetadata.entries()].filter(([tokenId, metadata]) => {
530
- if (!metadata.active || this.startingTokenIds.has(tokenId)) return false;
531
- return (this.workerPool.get(tokenId)?.length ?? 0) < this.poolConfig.minWorkersPerToken;
532
- });
533
- if (candidates.length === 0) return;
534
- candidates.forEach(([tokenId]) => minimumDeficitTokenIds.add(tokenId));
535
- const added = (await Promise.all(candidates.map(([tokenId, metadata]) => this.spawnAndCommitWorker(tokenId, metadata, false)))).filter((worker) => worker !== null).length;
536
- if (added > 0) {
537
- logger.info(`openai worker pool repaired: +${added} workers (${this.workerCount} total)`);
538
- this.requestDrainQueue();
539
- if (this.queue.length > 0) setTimeout(() => this.requestAutoscaleEvaluation(), Math.min(this.poolConfig.scaleIntervalMs, 1e3)).unref?.();
540
- }
541
- });
542
- return minimumDeficitTokenIds;
543
- }
544
- async scaleDownOneStep() {
545
- if (!this.poolConfig.autoscale || this.stopped) return;
546
- await this.runScaling(async () => {
547
- const removed = [];
548
- for (const tokenId of this.tokenMetadata.keys()) {
549
- const workers = this.workerPool.get(tokenId) ?? [];
550
- if (workers.length <= this.poolConfig.minWorkersPerToken) continue;
551
- const worker = workers.toSorted((a, b) => b.workerIndex - a.workerIndex).find((entry) => entry.hasCapacity);
552
- if (!worker) continue;
553
- this.workerPool.set(tokenId, workers.filter((entry) => entry !== worker));
554
- removed.push(worker);
555
- }
556
- if (removed.length === 0) return;
557
- await Promise.allSettled(removed.map((worker) => worker.kill()));
558
- logger.info(`openai autoscale down: -${removed.length} workers (${this.workerCount} total)`);
559
- });
560
- }
561
- nextAvailableWorkerIndex(workers) {
562
- const used = new Set(workers.map((worker) => worker.workerIndex));
563
- for (let index = 0; index < this.poolConfig.maxWorkersPerToken; index++) if (!used.has(index)) return index;
564
- return this.poolConfig.maxWorkersPerToken;
565
- }
566
- sweepIdleWorkerThreads() {
567
- for (const worker of [...this.workerPool.values()].flat()) if (worker.isReady && worker.hasCapacity) worker.sweepIdleThreads();
568
- }
569
- async spawnAndCommitWorker(tokenId, metadata, respectQuotaBlock) {
570
- const expectedWorkers = this.workerPool.get(tokenId);
571
- const workerIndex = this.nextAvailableWorkerIndex(expectedWorkers ?? []);
572
- if (workerIndex >= this.poolConfig.maxWorkersPerToken) return null;
573
- const worker = await this.spawnSingleWorker(tokenId, metadata.name, metadata.credentials, workerIndex);
574
- if (!worker) return null;
575
- const currentMetadata = this.tokenMetadata.get(tokenId);
576
- const currentWorkers = this.workerPool.get(tokenId);
577
- if (!currentMetadata?.active || currentMetadata !== metadata || currentWorkers !== expectedWorkers || respectQuotaBlock && this.quotaBlockedTokenIds.has(tokenId) || currentWorkers?.some((entry) => entry.workerIndex === workerIndex)) {
578
- await worker.kill().catch(() => {});
579
- return null;
288
+ /** map 에서 떼어내고, 진행 중인 요청이 없을 때만 즉시 닫는다. */
289
+ retireClient(tokenId) {
290
+ const entry = this.clients.get(tokenId);
291
+ if (!entry) return;
292
+ this.clients.delete(tokenId);
293
+ entry.retired = true;
294
+ if (entry.inFlight === 0) entry.client.close?.();
295
+ else this.retiredClients.add(entry);
296
+ }
297
+ /**
298
+ * 토큰 선택 — quota gate 를 통과한 active 토큰 중에서 고른다. cache affinity 선호
299
+ * 토큰이 eligible 하면 그 판정만으로 즉시 결정하고(전체 sweep 생략, weighted 상태
300
+ * 비변경), 아니면 병렬 quota 판정 후 smooth weighted round-robin. 동시성 상한이
301
+ * 없으므로 "빈 자리" 개념도 없다 — 선택 즉시 실행이다.
302
+ */
303
+ async selectToken(preferredTokenId, signal) {
304
+ if (preferredTokenId !== void 0) {
305
+ const preferred = this.tokenMetadata.get(preferredTokenId);
306
+ if (preferred?.active && await this.isQuotaEligible(preferredTokenId, preferred, signal)) return {
307
+ tokenId: preferredTokenId,
308
+ metadata: preferred
309
+ };
580
310
  }
581
- const nextWorkers = currentWorkers ?? [];
582
- nextWorkers.push(worker);
583
- nextWorkers.sort((a, b) => a.workerIndex - b.workerIndex);
584
- if (!currentWorkers) this.workerPool.set(tokenId, nextWorkers);
585
- return worker;
586
- }
587
- async handleWorkerTerminalFailure(worker) {
588
- if (!this.workerPool.get(worker.tokenId)?.includes(worker)) return;
589
- await worker.kill().catch(() => {});
590
- const currentWorkers = this.workerPool.get(worker.tokenId);
591
- if (!currentWorkers?.includes(worker)) return;
592
- const remaining = currentWorkers.filter((entry) => entry !== worker);
593
- if (remaining.length > 0) this.workerPool.set(worker.tokenId, remaining);
594
- else this.workerPool.delete(worker.tokenId);
595
- logger.warn(`terminal worker removed: ${worker.tokenName}[${worker.workerIndex}] (${remaining.length} remaining)`);
596
- this.requestAutoscaleEvaluation();
597
- }
598
- requestAutoscaleEvaluation() {
599
- if (this.stopped) return;
600
- this.evaluateAutoscaling().catch((e) => logger.warn(`openai autoscale evaluation failed: ${e.message}`));
601
- }
602
- async runScaling(task) {
603
- if (this.scalingPromise) {
604
- await this.scalingPromise;
605
- return;
311
+ const checks = await Promise.all([...this.tokenMetadata.entries()].filter(([, token]) => token.active).map(async ([id, token]) => ({
312
+ id,
313
+ token,
314
+ eligible: await this.isQuotaEligible(id, token, signal)
315
+ })));
316
+ const eligible = new Set(checks.filter((c) => c.eligible).map((c) => c.id));
317
+ if (eligible.size === 0) {
318
+ const over = checks.filter((c) => !c.eligible && c.token.quotaThreshold !== null && c.token.quotaThreshold !== void 0).map((c) => ({
319
+ name: c.token.name,
320
+ threshold: c.token.quotaThreshold
321
+ }));
322
+ if (over.length) {
323
+ logger.warn("quota_threshold gate: all_exceeded", {
324
+ provider: "openai",
325
+ overThresholdTokens: over
326
+ });
327
+ throw new QuotaThresholdExceededError(quotaMessage(over));
328
+ }
329
+ throw new Error("NO_OPENAI_WORKERS");
606
330
  }
607
- const scaling = task().finally(() => {
608
- if (this.scalingPromise === scaling) this.scalingPromise = null;
609
- });
610
- this.scalingPromise = scaling;
611
- await scaling;
612
- }
613
- rateLimitsCache = /* @__PURE__ */ new Map();
614
- static RATE_LIMITS_CACHE_TTL = 6e4;
615
- async getRateLimitsByTokenId(tokenId) {
616
- const generation = this.rateLimitsGenerationByToken.get(tokenId) ?? 0;
617
- const cached = this.rateLimitsCache.get(tokenId);
618
- if (cached && cached.generation === generation && Date.now() - cached.cachedAt < OpenAIDispatcher.RATE_LIMITS_CACHE_TTL) return {
619
- data: cached.data,
620
- cachedAt: cached.cachedAt
621
- };
622
- const worker = (this.workerPool.get(tokenId) ?? []).find((w) => w.isReady);
623
- if (!worker) throw new Error("no ready openai workers");
624
- const entry = {
625
- data: await worker.getRateLimits(),
626
- cachedAt: Date.now(),
627
- generation
628
- };
629
- if ((this.rateLimitsGenerationByToken.get(tokenId) ?? 0) === generation) this.rateLimitsCache.set(tokenId, entry);
331
+ const selected = this.selector.select(eligible);
332
+ const metadata = selected !== null ? this.tokenMetadata.get(selected) : void 0;
333
+ if (selected === null || !metadata) throw new Error("NO_OPENAI_WORKERS");
630
334
  return {
631
- data: entry.data,
632
- cachedAt: entry.cachedAt
335
+ tokenId: selected,
336
+ metadata
633
337
  };
634
338
  }
635
- requestDrainQueue() {
636
- this.drainQueue().catch((e) => logger.warn(`drainQueue failed: ${e.message}`));
637
- }
638
- invalidateRateLimitsCache(tokenId) {
639
- this.rateLimitsCache.delete(tokenId);
640
- this.rateLimitsGenerationByToken.set(tokenId, (this.rateLimitsGenerationByToken.get(tokenId) ?? 0) + 1);
641
- }
642
- setTokenMetadata(id, name, credentials, quotaThreshold, weight) {
643
- this.tokenMetadata.set(id, {
339
+ setToken(id, name, credentials, quotaThreshold, weight, active) {
340
+ const old = this.tokenMetadata.get(id);
341
+ if (old) Object.assign(old, {
644
342
  name,
645
343
  credentials,
646
344
  quotaThreshold,
647
345
  weight,
648
- active: this.tokenMetadata.get(id)?.active ?? true
346
+ active,
347
+ generation: old.generation + 1
649
348
  });
650
- this.weightedSelector.setToken(id, weight);
651
- }
652
- hasActiveTokenCandidate(excludedTokenIds) {
653
- return [...this.tokenMetadata.entries()].some(([tokenId, metadata]) => metadata.active && !excludedTokenIds.has(tokenId));
654
- }
655
- getQuotaThreshold(tokenId) {
656
- return this.tokenMetadata.get(tokenId)?.quotaThreshold;
657
- }
658
- hasQuotaThreshold(tokenId) {
659
- const threshold = this.getQuotaThreshold(tokenId);
660
- return threshold !== void 0 && threshold !== null;
661
- }
662
- async resolveTokenEligibility(excludedTokenIds) {
663
- const workers = this.getAllReadyActiveWorkers();
664
- const byToken = /* @__PURE__ */ new Map();
665
- for (const worker of workers) if (!byToken.has(worker.tokenId)) byToken.set(worker.tokenId, worker.tokenName);
666
- const readyActiveTokenIds = new Set(byToken.keys());
667
- const eligibleTokenIds = /* @__PURE__ */ new Set();
668
- const overThresholdTokens = [];
669
- let thresholdedTokenCount = 0;
670
- const entries = Array.from(byToken.entries());
671
- (await Promise.allSettled(entries.map(async ([tokenId, tokenName]) => {
672
- if (excludedTokenIds.has(tokenId)) {
673
- thresholdedTokenCount++;
674
- return {
675
- tokenId,
676
- tokenName,
677
- eligible: false
678
- };
679
- }
680
- if (!this.hasQuotaThreshold(tokenId)) return {
681
- tokenId,
682
- tokenName,
683
- eligible: true
684
- };
685
- thresholdedTokenCount++;
686
- return {
687
- tokenId,
688
- tokenName,
689
- eligible: await this.isTokenQuotaEligible(tokenId, tokenName)
690
- };
691
- }))).forEach((check, index) => {
692
- if (check.status === "fulfilled") {
693
- if (check.value.eligible) eligibleTokenIds.add(check.value.tokenId);
694
- else {
695
- const threshold = this.getQuotaThreshold(check.value.tokenId);
696
- if (threshold !== void 0 && threshold !== null) overThresholdTokens.push({
697
- tokenName: check.value.tokenName,
698
- threshold
699
- });
700
- }
701
- return;
702
- }
703
- const entry = entries[index];
704
- if (entry) {
705
- const [tokenId, tokenName] = entry;
706
- this.logQuotaLookupFailOpen(tokenId, tokenName, String(check.reason));
707
- eligibleTokenIds.add(tokenId);
708
- }
349
+ else this.tokenMetadata.set(id, {
350
+ name,
351
+ credentials,
352
+ quotaThreshold,
353
+ weight,
354
+ active,
355
+ generation: 1
709
356
  });
710
- return {
711
- readyActiveTokenIds,
712
- eligibleTokenIds,
713
- overThresholdTokens,
714
- thresholdedTokenCount
715
- };
357
+ this.selector.setToken(id, weight);
358
+ this.invalidateRateLimitsCache(id);
359
+ this.quotaBlocked.delete(id);
716
360
  }
717
- async isTokenQuotaEligible(tokenId, tokenName, excludedTokenIds) {
718
- for (;;) {
719
- const tokenMetadata = this.tokenMetadata.get(tokenId);
720
- const threshold = tokenMetadata?.quotaThreshold;
721
- if (!tokenMetadata?.active || threshold === void 0 || threshold === null) {
722
- this.quotaBlockedTokenIds.delete(tokenId);
723
- return true;
724
- }
725
- let result;
726
- try {
727
- result = await readOpenAIQuotaUsage(() => this.getRateLimitsByTokenId(tokenId));
728
- } catch (e) {
729
- if (this.tokenMetadata.get(tokenId) !== tokenMetadata) continue;
730
- this.quotaBlockedTokenIds.delete(tokenId);
731
- this.logQuotaLookupFailOpen(tokenId, tokenMetadata.name ?? tokenName, e.message);
732
- return true;
733
- }
734
- if (this.tokenMetadata.get(tokenId) !== tokenMetadata) continue;
735
- if (result.kind === "lookup_failed") {
736
- this.quotaBlockedTokenIds.delete(tokenId);
737
- this.logQuotaLookupFailOpen(tokenId, tokenMetadata.name ?? tokenName, result.reason);
738
- return true;
739
- }
740
- if (result.utilizationPct >= threshold) {
741
- const transitioned = !this.quotaBlockedTokenIds.has(tokenId);
742
- this.quotaBlockedTokenIds.add(tokenId);
743
- if (transitioned) this.logQuotaOverThreshold(tokenId, tokenMetadata.name ?? tokenName, threshold, result);
744
- excludedTokenIds?.add(tokenId);
745
- return false;
746
- }
747
- if (this.quotaBlockedTokenIds.delete(tokenId)) this.logQuotaRecovered(tokenId, tokenMetadata.name ?? tokenName, threshold, result);
361
+ async getRateLimitsByTokenId(tokenId, signal) {
362
+ const token = this.tokenMetadata.get(tokenId);
363
+ if (!token) throw new Error(`openai token ${tokenId} not found`);
364
+ const cached = this.rateLimitsCache.get(tokenId);
365
+ if (cached && cached.generation === token.generation && Date.now() - cached.cachedAt < OpenAIDispatcher.RATE_LIMITS_CACHE_TTL) return cached;
366
+ const pending = this.pendingRateLimits.get(tokenId);
367
+ if (pending) return pending;
368
+ const fetchPromise = (async () => {
369
+ const result = await readOpenAIQuotaUsage({
370
+ credentials: token.credentials,
371
+ fetch: this.fetchImpl,
372
+ ...signal ? { signal } : {}
373
+ });
374
+ if (result.kind === "lookup_failed") throw new Error(result.reason);
375
+ if (!result.raw) throw new Error("OpenAI quota response missing raw rate limits");
376
+ const entry = {
377
+ data: result.raw,
378
+ cachedAt: Date.now(),
379
+ generation: token.generation
380
+ };
381
+ if (this.tokenMetadata.get(tokenId) === token) this.rateLimitsCache.set(tokenId, entry);
382
+ return entry;
383
+ })().finally(() => this.pendingRateLimits.delete(tokenId));
384
+ this.pendingRateLimits.set(tokenId, fetchPromise);
385
+ return fetchPromise;
386
+ }
387
+ async isQuotaEligible(id, token, signal) {
388
+ if (token.quotaThreshold === null || token.quotaThreshold === void 0) return true;
389
+ const generation = token.generation;
390
+ const result = await readOpenAIQuotaUsage(async () => this.getRateLimitsByTokenId(id, signal));
391
+ if (this.tokenMetadata.get(id) !== token || token.generation !== generation) return false;
392
+ if (result.kind === "lookup_failed") {
393
+ this.quotaBlocked.delete(id);
394
+ logger.warn("quota_threshold gate: lookup_fail_open", {
395
+ tokenId: id,
396
+ tokenName: token.name,
397
+ lookupReason: result.reason
398
+ });
748
399
  return true;
749
400
  }
750
- }
751
- logQuotaOverThreshold(tokenId, tokenName, threshold, result) {
752
- logger.info(`quota_threshold gate: over_threshold ${tokenName}[${tokenId}] (${result.utilizationPct}% >= ${threshold}%)`, {
753
- tokenId,
754
- tokenName,
755
- provider: "openai",
756
- threshold,
757
- cachedUtilization: result.utilizationPct,
758
- cacheAge: result.cacheAgeMs,
759
- windowDurationMins: result.windowDurationMins,
760
- resetsAt: result.resetsAt,
761
- limitId: result.limitId,
762
- reason: "over_threshold"
763
- });
764
- }
765
- logQuotaRecovered(tokenId, tokenName, threshold, result) {
766
- logger.info(`quota_threshold gate: recovered ${tokenName}[${tokenId}] (${result.utilizationPct}% < ${threshold}%)`, {
767
- tokenId,
768
- tokenName,
769
- provider: "openai",
770
- threshold,
771
- cachedUtilization: result.utilizationPct,
772
- cacheAge: result.cacheAgeMs,
773
- windowDurationMins: result.windowDurationMins,
774
- resetsAt: result.resetsAt,
775
- limitId: result.limitId,
776
- reason: "recovered"
777
- });
778
- }
779
- logQuotaLookupFailOpen(tokenId, tokenName, reason) {
780
- const threshold = this.getQuotaThreshold(tokenId);
781
- logger.warn("quota_threshold gate: lookup_fail_open", {
782
- tokenId,
783
- tokenName,
784
- provider: "openai",
785
- threshold,
786
- reason: "lookup_fail_open",
787
- lookupReason: reason
788
- });
789
- }
790
- throwQuotaThresholdExceeded(eligibility) {
791
- logger.warn("quota_threshold gate: all_exceeded", {
792
- provider: "openai",
793
- tokenCount: eligibility.readyActiveTokenIds.size,
794
- thresholdedTokenCount: eligibility.thresholdedTokenCount,
795
- overThresholdTokens: eligibility.overThresholdTokens,
796
- reason: "all_exceeded"
797
- });
798
- throw new QuotaThresholdExceededError(quotaThresholdExceededMessage("openai", eligibility.overThresholdTokens));
799
- }
800
- pendingLogin = null;
801
- async startBrowserLogin(name) {
802
- if (this.pendingLogin) {
803
- this.pendingLogin.worker.kill().catch(() => {});
804
- clearTimeout(this.pendingLogin.timer);
805
- this.pendingLogin = null;
806
- }
807
- const worker = new CodexAppServerWorker({
808
- tokenId: Date.now(),
809
- tokenName: name,
810
- accessToken: "",
811
- accountId: ""
812
- });
813
- const authUrl = await worker.startBrowserLogin();
814
- const timer = setTimeout(() => {
815
- if (this.pendingLogin?.worker === worker) {
816
- logger.warn(`browser login timeout for ${name}, killing worker`);
817
- worker.kill().catch(() => {});
818
- this.pendingLogin = null;
819
- }
820
- }, 3e5);
821
- this.pendingLogin = {
822
- worker,
823
- name,
824
- timer
825
- };
826
- return { authUrl };
827
- }
828
- get pendingLoginName() {
829
- return this.pendingLogin?.name ?? null;
830
- }
831
- async completeBrowserLogin() {
832
- if (!this.pendingLogin) throw new Error("no pending login");
833
- const { worker, timer } = this.pendingLogin;
834
- try {
835
- await worker.waitForBrowserLoginComplete();
836
- const creds = await worker.readManagedCredentials();
837
- if (!creds) throw new Error("failed to read credentials after login");
838
- return creds;
839
- } finally {
840
- clearTimeout(timer);
841
- this.pendingLogin = null;
842
- await worker.kill().catch(() => {});
401
+ if (result.utilizationPct >= token.quotaThreshold) {
402
+ if (!this.quotaBlocked.has(id)) logger.info(`quota_threshold gate: over_threshold ${token.name}[${id}] (${result.utilizationPct}% >= ${token.quotaThreshold}%)`);
403
+ this.quotaBlocked.add(id);
404
+ return false;
843
405
  }
844
- }
845
- get workerCount() {
846
- return [...this.workerPool.values()].flat().length;
847
- }
848
- get readyWorkerCount() {
849
- return [...this.workerPool.values()].flat().filter((w) => w.isReady).length;
850
- }
851
- get queueLength() {
852
- return this.queue.length;
853
- }
854
- get workerCountsByToken() {
855
- return [...this.workerPool.entries()].map(([tokenId, workers]) => ({
856
- name: workers[0]?.tokenName ?? `token ${tokenId}`,
857
- count: workers.length
858
- })).filter((entry) => entry.count > 0).toSorted((a, b) => a.name.localeCompare(b.name));
406
+ if (this.quotaBlocked.delete(id)) logger.info(`quota_threshold gate: recovered ${token.name}[${id}] (${result.utilizationPct}% < ${token.quotaThreshold}%)`);
407
+ return true;
408
+ }
409
+ invalidateRateLimitsCache(id) {
410
+ this.rateLimitsCache.delete(id);
411
+ }
412
+ get tokenCount() {
413
+ return [...this.tokenMetadata.values()].filter((t) => t.active).length;
414
+ }
415
+ get inFlight() {
416
+ return this.inFlightCount;
417
+ }
418
+ /**
419
+ * 토큰별 쿼터 스냅샷 — 신선한(rate limits TTL 내) 캐시만 읽고 절대 fetch 하지 않는다.
420
+ * monit vitals 는 로그 폴링에 편승하는 값이라 여기서 네트워크를 타면 안 된다.
421
+ * threshold 미설정 토큰은 쿼터 판정을 돌지 않아 usedPercent 가 null 로 남을 수 있다.
422
+ */
423
+ get quotaByToken() {
424
+ const now = Date.now();
425
+ return [...this.tokenMetadata.entries()].map(([id, t]) => {
426
+ const cached = this.rateLimitsCache.get(id);
427
+ const primary = cached !== void 0 && cached.generation === t.generation && now - cached.cachedAt < OpenAIDispatcher.RATE_LIMITS_CACHE_TTL ? cached.data.rateLimits?.primary : void 0;
428
+ return {
429
+ name: t.name,
430
+ usedPercent: primary?.usedPercent ?? null,
431
+ threshold: t.quotaThreshold ?? null,
432
+ blocked: this.quotaBlocked.has(id),
433
+ resetsAt: primary?.resetsAt !== null && primary?.resetsAt !== void 0 ? primary.resetsAt * 1e3 : null
434
+ };
435
+ }).toSorted((a, b) => a.name.localeCompare(b.name));
859
436
  }
860
437
  };
861
438
  //#endregion
862
- export { ImageGenerationError, OpenAIDispatcher, makeOpenAIWorkerId };
439
+ export { ImageGenerationError, OpenAIDispatcher };
863
440
 
864
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLWRpc3BhdGNoZXIuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9vcGVuYWkvb3BlbmFpLWRpc3BhdGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBPcGVuQUlEaXNwYXRjaGVyIOKAlCBjb2RleCBhcHAtc2VydmVyIHdvcmtlciBwb29sICsg7Yag7YGwIOudvOyasO2MhS5cbiAqXG4gKiAtIO2GoO2BsOuLuSBDb2RleEFwcFNlcnZlcldvcmtlciDsnpDrj5kg7ZmV7J6lICjquLDrs7ggMX4zLCBoYXJkIGNhcCAyMClcbiAqIC0gaWRsZSB3b3JrZXIgcm91bmQtcm9iaW4g7ISg7YOdICsg7YGQIOuMgOq4sCAo7KCE67aAIGJ1c3kg7IucKVxuICogLSBUb2tlblN1YnNjcmliZXIg7J2067Kk7Yq466GcIHdvcmtlciBwb29sIOuPmeq4sO2ZlFxuICogLSBiYWNrcHJlc3N1cmU6IO2BkCBmdWxsIOuYkOuKlCB0aW1lb3V0IOyLnCBTRVJWRVJfQlVTWVxuICovXG5pbXBvcnQgeyByZWFkRmlsZVN5bmMgfSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHsgZnJlZW1lbSB9IGZyb20gXCJub2RlOm9zXCI7XG5cbmltcG9ydCB7IGdldExvZ2dlciB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5cbmltcG9ydCB7IFF1b3RhVGhyZXNob2xkRXhjZWVkZWRFcnJvciB9IGZyb20gXCIuLi8uLi8uLi9hcHBsaWNhdGlvbi9xZ3JpZC9xZ3JpZC50eXBlc1wiO1xuaW1wb3J0IHsgVG9rZW5Nb2RlbCB9IGZyb20gXCIuLi8uLi8uLi9hcHBsaWNhdGlvbi90b2tlbi90b2tlbi5tb2RlbFwiO1xuaW1wb3J0IHsgdHlwZSBPcGVuQUlDcmVkZW50aWFscyB9IGZyb20gXCIuLi8uLi8uLi9hcHBsaWNhdGlvbi90b2tlbi90b2tlbi50eXBlc1wiO1xuaW1wb3J0IHsgdHlwZSBHZXRBY2NvdW50UmF0ZUxpbWl0c1Jlc3BvbnNlIH0gZnJvbSBcIi4uLy4uLy4uL2NvZGV4LXByb3RvY29sL3YyL0dldEFjY291bnRSYXRlTGltaXRzUmVzcG9uc2VcIjtcbmltcG9ydCB7XG4gIHR5cGUgR2VuZXJhdGVSZXF1ZXN0LFxuICB0eXBlIEdlbmVyYXRlUmVzdWx0LFxuICB0eXBlIEdlbmVyYXRlU3RyZWFtQ2FsbGJhY2tzLFxuICB0eXBlIFByb3ZpZGVyRGlzcGF0Y2hlcixcbn0gZnJvbSBcIi4uL2NvbW1vbi9wcm92aWRlci1kaXNwYXRjaGVyXCI7XG5pbXBvcnQgeyBTbW9vdGhXZWlnaHRlZFJvdW5kUm9iaW4gfSBmcm9tIFwiLi4vY29tbW9uL3Ntb290aC13ZWlnaHRlZC1yb3VuZC1yb2JpblwiO1xuaW1wb3J0IHsgQ29kZXhBcHBTZXJ2ZXJXb3JrZXIsIHR5cGUgU3RyZWFtQ2FsbGJhY2tzLCB0eXBlIFR1cm5SZXF1ZXN0IH0gZnJvbSBcIi4vY29kZXgtd29ya2VyXCI7XG5pbXBvcnQge1xuICByZWFkT3BlbkFJUXVvdGFVc2FnZSxcbiAgdHlwZSBPcGVuQUlRdW90YVVzYWdlUmVzdWx0LFxuICB0eXBlIE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YSxcbn0gZnJvbSBcIi4vb3BlbmFpLXF1b3RhXCI7XG5pbXBvcnQgeyBoYW5kbGVDaGF0Z3B0QXV0aFRva2Vuc1JlZnJlc2ggfSBmcm9tIFwiLi9vcGVuYWktcmVmcmVzaFwiO1xuaW1wb3J0IHtcbiAgZXN0aW1hdGVPcGVuQUlXb3JrZXJSc3NHaUIsXG4gIHR5cGUgT3BlbkFJV29ya2VyUG9vbENvbmZpZyxcbiAgcmVzb2x2ZU9wZW5BSVdvcmtlclBvb2xDb25maWcsXG59IGZyb20gXCIuL29wZW5haS13b3JrZXItcG9vbC1jb25maWdcIjtcblxuY29uc3QgbG9nZ2VyID0gZ2V0TG9nZ2VyKFtcInFncmlkXCIsIFwib3BlbmFpLWRpc3BhdGNoZXJcIl0pO1xuXG4vLyDsnbTrr7jsp4Ag7IOd7ISxIOyalOyyreydtCDqsozsnbTtirgv7IOd7ISx7JeQIOyLpO2MqO2WiOydhCDrlYzsnZgg6rWs67aE7J6QLlxuLy8gLSBcImdhdGVcIjog7IKs7KCEIOqygOymnSDsi6TtjKgoY2FwYWJpbGl0eS/rqqjrjbgg66mA7Yuw66qo64usIOu2iOy2qeyhsSkg4oCUIHR1cm4g66+47Iuk7ZaJLlxuLy8gLSBcIm5vdF9jYWxsZWRcIjogdHVybiDsnYAg7ISx6rO17ZaI7Jy864KYIOuqqOuNuOydtCBpbWFnZSB0b29sIOydhCDtmLjstpwg7JWIIO2VqCDigJQg7J6s7Iuc64+EIOustOydtSjtlITroaztlITtirgg66y47KCcKS5cbi8vIC0gXCJpbmNvbXBsZXRlXCI6IHRvb2wg7Iuc64+E65CQ7Jy864KYIOyZhOyEsSDsnbTrr7jsp4Ag66+464+E7LCpIOKAlCDsnqzsi5zrj4Qg7ZuE67O0KOyEnOuyhOy4oSDsi6TtjKgv6rGw67aAKS5cbmV4cG9ydCB0eXBlIEltYWdlRmFpbHVyZUtpbmQgPSBcImdhdGVcIiB8IFwibm90X2NhbGxlZFwiIHwgXCJpbmNvbXBsZXRlXCI7XG5cbmV4cG9ydCBjbGFzcyBJbWFnZUdlbmVyYXRpb25FcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcmVhZG9ubHkga2luZDogSW1hZ2VGYWlsdXJlS2luZCxcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiSW1hZ2VHZW5lcmF0aW9uRXJyb3JcIjtcbiAgfVxufVxuXG5jb25zdCBERUZBVUxUX0VGRk9SVCA9IFwibG93XCI7XG5jb25zdCBRVUVVRV9USU1FT1VUX01TID0gNjBfMDAwO1xuY29uc3QgTUFYX1FVRVVFX1NJWkUgPSA1MDtcbmNvbnN0IFNQQVdOX0lOVEVSVkFMX01TID0gNTAwO1xuXG5mdW5jdGlvbiByZWFkSG9zdEF2YWlsYWJsZUdpQigpOiBudW1iZXIge1xuICB0cnkge1xuICAgIGNvbnN0IG1hdGNoID0gcmVhZEZpbGVTeW5jKFwiL3Byb2MvbWVtaW5mb1wiLCBcInV0ZjhcIikubWF0Y2goL15NZW1BdmFpbGFibGU6XFxzKyhcXGQrKVxccytrQiQvbSk7XG4gICAgaWYgKG1hdGNoPy5bMV0pIHJldHVybiBOdW1iZXIobWF0Y2hbMV0pIC8gMTAyNCAvIDEwMjQ7XG4gIH0gY2F0Y2gge31cbiAgcmV0dXJuIGZyZWVtZW0oKSAvIDEwMjQgLyAxMDI0IC8gMTAyNDtcbn1cblxuLy8gdGhyZWFkIOyerOyCrOyaqShwcm9tcHQgY2FjaGUg6rOg7KCVKS4g64GE66m0IOq4sOyhtCBcIuunpCB0dXJuIOyDiCB0aHJlYWQgKyBoaXN0b3J5IGluamVjdFwiIOuPmeyekS5cbmNvbnN0IFRIUkVBRF9SRVVTRV9FTkFCTEVEID0gcHJvY2Vzcy5lbnYuUUdSSURfT1BFTkFJX1RIUkVBRF9SRVVTRSAhPT0gXCJmYWxzZVwiO1xuLy8g7KKM7ZGcIHdvcmtlciDqsIAgYnVzeSDsnbwg65WMIGZyZWUg66W8IOq4sOuLpOumrOuKlCDstZzrjIAg7Iuc6rCELiDstIjqs7wg7IucIOyDiCB0aHJlYWQg66GcIO2PtOuwsS5cbmNvbnN0IFJFVVNFX1dPUktFUl9XQUlUX01TID0gNV8wMDA7XG5jb25zdCBSRVVTRV9XT1JLRVJfUE9MTF9NUyA9IDUwO1xuXG4vLyB3b3JrZXJJZCDtlanshLE6IHRva2VuSWQg7JmAIHdvcmtlckluZGV4KDAuLjE5KSDrpbwg7ZWY64KY7J2YIOyViOyglSDsiKvsnpDroZwg7J247L2U65SpLlxuY29uc3QgT1BFTkFJX1dPUktFUl9JRF9TVFJJREUgPSAxMDA7XG5leHBvcnQgZnVuY3Rpb24gbWFrZU9wZW5BSVdvcmtlcklkKHRva2VuSWQ6IG51bWJlciwgd29ya2VySW5kZXg6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiB0b2tlbklkICogT1BFTkFJX1dPUktFUl9JRF9TVFJJREUgKyB3b3JrZXJJbmRleDtcbn1cblxuZnVuY3Rpb24gc2xlZXAobXM6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcbn1cblxuZnVuY3Rpb24gcXVvdGFUaHJlc2hvbGRFeGNlZWRlZE1lc3NhZ2UoXG4gIHByb3ZpZGVyOiBzdHJpbmcsXG4gIHRva2VuczogQXJyYXk8eyB0b2tlbk5hbWU6IHN0cmluZzsgdGhyZXNob2xkOiBudW1iZXIgfT4sXG4pOiBzdHJpbmcge1xuICBjb25zdCBkZXRhaWxzID0gdG9rZW5zXG4gICAgLm1hcCgodG9rZW4pID0+IGAke3Rva2VuLnRva2VuTmFtZX0gKHRocmVzaG9sZCAke3Rva2VuLnRocmVzaG9sZH0lKWApXG4gICAgLmpvaW4oXCIsIFwiKTtcbiAgcmV0dXJuIGRldGFpbHMubGVuZ3RoID4gMFxuICAgID8gYEFsbCAke3Byb3ZpZGVyfSB0b2tlbnMgZXhjZWVkZWQgcXVvdGEgdGhyZXNob2xkOiAke2RldGFpbHN9YFxuICAgIDogYEFsbCAke3Byb3ZpZGVyfSB0b2tlbnMgZXhjZWVkZWQgcXVvdGEgdGhyZXNob2xkYDtcbn1cblxudHlwZSBRdWV1ZUl0ZW0gPSB7XG4gIHJlc29sdmU6ICh3b3JrZXI6IENvZGV4QXBwU2VydmVyV29ya2VyKSA9PiB2b2lkO1xuICByZWplY3Q6IChlcnJvcjogRXJyb3IpID0+IHZvaWQ7XG4gIHRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PjtcbiAgYWJvcnRDbGVhbnVwPzogKCkgPT4gdm9pZDtcbiAgZXhjbHVkZWRUb2tlbklkczogU2V0PG51bWJlcj47XG59O1xuXG50eXBlIFRva2VuTWV0YWRhdGEgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzO1xuICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGw7XG4gIHdlaWdodDogbnVtYmVyO1xuICBhY3RpdmU6IGJvb2xlYW47XG59O1xuXG50eXBlIFRva2VuRWxpZ2liaWxpdHkgPSB7XG4gIHJlYWR5QWN0aXZlVG9rZW5JZHM6IFNldDxudW1iZXI+O1xuICBlbGlnaWJsZVRva2VuSWRzOiBTZXQ8bnVtYmVyPjtcbiAgb3ZlclRocmVzaG9sZFRva2VuczogQXJyYXk8eyB0b2tlbk5hbWU6IHN0cmluZzsgdGhyZXNob2xkOiBudW1iZXIgfT47XG4gIHRocmVzaG9sZGVkVG9rZW5Db3VudDogbnVtYmVyO1xufTtcblxudHlwZSBSYXRlTGltaXRzQ2FjaGVFbnRyeSA9IE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YSAmIHtcbiAgZ2VuZXJhdGlvbjogbnVtYmVyO1xufTtcblxuZXhwb3J0IGNsYXNzIE9wZW5BSURpc3BhdGNoZXIgaW1wbGVtZW50cyBQcm92aWRlckRpc3BhdGNoZXIge1xuICB3b3JrZXJQb29sID0gbmV3IE1hcDxudW1iZXIsIENvZGV4QXBwU2VydmVyV29ya2VyW10+KCk7XG4gIHRva2VuTWV0YWRhdGEgPSBuZXcgTWFwPG51bWJlciwgVG9rZW5NZXRhZGF0YT4oKTtcbiAgcXVldWU6IFF1ZXVlSXRlbVtdID0gW107XG4gIHJlYWRvbmx5IHBvb2xDb25maWc6IE9wZW5BSVdvcmtlclBvb2xDb25maWc7XG4gIHByaXZhdGUgcmVhZG9ubHkgcXVvdGFCbG9ja2VkVG9rZW5JZHMgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBzdGFydGluZ1Rva2VuSWRzID0gbmV3IFNldDxudW1iZXI+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmF0ZUxpbWl0c0dlbmVyYXRpb25CeVRva2VuID0gbmV3IE1hcDxudW1iZXIsIG51bWJlcj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSB3ZWlnaHRlZFNlbGVjdG9yID0gbmV3IFNtb290aFdlaWdodGVkUm91bmRSb2JpbigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHdvcmtlckN1cnNvckJ5VG9rZW4gPSBuZXcgTWFwPG51bWJlciwgbnVtYmVyPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGdldEhvc3RBdmFpbGFibGVHaUI6ICgpID0+IG51bWJlcjtcbiAgcHJpdmF0ZSBkcmFpbmluZyA9IGZhbHNlO1xuICBwcml2YXRlIGRyYWluQWdhaW4gPSBmYWxzZTtcbiAgcHJpdmF0ZSBzY2FsZXJUaW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0SW50ZXJ2YWw+IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgc2NhbGluZ1Byb21pc2U6IFByb21pc2U8dm9pZD4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBsYXN0UmVxdWVzdEF0ID0gRGF0ZS5ub3coKTtcbiAgcHJpdmF0ZSBzdG9wcGVkID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcG9vbENvbmZpZzogT3BlbkFJV29ya2VyUG9vbENvbmZpZyA9IHJlc29sdmVPcGVuQUlXb3JrZXJQb29sQ29uZmlnKCksXG4gICAgZ2V0SG9zdEF2YWlsYWJsZUdpQjogKCkgPT4gbnVtYmVyID0gcmVhZEhvc3RBdmFpbGFibGVHaUIsXG4gICkge1xuICAgIHRoaXMucG9vbENvbmZpZyA9IHBvb2xDb25maWc7XG4gICAgdGhpcy5nZXRIb3N0QXZhaWxhYmxlR2lCID0gZ2V0SG9zdEF2YWlsYWJsZUdpQjtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuc3RvcHBlZCA9IGZhbHNlO1xuICAgIGNvbnN0IHsgcm93cyB9ID0gYXdhaXQgVG9rZW5Nb2RlbC5maW5kTWFueShcIkFcIik7XG4gICAgY29uc3Qgb3BlbmFpVG9rZW5zID0gcm93cy5maWx0ZXIoKHQpID0+IHQucHJvdmlkZXIgPT09IFwib3BlbmFpXCIpO1xuICAgIGxvZ2dlci5pbmZvKFxuICAgICAgdGhpcy5wb29sQ29uZmlnLmF1dG9zY2FsZVxuICAgICAgICA/IGBzdGFydGluZyAke29wZW5haVRva2Vucy5sZW5ndGh9IG9wZW5haSB0b2tlbnMgKCR7dGhpcy5wb29sQ29uZmlnLm1pbldvcmtlcnNQZXJUb2tlbn0tJHt0aGlzLnBvb2xDb25maWcubWF4V29ya2Vyc1BlclRva2VufSB3b3JrZXJzIGVhY2gsIGF1dG9zY2FsZSlgXG4gICAgICAgIDogYHN0YXJ0aW5nICR7b3BlbmFpVG9rZW5zLmxlbmd0aH0gb3BlbmFpIHRva2VucyAoJHt0aGlzLnBvb2xDb25maWcubWluV29ya2Vyc1BlclRva2VufSB3b3JrZXJzIGVhY2gpYCxcbiAgICApO1xuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFxuICAgICAgb3BlbmFpVG9rZW5zLm1hcChhc3luYyAodCkgPT4ge1xuICAgICAgICBhd2FpdCB0aGlzLnNwYXduV29ya2VycyhcbiAgICAgICAgICB0LmlkLFxuICAgICAgICAgIHQubmFtZSxcbiAgICAgICAgICB0LmNyZWRlbnRpYWxzIGFzIE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgICAgICAgIHQucXVvdGFfdGhyZXNob2xkLFxuICAgICAgICAgIHQud2VpZ2h0LFxuICAgICAgICApO1xuICAgICAgICBpZiAoIXQuYWN0aXZlKSB0aGlzLm9uVG9rZW5EZWFjdGl2YXRlZCh0LmlkKTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICAvLyBhdXRvc2NhbGUgb2Zm64+EIGZpeGVkIG1pbuydmCBoZWFsdGggbWFpbnRlbmFuY2XripQg6rOE7IaNIO2VhOyalO2VmOuLpC5cbiAgICB0aGlzLnNjYWxlclRpbWVyID0gc2V0SW50ZXJ2YWwoXG4gICAgICAoKSA9PiB0aGlzLnJlcXVlc3RBdXRvc2NhbGVFdmFsdWF0aW9uKCksXG4gICAgICB0aGlzLnBvb2xDb25maWcuc2NhbGVJbnRlcnZhbE1zLFxuICAgICk7XG4gICAgdGhpcy5zY2FsZXJUaW1lci51bnJlZj8uKCk7XG4gIH1cblxuICBhc3luYyBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuc3RvcHBlZCA9IHRydWU7XG4gICAgaWYgKHRoaXMuc2NhbGVyVGltZXIpIHtcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5zY2FsZXJUaW1lcik7XG4gICAgICB0aGlzLnNjYWxlclRpbWVyID0gbnVsbDtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5zY2FsaW5nUHJvbWlzZT8uY2F0Y2goKCkgPT4ge30pO1xuICAgIHRoaXMucmVqZWN0QWxsUXVldWVkKFwiRElTUEFUQ0hFUl9TSFVURE9XTlwiKTtcbiAgICBjb25zdCBraWxscyA9IFsuLi50aGlzLndvcmtlclBvb2wudmFsdWVzKCldLmZsYXQoKS5tYXAoKHcpID0+IHcua2lsbCgpKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoa2lsbHMpO1xuICAgIGZvciAoY29uc3QgaWQgb2YgdGhpcy50b2tlbk1ldGFkYXRhLmtleXMoKSkgdGhpcy53ZWlnaHRlZFNlbGVjdG9yLnJlbW92ZVRva2VuKGlkKTtcbiAgICB0aGlzLndvcmtlclBvb2wuY2xlYXIoKTtcbiAgICB0aGlzLnRva2VuTWV0YWRhdGEuY2xlYXIoKTtcbiAgICB0aGlzLndvcmtlckN1cnNvckJ5VG9rZW4uY2xlYXIoKTtcbiAgICB0aGlzLndlaWdodGVkU2VsZWN0b3IucmVzZXRTY29yZXMoKTtcbiAgICB0aGlzLnJhdGVMaW1pdHNDYWNoZS5jbGVhcigpO1xuICAgIHRoaXMucmF0ZUxpbWl0c0dlbmVyYXRpb25CeVRva2VuLmNsZWFyKCk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWRUb2tlbklkcy5jbGVhcigpO1xuICAgIHRoaXMuc3RhcnRpbmdUb2tlbklkcy5jbGVhcigpO1xuICB9XG5cbiAgLy8g4pSA4pSAIFRva2VuIGV2ZW50cyAoZnJvbSBUb2tlblN1YnNjcmliZXIpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGFzeW5jIG9uVG9rZW5BZGRlZChcbiAgICBpZDogbnVtYmVyLFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsLFxuICAgIHdlaWdodCA9IDEsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMucXVvdGFCbG9ja2VkVG9rZW5JZHMuZGVsZXRlKGlkKTtcbiAgICB0aGlzLmludmFsaWRhdGVSYXRlTGltaXRzQ2FjaGUoaWQpO1xuICAgIHRoaXMuc2V0VG9rZW5NZXRhZGF0YShpZCwgbmFtZSwgY3JlZGVudGlhbHMsIHF1b3RhVGhyZXNob2xkLCB3ZWlnaHQpO1xuICAgIGlmICh0aGlzLndvcmtlclBvb2wuaGFzKGlkKSkgcmV0dXJuO1xuICAgIGF3YWl0IHRoaXMuc3Bhd25Xb3JrZXJzKGlkLCBuYW1lLCBjcmVkZW50aWFscywgcXVvdGFUaHJlc2hvbGQsIHdlaWdodCk7XG4gIH1cblxuICBhc3luYyBvblRva2VuUmVtb3ZlZChpZDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgd29ya2VycyA9IHRoaXMud29ya2VyUG9vbC5nZXQoaWQpID8/IFtdO1xuICAgIGNvbnN0IHRva2VuTmFtZSA9IHdvcmtlcnNbMF0/LnRva2VuTmFtZTtcbiAgICB0aGlzLndvcmtlclBvb2wuZGVsZXRlKGlkKTtcbiAgICB0aGlzLnRva2VuTWV0YWRhdGEuZGVsZXRlKGlkKTtcbiAgICB0aGlzLndlaWdodGVkU2VsZWN0b3IucmVtb3ZlVG9rZW4oaWQpO1xuICAgIHRoaXMud29ya2VyQ3Vyc29yQnlUb2tlbi5kZWxldGUoaWQpO1xuICAgIHRoaXMuaW52YWxpZGF0ZVJhdGVMaW1pdHNDYWNoZShpZCk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWRUb2tlbklkcy5kZWxldGUoaWQpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZCh3b3JrZXJzLm1hcCgodykgPT4gdy5raWxsKCkpKTtcbiAgICBpZiAoIXRoaXMuaGFzQWN0aXZlVG9rZW5DYW5kaWRhdGUobmV3IFNldCgpKSkge1xuICAgICAgdGhpcy5yZWplY3RBbGxRdWV1ZWQoXCJOT19PUEVOQUlfV09SS0VSU1wiKTtcbiAgICB9XG4gICAgaWYgKHdvcmtlcnMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgbGFiZWwgPSB0b2tlbk5hbWUgPz8gYHRva2VuICR7aWR9YDtcbiAgICAgIGxvZ2dlci5pbmZvKGB3b3JrZXJzIHJlbW92ZWQ6ICR7bGFiZWx9ICgke3dvcmtlcnMubGVuZ3RofSlgKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBvblRva2VuVXBkYXRlZChcbiAgICBpZDogbnVtYmVyLFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsLFxuICAgIHdlaWdodCA9IDEsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy53b3JrZXJQb29sLmdldChpZCkgPz8gW107XG4gICAgY29uc3QgdGhyZXNob2xkQ2hhbmdlZCA9IHRoaXMuZ2V0UXVvdGFUaHJlc2hvbGQoaWQpICE9PSBxdW90YVRocmVzaG9sZDtcbiAgICBpZiAodGhyZXNob2xkQ2hhbmdlZCkgdGhpcy5xdW90YUJsb2NrZWRUb2tlbklkcy5kZWxldGUoaWQpO1xuICAgIHRoaXMuc2V0VG9rZW5NZXRhZGF0YShpZCwgbmFtZSwgY3JlZGVudGlhbHMsIHF1b3RhVGhyZXNob2xkLCB3ZWlnaHQpO1xuXG4gICAgaWYgKGV4aXN0aW5nLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5pbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKGlkKTtcbiAgICAgIGF3YWl0IHRoaXMuc3Bhd25Xb3JrZXJzKGlkLCBuYW1lLCBjcmVkZW50aWFscywgcXVvdGFUaHJlc2hvbGQsIHdlaWdodCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGV4aXN0aW5nLmV2ZXJ5KCh3KSA9PiB3LmNhblJldXNlRm9yVG9rZW4obmFtZSwgY3JlZGVudGlhbHMpKSkge1xuICAgICAgZXhpc3RpbmcuZm9yRWFjaCgodykgPT4gdy51cGRhdGVUb2tlblN0YXRlKG5hbWUsIGNyZWRlbnRpYWxzKSk7XG4gICAgICBsb2dnZXIuaW5mbyhgd29ya2VycyB1cGRhdGVkIGluLXBsYWNlOiAke25hbWV9YCk7XG4gICAgICB0aGlzLnJlcXVlc3REcmFpblF1ZXVlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy53b3JrZXJQb29sLmRlbGV0ZShpZCk7XG4gICAgdGhpcy5pbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKGlkKTtcbiAgICB0aGlzLnF1b3RhQmxvY2tlZFRva2VuSWRzLmRlbGV0ZShpZCk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKGV4aXN0aW5nLm1hcCgodykgPT4gdy5raWxsKCkpKTtcbiAgICBhd2FpdCB0aGlzLnNwYXduV29ya2VycyhpZCwgbmFtZSwgY3JlZGVudGlhbHMsIHF1b3RhVGhyZXNob2xkLCB3ZWlnaHQpO1xuICB9XG5cbiAgb25Ub2tlbkRlYWN0aXZhdGVkKGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCB3b3JrZXJzID0gdGhpcy53b3JrZXJQb29sLmdldChpZCkgPz8gW107XG4gICAgY29uc3QgdG9rZW5OYW1lID0gd29ya2Vyc1swXT8udG9rZW5OYW1lO1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldChpZCk7XG4gICAgaWYgKG1ldGFkYXRhPy5hY3RpdmUpIHRoaXMudG9rZW5NZXRhZGF0YS5zZXQoaWQsIHsgLi4ubWV0YWRhdGEsIGFjdGl2ZTogZmFsc2UgfSk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWRUb2tlbklkcy5kZWxldGUoaWQpO1xuICAgIGNvbnN0IGNoYW5nZWQgPSB3b3JrZXJzLnNvbWUoKHdvcmtlcikgPT4gd29ya2VyLmFjdGl2ZSk7XG4gICAgd29ya2Vycy5mb3JFYWNoKCh3KSA9PiB7XG4gICAgICB3LmFjdGl2ZSA9IGZhbHNlO1xuICAgIH0pO1xuICAgIGlmIChjaGFuZ2VkKSB0aGlzLndlaWdodGVkU2VsZWN0b3IucmVzZXRTY29yZXMoKTtcbiAgICBpZiAoIXRoaXMuaGFzQWN0aXZlVG9rZW5DYW5kaWRhdGUobmV3IFNldCgpKSkge1xuICAgICAgdGhpcy5yZWplY3RBbGxRdWV1ZWQoXCJOT19BQ1RJVkVfV09SS0VSU1wiKTtcbiAgICB9XG4gICAgY29uc3QgbGFiZWwgPSB0b2tlbk5hbWUgPz8gYHRva2VuICR7aWR9YDtcbiAgICBsb2dnZXIuaW5mbyhgd29ya2VycyBkZWFjdGl2YXRlZDogJHtsYWJlbH1gKTtcbiAgfVxuXG4gIG9uVG9rZW5BY3RpdmF0ZWQoaWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHdvcmtlcnMgPSB0aGlzLndvcmtlclBvb2wuZ2V0KGlkKSA/PyBbXTtcbiAgICBjb25zdCB0b2tlbk5hbWUgPSB3b3JrZXJzWzBdPy50b2tlbk5hbWU7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICBpZiAobWV0YWRhdGEgJiYgIW1ldGFkYXRhLmFjdGl2ZSkgdGhpcy50b2tlbk1ldGFkYXRhLnNldChpZCwgeyAuLi5tZXRhZGF0YSwgYWN0aXZlOiB0cnVlIH0pO1xuICAgIGNvbnN0IGNoYW5nZWQgPSB3b3JrZXJzLnNvbWUoKHdvcmtlcikgPT4gIXdvcmtlci5hY3RpdmUpO1xuICAgIHdvcmtlcnMuZm9yRWFjaCgodykgPT4ge1xuICAgICAgdy5hY3RpdmUgPSB0cnVlO1xuICAgIH0pO1xuICAgIGlmIChjaGFuZ2VkKSB0aGlzLndlaWdodGVkU2VsZWN0b3IucmVzZXRTY29yZXMoKTtcbiAgICB0aGlzLnJlcXVlc3REcmFpblF1ZXVlKCk7XG4gICAgY29uc3QgbGFiZWwgPSB0b2tlbk5hbWUgPz8gYHRva2VuICR7aWR9YDtcbiAgICBsb2dnZXIuaW5mbyhgd29ya2VycyBhY3RpdmF0ZWQ6ICR7bGFiZWx9YCk7XG4gIH1cblxuICBhc3luYyByZXBsYWNlVG9rZW5zKFxuICAgIHJvd3M6IEFycmF5PHtcbiAgICAgIGlkOiBudW1iZXI7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHM7XG4gICAgICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGw7XG4gICAgICB3ZWlnaHQ6IG51bWJlcjtcbiAgICB9PixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbmV4dCA9IG5ldyBTZXQocm93cy5tYXAoKHIpID0+IHIuaWQpKTtcbiAgICBmb3IgKGNvbnN0IGlkIG9mIEFycmF5LmZyb20odGhpcy53b3JrZXJQb29sLmtleXMoKSkpIHtcbiAgICAgIGlmICghbmV4dC5oYXMoaWQpKSBhd2FpdCB0aGlzLm9uVG9rZW5SZW1vdmVkKGlkKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XG4gICAgICBpZiAodGhpcy53b3JrZXJQb29sLmhhcyhyb3cuaWQpKSB7XG4gICAgICAgIGF3YWl0IHRoaXMub25Ub2tlblVwZGF0ZWQoXG4gICAgICAgICAgcm93LmlkLFxuICAgICAgICAgIHJvdy5uYW1lLFxuICAgICAgICAgIHJvdy5jcmVkZW50aWFscyxcbiAgICAgICAgICByb3cucXVvdGFUaHJlc2hvbGQsXG4gICAgICAgICAgcm93LndlaWdodCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IHRoaXMub25Ub2tlbkFkZGVkKHJvdy5pZCwgcm93Lm5hbWUsIHJvdy5jcmVkZW50aWFscywgcm93LnF1b3RhVGhyZXNob2xkLCByb3cud2VpZ2h0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMub25Ub2tlbkFjdGl2YXRlZChyb3cuaWQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIOKUgOKUgCBHZW5lcmF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBhc3luYyBnZW5lcmF0ZShyZXE6IEdlbmVyYXRlUmVxdWVzdCk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICB0aGlzLmxhc3RSZXF1ZXN0QXQgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IGV4Y2x1ZGVkVG9rZW5JZHMgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgICAvLyB0aHJlYWQg7J6s7IKs7JqpIOqyveuhnDog7KKM7ZGcIHdvcmtlciDrpbwg7KCQ7Jyg7ZW0IOq4sOyhtCB0aHJlYWQg7JeQIHR1cm4g66eMIOyLpO2WiS5cbiAgICBjb25zdCByZXVzZVdvcmtlciA9IGF3YWl0IHRoaXMuYWNxdWlyZVJldXNlV29ya2VyKHJlcSwgZXhjbHVkZWRUb2tlbklkcyk7XG4gICAgaWYgKHJldXNlV29ya2VyKSB7XG4gICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgYOKGuyAke3JldXNlV29ya2VyLnRva2VuTmFtZX1bJHtyZXVzZVdvcmtlci50b2tlbklkfV0gKHJldXNlIHRocmVhZCwgJHtyZXEubW9kZWx9KWAsXG4gICAgICApO1xuICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZUFuZFJlbGVhc2UocmV1c2VXb3JrZXIsICh3KSA9PlxuICAgICAgICB0aGlzLmV4ZWN1dGVUdXJuKHcsIHJlcSwgcmVxLnJldXNlIS50aHJlYWRJZCksXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHdvcmtlciA9IGF3YWl0IHRoaXMuYWNxdWlyZUlkbGVXb3JrZXIoZXhjbHVkZWRUb2tlbklkcyk7XG4gICAgaWYgKHdvcmtlcikge1xuICAgICAgbG9nZ2VyLmluZm8oYOKGkiAke3dvcmtlci50b2tlbk5hbWV9WyR7d29ya2VyLnRva2VuSWR9XSAobW9kZWw6ICR7cmVxLm1vZGVsfSlgKTtcbiAgICAgIHJldHVybiB0aGlzLmV4ZWN1dGVBbmRSZWxlYXNlKHdvcmtlciwgKHcpID0+IHRoaXMuZXhlY3V0ZVR1cm4odywgcmVxKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmVucXVldWUoKHcpID0+IHtcbiAgICAgIGxvZ2dlci5pbmZvKGDihpIgJHt3LnRva2VuTmFtZX1bJHt3LnRva2VuSWR9XSAobW9kZWw6ICR7cmVxLm1vZGVsfSwgcXVldWVkKWApO1xuICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZVR1cm4odywgcmVxKTtcbiAgICB9LCBleGNsdWRlZFRva2VuSWRzKTtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlU3RyZWFtKHJlcTogR2VuZXJhdGVSZXF1ZXN0LCBjYjogR2VuZXJhdGVTdHJlYW1DYWxsYmFja3MpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmxhc3RSZXF1ZXN0QXQgPSBEYXRlLm5vdygpO1xuICAgIC8vIOydtOuvuOyngCDsg53shLHsnYAgbm9uLXN0cmVhbSDsoITsmqkoUjIpOiBjb2RleCDqsIAg7J2066+47KeAIOuNuO2DgOulvCDso7zsp4Ag7JWK6rOgIOyZhOyEsSBiYXNlNjQg66W8XG4gICAgLy8g7ZWcIOuyiOyXkCDspIDri6QuIOyKpO2KuOumrOuwjSDqsr3roZzroZwg7J2066+47KeAIOyalOyyreydtCDsmKTrqbQg66qF7Iuc7KCBIOyXkOufrC5cbiAgICBpZiAocmVxLmltYWdlR2VuZXJhdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFxuICAgICAgICBcImdhdGVcIixcbiAgICAgICAgXCJpbWFnZSBnZW5lcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgb24gdGhlIHN0cmVhbWluZyBwYXRoXCIsXG4gICAgICApO1xuICAgIH1cbiAgICBjb25zdCBleGNsdWRlZFRva2VuSWRzID0gbmV3IFNldDxudW1iZXI+KCk7XG4gICAgY29uc3QgcmV1c2VXb3JrZXIgPSBhd2FpdCB0aGlzLmFjcXVpcmVSZXVzZVdvcmtlcihyZXEsIGV4Y2x1ZGVkVG9rZW5JZHMpO1xuICAgIGlmIChyZXVzZVdvcmtlcikge1xuICAgICAgbG9nZ2VyLmluZm8oYOKGuyAke3JldXNlV29ya2VyLnRva2VuTmFtZX1bJHtyZXVzZVdvcmtlci50b2tlbklkfV0gKHJldXNlIHRocmVhZCwgW3N0cmVhbV0pYCk7XG4gICAgICByZXR1cm4gdGhpcy5leGVjdXRlQW5kUmVsZWFzZShyZXVzZVdvcmtlciwgKHcpID0+XG4gICAgICAgIHRoaXMuZXhlY3V0ZVN0cmVhbVR1cm4odywgcmVxLCBjYiwgcmVxLnJldXNlIS50aHJlYWRJZCksXG4gICAgICApO1xuICAgIH1cblxuICAgIGNvbnN0IHdvcmtlciA9IGF3YWl0IHRoaXMuYWNxdWlyZUlkbGVXb3JrZXIoZXhjbHVkZWRUb2tlbklkcyk7XG4gICAgaWYgKHdvcmtlcikge1xuICAgICAgbG9nZ2VyLmluZm8oYOKGkiAke3dvcmtlci50b2tlbk5hbWV9WyR7d29ya2VyLnRva2VuSWR9XSAobW9kZWw6ICR7cmVxLm1vZGVsfSwgW3N0cmVhbV0pYCk7XG4gICAgICByZXR1cm4gdGhpcy5leGVjdXRlQW5kUmVsZWFzZSh3b3JrZXIsICh3KSA9PiB0aGlzLmV4ZWN1dGVTdHJlYW1UdXJuKHcsIHJlcSwgY2IpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuZW5xdWV1ZSgodykgPT4ge1xuICAgICAgbG9nZ2VyLmluZm8oYOKGkiAke3cudG9rZW5OYW1lfVske3cudG9rZW5JZH1dIChtb2RlbDogJHtyZXEubW9kZWx9LCBbc3RyZWFtXSwgcXVldWVkKWApO1xuICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZVN0cmVhbVR1cm4odywgcmVxLCBjYik7XG4gICAgfSwgZXhjbHVkZWRUb2tlbklkcyk7XG4gIH1cblxuICAvLyByZXVzZSDsooztkZzqsIAg7Jyg7Zqo7ZWY66m0IOq3uCB3b3JrZXIg66W8IGJ1c3kg7KCQ7Jyg7ZW0IOuwmO2ZmC4g7JeG6rGw64KYIO2PtOuwsSDrjIDsg4HsnbTrqbQgbnVsbC5cbiAgLy8g7Y+067CxIOyCrOycoDog6riw64qlIG9mZiAvIOyijO2RnCDsl4bsnYwgLyB3b3JrZXIg67aA7J6swrfso73snYwgLyBlcG9jaCDrtojsnbzsuZgocmVzdGFydCkgLyB0aHJlYWQg7IaM66m4IC9cbiAgLy8gICAgICAgICAgICBidXN5IOuMgOq4sCDtg4DsnoTslYTsm4MuIG51bGwg67CY7ZmYIOyLnCDtmLjstpzrtoDripQg7IOIIHRocmVhZCDqsr3roZzroZwg7KeE7ZaJLlxuICBhc3luYyBhY3F1aXJlUmV1c2VXb3JrZXIoXG4gICAgcmVxOiBHZW5lcmF0ZVJlcXVlc3QsXG4gICAgZXhjbHVkZWRUb2tlbklkcyA9IG5ldyBTZXQ8bnVtYmVyPigpLFxuICApOiBQcm9taXNlPENvZGV4QXBwU2VydmVyV29ya2VyIHwgbnVsbD4ge1xuICAgIC8vIOydtOuvuOyngCDsmpTssq3snYAg7ZWt7IOBIGNvbGQgdGhyZWFkKFI4KTog7J6s7IKs7JqpIOyijO2RnOqwgCDsnojslrTrj4Qg6rG064SI65u064ukLlxuICAgIC8vIGJhc2U2NCDqsIAgdGhyZWFkIOuplOuqqOumrMK37LqQ7IucIHByZWZpeCDsl5Ag7IOB7KO87ZWY64qUIOqyg+ydhCDrp4nripTri6QuXG4gICAgaWYgKHJlcS5pbWFnZUdlbmVyYXRpb24pIHJldHVybiBudWxsO1xuICAgIGlmICghVEhSRUFEX1JFVVNFX0VOQUJMRUQgfHwgIXJlcS5yZXVzZSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgeyB3b3JrZXJJZCwgdGhyZWFkSWQsIGVwb2NoIH0gPSByZXEucmV1c2U7XG5cbiAgICBjb25zdCB3b3JrZXIgPSB0aGlzLmZpbmRXb3JrZXJCeUlkKHdvcmtlcklkKTtcbiAgICBpZiAoIXdvcmtlciB8fCAhd29ya2VyLmlzUmVhZHkgfHwgIXdvcmtlci5hY3RpdmUpIHJldHVybiBudWxsO1xuICAgIGlmICh3b3JrZXIuZXBvY2ggIT09IGVwb2NoKSByZXR1cm4gbnVsbDtcbiAgICBpZiAoIXdvcmtlci5oYXNUaHJlYWQodGhyZWFkSWQpKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBxdW90YU1ldGFkYXRhID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldCh3b3JrZXIudG9rZW5JZCk7XG4gICAgaWYgKCEoYXdhaXQgdGhpcy5pc1Rva2VuUXVvdGFFbGlnaWJsZSh3b3JrZXIudG9rZW5JZCwgd29ya2VyLnRva2VuTmFtZSwgZXhjbHVkZWRUb2tlbklkcykpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgIXdvcmtlci5pc1JlYWR5IHx8XG4gICAgICAhd29ya2VyLmFjdGl2ZSB8fFxuICAgICAgdGhpcy50b2tlbk1ldGFkYXRhLmdldCh3b3JrZXIudG9rZW5JZCkgIT09IHF1b3RhTWV0YWRhdGEgfHxcbiAgICAgIHRoaXMucXVvdGFCbG9ja2VkVG9rZW5JZHMuaGFzKHdvcmtlci50b2tlbklkKVxuICAgICkge1xuICAgICAgaWYgKHRoaXMucXVvdGFCbG9ja2VkVG9rZW5JZHMuaGFzKHdvcmtlci50b2tlbklkKSkge1xuICAgICAgICBleGNsdWRlZFRva2VuSWRzLmFkZCh3b3JrZXIudG9rZW5JZCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBkZWFkbGluZSA9IERhdGUubm93KCkgKyBSRVVTRV9XT1JLRVJfV0FJVF9NUztcbiAgICBmb3IgKDs7KSB7XG4gICAgICAvLyByZXN0YXJ0KGVwb2NoIOuzgOqyvSkgLyB0aHJlYWQg7IaM66m47J20IOuMgOq4sCDspJHsl5Ag67Cc7IOd7ZWY66m0IO2PtOuwsS5cbiAgICAgIGlmIChcbiAgICAgICAgIXdvcmtlci5pc1JlYWR5IHx8XG4gICAgICAgICF3b3JrZXIuYWN0aXZlIHx8XG4gICAgICAgIHdvcmtlci5lcG9jaCAhPT0gZXBvY2ggfHxcbiAgICAgICAgIXdvcmtlci5oYXNUaHJlYWQodGhyZWFkSWQpIHx8XG4gICAgICAgIHRoaXMudG9rZW5NZXRhZGF0YS5nZXQod29ya2VyLnRva2VuSWQpICE9PSBxdW90YU1ldGFkYXRhIHx8XG4gICAgICAgIHRoaXMucXVvdGFCbG9ja2VkVG9rZW5JZHMuaGFzKHdvcmtlci50b2tlbklkKVxuICAgICAgKSB7XG4gICAgICAgIGlmICh0aGlzLnF1b3RhQmxvY2tlZFRva2VuSWRzLmhhcyh3b3JrZXIudG9rZW5JZCkpIHtcbiAgICAgICAgICBleGNsdWRlZFRva2VuSWRzLmFkZCh3b3JrZXIudG9rZW5JZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICBpZiAod29ya2VyLnRyeUFjcXVpcmVUdXJuKCkpIHJldHVybiB3b3JrZXI7XG4gICAgICBpZiAoRGF0ZS5ub3coKSA+PSBkZWFkbGluZSkgcmV0dXJuIG51bGw7XG4gICAgICBhd2FpdCBzbGVlcChSRVVTRV9XT1JLRVJfUE9MTF9NUyk7XG4gICAgfVxuICB9XG5cbiAgZmluZFdvcmtlckJ5SWQod29ya2VySWQ6IG51bWJlcik6IENvZGV4QXBwU2VydmVyV29ya2VyIHwgbnVsbCB7XG4gICAgZm9yIChjb25zdCB3b3JrZXJzIG9mIHRoaXMud29ya2VyUG9vbC52YWx1ZXMoKSkge1xuICAgICAgZm9yIChjb25zdCB3IG9mIHdvcmtlcnMpIHtcbiAgICAgICAgaWYgKG1ha2VPcGVuQUlXb3JrZXJJZCh3LnRva2VuSWQsIHcud29ya2VySW5kZXgpID09PSB3b3JrZXJJZCkgcmV0dXJuIHc7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgYXN5bmMgaW50ZXJydXB0V29ya2VyVHVybih0aHJlYWRJZDogc3RyaW5nLCB0dXJuSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGFsbFdvcmtlcnMgPSBbLi4udGhpcy53b3JrZXJQb29sLnZhbHVlcygpXS5mbGF0KCkuZmlsdGVyKCh3KSA9PiB3LmlzUmVhZHkpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChhbGxXb3JrZXJzLm1hcCgodykgPT4gdy5pbnRlcnJ1cHRUdXJuKHRocmVhZElkLCB0dXJuSWQpKSk7XG4gIH1cblxuICAvLyDilIDilIAgV29ya2VyIHNlbGVjdGlvbiDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgLy8gUXVvdGEtZWxpZ2libGUgaWRsZSB0b2tlbuydhCB3ZWlnaHTroZwg6rOg66W4IOuSpCwg6re4IHRva2VuIOyViOyXkOyEnCB3b3JrZXLrpbwg7Iic7ZmY7ZWc64ukLlxuICBhc3luYyBhY3F1aXJlSWRsZVdvcmtlcihcbiAgICBleGNsdWRlZFRva2VuSWRzID0gbmV3IFNldDxudW1iZXI+KCksXG4gICk6IFByb21pc2U8Q29kZXhBcHBTZXJ2ZXJXb3JrZXIgfCBudWxsPiB7XG4gICAgY29uc3QgZWxpZ2liaWxpdHkgPSBhd2FpdCB0aGlzLnJlc29sdmVUb2tlbkVsaWdpYmlsaXR5KGV4Y2x1ZGVkVG9rZW5JZHMpO1xuICAgIGlmIChlbGlnaWJpbGl0eS5yZWFkeUFjdGl2ZVRva2VuSWRzLnNpemUgPT09IDApIHJldHVybiBudWxsO1xuICAgIGlmIChlbGlnaWJpbGl0eS5lbGlnaWJsZVRva2VuSWRzLnNpemUgPT09IDApIHRoaXMudGhyb3dRdW90YVRocmVzaG9sZEV4Y2VlZGVkKGVsaWdpYmlsaXR5KTtcblxuICAgIGNvbnN0IHdvcmtlcnNCeVRva2VuID0gbmV3IE1hcDxudW1iZXIsIENvZGV4QXBwU2VydmVyV29ya2VyW10+KCk7XG4gICAgZm9yIChjb25zdCB3b3JrZXIgb2YgdGhpcy5nZXRBbGxSZWFkeUFjdGl2ZVdvcmtlcnMoKSkge1xuICAgICAgaWYgKCFlbGlnaWJpbGl0eS5lbGlnaWJsZVRva2VuSWRzLmhhcyh3b3JrZXIudG9rZW5JZCkgfHwgIXdvcmtlci5oYXNDYXBhY2l0eSkgY29udGludWU7XG4gICAgICBjb25zdCB3b3JrZXJzID0gd29ya2Vyc0J5VG9rZW4uZ2V0KHdvcmtlci50b2tlbklkKSA/PyBbXTtcbiAgICAgIHdvcmtlcnMucHVzaCh3b3JrZXIpO1xuICAgICAgd29ya2Vyc0J5VG9rZW4uc2V0KHdvcmtlci50b2tlbklkLCB3b3JrZXJzKTtcbiAgICB9XG5cbiAgICBjb25zdCBzZWxlY3RlZFRva2VuSWQgPSB0aGlzLndlaWdodGVkU2VsZWN0b3Iuc2VsZWN0KG5ldyBTZXQod29ya2Vyc0J5VG9rZW4ua2V5cygpKSk7XG4gICAgaWYgKHNlbGVjdGVkVG9rZW5JZCA9PT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3Qgd29ya2VycyA9IHdvcmtlcnNCeVRva2VuLmdldChzZWxlY3RlZFRva2VuSWQpITtcbiAgICBjb25zdCBjdXJzb3IgPSB0aGlzLndvcmtlckN1cnNvckJ5VG9rZW4uZ2V0KHNlbGVjdGVkVG9rZW5JZCkgPz8gMDtcbiAgICBmb3IgKGxldCBvZmZzZXQgPSAwOyBvZmZzZXQgPCB3b3JrZXJzLmxlbmd0aDsgb2Zmc2V0KyspIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gKGN1cnNvciArIG9mZnNldCkgJSB3b3JrZXJzLmxlbmd0aDtcbiAgICAgIGNvbnN0IHdvcmtlciA9IHdvcmtlcnNbaW5kZXhdITtcbiAgICAgIGlmICh3b3JrZXIudHJ5QWNxdWlyZVR1cm4oKSkge1xuICAgICAgICB0aGlzLndvcmtlckN1cnNvckJ5VG9rZW4uc2V0KHNlbGVjdGVkVG9rZW5JZCwgKGluZGV4ICsgMSkgJSB3b3JrZXJzLmxlbmd0aCk7XG4gICAgICAgIHJldHVybiB3b3JrZXI7XG4gICAgICB9XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGB3ZWlnaHRlZCB0b2tlbiAke3NlbGVjdGVkVG9rZW5JZH0gbG9zdCBpZGxlIGNhcGFjaXR5IGR1cmluZyBzeW5jaHJvbm91cyBhY3F1aXJlYCxcbiAgICApO1xuICB9XG5cbiAgZ2V0QWxsUmVhZHlBY3RpdmVXb3JrZXJzKCk6IENvZGV4QXBwU2VydmVyV29ya2VyW10ge1xuICAgIHJldHVybiBbLi4udGhpcy53b3JrZXJQb29sLnZhbHVlcygpXS5mbGF0KCkuZmlsdGVyKCh3KSA9PiB3LmlzUmVhZHkgJiYgdy5hY3RpdmUpO1xuICB9XG5cbiAgLy8g4pSA4pSAIFF1ZXVlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGFzeW5jIGVucXVldWU8VD4oXG4gICAgZXhlY3V0ZTogKHdvcmtlcjogQ29kZXhBcHBTZXJ2ZXJXb3JrZXIpID0+IFByb21pc2U8VD4sXG4gICAgZXhjbHVkZWRUb2tlbklkcyA9IG5ldyBTZXQ8bnVtYmVyPigpLFxuICApOiBQcm9taXNlPFQ+IHtcbiAgICBjb25zdCBlbGlnaWJpbGl0eSA9IGF3YWl0IHRoaXMucmVzb2x2ZVRva2VuRWxpZ2liaWxpdHkoZXhjbHVkZWRUb2tlbklkcyk7XG4gICAgaWYgKFxuICAgICAgZWxpZ2liaWxpdHkucmVhZHlBY3RpdmVUb2tlbklkcy5zaXplID09PSAwICYmXG4gICAgICAhdGhpcy5oYXNBY3RpdmVUb2tlbkNhbmRpZGF0ZShleGNsdWRlZFRva2VuSWRzKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTk9fT1BFTkFJX1dPUktFUlNcIik7XG4gICAgfVxuICAgIGlmIChlbGlnaWJpbGl0eS5yZWFkeUFjdGl2ZVRva2VuSWRzLnNpemUgPiAwICYmIGVsaWdpYmlsaXR5LmVsaWdpYmxlVG9rZW5JZHMuc2l6ZSA9PT0gMCkge1xuICAgICAgdGhpcy50aHJvd1F1b3RhVGhyZXNob2xkRXhjZWVkZWQoZWxpZ2liaWxpdHkpO1xuICAgIH1cbiAgICBpZiAodGhpcy5xdWV1ZS5sZW5ndGggPj0gTUFYX1FVRVVFX1NJWkUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlNFUlZFUl9CVVNZXCIpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxUPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBpdGVtOiBRdWV1ZUl0ZW0gPSB7XG4gICAgICAgIHJlc29sdmU6ICh3b3JrZXIpID0+IHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQoaXRlbS50aW1lcik7XG4gICAgICAgICAgaXRlbS5hYm9ydENsZWFudXA/LigpO1xuICAgICAgICAgIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAgICAgICAudGhlbigoKSA9PiB0aGlzLmV4ZWN1dGVBbmRSZWxlYXNlKHdvcmtlciwgZXhlY3V0ZSkpXG4gICAgICAgICAgICAudGhlbihyZXNvbHZlLCByZWplY3QpO1xuICAgICAgICB9LFxuICAgICAgICByZWplY3Q6IChlcnIpID0+IHtcbiAgICAgICAgICBjbGVhclRpbWVvdXQoaXRlbS50aW1lcik7XG4gICAgICAgICAgaXRlbS5hYm9ydENsZWFudXA/LigpO1xuICAgICAgICAgIHJlamVjdChlcnIpO1xuICAgICAgICB9LFxuICAgICAgICB0aW1lcjogc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5yZW1vdmVGcm9tUXVldWUoaXRlbSk7XG4gICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIlNFUlZFUl9CVVNZXCIpKTtcbiAgICAgICAgfSwgUVVFVUVfVElNRU9VVF9NUyksXG4gICAgICAgIGV4Y2x1ZGVkVG9rZW5JZHM6IG5ldyBTZXQoZXhjbHVkZWRUb2tlbklkcyksXG4gICAgICB9O1xuXG4gICAgICB0aGlzLnF1ZXVlLnB1c2goaXRlbSk7XG4gICAgICAvLyBlbGlnaWJpbGl0eSDtmZXsnbjqs7wgcXVldWUg7IK97J6FIOyCrOydtOyXkCB3b3JrZXLqsIAgcmVhZHkvaWRsZeydtCDrkJwg6rK97Jqw7J2YIGxvc3Qgd2FrZS11cOydhFxuICAgICAgLy8g64ur64qU64ukLiBmaXhlZCBtb2Rl7JeQ7ISc64+EIGlkbGUgd29ya2Vy6rCAIOymieyLnCBxdWV1ZeulvCDqsIDsoLjqsIDslbwg7ZWc64ukLlxuICAgICAgdGhpcy5yZXF1ZXN0RHJhaW5RdWV1ZSgpO1xuICAgICAgdGhpcy5yZXF1ZXN0QXV0b3NjYWxlRXZhbHVhdGlvbigpO1xuICAgIH0pO1xuICB9XG5cbiAgcmVtb3ZlRnJvbVF1ZXVlKGl0ZW06IFF1ZXVlSXRlbSk6IHZvaWQge1xuICAgIGNsZWFyVGltZW91dChpdGVtLnRpbWVyKTtcbiAgICBpdGVtLmFib3J0Q2xlYW51cD8uKCk7XG4gICAgY29uc3QgaWR4ID0gdGhpcy5xdWV1ZS5pbmRleE9mKGl0ZW0pO1xuICAgIGlmIChpZHggIT09IC0xKSB0aGlzLnF1ZXVlLnNwbGljZShpZHgsIDEpO1xuICB9XG5cbiAgcmVqZWN0QWxsUXVldWVkKHJlYXNvbjogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZXJyID0gbmV3IEVycm9yKHJlYXNvbik7XG4gICAgdGhpcy5xdWV1ZS5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQoaXRlbS50aW1lcik7XG4gICAgICBpdGVtLmFib3J0Q2xlYW51cD8uKCk7XG4gICAgICBpdGVtLnJlamVjdChlcnIpO1xuICAgIH0pO1xuICAgIHRoaXMucXVldWUgPSBbXTtcbiAgfVxuXG4gIGFzeW5jIGRyYWluUXVldWUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuZHJhaW5pbmcpIHtcbiAgICAgIHRoaXMuZHJhaW5BZ2FpbiA9IHRydWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5kcmFpbmluZyA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIGRvIHtcbiAgICAgICAgdGhpcy5kcmFpbkFnYWluID0gZmFsc2U7XG4gICAgICAgIGF3YWl0IHRoaXMuZHJhaW5RdWV1ZU9uY2UoKTtcbiAgICAgIH0gd2hpbGUgKHRoaXMuZHJhaW5BZ2Fpbik7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgbG9nZ2VyLndhcm4oYGRyYWluUXVldWUgZmFpbGVkOiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWApO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmRyYWluaW5nID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBkcmFpblF1ZXVlT25jZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB3aGlsZSAodGhpcy5xdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBuZXh0ID0gdGhpcy5xdWV1ZVswXSE7XG4gICAgICBsZXQgd29ya2VyOiBDb2RleEFwcFNlcnZlcldvcmtlciB8IG51bGw7XG4gICAgICB0cnkge1xuICAgICAgICB3b3JrZXIgPSBhd2FpdCB0aGlzLmFjcXVpcmVJZGxlV29ya2VyKG5leHQuZXhjbHVkZWRUb2tlbklkcyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGlmIChlIGluc3RhbmNlb2YgUXVvdGFUaHJlc2hvbGRFeGNlZWRlZEVycm9yKSB7XG4gICAgICAgICAgdGhpcy5xdWV1ZS5zaGlmdCgpO1xuICAgICAgICAgIG5leHQucmVqZWN0KGUpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgICBpZiAoIXdvcmtlcikgYnJlYWs7XG4gICAgICB0aGlzLnF1ZXVlLnNoaWZ0KCk7XG4gICAgICBuZXh0LnJlc29sdmUod29ya2VyKTtcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIAgRXhlY3V0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGFzeW5jIGV4ZWN1dGVBbmRSZWxlYXNlPFQ+KFxuICAgIHdvcmtlcjogQ29kZXhBcHBTZXJ2ZXJXb3JrZXIsXG4gICAgZXhlY3V0ZTogKHdvcmtlcjogQ29kZXhBcHBTZXJ2ZXJXb3JrZXIpID0+IFByb21pc2U8VD4sXG4gICk6IFByb21pc2U8VD4ge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgZXhlY3V0ZSh3b3JrZXIpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB3b3JrZXIucmVsZWFzZVR1cm4oKTtcbiAgICAgIHRoaXMucmVxdWVzdERyYWluUXVldWUoKTtcbiAgICB9XG4gIH1cblxuICAvLyByZXVzZVRocmVhZElkIOqwgCDsnojsnLzrqbQg6riw7KG0IHRocmVhZCDsl5AgZGVsdGEocmV1c2VJbnB1dCnrp4wsIOyXhuycvOuptCDsg4ggdGhyZWFkIOyXkCDsoITssrRcbiAgLy8gcHJvbXB0KGNvbGRJbnB1dCkgKyBoaXN0b3J5IGluamVjdC4gcmV1c2Ug6rCAIGRpc3BhdGNoZXIg64uo7JeQ7IScIO2PtOuwseuQmOuptCDtm4TsnpDroZwg65ao7Ja07KeE64ukLlxuICBwcml2YXRlIGJ1aWxkVHVyblJlcXVlc3QocmVxOiBHZW5lcmF0ZVJlcXVlc3QsIHJldXNlVGhyZWFkSWQ/OiBzdHJpbmcpOiBUdXJuUmVxdWVzdCB7XG4gICAgY29uc3QgcmV1c2luZyA9IHJldXNlVGhyZWFkSWQgIT09IHVuZGVmaW5lZDtcbiAgICByZXR1cm4ge1xuICAgICAgaW5wdXQ6IHJldXNpbmcgJiYgcmVxLnJldXNlSW5wdXQgPyByZXEucmV1c2VJbnB1dCA6IHJlcS5jb2xkSW5wdXQsXG4gICAgICBoaXN0b3J5OiByZXVzaW5nID8gdW5kZWZpbmVkIDogcmVxLmNvbGRIaXN0b3J5LFxuICAgICAgZGV2ZWxvcGVySW5zdHJ1Y3Rpb25zOiByZXEuc3lzdGVtUHJvbXB0LFxuICAgICAgb3V0cHV0U2NoZW1hOiByZXEub3V0cHV0U2NoZW1hLFxuICAgICAgZWZmb3J0OiByZXEuZWZmb3J0ID8/IERFRkFVTFRfRUZGT1JULFxuICAgICAgbW9kZWw6IHJlcS5tb2RlbCxcbiAgICAgIHZlcmJvc2l0eTogcmVxLnZlcmJvc2l0eSxcbiAgICAgIHJlYXNvbmluZ1N1bW1hcnk6IHJlcS5yZWFzb25pbmdTdW1tYXJ5LFxuICAgICAgc2VydmljZVRpZXI6IHJlcS5zZXJ2aWNlVGllcixcbiAgICAgIGltYWdlR2VuZXJhdGlvbjogcmVxLmltYWdlR2VuZXJhdGlvbixcbiAgICAgIGltYWdlR2VuZXJhdGlvbk9wdGlvbnM6IHJlcS5pbWFnZUdlbmVyYXRpb25PcHRpb25zLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBleGVjdXRlVHVybihcbiAgICB3b3JrZXI6IENvZGV4QXBwU2VydmVyV29ya2VyLFxuICAgIHJlcTogR2VuZXJhdGVSZXF1ZXN0LFxuICAgIHJldXNlVGhyZWFkSWQ/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICAvLyDsnbTrr7jsp4Ag7JqU7LKtIOyCrOyghCDqsozsnbTtirgoUjUpOiDrsLDsoJXrkJwgd29ya2VyIOydmCBjYXBhYmlsaXR5ICsg7KCB7JqpIOuqqOuNuCDrqYDti7Drqqjri6wuXG4gICAgLy8g67aI7Lap7KGx7J2066m0IHR1cm4g7J2EIOyLpO2Wie2VmOyngCDslYrqs6Ag66qF7Iuc7KCBIOyXkOufrC5cbiAgICBpZiAocmVxLmltYWdlR2VuZXJhdGlvbikge1xuICAgICAgY29uc3QgcmVhc29uID0gYXdhaXQgd29ya2VyLmNoZWNrSW1hZ2VHZW5lcmF0aW9uU3VwcG9ydChyZXEubW9kZWwpO1xuICAgICAgaWYgKHJlYXNvbikgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiZ2F0ZVwiLCByZWFzb24pO1xuICAgIH1cblxuICAgIGNvbnN0IHR1cm5SZXEgPSB0aGlzLmJ1aWxkVHVyblJlcXVlc3QocmVxLCByZXVzZVRocmVhZElkKTtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB3b3JrZXIuZXhlY3V0ZVR1cm4odHVyblJlcSwgcmV1c2VUaHJlYWRJZCk7XG5cbiAgICAvLyDsnbTrr7jsp4AgMOqwnCDsi6TtjKgg67aE66WYKFI2KTogdG9vbCDrr7jtmLjstpwo7J6s7Iuc64+EIOustOydtSkgdnMg7Iuc64+EIO2bhCDrr7jsmYTshLEo7J6s7Iuc64+EIO2bhOuztCkuXG4gICAgaWYgKHJlcS5pbWFnZUdlbmVyYXRpb24gJiYgKCFyZXN1bHQuaW1hZ2VzIHx8IHJlc3VsdC5pbWFnZXMubGVuZ3RoID09PSAwKSkge1xuICAgICAgdGhyb3cgcmVzdWx0LmltYWdlQXR0ZW1wdGVkXG4gICAgICAgID8gbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBcImltYWdlIHRvb2wgcmFuIGJ1dCBwcm9kdWNlZCBubyBjb21wbGV0ZWQgaW1hZ2VcIilcbiAgICAgICAgOiBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXCJub3RfY2FsbGVkXCIsIFwibW9kZWwgZGlkIG5vdCBjYWxsIHRoZSBpbWFnZV9nZW5lcmF0aW9uIHRvb2xcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRleHQ6IHJlc3VsdC50ZXh0LFxuICAgICAgdG9rZW5OYW1lOiB3b3JrZXIudG9rZW5OYW1lLFxuICAgICAgdXNhZ2U6IHJlc3VsdC51c2FnZSxcbiAgICAgIGR1cmF0aW9uTXM6IHJlc3VsdC5kdXJhdGlvbk1zLFxuICAgICAgdHRmdE1zOiByZXN1bHQudHRmdE1zLFxuICAgICAgbW9kZWw6IHJlc3VsdC5tb2RlbCxcbiAgICAgIHRocmVhZENvb3JkOiB7XG4gICAgICAgIHdvcmtlcklkOiBtYWtlT3BlbkFJV29ya2VySWQod29ya2VyLnRva2VuSWQsIHdvcmtlci53b3JrZXJJbmRleCksXG4gICAgICAgIHRocmVhZElkOiByZXN1bHQudGhyZWFkSWQsXG4gICAgICAgIGVwb2NoOiB3b3JrZXIuZXBvY2gsXG4gICAgICB9LFxuICAgICAgaW1hZ2VzOiByZXN1bHQuaW1hZ2VzLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBleGVjdXRlU3RyZWFtVHVybihcbiAgICB3b3JrZXI6IENvZGV4QXBwU2VydmVyV29ya2VyLFxuICAgIHJlcTogR2VuZXJhdGVSZXF1ZXN0LFxuICAgIGNiOiBHZW5lcmF0ZVN0cmVhbUNhbGxiYWNrcyxcbiAgICByZXVzZVRocmVhZElkPzogc3RyaW5nLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB0dXJuUmVxID0gdGhpcy5idWlsZFR1cm5SZXF1ZXN0KHJlcSwgcmV1c2VUaHJlYWRJZCk7XG4gICAgLy8gd29ya2VyIOydmCBUdXJuUmVzdWx0IOyXkCB0b2tlbk5hbWUvdGhyZWFkQ29vcmQg66W8IOu2meyXrCDsg4HsnIQoR2VuZXJhdGVSZXN1bHQp66GcIOyYrOumsOuLpC5cbiAgICAvLyB0aHJlYWRJZCDripQg7IOIIHRocmVhZCDrqbQgb25UaHJlYWRJZCDroZwg7ZmV7KCV65CY66+A66GcIOuvuOumrCDrs7TqtIDtlbQg65GQ6rOgIG9uQ29tcGxldGUg65WMIOydveuKlOuLpC5cbiAgICBsZXQgcmVzb2x2ZWRUaHJlYWRJZCA9IHJldXNlVGhyZWFkSWQgPz8gXCJcIjtcbiAgICBjb25zdCB3cmFwcGVkQ2I6IFN0cmVhbUNhbGxiYWNrcyA9IHtcbiAgICAgIC4uLmNiLFxuICAgICAgb25UaHJlYWRJZDogKHRocmVhZElkKSA9PiB7XG4gICAgICAgIHJlc29sdmVkVGhyZWFkSWQgPSB0aHJlYWRJZDtcbiAgICAgICAgY2Iub25UaHJlYWRJZD8uKHRocmVhZElkKTtcbiAgICAgIH0sXG4gICAgICBvbkNvbXBsZXRlOiAocmVzdWx0KSA9PiB7XG4gICAgICAgIGNiLm9uQ29tcGxldGUoe1xuICAgICAgICAgIC4uLnJlc3VsdCxcbiAgICAgICAgICB0b2tlbk5hbWU6IHdvcmtlci50b2tlbk5hbWUsXG4gICAgICAgICAgdGhyZWFkQ29vcmQ6IHtcbiAgICAgICAgICAgIHdvcmtlcklkOiBtYWtlT3BlbkFJV29ya2VySWQod29ya2VyLnRva2VuSWQsIHdvcmtlci53b3JrZXJJbmRleCksXG4gICAgICAgICAgICB0aHJlYWRJZDogcmVzb2x2ZWRUaHJlYWRJZCxcbiAgICAgICAgICAgIGVwb2NoOiB3b3JrZXIuZXBvY2gsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgICB9LFxuICAgIH07XG4gICAgYXdhaXQgd29ya2VyLmV4ZWN1dGVUdXJuU3RyZWFtKHR1cm5SZXEsIHdyYXBwZWRDYiwgcmV1c2VUaHJlYWRJZCk7XG4gIH1cblxuICAvLyDilIDilIAgU3Bhd24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgYXN5bmMgc3Bhd25Xb3JrZXJzKFxuICAgIHRva2VuSWQ6IG51bWJlcixcbiAgICB0b2tlbk5hbWU6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsLFxuICAgIHdlaWdodCA9IDEsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLnN0YXJ0aW5nVG9rZW5JZHMuaGFzKHRva2VuSWQpKSByZXR1cm47XG4gICAgdGhpcy5zdGFydGluZ1Rva2VuSWRzLmFkZCh0b2tlbklkKTtcbiAgICB0aGlzLnNldFRva2VuTWV0YWRhdGEodG9rZW5JZCwgdG9rZW5OYW1lLCBjcmVkZW50aWFscywgcXVvdGFUaHJlc2hvbGQsIHdlaWdodCk7XG4gICAgY29uc3QgZXhwZWN0ZWRNZXRhZGF0YSA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCk7XG4gICAgY29uc3Qgd29ya2VyczogQ29kZXhBcHBTZXJ2ZXJXb3JrZXJbXSA9IFtdO1xuICAgIHRyeSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMucG9vbENvbmZpZy5taW5Xb3JrZXJzUGVyVG9rZW47IGkrKykge1xuICAgICAgICBpZiAoaSA+IDApIGF3YWl0IHNsZWVwKFNQQVdOX0lOVEVSVkFMX01TKTtcbiAgICAgICAgY29uc3Qgd29ya2VyID0gYXdhaXQgdGhpcy5zcGF3blNpbmdsZVdvcmtlcih0b2tlbklkLCB0b2tlbk5hbWUsIGNyZWRlbnRpYWxzLCBpKTtcbiAgICAgICAgaWYgKHdvcmtlcikgd29ya2Vycy5wdXNoKHdvcmtlcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChcbiAgICAgICAgIXRoaXMuc3RvcHBlZCAmJlxuICAgICAgICBleHBlY3RlZE1ldGFkYXRhPy5hY3RpdmUgJiZcbiAgICAgICAgdGhpcy50b2tlbk1ldGFkYXRhLmdldCh0b2tlbklkKSA9PT0gZXhwZWN0ZWRNZXRhZGF0YSAmJlxuICAgICAgICAhdGhpcy53b3JrZXJQb29sLmhhcyh0b2tlbklkKVxuICAgICAgKSB7XG4gICAgICAgIGlmICh3b3JrZXJzLmxlbmd0aCA+IDApIHRoaXMud29ya2VyUG9vbC5zZXQodG9rZW5JZCwgd29ya2Vycyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQod29ya2Vycy5tYXAoKHdvcmtlcikgPT4gd29ya2VyLmtpbGwoKSkpO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnN0YXJ0aW5nVG9rZW5JZHMuZGVsZXRlKHRva2VuSWQpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNwYXduU2luZ2xlV29ya2VyKFxuICAgIHRva2VuSWQ6IG51bWJlcixcbiAgICB0b2tlbk5hbWU6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgd29ya2VySW5kZXg6IG51bWJlcixcbiAgKTogUHJvbWlzZTxDb2RleEFwcFNlcnZlcldvcmtlciB8IG51bGw+IHtcbiAgICBjb25zdCB3b3JrZXIgPSBuZXcgQ29kZXhBcHBTZXJ2ZXJXb3JrZXIoe1xuICAgICAgdG9rZW5JZCxcbiAgICAgIHRva2VuTmFtZSxcbiAgICAgIGFjY2Vzc1Rva2VuOiBjcmVkZW50aWFscy5hY2Nlc3NUb2tlbixcbiAgICAgIGFjY291bnRJZDogY3JlZGVudGlhbHMuYWNjb3VudElkLFxuICAgICAgcGxhblR5cGU6IGNyZWRlbnRpYWxzLnBsYW5UeXBlLFxuICAgICAgd29ya2VySW5kZXgsXG4gICAgfSk7XG5cbiAgICB3b3JrZXIub25SZWFkeSA9ICgpID0+IHRoaXMucmVxdWVzdERyYWluUXVldWUoKTtcbiAgICB3b3JrZXIub25UZXJtaW5hbEZhaWx1cmUgPSAoKSA9PiB7XG4gICAgICB2b2lkIHRoaXMuaGFuZGxlV29ya2VyVGVybWluYWxGYWlsdXJlKHdvcmtlcikuY2F0Y2goKGUpID0+XG4gICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgIGB0ZXJtaW5hbCB3b3JrZXIgY2xlYW51cCBmYWlsZWQ6ICR7dG9rZW5OYW1lfVske3dvcmtlckluZGV4fV06ICR7KGUgYXMgRXJyb3IpLm1lc3NhZ2V9YCxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfTtcblxuICAgIHdvcmtlci5zZXRTZXJ2ZXJSZXF1ZXN0SGFuZGxlcihhc3luYyAobWV0aG9kKSA9PiB7XG4gICAgICBpZiAobWV0aG9kID09PSBcImFjY291bnQvY2hhdGdwdEF1dGhUb2tlbnMvcmVmcmVzaFwiKSB7XG4gICAgICAgIHJldHVybiBoYW5kbGVDaGF0Z3B0QXV0aFRva2Vuc1JlZnJlc2godG9rZW5JZCk7XG4gICAgICB9XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuaGFuZGxlZCBzZXJ2ZXItcmVxdWVzdDogJHttZXRob2R9YCk7XG4gICAgfSk7XG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgd29ya2VyLmluaXRpYWxpemUoKTtcbiAgICAgIGxvZ2dlci5pbmZvKGB3b3JrZXIgc3Bhd25lZDogJHt0b2tlbk5hbWV9WyR7d29ya2VySW5kZXh9XWApO1xuICAgICAgcmV0dXJuIHdvcmtlcjtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBsb2dnZXIud2Fybihgd29ya2VyIHNwYXduIGZhaWxlZDogJHt0b2tlbk5hbWV9WyR7d29ya2VySW5kZXh9XTogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKTtcbiAgICAgIGF3YWl0IHdvcmtlci5raWxsKCkuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgZXZhbHVhdGVBdXRvc2NhbGluZygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5zdG9wcGVkKSByZXR1cm47XG4gICAgdGhpcy5zd2VlcElkbGVXb3JrZXJUaHJlYWRzKCk7XG4gICAgY29uc3QgbWluaW11bURlZmljaXRUb2tlbklkcyA9IGF3YWl0IHRoaXMuZW5zdXJlTWluaW11bVdvcmtlcnNPbmVTdGVwKCk7XG4gICAgaWYgKCF0aGlzLnBvb2xDb25maWcuYXV0b3NjYWxlIHx8IHRoaXMuc3RvcHBlZCkgcmV0dXJuO1xuICAgIGlmICh0aGlzLnF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIGJhc2VsaW5lIOuzteq1rOulvCDsi5zrj4TtlZwgdG9rZW7rp4wg6rCZ7J2AIGV2YWx1YXRpb27snZggZGVtYW5kIGV4cGFuc2lvbuyXkOyEnCDsoJzsmbjtlZzri6QuXG4gICAgICAvLyDri6Trpbgg7KCV7IOBIHRva2Vu7J2YIO2Zleyepeq5jOyngCDrp4nsp4DripQg7JWK64qU64ukLlxuICAgICAgYXdhaXQgdGhpcy5zY2FsZVVwT25lU3RlcChtaW5pbXVtRGVmaWNpdFRva2VuSWRzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKERhdGUubm93KCkgLSB0aGlzLmxhc3RSZXF1ZXN0QXQgPj0gdGhpcy5wb29sQ29uZmlnLnNjYWxlRG93bklkbGVNcykge1xuICAgICAgYXdhaXQgdGhpcy5zY2FsZURvd25PbmVTdGVwKCk7XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgc2NhbGVVcE9uZVN0ZXAoZXhjbHVkZWRUb2tlbklkcyA9IG5ldyBTZXQ8bnVtYmVyPigpKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLnBvb2xDb25maWcuYXV0b3NjYWxlIHx8IHRoaXMuc3RvcHBlZCkgcmV0dXJuO1xuICAgIGF3YWl0IHRoaXMucnVuU2NhbGluZyhhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjYW5kaWRhdGVzID0gWy4uLnRoaXMudG9rZW5NZXRhZGF0YS5lbnRyaWVzKCldLmZpbHRlcigoW3Rva2VuSWQsIG1ldGFkYXRhXSkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgIW1ldGFkYXRhLmFjdGl2ZSB8fFxuICAgICAgICAgIHRoaXMuc3RhcnRpbmdUb2tlbklkcy5oYXModG9rZW5JZCkgfHxcbiAgICAgICAgICBleGNsdWRlZFRva2VuSWRzLmhhcyh0b2tlbklkKSB8fFxuICAgICAgICAgIHRoaXMucXVvdGFCbG9ja2VkVG9rZW5JZHMuaGFzKHRva2VuSWQpXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKHRoaXMud29ya2VyUG9vbC5nZXQodG9rZW5JZCk/Lmxlbmd0aCA/PyAwKSA8IHRoaXMucG9vbENvbmZpZy5tYXhXb3JrZXJzUGVyVG9rZW47XG4gICAgICB9KTtcbiAgICAgIGlmIChjYW5kaWRhdGVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgICBjb25zdCBwcm9qZWN0ZWRXb3JrZXJDb3VudCA9IHRoaXMud29ya2VyQ291bnQgKyBjYW5kaWRhdGVzLmxlbmd0aDtcbiAgICAgIGNvbnN0IHByb2plY3RlZFJzc0dpQiA9IGVzdGltYXRlT3BlbkFJV29ya2VyUnNzR2lCKHByb2plY3RlZFdvcmtlckNvdW50KTtcbiAgICAgIGlmIChwcm9qZWN0ZWRSc3NHaUIgPiB0aGlzLnBvb2xDb25maWcubWF4RXN0aW1hdGVkUnNzR2lCKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgIGBvcGVuYWkgYXV0b3NjYWxlIGJsb2NrZWQ6IGVzdGltYXRlZCBSU1MgJHtwcm9qZWN0ZWRSc3NHaUIudG9GaXhlZCgyKX1HaUIgZXhjZWVkcyAke3RoaXMucG9vbENvbmZpZy5tYXhFc3RpbWF0ZWRSc3NHaUIudG9GaXhlZCgyKX1HaUJgLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGhvc3RBdmFpbGFibGVHaUIgPSB0aGlzLmdldEhvc3RBdmFpbGFibGVHaUIoKTtcbiAgICAgIGlmIChob3N0QXZhaWxhYmxlR2lCIDwgdGhpcy5wb29sQ29uZmlnLm1pbkhvc3RBdmFpbGFibGVHaUIpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgYG9wZW5haSBhdXRvc2NhbGUgYmxvY2tlZDogaG9zdCBhdmFpbGFibGUgJHtob3N0QXZhaWxhYmxlR2lCLnRvRml4ZWQoMil9R2lCIGJlbG93ICR7dGhpcy5wb29sQ29uZmlnLm1pbkhvc3RBdmFpbGFibGVHaUIudG9GaXhlZCgyKX1HaUJgLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHNwYXduZWQgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgY2FuZGlkYXRlcy5tYXAoKFt0b2tlbklkLCBtZXRhZGF0YV0pID0+IHRoaXMuc3Bhd25BbmRDb21taXRXb3JrZXIodG9rZW5JZCwgbWV0YWRhdGEsIHRydWUpKSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGFkZGVkID0gc3Bhd25lZC5maWx0ZXIoKHdvcmtlcikgPT4gd29ya2VyICE9PSBudWxsKS5sZW5ndGg7XG4gICAgICBpZiAoYWRkZWQgPiAwKSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICAgIGBvcGVuYWkgYXV0b3NjYWxlIHVwOiArJHthZGRlZH0gd29ya2VycyAoJHt0aGlzLndvcmtlckNvdW50fSB0b3RhbCwgcXVldWUgJHt0aGlzLnF1ZXVlLmxlbmd0aH0pYCxcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5yZXF1ZXN0RHJhaW5RdWV1ZSgpO1xuICAgICAgICBpZiAodGhpcy5xdWV1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KFxuICAgICAgICAgICAgKCkgPT4gdGhpcy5yZXF1ZXN0QXV0b3NjYWxlRXZhbHVhdGlvbigpLFxuICAgICAgICAgICAgTWF0aC5taW4odGhpcy5wb29sQ29uZmlnLnNjYWxlSW50ZXJ2YWxNcywgMV8wMDApLFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGltZXIudW5yZWY/LigpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBhc3luYyBlbnN1cmVNaW5pbXVtV29ya2Vyc09uZVN0ZXAoKTogUHJvbWlzZTxTZXQ8bnVtYmVyPj4ge1xuICAgIGNvbnN0IG1pbmltdW1EZWZpY2l0VG9rZW5JZHMgPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgICBpZiAodGhpcy5zdG9wcGVkKSByZXR1cm4gbWluaW11bURlZmljaXRUb2tlbklkcztcbiAgICBhd2FpdCB0aGlzLnJ1blNjYWxpbmcoYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgY2FuZGlkYXRlcyA9IFsuLi50aGlzLnRva2VuTWV0YWRhdGEuZW50cmllcygpXS5maWx0ZXIoKFt0b2tlbklkLCBtZXRhZGF0YV0pID0+IHtcbiAgICAgICAgaWYgKCFtZXRhZGF0YS5hY3RpdmUgfHwgdGhpcy5zdGFydGluZ1Rva2VuSWRzLmhhcyh0b2tlbklkKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICByZXR1cm4gKHRoaXMud29ya2VyUG9vbC5nZXQodG9rZW5JZCk/Lmxlbmd0aCA/PyAwKSA8IHRoaXMucG9vbENvbmZpZy5taW5Xb3JrZXJzUGVyVG9rZW47XG4gICAgICB9KTtcbiAgICAgIGlmIChjYW5kaWRhdGVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgY2FuZGlkYXRlcy5mb3JFYWNoKChbdG9rZW5JZF0pID0+IG1pbmltdW1EZWZpY2l0VG9rZW5JZHMuYWRkKHRva2VuSWQpKTtcblxuICAgICAgY29uc3Qgc3Bhd25lZCA9IGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgICBjYW5kaWRhdGVzLm1hcCgoW3Rva2VuSWQsIG1ldGFkYXRhXSkgPT5cbiAgICAgICAgICB0aGlzLnNwYXduQW5kQ29tbWl0V29ya2VyKHRva2VuSWQsIG1ldGFkYXRhLCBmYWxzZSksXG4gICAgICAgICksXG4gICAgICApO1xuICAgICAgY29uc3QgYWRkZWQgPSBzcGF3bmVkLmZpbHRlcigod29ya2VyKSA9PiB3b3JrZXIgIT09IG51bGwpLmxlbmd0aDtcbiAgICAgIGlmIChhZGRlZCA+IDApIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oYG9wZW5haSB3b3JrZXIgcG9vbCByZXBhaXJlZDogKyR7YWRkZWR9IHdvcmtlcnMgKCR7dGhpcy53b3JrZXJDb3VudH0gdG90YWwpYCk7XG4gICAgICAgIHRoaXMucmVxdWVzdERyYWluUXVldWUoKTtcbiAgICAgICAgaWYgKHRoaXMucXVldWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dChcbiAgICAgICAgICAgICgpID0+IHRoaXMucmVxdWVzdEF1dG9zY2FsZUV2YWx1YXRpb24oKSxcbiAgICAgICAgICAgIE1hdGgubWluKHRoaXMucG9vbENvbmZpZy5zY2FsZUludGVydmFsTXMsIDFfMDAwKSxcbiAgICAgICAgICApO1xuICAgICAgICAgIHRpbWVyLnVucmVmPy4oKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBtaW5pbXVtRGVmaWNpdFRva2VuSWRzO1xuICB9XG5cbiAgYXN5bmMgc2NhbGVEb3duT25lU3RlcCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMucG9vbENvbmZpZy5hdXRvc2NhbGUgfHwgdGhpcy5zdG9wcGVkKSByZXR1cm47XG4gICAgYXdhaXQgdGhpcy5ydW5TY2FsaW5nKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHJlbW92ZWQ6IENvZGV4QXBwU2VydmVyV29ya2VyW10gPSBbXTtcbiAgICAgIGZvciAoY29uc3QgdG9rZW5JZCBvZiB0aGlzLnRva2VuTWV0YWRhdGEua2V5cygpKSB7XG4gICAgICAgIGNvbnN0IHdvcmtlcnMgPSB0aGlzLndvcmtlclBvb2wuZ2V0KHRva2VuSWQpID8/IFtdO1xuICAgICAgICBpZiAod29ya2Vycy5sZW5ndGggPD0gdGhpcy5wb29sQ29uZmlnLm1pbldvcmtlcnNQZXJUb2tlbikgY29udGludWU7XG5cbiAgICAgICAgY29uc3Qgd29ya2VyID0gd29ya2Vyc1xuICAgICAgICAgIC50b1NvcnRlZCgoYSwgYikgPT4gYi53b3JrZXJJbmRleCAtIGEud29ya2VySW5kZXgpXG4gICAgICAgICAgLmZpbmQoKGVudHJ5KSA9PiBlbnRyeS5oYXNDYXBhY2l0eSk7XG4gICAgICAgIGlmICghd29ya2VyKSBjb250aW51ZTtcblxuICAgICAgICB0aGlzLndvcmtlclBvb2wuc2V0KFxuICAgICAgICAgIHRva2VuSWQsXG4gICAgICAgICAgd29ya2Vycy5maWx0ZXIoKGVudHJ5KSA9PiBlbnRyeSAhPT0gd29ya2VyKSxcbiAgICAgICAgKTtcbiAgICAgICAgcmVtb3ZlZC5wdXNoKHdvcmtlcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChyZW1vdmVkLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKHJlbW92ZWQubWFwKCh3b3JrZXIpID0+IHdvcmtlci5raWxsKCkpKTtcbiAgICAgIGxvZ2dlci5pbmZvKGBvcGVuYWkgYXV0b3NjYWxlIGRvd246IC0ke3JlbW92ZWQubGVuZ3RofSB3b3JrZXJzICgke3RoaXMud29ya2VyQ291bnR9IHRvdGFsKWApO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBuZXh0QXZhaWxhYmxlV29ya2VySW5kZXgod29ya2VyczogQ29kZXhBcHBTZXJ2ZXJXb3JrZXJbXSk6IG51bWJlciB7XG4gICAgY29uc3QgdXNlZCA9IG5ldyBTZXQod29ya2Vycy5tYXAoKHdvcmtlcikgPT4gd29ya2VyLndvcmtlckluZGV4KSk7XG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMucG9vbENvbmZpZy5tYXhXb3JrZXJzUGVyVG9rZW47IGluZGV4KyspIHtcbiAgICAgIGlmICghdXNlZC5oYXMoaW5kZXgpKSByZXR1cm4gaW5kZXg7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnBvb2xDb25maWcubWF4V29ya2Vyc1BlclRva2VuO1xuICB9XG5cbiAgcHJpdmF0ZSBzd2VlcElkbGVXb3JrZXJUaHJlYWRzKCk6IHZvaWQge1xuICAgIGZvciAoY29uc3Qgd29ya2VyIG9mIFsuLi50aGlzLndvcmtlclBvb2wudmFsdWVzKCldLmZsYXQoKSkge1xuICAgICAgLy8gdHVybiDspJEgdW5zdWJzY3JpYmXtlZjrqbQg7ZW064u5IGNvbm5lY3Rpb27snLzroZwgbm90aWZpY2F0aW9u7J20IOuNlCDsmKTsp4Ag7JWK7JWEXG4gICAgICAvLyDsi6Ttlokg7KSRIOyalOyyreydtCB0aW1lb3V065CgIOyImCDsnojri6QuIHJlYWR5ICsgaWRsZSB3b3JrZXLrp4wgc3dlZXDtlZzri6QuXG4gICAgICBpZiAod29ya2VyLmlzUmVhZHkgJiYgd29ya2VyLmhhc0NhcGFjaXR5KSB3b3JrZXIuc3dlZXBJZGxlVGhyZWFkcygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgc3Bhd25BbmRDb21taXRXb3JrZXIoXG4gICAgdG9rZW5JZDogbnVtYmVyLFxuICAgIG1ldGFkYXRhOiBUb2tlbk1ldGFkYXRhLFxuICAgIHJlc3BlY3RRdW90YUJsb2NrOiBib29sZWFuLFxuICApOiBQcm9taXNlPENvZGV4QXBwU2VydmVyV29ya2VyIHwgbnVsbD4ge1xuICAgIGNvbnN0IGV4cGVjdGVkV29ya2VycyA9IHRoaXMud29ya2VyUG9vbC5nZXQodG9rZW5JZCk7XG4gICAgY29uc3Qgd29ya2VySW5kZXggPSB0aGlzLm5leHRBdmFpbGFibGVXb3JrZXJJbmRleChleHBlY3RlZFdvcmtlcnMgPz8gW10pO1xuICAgIGlmICh3b3JrZXJJbmRleCA+PSB0aGlzLnBvb2xDb25maWcubWF4V29ya2Vyc1BlclRva2VuKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IHdvcmtlciA9IGF3YWl0IHRoaXMuc3Bhd25TaW5nbGVXb3JrZXIoXG4gICAgICB0b2tlbklkLFxuICAgICAgbWV0YWRhdGEubmFtZSxcbiAgICAgIG1ldGFkYXRhLmNyZWRlbnRpYWxzLFxuICAgICAgd29ya2VySW5kZXgsXG4gICAgKTtcbiAgICBpZiAoIXdvcmtlcikgcmV0dXJuIG51bGw7XG5cbiAgICBjb25zdCBjdXJyZW50TWV0YWRhdGEgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpO1xuICAgIGNvbnN0IGN1cnJlbnRXb3JrZXJzID0gdGhpcy53b3JrZXJQb29sLmdldCh0b2tlbklkKTtcbiAgICBpZiAoXG4gICAgICAhY3VycmVudE1ldGFkYXRhPy5hY3RpdmUgfHxcbiAgICAgIGN1cnJlbnRNZXRhZGF0YSAhPT0gbWV0YWRhdGEgfHxcbiAgICAgIGN1cnJlbnRXb3JrZXJzICE9PSBleHBlY3RlZFdvcmtlcnMgfHxcbiAgICAgIChyZXNwZWN0UXVvdGFCbG9jayAmJiB0aGlzLnF1b3RhQmxvY2tlZFRva2VuSWRzLmhhcyh0b2tlbklkKSkgfHxcbiAgICAgIGN1cnJlbnRXb3JrZXJzPy5zb21lKChlbnRyeSkgPT4gZW50cnkud29ya2VySW5kZXggPT09IHdvcmtlckluZGV4KVxuICAgICkge1xuICAgICAgYXdhaXQgd29ya2VyLmtpbGwoKS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBuZXh0V29ya2VycyA9IGN1cnJlbnRXb3JrZXJzID8/IFtdO1xuICAgIG5leHRXb3JrZXJzLnB1c2god29ya2VyKTtcbiAgICBuZXh0V29ya2Vycy5zb3J0KChhLCBiKSA9PiBhLndvcmtlckluZGV4IC0gYi53b3JrZXJJbmRleCk7XG4gICAgaWYgKCFjdXJyZW50V29ya2VycykgdGhpcy53b3JrZXJQb29sLnNldCh0b2tlbklkLCBuZXh0V29ya2Vycyk7XG4gICAgcmV0dXJuIHdvcmtlcjtcbiAgfVxuXG4gIGFzeW5jIGhhbmRsZVdvcmtlclRlcm1pbmFsRmFpbHVyZSh3b3JrZXI6IENvZGV4QXBwU2VydmVyV29ya2VyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgd29ya2VycyA9IHRoaXMud29ya2VyUG9vbC5nZXQod29ya2VyLnRva2VuSWQpO1xuICAgIGlmICghd29ya2Vycz8uaW5jbHVkZXMod29ya2VyKSkgcmV0dXJuO1xuXG4gICAgYXdhaXQgd29ya2VyLmtpbGwoKS5jYXRjaCgoKSA9PiB7fSk7XG5cbiAgICBjb25zdCBjdXJyZW50V29ya2VycyA9IHRoaXMud29ya2VyUG9vbC5nZXQod29ya2VyLnRva2VuSWQpO1xuICAgIGlmICghY3VycmVudFdvcmtlcnM/LmluY2x1ZGVzKHdvcmtlcikpIHJldHVybjtcbiAgICBjb25zdCByZW1haW5pbmcgPSBjdXJyZW50V29ya2Vycy5maWx0ZXIoKGVudHJ5KSA9PiBlbnRyeSAhPT0gd29ya2VyKTtcbiAgICBpZiAocmVtYWluaW5nLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMud29ya2VyUG9vbC5zZXQod29ya2VyLnRva2VuSWQsIHJlbWFpbmluZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMud29ya2VyUG9vbC5kZWxldGUod29ya2VyLnRva2VuSWQpO1xuICAgIH1cbiAgICBsb2dnZXIud2FybihcbiAgICAgIGB0ZXJtaW5hbCB3b3JrZXIgcmVtb3ZlZDogJHt3b3JrZXIudG9rZW5OYW1lfVske3dvcmtlci53b3JrZXJJbmRleH1dICgke3JlbWFpbmluZy5sZW5ndGh9IHJlbWFpbmluZylgLFxuICAgICk7XG4gICAgdGhpcy5yZXF1ZXN0QXV0b3NjYWxlRXZhbHVhdGlvbigpO1xuICB9XG5cbiAgcHJpdmF0ZSByZXF1ZXN0QXV0b3NjYWxlRXZhbHVhdGlvbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zdG9wcGVkKSByZXR1cm47XG4gICAgdm9pZCB0aGlzLmV2YWx1YXRlQXV0b3NjYWxpbmcoKS5jYXRjaCgoZSkgPT5cbiAgICAgIGxvZ2dlci53YXJuKGBvcGVuYWkgYXV0b3NjYWxlIGV2YWx1YXRpb24gZmFpbGVkOiAkeyhlIGFzIEVycm9yKS5tZXNzYWdlfWApLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJ1blNjYWxpbmcodGFzazogKCkgPT4gUHJvbWlzZTx2b2lkPik6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLnNjYWxpbmdQcm9taXNlKSB7XG4gICAgICBhd2FpdCB0aGlzLnNjYWxpbmdQcm9taXNlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzY2FsaW5nID0gdGFzaygpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgaWYgKHRoaXMuc2NhbGluZ1Byb21pc2UgPT09IHNjYWxpbmcpIHRoaXMuc2NhbGluZ1Byb21pc2UgPSBudWxsO1xuICAgIH0pO1xuICAgIHRoaXMuc2NhbGluZ1Byb21pc2UgPSBzY2FsaW5nO1xuICAgIGF3YWl0IHNjYWxpbmc7XG4gIH1cblxuICAvLyDilIDilIAgUmF0ZSBsaW1pdHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcmF0ZUxpbWl0c0NhY2hlID0gbmV3IE1hcDxudW1iZXIsIFJhdGVMaW1pdHNDYWNoZUVudHJ5PigpO1xuICBzdGF0aWMgcmVhZG9ubHkgUkFURV9MSU1JVFNfQ0FDSEVfVFRMID0gNjBfMDAwO1xuXG4gIGFzeW5jIGdldFJhdGVMaW1pdHNCeVRva2VuSWQodG9rZW5JZDogbnVtYmVyKTogUHJvbWlzZTxPcGVuQUlSYXRlTGltaXRzV2l0aE1ldGE+IHtcbiAgICBjb25zdCBnZW5lcmF0aW9uID0gdGhpcy5yYXRlTGltaXRzR2VuZXJhdGlvbkJ5VG9rZW4uZ2V0KHRva2VuSWQpID8/IDA7XG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5yYXRlTGltaXRzQ2FjaGUuZ2V0KHRva2VuSWQpO1xuICAgIGlmIChcbiAgICAgIGNhY2hlZCAmJlxuICAgICAgY2FjaGVkLmdlbmVyYXRpb24gPT09IGdlbmVyYXRpb24gJiZcbiAgICAgIERhdGUubm93KCkgLSBjYWNoZWQuY2FjaGVkQXQgPCBPcGVuQUlEaXNwYXRjaGVyLlJBVEVfTElNSVRTX0NBQ0hFX1RUTFxuICAgICkge1xuICAgICAgcmV0dXJuIHsgZGF0YTogY2FjaGVkLmRhdGEsIGNhY2hlZEF0OiBjYWNoZWQuY2FjaGVkQXQgfTtcbiAgICB9XG5cbiAgICBjb25zdCB3b3JrZXIgPSAodGhpcy53b3JrZXJQb29sLmdldCh0b2tlbklkKSA/PyBbXSkuZmluZCgodykgPT4gdy5pc1JlYWR5KTtcbiAgICBpZiAoIXdvcmtlcikgdGhyb3cgbmV3IEVycm9yKFwibm8gcmVhZHkgb3BlbmFpIHdvcmtlcnNcIik7XG4gICAgY29uc3QgZGF0YSA9IChhd2FpdCB3b3JrZXIuZ2V0UmF0ZUxpbWl0cygpKSBhcyBHZXRBY2NvdW50UmF0ZUxpbWl0c1Jlc3BvbnNlO1xuICAgIGNvbnN0IGVudHJ5OiBSYXRlTGltaXRzQ2FjaGVFbnRyeSA9IHsgZGF0YSwgY2FjaGVkQXQ6IERhdGUubm93KCksIGdlbmVyYXRpb24gfTtcbiAgICBpZiAoKHRoaXMucmF0ZUxpbWl0c0dlbmVyYXRpb25CeVRva2VuLmdldCh0b2tlbklkKSA/PyAwKSA9PT0gZ2VuZXJhdGlvbikge1xuICAgICAgdGhpcy5yYXRlTGltaXRzQ2FjaGUuc2V0KHRva2VuSWQsIGVudHJ5KTtcbiAgICB9XG4gICAgcmV0dXJuIHsgZGF0YTogZW50cnkuZGF0YSwgY2FjaGVkQXQ6IGVudHJ5LmNhY2hlZEF0IH07XG4gIH1cblxuICBwcml2YXRlIHJlcXVlc3REcmFpblF1ZXVlKCk6IHZvaWQge1xuICAgIHZvaWQgdGhpcy5kcmFpblF1ZXVlKCkuY2F0Y2goKGUpID0+IGxvZ2dlci53YXJuKGBkcmFpblF1ZXVlIGZhaWxlZDogJHsoZSBhcyBFcnJvcikubWVzc2FnZX1gKSk7XG4gIH1cblxuICBwcml2YXRlIGludmFsaWRhdGVSYXRlTGltaXRzQ2FjaGUodG9rZW5JZDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5yYXRlTGltaXRzQ2FjaGUuZGVsZXRlKHRva2VuSWQpO1xuICAgIHRoaXMucmF0ZUxpbWl0c0dlbmVyYXRpb25CeVRva2VuLnNldChcbiAgICAgIHRva2VuSWQsXG4gICAgICAodGhpcy5yYXRlTGltaXRzR2VuZXJhdGlvbkJ5VG9rZW4uZ2V0KHRva2VuSWQpID8/IDApICsgMSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRUb2tlbk1ldGFkYXRhKFxuICAgIGlkOiBudW1iZXIsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscyxcbiAgICBxdW90YVRocmVzaG9sZDogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgICB3ZWlnaHQ6IG51bWJlcixcbiAgKTogdm9pZCB7XG4gICAgdGhpcy50b2tlbk1ldGFkYXRhLnNldChpZCwge1xuICAgICAgbmFtZSxcbiAgICAgIGNyZWRlbnRpYWxzLFxuICAgICAgcXVvdGFUaHJlc2hvbGQsXG4gICAgICB3ZWlnaHQsXG4gICAgICBhY3RpdmU6IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoaWQpPy5hY3RpdmUgPz8gdHJ1ZSxcbiAgICB9KTtcbiAgICB0aGlzLndlaWdodGVkU2VsZWN0b3Iuc2V0VG9rZW4oaWQsIHdlaWdodCk7XG4gIH1cblxuICBwcml2YXRlIGhhc0FjdGl2ZVRva2VuQ2FuZGlkYXRlKGV4Y2x1ZGVkVG9rZW5JZHM6IFNldDxudW1iZXI+KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIFsuLi50aGlzLnRva2VuTWV0YWRhdGEuZW50cmllcygpXS5zb21lKFxuICAgICAgKFt0b2tlbklkLCBtZXRhZGF0YV0pID0+IG1ldGFkYXRhLmFjdGl2ZSAmJiAhZXhjbHVkZWRUb2tlbklkcy5oYXModG9rZW5JZCksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UXVvdGFUaHJlc2hvbGQodG9rZW5JZDogbnVtYmVyKTogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCk/LnF1b3RhVGhyZXNob2xkO1xuICB9XG5cbiAgcHJpdmF0ZSBoYXNRdW90YVRocmVzaG9sZCh0b2tlbklkOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCB0aHJlc2hvbGQgPSB0aGlzLmdldFF1b3RhVGhyZXNob2xkKHRva2VuSWQpO1xuICAgIHJldHVybiB0aHJlc2hvbGQgIT09IHVuZGVmaW5lZCAmJiB0aHJlc2hvbGQgIT09IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlc29sdmVUb2tlbkVsaWdpYmlsaXR5KGV4Y2x1ZGVkVG9rZW5JZHM6IFNldDxudW1iZXI+KTogUHJvbWlzZTxUb2tlbkVsaWdpYmlsaXR5PiB7XG4gICAgY29uc3Qgd29ya2VycyA9IHRoaXMuZ2V0QWxsUmVhZHlBY3RpdmVXb3JrZXJzKCk7XG4gICAgY29uc3QgYnlUb2tlbiA9IG5ldyBNYXA8bnVtYmVyLCBzdHJpbmc+KCk7XG4gICAgZm9yIChjb25zdCB3b3JrZXIgb2Ygd29ya2Vycykge1xuICAgICAgaWYgKCFieVRva2VuLmhhcyh3b3JrZXIudG9rZW5JZCkpIGJ5VG9rZW4uc2V0KHdvcmtlci50b2tlbklkLCB3b3JrZXIudG9rZW5OYW1lKTtcbiAgICB9XG5cbiAgICBjb25zdCByZWFkeUFjdGl2ZVRva2VuSWRzID0gbmV3IFNldChieVRva2VuLmtleXMoKSk7XG4gICAgY29uc3QgZWxpZ2libGVUb2tlbklkcyA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICAgIGNvbnN0IG92ZXJUaHJlc2hvbGRUb2tlbnM6IEFycmF5PHsgdG9rZW5OYW1lOiBzdHJpbmc7IHRocmVzaG9sZDogbnVtYmVyIH0+ID0gW107XG4gICAgbGV0IHRocmVzaG9sZGVkVG9rZW5Db3VudCA9IDA7XG5cbiAgICBjb25zdCBlbnRyaWVzID0gQXJyYXkuZnJvbShieVRva2VuLmVudHJpZXMoKSk7XG4gICAgY29uc3QgY2hlY2tzID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFxuICAgICAgZW50cmllcy5tYXAoYXN5bmMgKFt0b2tlbklkLCB0b2tlbk5hbWVdKSA9PiB7XG4gICAgICAgIGlmIChleGNsdWRlZFRva2VuSWRzLmhhcyh0b2tlbklkKSkge1xuICAgICAgICAgIHRocmVzaG9sZGVkVG9rZW5Db3VudCsrO1xuICAgICAgICAgIHJldHVybiB7IHRva2VuSWQsIHRva2VuTmFtZSwgZWxpZ2libGU6IGZhbHNlIH07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLmhhc1F1b3RhVGhyZXNob2xkKHRva2VuSWQpKSB7XG4gICAgICAgICAgcmV0dXJuIHsgdG9rZW5JZCwgdG9rZW5OYW1lLCBlbGlnaWJsZTogdHJ1ZSB9O1xuICAgICAgICB9XG4gICAgICAgIHRocmVzaG9sZGVkVG9rZW5Db3VudCsrO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHRva2VuSWQsXG4gICAgICAgICAgdG9rZW5OYW1lLFxuICAgICAgICAgIGVsaWdpYmxlOiBhd2FpdCB0aGlzLmlzVG9rZW5RdW90YUVsaWdpYmxlKHRva2VuSWQsIHRva2VuTmFtZSksXG4gICAgICAgIH07XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgY2hlY2tzLmZvckVhY2goKGNoZWNrLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGNoZWNrLnN0YXR1cyA9PT0gXCJmdWxmaWxsZWRcIikge1xuICAgICAgICBpZiAoY2hlY2sudmFsdWUuZWxpZ2libGUpIHtcbiAgICAgICAgICBlbGlnaWJsZVRva2VuSWRzLmFkZChjaGVjay52YWx1ZS50b2tlbklkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCB0aHJlc2hvbGQgPSB0aGlzLmdldFF1b3RhVGhyZXNob2xkKGNoZWNrLnZhbHVlLnRva2VuSWQpO1xuICAgICAgICAgIGlmICh0aHJlc2hvbGQgIT09IHVuZGVmaW5lZCAmJiB0aHJlc2hvbGQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG92ZXJUaHJlc2hvbGRUb2tlbnMucHVzaCh7IHRva2VuTmFtZTogY2hlY2sudmFsdWUudG9rZW5OYW1lLCB0aHJlc2hvbGQgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZW50cnkgPSBlbnRyaWVzW2luZGV4XTtcbiAgICAgIGlmIChlbnRyeSkge1xuICAgICAgICBjb25zdCBbdG9rZW5JZCwgdG9rZW5OYW1lXSA9IGVudHJ5O1xuICAgICAgICB0aGlzLmxvZ1F1b3RhTG9va3VwRmFpbE9wZW4odG9rZW5JZCwgdG9rZW5OYW1lLCBTdHJpbmcoY2hlY2sucmVhc29uKSk7XG4gICAgICAgIGVsaWdpYmxlVG9rZW5JZHMuYWRkKHRva2VuSWQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIHsgcmVhZHlBY3RpdmVUb2tlbklkcywgZWxpZ2libGVUb2tlbklkcywgb3ZlclRocmVzaG9sZFRva2VucywgdGhyZXNob2xkZWRUb2tlbkNvdW50IH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGlzVG9rZW5RdW90YUVsaWdpYmxlKFxuICAgIHRva2VuSWQ6IG51bWJlcixcbiAgICB0b2tlbk5hbWU6IHN0cmluZyxcbiAgICBleGNsdWRlZFRva2VuSWRzPzogU2V0PG51bWJlcj4sXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGZvciAoOzspIHtcbiAgICAgIGNvbnN0IHRva2VuTWV0YWRhdGEgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpO1xuICAgICAgY29uc3QgdGhyZXNob2xkID0gdG9rZW5NZXRhZGF0YT8ucXVvdGFUaHJlc2hvbGQ7XG4gICAgICBpZiAoIXRva2VuTWV0YWRhdGE/LmFjdGl2ZSB8fCB0aHJlc2hvbGQgPT09IHVuZGVmaW5lZCB8fCB0aHJlc2hvbGQgPT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5xdW90YUJsb2NrZWRUb2tlbklkcy5kZWxldGUodG9rZW5JZCk7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuXG4gICAgICBsZXQgcmVzdWx0OiBPcGVuQUlRdW90YVVzYWdlUmVzdWx0O1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmVzdWx0ID0gYXdhaXQgcmVhZE9wZW5BSVF1b3RhVXNhZ2UoKCkgPT4gdGhpcy5nZXRSYXRlTGltaXRzQnlUb2tlbklkKHRva2VuSWQpKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgaWYgKHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCkgIT09IHRva2VuTWV0YWRhdGEpIGNvbnRpbnVlO1xuICAgICAgICB0aGlzLnF1b3RhQmxvY2tlZFRva2VuSWRzLmRlbGV0ZSh0b2tlbklkKTtcbiAgICAgICAgdGhpcy5sb2dRdW90YUxvb2t1cEZhaWxPcGVuKHRva2VuSWQsIHRva2VuTWV0YWRhdGEubmFtZSA/PyB0b2tlbk5hbWUsIChlIGFzIEVycm9yKS5tZXNzYWdlKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpICE9PSB0b2tlbk1ldGFkYXRhKSBjb250aW51ZTtcblxuICAgICAgaWYgKHJlc3VsdC5raW5kID09PSBcImxvb2t1cF9mYWlsZWRcIikge1xuICAgICAgICB0aGlzLnF1b3RhQmxvY2tlZFRva2VuSWRzLmRlbGV0ZSh0b2tlbklkKTtcbiAgICAgICAgdGhpcy5sb2dRdW90YUxvb2t1cEZhaWxPcGVuKHRva2VuSWQsIHRva2VuTWV0YWRhdGEubmFtZSA/PyB0b2tlbk5hbWUsIHJlc3VsdC5yZWFzb24pO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlc3VsdC51dGlsaXphdGlvblBjdCA+PSB0aHJlc2hvbGQpIHtcbiAgICAgICAgY29uc3QgdHJhbnNpdGlvbmVkID0gIXRoaXMucXVvdGFCbG9ja2VkVG9rZW5JZHMuaGFzKHRva2VuSWQpO1xuICAgICAgICB0aGlzLnF1b3RhQmxvY2tlZFRva2VuSWRzLmFkZCh0b2tlbklkKTtcbiAgICAgICAgaWYgKHRyYW5zaXRpb25lZCkge1xuICAgICAgICAgIHRoaXMubG9nUXVvdGFPdmVyVGhyZXNob2xkKHRva2VuSWQsIHRva2VuTWV0YWRhdGEubmFtZSA/PyB0b2tlbk5hbWUsIHRocmVzaG9sZCwgcmVzdWx0KTtcbiAgICAgICAgfVxuICAgICAgICBleGNsdWRlZFRva2VuSWRzPy5hZGQodG9rZW5JZCk7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMucXVvdGFCbG9ja2VkVG9rZW5JZHMuZGVsZXRlKHRva2VuSWQpKSB7XG4gICAgICAgIHRoaXMubG9nUXVvdGFSZWNvdmVyZWQodG9rZW5JZCwgdG9rZW5NZXRhZGF0YS5uYW1lID8/IHRva2VuTmFtZSwgdGhyZXNob2xkLCByZXN1bHQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBsb2dRdW90YU92ZXJUaHJlc2hvbGQoXG4gICAgdG9rZW5JZDogbnVtYmVyLFxuICAgIHRva2VuTmFtZTogc3RyaW5nLFxuICAgIHRocmVzaG9sZDogbnVtYmVyLFxuICAgIHJlc3VsdDogRXh0cmFjdDxPcGVuQUlRdW90YVVzYWdlUmVzdWx0LCB7IGtpbmQ6IFwib2tcIiB9PixcbiAgKTogdm9pZCB7XG4gICAgbG9nZ2VyLmluZm8oXG4gICAgICBgcXVvdGFfdGhyZXNob2xkIGdhdGU6IG92ZXJfdGhyZXNob2xkICR7dG9rZW5OYW1lfVske3Rva2VuSWR9XSAoJHtyZXN1bHQudXRpbGl6YXRpb25QY3R9JSA+PSAke3RocmVzaG9sZH0lKWAsXG4gICAgICB7XG4gICAgICAgIHRva2VuSWQsXG4gICAgICAgIHRva2VuTmFtZSxcbiAgICAgICAgcHJvdmlkZXI6IFwib3BlbmFpXCIsXG4gICAgICAgIHRocmVzaG9sZCxcbiAgICAgICAgY2FjaGVkVXRpbGl6YXRpb246IHJlc3VsdC51dGlsaXphdGlvblBjdCxcbiAgICAgICAgY2FjaGVBZ2U6IHJlc3VsdC5jYWNoZUFnZU1zLFxuICAgICAgICB3aW5kb3dEdXJhdGlvbk1pbnM6IHJlc3VsdC53aW5kb3dEdXJhdGlvbk1pbnMsXG4gICAgICAgIHJlc2V0c0F0OiByZXN1bHQucmVzZXRzQXQsXG4gICAgICAgIGxpbWl0SWQ6IHJlc3VsdC5saW1pdElkLFxuICAgICAgICByZWFzb246IFwib3Zlcl90aHJlc2hvbGRcIixcbiAgICAgIH0sXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9nUXVvdGFSZWNvdmVyZWQoXG4gICAgdG9rZW5JZDogbnVtYmVyLFxuICAgIHRva2VuTmFtZTogc3RyaW5nLFxuICAgIHRocmVzaG9sZDogbnVtYmVyLFxuICAgIHJlc3VsdDogRXh0cmFjdDxPcGVuQUlRdW90YVVzYWdlUmVzdWx0LCB7IGtpbmQ6IFwib2tcIiB9PixcbiAgKTogdm9pZCB7XG4gICAgbG9nZ2VyLmluZm8oXG4gICAgICBgcXVvdGFfdGhyZXNob2xkIGdhdGU6IHJlY292ZXJlZCAke3Rva2VuTmFtZX1bJHt0b2tlbklkfV0gKCR7cmVzdWx0LnV0aWxpemF0aW9uUGN0fSUgPCAke3RocmVzaG9sZH0lKWAsXG4gICAgICB7XG4gICAgICAgIHRva2VuSWQsXG4gICAgICAgIHRva2VuTmFtZSxcbiAgICAgICAgcHJvdmlkZXI6IFwib3BlbmFpXCIsXG4gICAgICAgIHRocmVzaG9sZCxcbiAgICAgICAgY2FjaGVkVXRpbGl6YXRpb246IHJlc3VsdC51dGlsaXphdGlvblBjdCxcbiAgICAgICAgY2FjaGVBZ2U6IHJlc3VsdC5jYWNoZUFnZU1zLFxuICAgICAgICB3aW5kb3dEdXJhdGlvbk1pbnM6IHJlc3VsdC53aW5kb3dEdXJhdGlvbk1pbnMsXG4gICAgICAgIHJlc2V0c0F0OiByZXN1bHQucmVzZXRzQXQsXG4gICAgICAgIGxpbWl0SWQ6IHJlc3VsdC5saW1pdElkLFxuICAgICAgICByZWFzb246IFwicmVjb3ZlcmVkXCIsXG4gICAgICB9LFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGxvZ1F1b3RhTG9va3VwRmFpbE9wZW4odG9rZW5JZDogbnVtYmVyLCB0b2tlbk5hbWU6IHN0cmluZywgcmVhc29uOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCB0aHJlc2hvbGQgPSB0aGlzLmdldFF1b3RhVGhyZXNob2xkKHRva2VuSWQpO1xuICAgIGxvZ2dlci53YXJuKFwicXVvdGFfdGhyZXNob2xkIGdhdGU6IGxvb2t1cF9mYWlsX29wZW5cIiwge1xuICAgICAgdG9rZW5JZCxcbiAgICAgIHRva2VuTmFtZSxcbiAgICAgIHByb3ZpZGVyOiBcIm9wZW5haVwiLFxuICAgICAgdGhyZXNob2xkLFxuICAgICAgcmVhc29uOiBcImxvb2t1cF9mYWlsX29wZW5cIixcbiAgICAgIGxvb2t1cFJlYXNvbjogcmVhc29uLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB0aHJvd1F1b3RhVGhyZXNob2xkRXhjZWVkZWQoZWxpZ2liaWxpdHk6IFRva2VuRWxpZ2liaWxpdHkpOiBuZXZlciB7XG4gICAgbG9nZ2VyLndhcm4oXCJxdW90YV90aHJlc2hvbGQgZ2F0ZTogYWxsX2V4Y2VlZGVkXCIsIHtcbiAgICAgIHByb3ZpZGVyOiBcIm9wZW5haVwiLFxuICAgICAgdG9rZW5Db3VudDogZWxpZ2liaWxpdHkucmVhZHlBY3RpdmVUb2tlbklkcy5zaXplLFxuICAgICAgdGhyZXNob2xkZWRUb2tlbkNvdW50OiBlbGlnaWJpbGl0eS50aHJlc2hvbGRlZFRva2VuQ291bnQsXG4gICAgICBvdmVyVGhyZXNob2xkVG9rZW5zOiBlbGlnaWJpbGl0eS5vdmVyVGhyZXNob2xkVG9rZW5zLFxuICAgICAgcmVhc29uOiBcImFsbF9leGNlZWRlZFwiLFxuICAgIH0pO1xuICAgIHRocm93IG5ldyBRdW90YVRocmVzaG9sZEV4Y2VlZGVkRXJyb3IoXG4gICAgICBxdW90YVRocmVzaG9sZEV4Y2VlZGVkTWVzc2FnZShcIm9wZW5haVwiLCBlbGlnaWJpbGl0eS5vdmVyVGhyZXNob2xkVG9rZW5zKSxcbiAgICApO1xuICB9XG5cbiAgLy8g4pSA4pSAIEJyb3dzZXIgbG9naW4gZmxvdyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwZW5kaW5nTG9naW46IHtcbiAgICB3b3JrZXI6IENvZGV4QXBwU2VydmVyV29ya2VyO1xuICAgIG5hbWU6IHN0cmluZztcbiAgICB0aW1lcjogUmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD47XG4gIH0gfCBudWxsID0gbnVsbDtcblxuICBhc3luYyBzdGFydEJyb3dzZXJMb2dpbihuYW1lOiBzdHJpbmcpOiBQcm9taXNlPHsgYXV0aFVybDogc3RyaW5nIH0+IHtcbiAgICBpZiAodGhpcy5wZW5kaW5nTG9naW4pIHtcbiAgICAgIHRoaXMucGVuZGluZ0xvZ2luLndvcmtlci5raWxsKCkuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucGVuZGluZ0xvZ2luLnRpbWVyKTtcbiAgICAgIHRoaXMucGVuZGluZ0xvZ2luID0gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCB0ZW1wSWQgPSBEYXRlLm5vdygpO1xuICAgIGNvbnN0IHdvcmtlciA9IG5ldyBDb2RleEFwcFNlcnZlcldvcmtlcih7XG4gICAgICB0b2tlbklkOiB0ZW1wSWQsXG4gICAgICB0b2tlbk5hbWU6IG5hbWUsXG4gICAgICBhY2Nlc3NUb2tlbjogXCJcIixcbiAgICAgIGFjY291bnRJZDogXCJcIixcbiAgICB9KTtcblxuICAgIGNvbnN0IGF1dGhVcmwgPSBhd2FpdCB3b3JrZXIuc3RhcnRCcm93c2VyTG9naW4oKTtcblxuICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5wZW5kaW5nTG9naW4/LndvcmtlciA9PT0gd29ya2VyKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBicm93c2VyIGxvZ2luIHRpbWVvdXQgZm9yICR7bmFtZX0sIGtpbGxpbmcgd29ya2VyYCk7XG4gICAgICAgIHdvcmtlci5raWxsKCkuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgICB0aGlzLnBlbmRpbmdMb2dpbiA9IG51bGw7XG4gICAgICB9XG4gICAgfSwgMzAwXzAwMCk7XG5cbiAgICB0aGlzLnBlbmRpbmdMb2dpbiA9IHsgd29ya2VyLCBuYW1lLCB0aW1lciB9O1xuICAgIHJldHVybiB7IGF1dGhVcmwgfTtcbiAgfVxuXG4gIGdldCBwZW5kaW5nTG9naW5OYW1lKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLnBlbmRpbmdMb2dpbj8ubmFtZSA/PyBudWxsO1xuICB9XG5cbiAgYXN5bmMgY29tcGxldGVCcm93c2VyTG9naW4oKTogUHJvbWlzZTx7XG4gICAgYWNjZXNzVG9rZW46IHN0cmluZztcbiAgICByZWZyZXNoVG9rZW46IHN0cmluZztcbiAgICBpZFRva2VuPzogc3RyaW5nO1xuICAgIGFjY291bnRJZDogc3RyaW5nO1xuICB9PiB7XG4gICAgaWYgKCF0aGlzLnBlbmRpbmdMb2dpbikgdGhyb3cgbmV3IEVycm9yKFwibm8gcGVuZGluZyBsb2dpblwiKTtcbiAgICBjb25zdCB7IHdvcmtlciwgdGltZXIgfSA9IHRoaXMucGVuZGluZ0xvZ2luO1xuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHdvcmtlci53YWl0Rm9yQnJvd3NlckxvZ2luQ29tcGxldGUoKTtcbiAgICAgIGNvbnN0IGNyZWRzID0gYXdhaXQgd29ya2VyLnJlYWRNYW5hZ2VkQ3JlZGVudGlhbHMoKTtcbiAgICAgIGlmICghY3JlZHMpIHRocm93IG5ldyBFcnJvcihcImZhaWxlZCB0byByZWFkIGNyZWRlbnRpYWxzIGFmdGVyIGxvZ2luXCIpO1xuICAgICAgcmV0dXJuIGNyZWRzO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgdGhpcy5wZW5kaW5nTG9naW4gPSBudWxsO1xuICAgICAgYXdhaXQgd29ya2VyLmtpbGwoKS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgfVxuICB9XG5cbiAgLy8g4pSA4pSAIFN0YXRzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGdldCB3b3JrZXJDb3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiBbLi4udGhpcy53b3JrZXJQb29sLnZhbHVlcygpXS5mbGF0KCkubGVuZ3RoO1xuICB9XG5cbiAgZ2V0IHJlYWR5V29ya2VyQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gWy4uLnRoaXMud29ya2VyUG9vbC52YWx1ZXMoKV0uZmxhdCgpLmZpbHRlcigodykgPT4gdy5pc1JlYWR5KS5sZW5ndGg7XG4gIH1cblxuICBnZXQgcXVldWVMZW5ndGgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5xdWV1ZS5sZW5ndGg7XG4gIH1cblxuICAvLyBNb25pdCDtkZzsi5zsmqkg4oCUIO2GoO2BsOuzhCDtmITsnqwg7JuM7LukIOyImCDsiqTrg4Xsg7cgKOydtOumhOyInCDsoJXroKwpXG4gIGdldCB3b3JrZXJDb3VudHNCeVRva2VuKCk6IEFycmF5PHsgbmFtZTogc3RyaW5nOyBjb3VudDogbnVtYmVyIH0+IHtcbiAgICByZXR1cm4gWy4uLnRoaXMud29ya2VyUG9vbC5lbnRyaWVzKCldXG4gICAgICAubWFwKChbdG9rZW5JZCwgd29ya2Vyc10pID0+ICh7XG4gICAgICAgIG5hbWU6IHdvcmtlcnNbMF0/LnRva2VuTmFtZSA/PyBgdG9rZW4gJHt0b2tlbklkfWAsXG4gICAgICAgIGNvdW50OiB3b3JrZXJzLmxlbmd0aCxcbiAgICAgIH0pKVxuICAgICAgLmZpbHRlcigoZW50cnkpID0+IGVudHJ5LmNvdW50ID4gMClcbiAgICAgIC50b1NvcnRlZCgoYSwgYikg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
441
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLWRpc3BhdGNoZXIuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9vcGVuYWkvb3BlbmFpLWRpc3BhdGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcblxuaW1wb3J0IHsgUXVvdGFUaHJlc2hvbGRFeGNlZWRlZEVycm9yIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLnR5cGVzXCI7XG5pbXBvcnQgeyBUb2tlbk1vZGVsIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLm1vZGVsXCI7XG5pbXBvcnQgeyB0eXBlIE9wZW5BSUNyZWRlbnRpYWxzIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLnR5cGVzXCI7XG5pbXBvcnQge1xuICB0eXBlIEdlbmVyYXRlUmVxdWVzdCxcbiAgdHlwZSBHZW5lcmF0ZVJlc3VsdCxcbiAgdHlwZSBHZW5lcmF0ZVN0cmVhbUNhbGxiYWNrcyxcbiAgdHlwZSBHZW5lcmF0ZWRJbWFnZSxcbiAgdHlwZSBQcm92aWRlckRpc3BhdGNoZXIsXG59IGZyb20gXCIuLi9jb21tb24vcHJvdmlkZXItZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgU21vb3RoV2VpZ2h0ZWRSb3VuZFJvYmluIH0gZnJvbSBcIi4uL2NvbW1vbi9zbW9vdGgtd2VpZ2h0ZWQtcm91bmQtcm9iaW5cIjtcbmltcG9ydCB7XG4gIHR5cGUgSnNvblZhbHVlLFxuICB0eXBlIE9wZW5BSVJlc3BvbnNlSXRlbSxcbiAgdHlwZSBPcGVuQUlSZXNwb25zZXNPcHRpb25zLFxufSBmcm9tIFwiLi9vcGVuYWktYmFja2VuZC1wcm90b2NvbFwiO1xuaW1wb3J0IHsgT3BlbkFJRGlyZWN0Q2xpZW50LCB0eXBlIE9wZW5BSURpcmVjdENsaWVudE9wdGlvbnMgfSBmcm9tIFwiLi9vcGVuYWktZGlyZWN0LWNsaWVudFwiO1xuaW1wb3J0IHsgcmVhZE9wZW5BSVF1b3RhVXNhZ2UsIHR5cGUgT3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhIH0gZnJvbSBcIi4vb3BlbmFpLXF1b3RhXCI7XG5pbXBvcnQgeyBoYW5kbGVDaGF0Z3B0QXV0aFRva2Vuc1JlZnJlc2ggfSBmcm9tIFwiLi9vcGVuYWktcmVmcmVzaFwiO1xuaW1wb3J0IHsgdHlwZSBPcGVuQUlUcmFuc3BvcnRLaW5kLCByZXNvbHZlT3BlbkFJVHJhbnNwb3J0S2luZCB9IGZyb20gXCIuL29wZW5haS10cmFuc3BvcnQtY29uZmlnXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGdldExvZ2dlcihbXCJxZ3JpZFwiLCBcIm9wZW5haS1kaXNwYXRjaGVyXCJdKTtcbi8vIOq1kOyytOuQnCBjb2RleCB3b3JrZXIg6rCAIOqwleygnO2VmOuNmCB3YXRjaGRvZy4g7Zi47Lac7J6Q6rCAIHRpbWVvdXRNcyDrpbwg7IOd65617ZW064+EIOyalOyyreydtFxuLy8g7JiB7JuQ7Z6IIOunpOuLrOumrOyngCDslYrrj4TroZ0gZGlyZWN0IHRyYW5zcG9ydCDrj4Qg7Jyg7ZWc7ZWcIOq4sOuzuCDsg4HtlZzsnYQg7Jyg7KeA7ZWc64ukLlxuY29uc3QgREVGQVVMVF9SRVFVRVNUX1RJTUVPVVRfTVMgPSA2MDBfMDAwO1xuXG5leHBvcnQgdHlwZSBJbWFnZUZhaWx1cmVLaW5kID0gXCJnYXRlXCIgfCBcIm5vdF9jYWxsZWRcIiB8IFwiaW5jb21wbGV0ZVwiO1xuXG5leHBvcnQgY2xhc3MgSW1hZ2VHZW5lcmF0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHJlYWRvbmx5IGtpbmQ6IEltYWdlRmFpbHVyZUtpbmQsXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICApIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSBcIkltYWdlR2VuZXJhdGlvbkVycm9yXCI7XG4gIH1cbn1cblxudHlwZSBUb2tlbk1ldGFkYXRhID0ge1xuICBuYW1lOiBzdHJpbmc7XG4gIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscztcbiAgcXVvdGFUaHJlc2hvbGQ/OiBudW1iZXIgfCBudWxsO1xuICB3ZWlnaHQ6IG51bWJlcjtcbiAgYWN0aXZlOiBib29sZWFuO1xuICBnZW5lcmF0aW9uOiBudW1iZXI7XG59O1xuXG50eXBlIFRva2VuU2VsZWN0aW9uID0geyB0b2tlbklkOiBudW1iZXI7IG1ldGFkYXRhOiBUb2tlbk1ldGFkYXRhIH07XG5cbmV4cG9ydCB0eXBlIE9wZW5BSURpcmVjdENsaWVudEZhY3RvcnkgPSAoXG4gIG9wdGlvbnM6IE9wZW5BSURpcmVjdENsaWVudE9wdGlvbnMsXG4gIHRva2VuSWQ6IG51bWJlcixcbikgPT4gUGljazxPcGVuQUlEaXJlY3RDbGllbnQsIFwicmVzcG9uc2VzXCI+ICYgeyBjbG9zZT86ICgpID0+IHZvaWQgfTtcblxudHlwZSBDbGllbnRFbnRyeSA9IHtcbiAgZ2VuZXJhdGlvbjogbnVtYmVyO1xuICBjbGllbnQ6IFBpY2s8T3BlbkFJRGlyZWN0Q2xpZW50LCBcInJlc3BvbnNlc1wiPiAmIHsgY2xvc2U/OiAoKSA9PiB2b2lkIH07XG4gIGluRmxpZ2h0OiBudW1iZXI7XG4gIHJldGlyZWQ6IGJvb2xlYW47XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIE9wZW5BSURpc3BhdGNoZXJEZXBlbmRlbmNpZXMge1xuICBjbGllbnRGYWN0b3J5PzogT3BlbkFJRGlyZWN0Q2xpZW50RmFjdG9yeTtcbiAgZmV0Y2g/OiB0eXBlb2YgZmV0Y2g7XG59XG5cbmZ1bmN0aW9uIGFib3J0RXJyb3Ioc2lnbmFsOiBBYm9ydFNpZ25hbCk6IEVycm9yIHtcbiAgY29uc3QgcmVhc29uID0gc2lnbmFsLnJlYXNvbjtcbiAgcmV0dXJuIHJlYXNvbiBpbnN0YW5jZW9mIEVycm9yID8gcmVhc29uIDogbmV3IERPTUV4Y2VwdGlvbihcIkFib3J0ZWRcIiwgXCJBYm9ydEVycm9yXCIpO1xufVxuXG5mdW5jdGlvbiBhY3RpdmVTaWduYWwoc2lnbmFsPzogQWJvcnRTaWduYWwsIHRpbWVvdXRNcz86IG51bWJlcik6IEFib3J0U2lnbmFsIHtcbiAgY29uc3QgdGltZW91dCA9IEFib3J0U2lnbmFsLnRpbWVvdXQodGltZW91dE1zID8/IERFRkFVTFRfUkVRVUVTVF9USU1FT1VUX01TKTtcbiAgcmV0dXJuIHNpZ25hbCA/IEFib3J0U2lnbmFsLmFueShbc2lnbmFsLCB0aW1lb3V0XSkgOiB0aW1lb3V0O1xufVxuXG5mdW5jdGlvbiBxdW90YU1lc3NhZ2UoZW50cmllczogQXJyYXk8eyBuYW1lOiBzdHJpbmc7IHRocmVzaG9sZDogbnVtYmVyIH0+KTogc3RyaW5nIHtcbiAgY29uc3QgZGV0YWlsID0gZW50cmllcy5tYXAoKGUpID0+IGAke2UubmFtZX0gKHRocmVzaG9sZCAke2UudGhyZXNob2xkfSUpYCkuam9pbihcIiwgXCIpO1xuICByZXR1cm4gZGV0YWlsXG4gICAgPyBgQWxsIG9wZW5haSB0b2tlbnMgZXhjZWVkZWQgcXVvdGEgdGhyZXNob2xkOiAke2RldGFpbH1gXG4gICAgOiBcIkFsbCBvcGVuYWkgdG9rZW5zIGV4Y2VlZGVkIHF1b3RhIHRocmVzaG9sZFwiO1xufVxuXG5mdW5jdGlvbiBpbnB1dEl0ZW1zKHJlcTogR2VuZXJhdGVSZXF1ZXN0KTogT3BlbkFJUmVzcG9uc2VJdGVtW10ge1xuICBjb25zdCBoaXN0b3J5ID0gKHJlcS5jb2xkSGlzdG9yeSA/PyBbXSkgYXMgT3BlbkFJUmVzcG9uc2VJdGVtW107XG4gIGNvbnN0IGNvbnRlbnQ6IE9wZW5BSVJlc3BvbnNlSXRlbVtdID0gcmVxLmNvbGRJbnB1dC5tYXAoKGlucHV0KSA9PiB7XG4gICAgaWYgKGlucHV0LnR5cGUgPT09IFwidGV4dFwiKSByZXR1cm4geyB0eXBlOiBcImlucHV0X3RleHRcIiwgdGV4dDogaW5wdXQudGV4dCB9O1xuICAgIGlmIChpbnB1dC50eXBlID09PSBcImltYWdlXCIpIHJldHVybiB7IHR5cGU6IFwiaW5wdXRfaW1hZ2VcIiwgaW1hZ2VfdXJsOiBpbnB1dC51cmwgfTtcbiAgICBpZiAoaW5wdXQudHlwZSA9PT0gXCJsb2NhbEltYWdlXCIpIHJldHVybiB7IHR5cGU6IFwiaW5wdXRfaW1hZ2VcIiwgaW1hZ2VfdXJsOiBpbnB1dC5wYXRoIH07XG4gICAgcmV0dXJuIHsgdHlwZTogXCJpbnB1dF90ZXh0XCIsIHRleHQ6IGAke2lucHV0Lm5hbWV9OiAke2lucHV0LnBhdGh9YCB9O1xuICB9KTtcbiAgcmV0dXJuIFsuLi5oaXN0b3J5LCB7IHR5cGU6IFwibWVzc2FnZVwiLCByb2xlOiBcInVzZXJcIiwgY29udGVudCB9XTtcbn1cblxuZnVuY3Rpb24gYXNSZWFzb25pbmcocmVxOiBHZW5lcmF0ZVJlcXVlc3QpOiBPcGVuQUlSZXNwb25zZXNPcHRpb25zW1wicmVhc29uaW5nXCJdIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgc3VtbWFyeSA9XG4gICAgcmVxLnJlYXNvbmluZ1N1bW1hcnkgJiYgcmVxLnJlYXNvbmluZ1N1bW1hcnkgIT09IFwibm9uZVwiID8gcmVxLnJlYXNvbmluZ1N1bW1hcnkgOiB1bmRlZmluZWQ7XG4gIGlmICghcmVxLmVmZm9ydCAmJiAhc3VtbWFyeSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgcmV0dXJuIHtcbiAgICAuLi4ocmVxLmVmZm9ydFxuICAgICAgPyB7IGVmZm9ydDogcmVxLmVmZm9ydCBhcyBOb25OdWxsYWJsZTxPcGVuQUlSZXNwb25zZXNPcHRpb25zW1wicmVhc29uaW5nXCJdPltcImVmZm9ydFwiXSB9XG4gICAgICA6IHt9KSxcbiAgICAuLi4oc3VtbWFyeVxuICAgICAgPyB7XG4gICAgICAgICAgc3VtbWFyeTogc3VtbWFyeSBhcyBOb25OdWxsYWJsZTxPcGVuQUlSZXNwb25zZXNPcHRpb25zW1wicmVhc29uaW5nXCJdPltcInN1bW1hcnlcIl0sXG4gICAgICAgIH1cbiAgICAgIDoge30pLFxuICB9O1xufVxuXG5mdW5jdGlvbiByZXF1ZXN0T3B0aW9ucyhyZXE6IEdlbmVyYXRlUmVxdWVzdCk6IE9wZW5BSVJlc3BvbnNlc09wdGlvbnMge1xuICByZXR1cm4ge1xuICAgIG1vZGVsOiByZXEubW9kZWwgPz8gXCJcIixcbiAgICAuLi4ocmVxLnN5c3RlbVByb21wdCA/IHsgaW5zdHJ1Y3Rpb25zOiByZXEuc3lzdGVtUHJvbXB0IH0gOiB7fSksXG4gICAgaGlzdG9yeTogaW5wdXRJdGVtcyhyZXEpLFxuICAgIC4uLihhc1JlYXNvbmluZyhyZXEpID8geyByZWFzb25pbmc6IGFzUmVhc29uaW5nKHJlcSkgfSA6IHt9KSxcbiAgICAuLi4ocmVxLnZlcmJvc2l0eSA/IHsgdmVyYm9zaXR5OiByZXEudmVyYm9zaXR5IGFzIE9wZW5BSVJlc3BvbnNlc09wdGlvbnNbXCJ2ZXJib3NpdHlcIl0gfSA6IHt9KSxcbiAgICAuLi4ocmVxLnNlcnZpY2VUaWVyXG4gICAgICA/IHsgc2VydmljZVRpZXI6IHJlcS5zZXJ2aWNlVGllciA9PT0gXCJmYXN0XCIgPyBcInByaW9yaXR5XCIgOiByZXEuc2VydmljZVRpZXIgfVxuICAgICAgOiB7fSksXG4gICAgLi4uKHJlcS5wcm9tcHRDYWNoZUtleSA/IHsgcHJvbXB0Q2FjaGVLZXk6IHJlcS5wcm9tcHRDYWNoZUtleSB9IDoge30pLFxuICAgIC4uLihyZXEub3V0cHV0U2NoZW1hID8geyBvdXRwdXRTY2hlbWE6IHsgc2NoZW1hOiByZXEub3V0cHV0U2NoZW1hIGFzIEpzb25WYWx1ZSB9IH0gOiB7fSksXG4gICAgLi4uKHJlcS5pbWFnZUdlbmVyYXRpb25cbiAgICAgID8geyBpbWFnZUdlbmVyYXRpb246IHJlcS5pbWFnZUdlbmVyYXRpb25PcHRpb25zID8geyAuLi5yZXEuaW1hZ2VHZW5lcmF0aW9uT3B0aW9ucyB9IDogdHJ1ZSB9XG4gICAgICA6IHt9KSxcbiAgfTtcbn1cblxuLyoqXG4gKiBEaXJlY3QgT3BlbkFJIGRpc3BhdGNoZXIg4oCUIEFudGhyb3BpYyDqs7wg64+Z7J287ZWcIHN0YXRlbGVzcyDsi6Ttlokg66qo6424LlxuICpcbiAqIOyalOyyrSA9IO2GoO2BsCDshKDtg50ocXVvdGEgZ2F0ZSArIHdlaWdodGVkIHJvdW5kLXJvYmluICsgY2FjaGUgYWZmaW5pdHkg7ISg7Zi4KSDihpIgSFRUUFMvV1NcbiAqIOyghOyGoS4gcGVybWl0L+2BkCDqsJnsnYAg64+Z7Iuc7ISxIOyDge2VnOydgCDrkZDsp4Ag7JWK64qU64ukOiDsoITshqHsnYAgZmV0Y2gg7ZWcIOuyiOydtOudvCDroZzsu6wg7J6Q7JuQ7J20XG4gKiDtnazshoztlZjsp4Ag7JWK6rOgLCDsg4HrpZgg7KCc7ZWc7J2AIOuwseyXlOuTnOydmCDsnZHri7UoNDI5IOuTsSnsnbQg7KeE7Iuk7J2064ukLiB3b3JrZXIgcG9vbCDsi5zsoIjsnZhcbiAqIO2BkCDsnZjrr7jroaAoU0VSVkVSX0JVU1ksIO2BkCDtg4DsnoTslYTsm4Mp7J2AIOydtCDsoITtmZjsnLzroZwg7KCc6rGw65CQ64ukLlxuICovXG5leHBvcnQgY2xhc3MgT3BlbkFJRGlzcGF0Y2hlciBpbXBsZW1lbnRzIFByb3ZpZGVyRGlzcGF0Y2hlciB7XG4gIHJlYWRvbmx5IHRva2VuTWV0YWRhdGEgPSBuZXcgTWFwPG51bWJlciwgVG9rZW5NZXRhZGF0YT4oKTtcbiAgcmVhZG9ubHkgdHJhbnNwb3J0S2luZDogT3BlbkFJVHJhbnNwb3J0S2luZDtcbiAgcmVhZG9ubHkgcmF0ZUxpbWl0c0NhY2hlID0gbmV3IE1hcDxudW1iZXIsIE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YSAmIHsgZ2VuZXJhdGlvbjogbnVtYmVyIH0+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcGVuZGluZ1JhdGVMaW1pdHMgPSBuZXcgTWFwPFxuICAgIG51bWJlcixcbiAgICBQcm9taXNlPE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YSAmIHsgZ2VuZXJhdGlvbjogbnVtYmVyIH0+XG4gID4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBjbGllbnRzID0gbmV3IE1hcDxudW1iZXIsIENsaWVudEVudHJ5PigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHJldGlyZWRDbGllbnRzID0gbmV3IFNldDxDbGllbnRFbnRyeT4oKTtcbiAgc3RhdGljIHJlYWRvbmx5IFJBVEVfTElNSVRTX0NBQ0hFX1RUTCA9IDYwXzAwMDtcblxuICBwcml2YXRlIHJlYWRvbmx5IHNlbGVjdG9yID0gbmV3IFNtb290aFdlaWdodGVkUm91bmRSb2JpbigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudEZhY3Rvcnk6IE9wZW5BSURpcmVjdENsaWVudEZhY3Rvcnk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZmV0Y2hJbXBsOiB0eXBlb2YgZmV0Y2g7XG4gIHByaXZhdGUgcmVhZG9ubHkgcXVvdGFCbG9ja2VkID0gbmV3IFNldDxudW1iZXI+KCk7XG4gIHByaXZhdGUgaW5GbGlnaHRDb3VudCA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgdHJhbnNwb3J0S2luZDogT3BlbkFJVHJhbnNwb3J0S2luZCA9IHJlc29sdmVPcGVuQUlUcmFuc3BvcnRLaW5kKCksXG4gICAgZGVwZW5kZW5jaWVzOiBPcGVuQUlEaXNwYXRjaGVyRGVwZW5kZW5jaWVzID0ge30sXG4gICkge1xuICAgIHRoaXMudHJhbnNwb3J0S2luZCA9IHRyYW5zcG9ydEtpbmQ7XG4gICAgdGhpcy5jbGllbnRGYWN0b3J5ID1cbiAgICAgIGRlcGVuZGVuY2llcy5jbGllbnRGYWN0b3J5ID8/ICgob3B0aW9ucykgPT4gbmV3IE9wZW5BSURpcmVjdENsaWVudChvcHRpb25zKSk7XG4gICAgdGhpcy5mZXRjaEltcGwgPSBkZXBlbmRlbmNpZXMuZmV0Y2ggPz8gZmV0Y2g7XG4gIH1cblxuICBhc3luYyBzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IHJvd3MgfSA9IGF3YWl0IFRva2VuTW9kZWwuZmluZE1hbnkoXCJBXCIpO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgIGlmIChyb3cucHJvdmlkZXIgIT09IFwib3BlbmFpXCIpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5zZXRUb2tlbihcbiAgICAgICAgcm93LmlkLFxuICAgICAgICByb3cubmFtZSxcbiAgICAgICAgcm93LmNyZWRlbnRpYWxzIGFzIE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgICAgICByb3cucXVvdGFfdGhyZXNob2xkLFxuICAgICAgICByb3cud2VpZ2h0LFxuICAgICAgICByb3cuYWN0aXZlLFxuICAgICAgKTtcbiAgICB9XG4gICAgbG9nZ2VyLmluZm8oYHN0YXJ0ZWQgZGlyZWN0IE9wZW5BSSBydW50aW1lIHdpdGggJHt0aGlzLnRva2VuTWV0YWRhdGEuc2l6ZX0gdG9rZW5zYCk7XG4gIH1cblxuICBhc3luYyBzdG9wKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAoY29uc3QgeyBjbGllbnQgfSBvZiB0aGlzLmNsaWVudHMudmFsdWVzKCkpIGNsaWVudC5jbG9zZT8uKCk7XG4gICAgdGhpcy5jbGllbnRzLmNsZWFyKCk7XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiB0aGlzLnJldGlyZWRDbGllbnRzKSBlbnRyeS5jbGllbnQuY2xvc2U/LigpO1xuICAgIHRoaXMucmV0aXJlZENsaWVudHMuY2xlYXIoKTtcbiAgICB0aGlzLnRva2VuTWV0YWRhdGEuY2xlYXIoKTtcbiAgICB0aGlzLnJhdGVMaW1pdHNDYWNoZS5jbGVhcigpO1xuICAgIHRoaXMucXVvdGFCbG9ja2VkLmNsZWFyKCk7XG4gICAgdGhpcy5zZWxlY3Rvci5yZXNldFNjb3JlcygpO1xuICB9XG5cbiAgYXN5bmMgb25Ub2tlbkFkZGVkKFxuICAgIGlkOiBudW1iZXIsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscyxcbiAgICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGwsXG4gICAgd2VpZ2h0ID0gMSxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5zZXRUb2tlbihpZCwgbmFtZSwgY3JlZGVudGlhbHMsIHF1b3RhVGhyZXNob2xkLCB3ZWlnaHQsIHRydWUpO1xuICB9XG5cbiAgYXN5bmMgb25Ub2tlblVwZGF0ZWQoXG4gICAgaWQ6IG51bWJlcixcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgIHF1b3RhVGhyZXNob2xkPzogbnVtYmVyIHwgbnVsbCxcbiAgICB3ZWlnaHQgPSAxLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBvbGQgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICB0aGlzLnNldFRva2VuKGlkLCBuYW1lLCBjcmVkZW50aWFscywgcXVvdGFUaHJlc2hvbGQsIHdlaWdodCwgb2xkPy5hY3RpdmUgPz8gdHJ1ZSk7XG4gIH1cblxuICBhc3luYyBvblRva2VuUmVtb3ZlZChpZDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5yZXRpcmVDbGllbnQoaWQpO1xuICAgIHRoaXMudG9rZW5NZXRhZGF0YS5kZWxldGUoaWQpO1xuICAgIHRoaXMuc2VsZWN0b3IucmVtb3ZlVG9rZW4oaWQpO1xuICAgIHRoaXMuaW52YWxpZGF0ZVJhdGVMaW1pdHNDYWNoZShpZCk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWQuZGVsZXRlKGlkKTtcbiAgfVxuXG4gIG9uVG9rZW5EZWFjdGl2YXRlZChpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICBpZiAodG9rZW4pIHRva2VuLmFjdGl2ZSA9IGZhbHNlO1xuICAgIHRoaXMuc2VsZWN0b3IucmVzZXRTY29yZXMoKTtcbiAgfVxuXG4gIG9uVG9rZW5BY3RpdmF0ZWQoaWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHRva2VuID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldChpZCk7XG4gICAgaWYgKHRva2VuKSB0b2tlbi5hY3RpdmUgPSB0cnVlO1xuICAgIHRoaXMuc2VsZWN0b3IucmVzZXRTY29yZXMoKTtcbiAgfVxuXG4gIGFzeW5jIHJlcGxhY2VUb2tlbnMoXG4gICAgcm93czogQXJyYXk8e1xuICAgICAgaWQ6IG51bWJlcjtcbiAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscztcbiAgICAgIHF1b3RhVGhyZXNob2xkPzogbnVtYmVyIHwgbnVsbDtcbiAgICAgIHdlaWdodDogbnVtYmVyO1xuICAgIH0+LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBpZHMgPSBuZXcgU2V0KHJvd3MubWFwKChyKSA9PiByLmlkKSk7XG4gICAgZm9yIChjb25zdCBpZCBvZiB0aGlzLnRva2VuTWV0YWRhdGEua2V5cygpKSBpZiAoIWlkcy5oYXMoaWQpKSBhd2FpdCB0aGlzLm9uVG9rZW5SZW1vdmVkKGlkKTtcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKVxuICAgICAgYXdhaXQgdGhpcy5vblRva2VuVXBkYXRlZChyb3cuaWQsIHJvdy5uYW1lLCByb3cuY3JlZGVudGlhbHMsIHJvdy5xdW90YVRocmVzaG9sZCwgcm93LndlaWdodCk7XG4gIH1cblxuICBhc3luYyBnZW5lcmF0ZShyZXE6IEdlbmVyYXRlUmVxdWVzdCk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5ydW4ocmVxKTtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlU3RyZWFtKHJlcTogR2VuZXJhdGVSZXF1ZXN0LCBjYjogR2VuZXJhdGVTdHJlYW1DYWxsYmFja3MpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAocmVxLmltYWdlR2VuZXJhdGlvbilcbiAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcbiAgICAgICAgXCJnYXRlXCIsXG4gICAgICAgIFwiaW1hZ2UgZ2VuZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIG9uIHRoZSBzdHJlYW1pbmcgcGF0aFwiLFxuICAgICAgKTtcbiAgICB0cnkge1xuICAgICAgY2Iub25Db21wbGV0ZShhd2FpdCB0aGlzLnJ1bihyZXEsIGNiLm9uRGVsdGEpKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY2Iub25FcnJvcihlcnJvciBhcyBFcnJvcik7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvLyBnZW5lcmF0ZS9nZW5lcmF0ZVN0cmVhbSDqs7XthrUg7Iuk7ZaJIOKAlCDthqDtgbAg7ISg7YOd6rO8IGluLWZsaWdodCDsp5Hqs4Trpbwg7ZWcIOqzs+yXkCDrkZTri6QuXG4gIHByaXZhdGUgYXN5bmMgcnVuKFxuICAgIHJlcTogR2VuZXJhdGVSZXF1ZXN0LFxuICAgIG9uRGVsdGE/OiAodGV4dDogc3RyaW5nKSA9PiB2b2lkLFxuICApOiBQcm9taXNlPEdlbmVyYXRlUmVzdWx0PiB7XG4gICAgY29uc3Qgc2lnbmFsID0gYWN0aXZlU2lnbmFsKHJlcS5hYm9ydFNpZ25hbCwgcmVxLnRpbWVvdXRNcyk7XG4gICAgaWYgKHNpZ25hbC5hYm9ydGVkKSB0aHJvdyBhYm9ydEVycm9yKHNpZ25hbCk7XG4gICAgY29uc3Qgc2VsZWN0aW9uID0gYXdhaXQgdGhpcy5zZWxlY3RUb2tlbihyZXEucHJlZmVycmVkVG9rZW5JZCwgc2lnbmFsKTtcbiAgICB0aGlzLmluRmxpZ2h0Q291bnQrKztcbiAgICB0cnkge1xuICAgICAgaWYgKHNpZ25hbC5hYm9ydGVkKSB0aHJvdyBhYm9ydEVycm9yKHNpZ25hbCk7XG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5ydW5EaXJlY3Qoc2VsZWN0aW9uLCB7IC4uLnJlcSwgYWJvcnRTaWduYWw6IHNpZ25hbCB9LCBvbkRlbHRhKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5pbkZsaWdodENvdW50LS07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBydW5EaXJlY3QoXG4gICAgc2VsZWN0aW9uOiBUb2tlblNlbGVjdGlvbixcbiAgICByZXE6IEdlbmVyYXRlUmVxdWVzdCxcbiAgICBvbkRlbHRhPzogKHRleHQ6IHN0cmluZykgPT4gdm9pZCxcbiAgKTogUHJvbWlzZTxHZW5lcmF0ZVJlc3VsdD4ge1xuICAgIGNvbnN0IHN0YXJ0ZWRBdCA9IERhdGUubm93KCk7XG4gICAgbGV0IGZpcnN0RGVsdGFBdDogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgIGxldCB0ZXh0ID0gXCJcIjtcbiAgICBsZXQgdXNhZ2UgPSB7XG4gICAgICB0b3RhbFRva2VuczogMCxcbiAgICAgIGlucHV0VG9rZW5zOiAwLFxuICAgICAgb3V0cHV0VG9rZW5zOiAwLFxuICAgICAgY2FjaGVkSW5wdXRUb2tlbnM6IDAsXG4gICAgICByZWFzb25pbmdPdXRwdXRUb2tlbnM6IDAsXG4gICAgfTtcbiAgICBjb25zdCBpbWFnZXM6IEdlbmVyYXRlZEltYWdlW10gPSBbXTtcbiAgICBsZXQgaW1hZ2VBdHRlbXB0ZWQgPSBmYWxzZTtcbiAgICBsZXQgc2VydmluZ01vZGVsID0gcmVxLm1vZGVsID8/IFwiXCI7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBzZWxlY3Rpb24ubWV0YWRhdGE7XG4gICAgY29uc3QgY2xpZW50RW50cnkgPSB0aGlzLmFjcXVpcmVDbGllbnQoc2VsZWN0aW9uKTtcbiAgICB0cnkge1xuICAgICAgZm9yIGF3YWl0IChjb25zdCBldmVudCBvZiBjbGllbnRFbnRyeS5jbGllbnQucmVzcG9uc2VzKFxuICAgICAgICByZXF1ZXN0T3B0aW9ucyhyZXEpLFxuICAgICAgICByZXEuYWJvcnRTaWduYWwsXG4gICAgICApKSB7XG4gICAgICAgIGlmIChldmVudC50eXBlID09PSBcInRleHQtZGVsdGFcIikge1xuICAgICAgICAgIGZpcnN0RGVsdGFBdCA/Pz0gRGF0ZS5ub3coKTtcbiAgICAgICAgICB0ZXh0ICs9IGV2ZW50LnRleHQ7XG4gICAgICAgICAgb25EZWx0YT8uKGV2ZW50LnRleHQpO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwiaW1hZ2VcIikge1xuICAgICAgICAgIGltYWdlQXR0ZW1wdGVkID0gdHJ1ZTtcbiAgICAgICAgICBpbWFnZXMucHVzaCh7IGRhdGE6IGV2ZW50LmJhc2U2NCwgcmV2aXNlZFByb21wdDogZXZlbnQucmV2aXNlZFByb21wdCA/PyBudWxsIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwib3V0cHV0LWl0ZW1cIiAmJiBldmVudC5pdGVtLnR5cGUgPT09IFwiaW1hZ2VfZ2VuZXJhdGlvbl9jYWxsXCIpIHtcbiAgICAgICAgICBpbWFnZUF0dGVtcHRlZCA9IHRydWU7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gXCJjb21wbGV0ZWRcIiAmJiBldmVudC51c2FnZSkge1xuICAgICAgICAgIHNlcnZpbmdNb2RlbCA9IGV2ZW50Lm1vZGVsID8/IHNlcnZpbmdNb2RlbDtcbiAgICAgICAgICB1c2FnZSA9IHtcbiAgICAgICAgICAgIHRvdGFsVG9rZW5zOiBldmVudC51c2FnZS50b3RhbFRva2VucyxcbiAgICAgICAgICAgIGlucHV0VG9rZW5zOiBldmVudC51c2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgIG91dHB1dFRva2VuczogZXZlbnQudXNhZ2Uub3V0cHV0VG9rZW5zLFxuICAgICAgICAgICAgY2FjaGVkSW5wdXRUb2tlbnM6IGV2ZW50LnVzYWdlLmNhY2hlZElucHV0VG9rZW5zLFxuICAgICAgICAgICAgcmVhc29uaW5nT3V0cHV0VG9rZW5zOiBldmVudC51c2FnZS5yZWFzb25pbmdUb2tlbnMsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSBcImNvbXBsZXRlZFwiKSB7XG4gICAgICAgICAgc2VydmluZ01vZGVsID0gZXZlbnQubW9kZWwgPz8gc2VydmluZ01vZGVsO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwiZXJyb3JcIikge1xuICAgICAgICAgIGlmIChyZXEuaW1hZ2VHZW5lcmF0aW9uKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBldmVudC5lcnJvci5tZXNzYWdlKTtcbiAgICAgICAgICB0aHJvdyBldmVudC5lcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnJlbGVhc2VDbGllbnQoY2xpZW50RW50cnkpO1xuICAgIH1cbiAgICBpZiAocmVxLmltYWdlR2VuZXJhdGlvbiAmJiBpbWFnZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXG4gICAgICAgIGltYWdlQXR0ZW1wdGVkID8gXCJpbmNvbXBsZXRlXCIgOiBcIm5vdF9jYWxsZWRcIixcbiAgICAgICAgaW1hZ2VBdHRlbXB0ZWRcbiAgICAgICAgICA/IFwiaW1hZ2UgZ2VuZXJhdGlvbiBkaWQgbm90IGNvbXBsZXRlXCJcbiAgICAgICAgICA6IFwibW9kZWwgZGlkIG5vdCBjYWxsIGltYWdlIGdlbmVyYXRpb25cIixcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICB0ZXh0LFxuICAgICAgdG9rZW5OYW1lOiBtZXRhZGF0YS5uYW1lLFxuICAgICAgdXNhZ2UsXG4gICAgICBkdXJhdGlvbk1zOiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0LFxuICAgICAgdHRmdE1zOiBmaXJzdERlbHRhQXQgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBmaXJzdERlbHRhQXQgLSBzdGFydGVkQXQsXG4gICAgICBtb2RlbDogc2VydmluZ01vZGVsLFxuICAgICAgdGhyZWFkQ29vcmQ6IHsgd29ya2VySWQ6IHNlbGVjdGlvbi50b2tlbklkLCB0aHJlYWRJZDogcmVxLnByb21wdENhY2hlS2V5ID8/IFwiXCIsIGVwb2NoOiAtMSB9LFxuICAgICAgLi4uKGltYWdlcy5sZW5ndGggPyB7IGltYWdlcyB9IDoge30pLFxuICAgIH07XG4gIH1cblxuICAvKiog7IS464yA6rCAIOuwlOuAkCBjbGllbnQg64qUIOyCrOyaqSDspJHsnbgg7JqU7LKt7J20IOuBneuCnCDrkqTsl5Ag64ur64qU64ukLiAqL1xuICBwcml2YXRlIGFjcXVpcmVDbGllbnQoc2VsZWN0aW9uOiBUb2tlblNlbGVjdGlvbik6IENsaWVudEVudHJ5IHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHNlbGVjdGlvbi5tZXRhZGF0YTtcbiAgICBsZXQgZW50cnkgPSB0aGlzLmNsaWVudHMuZ2V0KHNlbGVjdGlvbi50b2tlbklkKTtcbiAgICBpZiAoZW50cnkgJiYgZW50cnkuZ2VuZXJhdGlvbiAhPT0gbWV0YWRhdGEuZ2VuZXJhdGlvbikge1xuICAgICAgdGhpcy5yZXRpcmVDbGllbnQoc2VsZWN0aW9uLnRva2VuSWQpO1xuICAgICAgZW50cnkgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGlmICghZW50cnkpIHtcbiAgICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xpZW50RmFjdG9yeShcbiAgICAgICAge1xuICAgICAgICAgIGNyZWRlbnRpYWxzOiB7XG4gICAgICAgICAgICBhY2Nlc3NUb2tlbjogbWV0YWRhdGEuY3JlZGVudGlhbHMuYWNjZXNzVG9rZW4sXG4gICAgICAgICAgICBhY2NvdW50SWQ6IG1ldGFkYXRhLmNyZWRlbnRpYWxzLmFjY291bnRJZCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRyYW5zcG9ydEtpbmQ6IHRoaXMudHJhbnNwb3J0S2luZCxcbiAgICAgICAgICBmZXRjaDogdGhpcy5mZXRjaEltcGwsXG4gICAgICAgICAgcmVmcmVzaENyZWRlbnRpYWxzOiBhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZWZyZXNoZWQgPSBhd2FpdCBoYW5kbGVDaGF0Z3B0QXV0aFRva2Vuc1JlZnJlc2goc2VsZWN0aW9uLnRva2VuSWQpO1xuICAgICAgICAgICAgY29uc3QgY3VycmVudCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoc2VsZWN0aW9uLnRva2VuSWQpO1xuICAgICAgICAgICAgaWYgKGN1cnJlbnQpXG4gICAgICAgICAgICAgIGN1cnJlbnQuY3JlZGVudGlhbHMgPSB7XG4gICAgICAgICAgICAgICAgLi4uY3VycmVudC5jcmVkZW50aWFscyxcbiAgICAgICAgICAgICAgICBhY2Nlc3NUb2tlbjogcmVmcmVzaGVkLmFjY2Vzc1Rva2VuLFxuICAgICAgICAgICAgICAgIGFjY291bnRJZDogcmVmcmVzaGVkLmNoYXRncHRBY2NvdW50SWQsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICByZXR1cm4geyBhY2Nlc3NUb2tlbjogcmVmcmVzaGVkLmFjY2Vzc1Rva2VuLCBhY2NvdW50SWQ6IHJlZnJlc2hlZC5jaGF0Z3B0QWNjb3VudElkIH07XG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgc2VsZWN0aW9uLnRva2VuSWQsXG4gICAgICApO1xuICAgICAgZW50cnkgPSB7IGdlbmVyYXRpb246IG1ldGFkYXRhLmdlbmVyYXRpb24sIGNsaWVudCwgaW5GbGlnaHQ6IDAsIHJldGlyZWQ6IGZhbHNlIH07XG4gICAgICB0aGlzLmNsaWVudHMuc2V0KHNlbGVjdGlvbi50b2tlbklkLCBlbnRyeSk7XG4gICAgfVxuICAgIGVudHJ5LmluRmxpZ2h0Kys7XG4gICAgcmV0dXJuIGVudHJ5O1xuICB9XG5cbiAgcHJpdmF0ZSByZWxlYXNlQ2xpZW50KGVudHJ5OiBDbGllbnRFbnRyeSk6IHZvaWQge1xuICAgIGVudHJ5LmluRmxpZ2h0ID0gTWF0aC5tYXgoMCwgZW50cnkuaW5GbGlnaHQgLSAxKTtcbiAgICBpZiAoZW50cnkucmV0aXJlZCAmJiBlbnRyeS5pbkZsaWdodCA9PT0gMCkge1xuICAgICAgdGhpcy5yZXRpcmVkQ2xpZW50cy5kZWxldGUoZW50cnkpO1xuICAgICAgZW50cnkuY2xpZW50LmNsb3NlPy4oKTtcbiAgICB9XG4gIH1cblxuICAvKiogbWFwIOyXkOyEnCDrlrzslrTrgrTqs6AsIOynhO2WiSDspJHsnbgg7JqU7LKt7J20IOyXhuydhCDrlYzrp4wg7KaJ7IucIOuLq+uKlOuLpC4gKi9cbiAgcHJpdmF0ZSByZXRpcmVDbGllbnQodG9rZW5JZDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgZW50cnkgPSB0aGlzLmNsaWVudHMuZ2V0KHRva2VuSWQpO1xuICAgIGlmICghZW50cnkpIHJldHVybjtcbiAgICB0aGlzLmNsaWVudHMuZGVsZXRlKHRva2VuSWQpO1xuICAgIGVudHJ5LnJldGlyZWQgPSB0cnVlO1xuICAgIGlmIChlbnRyeS5pbkZsaWdodCA9PT0gMCkgZW50cnkuY2xpZW50LmNsb3NlPy4oKTtcbiAgICBlbHNlIHRoaXMucmV0aXJlZENsaWVudHMuYWRkKGVudHJ5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDthqDtgbAg7ISg7YOdIOKAlCBxdW90YSBnYXRlIOulvCDthrXqs7ztlZwgYWN0aXZlIO2GoO2BsCDspJHsl5DshJwg6rOg66W464ukLiBjYWNoZSBhZmZpbml0eSDshKDtmLhcbiAgICog7Yag7YGw7J20IGVsaWdpYmxlIO2VmOuptCDqt7gg7YyQ7KCV66eM7Jy866GcIOymieyLnCDqsrDsoJXtlZjqs6Ao7KCE7LK0IHN3ZWVwIOyDneuetSwgd2VpZ2h0ZWQg7IOB7YOcXG4gICAqIOu5hOuzgOqyvSksIOyVhOuLiOuptCDrs5HroKwgcXVvdGEg7YyQ7KCVIO2bhCBzbW9vdGggd2VpZ2h0ZWQgcm91bmQtcm9iaW4uIOuPmeyLnOyEsSDsg4HtlZzsnbRcbiAgICog7JeG7Jy866+A66GcIFwi67mIIOyekOumrFwiIOqwnOuFkOuPhCDsl4bri6Qg4oCUIOyEoO2DnSDsponsi5wg7Iuk7ZaJ7J2064ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzZWxlY3RUb2tlbihcbiAgICBwcmVmZXJyZWRUb2tlbklkOiBudW1iZXIgfCB1bmRlZmluZWQsXG4gICAgc2lnbmFsOiBBYm9ydFNpZ25hbCxcbiAgKTogUHJvbWlzZTxUb2tlblNlbGVjdGlvbj4ge1xuICAgIGlmIChwcmVmZXJyZWRUb2tlbklkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IHByZWZlcnJlZCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQocHJlZmVycmVkVG9rZW5JZCk7XG4gICAgICBpZiAocHJlZmVycmVkPy5hY3RpdmUgJiYgKGF3YWl0IHRoaXMuaXNRdW90YUVsaWdpYmxlKHByZWZlcnJlZFRva2VuSWQsIHByZWZlcnJlZCwgc2lnbmFsKSkpIHtcbiAgICAgICAgcmV0dXJuIHsgdG9rZW5JZDogcHJlZmVycmVkVG9rZW5JZCwgbWV0YWRhdGE6IHByZWZlcnJlZCB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIO2GoO2BsOuzhCBxdW90YSDtjJDsoJXsnYAg7ISc66GcIOuPheumveydtOudvCDrs5HroKzroZwg4oCUIOyngeugrCDrjIDquLDripQg7L2c65OcIOy6kOyLnOyXkOyEnFxuICAgIC8vIO2GoO2BsCDsiJggw5cg7KGw7ZqMIOyngOyXsOunjO2BvCDsmpTssq0g7Iuc7J6R7J2EIOuKpuy2mOuLpC5cbiAgICBjb25zdCBjaGVja3MgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIFsuLi50aGlzLnRva2VuTWV0YWRhdGEuZW50cmllcygpXVxuICAgICAgICAuZmlsdGVyKChbLCB0b2tlbl0pID0+IHRva2VuLmFjdGl2ZSlcbiAgICAgICAgLm1hcChhc3luYyAoW2lkLCB0b2tlbl0pID0+ICh7XG4gICAgICAgICAgaWQsXG4gICAgICAgICAgdG9rZW4sXG4gICAgICAgICAgZWxpZ2libGU6IGF3YWl0IHRoaXMuaXNRdW90YUVsaWdpYmxlKGlkLCB0b2tlbiwgc2lnbmFsKSxcbiAgICAgICAgfSkpLFxuICAgICk7XG4gICAgY29uc3QgZWxpZ2libGUgPSBuZXcgU2V0KGNoZWNrcy5maWx0ZXIoKGMpID0+IGMuZWxpZ2libGUpLm1hcCgoYykgPT4gYy5pZCkpO1xuICAgIGlmIChlbGlnaWJsZS5zaXplID09PSAwKSB7XG4gICAgICBjb25zdCBvdmVyID0gY2hlY2tzXG4gICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgKGMpID0+XG4gICAgICAgICAgICAhYy5lbGlnaWJsZSAmJiBjLnRva2VuLnF1b3RhVGhyZXNob2xkICE9PSBudWxsICYmIGMudG9rZW4ucXVvdGFUaHJlc2hvbGQgIT09IHVuZGVmaW5lZCxcbiAgICAgICAgKVxuICAgICAgICAubWFwKChjKSA9PiAoeyBuYW1lOiBjLnRva2VuLm5hbWUsIHRocmVzaG9sZDogYy50b2tlbi5xdW90YVRocmVzaG9sZCBhcyBudW1iZXIgfSkpO1xuICAgICAgaWYgKG92ZXIubGVuZ3RoKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKFwicXVvdGFfdGhyZXNob2xkIGdhdGU6IGFsbF9leGNlZWRlZFwiLCB7XG4gICAgICAgICAgcHJvdmlkZXI6IFwib3BlbmFpXCIsXG4gICAgICAgICAgb3ZlclRocmVzaG9sZFRva2Vuczogb3ZlcixcbiAgICAgICAgfSk7XG4gICAgICAgIHRocm93IG5ldyBRdW90YVRocmVzaG9sZEV4Y2VlZGVkRXJyb3IocXVvdGFNZXNzYWdlKG92ZXIpKTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5PX09QRU5BSV9XT1JLRVJTXCIpO1xuICAgIH1cbiAgICBjb25zdCBzZWxlY3RlZCA9IHRoaXMuc2VsZWN0b3Iuc2VsZWN0KGVsaWdpYmxlKTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHNlbGVjdGVkICE9PSBudWxsID8gdGhpcy50b2tlbk1ldGFkYXRhLmdldChzZWxlY3RlZCkgOiB1bmRlZmluZWQ7XG4gICAgaWYgKHNlbGVjdGVkID09PSBudWxsIHx8ICFtZXRhZGF0YSkgdGhyb3cgbmV3IEVycm9yKFwiTk9fT1BFTkFJX1dPUktFUlNcIik7XG4gICAgcmV0dXJuIHsgdG9rZW5JZDogc2VsZWN0ZWQsIG1ldGFkYXRhIH07XG4gIH1cblxuICBwcml2YXRlIHNldFRva2VuKFxuICAgIGlkOiBudW1iZXIsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscyxcbiAgICBxdW90YVRocmVzaG9sZDogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgICB3ZWlnaHQ6IG51bWJlcixcbiAgICBhY3RpdmU6IGJvb2xlYW4sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IG9sZCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoaWQpO1xuICAgIGlmIChvbGQpIHtcbiAgICAgIE9iamVjdC5hc3NpZ24ob2xkLCB7XG4gICAgICAgIG5hbWUsXG4gICAgICAgIGNyZWRlbnRpYWxzLFxuICAgICAgICBxdW90YVRocmVzaG9sZCxcbiAgICAgICAgd2VpZ2h0LFxuICAgICAgICBhY3RpdmUsXG4gICAgICAgIGdlbmVyYXRpb246IG9sZC5nZW5lcmF0aW9uICsgMSxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnRva2VuTWV0YWRhdGEuc2V0KGlkLCB7XG4gICAgICAgIG5hbWUsXG4gICAgICAgIGNyZWRlbnRpYWxzLFxuICAgICAgICBxdW90YVRocmVzaG9sZCxcbiAgICAgICAgd2VpZ2h0LFxuICAgICAgICBhY3RpdmUsXG4gICAgICAgIGdlbmVyYXRpb246IDEsXG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5zZWxlY3Rvci5zZXRUb2tlbihpZCwgd2VpZ2h0KTtcbiAgICB0aGlzLmludmFsaWRhdGVSYXRlTGltaXRzQ2FjaGUoaWQpO1xuICAgIHRoaXMucXVvdGFCbG9ja2VkLmRlbGV0ZShpZCk7XG4gIH1cblxuICBhc3luYyBnZXRSYXRlTGltaXRzQnlUb2tlbklkKFxuICAgIHRva2VuSWQ6IG51bWJlcixcbiAgICBzaWduYWw/OiBBYm9ydFNpZ25hbCxcbiAgKTogUHJvbWlzZTxPcGVuQUlSYXRlTGltaXRzV2l0aE1ldGE+IHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCk7XG4gICAgaWYgKCF0b2tlbikgdGhyb3cgbmV3IEVycm9yKGBvcGVuYWkgdG9rZW4gJHt0b2tlbklkfSBub3QgZm91bmRgKTtcbiAgICBjb25zdCBjYWNoZWQgPSB0aGlzLnJhdGVMaW1pdHNDYWNoZS5nZXQodG9rZW5JZCk7XG4gICAgaWYgKFxuICAgICAgY2FjaGVkICYmXG4gICAgICBjYWNoZWQuZ2VuZXJhdGlvbiA9PT0gdG9rZW4uZ2VuZXJhdGlvbiAmJlxuICAgICAgRGF0ZS5ub3coKSAtIGNhY2hlZC5jYWNoZWRBdCA8IE9wZW5BSURpc3BhdGNoZXIuUkFURV9MSU1JVFNfQ0FDSEVfVFRMXG4gICAgKVxuICAgICAgcmV0dXJuIGNhY2hlZDtcblxuICAgIC8vIHNpbmdsZS1mbGlnaHQ6IOuPmeyLnOyEsSDsg4HtlZzsnbQg7JeG7Ja07KeEIOuSpOuhnCBUVEwg66eM66OMIOyInOqwhCDrj5nsi5wg7JqU7LKtIOyImOunjO2BvCDqsJnsnYBcbiAgICAvLyDsobDtmozqsIAg66qw66a0IOyImCDsnojri6Qg4oCUIOynhO2WiSDspJHsnbggZmV0Y2gg66W8IOqzteycoO2VnOuLpC4g7LWc7LSIIO2YuOy2nOyekOydmCBhYm9ydCDroZxcbiAgICAvLyDqs7XsnKAg7KGw7ZqM6rCAIOyLpO2MqO2VtOuPhCDshozruYTsspgoaXNRdW90YUVsaWdpYmxlKeqwgCBmYWlsLW9wZW4g7Jy866GcIOyymOumrO2VnOuLpC5cbiAgICBjb25zdCBwZW5kaW5nID0gdGhpcy5wZW5kaW5nUmF0ZUxpbWl0cy5nZXQodG9rZW5JZCk7XG4gICAgaWYgKHBlbmRpbmcpIHJldHVybiBwZW5kaW5nO1xuICAgIGNvbnN0IGZldGNoUHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZWFkT3BlbkFJUXVvdGFVc2FnZSh7XG4gICAgICAgIGNyZWRlbnRpYWxzOiB0b2tlbi5jcmVkZW50aWFscyxcbiAgICAgICAgZmV0Y2g6IHRoaXMuZmV0Y2hJbXBsLFxuICAgICAgICAuLi4oc2lnbmFsID8geyBzaWduYWwgfSA6IHt9KSxcbiAgICAgIH0pO1xuICAgICAgaWYgKHJlc3VsdC5raW5kID09PSBcImxvb2t1cF9mYWlsZWRcIikgdGhyb3cgbmV3IEVycm9yKHJlc3VsdC5yZWFzb24pO1xuICAgICAgaWYgKCFyZXN1bHQucmF3KSB0aHJvdyBuZXcgRXJyb3IoXCJPcGVuQUkgcXVvdGEgcmVzcG9uc2UgbWlzc2luZyByYXcgcmF0ZSBsaW1pdHNcIik7XG4gICAgICBjb25zdCBlbnRyeSA9IHsgZGF0YTogcmVzdWx0LnJhdywgY2FjaGVkQXQ6IERhdGUubm93KCksIGdlbmVyYXRpb246IHRva2VuLmdlbmVyYXRpb24gfTtcbiAgICAgIGlmICh0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpID09PSB0b2tlbikgdGhpcy5yYXRlTGltaXRzQ2FjaGUuc2V0KHRva2VuSWQsIGVudHJ5KTtcbiAgICAgIHJldHVybiBlbnRyeTtcbiAgICB9KSgpLmZpbmFsbHkoKCkgPT4gdGhpcy5wZW5kaW5nUmF0ZUxpbWl0cy5kZWxldGUodG9rZW5JZCkpO1xuICAgIHRoaXMucGVuZGluZ1JhdGVMaW1pdHMuc2V0KHRva2VuSWQsIGZldGNoUHJvbWlzZSk7XG4gICAgcmV0dXJuIGZldGNoUHJvbWlzZTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaXNRdW90YUVsaWdpYmxlKFxuICAgIGlkOiBudW1iZXIsXG4gICAgdG9rZW46IFRva2VuTWV0YWRhdGEsXG4gICAgc2lnbmFsPzogQWJvcnRTaWduYWwsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICh0b2tlbi5xdW90YVRocmVzaG9sZCA9PT0gbnVsbCB8fCB0b2tlbi5xdW90YVRocmVzaG9sZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdHJ1ZTtcbiAgICBjb25zdCBnZW5lcmF0aW9uID0gdG9rZW4uZ2VuZXJhdGlvbjtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZWFkT3BlbkFJUXVvdGFVc2FnZShhc3luYyAoKSA9PiB0aGlzLmdldFJhdGVMaW1pdHNCeVRva2VuSWQoaWQsIHNpZ25hbCkpO1xuICAgIGlmICh0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKSAhPT0gdG9rZW4gfHwgdG9rZW4uZ2VuZXJhdGlvbiAhPT0gZ2VuZXJhdGlvbikgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChyZXN1bHQua2luZCA9PT0gXCJsb29rdXBfZmFpbGVkXCIpIHtcbiAgICAgIHRoaXMucXVvdGFCbG9ja2VkLmRlbGV0ZShpZCk7XG4gICAgICBsb2dnZXIud2FybihcInF1b3RhX3RocmVzaG9sZCBnYXRlOiBsb29rdXBfZmFpbF9vcGVuXCIsIHtcbiAgICAgICAgdG9rZW5JZDogaWQsXG4gICAgICAgIHRva2VuTmFtZTogdG9rZW4ubmFtZSxcbiAgICAgICAgbG9va3VwUmVhc29uOiByZXN1bHQucmVhc29uLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHJlc3VsdC51dGlsaXphdGlvblBjdCA+PSB0b2tlbi5xdW90YVRocmVzaG9sZCkge1xuICAgICAgaWYgKCF0aGlzLnF1b3RhQmxvY2tlZC5oYXMoaWQpKVxuICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICBgcXVvdGFfdGhyZXNob2xkIGdhdGU6IG92ZXJfdGhyZXNob2xkICR7dG9rZW4ubmFtZX1bJHtpZH1dICgke3Jlc3VsdC51dGlsaXphdGlvblBjdH0lID49ICR7dG9rZW4ucXVvdGFUaHJlc2hvbGR9JSlgLFxuICAgICAgICApO1xuICAgICAgdGhpcy5xdW90YUJsb2NrZWQuYWRkKGlkKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHRoaXMucXVvdGFCbG9ja2VkLmRlbGV0ZShpZCkpXG4gICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgYHF1b3RhX3RocmVzaG9sZCBnYXRlOiByZWNvdmVyZWQgJHt0b2tlbi5uYW1lfVske2lkfV0gKCR7cmVzdWx0LnV0aWxpemF0aW9uUGN0fSUgPCAke3Rva2VuLnF1b3RhVGhyZXNob2xkfSUpYCxcbiAgICAgICk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBwcml2YXRlIGludmFsaWRhdGVSYXRlTGltaXRzQ2FjaGUoaWQ6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMucmF0ZUxpbWl0c0NhY2hlLmRlbGV0ZShpZCk7XG4gIH1cblxuICBnZXQgdG9rZW5Db3VudCgpOiBudW1iZXIge1xuICAgIHJldHVybiBbLi4udGhpcy50b2tlbk1ldGFkYXRhLnZhbHVlcygpXS5maWx0ZXIoKHQpID0+IHQuYWN0aXZlKS5sZW5ndGg7XG4gIH1cbiAgZ2V0IGluRmxpZ2h0KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuaW5GbGlnaHRDb3VudDtcbiAgfVxuXG4gIC8qKlxuICAgKiDthqDtgbDrs4Qg7L+87YSwIOyKpOuDheyDtyDigJQg7Iug7ISg7ZWcKHJhdGUgbGltaXRzIFRUTCDrgrQpIOy6kOyLnOunjCDsnb3qs6Ag7KCI64yAIGZldGNoIO2VmOyngCDslYrripTri6QuXG4gICAqIG1vbml0IHZpdGFscyDripQg66Gc6re4IO2PtOungeyXkCDtjrjsirntlZjripQg6rCS7J206528IOyXrOq4sOyEnCDrhKTtirjsm4ztgazrpbwg7YOA66m0IOyViCDrkJzri6QuXG4gICAqIHRocmVzaG9sZCDrr7jshKTsoJUg7Yag7YGw7J2AIOy/vO2EsCDtjJDsoJXsnYQg64+M7KeAIOyViuyVhCB1c2VkUGVyY2VudCDqsIAgbnVsbCDroZwg64Ko7J2EIOyImCDsnojri6QuXG4gICAqL1xuICBnZXQgcXVvdGFCeVRva2VuKCk6IEFycmF5PHtcbiAgICBuYW1lOiBzdHJpbmc7XG4gICAgdXNlZFBlcmNlbnQ6IG51bWJlciB8IG51bGw7XG4gICAgdGhyZXNob2xkOiBudW1iZXIgfCBudWxsO1xuICAgIGJsb2NrZWQ6IGJvb2xlYW47XG4gICAgcmVzZXRzQXQ6IG51bWJlciB8IG51bGw7XG4gIH0+IHtcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgIHJldHVybiBbLi4udGhpcy50b2tlbk1ldGFkYXRhLmVudHJpZXMoKV1cbiAgICAgIC5tYXAoKFtpZCwgdF0pID0+IHtcbiAgICAgICAgY29uc3QgY2FjaGVkID0gdGhpcy5yYXRlTGltaXRzQ2FjaGUuZ2V0KGlkKTtcbiAgICAgICAgY29uc3QgZnJlc2ggPVxuICAgICAgICAgIGNhY2hlZCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgY2FjaGVkLmdlbmVyYXRpb24gPT09IHQuZ2VuZXJhdGlvbiAmJlxuICAgICAgICAgIG5vdyAtIGNhY2hlZC5jYWNoZWRBdCA8IE9wZW5BSURpc3BhdGNoZXIuUkFURV9MSU1JVFNfQ0FDSEVfVFRMO1xuICAgICAgICBjb25zdCBwcmltYXJ5ID0gZnJlc2ggPyBjYWNoZWQuZGF0YS5yYXRlTGltaXRzPy5wcmltYXJ5IDogdW5kZWZpbmVkO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG5hbWU6IHQubmFtZSxcbiAgICAgICAgICB1c2VkUGVyY2VudDogcHJpbWFyeT8udXNlZFBlcmNlbnQgPz8gbnVsbCxcbiAgICAgICAgICB0aHJlc2hvbGQ6IHQucXVvdGFUaHJlc2hvbGQgPz8gbnVsbCxcbiAgICAgICAgICBibG9ja2VkOiB0aGlzLnF1b3RhQmxvY2tlZC5oYXMoaWQpLFxuICAgICAgICAgIC8vIHdoYW0g7J2YIHJlc2V0c0F0IOydgCB1bml4IOy0iCDri6jsnITri6QocWdyaWQuZnJhbWUgdW5peFNlY29uZHNUb0lzbyDsmYAg64+Z7J28IOq3nOyVvSkuXG4gICAgICAgICAgLy8g7IaM67mE7LKY6rCAIOuLqOychOulvCDstpTsuKHtlZjsp4Ag7JWK64+E66GdIOyXrOq4sOyEnCBtcyBlcG9jaCDsnLzroZwg7KCV6rec7ZmU7ZWc64ukLlxuICAgICAgICAgIHJlc2V0c0F0OlxuICAgICAgICAgICAgcHJpbWFyeT8ucmVzZXRzQXQgIT09IG51bGwgJiYgcHJpbWFyeT8ucmVzZXRzQXQgIT09IHVuZGVmaW5lZFxuICAgICAgICAgICAgICA/IHByaW1hcnkucmVzZXRzQXQgKiAxMDAwXG4gICAgICAgICAgICAgIDogbnVsbCxcbiAgICAgICAgfTtcbiAgICAgIH0pXG4gICAgICAudG9Tb3J0ZWQoKGEsIGIpID0+IGEubmFtZS5sb2NhbGVDb21wYXJlKGIubmFtZSkpO1xuICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQXVCQSxNQUFNLFNBQVMsVUFBVSxDQUFDLFNBQVMsbUJBQW1CLENBQUM7QUFHdkQsTUFBTSw2QkFBNkI7QUFJ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