@cartanova/qgrid-cli 2.10.10 → 2.11.1

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 (302) hide show
  1. package/bundle/dist/_virtual/_rolldown/runtime.js +1 -10
  2. package/bundle/dist/application/monit/log-buffer.js +12 -6
  3. package/bundle/dist/application/monit/monit.frame.js +11 -3
  4. package/bundle/dist/application/monit/monit.types.js +1 -1
  5. package/bundle/dist/application/qgrid/conv-routing.js +9 -6
  6. package/bundle/dist/application/qgrid/expired-token-reminder.js +2 -2
  7. package/bundle/dist/application/qgrid/oauth.js +31 -4
  8. package/bundle/dist/application/qgrid/qgrid-image-generation.js +1 -1
  9. package/bundle/dist/application/qgrid/qgrid-response-format.js +21 -19
  10. package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +40 -33
  11. package/bundle/dist/application/qgrid/qgrid.dispatcher.js +128 -93
  12. package/bundle/dist/application/qgrid/qgrid.frame.js +930 -49
  13. package/bundle/dist/application/qgrid/qgrid.types.js +212 -5
  14. package/bundle/dist/application/qgrid/schema-prompt.js +75 -48
  15. package/bundle/dist/application/qgrid/slack-user-map.js +1 -1
  16. package/bundle/dist/application/qgrid/token-death.js +1 -1
  17. package/bundle/dist/application/qgrid/token-subscriber.js +83 -30
  18. package/bundle/dist/application/qgrid/token-trigger-setup.js +1 -1
  19. package/bundle/dist/application/qgrid/token-window-keepalive.js +8 -6
  20. package/bundle/dist/application/qgrid/tool-emulation-schema.js +13 -13
  21. package/bundle/dist/application/qgrid/tool-emulation.js +19 -15
  22. package/bundle/dist/application/request-log/json-schema-type-text.js +29 -12
  23. package/bundle/dist/application/request-log/request-log.model.js +83 -70
  24. package/bundle/dist/application/request-log/request-log.types.js +1 -1
  25. package/bundle/dist/application/request-log/zod-code-format.js +1 -1
  26. package/bundle/dist/application/request-log-step/request-log-step.model.js +1 -1
  27. package/bundle/dist/application/request-log-step/request-log-step.types.js +1 -1
  28. package/bundle/dist/application/setting/setting.constant.js +1 -1
  29. package/bundle/dist/application/setting/setting.model.js +2 -2
  30. package/bundle/dist/application/setting/setting.store.js +2 -2
  31. package/bundle/dist/application/setting/setting.types.js +1 -1
  32. package/bundle/dist/application/sonamu.generated.js +32 -16
  33. package/bundle/dist/application/sonamu.generated.sso.js +1 -1
  34. package/bundle/dist/application/token/token.model.js +26 -9
  35. package/bundle/dist/application/token/token.types.js +20 -3
  36. package/bundle/dist/i18n/en.js +15 -1
  37. package/bundle/dist/i18n/ko.js +15 -1
  38. package/bundle/dist/i18n/sd.generated.js +1 -1
  39. package/bundle/dist/migrations/20260807133553_manual__backfill_request_log_cost.js +8 -6
  40. package/bundle/dist/server-bootstrap.js +4 -2
  41. package/bundle/dist/server-error-handler.js +1 -1
  42. package/bundle/dist/sonamu.config.js +37 -8
  43. package/bundle/dist/startup-migrations.js +17 -7
  44. package/bundle/dist/testing/global.js +1 -1
  45. package/bundle/dist/testing/schema-bench.js +0 -0
  46. package/bundle/dist/testing/test-database-name.js +1 -1
  47. package/bundle/dist/utils/providers/anthropic/anthropic-constants.js +1 -1
  48. package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +11 -5
  49. package/bundle/dist/utils/providers/anthropic/anthropic-quota.js +4 -4
  50. package/bundle/dist/utils/providers/anthropic/anthropic-thinking.js +1 -1
  51. package/bundle/dist/utils/providers/anthropic/claude-session.js +20 -19
  52. package/bundle/dist/utils/providers/anthropic/fence-strip.js +1 -1
  53. package/bundle/dist/utils/providers/anthropic/stream-json-adapter.js +49 -23
  54. package/bundle/dist/utils/providers/common/credentials.js +5 -1
  55. package/bundle/dist/utils/providers/common/effort.js +3 -3
  56. package/bundle/dist/utils/providers/common/model-cost.js +69 -14
  57. package/bundle/dist/utils/providers/common/provider-types.js +29 -1
  58. package/bundle/dist/utils/providers/common/schema-validation.js +78 -40
  59. package/bundle/dist/utils/providers/common/smooth-weighted-round-robin.js +1 -1
  60. package/bundle/dist/utils/providers/common/strictifier.js +62 -43
  61. package/bundle/dist/utils/providers/common/thinking.js +3 -2
  62. package/bundle/dist/utils/providers/common/ttft.js +1 -1
  63. package/bundle/dist/utils/providers/grok/grok-backend-protocol.js +427 -0
  64. package/bundle/dist/utils/providers/grok/grok-constants.js +55 -0
  65. package/bundle/dist/utils/providers/grok/grok-direct-client.js +196 -0
  66. package/bundle/dist/utils/providers/grok/grok-dispatcher.js +1313 -0
  67. package/bundle/dist/utils/providers/grok/grok-headers.js +118 -0
  68. package/bundle/dist/utils/providers/grok/grok-media-client.js +420 -0
  69. package/bundle/dist/utils/providers/grok/grok-models.js +114 -0
  70. package/bundle/dist/utils/providers/grok/grok-oauth.js +455 -0
  71. package/bundle/dist/utils/providers/grok/grok-quota.js +119 -0
  72. package/bundle/dist/utils/providers/grok/grok-refresh.js +192 -0
  73. package/bundle/dist/utils/providers/grok/grok-types.js +186 -0
  74. package/bundle/dist/utils/providers/grok/grok-voice-client.js +199 -0
  75. package/bundle/dist/utils/providers/grok/index.js +11 -0
  76. package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +111 -83
  77. package/bundle/dist/utils/providers/openai/openai-callback-relay.js +3 -2
  78. package/bundle/dist/utils/providers/openai/openai-constants.js +1 -1
  79. package/bundle/dist/utils/providers/openai/openai-direct-client.js +23 -7
  80. package/bundle/dist/utils/providers/openai/openai-dispatcher.js +143 -106
  81. package/bundle/dist/utils/providers/openai/openai-image-generation.js +48 -33
  82. package/bundle/dist/utils/providers/openai/openai-oauth.js +28 -13
  83. package/bundle/dist/utils/providers/openai/openai-quota.js +38 -27
  84. package/bundle/dist/utils/providers/openai/openai-refresh.js +17 -9
  85. package/bundle/dist/utils/providers/openai/openai-sse.js +1 -1
  86. package/bundle/dist/utils/providers/openai/openai-transport-config.js +1 -1
  87. package/bundle/dist/utils/quiet-hours.js +1 -1
  88. package/bundle/dist/utils/slack-notify.js +14 -8
  89. package/bundle/dist/utils/subset-loaders.js +4 -5
  90. package/bundle/src/application/monit/log-buffer.ts +23 -9
  91. package/bundle/src/application/monit/monit.frame.ts +22 -5
  92. package/bundle/src/application/monit/monit.types.ts +6 -0
  93. package/bundle/src/application/qgrid/conv-routing.test.ts +76 -4
  94. package/bundle/src/application/qgrid/conv-routing.ts +35 -9
  95. package/bundle/src/application/qgrid/expired-token-reminder.ts +9 -1
  96. package/bundle/src/application/qgrid/oauth.ts +51 -15
  97. package/bundle/src/application/qgrid/qgrid-image-generation.ts +9 -0
  98. package/bundle/src/application/qgrid/qgrid-response-format.ts +50 -25
  99. package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +19 -0
  100. package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +84 -40
  101. package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +97 -0
  102. package/bundle/src/application/qgrid/qgrid.dispatcher.ts +274 -126
  103. package/bundle/src/application/qgrid/qgrid.frame.test.ts +1013 -3
  104. package/bundle/src/application/qgrid/qgrid.frame.ts +1415 -60
  105. package/bundle/src/application/qgrid/qgrid.types.ts +335 -0
  106. package/bundle/src/application/qgrid/schema-prompt.ts +105 -41
  107. package/bundle/src/application/qgrid/slack-user-map.ts +5 -0
  108. package/bundle/src/application/qgrid/token-death.ts +4 -0
  109. package/bundle/src/application/qgrid/token-subscriber.test.ts +21 -19
  110. package/bundle/src/application/qgrid/token-subscriber.ts +186 -53
  111. package/bundle/src/application/qgrid/token-trigger-setup.ts +2 -0
  112. package/bundle/src/application/qgrid/token-window-keepalive.ts +49 -6
  113. package/bundle/src/application/qgrid/tool-emulation-schema.ts +33 -29
  114. package/bundle/src/application/qgrid/tool-emulation.ts +52 -27
  115. package/bundle/src/application/request-log/json-schema-type-text.test.ts +5 -5
  116. package/bundle/src/application/request-log/json-schema-type-text.ts +81 -26
  117. package/bundle/src/application/request-log/request-log.model.test.ts +111 -4
  118. package/bundle/src/application/request-log/request-log.model.ts +277 -146
  119. package/bundle/src/application/request-log/request-log.types.ts +6 -0
  120. package/bundle/src/application/request-log/zod-code-format.ts +11 -0
  121. package/bundle/src/application/request-log-step/request-log-step.model.ts +1 -0
  122. package/bundle/src/application/request-log-step/request-log-step.types.ts +2 -0
  123. package/bundle/src/application/setting/setting.constant.ts +9 -0
  124. package/bundle/src/application/setting/setting.model.ts +12 -2
  125. package/bundle/src/application/setting/setting.store.ts +5 -1
  126. package/bundle/src/application/setting/setting.types.ts +8 -0
  127. package/bundle/src/application/sonamu.generated.http +133 -0
  128. package/bundle/src/application/sonamu.generated.sso.ts +2 -0
  129. package/bundle/src/application/sonamu.generated.ts +15 -0
  130. package/bundle/src/application/token/token.identity.test.ts +20 -0
  131. package/bundle/src/application/token/token.model.ts +66 -7
  132. package/bundle/src/application/token/token.types.ts +24 -1
  133. package/bundle/src/i18n/en.ts +19 -0
  134. package/bundle/src/i18n/ko.ts +21 -0
  135. package/bundle/src/i18n/sd.generated.ts +23 -2
  136. package/bundle/src/migrations/20260807133553_manual__backfill_request_log_cost.ts +16 -8
  137. package/bundle/src/server-bootstrap.ts +4 -2
  138. package/bundle/src/server-error-handler.ts +1 -0
  139. package/bundle/src/sonamu.config.ts +69 -7
  140. package/bundle/src/startup-migrations.ts +27 -9
  141. package/bundle/src/testing/global.ts +20 -0
  142. package/bundle/src/testing/schema-bench.ts +105 -30
  143. package/bundle/src/testing/test-database-name.ts +2 -0
  144. package/bundle/src/utils/providers/anthropic/anthropic-constants.ts +8 -0
  145. package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +41 -6
  146. package/bundle/src/utils/providers/anthropic/anthropic-quota.ts +7 -3
  147. package/bundle/src/utils/providers/anthropic/anthropic-thinking.ts +6 -0
  148. package/bundle/src/utils/providers/anthropic/claude-session.ts +58 -24
  149. package/bundle/src/utils/providers/anthropic/fence-strip.ts +11 -0
  150. package/bundle/src/utils/providers/anthropic/stream-json-adapter.ts +110 -45
  151. package/bundle/src/utils/providers/common/credentials.ts +8 -0
  152. package/bundle/src/utils/providers/common/effort.ts +9 -2
  153. package/bundle/src/utils/providers/common/model-cost.test.ts +48 -1
  154. package/bundle/src/utils/providers/common/model-cost.ts +259 -158
  155. package/bundle/src/utils/providers/common/provider-dispatcher.ts +98 -2
  156. package/bundle/src/utils/providers/common/provider-types.ts +46 -3
  157. package/bundle/src/utils/providers/common/schema-validation.test.ts +5 -1
  158. package/bundle/src/utils/providers/common/schema-validation.ts +124 -56
  159. package/bundle/src/utils/providers/common/smooth-weighted-round-robin.ts +4 -0
  160. package/bundle/src/utils/providers/common/strictifier.ts +185 -59
  161. package/bundle/src/utils/providers/common/thinking.ts +2 -2
  162. package/bundle/src/utils/providers/common/ttft.ts +4 -2
  163. package/bundle/src/utils/providers/grok/__fixtures__/golden-responses-1.0.60.json +164 -0
  164. package/bundle/src/utils/providers/grok/grok-backend-protocol.test.ts +325 -0
  165. package/bundle/src/utils/providers/grok/grok-backend-protocol.ts +721 -0
  166. package/bundle/src/utils/providers/grok/grok-constants.ts +105 -0
  167. package/bundle/src/utils/providers/grok/grok-direct-client.test.ts +179 -0
  168. package/bundle/src/utils/providers/grok/grok-direct-client.ts +313 -0
  169. package/bundle/src/utils/providers/grok/grok-dispatcher.test.ts +1395 -0
  170. package/bundle/src/utils/providers/grok/grok-dispatcher.ts +2105 -0
  171. package/bundle/src/utils/providers/grok/grok-headers.test.ts +149 -0
  172. package/bundle/src/utils/providers/grok/grok-headers.ts +199 -0
  173. package/bundle/src/utils/providers/grok/grok-media-client.test.ts +446 -0
  174. package/bundle/src/utils/providers/grok/grok-media-client.ts +703 -0
  175. package/bundle/src/utils/providers/grok/grok-models.test.ts +96 -0
  176. package/bundle/src/utils/providers/grok/grok-models.ts +161 -0
  177. package/bundle/src/utils/providers/grok/grok-oauth.test.ts +406 -0
  178. package/bundle/src/utils/providers/grok/grok-oauth.ts +771 -0
  179. package/bundle/src/utils/providers/grok/grok-quota.test.ts +142 -0
  180. package/bundle/src/utils/providers/grok/grok-quota.ts +198 -0
  181. package/bundle/src/utils/providers/grok/grok-refresh.test.ts +239 -0
  182. package/bundle/src/utils/providers/grok/grok-refresh.ts +325 -0
  183. package/bundle/src/utils/providers/grok/grok-types.test.ts +252 -0
  184. package/bundle/src/utils/providers/grok/grok-types.ts +374 -0
  185. package/bundle/src/utils/providers/grok/grok-voice-client.test.ts +321 -0
  186. package/bundle/src/utils/providers/grok/grok-voice-client.ts +284 -0
  187. package/bundle/src/utils/providers/grok/index.ts +20 -0
  188. package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +221 -137
  189. package/bundle/src/utils/providers/openai/openai-callback-relay.ts +12 -1
  190. package/bundle/src/utils/providers/openai/openai-constants.ts +2 -0
  191. package/bundle/src/utils/providers/openai/openai-direct-client.ts +111 -21
  192. package/bundle/src/utils/providers/openai/openai-dispatcher.ts +322 -169
  193. package/bundle/src/utils/providers/openai/openai-image-generation.ts +116 -36
  194. package/bundle/src/utils/providers/openai/openai-oauth.ts +48 -20
  195. package/bundle/src/utils/providers/openai/openai-quota.ts +77 -46
  196. package/bundle/src/utils/providers/openai/openai-refresh.ts +42 -18
  197. package/bundle/src/utils/providers/openai/openai-sse.ts +27 -3
  198. package/bundle/src/utils/providers/openai/openai-transport-config.ts +2 -0
  199. package/bundle/src/utils/quiet-hours.ts +12 -1
  200. package/bundle/src/utils/slack-notify.ts +44 -13
  201. package/bundle/src/utils/subset-loaders.ts +7 -7
  202. package/bundle/web-dist/client/assets/clsx-5XM_pHvN.js +1 -0
  203. package/bundle/web-dist/client/assets/index-Be2qCZmI.css +1 -0
  204. package/bundle/web-dist/client/assets/index-C96h3feE.js +32 -0
  205. package/bundle/web-dist/client/assets/logs-DBM6U0QD.js +1 -0
  206. package/bundle/web-dist/client/assets/monit-BBjXa7vB.js +1 -0
  207. package/bundle/web-dist/client/assets/routes-Crz_PQzi.js +5 -0
  208. package/bundle/web-dist/client/assets/{services.generated-NP-ValHd.js → services.generated-B5lc3aIC.js} +5 -5
  209. package/bundle/web-dist/client/assets/settings-Cdwm3OBB.js +1 -0
  210. package/bundle/web-dist/client/assets/show-DBUhALT1.js +2 -0
  211. package/bundle/web-dist/client/assets/tokens-CVQAVJTo.js +1 -0
  212. package/bundle/web-dist/client/assets/total-cost-MnfKU8IN.js +1 -0
  213. package/bundle/web-dist/client/assets/use-oauth-login-flow-BfxYI4Oh.js +1 -0
  214. package/bundle/web-dist/client/assets/use-update-token-mutation-qKBC2sn7.js +1 -0
  215. package/bundle/web-dist/client/assets/{vendor-tanstack-DJRQAbrY.js → vendor-tanstack-DRPs09ai.js} +1 -1
  216. package/bundle/web-dist/client/index.html +5 -5
  217. package/bundle/web-dist/server/assets/clsx-D_N5PN_2.js +16 -0
  218. package/bundle/web-dist/server/assets/{lazyRouteComponent-CgBdabgd.js → lazyRouteComponent-AKiHfZWp.js} +129 -2
  219. package/bundle/web-dist/server/assets/{logs-BMyR98rU.js → logs-B7QmGJq3.js} +18 -14
  220. package/bundle/web-dist/server/assets/{monit-ZPt66W5M.js → monit-DFt7x3bh.js} +13 -12
  221. package/bundle/web-dist/server/assets/{plus-BZ9I0VgC.js → plus-DaYQRpBt.js} +1 -1
  222. package/bundle/web-dist/server/assets/{react-dom-Ds75e4Jl.js → react-dom-Cv23mm1K.js} +2 -129
  223. package/bundle/web-dist/server/assets/{refresh-cw-CztCFis-.js → refresh-cw-BpXNsAy-.js} +1 -1
  224. package/bundle/web-dist/server/assets/{request-model-DjGldb-h.js → request-model-eHE6YbaF.js} +1 -1
  225. package/bundle/web-dist/server/assets/{routes-Ct-k7nBA.js → routes-_Y-PJfgO.js} +110 -39
  226. package/bundle/web-dist/server/assets/{services.generated-BA4AcAf5.js → services.generated-CMJ8AHbO.js} +582 -172
  227. package/bundle/web-dist/server/assets/{settings-CBUZ47Xx.js → settings-JwJKxn2e.js} +14 -14
  228. package/bundle/web-dist/server/assets/{show-LSFIzvO2.js → show-BEv6z1v_.js} +90 -60
  229. package/bundle/web-dist/server/assets/{tokens-DxrBW512.js → tokens-CNT4mI-f.js} +162 -50
  230. package/bundle/web-dist/server/assets/total-cost-fTE9Xy82.js +18 -0
  231. package/bundle/web-dist/server/assets/use-oauth-login-flow-jkAkT3X6.js +2345 -0
  232. package/bundle/web-dist/server/assets/{use-update-token-mutation-pkArIzCP.js → use-update-token-mutation-Sm6kh02m.js} +1 -1
  233. package/bundle/web-dist/server/entry-server.generated.js +1644 -21655
  234. package/dist/cli.js +9 -9
  235. package/package.json +4 -11
  236. package/postinstall.mjs +12 -0
  237. package/skills/qgrid/SKILL.md +1 -0
  238. package/skills/qgrid/references/cli-env-and-server-boot.md +4 -1
  239. package/skills/qgrid/references/decision-rationale.md +23 -0
  240. package/skills/qgrid/references/grok-runtime.md +89 -0
  241. package/skills/qgrid/references/provider-runtime-differences.md +30 -29
  242. package/skills/qgrid/references/repo-map.md +10 -0
  243. package/skills/qgrid/references/token-auth-quota-lifecycle.md +56 -3
  244. package/bundle/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +0 -406
  245. package/bundle/dist/node_modules/.pnpm/@vitest_expect@4.1.10/node_modules/@vitest/expect/dist/index.js +0 -1507
  246. package/bundle/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.10/node_modules/@vitest/pretty-format/dist/index.js +0 -887
  247. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2756
  248. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/index.js +0 -8
  249. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/utils.js +0 -8
  250. package/bundle/dist/node_modules/.pnpm/@vitest_snapshot@4.1.10/node_modules/@vitest/snapshot/dist/index.js +0 -922
  251. package/bundle/dist/node_modules/.pnpm/@vitest_spy@4.1.10/node_modules/@vitest/spy/dist/index.js +0 -386
  252. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -121
  253. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/constants.js +0 -51
  254. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/diff.js +0 -1317
  255. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/display.js +0 -561
  256. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js +0 -40
  257. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js +0 -272
  258. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/offset.js +0 -27
  259. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/serialize.js +0 -77
  260. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/source-map.js +0 -381
  261. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/timers.js +0 -51
  262. package/bundle/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +0 -2986
  263. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +0 -10
  264. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +0 -109
  265. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +0 -10
  266. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +0 -10
  267. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +0 -10
  268. package/bundle/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +0 -1126
  269. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +0 -21
  270. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +0 -432
  271. package/bundle/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +0 -517
  272. package/bundle/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +0 -101
  273. package/bundle/dist/node_modules/.pnpm/vite@8.0.3_@emnapi_core@1.11.2_@emnapi_runtime@1.11.2_@types_node@25.0.7_esbuild@0.27.4_5b35fc1fb85d2af4d105e0d74f940f50/node_modules/vite/dist/node/module-runner.js +0 -1265
  274. 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_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +0 -9
  275. 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_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +0 -41
  276. 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_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +0 -19
  277. 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_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +0 -202
  278. 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_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/index.DdgEv5B1.js +0 -46
  279. 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_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +0 -119
  280. 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_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js +0 -3044
  281. 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_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +0 -59
  282. 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_vi_a1977b93af7bb69308bcb1dbab39b618/node_modules/vitest/dist/index.js +0 -28
  283. package/bundle/dist/testing/setup-mocks.js +0 -16
  284. package/bundle/src/testing/setup-mocks.ts +0 -44
  285. package/bundle/web-dist/client/assets/index-Bw2s88Ot.css +0 -1
  286. package/bundle/web-dist/client/assets/index-DZwzUfI-.js +0 -106
  287. package/bundle/web-dist/client/assets/logs-Cog79DU5.js +0 -1
  288. package/bundle/web-dist/client/assets/monit-2auznBys.js +0 -1
  289. package/bundle/web-dist/client/assets/routes-B0lTeLK-.js +0 -5
  290. package/bundle/web-dist/client/assets/settings-D8ZxZGSJ.js +0 -1
  291. package/bundle/web-dist/client/assets/show-CFSERlnM.js +0 -2
  292. package/bundle/web-dist/client/assets/tokens-CZXUyI7O.js +0 -1
  293. package/bundle/web-dist/client/assets/use-oauth-login-flow-hboOs3wG.js +0 -1
  294. package/bundle/web-dist/client/assets/use-update-token-mutation-BQHS0byG.js +0 -1
  295. package/bundle/web-dist/server/assets/use-oauth-login-flow-Gn8flMK5.js +0 -178
  296. package/dist/cli.d.ts +0 -10
  297. /package/bundle/web-dist/client/assets/{cost-DH2jZbrw.js → cost-DB3HbU7T.js} +0 -0
  298. /package/bundle/web-dist/client/assets/{plus-B62CuqT8.js → plus-BsQdY7PS.js} +0 -0
  299. /package/bundle/web-dist/client/assets/{preload-helper-ca-nBW7U.js → preload-helper-DWTEM3RW.js} +0 -0
  300. /package/bundle/web-dist/client/assets/{refresh-cw-NNcU0Cmq.js → refresh-cw-D9IUmT23.js} +0 -0
  301. /package/bundle/web-dist/client/assets/{request-model-CojtinqK.js → request-model-Bpp_rkK8.js} +0 -0
  302. /package/bundle/web-dist/server/assets/{cost-eEHeTRT5.js → cost-BC9yzyA9.js} +0 -0
@@ -0,0 +1,199 @@
1
+ import "./grok-constants.js";
2
+ import { classifyGrokHttpError, readGrokResponseHeaders } from "./grok-backend-protocol.js";
3
+ import { GrokHttpError, grokHttpErrorFromResponse } from "./grok-direct-client.js";
4
+ import { buildGrokVoiceHeaders } from "./grok-headers.js";
5
+ import { GrokSttResponse, GrokTtsRequest } from "./grok-types.js";
6
+ import { z } from "zod";
7
+ //#region src/utils/providers/grok/grok-voice-client.ts
8
+ const GROK_VOICE_TIMEOUT_MS = 12e4;
9
+ const GROK_TTS_DEFAULT_VOICE = "ara";
10
+ const GROK_TTS_DEFAULT_LANGUAGE = "en";
11
+ const GROK_TTS_DEFAULT_FORMAT = "mp3";
12
+ const CONNECT_FAILURE_CODES = /* @__PURE__ */ new Set([
13
+ "ECONNREFUSED",
14
+ "ENOTFOUND",
15
+ "EAI_AGAIN",
16
+ "EHOSTUNREACH",
17
+ "ENETUNREACH",
18
+ "UND_ERR_CONNECT_TIMEOUT"
19
+ ]);
20
+ const EXTENSION_BY_SUBTYPE = /* @__PURE__ */ new Map([
21
+ ["mpeg", "mp3"],
22
+ ["x-wav", "wav"],
23
+ ["opus", "ogg"],
24
+ ["mp4", "m4a"],
25
+ ["x-m4a", "m4a"]
26
+ ]);
27
+ const MEDIA_TYPE_BY_FORMAT = /* @__PURE__ */ new Map([
28
+ ["mp3", "audio/mpeg"],
29
+ ["wav", "audio/wav"],
30
+ ["pcm", "audio/pcm"],
31
+ ["mulaw", "audio/basic"],
32
+ ["alaw", "audio/x-alaw-basic"]
33
+ ]);
34
+ const errorChainLink = z.looseObject({
35
+ code: z.unknown().optional(),
36
+ errors: z.unknown().optional(),
37
+ cause: z.unknown().optional()
38
+ });
39
+ const coded = z.looseObject({ code: z.string() });
40
+ function errorCodes(cause) {
41
+ const codes = [];
42
+ let link = errorChainLink.safeParse(cause);
43
+ for (let depth = 0; depth < 5 && link.success; depth++) {
44
+ const code = z.string().safeParse(link.data.code);
45
+ if (code.success) codes.push(code.data);
46
+ const nested = z.array(z.unknown()).safeParse(link.data.errors);
47
+ if (nested.success) for (const inner of nested.data) {
48
+ const innerCode = coded.safeParse(inner);
49
+ if (innerCode.success) codes.push(innerCode.data.code);
50
+ }
51
+ link = errorChainLink.safeParse(link.data.cause);
52
+ }
53
+ return codes;
54
+ }
55
+ function isConnectFailure(cause) {
56
+ const codes = errorCodes(cause);
57
+ return codes.length > 0 && codes.every((code) => CONNECT_FAILURE_CODES.has(code));
58
+ }
59
+ function abortReason(signal) {
60
+ const reason = signal.reason;
61
+ return reason instanceof Error ? reason : new DOMException("Aborted", "AbortError");
62
+ }
63
+ /**
64
+ * Status-0 transient error. `afterSend` failures carry `shouldRetry: false` so no layer replays a
65
+ * POST whose body may have been executed upstream.
66
+ */
67
+ function transportError(message, afterSend, cause) {
68
+ const classification = {
69
+ ...classifyGrokHttpError(0, "", {}),
70
+ message
71
+ };
72
+ if (afterSend) classification.shouldRetry = false;
73
+ return new GrokHttpError(classification, "", {}, { cause });
74
+ }
75
+ function invalidBodyError(response, message, cause) {
76
+ return new GrokHttpError({
77
+ ...classifyGrokHttpError(502, "", response.headers),
78
+ message,
79
+ shouldRetry: false
80
+ }, "", readGrokResponseHeaders(response.headers), cause === void 0 ? void 0 : { cause });
81
+ }
82
+ function audioExtension(mediaType) {
83
+ const subtype = mediaType.toLowerCase().split(";")[0]?.split("/")[1]?.trim() ?? "";
84
+ return EXTENSION_BY_SUBTYPE.get(subtype) ?? (/^[a-z0-9.+-]+$/.test(subtype) ? subtype : "bin");
85
+ }
86
+ function contentMediaType(response) {
87
+ const value = response.headers.get("content-type")?.split(";")[0]?.trim().toLowerCase();
88
+ return value ? value : void 0;
89
+ }
90
+ var GrokVoiceClient = class {
91
+ fetchImpl;
92
+ baseUrl;
93
+ timeoutMs;
94
+ platform;
95
+ constructor(options = {}) {
96
+ this.fetchImpl = options.fetch ?? fetch;
97
+ this.baseUrl = options.baseUrl ?? "https://api.x.ai/v1";
98
+ this.timeoutMs = options.timeoutMs ?? 12e4;
99
+ this.platform = options.platform;
100
+ }
101
+ /** Multipart `POST /stt`: `model` first, optional `language`, `file` last (xAI requirement). */
102
+ async transcribe(bearer, request) {
103
+ if (request.audio.byteLength === 0) throw new TypeError("audio must not be empty");
104
+ if (!/^[\w.+-]+\/[\w.+-]+/.test(request.mediaType)) throw new TypeError("mediaType must be a type/subtype media type");
105
+ const form = new FormData();
106
+ form.append("model", request.model ?? "grok-voice-transcribe-2.0");
107
+ if (request.language) form.append("language", request.language);
108
+ const filename = `audio.${audioExtension(request.mediaType)}`;
109
+ form.append("file", new File([new Uint8Array(request.audio)], filename, { type: request.mediaType }), filename);
110
+ const headers = buildGrokVoiceHeaders({
111
+ bearer,
112
+ platform: this.platform
113
+ });
114
+ return this.post("/stt", headers, form, request.signal, async (response) => {
115
+ let json;
116
+ try {
117
+ json = await response.json();
118
+ } catch (error) {
119
+ throw invalidBodyError(response, "invalid JSON body", error);
120
+ }
121
+ const record = z.looseObject({}).safeParse(json);
122
+ const normalized = record.success ? Object.fromEntries(Object.entries(record.data).filter(([, value]) => value !== null)) : json;
123
+ const parsed = GrokSttResponse.safeParse(normalized);
124
+ if (!parsed.success) throw invalidBodyError(response, "invalid STT response", parsed.error);
125
+ const { language, ...rest } = parsed.data;
126
+ return language ? {
127
+ ...rest,
128
+ language
129
+ } : rest;
130
+ });
131
+ }
132
+ /** JSON `POST /tts` returning the raw audio bytes. `language` is required upstream (U0). */
133
+ async speak(bearer, request) {
134
+ const body = GrokTtsRequest.parse({
135
+ text: request.text,
136
+ voice: request.voice ?? "ara",
137
+ language: request.language ?? "en",
138
+ format: request.format ?? "mp3"
139
+ });
140
+ const headers = {
141
+ ...buildGrokVoiceHeaders({
142
+ bearer,
143
+ platform: this.platform
144
+ }),
145
+ "content-type": "application/json"
146
+ };
147
+ return this.post("/tts", headers, JSON.stringify(body), request.signal, async (response) => {
148
+ const mediaType = contentMediaType(response);
149
+ if (mediaType === "application/json" || mediaType?.startsWith("text/")) throw invalidBodyError(response, `expected audio, got ${mediaType}`);
150
+ let audio;
151
+ try {
152
+ audio = new Uint8Array(await response.arrayBuffer());
153
+ } catch (error) {
154
+ throw invalidBodyError(response, "failed to read audio body", error);
155
+ }
156
+ if (audio.byteLength === 0) throw invalidBodyError(response, "empty audio body");
157
+ return {
158
+ audio,
159
+ mediaType: mediaType ?? MEDIA_TYPE_BY_FORMAT.get(body.format) ?? "application/octet-stream"
160
+ };
161
+ });
162
+ }
163
+ /**
164
+ * One POST, never retried. The total timeout covers the response body too; a caller abort
165
+ * rethrows the caller's reason.
166
+ */
167
+ async post(path, headers, body, callerSignal, readBody) {
168
+ if (callerSignal?.aborted) throw abortReason(callerSignal);
169
+ const timeout = AbortSignal.timeout(this.timeoutMs);
170
+ const signal = callerSignal ? AbortSignal.any([callerSignal, timeout]) : timeout;
171
+ const interrupted = (cause) => {
172
+ if (callerSignal?.aborted) return abortReason(callerSignal);
173
+ if (timeout.aborted) return transportError(`timed out after ${this.timeoutMs} ms`, true, cause);
174
+ };
175
+ let response;
176
+ try {
177
+ response = await this.fetchImpl(`${this.baseUrl}${path}`, {
178
+ method: "POST",
179
+ headers,
180
+ body,
181
+ signal
182
+ });
183
+ } catch (error) {
184
+ const stop = interrupted(error);
185
+ if (stop) throw stop;
186
+ throw transportError(error instanceof Error ? error.message : String(error), !isConnectFailure(error), error);
187
+ }
188
+ try {
189
+ if (!response.ok) throw await grokHttpErrorFromResponse(response);
190
+ return await readBody(response);
191
+ } catch (error) {
192
+ throw interrupted(error) ?? error;
193
+ }
194
+ }
195
+ };
196
+ //#endregion
197
+ export { GROK_TTS_DEFAULT_FORMAT, GROK_TTS_DEFAULT_LANGUAGE, GROK_TTS_DEFAULT_VOICE, GROK_VOICE_TIMEOUT_MS, GrokVoiceClient };
198
+
199
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3Jvay12b2ljZS1jbGllbnQuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9ncm9rL2dyb2stdm9pY2UtY2xpZW50LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmltcG9ydCB7IGNsYXNzaWZ5R3Jva0h0dHBFcnJvciwgcmVhZEdyb2tSZXNwb25zZUhlYWRlcnMgfSBmcm9tIFwiLi9ncm9rLWJhY2tlbmQtcHJvdG9jb2xcIjtcbmltcG9ydCB7IEdST0tfUFVCTElDX0FQSV9VUkwsIEdST0tfU1RUX0RFRkFVTFRfTU9ERUwgfSBmcm9tIFwiLi9ncm9rLWNvbnN0YW50c1wiO1xuaW1wb3J0IHsgR3Jva0h0dHBFcnJvciwgZ3Jva0h0dHBFcnJvckZyb21SZXNwb25zZSB9IGZyb20gXCIuL2dyb2stZGlyZWN0LWNsaWVudFwiO1xuaW1wb3J0IHsgYnVpbGRHcm9rVm9pY2VIZWFkZXJzLCB0eXBlIEdyb2tQbGF0Zm9ybSB9IGZyb20gXCIuL2dyb2staGVhZGVyc1wiO1xuaW1wb3J0IHtcbiAgR3Jva1N0dFJlc3BvbnNlLFxuICBHcm9rVHRzUmVxdWVzdCxcbiAgdHlwZSBHcm9rU3BlZWNoUmVzdWx0LFxuICB0eXBlIEdyb2tUcmFuc2NyaWJlUmVxdWVzdCxcbiAgdHlwZSBHcm9rVm9pY2VQb3J0LFxufSBmcm9tIFwiLi9ncm9rLXR5cGVzXCI7XG5cbi8vIEhUVFAgY2xpZW50IGZvciBhcGkueC5haSBzcGVlY2gtdG8tdGV4dCAobXVsdGlwYXJ0IGBQT1NUIC9zdHRgKSBhbmQgdGV4dC10by1zcGVlY2ggKEpTT05cbi8vIGBQT1NUIC90dHNgKSwgYm90aCBhY2NlcHRlZCB3aXRoIHRoZSBzdWJzY3JpcHRpb24gSldUIChVMCkuIGdyb2stYnVpbGQgb25seSBzaGlwcyBhIFdlYlNvY2tldFxuLy8gU1RUIGNsaWVudCwgc28gdGhlcmUgaXMgbm8gZ3Jvay1idWlsZCBwcmVjZWRlbnQgZm9yIGFuIEhUVFAgdGltZW91dDsgMTIwIHMgdG90YWwgY292ZXJzXG4vLyB1cGxvYWQsIHNlcnZlciBwcm9jZXNzaW5nIGFuZCB0aGUgYm9keSBkb3dubG9hZCBvZiBsb25nIGF1ZGlvLiBSZXF1ZXN0cyBhcmUgbmV2ZXIgcmUtaXNzdWVkOlxuLy8gb25jZSB0aGUgYm9keSBtYXkgaGF2ZSBiZWVuIHNlbnQsIHVwc3RyZWFtIG1heSBhbHJlYWR5IGJlIGV4ZWN1dGluZyAoYW5kIGJpbGxpbmcpIGl0LlxuXG5leHBvcnQgY29uc3QgR1JPS19WT0lDRV9USU1FT1VUX01TID0gMTIwXzAwMDtcbmV4cG9ydCBjb25zdCBHUk9LX1RUU19ERUZBVUxUX1ZPSUNFID0gXCJhcmFcIjtcbmV4cG9ydCBjb25zdCBHUk9LX1RUU19ERUZBVUxUX0xBTkdVQUdFID0gXCJlblwiO1xuZXhwb3J0IGNvbnN0IEdST0tfVFRTX0RFRkFVTFRfRk9STUFUID0gXCJtcDNcIjtcblxuLy8gVW5kaWNpIC8gTm9kZSBlcnJvciBjb2RlcyB0aGF0IHByb3ZlIG5vIGNvbm5lY3Rpb24gZXhpc3RlZCwgc28gbm8gcmVxdWVzdCBieXRlIGxlZnQgcWdyaWQuXG5jb25zdCBDT05ORUNUX0ZBSUxVUkVfQ09ERVMgPSBuZXcgU2V0KFtcbiAgXCJFQ09OTlJFRlVTRURcIixcbiAgXCJFTk9URk9VTkRcIixcbiAgXCJFQUlfQUdBSU5cIixcbiAgXCJFSE9TVFVOUkVBQ0hcIixcbiAgXCJFTkVUVU5SRUFDSFwiLFxuICBcIlVORF9FUlJfQ09OTkVDVF9USU1FT1VUXCIsXG5dKTtcblxuLy8gU2FtZSBzdWJ0eXBlIG1hcHBpbmcgYXMgQGFpLXNkay9wcm92aWRlci11dGlscyBtZWRpYVR5cGVUb0V4dGVuc2lvbi5cbmNvbnN0IEVYVEVOU0lPTl9CWV9TVUJUWVBFOiBSZWFkb25seU1hcDxzdHJpbmcsIHN0cmluZz4gPSBuZXcgTWFwKFtcbiAgW1wibXBlZ1wiLCBcIm1wM1wiXSxcbiAgW1wieC13YXZcIiwgXCJ3YXZcIl0sXG4gIFtcIm9wdXNcIiwgXCJvZ2dcIl0sXG4gIFtcIm1wNFwiLCBcIm00YVwiXSxcbiAgW1wieC1tNGFcIiwgXCJtNGFcIl0sXG5dKTtcblxuY29uc3QgTUVESUFfVFlQRV9CWV9GT1JNQVQ6IFJlYWRvbmx5TWFwPHN0cmluZywgc3RyaW5nPiA9IG5ldyBNYXAoW1xuICBbXCJtcDNcIiwgXCJhdWRpby9tcGVnXCJdLFxuICBbXCJ3YXZcIiwgXCJhdWRpby93YXZcIl0sXG4gIFtcInBjbVwiLCBcImF1ZGlvL3BjbVwiXSxcbiAgW1wibXVsYXdcIiwgXCJhdWRpby9iYXNpY1wiXSxcbiAgW1wiYWxhd1wiLCBcImF1ZGlvL3gtYWxhdy1iYXNpY1wiXSxcbl0pO1xuXG5leHBvcnQgaW50ZXJmYWNlIEdyb2tWb2ljZUNsaWVudE9wdGlvbnMge1xuICBmZXRjaD86IHR5cGVvZiBmZXRjaDtcbiAgYmFzZVVybD86IHN0cmluZztcbiAgdGltZW91dE1zPzogbnVtYmVyO1xuICBwbGF0Zm9ybT86IEdyb2tQbGF0Zm9ybTtcbn1cblxuLyoqIGBzcGVha2AgaW5wdXQ6IHRoZSBwb3J0J3MgcmVxdWVzdCB3aXRoIGB2b2ljZWAsIGBsYW5ndWFnZWAgYW5kIGBmb3JtYXRgIGRlZmF1bHRlZC4gKi9cbmV4cG9ydCB0eXBlIEdyb2tTcGVha0lucHV0ID0gUGljazxHcm9rVHRzUmVxdWVzdCwgXCJ0ZXh0XCI+ICZcbiAgUGFydGlhbDxPbWl0PEdyb2tUdHNSZXF1ZXN0LCBcInRleHRcIj4+ICYgeyBzaWduYWw/OiBBYm9ydFNpZ25hbCB9O1xuXG4vLyBPbmUgbGluayBvZiBhIHRocm93biB2YWx1ZSdzIGNhdXNlIGNoYWluOyBhbnkgbm9uLW51bGwgb2JqZWN0IHF1YWxpZmllcy5cbmNvbnN0IGVycm9yQ2hhaW5MaW5rID0gei5sb29zZU9iamVjdCh7XG4gIGNvZGU6IHoudW5rbm93bigpLm9wdGlvbmFsKCksXG4gIGVycm9yczogei51bmtub3duKCkub3B0aW9uYWwoKSxcbiAgY2F1c2U6IHoudW5rbm93bigpLm9wdGlvbmFsKCksXG59KTtcblxuY29uc3QgY29kZWQgPSB6Lmxvb3NlT2JqZWN0KHsgY29kZTogei5zdHJpbmcoKSB9KTtcblxuZnVuY3Rpb24gZXJyb3JDb2RlcyhjYXVzZTogdW5rbm93bik6IHN0cmluZ1tdIHtcbiAgY29uc3QgY29kZXM6IHN0cmluZ1tdID0gW107XG4gIGxldCBsaW5rID0gZXJyb3JDaGFpbkxpbmsuc2FmZVBhcnNlKGNhdXNlKTtcblxuICBmb3IgKGxldCBkZXB0aCA9IDA7IGRlcHRoIDwgNSAmJiBsaW5rLnN1Y2Nlc3M7IGRlcHRoKyspIHtcbiAgICBjb25zdCBjb2RlID0gei5zdHJpbmcoKS5zYWZlUGFyc2UobGluay5kYXRhLmNvZGUpO1xuXG4gICAgaWYgKGNvZGUuc3VjY2VzcykgY29kZXMucHVzaChjb2RlLmRhdGEpO1xuICAgIGNvbnN0IG5lc3RlZCA9IHouYXJyYXkoei51bmtub3duKCkpLnNhZmVQYXJzZShsaW5rLmRhdGEuZXJyb3JzKTtcblxuICAgIGlmIChuZXN0ZWQuc3VjY2Vzcykge1xuICAgICAgZm9yIChjb25zdCBpbm5lciBvZiBuZXN0ZWQuZGF0YSkge1xuICAgICAgICBjb25zdCBpbm5lckNvZGUgPSBjb2RlZC5zYWZlUGFyc2UoaW5uZXIpO1xuXG4gICAgICAgIGlmIChpbm5lckNvZGUuc3VjY2VzcykgY29kZXMucHVzaChpbm5lckNvZGUuZGF0YS5jb2RlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBsaW5rID0gZXJyb3JDaGFpbkxpbmsuc2FmZVBhcnNlKGxpbmsuZGF0YS5jYXVzZSk7XG4gIH1cblxuICByZXR1cm4gY29kZXM7XG59XG5cbmZ1bmN0aW9uIGlzQ29ubmVjdEZhaWx1cmUoY2F1c2U6IHVua25vd24pOiBib29sZWFuIHtcbiAgY29uc3QgY29kZXMgPSBlcnJvckNvZGVzKGNhdXNlKTtcblxuICByZXR1cm4gY29kZXMubGVuZ3RoID4gMCAmJiBjb2Rlcy5ldmVyeSgoY29kZSkgPT4gQ09OTkVDVF9GQUlMVVJFX0NPREVTLmhhcyhjb2RlKSk7XG59XG5cbmZ1bmN0aW9uIGFib3J0UmVhc29uKHNpZ25hbDogQWJvcnRTaWduYWwpOiBFcnJvciB7XG4gIGNvbnN0IHJlYXNvbjogdW5rbm93biA9IHNpZ25hbC5yZWFzb247XG5cbiAgcmV0dXJuIHJlYXNvbiBpbnN0YW5jZW9mIEVycm9yID8gcmVhc29uIDogbmV3IERPTUV4Y2VwdGlvbihcIkFib3J0ZWRcIiwgXCJBYm9ydEVycm9yXCIpO1xufVxuXG4vKipcbiAqIFN0YXR1cy0wIHRyYW5zaWVudCBlcnJvci4gYGFmdGVyU2VuZGAgZmFpbHVyZXMgY2FycnkgYHNob3VsZFJldHJ5OiBmYWxzZWAgc28gbm8gbGF5ZXIgcmVwbGF5cyBhXG4gKiBQT1NUIHdob3NlIGJvZHkgbWF5IGhhdmUgYmVlbiBleGVjdXRlZCB1cHN0cmVhbS5cbiAqL1xuZnVuY3Rpb24gdHJhbnNwb3J0RXJyb3IobWVzc2FnZTogc3RyaW5nLCBhZnRlclNlbmQ6IGJvb2xlYW4sIGNhdXNlOiB1bmtub3duKTogR3Jva0h0dHBFcnJvciB7XG4gIGNvbnN0IGNsYXNzaWZpY2F0aW9uID0geyAuLi5jbGFzc2lmeUdyb2tIdHRwRXJyb3IoMCwgXCJcIiwge30pLCBtZXNzYWdlIH07XG5cbiAgaWYgKGFmdGVyU2VuZCkgY2xhc3NpZmljYXRpb24uc2hvdWxkUmV0cnkgPSBmYWxzZTtcblxuICByZXR1cm4gbmV3IEdyb2tIdHRwRXJyb3IoY2xhc3NpZmljYXRpb24sIFwiXCIsIHt9LCB7IGNhdXNlIH0pO1xufVxuXG5mdW5jdGlvbiBpbnZhbGlkQm9keUVycm9yKHJlc3BvbnNlOiBSZXNwb25zZSwgbWVzc2FnZTogc3RyaW5nLCBjYXVzZT86IHVua25vd24pOiBHcm9rSHR0cEVycm9yIHtcbiAgcmV0dXJuIG5ldyBHcm9rSHR0cEVycm9yKFxuICAgIHsgLi4uY2xhc3NpZnlHcm9rSHR0cEVycm9yKDUwMiwgXCJcIiwgcmVzcG9uc2UuaGVhZGVycyksIG1lc3NhZ2UsIHNob3VsZFJldHJ5OiBmYWxzZSB9LFxuICAgIFwiXCIsXG4gICAgcmVhZEdyb2tSZXNwb25zZUhlYWRlcnMocmVzcG9uc2UuaGVhZGVycyksXG4gICAgY2F1c2UgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHsgY2F1c2UgfSxcbiAgKTtcbn1cblxuZnVuY3Rpb24gYXVkaW9FeHRlbnNpb24obWVkaWFUeXBlOiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCBzdWJ0eXBlID0gbWVkaWFUeXBlLnRvTG93ZXJDYXNlKCkuc3BsaXQoXCI7XCIpWzBdPy5zcGxpdChcIi9cIilbMV0/LnRyaW0oKSA/PyBcIlwiO1xuXG4gIHJldHVybiBFWFRFTlNJT05fQllfU1VCVFlQRS5nZXQoc3VidHlwZSkgPz8gKC9eW2EtejAtOS4rLV0rJC8udGVzdChzdWJ0eXBlKSA/IHN1YnR5cGUgOiBcImJpblwiKTtcbn1cblxuZnVuY3Rpb24gY29udGVudE1lZGlhVHlwZShyZXNwb25zZTogUmVzcG9uc2UpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCB2YWx1ZSA9IHJlc3BvbnNlLmhlYWRlcnMuZ2V0KFwiY29udGVudC10eXBlXCIpPy5zcGxpdChcIjtcIilbMF0/LnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuXG4gIHJldHVybiB2YWx1ZSA/IHZhbHVlIDogdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgY2xhc3MgR3Jva1ZvaWNlQ2xpZW50IGltcGxlbWVudHMgR3Jva1ZvaWNlUG9ydCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZmV0Y2hJbXBsOiB0eXBlb2YgZmV0Y2g7XG4gIHByaXZhdGUgcmVhZG9ubHkgYmFzZVVybDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IHRpbWVvdXRNczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHBsYXRmb3JtOiBHcm9rUGxhdGZvcm0gfCB1bmRlZmluZWQ7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogR3Jva1ZvaWNlQ2xpZW50T3B0aW9ucyA9IHt9KSB7XG4gICAgdGhpcy5mZXRjaEltcGwgPSBvcHRpb25zLmZldGNoID8/IGZldGNoO1xuICAgIHRoaXMuYmFzZVVybCA9IG9wdGlvbnMuYmFzZVVybCA/PyBHUk9LX1BVQkxJQ19BUElfVVJMO1xuICAgIHRoaXMudGltZW91dE1zID0gb3B0aW9ucy50aW1lb3V0TXMgPz8gR1JPS19WT0lDRV9USU1FT1VUX01TO1xuICAgIHRoaXMucGxhdGZvcm0gPSBvcHRpb25zLnBsYXRmb3JtO1xuICB9XG5cbiAgLyoqIE11bHRpcGFydCBgUE9TVCAvc3R0YDogYG1vZGVsYCBmaXJzdCwgb3B0aW9uYWwgYGxhbmd1YWdlYCwgYGZpbGVgIGxhc3QgKHhBSSByZXF1aXJlbWVudCkuICovXG4gIGFzeW5jIHRyYW5zY3JpYmUoYmVhcmVyOiBzdHJpbmcsIHJlcXVlc3Q6IEdyb2tUcmFuc2NyaWJlUmVxdWVzdCk6IFByb21pc2U8R3Jva1N0dFJlc3BvbnNlPiB7XG4gICAgaWYgKHJlcXVlc3QuYXVkaW8uYnl0ZUxlbmd0aCA9PT0gMCkgdGhyb3cgbmV3IFR5cGVFcnJvcihcImF1ZGlvIG11c3Qgbm90IGJlIGVtcHR5XCIpO1xuXG4gICAgaWYgKCEvXltcXHcuKy1dK1xcL1tcXHcuKy1dKy8udGVzdChyZXF1ZXN0Lm1lZGlhVHlwZSkpXG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwibWVkaWFUeXBlIG11c3QgYmUgYSB0eXBlL3N1YnR5cGUgbWVkaWEgdHlwZVwiKTtcbiAgICBjb25zdCBmb3JtID0gbmV3IEZvcm1EYXRhKCk7XG4gICAgZm9ybS5hcHBlbmQoXCJtb2RlbFwiLCByZXF1ZXN0Lm1vZGVsID8/IEdST0tfU1RUX0RFRkFVTFRfTU9ERUwpO1xuXG4gICAgaWYgKHJlcXVlc3QubGFuZ3VhZ2UpIGZvcm0uYXBwZW5kKFwibGFuZ3VhZ2VcIiwgcmVxdWVzdC5sYW5ndWFnZSk7XG4gICAgY29uc3QgZmlsZW5hbWUgPSBgYXVkaW8uJHthdWRpb0V4dGVuc2lvbihyZXF1ZXN0Lm1lZGlhVHlwZSl9YDtcbiAgICBmb3JtLmFwcGVuZChcbiAgICAgIFwiZmlsZVwiLFxuICAgICAgbmV3IEZpbGUoW25ldyBVaW50OEFycmF5KHJlcXVlc3QuYXVkaW8pXSwgZmlsZW5hbWUsIHsgdHlwZTogcmVxdWVzdC5tZWRpYVR5cGUgfSksXG4gICAgICBmaWxlbmFtZSxcbiAgICApO1xuICAgIC8vIGZldGNoIHNldHMgdGhlIG11bHRpcGFydCBjb250ZW50LXR5cGUgd2l0aCBpdHMgYm91bmRhcnkuXG4gICAgY29uc3QgaGVhZGVycyA9IGJ1aWxkR3Jva1ZvaWNlSGVhZGVycyh7IGJlYXJlciwgcGxhdGZvcm06IHRoaXMucGxhdGZvcm0gfSk7XG5cbiAgICByZXR1cm4gdGhpcy5wb3N0KFwiL3N0dFwiLCBoZWFkZXJzLCBmb3JtLCByZXF1ZXN0LnNpZ25hbCwgYXN5bmMgKHJlc3BvbnNlKSA9PiB7XG4gICAgICBsZXQganNvbjogdW5rbm93bjtcblxuICAgICAgdHJ5IHtcbiAgICAgICAganNvbiA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHRocm93IGludmFsaWRCb2R5RXJyb3IocmVzcG9uc2UsIFwiaW52YWxpZCBKU09OIGJvZHlcIiwgZXJyb3IpO1xuICAgICAgfVxuXG4gICAgICAvLyBUaGUgU0RLIHNjaGVtYSBhbGxvd3MgbnVsbCBsYW5ndWFnZS9kdXJhdGlvbjsgdHJlYXQgbnVsbCBhcyBhYnNlbnQuXG4gICAgICBjb25zdCByZWNvcmQgPSB6Lmxvb3NlT2JqZWN0KHt9KS5zYWZlUGFyc2UoanNvbik7XG5cbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSByZWNvcmQuc3VjY2Vzc1xuICAgICAgICA/IE9iamVjdC5mcm9tRW50cmllcyhPYmplY3QuZW50cmllcyhyZWNvcmQuZGF0YSkuZmlsdGVyKChbLCB2YWx1ZV0pID0+IHZhbHVlICE9PSBudWxsKSlcbiAgICAgICAgOiBqc29uO1xuXG4gICAgICBjb25zdCBwYXJzZWQgPSBHcm9rU3R0UmVzcG9uc2Uuc2FmZVBhcnNlKG5vcm1hbGl6ZWQpO1xuXG4gICAgICBpZiAoIXBhcnNlZC5zdWNjZXNzKSB0aHJvdyBpbnZhbGlkQm9keUVycm9yKHJlc3BvbnNlLCBcImludmFsaWQgU1RUIHJlc3BvbnNlXCIsIHBhcnNlZC5lcnJvcik7XG4gICAgICBjb25zdCB7IGxhbmd1YWdlLCAuLi5yZXN0IH0gPSBwYXJzZWQuZGF0YTtcblxuICAgICAgcmV0dXJuIGxhbmd1YWdlID8geyAuLi5yZXN0LCBsYW5ndWFnZSB9IDogcmVzdDtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBKU09OIGBQT1NUIC90dHNgIHJldHVybmluZyB0aGUgcmF3IGF1ZGlvIGJ5dGVzLiBgbGFuZ3VhZ2VgIGlzIHJlcXVpcmVkIHVwc3RyZWFtIChVMCkuICovXG4gIGFzeW5jIHNwZWFrKGJlYXJlcjogc3RyaW5nLCByZXF1ZXN0OiBHcm9rU3BlYWtJbnB1dCk6IFByb21pc2U8R3Jva1NwZWVjaFJlc3VsdD4ge1xuICAgIGNvbnN0IGJvZHkgPSBHcm9rVHRzUmVxdWVzdC5wYXJzZSh7XG4gICAgICB0ZXh0OiByZXF1ZXN0LnRleHQsXG4gICAgICB2b2ljZTogcmVxdWVzdC52b2ljZSA/PyBHUk9LX1RUU19ERUZBVUxUX1ZPSUNFLFxuICAgICAgbGFuZ3VhZ2U6IHJlcXVlc3QubGFuZ3VhZ2UgPz8gR1JPS19UVFNfREVGQVVMVF9MQU5HVUFHRSxcbiAgICAgIGZvcm1hdDogcmVxdWVzdC5mb3JtYXQgPz8gR1JPS19UVFNfREVGQVVMVF9GT1JNQVQsXG4gICAgfSk7XG5cbiAgICBjb25zdCBoZWFkZXJzID0ge1xuICAgICAgLi4uYnVpbGRHcm9rVm9pY2VIZWFkZXJzKHsgYmVhcmVyLCBwbGF0Zm9ybTogdGhpcy5wbGF0Zm9ybSB9KSxcbiAgICAgIFwiY29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgIH07XG5cbiAgICByZXR1cm4gdGhpcy5wb3N0KFwiL3R0c1wiLCBoZWFkZXJzLCBKU09OLnN0cmluZ2lmeShib2R5KSwgcmVxdWVzdC5zaWduYWwsIGFzeW5jIChyZXNwb25zZSkgPT4ge1xuICAgICAgY29uc3QgbWVkaWFUeXBlID0gY29udGVudE1lZGlhVHlwZShyZXNwb25zZSk7XG5cbiAgICAgIGlmIChtZWRpYVR5cGUgPT09IFwiYXBwbGljYXRpb24vanNvblwiIHx8IG1lZGlhVHlwZT8uc3RhcnRzV2l0aChcInRleHQvXCIpKVxuICAgICAgICB0aHJvdyBpbnZhbGlkQm9keUVycm9yKHJlc3BvbnNlLCBgZXhwZWN0ZWQgYXVkaW8sIGdvdCAke21lZGlhVHlwZX1gKTtcbiAgICAgIGxldCBhdWRpbzogVWludDhBcnJheTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgYXVkaW8gPSBuZXcgVWludDhBcnJheShhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHRocm93IGludmFsaWRCb2R5RXJyb3IocmVzcG9uc2UsIFwiZmFpbGVkIHRvIHJlYWQgYXVkaW8gYm9keVwiLCBlcnJvcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChhdWRpby5ieXRlTGVuZ3RoID09PSAwKSB0aHJvdyBpbnZhbGlkQm9keUVycm9yKHJlc3BvbnNlLCBcImVtcHR5IGF1ZGlvIGJvZHlcIik7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGF1ZGlvLFxuICAgICAgICBtZWRpYVR5cGU6IG1lZGlhVHlwZSA/PyBNRURJQV9UWVBFX0JZX0ZPUk1BVC5nZXQoYm9keS5mb3JtYXQpID8/IFwiYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtXCIsXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE9uZSBQT1NULCBuZXZlciByZXRyaWVkLiBUaGUgdG90YWwgdGltZW91dCBjb3ZlcnMgdGhlIHJlc3BvbnNlIGJvZHkgdG9vOyBhIGNhbGxlciBhYm9ydFxuICAgKiByZXRocm93cyB0aGUgY2FsbGVyJ3MgcmVhc29uLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwb3N0PFQ+KFxuICAgIHBhdGg6IHN0cmluZyxcbiAgICBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LFxuICAgIGJvZHk6IEZvcm1EYXRhIHwgc3RyaW5nLFxuICAgIGNhbGxlclNpZ25hbDogQWJvcnRTaWduYWwgfCB1bmRlZmluZWQsXG4gICAgcmVhZEJvZHk6IChyZXNwb25zZTogUmVzcG9uc2UpID0+IFByb21pc2U8VD4sXG4gICk6IFByb21pc2U8VD4ge1xuICAgIGlmIChjYWxsZXJTaWduYWw/LmFib3J0ZWQpIHRocm93IGFib3J0UmVhc29uKGNhbGxlclNpZ25hbCk7XG4gICAgY29uc3QgdGltZW91dCA9IEFib3J0U2lnbmFsLnRpbWVvdXQodGhpcy50aW1lb3V0TXMpO1xuICAgIGNvbnN0IHNpZ25hbCA9IGNhbGxlclNpZ25hbCA/IEFib3J0U2lnbmFsLmFueShbY2FsbGVyU2lnbmFsLCB0aW1lb3V0XSkgOiB0aW1lb3V0O1xuXG4gICAgY29uc3QgaW50ZXJydXB0ZWQgPSAoY2F1c2U6IHVua25vd24pOiBFcnJvciB8IHVuZGVmaW5lZCA9PiB7XG4gICAgICBpZiAoY2FsbGVyU2lnbmFsPy5hYm9ydGVkKSByZXR1cm4gYWJvcnRSZWFzb24oY2FsbGVyU2lnbmFsKTtcblxuICAgICAgaWYgKHRpbWVvdXQuYWJvcnRlZClcbiAgICAgICAgcmV0dXJuIHRyYW5zcG9ydEVycm9yKGB0aW1lZCBvdXQgYWZ0ZXIgJHt0aGlzLnRpbWVvdXRNc30gbXNgLCB0cnVlLCBjYXVzZSk7XG5cbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfTtcblxuICAgIGxldCByZXNwb25zZTogUmVzcG9uc2U7XG5cbiAgICB0cnkge1xuICAgICAgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmZldGNoSW1wbChgJHt0aGlzLmJhc2VVcmx9JHtwYXRofWAsIHtcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgaGVhZGVycyxcbiAgICAgICAgYm9keSxcbiAgICAgICAgc2lnbmFsLFxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnN0IHN0b3AgPSBpbnRlcnJ1cHRlZChlcnJvcik7XG5cbiAgICAgIGlmIChzdG9wKSB0aHJvdyBzdG9wO1xuICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKTtcbiAgICAgIHRocm93IHRyYW5zcG9ydEVycm9yKG1lc3NhZ2UsICFpc0Nvbm5lY3RGYWlsdXJlKGVycm9yKSwgZXJyb3IpO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBpZiAoIXJlc3BvbnNlLm9rKSB0aHJvdyBhd2FpdCBncm9rSHR0cEVycm9yRnJvbVJlc3BvbnNlKHJlc3BvbnNlKTtcblxuICAgICAgcmV0dXJuIGF3YWl0IHJlYWRCb2R5KHJlc3BvbnNlKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgaW50ZXJydXB0ZWQoZXJyb3IpID8/IGVycm9yO1xuICAgIH1cbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7O0FBb0JBLE1BQWEsd0JBQXdCO0FBQ3JDLE1BQWEseUJBQXlCO0FBQ3RDLE1BQWEsNEJBQTRCO0FBQ3pDLE1BQWEsMEJBQTBCO0FBR3ZDLE1BQU0sd0NBQXdCLElBQUksSUFBSTtDQUNwQztDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7QUFDRixDQUFDO0FBR0QsTUFBTSx1Q0FBb0QsSUFBSSxJQUFJO0NBQ2hFLENBQUMsUUFBUSxLQUFLO0NBQ2QsQ0FBQyxTQUFTLEtBQUs7Q0FDZixDQUFDLFFBQVEsS0FBSztDQUNkLENBQUMsT0FBTyxLQUFLO0NBQ2IsQ0FBQyxTQUFTLEtBQUs7QUFDakIsQ0FBQztBQUVELE1BQU0sdUNBQW9ELElBQUksSUFBSTtDQUNoRSxDQUFDLE9BQU8sWUFBWTtDQUNwQixDQUFDLE9BQU8sV0FBVztDQUNuQixDQUFDLE9BQU8sV0FBVztDQUNuQixDQUFDLFNBQVMsYUFBYTtDQUN2QixDQUFDLFFBQVEsb0JBQW9CO0FBQy9CLENBQUM7QUFjRCxNQUFNLGlCQUFpQixFQUFFLFlBQVk7Q0FDbkMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDLFNBQVM7Q0FDM0IsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDLFNBQVM7Q0FDN0IsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDLFNBQVM7QUFDOUIsQ0FBQztBQUVELE1BQU0sUUFBUSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUM7QUFFaEQsU0FBUyxXQUFXLE9BQTBCO0NBQzVDLE1BQU0sUUFBa0IsQ0FBQztDQUN6QixJQUFJLE9BQU8sZUFBZSxVQUFVLEtBQUs7Q0FFekMsS0FBSyxJQUFJLFFBQVEsR0FBRyxRQUFRLEtBQUssS0FBSyxTQUFTLFNBQVM7RUFDdEQsTUFBTSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsVUFBVSxLQUFLLEtBQUssSUFBSTtFQUVoRCxJQUFJLEtBQUssU0FBUyxNQUFNLEtBQUssS0FBSyxJQUFJO0VBQ3RDLE1BQU0sU0FBUyxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLFVBQVUsS0FBSyxLQUFLLE1BQU07RUFFOUQsSUFBSSxPQUFPLFNBQ1QsS0FBSyxNQUFNLFNBQVMsT0FBTyxNQUFNO0dBQy9CLE1BQU0sWUFBWSxNQUFNLFVBQVUsS0FBSztHQUV2QyxJQUFJLFVBQVUsU0FBUyxNQUFNLEtBQUssVUFBVSxLQUFLLElBQUk7RUFDdkQ7RUFHRixPQUFPLGVBQWUsVUFBVSxLQUFLLEtBQUssS0FBSztDQUNqRDtDQUVBLE9BQU87QUFDVDtBQUVBLFNBQVMsaUJBQWlCLE9BQXlCO0NBQ2pELE1BQU0sUUFBUSxXQUFXLEtBQUs7Q0FFOUIsT0FBTyxNQUFNLFNBQVMsS0FBSyxNQUFNLE9BQU8sU0FBUyxzQkFBc0IsSUFBSSxJQUFJLENBQUM7QUFDbEY7QUFFQSxTQUFTLFlBQVksUUFBNEI7Q0FDL0MsTUFBTSxTQUFrQixPQUFPO0NBRS9CLE9BQU8sa0JBQWtCLFFBQVEsU0FBUyxJQUFJLGFBQWEsV0FBVyxZQUFZO0FBQ3BGOzs7OztBQU1BLFNBQVMsZUFBZSxTQUFpQixXQUFvQixPQUErQjtDQUMxRixNQUFNLGlCQUFpQjtFQUFFLEdBQUcsc0JBQXNCLEdBQUcsSUFBSSxDQUFDLENBQUM7RUFBRztDQUFRO0NBRXRFLElBQUksV0FBVyxlQUFlLGNBQWM7Q0FFNUMsT0FBTyxJQUFJLGNBQWMsZ0JBQWdCLElBQUksQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDO0FBQzVEO0FBRUEsU0FBUyxpQkFBaUIsVUFBb0IsU0FBaUIsT0FBZ0M7Q0FDN0YsT0FBTyxJQUFJLGNBQ1Q7RUFBRSxHQUFHLHNCQUFzQixLQUFLLElBQUksU0FBUyxPQUFPO0VBQUc7RUFBUyxhQUFhO0NBQU0sR0FDbkYsSUFDQSx3QkFBd0IsU0FBUyxPQUFPLEdBQ3hDLFVBQVUsU0FBWSxTQUFZLEVBQUUsTUFBTSxDQUM1QztBQUNGO0FBRUEsU0FBUyxlQUFlLFdBQTJCO0NBQ2pELE1BQU0sVUFBVSxVQUFVLFlBQVksQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLE1BQU0sR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEtBQUssS0FBSztDQUVoRixPQUFPLHFCQUFxQixJQUFJLE9BQU8sTUFBTSxpQkFBaUIsS0FBSyxPQUFPLElBQUksVUFBVTtBQUMxRjtBQUVBLFNBQVMsaUJBQWlCLFVBQXdDO0NBQ2hFLE1BQU0sUUFBUSxTQUFTLFFBQVEsSUFBSSxjQUFjLENBQUMsRUFBRSxNQUFNLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQyxZQUFZO0NBRXRGLE9BQU8sUUFBUSxRQUFRO0FBQ3pCO0FBRUEsSUFBYSxrQkFBYixNQUFzRDtDQUNwRDtDQUNBO0NBQ0E7Q0FDQTtDQUVBLFlBQVksVUFBa0MsQ0FBQyxHQUFHO0VBQ2hELEtBQUssWUFBWSxRQUFRLFNBQVM7RUFDbEMsS0FBSyxVQUFVLFFBQVEsV0FBQTtFQUN2QixLQUFLLFlBQVksUUFBUSxhQUFBO0VBQ3pCLEtBQUssV0FBVyxRQUFRO0NBQzFCOztDQUdBLE1BQU0sV0FBVyxRQUFnQixTQUEwRDtFQUN6RixJQUFJLFFBQVEsTUFBTSxlQUFlLEdBQUcsTUFBTSxJQUFJLFVBQVUseUJBQXlCO0VBRWpGLElBQUksQ0FBQyxzQkFBc0IsS0FBSyxRQUFRLFNBQVMsR0FDL0MsTUFBTSxJQUFJLFVBQVUsNkNBQTZDO0VBQ25FLE1BQU0sT0FBTyxJQUFJLFNBQVM7RUFDMUIsS0FBSyxPQUFPLFNBQVMsUUFBUSxTQUFBLDJCQUErQjtFQUU1RCxJQUFJLFFBQVEsVUFBVSxLQUFLLE9BQU8sWUFBWSxRQUFRLFFBQVE7RUFDOUQsTUFBTSxXQUFXLFNBQVMsZUFBZSxRQUFRLFNBQVM7RUFDMUQsS0FBSyxPQUNILFFBQ0EsSUFBSSxLQUFLLENBQUMsSUFBSSxXQUFXLFFBQVEsS0FBSyxDQUFDLEdBQUcsVUFBVSxFQUFFLE1BQU0sUUFBUSxVQUFVLENBQUMsR0FDL0UsUUFDRjtFQUVBLE1BQU0sVUFBVSxzQkFBc0I7R0FBRTtHQUFRLFVBQVUsS0FBSztFQUFTLENBQUM7RUFFekUsT0FBTyxLQUFLLEtBQUssUUFBUSxTQUFTLE1BQU0sUUFBUSxRQUFRLE9BQU8sYUFBYTtHQUMxRSxJQUFJO0dBRUosSUFBSTtJQUNGLE9BQU8sTUFBTSxTQUFTLEtBQUs7R0FDN0IsU0FBUyxPQUFPO0lBQ2QsTUFBTSxpQkFBaUIsVUFBVSxxQkFBcUIsS0FBSztHQUM3RDtHQUdBLE1BQU0sU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLElBQUk7R0FFL0MsTUFBTSxhQUFhLE9BQU8sVUFDdEIsT0FBTyxZQUFZLE9BQU8sUUFBUSxPQUFPLElBQUksQ0FBQyxDQUFDLFFBQVEsR0FBRyxXQUFXLFVBQVUsSUFBSSxDQUFDLElBQ3BGO0dBRUosTUFBTSxTQUFTLGdCQUFnQixVQUFVLFVBQVU7R0FFbkQsSUFBSSxDQUFDLE9BQU8sU0FBUyxNQUFNLGlCQUFpQixVQUFVLHdCQUF3QixPQUFPLEtBQUs7R0FDMUYsTUFBTSxFQUFFLFVBQVUsR0FBRyxTQUFTLE9BQU87R0FFckMsT0FBTyxXQUFXO0lBQUUsR0FBRztJQUFNO0dBQVMsSUFBSTtFQUM1QyxDQUFDO0NBQ0g7O0NBR0EsTUFBTSxNQUFNLFFBQWdCLFNBQW9EO0VBQzlFLE1BQU0sT0FBTyxlQUFlLE1BQU07R0FDaEMsTUFBTSxRQUFRO0dBQ2QsT0FBTyxRQUFRLFNBQUE7R0FDZixVQUFVLFFBQVEsWUFBQTtHQUNsQixRQUFRLFFBQVEsVUFBQTtFQUNsQixDQUFDO0VBRUQsTUFBTSxVQUFVO0dBQ2QsR0FBRyxzQkFBc0I7SUFBRTtJQUFRLFVBQVUsS0FBSztHQUFTLENBQUM7R0FDNUQsZ0JBQWdCO0VBQ2xCO0VBRUEsT0FBTyxLQUFLLEtBQUssUUFBUSxTQUFTLEtBQUssVUFBVSxJQUFJLEdBQUcsUUFBUSxRQUFRLE9BQU8sYUFBYTtHQUMxRixNQUFNLFlBQVksaUJBQWlCLFFBQVE7R0FFM0MsSUFBSSxjQUFjLHNCQUFzQixXQUFXLFdBQVcsT0FBTyxHQUNuRSxNQUFNLGlCQUFpQixVQUFVLHVCQUF1QixXQUFXO0dBQ3JFLElBQUk7R0FFSixJQUFJO0lBQ0YsUUFBUSxJQUFJLFdBQVcsTUFBTSxTQUFTLFlBQVksQ0FBQztHQUNyRCxTQUFTLE9BQU87SUFDZCxNQUFNLGlCQUFpQixVQUFVLDZCQUE2QixLQUFLO0dBQ3JFO0dBRUEsSUFBSSxNQUFNLGVBQWUsR0FBRyxNQUFNLGlCQUFpQixVQUFVLGtCQUFrQjtHQUUvRSxPQUFPO0lBQ0w7SUFDQSxXQUFXLGFBQWEscUJBQXFCLElBQUksS0FBSyxNQUFNLEtBQUs7R0FDbkU7RUFDRixDQUFDO0NBQ0g7Ozs7O0NBTUEsTUFBYyxLQUNaLE1BQ0EsU0FDQSxNQUNBLGNBQ0EsVUFDWTtFQUNaLElBQUksY0FBYyxTQUFTLE1BQU0sWUFBWSxZQUFZO0VBQ3pELE1BQU0sVUFBVSxZQUFZLFFBQVEsS0FBSyxTQUFTO0VBQ2xELE1BQU0sU0FBUyxlQUFlLFlBQVksSUFBSSxDQUFDLGNBQWMsT0FBTyxDQUFDLElBQUk7RUFFekUsTUFBTSxlQUFlLFVBQXNDO0dBQ3pELElBQUksY0FBYyxTQUFTLE9BQU8sWUFBWSxZQUFZO0dBRTFELElBQUksUUFBUSxTQUNWLE9BQU8sZUFBZSxtQkFBbUIsS0FBSyxVQUFVLE1BQU0sTUFBTSxLQUFLO0VBRzdFO0VBRUEsSUFBSTtFQUVKLElBQUk7R0FDRixXQUFXLE1BQU0sS0FBSyxVQUFVLEdBQUcsS0FBSyxVQUFVLFFBQVE7SUFDeEQsUUFBUTtJQUNSO0lBQ0E7SUFDQTtHQUNGLENBQUM7RUFDSCxTQUFTLE9BQU87R0FDZCxNQUFNLE9BQU8sWUFBWSxLQUFLO0dBRTlCLElBQUksTUFBTSxNQUFNO0dBRWhCLE1BQU0sZUFEVSxpQkFBaUIsUUFBUSxNQUFNLFVBQVUsT0FBTyxLQUFLLEdBQ3ZDLENBQUMsaUJBQWlCLEtBQUssR0FBRyxLQUFLO0VBQy9EO0VBRUEsSUFBSTtHQUNGLElBQUksQ0FBQyxTQUFTLElBQUksTUFBTSxNQUFNLDBCQUEwQixRQUFRO0dBRWhFLE9BQU8sTUFBTSxTQUFTLFFBQVE7RUFDaEMsU0FBUyxPQUFPO0dBQ2QsTUFBTSxZQUFZLEtBQUssS0FBSztFQUM5QjtDQUNGO0FBQ0YifQ==
@@ -0,0 +1,11 @@
1
+ import { GROK_AUTH_ISSUER, GROK_BUILD_COMMIT, GROK_BUILD_VERSION, GROK_CHAT_PROXY_URL, GROK_CLIENT_IDENTIFIER, GROK_CLIENT_MODE, GROK_COMPACTIONS_REMAINING_DEFAULT, GROK_COMPACTION_AT, GROK_DEFAULT_MODEL, GROK_DEVICE_CODE_URL, GROK_DEVICE_TOKEN_URL, GROK_DOOM_LOOP_CHECK, GROK_EXACT_REPETITION_CHECK, GROK_IMAGE_DEFAULT_MODEL, GROK_MIN_CLIENT_VERSION_OBSERVED, GROK_OAUTH_CLIENT_ID, GROK_OAUTH_REFERRER, GROK_OAUTH_SCOPES, GROK_PUBLIC_API_URL, GROK_REASONING_EFFORTS, GROK_SEED_MODELS, GROK_STT_DEFAULT_MODEL, GROK_USD_PER_TICK, GROK_VIDEO_DEFAULT_MODEL } from "./grok-constants.js";
2
+ import { GROK_DEFAULT_OUTPUT_SCHEMA_NAME, GrokProtocolError, buildGrokResponsesRequest, classifyGrokHttpError, encodeGrokRequestBody, encodeGrokRequestBodyPlain, grokUsageFrom, normalizeGrokEvent, normalizeGrokSSE, parseGrokSSE, parseRetryAfterSec, parseShouldRetry, readGrokResponseHeaders } from "./grok-backend-protocol.js";
3
+ import { GROK_DEFAULT_IDLE_TIMEOUT_MS, GROK_PROXY_GET_TIMEOUT_MS, GrokChatClient, GrokHttpError, GrokIdleTimeoutError, grokHttpErrorFromResponse, grokProxyGet } from "./grok-direct-client.js";
4
+ import { buildGrokChatHeaders, buildGrokMediaHeaders, buildGrokProxyGetHeaders, buildGrokVoiceHeaders, generateTraceparent, grokMediaUserAgent, grokPlatform, grokShellUserAgent } from "./grok-headers.js";
5
+ import { GrokApiImageModel, GrokApiImageModelCatalog, GrokApiLanguageModel, GrokApiLanguageModelCatalog, GrokBillingConfig, GrokCredentials, GrokImageResponse, GrokModelReasoningEffort, GrokModelsResponse, GrokProxyModel, GrokSettings, GrokSttResponse, GrokTtsRequest, GrokUserSubscription, GrokVideoStart, GrokVideoStatus, decodeGrokJwt, grokCatalogModels, grokVideoUrl, isGrokAccessToken } from "./grok-types.js";
6
+ import { GrokModelCatalog, canonicalGrokModelId } from "./grok-models.js";
7
+ import { readGrokBilling, readGrokSettings, readGrokSubscription } from "./grok-quota.js";
8
+ import { GROK_DEVICE_DEFAULT_INTERVAL_S, GROK_DEVICE_SLOW_DOWN_INCREMENT_S, GROK_DISCOVERY_TTL_MS, GROK_FALLBACK_AUTHORIZATION_ENDPOINT, GROK_FALLBACK_TOKEN_ENDPOINT, GROK_OAUTH_SCOPE, GrokOAuthError, GrokTokenResponse, buildGrokAuthorizeUrl, completeGrokOAuth, finishGrokLogin, generateGrokPkce, getGrokOAuthEndpoints, grokLoopbackRedirectUri, parseGrokCallbackInput, pollGrokDeviceCode, readGrokOAuthErrorCode, resetGrokDiscoveryCache, startGrokDeviceCode, startGrokOAuth } from "./grok-oauth.js";
9
+ import { GROK_REFRESH_JITTER_MAX_MS, GROK_REFRESH_MARGIN_MS, GrokReauthRequiredError, GrokRefreshCoordinator, GrokRefreshTransientError, grokNeedsRefresh, grokRefreshJitterMs } from "./grok-refresh.js";
10
+ import { GROK_DEFAULT_COOLDOWN_MS, GROK_ENTITLEMENT_BLOCK_MS, GROK_LOOKUP_CACHE_TTL_MS, GROK_MAX_COOLDOWN_MS, GROK_MAX_COOLDOWN_WAIT_MS, GROK_MAX_HOPS, GROK_MAX_REFRESHES, GROK_MAX_STALE_AUTH_RETRIES, GROK_MAX_TRANSIENT_FAILOVERS, GROK_QUOTA_BLOCK_FALLBACK_MS, GROK_REFRESH_FAILED_COOLDOWN_MS, GROK_VERSION_GATE_REPROBE_MS, GrokAttemptBudgetExceededError, GrokCapabilityUnavailableError, GrokCapacityError, GrokCredentialRefreshError, GrokDispatcher, GrokIncompleteResponseError, GrokInvalidRequestError, GrokNoWorkersError, GrokOnDemandExcludedError, GrokRateLimitedError, GrokVersionGateError, GrokZdrVideoUnavailableError, grokConversationIds, grokTicksToUsd, isGrokZdrVideoRejection } from "./grok-dispatcher.js";
11
+ export { GROK_AUTH_ISSUER, GROK_BUILD_COMMIT, GROK_BUILD_VERSION, GROK_CHAT_PROXY_URL, GROK_CLIENT_IDENTIFIER, GROK_CLIENT_MODE, GROK_COMPACTIONS_REMAINING_DEFAULT, GROK_COMPACTION_AT, GROK_DEFAULT_COOLDOWN_MS, GROK_DEFAULT_IDLE_TIMEOUT_MS, GROK_DEFAULT_MODEL, GROK_DEFAULT_OUTPUT_SCHEMA_NAME, GROK_DEVICE_CODE_URL, GROK_DEVICE_DEFAULT_INTERVAL_S, GROK_DEVICE_SLOW_DOWN_INCREMENT_S, GROK_DEVICE_TOKEN_URL, GROK_DISCOVERY_TTL_MS, GROK_DOOM_LOOP_CHECK, GROK_ENTITLEMENT_BLOCK_MS, GROK_EXACT_REPETITION_CHECK, GROK_FALLBACK_AUTHORIZATION_ENDPOINT, GROK_FALLBACK_TOKEN_ENDPOINT, GROK_IMAGE_DEFAULT_MODEL, GROK_LOOKUP_CACHE_TTL_MS, GROK_MAX_COOLDOWN_MS, GROK_MAX_COOLDOWN_WAIT_MS, GROK_MAX_HOPS, GROK_MAX_REFRESHES, GROK_MAX_STALE_AUTH_RETRIES, GROK_MAX_TRANSIENT_FAILOVERS, GROK_MIN_CLIENT_VERSION_OBSERVED, GROK_OAUTH_CLIENT_ID, GROK_OAUTH_REFERRER, GROK_OAUTH_SCOPE, GROK_OAUTH_SCOPES, GROK_PROXY_GET_TIMEOUT_MS, GROK_PUBLIC_API_URL, GROK_QUOTA_BLOCK_FALLBACK_MS, GROK_REASONING_EFFORTS, GROK_REFRESH_FAILED_COOLDOWN_MS, GROK_REFRESH_JITTER_MAX_MS, GROK_REFRESH_MARGIN_MS, GROK_SEED_MODELS, GROK_STT_DEFAULT_MODEL, GROK_USD_PER_TICK, GROK_VERSION_GATE_REPROBE_MS, GROK_VIDEO_DEFAULT_MODEL, GrokApiImageModel, GrokApiImageModelCatalog, GrokApiLanguageModel, GrokApiLanguageModelCatalog, GrokAttemptBudgetExceededError, GrokBillingConfig, GrokCapabilityUnavailableError, GrokCapacityError, GrokChatClient, GrokCredentialRefreshError, GrokCredentials, GrokDispatcher, GrokHttpError, GrokIdleTimeoutError, GrokImageResponse, GrokIncompleteResponseError, GrokInvalidRequestError, GrokModelCatalog, GrokModelReasoningEffort, GrokModelsResponse, GrokNoWorkersError, GrokOAuthError, GrokOnDemandExcludedError, GrokProtocolError, GrokProxyModel, GrokRateLimitedError, GrokReauthRequiredError, GrokRefreshCoordinator, GrokRefreshTransientError, GrokSettings, GrokSttResponse, GrokTokenResponse, GrokTtsRequest, GrokUserSubscription, GrokVersionGateError, GrokVideoStart, GrokVideoStatus, GrokZdrVideoUnavailableError, buildGrokAuthorizeUrl, buildGrokChatHeaders, buildGrokMediaHeaders, buildGrokProxyGetHeaders, buildGrokResponsesRequest, buildGrokVoiceHeaders, canonicalGrokModelId, classifyGrokHttpError, completeGrokOAuth, decodeGrokJwt, encodeGrokRequestBody, encodeGrokRequestBodyPlain, finishGrokLogin, generateGrokPkce, generateTraceparent, getGrokOAuthEndpoints, grokCatalogModels, grokConversationIds, grokHttpErrorFromResponse, grokLoopbackRedirectUri, grokMediaUserAgent, grokNeedsRefresh, grokPlatform, grokProxyGet, grokRefreshJitterMs, grokShellUserAgent, grokTicksToUsd, grokUsageFrom, grokVideoUrl, isGrokAccessToken, isGrokZdrVideoRejection, normalizeGrokEvent, normalizeGrokSSE, parseGrokCallbackInput, parseGrokSSE, parseRetryAfterSec, parseShouldRetry, pollGrokDeviceCode, readGrokBilling, readGrokOAuthErrorCode, readGrokResponseHeaders, readGrokSettings, readGrokSubscription, resetGrokDiscoveryCache, startGrokDeviceCode, startGrokOAuth };
@@ -1,4 +1,6 @@
1
+ import { isJsonObject, jsonString } from "../common/provider-types.js";
1
2
  import { ImageGenerationMetadata } from "../../../application/qgrid/qgrid.types.js";
3
+ import { z } from "zod";
2
4
  import os from "node:os";
3
5
  //#region src/utils/providers/openai/openai-backend-protocol.ts
4
6
  const CHATGPT_CODEX_RESPONSES_URL = "https://chatgpt.com/backend-api/codex/responses";
@@ -29,43 +31,46 @@ function buildOpenAIResponsesRequest(options) {
29
31
  type: "image_generation",
30
32
  ...options.imageGeneration
31
33
  });
32
- const text = options.verbosity || options.outputSchema ? {
33
- ...options.verbosity ? { verbosity: options.verbosity } : {},
34
- ...options.outputSchema ? { format: {
35
- type: "json_schema",
36
- strict: true,
37
- schema: options.outputSchema.schema,
38
- name: options.outputSchema.name ?? "codex_output_schema"
39
- } } : {}
40
- } : void 0;
41
- return {
34
+ const request = {
42
35
  model: options.model,
43
- ...options.instructions ? { instructions: options.instructions } : {},
44
36
  input: [...options.history],
45
- ...tools.length ? { tools } : {},
46
37
  tool_choice: options.toolChoice ?? "auto",
47
38
  parallel_tool_calls: options.parallelToolCalls ?? true,
48
39
  reasoning: options.reasoning ?? null,
49
40
  store: false,
50
41
  stream: true,
51
- include: ["reasoning.encrypted_content"],
52
- ...options.serviceTier ? { service_tier: options.serviceTier } : {},
53
- ...options.promptCacheKey ? { prompt_cache_key: options.promptCacheKey } : {},
54
- ...text ? { text } : {}
42
+ include: ["reasoning.encrypted_content"]
55
43
  };
44
+ if (options.instructions) request.instructions = options.instructions;
45
+ if (tools.length) request.tools = tools;
46
+ if (options.serviceTier) request.service_tier = options.serviceTier;
47
+ if (options.promptCacheKey) request.prompt_cache_key = options.promptCacheKey;
48
+ if (options.verbosity || options.outputSchema) {
49
+ const text = {};
50
+ if (options.verbosity) text.verbosity = options.verbosity;
51
+ if (options.outputSchema) text.format = {
52
+ type: "json_schema",
53
+ strict: true,
54
+ schema: options.outputSchema.schema,
55
+ name: options.outputSchema.name ?? "codex_output_schema"
56
+ };
57
+ request.text = text;
58
+ }
59
+ return request;
56
60
  }
57
61
  function buildCodexIdentityHeaders(accessToken, accountId, correlation) {
58
- return {
62
+ const headers = {
59
63
  Accept: "text/event-stream",
60
64
  Authorization: `Bearer ${accessToken}`,
61
65
  "ChatGPT-Account-ID": accountId,
62
66
  "Content-Type": "application/json",
63
67
  originator: CODEX_CLI_ORIGINATOR,
64
- "User-Agent": codexCliUserAgent(),
65
- ...correlation?.sessionId ? { "session-id": correlation.sessionId } : {},
66
- ...correlation?.threadId ? { "thread-id": correlation.threadId } : {},
67
- ...correlation?.clientRequestId ? { "x-client-request-id": correlation.clientRequestId } : {}
68
+ "User-Agent": codexCliUserAgent()
68
69
  };
70
+ if (correlation?.sessionId) headers["session-id"] = correlation.sessionId;
71
+ if (correlation?.threadId) headers["thread-id"] = correlation.threadId;
72
+ if (correlation?.clientRequestId) headers["x-client-request-id"] = correlation.clientRequestId;
73
+ return headers;
69
74
  }
70
75
  var OpenAIProtocolError = class extends Error {
71
76
  code;
@@ -79,17 +84,19 @@ var OpenAIProtocolError = class extends Error {
79
84
  this.name = "OpenAIProtocolError";
80
85
  }
81
86
  };
87
+ const tokenCount = z.coerce.number().catch(0);
88
+ function jsonObjectOrEmpty(value) {
89
+ return isJsonObject(value) ? value : {};
90
+ }
82
91
  function usageFrom(value) {
83
- if (!value || typeof value !== "object") return void 0;
84
- const usage = value;
85
- const inputDetails = usage.input_tokens_details ?? {};
86
- const outputDetails = usage.output_tokens_details ?? {};
92
+ const inputDetails = jsonObjectOrEmpty(value.input_tokens_details);
93
+ const outputDetails = jsonObjectOrEmpty(value.output_tokens_details);
87
94
  return {
88
- inputTokens: Number(usage.input_tokens ?? 0),
89
- cachedInputTokens: Number(inputDetails.cached_tokens ?? 0),
90
- outputTokens: Number(usage.output_tokens ?? 0),
91
- reasoningTokens: Number(outputDetails.reasoning_tokens ?? 0),
92
- totalTokens: Number(usage.total_tokens ?? 0)
95
+ inputTokens: tokenCount.parse(value.input_tokens ?? 0),
96
+ cachedInputTokens: tokenCount.parse(inputDetails.cached_tokens ?? 0),
97
+ outputTokens: tokenCount.parse(value.output_tokens ?? 0),
98
+ reasoningTokens: tokenCount.parse(outputDetails.reasoning_tokens ?? 0),
99
+ totalTokens: tokenCount.parse(value.total_tokens ?? 0)
93
100
  };
94
101
  }
95
102
  function imageMimeType(base64, outputFormat) {
@@ -109,79 +116,100 @@ function imageMimeType(base64, outputFormat) {
109
116
  if (outputFormat === "jpeg") return "image/jpeg";
110
117
  if (outputFormat === "webp") return "image/webp";
111
118
  if (outputFormat === void 0 || outputFormat === "png") return "image/png";
112
- throw new OpenAIProtocolError(`Unsupported image output format: ${String(outputFormat)}`);
119
+ throw new OpenAIProtocolError(`Unsupported image output format: ${jsonString(outputFormat) ?? JSON.stringify(outputFormat)}`);
120
+ }
121
+ function imageEvent(item, result) {
122
+ const header = Buffer.from(result.slice(0, 32), "base64");
123
+ const pngSize = header.length >= 24 && header.subarray(0, 8).equals(Buffer.from("89504e470d0a1a0a", "hex")) && header.readUInt32BE(16) > 0 && header.readUInt32BE(20) > 0 ? `${header.readUInt32BE(16)}x${header.readUInt32BE(20)}` : void 0;
124
+ const reportedSize = jsonString(item.size);
125
+ const size = pngSize ?? (reportedSize !== void 0 && /^[1-9]\d*x[1-9]\d*$/.test(reportedSize) ? reportedSize : void 0);
126
+ const id = jsonString(item.id);
127
+ const model = jsonString(item.model);
128
+ const quality = jsonString(item.quality);
129
+ const background = jsonString(item.background);
130
+ const revisedPrompt = jsonString(item.revised_prompt) ?? jsonString(item.revisedPrompt);
131
+ const generation = { route: "codex-responses" };
132
+ if (size) generation.size = size;
133
+ if (model !== void 0) generation.model = model;
134
+ if (quality !== void 0) generation.quality = quality;
135
+ if (background !== void 0) generation.background = background;
136
+ const event = {
137
+ type: "image",
138
+ base64: result,
139
+ mimeType: "image/png"
140
+ };
141
+ if (id !== void 0) event.id = id;
142
+ event.base64 = result;
143
+ event.mimeType = imageMimeType(result, item.output_format);
144
+ event.generation = generation;
145
+ if (revisedPrompt !== void 0) event.revisedPrompt = revisedPrompt;
146
+ return event;
147
+ }
148
+ function completedEvent(response) {
149
+ const toolUsage = jsonObjectOrEmpty(response.tool_usage);
150
+ const parsedImageUsage = ImageGenerationMetadata.shape.usage.safeParse(toolUsage.image_gen);
151
+ const imageUsage = parsedImageUsage.success ? parsedImageUsage.data : void 0;
152
+ const imageTool = Array.isArray(response.tools) ? response.tools.find((tool) => isJsonObject(tool) && tool.type === "image_generation") : void 0;
153
+ const imageModel = isJsonObject(imageTool) ? jsonString(imageTool.model) : void 0;
154
+ const model = jsonString(response.model);
155
+ const event = {
156
+ type: "completed",
157
+ responseId: jsonString(response.id) ?? ""
158
+ };
159
+ if (isJsonObject(response.usage)) event.usage = usageFrom(response.usage);
160
+ if (model !== void 0) event.model = model;
161
+ if (imageUsage || imageModel) {
162
+ const imageGeneration = { route: "codex-responses" };
163
+ if (imageModel) imageGeneration.model = imageModel;
164
+ if (imageUsage) imageGeneration.usage = imageUsage;
165
+ event.imageGeneration = imageGeneration;
166
+ }
167
+ return event;
113
168
  }
114
169
  function normalizeOpenAIEvent(raw) {
115
- if (!raw || typeof raw !== "object") return void 0;
170
+ if (!isJsonObject(raw)) return void 0;
116
171
  const event = raw;
117
- const type = String(event.type ?? "");
172
+ const type = jsonString(event.type) ?? "";
118
173
  if (type === "response.created") {
119
- const response = event.response;
120
- return {
174
+ const responseId = isJsonObject(event.response) ? jsonString(event.response.id) : void 0;
175
+ return responseId ? {
121
176
  type: "created",
122
- ...response?.id ? { responseId: String(response.id) } : {}
177
+ responseId
178
+ } : { type: "created" };
179
+ }
180
+ const delta = jsonString(event.delta);
181
+ if (type === "response.output_text.delta" && delta !== void 0) {
182
+ const itemId = jsonString(event.item_id);
183
+ return itemId === void 0 ? {
184
+ type: "text-delta",
185
+ text: delta
186
+ } : {
187
+ type: "text-delta",
188
+ text: delta,
189
+ itemId
123
190
  };
124
191
  }
125
- if (type === "response.output_text.delta" && typeof event.delta === "string") return {
126
- type: "text-delta",
127
- text: event.delta,
128
- ...typeof event.item_id === "string" ? { itemId: event.item_id } : {}
129
- };
130
- if ((type === "response.output_item.added" || type === "response.output_item.done") && event.item && typeof event.item === "object") {
192
+ if ((type === "response.output_item.added" || type === "response.output_item.done") && isJsonObject(event.item)) {
131
193
  const item = event.item;
132
- if (item.type === "image_generation_call" && typeof item.result === "string") {
133
- const header = Buffer.from(item.result.slice(0, 32), "base64");
134
- const size = (header.length >= 24 && header.subarray(0, 8).equals(Buffer.from("89504e470d0a1a0a", "hex")) && header.readUInt32BE(16) > 0 && header.readUInt32BE(20) > 0 ? `${header.readUInt32BE(16)}x${header.readUInt32BE(20)}` : void 0) ?? (typeof item.size === "string" && /^[1-9]\d*x[1-9]\d*$/.test(item.size) ? item.size : void 0);
135
- return {
136
- type: "image",
137
- ...typeof item.id === "string" ? { id: item.id } : {},
138
- base64: item.result,
139
- mimeType: imageMimeType(item.result, item.output_format),
140
- generation: {
141
- route: "codex-responses",
142
- ...size ? { size } : {},
143
- ...typeof item.model === "string" ? { model: item.model } : {},
144
- ...typeof item.quality === "string" ? { quality: item.quality } : {},
145
- ...typeof item.background === "string" ? { background: item.background } : {}
146
- },
147
- ...typeof item.revised_prompt === "string" ? { revisedPrompt: item.revised_prompt } : typeof item.revisedPrompt === "string" ? { revisedPrompt: item.revisedPrompt } : {}
148
- };
149
- }
194
+ const result = jsonString(item.result);
195
+ if (item.type === "image_generation_call" && result !== void 0) return imageEvent(item, result);
150
196
  return {
151
197
  type: "output-item",
152
198
  item,
153
199
  completed: type === "response.output_item.done"
154
200
  };
155
201
  }
156
- if (type === "response.completed") {
157
- const response = event.response ?? {};
158
- const toolUsage = response.tool_usage;
159
- const parsedImageUsage = ImageGenerationMetadata.shape.usage.safeParse(toolUsage?.image_gen);
160
- const imageUsage = parsedImageUsage.success ? parsedImageUsage.data : void 0;
161
- const imageTool = Array.isArray(response.tools) ? response.tools.find((tool) => tool?.type === "image_generation") : void 0;
162
- const imageModel = typeof imageTool?.model === "string" ? imageTool.model : void 0;
163
- return {
164
- type: "completed",
165
- responseId: String(response.id ?? ""),
166
- ...response.usage ? { usage: usageFrom(response.usage) } : {},
167
- ...typeof response.model === "string" ? { model: response.model } : {},
168
- ...imageUsage || imageModel ? { imageGeneration: {
169
- route: "codex-responses",
170
- ...imageModel ? { model: imageModel } : {},
171
- ...imageUsage ? { usage: imageUsage } : {}
172
- } } : {}
173
- };
174
- }
202
+ if (type === "response.completed") return completedEvent(jsonObjectOrEmpty(event.response));
175
203
  if (type === "error" || type === "response.failed" || type === "response.incomplete") {
176
- const source = event.error ?? event.response ?? event;
177
- const nested = source.error ?? source;
204
+ const source = jsonObjectOrEmpty(event.error ?? event.response ?? event);
205
+ const nested = jsonObjectOrEmpty(source.error ?? source);
178
206
  return {
179
207
  type: "error",
180
- error: new OpenAIProtocolError(String(nested.message ?? `OpenAI stream ended with ${type}`), typeof nested.code === "string" ? nested.code : void 0)
208
+ error: new OpenAIProtocolError(jsonString(nested.message) ?? `OpenAI stream ended with ${type}`, jsonString(nested.code))
181
209
  };
182
210
  }
183
211
  }
184
212
  //#endregion
185
213
  export { CHATGPT_CODEX_RESPONSES_URL, CODEX_CLI_ORIGINATOR, CODEX_CLI_VERSION, OpenAIProtocolError, buildCodexIdentityHeaders, buildOpenAIResponsesRequest, codexCliUserAgent, imageMimeType, normalizeOpenAIEvent };
186
214
 
187
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLWJhY2tlbmQtcHJvdG9jb2wuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9vcGVuYWkvb3BlbmFpLWJhY2tlbmQtcHJvdG9jb2wudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IG9zIGZyb20gXCJub2RlOm9zXCI7XG5cbmltcG9ydCB7IEltYWdlR2VuZXJhdGlvbk1ldGFkYXRhIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLnR5cGVzXCI7XG5pbXBvcnQgeyB0eXBlIE9wZW5BSUVmZm9ydCB9IGZyb20gXCIuLi9jb21tb24vZWZmb3J0XCI7XG5cbmV4cG9ydCBjb25zdCBDSEFUR1BUX0NPREVYX1JFU1BPTlNFU19VUkwgPVxuICBcImh0dHBzOi8vY2hhdGdwdC5jb20vYmFja2VuZC1hcGkvY29kZXgvcmVzcG9uc2VzXCIgYXMgY29uc3Q7XG5cbmV4cG9ydCBjb25zdCBDT0RFWF9DTElfT1JJR0lOQVRPUiA9IFwiY29kZXhfY2xpX3JzXCIgYXMgY29uc3Q7XG5leHBvcnQgY29uc3QgQ09ERVhfQ0xJX1ZFUlNJT04gPSBcIjAuMTQ3LjBcIiBhcyBjb25zdDtcblxuZXhwb3J0IGludGVyZmFjZSBDb2RleFVzZXJBZ2VudFBsYXRmb3JtIHtcbiAgb3NUeXBlOiBzdHJpbmc7XG4gIG9zVmVyc2lvbjogc3RyaW5nO1xuICBhcmNoaXRlY3R1cmU6IHN0cmluZztcbiAgdGVybWluYWw6IHN0cmluZztcbn1cblxuZnVuY3Rpb24gY29kZXhQbGF0Zm9ybSgpOiBDb2RleFVzZXJBZ2VudFBsYXRmb3JtIHtcbiAgY29uc3QgbmFtZXM6IFBhcnRpYWw8UmVjb3JkPE5vZGVKUy5QbGF0Zm9ybSwgc3RyaW5nPj4gPSB7XG4gICAgZGFyd2luOiBcIk1hYyBPU1wiLFxuICAgIGxpbnV4OiBcIkxpbnV4XCIsXG4gICAgd2luMzI6IFwiV2luZG93c1wiLFxuICB9O1xuICBjb25zdCB0ZXJtaW5hbCA9IHByb2Nlc3MuZW52LlRFUk1fUFJPR1JBTTtcbiAgY29uc3QgdGVybWluYWxWZXJzaW9uID0gcHJvY2Vzcy5lbnYuVEVSTV9QUk9HUkFNX1ZFUlNJT047XG4gIHJldHVybiB7XG4gICAgb3NUeXBlOiBuYW1lc1twcm9jZXNzLnBsYXRmb3JtXSA/PyBwcm9jZXNzLnBsYXRmb3JtLFxuICAgIG9zVmVyc2lvbjogb3MucmVsZWFzZSgpLFxuICAgIGFyY2hpdGVjdHVyZTogcHJvY2Vzcy5hcmNoLFxuICAgIHRlcm1pbmFsOiB0ZXJtaW5hbCA/IGAke3Rlcm1pbmFsfSR7dGVybWluYWxWZXJzaW9uID8gYC8ke3Rlcm1pbmFsVmVyc2lvbn1gIDogXCJcIn1gIDogXCJ1bmtub3duXCIsXG4gIH07XG59XG5cbi8qKiBNYXRjaGVzIHRoZSBwbGF0Zm9ybS90ZXJtaW5hbCBzdWZmaXggZW1pdHRlZCBieSB0aGUgcGlubmVkIFJ1c3QgQ29kZXggQ0xJLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvZGV4Q2xpVXNlckFnZW50KHBsYXRmb3JtOiBDb2RleFVzZXJBZ2VudFBsYXRmb3JtID0gY29kZXhQbGF0Zm9ybSgpKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBjb2RleF9jbGlfcnMvJHtDT0RFWF9DTElfVkVSU0lPTn0gKCR7cGxhdGZvcm0ub3NUeXBlfSAke3BsYXRmb3JtLm9zVmVyc2lvbn07ICR7cGxhdGZvcm0uYXJjaGl0ZWN0dXJlfSkgJHtwbGF0Zm9ybS50ZXJtaW5hbH1gO1xufVxuXG5leHBvcnQgdHlwZSBKc29uVmFsdWUgPVxuICB8IG51bGxcbiAgfCBib29sZWFuXG4gIHwgbnVtYmVyXG4gIHwgc3RyaW5nXG4gIHwgSnNvblZhbHVlW11cbiAgfCB7IFtrZXk6IHN0cmluZ106IEpzb25WYWx1ZSB9O1xuXG4vKiogUmF3IFJlc3BvbnNlcyBBUEkgaXRlbXMuIEtlZXBpbmcgdGhlc2Ugb3BhcXVlIHByZXNlcnZlcyB0aGUgY29tcGxldGUgY29udmVyc2F0aW9uIGhpc3RvcnkuICovXG5leHBvcnQgdHlwZSBPcGVuQUlSZXNwb25zZUl0ZW0gPSBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcblxuZXhwb3J0IGludGVyZmFjZSBPcGVuQUlPdXRwdXRTY2hlbWEge1xuICBuYW1lPzogc3RyaW5nO1xuICBzY2hlbWE6IEpzb25WYWx1ZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcGVuQUlSZXNwb25zZXNPcHRpb25zIHtcbiAgbW9kZWw6IHN0cmluZztcbiAgaW5zdHJ1Y3Rpb25zPzogc3RyaW5nO1xuICBoaXN0b3J5OiByZWFkb25seSBPcGVuQUlSZXNwb25zZUl0ZW1bXTtcbiAgdG9vbHM/OiByZWFkb25seSBPcGVuQUlSZXNwb25zZUl0ZW1bXTtcbiAgdG9vbENob2ljZT86IHN0cmluZyB8IE9wZW5BSVJlc3BvbnNlSXRlbTtcbiAgcGFyYWxsZWxUb29sQ2FsbHM/OiBib29sZWFuO1xuICByZWFzb25pbmc/OiB7XG4gICAgZWZmb3J0PzogT3BlbkFJRWZmb3J0IHwgXCJub25lXCI7XG4gICAgc3VtbWFyeT86IFwiYXV0b1wiIHwgXCJjb25jaXNlXCIgfCBcImRldGFpbGVkXCI7XG4gIH07XG4gIHZlcmJvc2l0eT86IFwibG93XCIgfCBcIm1lZGl1bVwiIHwgXCJoaWdoXCI7XG4gIHNlcnZpY2VUaWVyPzogc3RyaW5nO1xuICBwcm9tcHRDYWNoZUtleT86IHN0cmluZztcbiAgb3V0cHV0U2NoZW1hPzogT3BlbkFJT3V0cHV0U2NoZW1hO1xuICBpbWFnZUdlbmVyYXRpb24/OiBib29sZWFuIHwgT3BlbkFJUmVzcG9uc2VJdGVtO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wZW5BSVJlc3BvbnNlc1JlcXVlc3Qge1xuICBtb2RlbDogc3RyaW5nO1xuICBpbnN0cnVjdGlvbnM/OiBzdHJpbmc7XG4gIGlucHV0OiBPcGVuQUlSZXNwb25zZUl0ZW1bXTtcbiAgdG9vbHM/OiBPcGVuQUlSZXNwb25zZUl0ZW1bXTtcbiAgdG9vbF9jaG9pY2U6IHN0cmluZyB8IE9wZW5BSVJlc3BvbnNlSXRlbTtcbiAgcGFyYWxsZWxfdG9vbF9jYWxsczogYm9vbGVhbjtcbiAgcmVhc29uaW5nOiBPcGVuQUlSZXNwb25zZXNPcHRpb25zW1wicmVhc29uaW5nXCJdIHwgbnVsbDtcbiAgc3RvcmU6IGZhbHNlO1xuICBzdHJlYW06IHRydWU7XG4gIGluY2x1ZGU6IHN0cmluZ1tdO1xuICBzZXJ2aWNlX3RpZXI/OiBzdHJpbmc7XG4gIHByb21wdF9jYWNoZV9rZXk/OiBzdHJpbmc7XG4gIHRleHQ/OiB7XG4gICAgdmVyYm9zaXR5PzogXCJsb3dcIiB8IFwibWVkaXVtXCIgfCBcImhpZ2hcIjtcbiAgICBmb3JtYXQ/OiB7XG4gICAgICB0eXBlOiBcImpzb25fc2NoZW1hXCI7XG4gICAgICBzdHJpY3Q6IHRydWU7XG4gICAgICBzY2hlbWE6IEpzb25WYWx1ZTtcbiAgICAgIG5hbWU6IHN0cmluZztcbiAgICB9O1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRPcGVuQUlSZXNwb25zZXNSZXF1ZXN0KFxuICBvcHRpb25zOiBPcGVuQUlSZXNwb25zZXNPcHRpb25zLFxuKTogT3BlbkFJUmVzcG9uc2VzUmVxdWVzdCB7XG4gIGNvbnN0IHRvb2xzID0gb3B0aW9ucy50b29scyA/IFsuLi5vcHRpb25zLnRvb2xzXSA6IFtdO1xuICBpZiAob3B0aW9ucy5pbWFnZUdlbmVyYXRpb24pIHtcbiAgICB0b29scy5wdXNoKFxuICAgICAgb3B0aW9ucy5pbWFnZUdlbmVyYXRpb24gPT09IHRydWVcbiAgICAgICAgPyB7IHR5cGU6IFwiaW1hZ2VfZ2VuZXJhdGlvblwiIH1cbiAgICAgICAgOiB7IHR5cGU6IFwiaW1hZ2VfZ2VuZXJhdGlvblwiLCAuLi5vcHRpb25zLmltYWdlR2VuZXJhdGlvbiB9LFxuICAgICk7XG4gIH1cblxuICBjb25zdCB0ZXh0ID1cbiAgICBvcHRpb25zLnZlcmJvc2l0eSB8fCBvcHRpb25zLm91dHB1dFNjaGVtYVxuICAgICAgPyB7XG4gICAgICAgICAgLi4uKG9wdGlvbnMudmVyYm9zaXR5ID8geyB2ZXJib3NpdHk6IG9wdGlvbnMudmVyYm9zaXR5IH0gOiB7fSksXG4gICAgICAgICAgLi4uKG9wdGlvbnMub3V0cHV0U2NoZW1hXG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICBmb3JtYXQ6IHtcbiAgICAgICAgICAgICAgICAgIHR5cGU6IFwianNvbl9zY2hlbWFcIiBhcyBjb25zdCxcbiAgICAgICAgICAgICAgICAgIHN0cmljdDogdHJ1ZSBhcyBjb25zdCxcbiAgICAgICAgICAgICAgICAgIHNjaGVtYTogb3B0aW9ucy5vdXRwdXRTY2hlbWEuc2NoZW1hLFxuICAgICAgICAgICAgICAgICAgbmFtZTogb3B0aW9ucy5vdXRwdXRTY2hlbWEubmFtZSA/PyBcImNvZGV4X291dHB1dF9zY2hlbWFcIixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgfVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgcmV0dXJuIHtcbiAgICBtb2RlbDogb3B0aW9ucy5tb2RlbCxcbiAgICAuLi4ob3B0aW9ucy5pbnN0cnVjdGlvbnMgPyB7IGluc3RydWN0aW9uczogb3B0aW9ucy5pbnN0cnVjdGlvbnMgfSA6IHt9KSxcbiAgICAvLyBDb3B5IHRoZSBhcnJheSwgbm90IGl0cyBpdGVtczogcmF3IGl0ZW1zIG11c3QgYXJyaXZlIGJ5dGUtZm9yLWJ5dGUgZXF1aXZhbGVudC5cbiAgICBpbnB1dDogWy4uLm9wdGlvbnMuaGlzdG9yeV0sXG4gICAgLi4uKHRvb2xzLmxlbmd0aCA/IHsgdG9vbHMgfSA6IHt9KSxcbiAgICB0b29sX2Nob2ljZTogb3B0aW9ucy50b29sQ2hvaWNlID8/IFwiYXV0b1wiLFxuICAgIHBhcmFsbGVsX3Rvb2xfY2FsbHM6IG9wdGlvbnMucGFyYWxsZWxUb29sQ2FsbHMgPz8gdHJ1ZSxcbiAgICByZWFzb25pbmc6IG9wdGlvbnMucmVhc29uaW5nID8/IG51bGwsXG4gICAgc3RvcmU6IGZhbHNlLFxuICAgIHN0cmVhbTogdHJ1ZSxcbiAgICBpbmNsdWRlOiBbXCJyZWFzb25pbmcuZW5jcnlwdGVkX2NvbnRlbnRcIl0sXG4gICAgLi4uKG9wdGlvbnMuc2VydmljZVRpZXIgPyB7IHNlcnZpY2VfdGllcjogb3B0aW9ucy5zZXJ2aWNlVGllciB9IDoge30pLFxuICAgIC4uLihvcHRpb25zLnByb21wdENhY2hlS2V5ID8geyBwcm9tcHRfY2FjaGVfa2V5OiBvcHRpb25zLnByb21wdENhY2hlS2V5IH0gOiB7fSksXG4gICAgLi4uKHRleHQgPyB7IHRleHQgfSA6IHt9KSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQ29kZXhJZGVudGl0eUhlYWRlcnMoXG4gIGFjY2Vzc1Rva2VuOiBzdHJpbmcsXG4gIGFjY291bnRJZDogc3RyaW5nLFxuICBjb3JyZWxhdGlvbj86IHsgc2Vzc2lvbklkPzogc3RyaW5nOyB0aHJlYWRJZD86IHN0cmluZzsgY2xpZW50UmVxdWVzdElkPzogc3RyaW5nIH0sXG4pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgcmV0dXJuIHtcbiAgICBBY2NlcHQ6IFwidGV4dC9ldmVudC1zdHJlYW1cIixcbiAgICBBdXRob3JpemF0aW9uOiBgQmVhcmVyICR7YWNjZXNzVG9rZW59YCxcbiAgICBcIkNoYXRHUFQtQWNjb3VudC1JRFwiOiBhY2NvdW50SWQsXG4gICAgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgb3JpZ2luYXRvcjogQ09ERVhfQ0xJX09SSUdJTkFUT1IsXG4gICAgXCJVc2VyLUFnZW50XCI6IGNvZGV4Q2xpVXNlckFnZW50KCksXG4gICAgLi4uKGNvcnJlbGF0aW9uPy5zZXNzaW9uSWQgPyB7IFwic2Vzc2lvbi1pZFwiOiBjb3JyZWxhdGlvbi5zZXNzaW9uSWQgfSA6IHt9KSxcbiAgICAuLi4oY29ycmVsYXRpb24/LnRocmVhZElkID8geyBcInRocmVhZC1pZFwiOiBjb3JyZWxhdGlvbi50aHJlYWRJZCB9IDoge30pLFxuICAgIC4uLihjb3JyZWxhdGlvbj8uY2xpZW50UmVxdWVzdElkID8geyBcIngtY2xpZW50LXJlcXVlc3QtaWRcIjogY29ycmVsYXRpb24uY2xpZW50UmVxdWVzdElkIH0gOiB7fSksXG4gIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlbkFJVXNhZ2Uge1xuICBpbnB1dFRva2VuczogbnVtYmVyO1xuICBjYWNoZWRJbnB1dFRva2VuczogbnVtYmVyO1xuICBvdXRwdXRUb2tlbnM6IG51bWJlcjtcbiAgcmVhc29uaW5nVG9rZW5zOiBudW1iZXI7XG4gIHRvdGFsVG9rZW5zOiBudW1iZXI7XG59XG5cbmV4cG9ydCB0eXBlIE9wZW5BSU5vcm1hbGl6ZWRFdmVudCA9XG4gIHwgeyB0eXBlOiBcImNyZWF0ZWRcIjsgcmVzcG9uc2VJZD86IHN0cmluZyB9XG4gIHwgeyB0eXBlOiBcInRleHQtZGVsdGFcIjsgdGV4dDogc3RyaW5nOyBpdGVtSWQ/OiBzdHJpbmcgfVxuICB8IHtcbiAgICAgIHR5cGU6IFwiaW1hZ2VcIjtcbiAgICAgIGlkPzogc3RyaW5nO1xuICAgICAgYmFzZTY0OiBzdHJpbmc7XG4gICAgICBtaW1lVHlwZTogXCJpbWFnZS9wbmdcIiB8IFwiaW1hZ2UvanBlZ1wiIHwgXCJpbWFnZS93ZWJwXCI7XG4gICAgICByZXZpc2VkUHJvbXB0Pzogc3RyaW5nO1xuICAgICAgZ2VuZXJhdGlvbj86IEltYWdlR2VuZXJhdGlvbk1ldGFkYXRhO1xuICAgIH1cbiAgfCB7IHR5cGU6IFwib3V0cHV0LWl0ZW1cIjsgaXRlbTogT3BlbkFJUmVzcG9uc2VJdGVtOyBjb21wbGV0ZWQ/OiBib29sZWFuIH1cbiAgfCB7XG4gICAgICB0eXBlOiBcImNvbXBsZXRlZFwiO1xuICAgICAgcmVzcG9uc2VJZDogc3RyaW5nO1xuICAgICAgdXNhZ2U/OiBPcGVuQUlVc2FnZTtcbiAgICAgIG1vZGVsPzogc3RyaW5nO1xuICAgICAgaW1hZ2VHZW5lcmF0aW9uPzogSW1hZ2VHZW5lcmF0aW9uTWV0YWRhdGE7XG4gICAgfVxuICB8IHsgdHlwZTogXCJlcnJvclwiOyBlcnJvcjogT3BlbkFJUHJvdG9jb2xFcnJvciB9O1xuXG5leHBvcnQgY2xhc3MgT3BlbkFJUHJvdG9jb2xFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IoXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICAgIHB1YmxpYyByZWFkb25seSBjb2RlPzogc3RyaW5nLFxuICAgIHB1YmxpYyByZWFkb25seSBzdGF0dXM/OiBudW1iZXIsXG4gICAgcHVibGljIHJlYWRvbmx5IHJldHJ5QWZ0ZXJNcz86IG51bWJlcixcbiAgKSB7XG4gICAgc3VwZXIobWVzc2FnZSk7XG4gICAgdGhpcy5uYW1lID0gXCJPcGVuQUlQcm90b2NvbEVycm9yXCI7XG4gIH1cbn1cblxuZnVuY3Rpb24gdXNhZ2VGcm9tKHZhbHVlOiB1bmtub3duKTogT3BlbkFJVXNhZ2UgfCB1bmRlZmluZWQge1xuICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIikgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgdXNhZ2UgPSB2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgY29uc3QgaW5wdXREZXRhaWxzID0gKHVzYWdlLmlucHV0X3Rva2Vuc19kZXRhaWxzID8/IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgY29uc3Qgb3V0cHV0RGV0YWlscyA9ICh1c2FnZS5vdXRwdXRfdG9rZW5zX2RldGFpbHMgPz8ge30pIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICByZXR1cm4ge1xuICAgIGlucHV0VG9rZW5zOiBOdW1iZXIodXNhZ2UuaW5wdXRfdG9rZW5zID8/IDApLFxuICAgIGNhY2hlZElucHV0VG9rZW5zOiBOdW1iZXIoaW5wdXREZXRhaWxzLmNhY2hlZF90b2tlbnMgPz8gMCksXG4gICAgb3V0cHV0VG9rZW5zOiBOdW1iZXIodXNhZ2Uub3V0cHV0X3Rva2VucyA/PyAwKSxcbiAgICByZWFzb25pbmdUb2tlbnM6IE51bWJlcihvdXRwdXREZXRhaWxzLnJlYXNvbmluZ190b2tlbnMgPz8gMCksXG4gICAgdG90YWxUb2tlbnM6IE51bWJlcih1c2FnZS50b3RhbF90b2tlbnMgPz8gMCksXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpbWFnZU1pbWVUeXBlKFxuICBiYXNlNjQ6IHN0cmluZyxcbiAgb3V0cHV0Rm9ybWF0PzogdW5rbm93bixcbik6IFwiaW1hZ2UvcG5nXCIgfCBcImltYWdlL2pwZWdcIiB8IFwiaW1hZ2Uvd2VicFwiIHtcbiAgLy8gSW5zcGVjdCBvbmx5IHRoZSBoZWFkZXIsIHdpdGhvdXQgZGVjb2RpbmcgYSBwb3RlbnRpYWxseSBsYXJnZSBpbWFnZSB0d2ljZS5cbiAgY29uc3QgaGVhZGVyID0gQnVmZmVyLmZyb20oYmFzZTY0LnNsaWNlKDAsIDI0KSwgXCJiYXNlNjRcIik7XG4gIGlmIChoZWFkZXIuc3ViYXJyYXkoMCwgOCkuZXF1YWxzKEJ1ZmZlci5mcm9tKFsxMzcsIDgwLCA3OCwgNzEsIDEzLCAxMCwgMjYsIDEwXSkpKVxuICAgIHJldHVybiBcImltYWdlL3BuZ1wiO1xuICBpZiAoaGVhZGVyWzBdID09PSAyNTUgJiYgaGVhZGVyWzFdID09PSAyMTYgJiYgaGVhZGVyWzJdID09PSAyNTUpIHJldHVybiBcImltYWdlL2pwZWdcIjtcbiAgaWYgKGhlYWRlci50b1N0cmluZyhcImFzY2lpXCIsIDAsIDQpID09PSBcIlJJRkZcIiAmJiBoZWFkZXIudG9TdHJpbmcoXCJhc2NpaVwiLCA4LCAxMikgPT09IFwiV0VCUFwiKVxuICAgIHJldHVybiBcImltYWdlL3dlYnBcIjtcbiAgaWYgKG91dHB1dEZvcm1hdCA9PT0gXCJqcGVnXCIpIHJldHVybiBcImltYWdlL2pwZWdcIjtcbiAgaWYgKG91dHB1dEZvcm1hdCA9PT0gXCJ3ZWJwXCIpIHJldHVybiBcImltYWdlL3dlYnBcIjtcbiAgaWYgKG91dHB1dEZvcm1hdCA9PT0gdW5kZWZpbmVkIHx8IG91dHB1dEZvcm1hdCA9PT0gXCJwbmdcIikgcmV0dXJuIFwiaW1hZ2UvcG5nXCI7XG4gIHRocm93IG5ldyBPcGVuQUlQcm90b2NvbEVycm9yKGBVbnN1cHBvcnRlZCBpbWFnZSBvdXRwdXQgZm9ybWF0OiAke1N0cmluZyhvdXRwdXRGb3JtYXQpfWApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplT3BlbkFJRXZlbnQocmF3OiB1bmtub3duKTogT3BlbkFJTm9ybWFsaXplZEV2ZW50IHwgdW5kZWZpbmVkIHtcbiAgaWYgKCFyYXcgfHwgdHlwZW9mIHJhdyAhPT0gXCJvYmplY3RcIikgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgZXZlbnQgPSByYXcgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gIGNvbnN0IHR5cGUgPSBTdHJpbmcoZXZlbnQudHlwZSA/PyBcIlwiKTtcbiAgaWYgKHR5cGUgPT09IFwicmVzcG9uc2UuY3JlYXRlZFwiKSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBldmVudC5yZXNwb25zZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB8IHVuZGVmaW5lZDtcbiAgICByZXR1cm4geyB0eXBlOiBcImNyZWF0ZWRcIiwgLi4uKHJlc3BvbnNlPy5pZCA/IHsgcmVzcG9uc2VJZDogU3RyaW5nKHJlc3BvbnNlLmlkKSB9IDoge30pIH07XG4gIH1cbiAgaWYgKHR5cGUgPT09IFwicmVzcG9uc2Uub3V0cHV0X3RleHQuZGVsdGFcIiAmJiB0eXBlb2YgZXZlbnQuZGVsdGEgPT09IFwic3RyaW5nXCIpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogXCJ0ZXh0LWRlbHRhXCIsXG4gICAgICB0ZXh0OiBldmVudC5kZWx0YSxcbiAgICAgIC4uLih0eXBlb2YgZXZlbnQuaXRlbV9pZCA9PT0gXCJzdHJpbmdcIiA/IHsgaXRlbUlkOiBldmVudC5pdGVtX2lkIH0gOiB7fSksXG4gICAgfTtcbiAgfVxuICBpZiAoXG4gICAgKHR5cGUgPT09IFwicmVzcG9uc2Uub3V0cHV0X2l0ZW0uYWRkZWRcIiB8fCB0eXBlID09PSBcInJlc3BvbnNlLm91dHB1dF9pdGVtLmRvbmVcIikgJiZcbiAgICBldmVudC5pdGVtICYmXG4gICAgdHlwZW9mIGV2ZW50Lml0ZW0gPT09IFwib2JqZWN0XCJcbiAgKSB7XG4gICAgY29uc3QgaXRlbSA9IGV2ZW50Lml0ZW0gYXMgT3BlbkFJUmVzcG9uc2VJdGVtO1xuICAgIGlmIChpdGVtLnR5cGUgPT09IFwiaW1hZ2VfZ2VuZXJhdGlvbl9jYWxsXCIgJiYgdHlwZW9mIGl0ZW0ucmVzdWx0ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAvLyBQTkcgZXhwb3NlcyBkaW1lbnNpb25zIGluIGl0cyBmaXhlZCBoZWFkZXIuIE90aGVyIGZvcm1hdHMgcmV0YWluIHRoZVxuICAgICAgLy8gYmFja2VuZCdzIG9ic2VydmVkIHNpemU7IG5ldmVyIHN1YnN0aXR1dGUgcmVxdWVzdGVkIGltYWdlIGNvbnRyb2xzLlxuICAgICAgY29uc3QgaGVhZGVyID0gQnVmZmVyLmZyb20oaXRlbS5yZXN1bHQuc2xpY2UoMCwgMzIpLCBcImJhc2U2NFwiKTtcbiAgICAgIGNvbnN0IHBuZ1NpemUgPVxuICAgICAgICBoZWFkZXIubGVuZ3RoID49IDI0ICYmXG4gICAgICAgIGhlYWRlci5zdWJhcnJheSgwLCA4KS5lcXVhbHMoQnVmZmVyLmZyb20oXCI4OTUwNGU0NzBkMGExYTBhXCIsIFwiaGV4XCIpKSAmJlxuICAgICAgICBoZWFkZXIucmVhZFVJbnQzMkJFKDE2KSA+IDAgJiZcbiAgICAgICAgaGVhZGVyLnJlYWRVSW50MzJCRSgyMCkgPiAwXG4gICAgICAgICAgPyBgJHtoZWFkZXIucmVhZFVJbnQzMkJFKDE2KX14JHtoZWFkZXIucmVhZFVJbnQzMkJFKDIwKX1gXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBzaXplID1cbiAgICAgICAgcG5nU2l6ZSA/P1xuICAgICAgICAodHlwZW9mIGl0ZW0uc2l6ZSA9PT0gXCJzdHJpbmdcIiAmJiAvXlsxLTldXFxkKnhbMS05XVxcZCokLy50ZXN0KGl0ZW0uc2l6ZSlcbiAgICAgICAgICA/IGl0ZW0uc2l6ZVxuICAgICAgICAgIDogdW5kZWZpbmVkKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IFwiaW1hZ2VcIixcbiAgICAgICAgLi4uKHR5cGVvZiBpdGVtLmlkID09PSBcInN0cmluZ1wiID8geyBpZDogaXRlbS5pZCB9IDoge30pLFxuICAgICAgICBiYXNlNjQ6IGl0ZW0ucmVzdWx0LFxuICAgICAgICBtaW1lVHlwZTogaW1hZ2VNaW1lVHlwZShpdGVtLnJlc3VsdCwgaXRlbS5vdXRwdXRfZm9ybWF0KSxcbiAgICAgICAgZ2VuZXJhdGlvbjoge1xuICAgICAgICAgIHJvdXRlOiBcImNvZGV4LXJlc3BvbnNlc1wiLFxuICAgICAgICAgIC4uLihzaXplID8geyBzaXplIH0gOiB7fSksXG4gICAgICAgICAgLi4uKHR5cGVvZiBpdGVtLm1vZGVsID09PSBcInN0cmluZ1wiID8geyBtb2RlbDogaXRlbS5tb2RlbCB9IDoge30pLFxuICAgICAgICAgIC4uLih0eXBlb2YgaXRlbS5xdWFsaXR5ID09PSBcInN0cmluZ1wiID8geyBxdWFsaXR5OiBpdGVtLnF1YWxpdHkgfSA6IHt9KSxcbiAgICAgICAgICAuLi4odHlwZW9mIGl0ZW0uYmFja2dyb3VuZCA9PT0gXCJzdHJpbmdcIiA/IHsgYmFja2dyb3VuZDogaXRlbS5iYWNrZ3JvdW5kIH0gOiB7fSksXG4gICAgICAgIH0sXG4gICAgICAgIC4uLih0eXBlb2YgaXRlbS5yZXZpc2VkX3Byb21wdCA9PT0gXCJzdHJpbmdcIlxuICAgICAgICAgID8geyByZXZpc2VkUHJvbXB0OiBpdGVtLnJldmlzZWRfcHJvbXB0IH1cbiAgICAgICAgICA6IHR5cGVvZiBpdGVtLnJldmlzZWRQcm9tcHQgPT09IFwic3RyaW5nXCJcbiAgICAgICAgICAgID8geyByZXZpc2VkUHJvbXB0OiBpdGVtLnJldmlzZWRQcm9tcHQgfVxuICAgICAgICAgICAgOiB7fSksXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4geyB0eXBlOiBcIm91dHB1dC1pdGVtXCIsIGl0ZW0sIGNvbXBsZXRlZDogdHlwZSA9PT0gXCJyZXNwb25zZS5vdXRwdXRfaXRlbS5kb25lXCIgfTtcbiAgfVxuICBpZiAodHlwZSA9PT0gXCJyZXNwb25zZS5jb21wbGV0ZWRcIikge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gKGV2ZW50LnJlc3BvbnNlID8/IHt9KSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICBjb25zdCB0b29sVXNhZ2UgPSByZXNwb25zZS50b29sX3VzYWdlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IHBhcnNlZEltYWdlVXNhZ2UgPSBJbWFnZUdlbmVyYXRpb25NZXRhZGF0YS5zaGFwZS51c2FnZS5zYWZlUGFyc2UodG9vbFVzYWdlPy5pbWFnZV9nZW4pO1xuICAgIGNvbnN0IGltYWdlVXNhZ2UgPSBwYXJzZWRJbWFnZVVzYWdlLnN1Y2Nlc3MgPyBwYXJzZWRJbWFnZVVzYWdlLmRhdGEgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgaW1hZ2VUb29sID0gQXJyYXkuaXNBcnJheShyZXNwb25zZS50b29scylcbiAgICAgID8gcmVzcG9uc2UudG9vbHMuZmluZCgodG9vbCkgPT4gdG9vbD8udHlwZSA9PT0gXCJpbWFnZV9nZW5lcmF0aW9uXCIpXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBpbWFnZU1vZGVsID0gdHlwZW9mIGltYWdlVG9vbD8ubW9kZWwgPT09IFwic3RyaW5nXCIgPyBpbWFnZVRvb2wubW9kZWwgOiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IFwiY29tcGxldGVkXCIsXG4gICAgICByZXNwb25zZUlkOiBTdHJpbmcocmVzcG9uc2UuaWQgPz8gXCJcIiksXG4gICAgICAuLi4ocmVzcG9uc2UudXNhZ2UgPyB7IHVzYWdlOiB1c2FnZUZyb20ocmVzcG9uc2UudXNhZ2UpIH0gOiB7fSksXG4gICAgICAuLi4odHlwZW9mIHJlc3BvbnNlLm1vZGVsID09PSBcInN0cmluZ1wiID8geyBtb2RlbDogcmVzcG9uc2UubW9kZWwgfSA6IHt9KSxcbiAgICAgIC4uLihpbWFnZVVzYWdlIHx8IGltYWdlTW9kZWxcbiAgICAgICAgPyB7XG4gICAgICAgICAgICBpbWFnZUdlbmVyYXRpb246IHtcbiAgICAgICAgICAgICAgcm91dGU6IFwiY29kZXgtcmVzcG9uc2VzXCIgYXMgY29uc3QsXG4gICAgICAgICAgICAgIC4uLihpbWFnZU1vZGVsID8geyBtb2RlbDogaW1hZ2VNb2RlbCB9IDoge30pLFxuICAgICAgICAgICAgICAuLi4oaW1hZ2VVc2FnZSA/IHsgdXNhZ2U6IGltYWdlVXNhZ2UgfSA6IHt9KSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfVxuICAgICAgICA6IHt9KSxcbiAgICB9O1xuICB9XG4gIGlmICh0eXBlID09PSBcImVycm9yXCIgfHwgdHlwZSA9PT0gXCJyZXNwb25zZS5mYWlsZWRcIiB8fCB0eXBlID09PSBcInJlc3BvbnNlLmluY29tcGxldGVcIikge1xuICAgIGNvbnN0IHNvdXJjZSA9IChldmVudC5lcnJvciA/PyBldmVudC5yZXNwb25zZSA/PyBldmVudCkgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgY29uc3QgbmVzdGVkID0gKHNvdXJjZS5lcnJvciA/PyBzb3VyY2UpIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBcImVycm9yXCIsXG4gICAgICBlcnJvcjogbmV3IE9wZW5BSVByb3RvY29sRXJyb3IoXG4gICAgICAgIFN0cmluZyhuZXN0ZWQubWVzc2FnZSA/PyBgT3BlbkFJIHN0cmVhbSBlbmRlZCB3aXRoICR7dHlwZX1gKSxcbiAgICAgICAgdHlwZW9mIG5lc3RlZC5jb2RlID09PSBcInN0cmluZ1wiID8gbmVzdGVkLmNvZGUgOiB1bmRlZmluZWQsXG4gICAgICApLFxuICAgIH07XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7O0FBS0EsTUFBYSw4QkFD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
215
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLWJhY2tlbmQtcHJvdG9jb2wuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9vcGVuYWkvb3BlbmFpLWJhY2tlbmQtcHJvdG9jb2wudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IG9zIGZyb20gXCJub2RlOm9zXCI7XG5cbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmltcG9ydCB7IEltYWdlR2VuZXJhdGlvbk1ldGFkYXRhIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLnR5cGVzXCI7XG5pbXBvcnQgeyB0eXBlIE9wZW5BSUVmZm9ydCB9IGZyb20gXCIuLi9jb21tb24vZWZmb3J0XCI7XG5pbXBvcnQge1xuICBpc0pzb25PYmplY3QsXG4gIHR5cGUgSnNvbk9iamVjdCxcbiAgdHlwZSBKc29uVmFsdWUsXG4gIGpzb25TdHJpbmcsXG59IGZyb20gXCIuLi9jb21tb24vcHJvdmlkZXItdHlwZXNcIjtcblxuZXhwb3J0IHsgdHlwZSBKc29uVmFsdWUgfSBmcm9tIFwiLi4vY29tbW9uL3Byb3ZpZGVyLXR5cGVzXCI7XG5cbmV4cG9ydCBjb25zdCBDSEFUR1BUX0NPREVYX1JFU1BPTlNFU19VUkwgPVxuICBcImh0dHBzOi8vY2hhdGdwdC5jb20vYmFja2VuZC1hcGkvY29kZXgvcmVzcG9uc2VzXCIgYXMgY29uc3Q7XG5cbmV4cG9ydCBjb25zdCBDT0RFWF9DTElfT1JJR0lOQVRPUiA9IFwiY29kZXhfY2xpX3JzXCIgYXMgY29uc3Q7XG5leHBvcnQgY29uc3QgQ09ERVhfQ0xJX1ZFUlNJT04gPSBcIjAuMTQ3LjBcIiBhcyBjb25zdDtcblxuZXhwb3J0IGludGVyZmFjZSBDb2RleFVzZXJBZ2VudFBsYXRmb3JtIHtcbiAgb3NUeXBlOiBzdHJpbmc7XG4gIG9zVmVyc2lvbjogc3RyaW5nO1xuICBhcmNoaXRlY3R1cmU6IHN0cmluZztcbiAgdGVybWluYWw6IHN0cmluZztcbn1cblxuZnVuY3Rpb24gY29kZXhQbGF0Zm9ybSgpOiBDb2RleFVzZXJBZ2VudFBsYXRmb3JtIHtcbiAgY29uc3QgbmFtZXM6IFBhcnRpYWw8UmVjb3JkPE5vZGVKUy5QbGF0Zm9ybSwgc3RyaW5nPj4gPSB7XG4gICAgZGFyd2luOiBcIk1hYyBPU1wiLFxuICAgIGxpbnV4OiBcIkxpbnV4XCIsXG4gICAgd2luMzI6IFwiV2luZG93c1wiLFxuICB9O1xuXG4gIGNvbnN0IHRlcm1pbmFsID0gcHJvY2Vzcy5lbnYuVEVSTV9QUk9HUkFNO1xuICBjb25zdCB0ZXJtaW5hbFZlcnNpb24gPSBwcm9jZXNzLmVudi5URVJNX1BST0dSQU1fVkVSU0lPTjtcblxuICByZXR1cm4ge1xuICAgIG9zVHlwZTogbmFtZXNbcHJvY2Vzcy5wbGF0Zm9ybV0gPz8gcHJvY2Vzcy5wbGF0Zm9ybSxcbiAgICBvc1ZlcnNpb246IG9zLnJlbGVhc2UoKSxcbiAgICBhcmNoaXRlY3R1cmU6IHByb2Nlc3MuYXJjaCxcbiAgICB0ZXJtaW5hbDogdGVybWluYWwgPyBgJHt0ZXJtaW5hbH0ke3Rlcm1pbmFsVmVyc2lvbiA/IGAvJHt0ZXJtaW5hbFZlcnNpb259YCA6IFwiXCJ9YCA6IFwidW5rbm93blwiLFxuICB9O1xufVxuXG4vKiogTWF0Y2hlcyB0aGUgcGxhdGZvcm0vdGVybWluYWwgc3VmZml4IGVtaXR0ZWQgYnkgdGhlIHBpbm5lZCBSdXN0IENvZGV4IENMSS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb2RleENsaVVzZXJBZ2VudChwbGF0Zm9ybTogQ29kZXhVc2VyQWdlbnRQbGF0Zm9ybSA9IGNvZGV4UGxhdGZvcm0oKSk6IHN0cmluZyB7XG4gIHJldHVybiBgY29kZXhfY2xpX3JzLyR7Q09ERVhfQ0xJX1ZFUlNJT059ICgke3BsYXRmb3JtLm9zVHlwZX0gJHtwbGF0Zm9ybS5vc1ZlcnNpb259OyAke3BsYXRmb3JtLmFyY2hpdGVjdHVyZX0pICR7cGxhdGZvcm0udGVybWluYWx9YDtcbn1cblxuLyoqIFJhdyBSZXNwb25zZXMgQVBJIGl0ZW1zLiBLZWVwaW5nIHRoZXNlIG9wYXF1ZSBwcmVzZXJ2ZXMgdGhlIGNvbXBsZXRlIGNvbnZlcnNhdGlvbiBoaXN0b3J5LiAqL1xuZXhwb3J0IHR5cGUgT3BlbkFJUmVzcG9uc2VJdGVtID0gSnNvbk9iamVjdDtcblxuZXhwb3J0IGludGVyZmFjZSBPcGVuQUlPdXRwdXRTY2hlbWEge1xuICBuYW1lPzogc3RyaW5nO1xuICBzY2hlbWE6IEpzb25WYWx1ZTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcGVuQUlSZXNwb25zZXNPcHRpb25zIHtcbiAgbW9kZWw6IHN0cmluZztcbiAgaW5zdHJ1Y3Rpb25zPzogc3RyaW5nO1xuICAvKiogUmF3IGNvbnZlcnNhdGlvbiBpdGVtcywgZm9yd2FyZGVkIHVuY2hhbmdlZC4gKi9cbiAgaGlzdG9yeTogcmVhZG9ubHkgSnNvblZhbHVlW107XG4gIHRvb2xzPzogcmVhZG9ubHkgT3BlbkFJUmVzcG9uc2VJdGVtW107XG4gIHRvb2xDaG9pY2U/OiBzdHJpbmcgfCBPcGVuQUlSZXNwb25zZUl0ZW07XG4gIHBhcmFsbGVsVG9vbENhbGxzPzogYm9vbGVhbjtcbiAgcmVhc29uaW5nPzoge1xuICAgIGVmZm9ydD86IE9wZW5BSUVmZm9ydCB8IFwibm9uZVwiO1xuICAgIHN1bW1hcnk/OiBcImF1dG9cIiB8IFwiY29uY2lzZVwiIHwgXCJkZXRhaWxlZFwiO1xuICB9O1xuICB2ZXJib3NpdHk/OiBcImxvd1wiIHwgXCJtZWRpdW1cIiB8IFwiaGlnaFwiO1xuICBzZXJ2aWNlVGllcj86IHN0cmluZztcbiAgcHJvbXB0Q2FjaGVLZXk/OiBzdHJpbmc7XG4gIG91dHB1dFNjaGVtYT86IE9wZW5BSU91dHB1dFNjaGVtYTtcbiAgaW1hZ2VHZW5lcmF0aW9uPzogYm9vbGVhbiB8IE9wZW5BSVJlc3BvbnNlSXRlbTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcGVuQUlSZXNwb25zZXNSZXF1ZXN0IHtcbiAgbW9kZWw6IHN0cmluZztcbiAgaW5zdHJ1Y3Rpb25zPzogc3RyaW5nO1xuICBpbnB1dDogSnNvblZhbHVlW107XG4gIHRvb2xzPzogT3BlbkFJUmVzcG9uc2VJdGVtW107XG4gIHRvb2xfY2hvaWNlOiBzdHJpbmcgfCBPcGVuQUlSZXNwb25zZUl0ZW07XG4gIHBhcmFsbGVsX3Rvb2xfY2FsbHM6IGJvb2xlYW47XG4gIHJlYXNvbmluZzogT3BlbkFJUmVzcG9uc2VzT3B0aW9uc1tcInJlYXNvbmluZ1wiXSB8IG51bGw7XG4gIHN0b3JlOiBmYWxzZTtcbiAgc3RyZWFtOiB0cnVlO1xuICBpbmNsdWRlOiBzdHJpbmdbXTtcbiAgc2VydmljZV90aWVyPzogc3RyaW5nO1xuICBwcm9tcHRfY2FjaGVfa2V5Pzogc3RyaW5nO1xuICB0ZXh0PzogT3BlbkFJUmVzcG9uc2VzVGV4dDtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBPcGVuQUlSZXNwb25zZXNUZXh0IHtcbiAgdmVyYm9zaXR5PzogXCJsb3dcIiB8IFwibWVkaXVtXCIgfCBcImhpZ2hcIjtcbiAgZm9ybWF0Pzoge1xuICAgIHR5cGU6IFwianNvbl9zY2hlbWFcIjtcbiAgICBzdHJpY3Q6IHRydWU7XG4gICAgc2NoZW1hOiBKc29uVmFsdWU7XG4gICAgbmFtZTogc3RyaW5nO1xuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRPcGVuQUlSZXNwb25zZXNSZXF1ZXN0KFxuICBvcHRpb25zOiBPcGVuQUlSZXNwb25zZXNPcHRpb25zLFxuKTogT3BlbkFJUmVzcG9uc2VzUmVxdWVzdCB7XG4gIGNvbnN0IHRvb2xzID0gb3B0aW9ucy50b29scyA/IFsuLi5vcHRpb25zLnRvb2xzXSA6IFtdO1xuXG4gIGlmIChvcHRpb25zLmltYWdlR2VuZXJhdGlvbikge1xuICAgIHRvb2xzLnB1c2goXG4gICAgICBvcHRpb25zLmltYWdlR2VuZXJhdGlvbiA9PT0gdHJ1ZVxuICAgICAgICA/IHsgdHlwZTogXCJpbWFnZV9nZW5lcmF0aW9uXCIgfVxuICAgICAgICA6IHsgdHlwZTogXCJpbWFnZV9nZW5lcmF0aW9uXCIsIC4uLm9wdGlvbnMuaW1hZ2VHZW5lcmF0aW9uIH0sXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IHJlcXVlc3Q6IE9wZW5BSVJlc3BvbnNlc1JlcXVlc3QgPSB7XG4gICAgbW9kZWw6IG9wdGlvbnMubW9kZWwsXG4gICAgLy8gQ29weSB0aGUgYXJyYXksIG5vdCBpdHMgaXRlbXM6IHJhdyBpdGVtcyBtdXN0IGFycml2ZSBieXRlLWZvci1ieXRlIGVxdWl2YWxlbnQuXG4gICAgaW5wdXQ6IFsuLi5vcHRpb25zLmhpc3RvcnldLFxuICAgIHRvb2xfY2hvaWNlOiBvcHRpb25zLnRvb2xDaG9pY2UgPz8gXCJhdXRvXCIsXG4gICAgcGFyYWxsZWxfdG9vbF9jYWxsczogb3B0aW9ucy5wYXJhbGxlbFRvb2xDYWxscyA/PyB0cnVlLFxuICAgIHJlYXNvbmluZzogb3B0aW9ucy5yZWFzb25pbmcgPz8gbnVsbCxcbiAgICBzdG9yZTogZmFsc2UsXG4gICAgc3RyZWFtOiB0cnVlLFxuICAgIGluY2x1ZGU6IFtcInJlYXNvbmluZy5lbmNyeXB0ZWRfY29udGVudFwiXSxcbiAgfTtcblxuICBpZiAob3B0aW9ucy5pbnN0cnVjdGlvbnMpIHJlcXVlc3QuaW5zdHJ1Y3Rpb25zID0gb3B0aW9ucy5pbnN0cnVjdGlvbnM7XG5cbiAgaWYgKHRvb2xzLmxlbmd0aCkgcmVxdWVzdC50b29scyA9IHRvb2xzO1xuXG4gIGlmIChvcHRpb25zLnNlcnZpY2VUaWVyKSByZXF1ZXN0LnNlcnZpY2VfdGllciA9IG9wdGlvbnMuc2VydmljZVRpZXI7XG5cbiAgaWYgKG9wdGlvbnMucHJvbXB0Q2FjaGVLZXkpIHJlcXVlc3QucHJvbXB0X2NhY2hlX2tleSA9IG9wdGlvbnMucHJvbXB0Q2FjaGVLZXk7XG5cbiAgaWYgKG9wdGlvbnMudmVyYm9zaXR5IHx8IG9wdGlvbnMub3V0cHV0U2NoZW1hKSB7XG4gICAgY29uc3QgdGV4dDogT3BlbkFJUmVzcG9uc2VzVGV4dCA9IHt9O1xuXG4gICAgaWYgKG9wdGlvbnMudmVyYm9zaXR5KSB0ZXh0LnZlcmJvc2l0eSA9IG9wdGlvbnMudmVyYm9zaXR5O1xuXG4gICAgaWYgKG9wdGlvbnMub3V0cHV0U2NoZW1hKSB7XG4gICAgICB0ZXh0LmZvcm1hdCA9IHtcbiAgICAgICAgdHlwZTogXCJqc29uX3NjaGVtYVwiLFxuICAgICAgICBzdHJpY3Q6IHRydWUsXG4gICAgICAgIHNjaGVtYTogb3B0aW9ucy5vdXRwdXRTY2hlbWEuc2NoZW1hLFxuICAgICAgICBuYW1lOiBvcHRpb25zLm91dHB1dFNjaGVtYS5uYW1lID8/IFwiY29kZXhfb3V0cHV0X3NjaGVtYVwiLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXF1ZXN0LnRleHQgPSB0ZXh0O1xuICB9XG5cbiAgcmV0dXJuIHJlcXVlc3Q7XG59XG5cbi8qKiBDb2RleCBDTEkgaWRlbnRpdHkgaGVhZGVyczsgY29ycmVsYXRpb24gaGVhZGVycyBhcmUgcHJlc2VudCBvbmx5IHdoZW4gc3VwcGxpZWQuICovXG5leHBvcnQgdHlwZSBDb2RleElkZW50aXR5SGVhZGVycyA9IHtcbiAgQWNjZXB0OiBcInRleHQvZXZlbnQtc3RyZWFtXCI7XG4gIEF1dGhvcml6YXRpb246IHN0cmluZztcbiAgXCJDaGF0R1BULUFjY291bnQtSURcIjogc3RyaW5nO1xuICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIjtcbiAgb3JpZ2luYXRvcjogdHlwZW9mIENPREVYX0NMSV9PUklHSU5BVE9SO1xuICBcIlVzZXItQWdlbnRcIjogc3RyaW5nO1xuICBcInNlc3Npb24taWRcIj86IHN0cmluZztcbiAgXCJ0aHJlYWQtaWRcIj86IHN0cmluZztcbiAgXCJ4LWNsaWVudC1yZXF1ZXN0LWlkXCI/OiBzdHJpbmc7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRDb2RleElkZW50aXR5SGVhZGVycyhcbiAgYWNjZXNzVG9rZW46IHN0cmluZyxcbiAgYWNjb3VudElkOiBzdHJpbmcsXG4gIGNvcnJlbGF0aW9uPzogeyBzZXNzaW9uSWQ/OiBzdHJpbmc7IHRocmVhZElkPzogc3RyaW5nOyBjbGllbnRSZXF1ZXN0SWQ/OiBzdHJpbmcgfSxcbik6IENvZGV4SWRlbnRpdHlIZWFkZXJzIHtcbiAgY29uc3QgaGVhZGVyczogQ29kZXhJZGVudGl0eUhlYWRlcnMgPSB7XG4gICAgQWNjZXB0OiBcInRleHQvZXZlbnQtc3RyZWFtXCIsXG4gICAgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke2FjY2Vzc1Rva2VufWAsXG4gICAgXCJDaGF0R1BULUFjY291bnQtSURcIjogYWNjb3VudElkLFxuICAgIFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgIG9yaWdpbmF0b3I6IENPREVYX0NMSV9PUklHSU5BVE9SLFxuICAgIFwiVXNlci1BZ2VudFwiOiBjb2RleENsaVVzZXJBZ2VudCgpLFxuICB9O1xuXG4gIGlmIChjb3JyZWxhdGlvbj8uc2Vzc2lvbklkKSBoZWFkZXJzW1wic2Vzc2lvbi1pZFwiXSA9IGNvcnJlbGF0aW9uLnNlc3Npb25JZDtcblxuICBpZiAoY29ycmVsYXRpb24/LnRocmVhZElkKSBoZWFkZXJzW1widGhyZWFkLWlkXCJdID0gY29ycmVsYXRpb24udGhyZWFkSWQ7XG5cbiAgaWYgKGNvcnJlbGF0aW9uPy5jbGllbnRSZXF1ZXN0SWQpIGhlYWRlcnNbXCJ4LWNsaWVudC1yZXF1ZXN0LWlkXCJdID0gY29ycmVsYXRpb24uY2xpZW50UmVxdWVzdElkO1xuXG4gIHJldHVybiBoZWFkZXJzO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE9wZW5BSVVzYWdlIHtcbiAgaW5wdXRUb2tlbnM6IG51bWJlcjtcbiAgY2FjaGVkSW5wdXRUb2tlbnM6IG51bWJlcjtcbiAgb3V0cHV0VG9rZW5zOiBudW1iZXI7XG4gIHJlYXNvbmluZ1Rva2VuczogbnVtYmVyO1xuICB0b3RhbFRva2VuczogbnVtYmVyO1xufVxuXG5leHBvcnQgdHlwZSBPcGVuQUlOb3JtYWxpemVkRXZlbnQgPVxuICB8IHsgdHlwZTogXCJjcmVhdGVkXCI7IHJlc3BvbnNlSWQ/OiBzdHJpbmcgfVxuICB8IHsgdHlwZTogXCJ0ZXh0LWRlbHRhXCI7IHRleHQ6IHN0cmluZzsgaXRlbUlkPzogc3RyaW5nIH1cbiAgfCB7XG4gICAgICB0eXBlOiBcImltYWdlXCI7XG4gICAgICBpZD86IHN0cmluZztcbiAgICAgIGJhc2U2NDogc3RyaW5nO1xuICAgICAgbWltZVR5cGU6IFwiaW1hZ2UvcG5nXCIgfCBcImltYWdlL2pwZWdcIiB8IFwiaW1hZ2Uvd2VicFwiO1xuICAgICAgcmV2aXNlZFByb21wdD86IHN0cmluZztcbiAgICAgIGdlbmVyYXRpb24/OiBJbWFnZUdlbmVyYXRpb25NZXRhZGF0YTtcbiAgICB9XG4gIHwgeyB0eXBlOiBcIm91dHB1dC1pdGVtXCI7IGl0ZW06IE9wZW5BSVJlc3BvbnNlSXRlbTsgY29tcGxldGVkPzogYm9vbGVhbiB9XG4gIHwge1xuICAgICAgdHlwZTogXCJjb21wbGV0ZWRcIjtcbiAgICAgIHJlc3BvbnNlSWQ6IHN0cmluZztcbiAgICAgIHVzYWdlPzogT3BlbkFJVXNhZ2U7XG4gICAgICBtb2RlbD86IHN0cmluZztcbiAgICAgIGltYWdlR2VuZXJhdGlvbj86IEltYWdlR2VuZXJhdGlvbk1ldGFkYXRhO1xuICAgIH1cbiAgfCB7IHR5cGU6IFwiZXJyb3JcIjsgZXJyb3I6IE9wZW5BSVByb3RvY29sRXJyb3IgfTtcblxuZXhwb3J0IGNsYXNzIE9wZW5BSVByb3RvY29sRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIG1lc3NhZ2U6IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgY29kZT86IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgc3RhdHVzPzogbnVtYmVyLFxuICAgIHB1YmxpYyByZWFkb25seSByZXRyeUFmdGVyTXM/OiBudW1iZXIsXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMubmFtZSA9IFwiT3BlbkFJUHJvdG9jb2xFcnJvclwiO1xuICB9XG59XG5cbmNvbnN0IHRva2VuQ291bnQgPSB6LmNvZXJjZS5udW1iZXIoKS5jYXRjaCgwKTtcblxuZnVuY3Rpb24ganNvbk9iamVjdE9yRW1wdHkodmFsdWU6IEpzb25WYWx1ZSB8IHVuZGVmaW5lZCk6IEpzb25PYmplY3Qge1xuICByZXR1cm4gaXNKc29uT2JqZWN0KHZhbHVlKSA/IHZhbHVlIDoge307XG59XG5cbmZ1bmN0aW9uIHVzYWdlRnJvbSh2YWx1ZTogSnNvbk9iamVjdCk6IE9wZW5BSVVzYWdlIHtcbiAgY29uc3QgaW5wdXREZXRhaWxzID0ganNvbk9iamVjdE9yRW1wdHkodmFsdWUuaW5wdXRfdG9rZW5zX2RldGFpbHMpO1xuICBjb25zdCBvdXRwdXREZXRhaWxzID0ganNvbk9iamVjdE9yRW1wdHkodmFsdWUub3V0cHV0X3Rva2Vuc19kZXRhaWxzKTtcblxuICByZXR1cm4ge1xuICAgIGlucHV0VG9rZW5zOiB0b2tlbkNvdW50LnBhcnNlKHZhbHVlLmlucHV0X3Rva2VucyA/PyAwKSxcbiAgICBjYWNoZWRJbnB1dFRva2VuczogdG9rZW5Db3VudC5wYXJzZShpbnB1dERldGFpbHMuY2FjaGVkX3Rva2VucyA/PyAwKSxcbiAgICBvdXRwdXRUb2tlbnM6IHRva2VuQ291bnQucGFyc2UodmFsdWUub3V0cHV0X3Rva2VucyA/PyAwKSxcbiAgICByZWFzb25pbmdUb2tlbnM6IHRva2VuQ291bnQucGFyc2Uob3V0cHV0RGV0YWlscy5yZWFzb25pbmdfdG9rZW5zID8/IDApLFxuICAgIHRvdGFsVG9rZW5zOiB0b2tlbkNvdW50LnBhcnNlKHZhbHVlLnRvdGFsX3Rva2VucyA/PyAwKSxcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGltYWdlTWltZVR5cGUoXG4gIGJhc2U2NDogc3RyaW5nLFxuICBvdXRwdXRGb3JtYXQ/OiBKc29uVmFsdWUsXG4pOiBcImltYWdlL3BuZ1wiIHwgXCJpbWFnZS9qcGVnXCIgfCBcImltYWdlL3dlYnBcIiB7XG4gIC8vIEluc3BlY3Qgb25seSB0aGUgaGVhZGVyLCB3aXRob3V0IGRlY29kaW5nIGEgcG90ZW50aWFsbHkgbGFyZ2UgaW1hZ2UgdHdpY2UuXG4gIGNvbnN0IGhlYWRlciA9IEJ1ZmZlci5mcm9tKGJhc2U2NC5zbGljZSgwLCAyNCksIFwiYmFzZTY0XCIpO1xuXG4gIGlmIChoZWFkZXIuc3ViYXJyYXkoMCwgOCkuZXF1YWxzKEJ1ZmZlci5mcm9tKFsxMzcsIDgwLCA3OCwgNzEsIDEzLCAxMCwgMjYsIDEwXSkpKVxuICAgIHJldHVybiBcImltYWdlL3BuZ1wiO1xuXG4gIGlmIChoZWFkZXJbMF0gPT09IDI1NSAmJiBoZWFkZXJbMV0gPT09IDIxNiAmJiBoZWFkZXJbMl0gPT09IDI1NSkgcmV0dXJuIFwiaW1hZ2UvanBlZ1wiO1xuXG4gIGlmIChoZWFkZXIudG9TdHJpbmcoXCJhc2NpaVwiLCAwLCA0KSA9PT0gXCJSSUZGXCIgJiYgaGVhZGVyLnRvU3RyaW5nKFwiYXNjaWlcIiwgOCwgMTIpID09PSBcIldFQlBcIilcbiAgICByZXR1cm4gXCJpbWFnZS93ZWJwXCI7XG5cbiAgaWYgKG91dHB1dEZvcm1hdCA9PT0gXCJqcGVnXCIpIHJldHVybiBcImltYWdlL2pwZWdcIjtcblxuICBpZiAob3V0cHV0Rm9ybWF0ID09PSBcIndlYnBcIikgcmV0dXJuIFwiaW1hZ2Uvd2VicFwiO1xuXG4gIGlmIChvdXRwdXRGb3JtYXQgPT09IHVuZGVmaW5lZCB8fCBvdXRwdXRGb3JtYXQgPT09IFwicG5nXCIpIHJldHVybiBcImltYWdlL3BuZ1wiO1xuICBjb25zdCBsYWJlbCA9IGpzb25TdHJpbmcob3V0cHV0Rm9ybWF0KSA/PyBKU09OLnN0cmluZ2lmeShvdXRwdXRGb3JtYXQpO1xuICB0aHJvdyBuZXcgT3BlbkFJUHJvdG9jb2xFcnJvcihgVW5zdXBwb3J0ZWQgaW1hZ2Ugb3V0cHV0IGZvcm1hdDogJHtsYWJlbH1gKTtcbn1cblxudHlwZSBPcGVuQUlJbWFnZUV2ZW50ID0gRXh0cmFjdDxPcGVuQUlOb3JtYWxpemVkRXZlbnQsIHsgdHlwZTogXCJpbWFnZVwiIH0+O1xuXG5mdW5jdGlvbiBpbWFnZUV2ZW50KGl0ZW06IEpzb25PYmplY3QsIHJlc3VsdDogc3RyaW5nKTogT3BlbkFJSW1hZ2VFdmVudCB7XG4gIC8vIFBORyBleHBvc2VzIGRpbWVuc2lvbnMgaW4gaXRzIGZpeGVkIGhlYWRlci4gT3RoZXIgZm9ybWF0cyByZXRhaW4gdGhlXG4gIC8vIGJhY2tlbmQncyBvYnNlcnZlZCBzaXplOyBuZXZlciBzdWJzdGl0dXRlIHJlcXVlc3RlZCBpbWFnZSBjb250cm9scy5cbiAgY29uc3QgaGVhZGVyID0gQnVmZmVyLmZyb20ocmVzdWx0LnNsaWNlKDAsIDMyKSwgXCJiYXNlNjRcIik7XG5cbiAgY29uc3QgcG5nU2l6ZSA9XG4gICAgaGVhZGVyLmxlbmd0aCA+PSAyNCAmJlxuICAgIGhlYWRlci5zdWJhcnJheSgwLCA4KS5lcXVhbHMoQnVmZmVyLmZyb20oXCI4OTUwNGU0NzBkMGExYTBhXCIsIFwiaGV4XCIpKSAmJlxuICAgIGhlYWRlci5yZWFkVUludDMyQkUoMTYpID4gMCAmJlxuICAgIGhlYWRlci5yZWFkVUludDMyQkUoMjApID4gMFxuICAgICAgPyBgJHtoZWFkZXIucmVhZFVJbnQzMkJFKDE2KX14JHtoZWFkZXIucmVhZFVJbnQzMkJFKDIwKX1gXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICBjb25zdCByZXBvcnRlZFNpemUgPSBqc29uU3RyaW5nKGl0ZW0uc2l6ZSk7XG5cbiAgY29uc3Qgc2l6ZSA9XG4gICAgcG5nU2l6ZSA/P1xuICAgIChyZXBvcnRlZFNpemUgIT09IHVuZGVmaW5lZCAmJiAvXlsxLTldXFxkKnhbMS05XVxcZCokLy50ZXN0KHJlcG9ydGVkU2l6ZSlcbiAgICAgID8gcmVwb3J0ZWRTaXplXG4gICAgICA6IHVuZGVmaW5lZCk7XG5cbiAgY29uc3QgaWQgPSBqc29uU3RyaW5nKGl0ZW0uaWQpO1xuICBjb25zdCBtb2RlbCA9IGpzb25TdHJpbmcoaXRlbS5tb2RlbCk7XG4gIGNvbnN0IHF1YWxpdHkgPSBqc29uU3RyaW5nKGl0ZW0ucXVhbGl0eSk7XG4gIGNvbnN0IGJhY2tncm91bmQgPSBqc29uU3RyaW5nKGl0ZW0uYmFja2dyb3VuZCk7XG4gIGNvbnN0IHJldmlzZWRQcm9tcHQgPSBqc29uU3RyaW5nKGl0ZW0ucmV2aXNlZF9wcm9tcHQpID8/IGpzb25TdHJpbmcoaXRlbS5yZXZpc2VkUHJvbXB0KTtcbiAgY29uc3QgZ2VuZXJhdGlvbjogSW1hZ2VHZW5lcmF0aW9uTWV0YWRhdGEgPSB7IHJvdXRlOiBcImNvZGV4LXJlc3BvbnNlc1wiIH07XG5cbiAgaWYgKHNpemUpIGdlbmVyYXRpb24uc2l6ZSA9IHNpemU7XG5cbiAgaWYgKG1vZGVsICE9PSB1bmRlZmluZWQpIGdlbmVyYXRpb24ubW9kZWwgPSBtb2RlbDtcblxuICBpZiAocXVhbGl0eSAhPT0gdW5kZWZpbmVkKSBnZW5lcmF0aW9uLnF1YWxpdHkgPSBxdWFsaXR5O1xuXG4gIGlmIChiYWNrZ3JvdW5kICE9PSB1bmRlZmluZWQpIGdlbmVyYXRpb24uYmFja2dyb3VuZCA9IGJhY2tncm91bmQ7XG5cbiAgY29uc3QgZXZlbnQ6IE9wZW5BSUltYWdlRXZlbnQgPSB7IHR5cGU6IFwiaW1hZ2VcIiwgYmFzZTY0OiByZXN1bHQsIG1pbWVUeXBlOiBcImltYWdlL3BuZ1wiIH07XG5cbiAgaWYgKGlkICE9PSB1bmRlZmluZWQpIGV2ZW50LmlkID0gaWQ7XG4gIGV2ZW50LmJhc2U2NCA9IHJlc3VsdDtcbiAgZXZlbnQubWltZVR5cGUgPSBpbWFnZU1pbWVUeXBlKHJlc3VsdCwgaXRlbS5vdXRwdXRfZm9ybWF0KTtcbiAgZXZlbnQuZ2VuZXJhdGlvbiA9IGdlbmVyYXRpb247XG5cbiAgaWYgKHJldmlzZWRQcm9tcHQgIT09IHVuZGVmaW5lZCkgZXZlbnQucmV2aXNlZFByb21wdCA9IHJldmlzZWRQcm9tcHQ7XG5cbiAgcmV0dXJuIGV2ZW50O1xufVxuXG50eXBlIE9wZW5BSUNvbXBsZXRlZEV2ZW50ID0gRXh0cmFjdDxPcGVuQUlOb3JtYWxpemVkRXZlbnQsIHsgdHlwZTogXCJjb21wbGV0ZWRcIiB9PjtcblxuZnVuY3Rpb24gY29tcGxldGVkRXZlbnQocmVzcG9uc2U6IEpzb25PYmplY3QpOiBPcGVuQUlDb21wbGV0ZWRFdmVudCB7XG4gIGNvbnN0IHRvb2xVc2FnZSA9IGpzb25PYmplY3RPckVtcHR5KHJlc3BvbnNlLnRvb2xfdXNhZ2UpO1xuICBjb25zdCBwYXJzZWRJbWFnZVVzYWdlID0gSW1hZ2VHZW5lcmF0aW9uTWV0YWRhdGEuc2hhcGUudXNhZ2Uuc2FmZVBhcnNlKHRvb2xVc2FnZS5pbWFnZV9nZW4pO1xuICBjb25zdCBpbWFnZVVzYWdlID0gcGFyc2VkSW1hZ2VVc2FnZS5zdWNjZXNzID8gcGFyc2VkSW1hZ2VVc2FnZS5kYXRhIDogdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGltYWdlVG9vbCA9IEFycmF5LmlzQXJyYXkocmVzcG9uc2UudG9vbHMpXG4gICAgPyByZXNwb25zZS50b29scy5maW5kKCh0b29sKSA9PiBpc0pzb25PYmplY3QodG9vbCkgJiYgdG9vbC50eXBlID09PSBcImltYWdlX2dlbmVyYXRpb25cIilcbiAgICA6IHVuZGVmaW5lZDtcblxuICBjb25zdCBpbWFnZU1vZGVsID0gaXNKc29uT2JqZWN0KGltYWdlVG9vbCkgPyBqc29uU3RyaW5nKGltYWdlVG9vbC5tb2RlbCkgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IG1vZGVsID0ganNvblN0cmluZyhyZXNwb25zZS5tb2RlbCk7XG5cbiAgY29uc3QgZXZlbnQ6IE9wZW5BSUNvbXBsZXRlZEV2ZW50ID0ge1xuICAgIHR5cGU6IFwiY29tcGxldGVkXCIsXG4gICAgcmVzcG9uc2VJZDoganNvblN0cmluZyhyZXNwb25zZS5pZCkgPz8gXCJcIixcbiAgfTtcblxuICBpZiAoaXNKc29uT2JqZWN0KHJlc3BvbnNlLnVzYWdlKSkgZXZlbnQudXNhZ2UgPSB1c2FnZUZyb20ocmVzcG9uc2UudXNhZ2UpO1xuXG4gIGlmIChtb2RlbCAhPT0gdW5kZWZpbmVkKSBldmVudC5tb2RlbCA9IG1vZGVsO1xuXG4gIGlmIChpbWFnZVVzYWdlIHx8IGltYWdlTW9kZWwpIHtcbiAgICBjb25zdCBpbWFnZUdlbmVyYXRpb246IEltYWdlR2VuZXJhdGlvbk1ldGFkYXRhID0geyByb3V0ZTogXCJjb2RleC1yZXNwb25zZXNcIiB9O1xuXG4gICAgaWYgKGltYWdlTW9kZWwpIGltYWdlR2VuZXJhdGlvbi5tb2RlbCA9IGltYWdlTW9kZWw7XG5cbiAgICBpZiAoaW1hZ2VVc2FnZSkgaW1hZ2VHZW5lcmF0aW9uLnVzYWdlID0gaW1hZ2VVc2FnZTtcbiAgICBldmVudC5pbWFnZUdlbmVyYXRpb24gPSBpbWFnZUdlbmVyYXRpb247XG4gIH1cblxuICByZXR1cm4gZXZlbnQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVPcGVuQUlFdmVudChyYXc6IEpzb25WYWx1ZSk6IE9wZW5BSU5vcm1hbGl6ZWRFdmVudCB8IHVuZGVmaW5lZCB7XG4gIGlmICghaXNKc29uT2JqZWN0KHJhdykpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IGV2ZW50ID0gcmF3O1xuICBjb25zdCB0eXBlID0ganNvblN0cmluZyhldmVudC50eXBlKSA/PyBcIlwiO1xuXG4gIGlmICh0eXBlID09PSBcInJlc3BvbnNlLmNyZWF0ZWRcIikge1xuICAgIGNvbnN0IHJlc3BvbnNlSWQgPSBpc0pzb25PYmplY3QoZXZlbnQucmVzcG9uc2UpID8ganNvblN0cmluZyhldmVudC5yZXNwb25zZS5pZCkgOiB1bmRlZmluZWQ7XG5cbiAgICByZXR1cm4gcmVzcG9uc2VJZCA/IHsgdHlwZTogXCJjcmVhdGVkXCIsIHJlc3BvbnNlSWQgfSA6IHsgdHlwZTogXCJjcmVhdGVkXCIgfTtcbiAgfVxuXG4gIGNvbnN0IGRlbHRhID0ganNvblN0cmluZyhldmVudC5kZWx0YSk7XG5cbiAgaWYgKHR5cGUgPT09IFwicmVzcG9uc2Uub3V0cHV0X3RleHQuZGVsdGFcIiAmJiBkZWx0YSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgaXRlbUlkID0ganNvblN0cmluZyhldmVudC5pdGVtX2lkKTtcblxuICAgIHJldHVybiBpdGVtSWQgPT09IHVuZGVmaW5lZFxuICAgICAgPyB7IHR5cGU6IFwidGV4dC1kZWx0YVwiLCB0ZXh0OiBkZWx0YSB9XG4gICAgICA6IHsgdHlwZTogXCJ0ZXh0LWRlbHRhXCIsIHRleHQ6IGRlbHRhLCBpdGVtSWQgfTtcbiAgfVxuXG4gIGlmIChcbiAgICAodHlwZSA9PT0gXCJyZXNwb25zZS5vdXRwdXRfaXRlbS5hZGRlZFwiIHx8IHR5cGUgPT09IFwicmVzcG9uc2Uub3V0cHV0X2l0ZW0uZG9uZVwiKSAmJlxuICAgIGlzSnNvbk9iamVjdChldmVudC5pdGVtKVxuICApIHtcbiAgICBjb25zdCBpdGVtID0gZXZlbnQuaXRlbTtcbiAgICBjb25zdCByZXN1bHQgPSBqc29uU3RyaW5nKGl0ZW0ucmVzdWx0KTtcblxuICAgIGlmIChpdGVtLnR5cGUgPT09IFwiaW1hZ2VfZ2VuZXJhdGlvbl9jYWxsXCIgJiYgcmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBpbWFnZUV2ZW50KGl0ZW0sIHJlc3VsdCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdHlwZTogXCJvdXRwdXQtaXRlbVwiLCBpdGVtLCBjb21wbGV0ZWQ6IHR5cGUgPT09IFwicmVzcG9uc2Uub3V0cHV0X2l0ZW0uZG9uZVwiIH07XG4gIH1cblxuICBpZiAodHlwZSA9PT0gXCJyZXNwb25zZS5jb21wbGV0ZWRcIikgcmV0dXJuIGNvbXBsZXRlZEV2ZW50KGpzb25PYmplY3RPckVtcHR5KGV2ZW50LnJlc3BvbnNlKSk7XG5cbiAgaWYgKHR5cGUgPT09IFwiZXJyb3JcIiB8fCB0eXBlID09PSBcInJlc3BvbnNlLmZhaWxlZFwiIHx8IHR5cGUgPT09IFwicmVzcG9uc2UuaW5jb21wbGV0ZVwiKSB7XG4gICAgY29uc3Qgc291cmNlID0ganNvbk9iamVjdE9yRW1wdHkoZXZlbnQuZXJyb3IgPz8gZXZlbnQucmVzcG9uc2UgPz8gZXZlbnQpO1xuICAgIGNvbnN0IG5lc3RlZCA9IGpzb25PYmplY3RPckVtcHR5KHNvdXJjZS5lcnJvciA/PyBzb3VyY2UpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IFwiZXJyb3JcIixcbiAgICAgIGVycm9yOiBuZXcgT3BlbkFJUHJvdG9jb2xFcnJvcihcbiAgICAgICAganNvblN0cmluZyhuZXN0ZWQubWVzc2FnZSkgPz8gYE9wZW5BSSBzdHJlYW0gZW5kZWQgd2l0aCAke3R5cGV9YCxcbiAgICAgICAganNvblN0cmluZyhuZXN0ZWQuY29kZSksXG4gICAgICApLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7OztBQWVBLE1BQWEsOEJBQ1g7QUFFRixNQUFhLHVCQUF1QjtBQUNwQyxNQUFhLG9CQUFvQjtBQVNqQyxTQUFTLGdCQUF3QztDQUMvQyxNQUFNLFFBQWtEO0VBQ3RELFFBQVE7RUFDUixPQUFPO0VBQ1AsT0FBTztDQUNUO0NBRUEsTUFBTSxXQUFXLFFBQVEsSUFBSTtDQUM3QixNQUFNLGtCQUFrQixRQUFRLElBQUk7Q0FFcEMsT0FBTztFQUNMLFFBQVEsTUFBTSxRQUFRLGFBQWEsUUFBUTtFQUMzQyxXQUFXLEdBQUcsUUFBUTtFQUN0QixjQUFjLFFBQVE7RUFDdEIsVUFBVSxXQUFXLEdBQUcsV0FBVyxrQkFBa0IsSUFBSSxvQkFBb0IsT0FBTztDQUN0RjtBQUNGOztBQUdBLFNBQWdCLGtCQUFrQixXQUFtQyxjQUFjLEdBQVc7Q0FDNUYsT0FBTyxnQkFBZ0Isa0JBQWtCLElBQUksU0FBUyxPQUFPLEdBQUcsU0FBUyxVQUFVLElBQUksU0FBUyxhQUFhLElBQUksU0FBUztBQUM1SDtBQXVEQSxTQUFnQiw0QkFDZCxTQUN3QjtDQUN4QixNQUFNLFFBQVEsUUFBUSxRQUFRLENBQUMsR0FBRyxRQUFRLEtBQUssSUFBSSxDQUFDO0NBRXBELElBQUksUUFBUSxpQkFDVixNQUFNLEtBQ0osUUFBUSxvQkFBb0IsT0FDeEIsRUFBRSxNQUFNLG1CQUFtQixJQUMzQjtFQUFFLE1BQU07RUFBb0IsR0FBRyxRQUFRO0NBQWdCLENBQzdEO0NBR0YsTUFBTSxVQUFrQztFQUN0QyxP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