@cartanova/qgrid-cli 2.10.9 → 2.11.0

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 (318) 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 +22 -20
  10. package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +43 -34
  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 -69
  24. package/bundle/dist/application/request-log/request-log.types.js +8 -2
  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 +40 -16
  33. package/bundle/dist/application/sonamu.generated.sso.js +2 -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 +2 -1
  39. package/bundle/dist/migrations/20260807133553_manual__backfill_request_log_cost.js +8 -6
  40. package/bundle/dist/migrations/20261018215031_alter_request_logs_add1_alter1.js +15 -0
  41. package/bundle/dist/server-bootstrap.js +4 -2
  42. package/bundle/dist/server-error-handler.js +1 -1
  43. package/bundle/dist/sonamu.config.js +37 -8
  44. package/bundle/dist/startup-migrations.js +17 -7
  45. package/bundle/dist/testing/global.js +1 -1
  46. package/bundle/dist/testing/schema-bench.js +0 -0
  47. package/bundle/dist/testing/test-database-name.js +1 -1
  48. package/bundle/dist/utils/providers/anthropic/anthropic-constants.js +1 -1
  49. package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +11 -5
  50. package/bundle/dist/utils/providers/anthropic/anthropic-quota.js +4 -4
  51. package/bundle/dist/utils/providers/anthropic/anthropic-thinking.js +1 -1
  52. package/bundle/dist/utils/providers/anthropic/claude-session.js +20 -19
  53. package/bundle/dist/utils/providers/anthropic/fence-strip.js +1 -1
  54. package/bundle/dist/utils/providers/anthropic/stream-json-adapter.js +49 -23
  55. package/bundle/dist/utils/providers/common/credentials.js +5 -1
  56. package/bundle/dist/utils/providers/common/effort.js +3 -3
  57. package/bundle/dist/utils/providers/common/model-cost.js +69 -14
  58. package/bundle/dist/utils/providers/common/provider-types.js +29 -1
  59. package/bundle/dist/utils/providers/common/schema-validation.js +78 -40
  60. package/bundle/dist/utils/providers/common/smooth-weighted-round-robin.js +1 -1
  61. package/bundle/dist/utils/providers/common/strictifier.js +62 -43
  62. package/bundle/dist/utils/providers/common/thinking.js +3 -2
  63. package/bundle/dist/utils/providers/common/ttft.js +1 -1
  64. package/bundle/dist/utils/providers/grok/grok-backend-protocol.js +427 -0
  65. package/bundle/dist/utils/providers/grok/grok-constants.js +55 -0
  66. package/bundle/dist/utils/providers/grok/grok-direct-client.js +196 -0
  67. package/bundle/dist/utils/providers/grok/grok-dispatcher.js +1313 -0
  68. package/bundle/dist/utils/providers/grok/grok-headers.js +118 -0
  69. package/bundle/dist/utils/providers/grok/grok-media-client.js +420 -0
  70. package/bundle/dist/utils/providers/grok/grok-models.js +114 -0
  71. package/bundle/dist/utils/providers/grok/grok-oauth.js +455 -0
  72. package/bundle/dist/utils/providers/grok/grok-quota.js +119 -0
  73. package/bundle/dist/utils/providers/grok/grok-refresh.js +192 -0
  74. package/bundle/dist/utils/providers/grok/grok-types.js +186 -0
  75. package/bundle/dist/utils/providers/grok/grok-voice-client.js +199 -0
  76. package/bundle/dist/utils/providers/grok/index.js +11 -0
  77. package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +111 -83
  78. package/bundle/dist/utils/providers/openai/openai-callback-relay.js +3 -2
  79. package/bundle/dist/utils/providers/openai/openai-constants.js +1 -1
  80. package/bundle/dist/utils/providers/openai/openai-direct-client.js +23 -7
  81. package/bundle/dist/utils/providers/openai/openai-dispatcher.js +143 -106
  82. package/bundle/dist/utils/providers/openai/openai-image-generation.js +48 -33
  83. package/bundle/dist/utils/providers/openai/openai-oauth.js +28 -13
  84. package/bundle/dist/utils/providers/openai/openai-quota.js +38 -27
  85. package/bundle/dist/utils/providers/openai/openai-refresh.js +17 -9
  86. package/bundle/dist/utils/providers/openai/openai-sse.js +1 -1
  87. package/bundle/dist/utils/providers/openai/openai-transport-config.js +1 -1
  88. package/bundle/dist/utils/quiet-hours.js +1 -1
  89. package/bundle/dist/utils/slack-notify.js +14 -8
  90. package/bundle/dist/utils/subset-loaders.js +4 -5
  91. package/bundle/src/application/monit/log-buffer.ts +23 -9
  92. package/bundle/src/application/monit/monit.frame.ts +22 -5
  93. package/bundle/src/application/monit/monit.types.ts +6 -0
  94. package/bundle/src/application/qgrid/conv-routing.test.ts +76 -4
  95. package/bundle/src/application/qgrid/conv-routing.ts +35 -9
  96. package/bundle/src/application/qgrid/expired-token-reminder.ts +9 -1
  97. package/bundle/src/application/qgrid/oauth.ts +51 -15
  98. package/bundle/src/application/qgrid/qgrid-image-generation.ts +9 -0
  99. package/bundle/src/application/qgrid/qgrid-response-format.ts +50 -25
  100. package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +33 -0
  101. package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +87 -40
  102. package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +97 -0
  103. package/bundle/src/application/qgrid/qgrid.dispatcher.ts +274 -126
  104. package/bundle/src/application/qgrid/qgrid.frame.test.ts +1013 -3
  105. package/bundle/src/application/qgrid/qgrid.frame.ts +1415 -60
  106. package/bundle/src/application/qgrid/qgrid.types.ts +335 -0
  107. package/bundle/src/application/qgrid/schema-prompt.ts +105 -41
  108. package/bundle/src/application/qgrid/slack-user-map.ts +5 -0
  109. package/bundle/src/application/qgrid/token-death.ts +4 -0
  110. package/bundle/src/application/qgrid/token-subscriber.test.ts +21 -19
  111. package/bundle/src/application/qgrid/token-subscriber.ts +186 -53
  112. package/bundle/src/application/qgrid/token-trigger-setup.ts +2 -0
  113. package/bundle/src/application/qgrid/token-window-keepalive.ts +49 -6
  114. package/bundle/src/application/qgrid/tool-emulation-schema.ts +33 -29
  115. package/bundle/src/application/qgrid/tool-emulation.ts +52 -27
  116. package/bundle/src/application/request-log/json-schema-type-text.test.ts +5 -5
  117. package/bundle/src/application/request-log/json-schema-type-text.ts +81 -26
  118. package/bundle/src/application/request-log/request-log.entity.json +8 -0
  119. package/bundle/src/application/request-log/request-log.model.test.ts +111 -4
  120. package/bundle/src/application/request-log/request-log.model.ts +279 -145
  121. package/bundle/src/application/request-log/request-log.types.ts +17 -0
  122. package/bundle/src/application/request-log/zod-code-format.ts +11 -0
  123. package/bundle/src/application/request-log-step/request-log-step.model.ts +1 -0
  124. package/bundle/src/application/request-log-step/request-log-step.types.ts +2 -0
  125. package/bundle/src/application/setting/setting.constant.ts +9 -0
  126. package/bundle/src/application/setting/setting.model.ts +12 -2
  127. package/bundle/src/application/setting/setting.store.ts +5 -1
  128. package/bundle/src/application/setting/setting.types.ts +8 -0
  129. package/bundle/src/application/sonamu.generated.http +135 -0
  130. package/bundle/src/application/sonamu.generated.sso.ts +3 -0
  131. package/bundle/src/application/sonamu.generated.ts +29 -0
  132. package/bundle/src/application/token/token.identity.test.ts +20 -0
  133. package/bundle/src/application/token/token.model.ts +66 -7
  134. package/bundle/src/application/token/token.types.ts +24 -1
  135. package/bundle/src/i18n/en.ts +19 -0
  136. package/bundle/src/i18n/ko.ts +21 -0
  137. package/bundle/src/i18n/sd.generated.ts +24 -2
  138. package/bundle/src/migrations/20260807133553_manual__backfill_request_log_cost.ts +16 -8
  139. package/bundle/src/migrations/20261018215031_alter_request_logs_add1_alter1.ts +15 -0
  140. package/bundle/src/server-bootstrap.ts +4 -2
  141. package/bundle/src/server-error-handler.ts +1 -0
  142. package/bundle/src/sonamu.config.ts +69 -7
  143. package/bundle/src/startup-migrations.ts +27 -9
  144. package/bundle/src/testing/global.ts +20 -0
  145. package/bundle/src/testing/schema-bench.ts +105 -30
  146. package/bundle/src/testing/test-database-name.ts +2 -0
  147. package/bundle/src/utils/providers/anthropic/anthropic-constants.ts +8 -0
  148. package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +41 -6
  149. package/bundle/src/utils/providers/anthropic/anthropic-quota.ts +7 -3
  150. package/bundle/src/utils/providers/anthropic/anthropic-thinking.ts +6 -0
  151. package/bundle/src/utils/providers/anthropic/claude-session.ts +58 -24
  152. package/bundle/src/utils/providers/anthropic/fence-strip.ts +11 -0
  153. package/bundle/src/utils/providers/anthropic/stream-json-adapter.ts +110 -45
  154. package/bundle/src/utils/providers/common/credentials.ts +8 -0
  155. package/bundle/src/utils/providers/common/effort.ts +9 -2
  156. package/bundle/src/utils/providers/common/model-cost.test.ts +48 -1
  157. package/bundle/src/utils/providers/common/model-cost.ts +259 -158
  158. package/bundle/src/utils/providers/common/provider-dispatcher.ts +98 -2
  159. package/bundle/src/utils/providers/common/provider-types.ts +46 -3
  160. package/bundle/src/utils/providers/common/schema-validation.test.ts +5 -1
  161. package/bundle/src/utils/providers/common/schema-validation.ts +124 -56
  162. package/bundle/src/utils/providers/common/smooth-weighted-round-robin.ts +4 -0
  163. package/bundle/src/utils/providers/common/strictifier.ts +185 -59
  164. package/bundle/src/utils/providers/common/thinking.ts +2 -2
  165. package/bundle/src/utils/providers/common/ttft.ts +4 -2
  166. package/bundle/src/utils/providers/grok/__fixtures__/golden-responses-1.0.60.json +164 -0
  167. package/bundle/src/utils/providers/grok/grok-backend-protocol.test.ts +325 -0
  168. package/bundle/src/utils/providers/grok/grok-backend-protocol.ts +721 -0
  169. package/bundle/src/utils/providers/grok/grok-constants.ts +105 -0
  170. package/bundle/src/utils/providers/grok/grok-direct-client.test.ts +179 -0
  171. package/bundle/src/utils/providers/grok/grok-direct-client.ts +313 -0
  172. package/bundle/src/utils/providers/grok/grok-dispatcher.test.ts +1395 -0
  173. package/bundle/src/utils/providers/grok/grok-dispatcher.ts +2105 -0
  174. package/bundle/src/utils/providers/grok/grok-headers.test.ts +149 -0
  175. package/bundle/src/utils/providers/grok/grok-headers.ts +199 -0
  176. package/bundle/src/utils/providers/grok/grok-media-client.test.ts +446 -0
  177. package/bundle/src/utils/providers/grok/grok-media-client.ts +703 -0
  178. package/bundle/src/utils/providers/grok/grok-models.test.ts +96 -0
  179. package/bundle/src/utils/providers/grok/grok-models.ts +161 -0
  180. package/bundle/src/utils/providers/grok/grok-oauth.test.ts +406 -0
  181. package/bundle/src/utils/providers/grok/grok-oauth.ts +771 -0
  182. package/bundle/src/utils/providers/grok/grok-quota.test.ts +142 -0
  183. package/bundle/src/utils/providers/grok/grok-quota.ts +198 -0
  184. package/bundle/src/utils/providers/grok/grok-refresh.test.ts +239 -0
  185. package/bundle/src/utils/providers/grok/grok-refresh.ts +325 -0
  186. package/bundle/src/utils/providers/grok/grok-types.test.ts +252 -0
  187. package/bundle/src/utils/providers/grok/grok-types.ts +374 -0
  188. package/bundle/src/utils/providers/grok/grok-voice-client.test.ts +321 -0
  189. package/bundle/src/utils/providers/grok/grok-voice-client.ts +284 -0
  190. package/bundle/src/utils/providers/grok/index.ts +20 -0
  191. package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +221 -137
  192. package/bundle/src/utils/providers/openai/openai-callback-relay.ts +12 -1
  193. package/bundle/src/utils/providers/openai/openai-constants.ts +2 -0
  194. package/bundle/src/utils/providers/openai/openai-direct-client.ts +111 -21
  195. package/bundle/src/utils/providers/openai/openai-dispatcher.ts +322 -169
  196. package/bundle/src/utils/providers/openai/openai-image-generation.ts +116 -36
  197. package/bundle/src/utils/providers/openai/openai-oauth.ts +48 -20
  198. package/bundle/src/utils/providers/openai/openai-quota.ts +77 -46
  199. package/bundle/src/utils/providers/openai/openai-refresh.ts +42 -18
  200. package/bundle/src/utils/providers/openai/openai-sse.ts +27 -3
  201. package/bundle/src/utils/providers/openai/openai-transport-config.ts +2 -0
  202. package/bundle/src/utils/quiet-hours.ts +12 -1
  203. package/bundle/src/utils/slack-notify.ts +44 -13
  204. package/bundle/src/utils/subset-loaders.ts +7 -7
  205. package/bundle/web-dist/client/assets/clsx-5XM_pHvN.js +1 -0
  206. package/bundle/web-dist/client/assets/index-BA7uQ-6c.js +31 -0
  207. package/bundle/web-dist/client/assets/index-Be2qCZmI.css +1 -0
  208. package/bundle/web-dist/client/assets/logs-C47OJGEI.js +1 -0
  209. package/bundle/web-dist/client/assets/monit-BS9no0dU.js +4 -0
  210. package/bundle/web-dist/client/assets/plus-sdACTfH0.js +1 -0
  211. package/bundle/web-dist/client/assets/refresh-cw-CY8o_1cT.js +1 -0
  212. package/bundle/web-dist/client/assets/request-model-BRtFuZvj.js +1 -0
  213. package/bundle/web-dist/client/assets/routes-kqgkUxE8.js +5 -0
  214. package/bundle/web-dist/client/assets/{services.generated-BsieU37H.js → services.generated-CefiDXEv.js} +5 -5
  215. package/bundle/web-dist/client/assets/settings-DNDvFGSw.js +1 -0
  216. package/bundle/web-dist/client/assets/show-u8Np69q3.js +2 -0
  217. package/bundle/web-dist/client/assets/tokens-QvP410NW.js +1 -0
  218. package/bundle/web-dist/client/assets/total-cost-MnfKU8IN.js +1 -0
  219. package/bundle/web-dist/client/assets/use-oauth-login-flow-Bzdh28Ws.js +1 -0
  220. package/bundle/web-dist/client/assets/use-update-token-mutation-CfJKaxmR.js +1 -0
  221. package/bundle/web-dist/client/assets/vendor-react-CUFFrVN9.js +244 -0
  222. package/bundle/web-dist/client/assets/vendor-tanstack-Bf_jag9G.js +1 -0
  223. package/bundle/web-dist/client/index.html +6 -6
  224. package/bundle/web-dist/server/assets/clsx-D_N5PN_2.js +16 -0
  225. package/bundle/web-dist/server/assets/{lazyRouteComponent-Dtd0NR4r.js → lazyRouteComponent-D8iTIHyn.js} +129 -2
  226. package/bundle/web-dist/server/assets/logs-B3OTd9hy.js +825 -0
  227. package/bundle/web-dist/server/assets/{monit-DvzribSE.js → monit-B2hqorPe.js} +385 -126
  228. package/bundle/web-dist/server/assets/plus-DwG7h9kq.js +28 -0
  229. package/bundle/web-dist/server/assets/{react-dom-B4a6-uuR.js → react-dom-BIYQzBqG.js} +2 -129
  230. package/bundle/web-dist/server/assets/refresh-cw-mMBkwOq0.js +44 -0
  231. package/bundle/web-dist/server/assets/{request-model-CbqfnQOJ.js → request-model-I6OdODSH.js} +15 -6
  232. package/bundle/web-dist/server/assets/{routes-BAPWTizT.js → routes-B95YlUv2.js} +760 -213
  233. package/bundle/web-dist/server/assets/{services.generated-CEbGjsI0.js → services.generated-DQATJ6qf.js} +12821 -12194
  234. package/bundle/web-dist/server/assets/settings-C3gbGk0m.js +830 -0
  235. package/bundle/web-dist/server/assets/{show-CxVZTAdv.js → show-Bxaj3rhH.js} +1355 -419
  236. package/bundle/web-dist/server/assets/tokens-CZjH3cB7.js +1038 -0
  237. package/bundle/web-dist/server/assets/total-cost-fTE9Xy82.js +18 -0
  238. package/bundle/web-dist/server/assets/use-oauth-login-flow-CKDHgc3U.js +2379 -0
  239. package/bundle/web-dist/server/assets/{use-update-token-mutation-CfYmk_4_.js → use-update-token-mutation-BEbgOzaa.js} +1 -1
  240. package/bundle/web-dist/server/entry-server.generated.js +4303 -22810
  241. package/dist/cli.js +9 -9
  242. package/package.json +4 -11
  243. package/postinstall.mjs +12 -0
  244. package/skills/qgrid/SKILL.md +1 -0
  245. package/skills/qgrid/references/cli-env-and-server-boot.md +4 -1
  246. package/skills/qgrid/references/decision-rationale.md +24 -1
  247. package/skills/qgrid/references/grok-runtime.md +89 -0
  248. package/skills/qgrid/references/provider-runtime-differences.md +30 -29
  249. package/skills/qgrid/references/repo-map.md +10 -0
  250. package/skills/qgrid/references/request-log-run-lifecycle.md +1 -1
  251. package/skills/qgrid/references/sonamu-api-web-flow.md +1 -1
  252. package/skills/qgrid/references/token-auth-quota-lifecycle.md +56 -3
  253. package/bundle/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +0 -406
  254. package/bundle/dist/node_modules/.pnpm/@vitest_expect@4.1.10/node_modules/@vitest/expect/dist/index.js +0 -1507
  255. package/bundle/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.10/node_modules/@vitest/pretty-format/dist/index.js +0 -887
  256. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2756
  257. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/index.js +0 -8
  258. package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/utils.js +0 -8
  259. package/bundle/dist/node_modules/.pnpm/@vitest_snapshot@4.1.10/node_modules/@vitest/snapshot/dist/index.js +0 -922
  260. package/bundle/dist/node_modules/.pnpm/@vitest_spy@4.1.10/node_modules/@vitest/spy/dist/index.js +0 -386
  261. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -121
  262. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/constants.js +0 -51
  263. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/diff.js +0 -1317
  264. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/display.js +0 -561
  265. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js +0 -40
  266. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js +0 -272
  267. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/offset.js +0 -27
  268. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/serialize.js +0 -77
  269. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/source-map.js +0 -381
  270. package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/timers.js +0 -51
  271. package/bundle/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +0 -2986
  272. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +0 -10
  273. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +0 -109
  274. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +0 -10
  275. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +0 -10
  276. package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +0 -10
  277. package/bundle/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +0 -1126
  278. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +0 -21
  279. package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +0 -432
  280. package/bundle/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +0 -517
  281. package/bundle/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +0 -101
  282. 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
  283. 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
  284. 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
  285. 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
  286. 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
  287. 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
  288. 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
  289. 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
  290. 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
  291. 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
  292. package/bundle/dist/testing/setup-mocks.js +0 -16
  293. package/bundle/src/testing/setup-mocks.ts +0 -44
  294. package/bundle/web-dist/client/assets/index-Bw2s88Ot.css +0 -1
  295. package/bundle/web-dist/client/assets/index-CrXKu_J8.js +0 -106
  296. package/bundle/web-dist/client/assets/logs-B2SmWJXA.js +0 -1
  297. package/bundle/web-dist/client/assets/monit-D-JwXXoA.js +0 -1
  298. package/bundle/web-dist/client/assets/plus-B62CuqT8.js +0 -1
  299. package/bundle/web-dist/client/assets/refresh-cw-NNcU0Cmq.js +0 -1
  300. package/bundle/web-dist/client/assets/request-model-CojtinqK.js +0 -1
  301. package/bundle/web-dist/client/assets/routes-C5r4gTvY.js +0 -5
  302. package/bundle/web-dist/client/assets/settings-D3tDSAck.js +0 -1
  303. package/bundle/web-dist/client/assets/show-Cah_kUKC.js +0 -2
  304. package/bundle/web-dist/client/assets/tokens-DU2Iyxxd.js +0 -1
  305. package/bundle/web-dist/client/assets/use-oauth-login-flow-D0UaR9_e.js +0 -1
  306. package/bundle/web-dist/client/assets/use-update-token-mutation-DAq0F8p-.js +0 -1
  307. package/bundle/web-dist/client/assets/vendor-react-DH4kUfK2.js +0 -9
  308. package/bundle/web-dist/client/assets/vendor-tanstack-DJRQAbrY.js +0 -1
  309. package/bundle/web-dist/server/assets/logs-l91avYif.js +0 -509
  310. package/bundle/web-dist/server/assets/plus-KZrECewT.js +0 -19
  311. package/bundle/web-dist/server/assets/refresh-cw-BND93JrF.js +0 -23
  312. package/bundle/web-dist/server/assets/settings-BZR5HSAL.js +0 -461
  313. package/bundle/web-dist/server/assets/tokens-D1hb4eKk.js +0 -448
  314. package/bundle/web-dist/server/assets/use-oauth-login-flow-Cvdy0zF8.js +0 -178
  315. package/dist/cli.d.ts +0 -10
  316. /package/bundle/web-dist/client/assets/{cost-DH2jZbrw.js → cost-DB3HbU7T.js} +0 -0
  317. /package/bundle/web-dist/client/assets/{preload-helper-ca-nBW7U.js → preload-helper-DWTEM3RW.js} +0 -0
  318. /package/bundle/web-dist/server/assets/{cost-eEHeTRT5.js → cost-BC9yzyA9.js} +0 -0
@@ -0,0 +1,118 @@
1
+ import { GROK_BUILD_VERSION, GROK_CLIENT_IDENTIFIER, GROK_CLIENT_MODE, GROK_COMPACTION_AT, GROK_DOOM_LOOP_CHECK } from "./grok-constants.js";
2
+ import { randomBytes } from "node:crypto";
3
+ //#region src/utils/providers/grok/grok-headers.ts
4
+ /** Maps Node platform/arch to the Rust `std::env::consts` names grok-build reports. */
5
+ function grokPlatform(platform = process.platform, arch = process.arch) {
6
+ return {
7
+ os: platform === "darwin" ? "macos" : platform === "win32" ? "windows" : "linux",
8
+ arch: arch === "arm64" ? "aarch64" : "x86_64"
9
+ };
10
+ }
11
+ /** `grok-shell/<ver> (<os>; <arch>)` (grok-build 1.0.45 xai-grok-sampler/src/client.rs:457-463). */
12
+ function grokShellUserAgent(platform = grokPlatform()) {
13
+ return `grok-shell/${GROK_BUILD_VERSION} (${platform.os}; ${platform.arch})`;
14
+ }
15
+ /** `xai-grok-build/<ver>` (grok-build 1.0.45 media_tool_config.rs:104). */
16
+ function grokMediaUserAgent() {
17
+ return `xai-grok-build/${GROK_BUILD_VERSION}`;
18
+ }
19
+ const TRACEPARENT_PATTERN = /^00-(?!0{32})[0-9a-f]{32}-(?!0{16})[0-9a-f]{16}-01$/;
20
+ /** W3C trace context `00-<trace-id>-<parent-id>-01` with non-zero random ids. */
21
+ function generateTraceparent() {
22
+ for (;;) {
23
+ const traceparent = `00-${randomBytes(16).toString("hex")}-${randomBytes(8).toString("hex")}-01`;
24
+ if (TRACEPARENT_PATTERN.test(traceparent)) return traceparent;
25
+ }
26
+ }
27
+ function bearerValue(bearer) {
28
+ if (!bearer || /\s/.test(bearer)) throw new TypeError("Grok bearer token must be non-empty");
29
+ return `Bearer ${bearer}`;
30
+ }
31
+ function nonNegativeInteger(name, value) {
32
+ if (!Number.isSafeInteger(value) || value < 0) throw new TypeError(`${name} must be a non-negative integer`);
33
+ return String(value);
34
+ }
35
+ function requiredValue(name, value) {
36
+ if (!value || /[\r\n]/.test(value)) throw new TypeError(`${name} must be a non-empty header value`);
37
+ return value;
38
+ }
39
+ /** Headers for `POST {proxy}/responses`, in the order of the 1.0.60 golden capture. */
40
+ function buildGrokChatHeaders(options) {
41
+ const traceparent = options.traceparent ?? generateTraceparent();
42
+ if (!TRACEPARENT_PATTERN.test(traceparent)) throw new TypeError("traceparent must be a W3C 00-<32hex>-<16hex>-01 value");
43
+ const headers = new Map(Object.entries({
44
+ "content-type": "application/json",
45
+ "user-agent": grokShellUserAgent(options.platform),
46
+ "x-grok-client-mode": GROK_CLIENT_MODE,
47
+ "x-xai-token-auth": "xai-grok-cli",
48
+ "x-authenticateresponse": "authenticate-response",
49
+ "x-compactions-remaining": nonNegativeInteger("compactionsRemaining", options.compactionsRemaining ?? 1),
50
+ "x-compaction-at": String(GROK_COMPACTION_AT),
51
+ "x-grok-client-version": GROK_BUILD_VERSION,
52
+ "x-grok-user-id": requiredValue("userId", options.userId),
53
+ "x-grok-conv-group-id": requiredValue("convGroupId", options.convGroupId),
54
+ "x-grok-client-identifier": GROK_CLIENT_IDENTIFIER,
55
+ authorization: bearerValue(options.bearer),
56
+ traceparent,
57
+ "x-grok-conv-id": requiredValue("convId", options.convId),
58
+ "x-grok-req-id": requiredValue("reqId", options.reqId),
59
+ "x-grok-model-override": requiredValue("model", options.model),
60
+ "x-grok-session-id": requiredValue("sessionId", options.sessionId),
61
+ "x-grok-agent-id": requiredValue("agentId", options.agentId),
62
+ "x-grok-turn-idx": nonNegativeInteger("turnIdx", options.turnIdx)
63
+ }));
64
+ if (options.transientRetry !== void 0) headers.set("x-grok-transient-retry", nonNegativeInteger("transientRetry", options.transientRetry));
65
+ headers.set("accept", "text/event-stream");
66
+ headers.set("x-grok-doom-loop-check", String(GROK_DOOM_LOOP_CHECK));
67
+ headers.set("x-grok-exact-repetition-check", String(64));
68
+ if (options.zstd) headers.set("content-encoding", "zstd");
69
+ return Object.fromEntries(headers);
70
+ }
71
+ /**
72
+ * Headers for proxy GETs (`/settings`, `/models`, `/billing`, `/user`). Order follows the
73
+ * 1.0.60 capture of `GET /settings`.
74
+ */
75
+ function buildGrokProxyGetHeaders(options) {
76
+ const headers = /* @__PURE__ */ new Map([
77
+ ["authorization", bearerValue(options.bearer)],
78
+ ["x-xai-token-auth", "xai-grok-cli"],
79
+ ["x-userid", requiredValue("userId", options.userId)],
80
+ ["x-grok-client-version", GROK_BUILD_VERSION]
81
+ ]);
82
+ if (options.email !== void 0) headers.set("x-email", requiredValue("email", options.email));
83
+ headers.set("x-grok-client-identifier", GROK_CLIENT_IDENTIFIER);
84
+ headers.set("x-grok-client-mode", GROK_CLIENT_MODE);
85
+ headers.set("accept", "*/*");
86
+ headers.set("user-agent", grokShellUserAgent(options.platform));
87
+ return Object.fromEntries(headers);
88
+ }
89
+ /**
90
+ * Headers for `api.x.ai` image/video calls. The proxy auth trio is never attached.
91
+ * `x-grok-session-id` is attached per request right after the bearer (grok-build xai-grok-tools
92
+ * image_gen/mod.rs:199-213, video_gen/mod.rs:258-270).
93
+ */
94
+ function buildGrokMediaHeaders(options) {
95
+ return {
96
+ "user-agent": grokMediaUserAgent(),
97
+ authorization: bearerValue(options.bearer),
98
+ "x-grok-session-id": requiredValue("sessionId", options.sessionId),
99
+ "x-grok-client-version": GROK_BUILD_VERSION,
100
+ "x-grok-client-identifier": GROK_CLIENT_IDENTIFIER
101
+ };
102
+ }
103
+ /**
104
+ * Headers for `api.x.ai` STT/TTS calls (grok-build 1.0.45 xai-grok-pager client_identity.rs).
105
+ * No session id: the voice client sends none (xai-grok-voice stt/streaming.rs:42-57).
106
+ */
107
+ function buildGrokVoiceHeaders(options) {
108
+ return {
109
+ "user-agent": grokShellUserAgent(options.platform),
110
+ authorization: bearerValue(options.bearer),
111
+ "x-grok-client-version": GROK_BUILD_VERSION,
112
+ "x-grok-client-identifier": GROK_CLIENT_IDENTIFIER
113
+ };
114
+ }
115
+ //#endregion
116
+ export { buildGrokChatHeaders, buildGrokMediaHeaders, buildGrokProxyGetHeaders, buildGrokVoiceHeaders, generateTraceparent, grokMediaUserAgent, grokPlatform, grokShellUserAgent };
117
+
118
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3Jvay1oZWFkZXJzLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy91dGlscy9wcm92aWRlcnMvZ3Jvay9ncm9rLWhlYWRlcnMudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcmFuZG9tQnl0ZXMgfSBmcm9tIFwibm9kZTpjcnlwdG9cIjtcblxuaW1wb3J0IHtcbiAgR1JPS19CVUlMRF9WRVJTSU9OLFxuICBHUk9LX0NMSUVOVF9JREVOVElGSUVSLFxuICBHUk9LX0NMSUVOVF9NT0RFLFxuICBHUk9LX0NPTVBBQ1RJT05fQVQsXG4gIEdST0tfQ09NUEFDVElPTlNfUkVNQUlOSU5HX0RFRkFVTFQsXG4gIEdST0tfRE9PTV9MT09QX0NIRUNLLFxuICBHUk9LX0VYQUNUX1JFUEVUSVRJT05fQ0hFQ0ssXG59IGZyb20gXCIuL2dyb2stY29uc3RhbnRzXCI7XG5cbi8vIEJ1aWxkZXJzIHJldHVybiBwbGFpbiBsb3dlcmNhc2Uta2V5IHJlY29yZHMgd2hvc2UgaW5zZXJ0aW9uIG9yZGVyIGlzIHRoZSB3aXJlIG9yZGVyIHRoZVxuLy8gcGlubmVkIGdyb2stYnVpbGQgZW1pdHMuIGBob3N0YCwgYGNvbnRlbnQtbGVuZ3RoYCBhbmQgYGFjY2VwdC1lbmNvZGluZ2AgYXJlIGxlZnQgdG8gdGhlXG4vLyB0cmFuc3BvcnQuIFRoZSB0aHJlZSBoZWFkZXIgZmFtaWxpZXMgKGNoYXQgcHJveHksIHByb3h5IEdFVCwgYXBpLnguYWkpIGFyZSBuZXZlciBtZXJnZWQuXG5cbmV4cG9ydCBpbnRlcmZhY2UgR3Jva1BsYXRmb3JtIHtcbiAgb3M6IFwibWFjb3NcIiB8IFwid2luZG93c1wiIHwgXCJsaW51eFwiO1xuICBhcmNoOiBcImFhcmNoNjRcIiB8IFwieDg2XzY0XCI7XG59XG5cbi8qKiBNYXBzIE5vZGUgcGxhdGZvcm0vYXJjaCB0byB0aGUgUnVzdCBgc3RkOjplbnY6OmNvbnN0c2AgbmFtZXMgZ3Jvay1idWlsZCByZXBvcnRzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyb2tQbGF0Zm9ybShcbiAgcGxhdGZvcm06IE5vZGVKUy5QbGF0Zm9ybSA9IHByb2Nlc3MucGxhdGZvcm0sXG4gIGFyY2g6IE5vZGVKUy5BcmNoaXRlY3R1cmUgPSBwcm9jZXNzLmFyY2gsXG4pOiBHcm9rUGxhdGZvcm0ge1xuICAvLyBncm9rLWJ1aWxkIHNoaXBzIG9ubHkgdGhlc2UgdGFyZ2V0czsgYW55dGhpbmcgZWxzZSBpcyByZXBvcnRlZCBhcyB0aGUgbmVhcmVzdCBzaGlwcGVkIG9uZVxuICAvLyBzbyB0aGUgVXNlci1BZ2VudCBuZXZlciBjYXJyaWVzIGEgdmFsdWUgdGhlIHJlYWwgYmluYXJ5IGNhbm5vdCBlbWl0LlxuICBjb25zdCBvcyA9IHBsYXRmb3JtID09PSBcImRhcndpblwiID8gXCJtYWNvc1wiIDogcGxhdGZvcm0gPT09IFwid2luMzJcIiA/IFwid2luZG93c1wiIDogXCJsaW51eFwiO1xuXG4gIHJldHVybiB7IG9zLCBhcmNoOiBhcmNoID09PSBcImFybTY0XCIgPyBcImFhcmNoNjRcIiA6IFwieDg2XzY0XCIgfTtcbn1cblxuLyoqIGBncm9rLXNoZWxsLzx2ZXI+ICg8b3M+OyA8YXJjaD4pYCAoZ3Jvay1idWlsZCAxLjAuNDUgeGFpLWdyb2stc2FtcGxlci9zcmMvY2xpZW50LnJzOjQ1Ny00NjMpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdyb2tTaGVsbFVzZXJBZ2VudChwbGF0Zm9ybTogR3Jva1BsYXRmb3JtID0gZ3Jva1BsYXRmb3JtKCkpOiBzdHJpbmcge1xuICByZXR1cm4gYGdyb2stc2hlbGwvJHtHUk9LX0JVSUxEX1ZFUlNJT059ICgke3BsYXRmb3JtLm9zfTsgJHtwbGF0Zm9ybS5hcmNofSlgO1xufVxuXG4vKiogYHhhaS1ncm9rLWJ1aWxkLzx2ZXI+YCAoZ3Jvay1idWlsZCAxLjAuNDUgbWVkaWFfdG9vbF9jb25maWcucnM6MTA0KS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBncm9rTWVkaWFVc2VyQWdlbnQoKTogc3RyaW5nIHtcbiAgcmV0dXJuIGB4YWktZ3Jvay1idWlsZC8ke0dST0tfQlVJTERfVkVSU0lPTn1gO1xufVxuXG5jb25zdCBUUkFDRVBBUkVOVF9QQVRURVJOID0gL14wMC0oPyEwezMyfSlbMC05YS1mXXszMn0tKD8hMHsxNn0pWzAtOWEtZl17MTZ9LTAxJC87XG5cbi8qKiBXM0MgdHJhY2UgY29udGV4dCBgMDAtPHRyYWNlLWlkPi08cGFyZW50LWlkPi0wMWAgd2l0aCBub24temVybyByYW5kb20gaWRzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlVHJhY2VwYXJlbnQoKTogc3RyaW5nIHtcbiAgZm9yICg7Oykge1xuICAgIGNvbnN0IHRyYWNlcGFyZW50ID0gYDAwLSR7cmFuZG9tQnl0ZXMoMTYpLnRvU3RyaW5nKFwiaGV4XCIpfS0ke3JhbmRvbUJ5dGVzKDgpLnRvU3RyaW5nKFwiaGV4XCIpfS0wMWA7XG5cbiAgICBpZiAoVFJBQ0VQQVJFTlRfUEFUVEVSTi50ZXN0KHRyYWNlcGFyZW50KSkgcmV0dXJuIHRyYWNlcGFyZW50O1xuICB9XG59XG5cbmZ1bmN0aW9uIGJlYXJlclZhbHVlKGJlYXJlcjogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKCFiZWFyZXIgfHwgL1xccy8udGVzdChiZWFyZXIpKSB0aHJvdyBuZXcgVHlwZUVycm9yKFwiR3JvayBiZWFyZXIgdG9rZW4gbXVzdCBiZSBub24tZW1wdHlcIik7XG5cbiAgcmV0dXJuIGBCZWFyZXIgJHtiZWFyZXJ9YDtcbn1cblxuZnVuY3Rpb24gbm9uTmVnYXRpdmVJbnRlZ2VyKG5hbWU6IHN0cmluZywgdmFsdWU6IG51bWJlcik6IHN0cmluZyB7XG4gIGlmICghTnVtYmVyLmlzU2FmZUludGVnZXIodmFsdWUpIHx8IHZhbHVlIDwgMClcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke25hbWV9IG11c3QgYmUgYSBub24tbmVnYXRpdmUgaW50ZWdlcmApO1xuXG4gIHJldHVybiBTdHJpbmcodmFsdWUpO1xufVxuXG5mdW5jdGlvbiByZXF1aXJlZFZhbHVlKG5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmICghdmFsdWUgfHwgL1tcXHJcXG5dLy50ZXN0KHZhbHVlKSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGAke25hbWV9IG11c3QgYmUgYSBub24tZW1wdHkgaGVhZGVyIHZhbHVlYCk7XG5cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdyb2tDaGF0SGVhZGVyT3B0aW9ucyB7XG4gIGJlYXJlcjogc3RyaW5nO1xuICBtb2RlbDogc3RyaW5nO1xuICBjb252SWQ6IHN0cmluZztcbiAgcmVxSWQ6IHN0cmluZztcbiAgc2Vzc2lvbklkOiBzdHJpbmc7XG4gIGFnZW50SWQ6IHN0cmluZztcbiAgdXNlcklkOiBzdHJpbmc7XG4gIGNvbnZHcm91cElkOiBzdHJpbmc7XG4gIHR1cm5JZHg6IG51bWJlcjtcbiAgdHJhY2VwYXJlbnQ/OiBzdHJpbmc7XG4gIHRyYW5zaWVudFJldHJ5PzogbnVtYmVyO1xuICBjb21wYWN0aW9uc1JlbWFpbmluZz86IG51bWJlcjtcbiAgenN0ZDogYm9vbGVhbjtcbiAgcGxhdGZvcm0/OiBHcm9rUGxhdGZvcm07XG59XG5cbi8qKiBIZWFkZXJzIGZvciBgUE9TVCB7cHJveHl9L3Jlc3BvbnNlc2AsIGluIHRoZSBvcmRlciBvZiB0aGUgMS4wLjYwIGdvbGRlbiBjYXB0dXJlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkR3Jva0NoYXRIZWFkZXJzKG9wdGlvbnM6IEdyb2tDaGF0SGVhZGVyT3B0aW9ucyk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCB0cmFjZXBhcmVudCA9IG9wdGlvbnMudHJhY2VwYXJlbnQgPz8gZ2VuZXJhdGVUcmFjZXBhcmVudCgpO1xuXG4gIGlmICghVFJBQ0VQQVJFTlRfUEFUVEVSTi50ZXN0KHRyYWNlcGFyZW50KSlcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwidHJhY2VwYXJlbnQgbXVzdCBiZSBhIFczQyAwMC08MzJoZXg+LTwxNmhleD4tMDEgdmFsdWVcIik7XG5cbiAgLy8gQSBNYXAga2VlcHMgaW5zZXJ0aW9uIG9yZGVyLCB3aGljaCBpcyB0aGUgd2lyZSBvcmRlciBvZiB0aGUgZ29sZGVuIGNhcHR1cmUuXG4gIGNvbnN0IGhlYWRlcnMgPSBuZXcgTWFwKFxuICAgIE9iamVjdC5lbnRyaWVzKHtcbiAgICAgIFwiY29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgXCJ1c2VyLWFnZW50XCI6IGdyb2tTaGVsbFVzZXJBZ2VudChvcHRpb25zLnBsYXRmb3JtKSxcbiAgICAgIFwieC1ncm9rLWNsaWVudC1tb2RlXCI6IEdST0tfQ0xJRU5UX01PREUsXG4gICAgICBcIngteGFpLXRva2VuLWF1dGhcIjogXCJ4YWktZ3Jvay1jbGlcIixcbiAgICAgIFwieC1hdXRoZW50aWNhdGVyZXNwb25zZVwiOiBcImF1dGhlbnRpY2F0ZS1yZXNwb25zZVwiLFxuICAgICAgXCJ4LWNvbXBhY3Rpb25zLXJlbWFpbmluZ1wiOiBub25OZWdhdGl2ZUludGVnZXIoXG4gICAgICAgIFwiY29tcGFjdGlvbnNSZW1haW5pbmdcIixcbiAgICAgICAgb3B0aW9ucy5jb21wYWN0aW9uc1JlbWFpbmluZyA/PyBHUk9LX0NPTVBBQ1RJT05TX1JFTUFJTklOR19ERUZBVUxULFxuICAgICAgKSxcbiAgICAgIFwieC1jb21wYWN0aW9uLWF0XCI6IFN0cmluZyhHUk9LX0NPTVBBQ1RJT05fQVQpLFxuICAgICAgXCJ4LWdyb2stY2xpZW50LXZlcnNpb25cIjogR1JPS19CVUlMRF9WRVJTSU9OLFxuICAgICAgXCJ4LWdyb2stdXNlci1pZFwiOiByZXF1aXJlZFZhbHVlKFwidXNlcklkXCIsIG9wdGlvbnMudXNlcklkKSxcbiAgICAgIFwieC1ncm9rLWNvbnYtZ3JvdXAtaWRcIjogcmVxdWlyZWRWYWx1ZShcImNvbnZHcm91cElkXCIsIG9wdGlvbnMuY29udkdyb3VwSWQpLFxuICAgICAgXCJ4LWdyb2stY2xpZW50LWlkZW50aWZpZXJcIjogR1JPS19DTElFTlRfSURFTlRJRklFUixcbiAgICAgIGF1dGhvcml6YXRpb246IGJlYXJlclZhbHVlKG9wdGlvbnMuYmVhcmVyKSxcbiAgICAgIHRyYWNlcGFyZW50LFxuICAgICAgXCJ4LWdyb2stY29udi1pZFwiOiByZXF1aXJlZFZhbHVlKFwiY29udklkXCIsIG9wdGlvbnMuY29udklkKSxcbiAgICAgIFwieC1ncm9rLXJlcS1pZFwiOiByZXF1aXJlZFZhbHVlKFwicmVxSWRcIiwgb3B0aW9ucy5yZXFJZCksXG4gICAgICBcIngtZ3Jvay1tb2RlbC1vdmVycmlkZVwiOiByZXF1aXJlZFZhbHVlKFwibW9kZWxcIiwgb3B0aW9ucy5tb2RlbCksXG4gICAgICBcIngtZ3Jvay1zZXNzaW9uLWlkXCI6IHJlcXVpcmVkVmFsdWUoXCJzZXNzaW9uSWRcIiwgb3B0aW9ucy5zZXNzaW9uSWQpLFxuICAgICAgXCJ4LWdyb2stYWdlbnQtaWRcIjogcmVxdWlyZWRWYWx1ZShcImFnZW50SWRcIiwgb3B0aW9ucy5hZ2VudElkKSxcbiAgICAgIFwieC1ncm9rLXR1cm4taWR4XCI6IG5vbk5lZ2F0aXZlSW50ZWdlcihcInR1cm5JZHhcIiwgb3B0aW9ucy50dXJuSWR4KSxcbiAgICB9KSxcbiAgKTtcblxuICAvLyBOb3QgcHJlc2VudCBpbiB0aGUgY2FwdHVyZTsgZ3Jvay1idWlsZCAxLjAuNDUgY2xpZW50LnJzOjU2MC02MDUgc2VuZHMgaXQgd2l0aCB0aGUgdHVyblxuICAvLyBpbmRleCBncm91cCBvbiByZXRyaWVzIG9ubHkuXG4gIGlmIChvcHRpb25zLnRyYW5zaWVudFJldHJ5ICE9PSB1bmRlZmluZWQpXG4gICAgaGVhZGVycy5zZXQoXG4gICAgICBcIngtZ3Jvay10cmFuc2llbnQtcmV0cnlcIixcbiAgICAgIG5vbk5lZ2F0aXZlSW50ZWdlcihcInRyYW5zaWVudFJldHJ5XCIsIG9wdGlvbnMudHJhbnNpZW50UmV0cnkpLFxuICAgICk7XG4gIGhlYWRlcnMuc2V0KFwiYWNjZXB0XCIsIFwidGV4dC9ldmVudC1zdHJlYW1cIik7XG4gIGhlYWRlcnMuc2V0KFwieC1ncm9rLWRvb20tbG9vcC1jaGVja1wiLCBTdHJpbmcoR1JPS19ET09NX0xPT1BfQ0hFQ0spKTtcbiAgaGVhZGVycy5zZXQoXCJ4LWdyb2stZXhhY3QtcmVwZXRpdGlvbi1jaGVja1wiLCBTdHJpbmcoR1JPS19FWEFDVF9SRVBFVElUSU9OX0NIRUNLKSk7XG5cbiAgaWYgKG9wdGlvbnMuenN0ZCkgaGVhZGVycy5zZXQoXCJjb250ZW50LWVuY29kaW5nXCIsIFwienN0ZFwiKTtcblxuICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKGhlYWRlcnMpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdyb2tQcm94eUdldEhlYWRlck9wdGlvbnMge1xuICBiZWFyZXI6IHN0cmluZztcbiAgdXNlcklkOiBzdHJpbmc7XG4gIGVtYWlsPzogc3RyaW5nO1xuICBwbGF0Zm9ybT86IEdyb2tQbGF0Zm9ybTtcbn1cblxuLyoqXG4gKiBIZWFkZXJzIGZvciBwcm94eSBHRVRzIChgL3NldHRpbmdzYCwgYC9tb2RlbHNgLCBgL2JpbGxpbmdgLCBgL3VzZXJgKS4gT3JkZXIgZm9sbG93cyB0aGVcbiAqIDEuMC42MCBjYXB0dXJlIG9mIGBHRVQgL3NldHRpbmdzYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkR3Jva1Byb3h5R2V0SGVhZGVycyhcbiAgb3B0aW9uczogR3Jva1Byb3h5R2V0SGVhZGVyT3B0aW9ucyxcbik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBoZWFkZXJzID0gbmV3IE1hcChbXG4gICAgW1wiYXV0aG9yaXphdGlvblwiLCBiZWFyZXJWYWx1ZShvcHRpb25zLmJlYXJlcildLFxuICAgIFtcIngteGFpLXRva2VuLWF1dGhcIiwgXCJ4YWktZ3Jvay1jbGlcIl0sXG4gICAgW1wieC11c2VyaWRcIiwgcmVxdWlyZWRWYWx1ZShcInVzZXJJZFwiLCBvcHRpb25zLnVzZXJJZCldLFxuICAgIFtcIngtZ3Jvay1jbGllbnQtdmVyc2lvblwiLCBHUk9LX0JVSUxEX1ZFUlNJT05dLFxuICBdKTtcblxuICBpZiAob3B0aW9ucy5lbWFpbCAhPT0gdW5kZWZpbmVkKSBoZWFkZXJzLnNldChcIngtZW1haWxcIiwgcmVxdWlyZWRWYWx1ZShcImVtYWlsXCIsIG9wdGlvbnMuZW1haWwpKTtcbiAgaGVhZGVycy5zZXQoXCJ4LWdyb2stY2xpZW50LWlkZW50aWZpZXJcIiwgR1JPS19DTElFTlRfSURFTlRJRklFUik7XG4gIGhlYWRlcnMuc2V0KFwieC1ncm9rLWNsaWVudC1tb2RlXCIsIEdST0tfQ0xJRU5UX01PREUpO1xuICBoZWFkZXJzLnNldChcImFjY2VwdFwiLCBcIiovKlwiKTtcbiAgaGVhZGVycy5zZXQoXCJ1c2VyLWFnZW50XCIsIGdyb2tTaGVsbFVzZXJBZ2VudChvcHRpb25zLnBsYXRmb3JtKSk7XG5cbiAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhoZWFkZXJzKTtcbn1cblxuLyoqXG4gKiBIZWFkZXJzIGZvciBgYXBpLnguYWlgIGltYWdlL3ZpZGVvIGNhbGxzLiBUaGUgcHJveHkgYXV0aCB0cmlvIGlzIG5ldmVyIGF0dGFjaGVkLlxuICogYHgtZ3Jvay1zZXNzaW9uLWlkYCBpcyBhdHRhY2hlZCBwZXIgcmVxdWVzdCByaWdodCBhZnRlciB0aGUgYmVhcmVyIChncm9rLWJ1aWxkIHhhaS1ncm9rLXRvb2xzXG4gKiBpbWFnZV9nZW4vbW9kLnJzOjE5OS0yMTMsIHZpZGVvX2dlbi9tb2QucnM6MjU4LTI3MCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZEdyb2tNZWRpYUhlYWRlcnMob3B0aW9uczogeyBiZWFyZXI6IHN0cmluZzsgc2Vzc2lvbklkOiBzdHJpbmcgfSkge1xuICByZXR1cm4ge1xuICAgIFwidXNlci1hZ2VudFwiOiBncm9rTWVkaWFVc2VyQWdlbnQoKSxcbiAgICBhdXRob3JpemF0aW9uOiBiZWFyZXJWYWx1ZShvcHRpb25zLmJlYXJlciksXG4gICAgXCJ4LWdyb2stc2Vzc2lvbi1pZFwiOiByZXF1aXJlZFZhbHVlKFwic2Vzc2lvbklkXCIsIG9wdGlvbnMuc2Vzc2lvbklkKSxcbiAgICBcIngtZ3Jvay1jbGllbnQtdmVyc2lvblwiOiBHUk9LX0JVSUxEX1ZFUlNJT04sXG4gICAgXCJ4LWdyb2stY2xpZW50LWlkZW50aWZpZXJcIjogR1JPS19DTElFTlRfSURFTlRJRklFUixcbiAgfTtcbn1cblxuLyoqXG4gKiBIZWFkZXJzIGZvciBgYXBpLnguYWlgIFNUVC9UVFMgY2FsbHMgKGdyb2stYnVpbGQgMS4wLjQ1IHhhaS1ncm9rLXBhZ2VyIGNsaWVudF9pZGVudGl0eS5ycykuXG4gKiBObyBzZXNzaW9uIGlkOiB0aGUgdm9pY2UgY2xpZW50IHNlbmRzIG5vbmUgKHhhaS1ncm9rLXZvaWNlIHN0dC9zdHJlYW1pbmcucnM6NDItNTcpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRHcm9rVm9pY2VIZWFkZXJzKG9wdGlvbnM6IHsgYmVhcmVyOiBzdHJpbmc7IHBsYXRmb3JtPzogR3Jva1BsYXRmb3JtIH0pIHtcbiAgcmV0dXJuIHtcbiAgICBcInVzZXItYWdlbnRcIjogZ3Jva1NoZWxsVXNlckFnZW50KG9wdGlvbnMucGxhdGZvcm0pLFxuICAgIGF1dGhvcml6YXRpb246IGJlYXJlclZhbHVlKG9wdGlvbnMuYmVhcmVyKSxcbiAgICBcIngtZ3Jvay1jbGllbnQtdmVyc2lvblwiOiBHUk9LX0JVSUxEX1ZFUlNJT04sXG4gICAgXCJ4LWdyb2stY2xpZW50LWlkZW50aWZpZXJcIjogR1JPS19DTElFTlRfSURFTlRJRklFUixcbiAgfTtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7OztBQXNCQSxTQUFnQixhQUNkLFdBQTRCLFFBQVEsVUFDcEMsT0FBNEIsUUFBUSxNQUN0QjtDQUtkLE9BQU87RUFBRSxJQUZFLGFBQWEsV0FBVyxVQUFVLGFBQWEsVUFBVSxZQUFZO0VBRW5FLE1BQU0sU0FBUyxVQUFVLFlBQVk7Q0FBUztBQUM3RDs7QUFHQSxTQUFnQixtQkFBbUIsV0FBeUIsYUFBYSxHQUFXO0NBQ2xGLE9BQU8sY0FBYyxtQkFBbUIs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
@@ -0,0 +1,420 @@
1
+ import { GROK_IMAGE_DEFAULT_MODEL } from "./grok-constants.js";
2
+ import { GrokProtocolError, classifyGrokHttpError, readGrokResponseHeaders } from "./grok-backend-protocol.js";
3
+ import { GrokHttpError } from "./grok-direct-client.js";
4
+ import { buildGrokMediaHeaders } from "./grok-headers.js";
5
+ import { GrokImageResponse, GrokVideoStart, GrokVideoStatus, grokVideoUrl } from "./grok-types.js";
6
+ import { GrokInvalidRequestError } from "./grok-dispatcher.js";
7
+ import { z } from "zod";
8
+ //#region src/utils/providers/grok/grok-media-client.ts
9
+ const GROK_IMAGE_TOTAL_TIMEOUT_MS = 3e5;
10
+ const GROK_IMAGE_READ_TIMEOUT_MS = 24e4;
11
+ const GROK_VIDEO_START_TIMEOUT_MS = 6e4;
12
+ const GROK_VIDEO_POLL_TIMEOUT_MS = 3e4;
13
+ const GROK_IMAGE_MAX_PER_CALL = 3;
14
+ const GROK_IMAGE_DEFAULT_RESOLUTION = "1k";
15
+ const GROK_IMAGE_EDIT_DEFAULT_MODEL = GROK_IMAGE_DEFAULT_MODEL;
16
+ const GROK_VIDEO_MAX_DURATION_SEC = 15;
17
+ const MAX_IMAGE_RESPONSE_BYTES = 64 * 1024 * 1024;
18
+ const MAX_JSON_RESPONSE_BYTES = 1024 * 1024;
19
+ const MAX_ERROR_BODY_BYTES = 64 * 1024;
20
+ const DEFAULT_TIMEOUTS = {
21
+ imageTotalMs: GROK_IMAGE_TOTAL_TIMEOUT_MS,
22
+ imageReadMs: GROK_IMAGE_READ_TIMEOUT_MS,
23
+ videoStartMs: GROK_VIDEO_START_TIMEOUT_MS,
24
+ videoPollMs: GROK_VIDEO_POLL_TIMEOUT_MS
25
+ };
26
+ /** Upstream flagged the output with `respect_moderation: false`. Never retried. */
27
+ var GrokContentPolicyError = class extends Error {
28
+ constructor(kind) {
29
+ super(`${kind === "image" ? "Image" : "Video"} generation was blocked due to a content policy violation.`);
30
+ this.name = "GrokContentPolicyError";
31
+ }
32
+ };
33
+ /** A total or read timeout fired. For a POST, upstream may already be executing the job. */
34
+ var GrokMediaTimeoutError = class extends Error {
35
+ phase;
36
+ timeoutMs;
37
+ constructor(phase, timeoutMs) {
38
+ super(`Grok media request ${phase === "total" ? "timed out" : "stalled"} after ${timeoutMs} ms`);
39
+ this.name = "GrokMediaTimeoutError";
40
+ this.phase = phase;
41
+ this.timeoutMs = timeoutMs;
42
+ }
43
+ };
44
+ /** A POST failed after it may have been written; replaying it could run the job twice. */
45
+ var GrokMediaDeliveryError = class extends Error {
46
+ constructor(message, options) {
47
+ super(`Grok media request failed after it may have been sent: ${message}`, options);
48
+ this.name = "GrokMediaDeliveryError";
49
+ }
50
+ };
51
+ const PRE_SEND_ERROR_CODES = /* @__PURE__ */ new Set([
52
+ "ECONNREFUSED",
53
+ "ENOTFOUND",
54
+ "EAI_AGAIN",
55
+ "EAI_FAIL",
56
+ "EHOSTUNREACH",
57
+ "EHOSTDOWN",
58
+ "ENETUNREACH",
59
+ "ENETDOWN",
60
+ "UND_ERR_CONNECT_TIMEOUT",
61
+ "ERR_TLS_CERT_ALTNAME_INVALID",
62
+ "CERT_HAS_EXPIRED",
63
+ "DEPTH_ZERO_SELF_SIGNED_CERT",
64
+ "SELF_SIGNED_CERT_IN_CHAIN",
65
+ "UNABLE_TO_GET_ISSUER_CERT_LOCALLY",
66
+ "UNABLE_TO_VERIFY_LEAF_SIGNATURE"
67
+ ]);
68
+ const ErrorWithCode = z.looseObject({ code: z.string() });
69
+ const ErrorWithCause = z.looseObject({ cause: z.unknown() });
70
+ /** The first `code` along the `cause` chain (undici wraps socket errors in `TypeError`). */
71
+ function errorCode(cause) {
72
+ let current = cause;
73
+ for (let depth = 0; depth < 5 && current !== void 0 && current !== null; depth++) {
74
+ const withCode = ErrorWithCode.safeParse(current);
75
+ if (withCode.success) return withCode.data.code;
76
+ const withCause = ErrorWithCause.safeParse(current);
77
+ current = withCause.success ? withCause.data.cause : void 0;
78
+ }
79
+ }
80
+ function errorMessage(cause) {
81
+ return cause instanceof Error ? cause.message : String(cause);
82
+ }
83
+ function abortReason(signal) {
84
+ const reason = signal.reason;
85
+ return reason instanceof Error ? reason : new DOMException("Aborted", "AbortError");
86
+ }
87
+ function connectFailure(cause) {
88
+ const code = errorCode(cause);
89
+ const message = `${errorMessage(cause)}${code ? ` (${code})` : ""}`;
90
+ return new GrokHttpError({
91
+ ...classifyGrokHttpError(0, "", {}),
92
+ message
93
+ }, "", {}, { cause });
94
+ }
95
+ const BASE64 = /^[A-Za-z0-9+/]*={0,2}$/;
96
+ function sniffImageMediaType(bytes) {
97
+ if (bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) return "image/jpeg";
98
+ if (bytes[0] === 137 && bytes[1] === 80 && bytes[2] === 78 && bytes[3] === 71) return "image/png";
99
+ if (bytes[0] === 71 && bytes[1] === 73 && bytes[2] === 70) return "image/gif";
100
+ const ascii = (from, to) => String.fromCharCode(...bytes.subarray(from, to));
101
+ if (ascii(0, 4) === "RIFF" && ascii(8, 12) === "WEBP") return "image/webp";
102
+ }
103
+ function assertImagesAllowed(response) {
104
+ if (response.data.some((image) => image.respect_moderation === false)) throw new GrokContentPolicyError("image");
105
+ for (const image of response.data) if (image.b64_json.length % 4 !== 0 || !BASE64.test(image.b64_json)) throw new GrokProtocolError("Grok image response carried invalid base64 data");
106
+ }
107
+ /** Decodes a validated image response. `mime_type` wins; otherwise the bytes are sniffed. */
108
+ function decodeGrokImages(response) {
109
+ assertImagesAllowed(response);
110
+ const images = response.data.map((image) => {
111
+ const bytes = new Uint8Array(Buffer.from(image.b64_json, "base64"));
112
+ const decoded = {
113
+ bytes,
114
+ mediaType: image.mime_type?.startsWith("image/") ? image.mime_type : sniffImageMediaType(bytes) ?? "image/jpeg"
115
+ };
116
+ if (image.revised_prompt) decoded.revisedPrompt = image.revised_prompt;
117
+ if (image.respect_moderation !== void 0) decoded.respectModeration = image.respect_moderation;
118
+ return decoded;
119
+ });
120
+ const ticks = response.usage?.cost_in_usd_ticks;
121
+ const result = { images };
122
+ if (ticks !== void 0) result.costInUsdTicks = ticks;
123
+ return result;
124
+ }
125
+ const VideoStatusExtras = z.looseObject({
126
+ video: z.looseObject({ respect_moderation: z.boolean().nullish() }).nullish(),
127
+ error: z.looseObject({
128
+ code: z.string().nullish(),
129
+ message: z.string().nullish()
130
+ }).nullish()
131
+ });
132
+ /**
133
+ * Collapses a poll response to the SDK's three outcomes. The URL is returned unchanged (D4);
134
+ * `expired` and a `done` without a URL are failures (xai-video-model.ts:643-705).
135
+ */
136
+ function summarizeGrokVideoStatus(status) {
137
+ const extras = VideoStatusExtras.parse(status);
138
+ if (extras.video?.respect_moderation === false) throw new GrokContentPolicyError("video");
139
+ const ticks = status.usage?.cost_in_usd_ticks;
140
+ const base = { mimeType: "video/mp4" };
141
+ if (ticks !== void 0) base.usageTicks = ticks;
142
+ if (status.status === "expired") return {
143
+ ...base,
144
+ status: "failed",
145
+ error: "Video generation request expired."
146
+ };
147
+ if (status.status === "failed") {
148
+ const error = extras.error?.message ?? extras.error?.code ?? "Video generation failed.";
149
+ return {
150
+ ...base,
151
+ status: "failed",
152
+ error
153
+ };
154
+ }
155
+ if (status.status === "done") {
156
+ const url = grokVideoUrl(status);
157
+ if (!url) return {
158
+ ...base,
159
+ status: "failed",
160
+ error: "Video generation completed but no video URL was returned."
161
+ };
162
+ return {
163
+ ...base,
164
+ status: "done",
165
+ url
166
+ };
167
+ }
168
+ return {
169
+ ...base,
170
+ status: "pending"
171
+ };
172
+ }
173
+ var BodyLimitError = class extends Error {};
174
+ var GrokMediaClient = class {
175
+ fetchImpl;
176
+ baseUrl;
177
+ timeouts;
178
+ constructor(options = {}) {
179
+ this.fetchImpl = options.fetch ?? fetch;
180
+ this.baseUrl = (options.baseUrl ?? "https://api.x.ai/v1").replace(/\/+$/, "");
181
+ this.timeouts = {
182
+ ...DEFAULT_TIMEOUTS,
183
+ ...options.timeouts
184
+ };
185
+ }
186
+ async generateImages(auth, request) {
187
+ const body = imageBody(request, request.model.trim() || "grok-imagine-image-quality");
188
+ return this.postImages("/images/generations", auth, body, request.signal);
189
+ }
190
+ async editImages(auth, request) {
191
+ if (request.images.length === 0) throw new GrokInvalidRequestError("Grok image edit needs at least one reference image");
192
+ const urls = request.images.map((url) => {
193
+ if (!url.trim()) throw new GrokInvalidRequestError("Grok image edit reference must be a non-empty URL");
194
+ return { url };
195
+ });
196
+ const body = imageBody(request, request.model.trim() || GROK_IMAGE_EDIT_DEFAULT_MODEL);
197
+ if (urls.length === 1) body.image = urls[0];
198
+ else body.images = urls;
199
+ return this.postImages("/images/edits", auth, body, request.signal);
200
+ }
201
+ async startVideo(auth, request) {
202
+ const body = videoBody(request);
203
+ const { text } = await this.call({
204
+ method: "POST",
205
+ path: "/videos/generations",
206
+ auth,
207
+ body,
208
+ totalMs: this.timeouts.videoStartMs,
209
+ readMs: this.timeouts.videoStartMs,
210
+ maxBytes: MAX_JSON_RESPONSE_BYTES,
211
+ signal: request.signal
212
+ });
213
+ return parseJson(GrokVideoStart, text, "video start");
214
+ }
215
+ async getVideo(auth, requestId, signal) {
216
+ if (!requestId.trim()) throw new TypeError("Grok video request id must be non-empty");
217
+ const { response, text } = await this.call({
218
+ method: "GET",
219
+ path: `/videos/${encodeURIComponent(requestId)}`,
220
+ auth,
221
+ totalMs: this.timeouts.videoPollMs,
222
+ readMs: this.timeouts.videoPollMs,
223
+ maxBytes: MAX_JSON_RESPONSE_BYTES,
224
+ signal
225
+ });
226
+ const status = parseVideoStatus(response.status, text);
227
+ if (VideoStatusExtras.parse(status).video?.respect_moderation === false) throw new GrokContentPolicyError("video");
228
+ return status;
229
+ }
230
+ async postImages(path, auth, body, signal) {
231
+ const { text } = await this.call({
232
+ method: "POST",
233
+ path,
234
+ auth,
235
+ body,
236
+ totalMs: this.timeouts.imageTotalMs,
237
+ readMs: this.timeouts.imageReadMs,
238
+ maxBytes: MAX_IMAGE_RESPONSE_BYTES,
239
+ signal
240
+ });
241
+ const response = parseJson(GrokImageResponse, text, "image");
242
+ assertImagesAllowed(response);
243
+ return response;
244
+ }
245
+ /** One HTTP exchange with total and read timeouts composed with the caller's signal. */
246
+ async call(call) {
247
+ const { signal } = call;
248
+ if (signal?.aborted) throw abortReason(signal);
249
+ const headers = {
250
+ "content-type": "application/json",
251
+ ...buildGrokMediaHeaders({
252
+ bearer: call.auth.bearer,
253
+ sessionId: call.auth.sessionId
254
+ })
255
+ };
256
+ const controller = new AbortController();
257
+ let timeout;
258
+ const fire = (error) => {
259
+ if (timeout || controller.signal.aborted) return;
260
+ timeout = error;
261
+ controller.abort(error);
262
+ };
263
+ const totalTimer = setTimeout(() => fire(new GrokMediaTimeoutError("total", call.totalMs)), call.totalMs);
264
+ let readTimer;
265
+ const armRead = () => {
266
+ clearTimeout(readTimer);
267
+ readTimer = setTimeout(() => fire(new GrokMediaTimeoutError("read", call.readMs)), call.readMs);
268
+ };
269
+ const onAbort = () => controller.abort(signal?.reason);
270
+ signal?.addEventListener("abort", onAbort, { once: true });
271
+ const settle = (cause, responded) => {
272
+ if (signal?.aborted) return abortReason(signal);
273
+ if (timeout) return timeout;
274
+ if (cause instanceof GrokProtocolError || cause instanceof GrokHttpError) return cause;
275
+ if (call.method === "GET") return connectFailure(cause);
276
+ if (!responded && PRE_SEND_ERROR_CODES.has(errorCode(cause) ?? "")) return connectFailure(cause);
277
+ return new GrokMediaDeliveryError(errorMessage(cause), { cause });
278
+ };
279
+ try {
280
+ armRead();
281
+ let response;
282
+ try {
283
+ response = await this.fetchImpl(`${this.baseUrl}${call.path}`, {
284
+ method: call.method,
285
+ headers,
286
+ body: call.body === void 0 ? void 0 : JSON.stringify(call.body),
287
+ signal: controller.signal
288
+ });
289
+ } catch (error) {
290
+ throw settle(error, false);
291
+ }
292
+ armRead();
293
+ try {
294
+ if (!response.ok) {
295
+ const bodyText = await readBody(response, MAX_ERROR_BODY_BYTES, armRead, true);
296
+ throw new GrokHttpError(classifyGrokHttpError(response.status, bodyText, response.headers), bodyText, readGrokResponseHeaders(response.headers));
297
+ }
298
+ const text = await readBody(response, call.maxBytes, armRead, false);
299
+ return {
300
+ response,
301
+ text
302
+ };
303
+ } catch (error) {
304
+ if (error instanceof BodyLimitError) throw new GrokProtocolError(error.message);
305
+ throw settle(error, true);
306
+ }
307
+ } finally {
308
+ clearTimeout(totalTimer);
309
+ clearTimeout(readTimer);
310
+ signal?.removeEventListener("abort", onAbort);
311
+ }
312
+ }
313
+ };
314
+ function imageBody(request, model) {
315
+ const n = request.n ?? 1;
316
+ if (!Number.isSafeInteger(n) || n < 1 || n > 3) throw new RangeError(`Grok image count must be an integer from 1 to 3`);
317
+ return {
318
+ model,
319
+ prompt: request.prompt,
320
+ n,
321
+ aspect_ratio: request.aspectRatio,
322
+ resolution: request.resolution ?? GROK_IMAGE_DEFAULT_RESOLUTION,
323
+ response_format: "b64_json",
324
+ quality: request.quality,
325
+ output_format: request.outputFormat
326
+ };
327
+ }
328
+ function videoBody(request) {
329
+ const references = request.referenceImages ?? [];
330
+ if (request.mode === "reference-to-video" && references.length === 0) throw new GrokInvalidRequestError("Grok reference-to-video needs at least one reference image");
331
+ const { duration } = request;
332
+ if (duration !== void 0 && (!Number.isSafeInteger(duration) || duration < 1 || duration > GROK_VIDEO_MAX_DURATION_SEC)) throw new GrokInvalidRequestError(`Grok video duration must be an integer from 1 to ${GROK_VIDEO_MAX_DURATION_SEC}`);
333
+ return {
334
+ model: request.model.trim() || "grok-imagine-video-1.5",
335
+ prompt: request.prompt,
336
+ image: request.image === void 0 ? void 0 : { url: request.image },
337
+ duration,
338
+ aspect_ratio: request.aspectRatio,
339
+ resolution: request.resolution,
340
+ reference_images: references.length === 0 ? void 0 : references.map((url) => ({ url })),
341
+ last_frame: request.lastFrame === void 0 ? void 0 : { url: request.lastFrame }
342
+ };
343
+ }
344
+ function parseJsonText(text, what) {
345
+ try {
346
+ return JSON.parse(text);
347
+ } catch {
348
+ throw new GrokProtocolError(`Grok ${what} response is not JSON`);
349
+ }
350
+ }
351
+ function parseJson(schema, text, what) {
352
+ const parsed = schema.safeParse(parseJsonText(text, what));
353
+ if (!parsed.success) throw new GrokProtocolError(`Grok ${what} response has an unexpected shape`);
354
+ return parsed.data;
355
+ }
356
+ const JsonObject = z.record(z.string(), z.unknown());
357
+ const LooseVideoStatus = z.looseObject({
358
+ status: z.string().nullish(),
359
+ video: z.looseObject({ url: z.string().nullish() }).nullish()
360
+ });
361
+ /**
362
+ * 202 means pending, possibly with an empty or partial body (xai-video-model.ts:876-894;
363
+ * grok-build video_gen/mod.rs:442 accepts it too). A 200 without `status` but with a video URL
364
+ * is done (xai-video-model.ts:673-676).
365
+ */
366
+ function parseVideoStatus(httpStatus, text) {
367
+ if (httpStatus === 202) {
368
+ if (!text.trim()) return { status: "pending" };
369
+ let json;
370
+ try {
371
+ json = JSON.parse(text);
372
+ } catch {
373
+ return { status: "pending" };
374
+ }
375
+ const object = JsonObject.safeParse(json);
376
+ const loose = LooseVideoStatus.safeParse(json);
377
+ if (!object.success || !loose.success) return { status: "pending" };
378
+ const parsed = GrokVideoStatus.safeParse({
379
+ ...object.data,
380
+ status: loose.data.status ?? "pending"
381
+ });
382
+ return parsed.success ? parsed.data : { status: "pending" };
383
+ }
384
+ const json = parseJsonText(text, "video status");
385
+ const object = JsonObject.safeParse(json);
386
+ const loose = LooseVideoStatus.safeParse(json);
387
+ if (!object.success || !loose.success) throw new GrokProtocolError("Grok video status response has an unexpected shape");
388
+ const status = loose.data.status ?? (loose.data.video?.url ? "done" : "pending");
389
+ const parsed = GrokVideoStatus.safeParse({
390
+ ...object.data,
391
+ status
392
+ });
393
+ if (!parsed.success) throw new GrokProtocolError("Grok video status response has an unexpected shape");
394
+ return parsed.data;
395
+ }
396
+ /** Reads the body, re-arming the read timer per chunk. `truncate` caps instead of failing. */
397
+ async function readBody(response, maxBytes, onChunk, truncate) {
398
+ if (!response.body) return "";
399
+ const reader = response.body.getReader();
400
+ const decoder = new TextDecoder();
401
+ let text = "";
402
+ let total = 0;
403
+ for (;;) {
404
+ const { done, value } = await reader.read();
405
+ if (done) break;
406
+ onChunk();
407
+ total += value.byteLength;
408
+ if (total > maxBytes) {
409
+ await reader.cancel().catch(() => void 0);
410
+ if (truncate) return text + decoder.decode(value.subarray(0, maxBytes - (total - value.byteLength)));
411
+ throw new BodyLimitError(`Grok media response exceeded ${maxBytes} bytes`);
412
+ }
413
+ text += decoder.decode(value, { stream: true });
414
+ }
415
+ return text + decoder.decode();
416
+ }
417
+ //#endregion
418
+ export { GROK_IMAGE_MAX_PER_CALL, GROK_IMAGE_READ_TIMEOUT_MS, GROK_IMAGE_TOTAL_TIMEOUT_MS, GROK_VIDEO_POLL_TIMEOUT_MS, GROK_VIDEO_START_TIMEOUT_MS, GrokContentPolicyError, GrokMediaClient, GrokMediaDeliveryError, GrokMediaTimeoutError, decodeGrokImages, summarizeGrokVideoStatus };
419
+
420
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3Jvay1tZWRpYS1jbGllbnQuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9ncm9rL2dyb2stbWVkaWEtY2xpZW50LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmltcG9ydCB7IHR5cGUgSnNvblZhbHVlIH0gZnJvbSBcIi4uL2NvbW1vbi9wcm92aWRlci10eXBlc1wiO1xuaW1wb3J0IHtcbiAgY2xhc3NpZnlHcm9rSHR0cEVycm9yLFxuICBHcm9rUHJvdG9jb2xFcnJvcixcbiAgcmVhZEdyb2tSZXNwb25zZUhlYWRlcnMsXG59IGZyb20gXCIuL2dyb2stYmFja2VuZC1wcm90b2NvbFwiO1xuaW1wb3J0IHtcbiAgR1JPS19JTUFHRV9ERUZBVUxUX01PREVMLFxuICBHUk9LX1BVQkxJQ19BUElfVVJMLFxuICBHUk9LX1ZJREVPX0RFRkFVTFRfTU9ERUwsXG59IGZyb20gXCIuL2dyb2stY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBHcm9rSHR0cEVycm9yIH0gZnJvbSBcIi4vZ3Jvay1kaXJlY3QtY2xpZW50XCI7XG5pbXBvcnQgeyBHcm9rSW52YWxpZFJlcXVlc3RFcnJvciB9IGZyb20gXCIuL2dyb2stZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgYnVpbGRHcm9rTWVkaWFIZWFkZXJzIH0gZnJvbSBcIi4vZ3Jvay1oZWFkZXJzXCI7XG5pbXBvcnQge1xuICBHcm9rSW1hZ2VSZXNwb25zZSxcbiAgR3Jva1ZpZGVvU3RhcnQsXG4gIEdyb2tWaWRlb1N0YXR1cyxcbiAgZ3Jva1ZpZGVvVXJsLFxuICB0eXBlIEdyb2tJbWFnZUVkaXRSZXF1ZXN0LFxuICB0eXBlIEdyb2tJbWFnZUdlbmVyYXRlUmVxdWVzdCxcbiAgdHlwZSBHcm9rTWVkaWFBdXRoLFxuICB0eXBlIEdyb2tNZWRpYVBvcnQsXG4gIHR5cGUgR3Jva1ZpZGVvU3RhcnRSZXF1ZXN0LFxufSBmcm9tIFwiLi9ncm9rLXR5cGVzXCI7XG5cbi8vIGFwaS54LmFpIEltYWdpbmUgY2xpZW50IChpbWFnZXMgKyB2aWRlbykuIEJvZGllcyBhcmUgcGxhaW4gSlNPTjogZ3Jvay1idWlsZCBzZW5kcyB0aGVtIHdpdGhcbi8vIHJlcXdlc3QgYC5qc29uKHBheWxvYWQpYCBhbmQgbm8gY29udGVudC1lbmNvZGluZyAoMS4wLjQ1IHhhaS1ncm9rLXRvb2xzIGltYWdlX2dlbi9tb2QucnM6MTk5LTIxNCxcbi8vIGltYWdlX2VkaXQvbW9kLnJzOjM5OCwgdmlkZW9fZ2VuL21vZC5yczozNjQtMzY3KS4gRXZlcnkgcmVxdWVzdCBjYXJyaWVzIGBjb250ZW50LXR5cGU6XG4vLyBhcHBsaWNhdGlvbi9qc29uYCBiZWNhdXNlIGdyb2stYnVpbGQgaW5zdGFsbHMgaXQgYXMgYSBjbGllbnQgZGVmYXVsdCBoZWFkZXIsIEdFVCBpbmNsdWRlZFxuLy8gKGltYWdlX2dlbi9tb2QucnM6MTA0LTEwNSwgdmlkZW9fZ2VuL21vZC5yczoxODUtMTg2KS5cbi8vXG4vLyBSZXRyeSBzYWZldHkgKHBsYW4gwqc1LjUpOiB0aGlzIGNsaWVudCBuZXZlciByZXRyaWVzLiBBIFBPU1QgdGhhdCBtYXkgaGF2ZSByZWFjaGVkIHVwc3RyZWFtXG4vLyBmYWlscyB3aXRoIEdyb2tNZWRpYURlbGl2ZXJ5RXJyb3Igb3IgR3Jva01lZGlhVGltZW91dEVycm9yLCB3aGljaCB0aGUgZGlzcGF0Y2hlciBjYW5ub3Rcbi8vIGNsYXNzaWZ5IGFuZCB0aGVyZWZvcmUgbmV2ZXIgcmVwbGF5cy4gT25seSBhIGNvbm5lY3QgZmFpbHVyZSB0aGF0IHByb3ZhYmx5IGhhcHBlbmVkIGJlZm9yZVxuLy8gdGhlIHJlcXVlc3Qgd2FzIHdyaXR0ZW4gYmVjb21lcyBhIHRyYW5zaWVudCBHcm9rSHR0cEVycm9yIChzdGF0dXMgMCk7IHRoZSBkaXNwYXRjaGVyIGZhaWxzXG4vLyBvdmVyIG9uIGV4YWN0bHkgdGhhdCBlcnJvciBvbmNlLiBHRVRzICh2aWRlbyBwb2xscykgYWxzbyBtYXAgZXZlcnkgdHJhbnNwb3J0IGZhaWx1cmUgdG9cbi8vIHN0YXR1cyAwOiB0aGV5IGFyZSBpZGVtcG90ZW50LCBhbmQgdGhlIGRpc3BhdGNoZXIgcGlucyBwb2xscyB0byB0aGVpciB0b2tlbi5cblxuLy8gaW1hZ2VfZ2VuL21vZC5yczozNy0zOCAodGhlIHByb3h5IGJ1ZmZlcnMgdGhlIHdob2xlIGltYWdlIGJlZm9yZSB0aGUgZmlyc3QgYnl0ZSlcbmV4cG9ydCBjb25zdCBHUk9LX0lNQUdFX1RPVEFMX1RJTUVPVVRfTVMgPSAzMDBfMDAwO1xuZXhwb3J0IGNvbnN0IEdST0tfSU1BR0VfUkVBRF9USU1FT1VUX01TID0gMjQwXzAwMDtcblxuLy8gdmlkZW9fZ2VuL21vZC5yczozNyw0MFxuZXhwb3J0IGNvbnN0IEdST0tfVklERU9fU1RBUlRfVElNRU9VVF9NUyA9IDYwXzAwMDtcbmV4cG9ydCBjb25zdCBHUk9LX1ZJREVPX1BPTExfVElNRU9VVF9NUyA9IDMwXzAwMDtcblxuLy8gQGFpLXNkay94YWkgeGFpLWltYWdlLW1vZGVsLnRzIG1heEltYWdlc1BlckNhbGxcbmV4cG9ydCBjb25zdCBHUk9LX0lNQUdFX01BWF9QRVJfQ0FMTCA9IDM7XG5cbi8vIGdyb2stYnVpbGQgaW1hZ2VfZ2VuL21vZC5yczoyMzYgYW5kIGltYWdlX2VkaXQvbW9kLnJzOjM2NyBhbHdheXMgc2VuZCBcIjFrXCJcbmNvbnN0IEdST0tfSU1BR0VfREVGQVVMVF9SRVNPTFVUSU9OID0gXCIxa1wiO1xuXG4vLyBpbWFnZV9lZGl0L21vZC5yczoyOCAoWEFJX0lNQUdJTkVfRURJVF9NT0RFTCBlcXVhbHMgdGhlIGdlbmVyYXRpb24gZGVmYXVsdClcbmNvbnN0IEdST0tfSU1BR0VfRURJVF9ERUZBVUxUX01PREVMID0gR1JPS19JTUFHRV9ERUZBVUxUX01PREVMO1xuXG4vLyBAYWktc2RrL3hhaSB2aWRlbyBkdXJhdGlvbiByYW5nZSAxLTE1IHMgKHBsYW4gwqczLjYpXG5jb25zdCBHUk9LX1ZJREVPX01BWF9EVVJBVElPTl9TRUMgPSAxNTtcblxuY29uc3QgTUFYX0lNQUdFX1JFU1BPTlNFX0JZVEVTID0gNjQgKiAxMDI0ICogMTAyNDtcbmNvbnN0IE1BWF9KU09OX1JFU1BPTlNFX0JZVEVTID0gMTAyNCAqIDEwMjQ7XG5jb25zdCBNQVhfRVJST1JfQk9EWV9CWVRFUyA9IDY0ICogMTAyNDtcblxuZXhwb3J0IGludGVyZmFjZSBHcm9rTWVkaWFUaW1lb3V0cyB7XG4gIGltYWdlVG90YWxNczogbnVtYmVyO1xuICBpbWFnZVJlYWRNczogbnVtYmVyO1xuICB2aWRlb1N0YXJ0TXM6IG51bWJlcjtcbiAgdmlkZW9Qb2xsTXM6IG51bWJlcjtcbn1cblxuY29uc3QgREVGQVVMVF9USU1FT1VUUzogR3Jva01lZGlhVGltZW91dHMgPSB7XG4gIGltYWdlVG90YWxNczogR1JPS19JTUFHRV9UT1RBTF9USU1FT1VUX01TLFxuICBpbWFnZVJlYWRNczogR1JPS19JTUFHRV9SRUFEX1RJTUVPVVRfTVMsXG4gIHZpZGVvU3RhcnRNczogR1JPS19WSURFT19TVEFSVF9USU1FT1VUX01TLFxuICB2aWRlb1BvbGxNczogR1JPS19WSURFT19QT0xMX1RJTUVPVVRfTVMsXG59O1xuXG4vKiogVXBzdHJlYW0gZmxhZ2dlZCB0aGUgb3V0cHV0IHdpdGggYHJlc3BlY3RfbW9kZXJhdGlvbjogZmFsc2VgLiBOZXZlciByZXRyaWVkLiAqL1xuZXhwb3J0IGNsYXNzIEdyb2tDb250ZW50UG9saWN5RXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbnN0cnVjdG9yKGtpbmQ6IFwiaW1hZ2VcIiB8IFwidmlkZW9cIikge1xuICAgIHN1cGVyKFxuICAgICAgYCR7a2luZCA9PT0gXCJpbWFnZVwiID8gXCJJbWFnZVwiIDogXCJWaWRlb1wifSBnZW5lcmF0aW9uIHdhcyBibG9ja2VkIGR1ZSB0byBhIGNvbnRlbnQgcG9saWN5IHZpb2xhdGlvbi5gLFxuICAgICk7XG4gICAgdGhpcy5uYW1lID0gXCJHcm9rQ29udGVudFBvbGljeUVycm9yXCI7XG4gIH1cbn1cblxuLyoqIEEgdG90YWwgb3IgcmVhZCB0aW1lb3V0IGZpcmVkLiBGb3IgYSBQT1NULCB1cHN0cmVhbSBtYXkgYWxyZWFkeSBiZSBleGVjdXRpbmcgdGhlIGpvYi4gKi9cbmV4cG9ydCBjbGFzcyBHcm9rTWVkaWFUaW1lb3V0RXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIHJlYWRvbmx5IHBoYXNlOiBcInRvdGFsXCIgfCBcInJlYWRcIjtcbiAgcmVhZG9ubHkgdGltZW91dE1zOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IocGhhc2U6IFwidG90YWxcIiB8IFwicmVhZFwiLCB0aW1lb3V0TXM6IG51bWJlcikge1xuICAgIHN1cGVyKFxuICAgICAgYEdyb2sgbWVkaWEgcmVxdWVzdCAke3BoYXNlID09PSBcInRvdGFsXCIgPyBcInRpbWVkIG91dFwiIDogXCJzdGFsbGVkXCJ9IGFmdGVyICR7dGltZW91dE1zfSBtc2AsXG4gICAgKTtcbiAgICB0aGlzLm5hbWUgPSBcIkdyb2tNZWRpYVRpbWVvdXRFcnJvclwiO1xuICAgIHRoaXMucGhhc2UgPSBwaGFzZTtcbiAgICB0aGlzLnRpbWVvdXRNcyA9IHRpbWVvdXRNcztcbiAgfVxufVxuXG4vKiogQSBQT1NUIGZhaWxlZCBhZnRlciBpdCBtYXkgaGF2ZSBiZWVuIHdyaXR0ZW47IHJlcGxheWluZyBpdCBjb3VsZCBydW4gdGhlIGpvYiB0d2ljZS4gKi9cbmV4cG9ydCBjbGFzcyBHcm9rTWVkaWFEZWxpdmVyeUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcsIG9wdGlvbnM/OiBFcnJvck9wdGlvbnMpIHtcbiAgICBzdXBlcihgR3JvayBtZWRpYSByZXF1ZXN0IGZhaWxlZCBhZnRlciBpdCBtYXkgaGF2ZSBiZWVuIHNlbnQ6ICR7bWVzc2FnZX1gLCBvcHRpb25zKTtcbiAgICB0aGlzLm5hbWUgPSBcIkdyb2tNZWRpYURlbGl2ZXJ5RXJyb3JcIjtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdyb2tNZWRpYUNsaWVudE9wdGlvbnMge1xuICBmZXRjaD86IHR5cGVvZiBmZXRjaDtcbiAgYmFzZVVybD86IHN0cmluZztcbiAgdGltZW91dHM/OiBQYXJ0aWFsPEdyb2tNZWRpYVRpbWVvdXRzPjtcbn1cblxuLy8gRXJyb3IgY29kZXMgcmFpc2VkIHdoaWxlIHJlc29sdmluZyBvciBjb25uZWN0aW5nLCBpLmUuIGJlZm9yZSBhbnkgcmVxdWVzdCBieXRlIHdhcyB3cml0dGVuLlxuY29uc3QgUFJFX1NFTkRfRVJST1JfQ09ERVMgPSBuZXcgU2V0KFtcbiAgXCJFQ09OTlJFRlVTRURcIixcbiAgXCJFTk9URk9VTkRcIixcbiAgXCJFQUlfQUdBSU5cIixcbiAgXCJFQUlfRkFJTFwiLFxuICBcIkVIT1NUVU5SRUFDSFwiLFxuICBcIkVIT1NURE9XTlwiLFxuICBcIkVORVRVTlJFQUNIXCIsXG4gIFwiRU5FVERPV05cIixcbiAgXCJVTkRfRVJSX0NPTk5FQ1RfVElNRU9VVFwiLFxuICBcIkVSUl9UTFNfQ0VSVF9BTFROQU1FX0lOVkFMSURcIixcbiAgXCJDRVJUX0hBU19FWFBJUkVEXCIsXG4gIFwiREVQVEhfWkVST19TRUxGX1NJR05FRF9DRVJUXCIsXG4gIFwiU0VMRl9TSUdORURfQ0VSVF9JTl9DSEFJTlwiLFxuICBcIlVOQUJMRV9UT19HRVRfSVNTVUVSX0NFUlRfTE9DQUxMWVwiLFxuICBcIlVOQUJMRV9UT19WRVJJRllfTEVBRl9TSUdOQVRVUkVcIixcbl0pO1xuXG5jb25zdCBFcnJvcldpdGhDb2RlID0gei5sb29zZU9iamVjdCh7IGNvZGU6IHouc3RyaW5nKCkgfSk7XG5jb25zdCBFcnJvcldpdGhDYXVzZSA9IHoubG9vc2VPYmplY3QoeyBjYXVzZTogei51bmtub3duKCkgfSk7XG5cbi8qKiBUaGUgZmlyc3QgYGNvZGVgIGFsb25nIHRoZSBgY2F1c2VgIGNoYWluICh1bmRpY2kgd3JhcHMgc29ja2V0IGVycm9ycyBpbiBgVHlwZUVycm9yYCkuICovXG5mdW5jdGlvbiBlcnJvckNvZGUoY2F1c2U6IHVua25vd24pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBsZXQgY3VycmVudDogdW5rbm93biA9IGNhdXNlO1xuXG4gIGZvciAobGV0IGRlcHRoID0gMDsgZGVwdGggPCA1ICYmIGN1cnJlbnQgIT09IHVuZGVmaW5lZCAmJiBjdXJyZW50ICE9PSBudWxsOyBkZXB0aCsrKSB7XG4gICAgY29uc3Qgd2l0aENvZGUgPSBFcnJvcldpdGhDb2RlLnNhZmVQYXJzZShjdXJyZW50KTtcblxuICAgIGlmICh3aXRoQ29kZS5zdWNjZXNzKSByZXR1cm4gd2l0aENvZGUuZGF0YS5jb2RlO1xuICAgIGNvbnN0IHdpdGhDYXVzZSA9IEVycm9yV2l0aENhdXNlLnNhZmVQYXJzZShjdXJyZW50KTtcbiAgICBjdXJyZW50ID0gd2l0aENhdXNlLnN1Y2Nlc3MgPyB3aXRoQ2F1c2UuZGF0YS5jYXVzZSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGVycm9yTWVzc2FnZShjYXVzZTogdW5rbm93bik6IHN0cmluZyB7XG4gIHJldHVybiBjYXVzZSBpbnN0YW5jZW9mIEVycm9yID8gY2F1c2UubWVzc2FnZSA6IFN0cmluZyhjYXVzZSk7XG59XG5cbmZ1bmN0aW9uIGFib3J0UmVhc29uKHNpZ25hbDogQWJvcnRTaWduYWwpOiBFcnJvciB7XG4gIGNvbnN0IHJlYXNvbjogdW5rbm93biA9IHNpZ25hbC5yZWFzb247XG5cbiAgcmV0dXJuIHJlYXNvbiBpbnN0YW5jZW9mIEVycm9yID8gcmVhc29uIDogbmV3IERPTUV4Y2VwdGlvbihcIkFib3J0ZWRcIiwgXCJBYm9ydEVycm9yXCIpO1xufVxuXG5mdW5jdGlvbiBjb25uZWN0RmFpbHVyZShjYXVzZTogdW5rbm93bik6IEdyb2tIdHRwRXJyb3Ige1xuICBjb25zdCBjb2RlID0gZXJyb3JDb2RlKGNhdXNlKTtcbiAgY29uc3QgbWVzc2FnZSA9IGAke2Vycm9yTWVzc2FnZShjYXVzZSl9JHtjb2RlID8gYCAoJHtjb2RlfSlgIDogXCJcIn1gO1xuXG4gIHJldHVybiBuZXcgR3Jva0h0dHBFcnJvcih7IC4uLmNsYXNzaWZ5R3Jva0h0dHBFcnJvcigwLCBcIlwiLCB7fSksIG1lc3NhZ2UgfSwgXCJcIiwge30sIHsgY2F1c2UgfSk7XG59XG5cbmNvbnN0IEJBU0U2NCA9IC9eW0EtWmEtejAtOSsvXSo9ezAsMn0kLztcblxuZnVuY3Rpb24gc25pZmZJbWFnZU1lZGlhVHlwZShieXRlczogVWludDhBcnJheSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmIChieXRlc1swXSA9PT0gMHhmZiAmJiBieXRlc1sxXSA9PT0gMHhkOCAmJiBieXRlc1syXSA9PT0gMHhmZikgcmV0dXJuIFwiaW1hZ2UvanBlZ1wiO1xuXG4gIGlmIChieXRlc1swXSA9PT0gMHg4OSAmJiBieXRlc1sxXSA9PT0gMHg1MCAmJiBieXRlc1syXSA9PT0gMHg0ZSAmJiBieXRlc1szXSA9PT0gMHg0NylcbiAgICByZXR1cm4gXCJpbWFnZS9wbmdcIjtcblxuICBpZiAoYnl0ZXNbMF0gPT09IDB4NDcgJiYgYnl0ZXNbMV0gPT09IDB4NDkgJiYgYnl0ZXNbMl0gPT09IDB4NDYpIHJldHVybiBcImltYWdlL2dpZlwiO1xuICBjb25zdCBhc2NpaSA9IChmcm9tOiBudW1iZXIsIHRvOiBudW1iZXIpID0+IFN0cmluZy5mcm9tQ2hhckNvZGUoLi4uYnl0ZXMuc3ViYXJyYXkoZnJvbSwgdG8pKTtcblxuICBpZiAoYXNjaWkoMCwgNCkgPT09IFwiUklGRlwiICYmIGFzY2lpKDgsIDEyKSA9PT0gXCJXRUJQXCIpIHJldHVybiBcImltYWdlL3dlYnBcIjtcblxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEdyb2tEZWNvZGVkSW1hZ2Uge1xuICBieXRlczogVWludDhBcnJheTtcbiAgbWVkaWFUeXBlOiBzdHJpbmc7XG4gIHJldmlzZWRQcm9tcHQ/OiBzdHJpbmc7XG4gIHJlc3BlY3RNb2RlcmF0aW9uPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHcm9rRGVjb2RlZEltYWdlcyB7XG4gIGltYWdlczogR3Jva0RlY29kZWRJbWFnZVtdO1xuICBjb3N0SW5Vc2RUaWNrcz86IG51bWJlcjtcbn1cblxuZnVuY3Rpb24gYXNzZXJ0SW1hZ2VzQWxsb3dlZChyZXNwb25zZTogR3Jva0ltYWdlUmVzcG9uc2UpOiB2b2lkIHtcbiAgaWYgKHJlc3BvbnNlLmRhdGEuc29tZSgoaW1hZ2UpID0+IGltYWdlLnJlc3BlY3RfbW9kZXJhdGlvbiA9PT0gZmFsc2UpKVxuICAgIHRocm93IG5ldyBHcm9rQ29udGVudFBvbGljeUVycm9yKFwiaW1hZ2VcIik7XG5cbiAgZm9yIChjb25zdCBpbWFnZSBvZiByZXNwb25zZS5kYXRhKSB7XG4gICAgaWYgKGltYWdlLmI2NF9qc29uLmxlbmd0aCAlIDQgIT09IDAgfHwgIUJBU0U2NC50ZXN0KGltYWdlLmI2NF9qc29uKSlcbiAgICAgIHRocm93IG5ldyBHcm9rUHJvdG9jb2xFcnJvcihcIkdyb2sgaW1hZ2UgcmVzcG9uc2UgY2FycmllZCBpbnZhbGlkIGJhc2U2NCBkYXRhXCIpO1xuICB9XG59XG5cbi8qKiBEZWNvZGVzIGEgdmFsaWRhdGVkIGltYWdlIHJlc3BvbnNlLiBgbWltZV90eXBlYCB3aW5zOyBvdGhlcndpc2UgdGhlIGJ5dGVzIGFyZSBzbmlmZmVkLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRlY29kZUdyb2tJbWFnZXMocmVzcG9uc2U6IEdyb2tJbWFnZVJlc3BvbnNlKTogR3Jva0RlY29kZWRJbWFnZXMge1xuICBhc3NlcnRJbWFnZXNBbGxvd2VkKHJlc3BvbnNlKTtcblxuICBjb25zdCBpbWFnZXMgPSByZXNwb25zZS5kYXRhLm1hcCgoaW1hZ2UpOiBHcm9rRGVjb2RlZEltYWdlID0+IHtcbiAgICBjb25zdCBieXRlcyA9IG5ldyBVaW50OEFycmF5KEJ1ZmZlci5mcm9tKGltYWdlLmI2NF9qc29uLCBcImJhc2U2NFwiKSk7XG5cbiAgICBjb25zdCBtZWRpYVR5cGUgPSBpbWFnZS5taW1lX3R5cGU/LnN0YXJ0c1dpdGgoXCJpbWFnZS9cIilcbiAgICAgID8gaW1hZ2UubWltZV90eXBlXG4gICAgICA6IChzbmlmZkltYWdlTWVkaWFUeXBlKGJ5dGVzKSA/PyBcImltYWdlL2pwZWdcIik7XG5cbiAgICBjb25zdCBkZWNvZGVkOiBHcm9rRGVjb2RlZEltYWdlID0geyBieXRlcywgbWVkaWFUeXBlIH07XG5cbiAgICBpZiAoaW1hZ2UucmV2aXNlZF9wcm9tcHQpIGRlY29kZWQucmV2aXNlZFByb21wdCA9IGltYWdlLnJldmlzZWRfcHJvbXB0O1xuXG4gICAgaWYgKGltYWdlLnJlc3BlY3RfbW9kZXJhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBkZWNvZGVkLnJlc3BlY3RNb2RlcmF0aW9uID0gaW1hZ2UucmVzcGVjdF9tb2RlcmF0aW9uO1xuICAgIH1cblxuICAgIHJldHVybiBkZWNvZGVkO1xuICB9KTtcblxuICBjb25zdCB0aWNrcyA9IHJlc3BvbnNlLnVzYWdlPy5jb3N0X2luX3VzZF90aWNrcztcbiAgY29uc3QgcmVzdWx0OiBHcm9rRGVjb2RlZEltYWdlcyA9IHsgaW1hZ2VzIH07XG5cbiAgaWYgKHRpY2tzICE9PSB1bmRlZmluZWQpIHJlc3VsdC5jb3N0SW5Vc2RUaWNrcyA9IHRpY2tzO1xuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8vIEZpZWxkcyBAYWktc2RrL3hhaSByZWFkcyB0aGF0IGdyb2stdHlwZXMnIEdyb2tWaWRlb1N0YXR1cyBsZWF2ZXMgbG9vc2Vcbi8vICh4YWktdmlkZW8tbW9kZWwudHM6NzgyLTgxMik6IGByZXNwZWN0X21vZGVyYXRpb25gIG5lc3RzIHVuZGVyIGB2aWRlb2AuXG5jb25zdCBWaWRlb1N0YXR1c0V4dHJhcyA9IHoubG9vc2VPYmplY3Qoe1xuICB2aWRlbzogei5sb29zZU9iamVjdCh7IHJlc3BlY3RfbW9kZXJhdGlvbjogei5ib29sZWFuKCkubnVsbGlzaCgpIH0pLm51bGxpc2goKSxcbiAgZXJyb3I6IHoubG9vc2VPYmplY3QoeyBjb2RlOiB6LnN0cmluZygpLm51bGxpc2goKSwgbWVzc2FnZTogei5zdHJpbmcoKS5udWxsaXNoKCkgfSkubnVsbGlzaCgpLFxufSk7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR3Jva1ZpZGVvU3VtbWFyeSB7XG4gIHN0YXR1czogXCJwZW5kaW5nXCIgfCBcImRvbmVcIiB8IFwiZmFpbGVkXCI7XG4gIHVybD86IHN0cmluZztcbiAgbWltZVR5cGU6IFwidmlkZW8vbXA0XCI7XG4gIHVzYWdlVGlja3M/OiBudW1iZXI7XG4gIGVycm9yPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIENvbGxhcHNlcyBhIHBvbGwgcmVzcG9uc2UgdG8gdGhlIFNESydzIHRocmVlIG91dGNvbWVzLiBUaGUgVVJMIGlzIHJldHVybmVkIHVuY2hhbmdlZCAoRDQpO1xuICogYGV4cGlyZWRgIGFuZCBhIGBkb25lYCB3aXRob3V0IGEgVVJMIGFyZSBmYWlsdXJlcyAoeGFpLXZpZGVvLW1vZGVsLnRzOjY0My03MDUpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3VtbWFyaXplR3Jva1ZpZGVvU3RhdHVzKHN0YXR1czogR3Jva1ZpZGVvU3RhdHVzKTogR3Jva1ZpZGVvU3VtbWFyeSB7XG4gIGNvbnN0IGV4dHJhcyA9IFZpZGVvU3RhdHVzRXh0cmFzLnBhcnNlKHN0YXR1cyk7XG5cbiAgaWYgKGV4dHJhcy52aWRlbz8ucmVzcGVjdF9tb2RlcmF0aW9uID09PSBmYWxzZSkgdGhyb3cgbmV3IEdyb2tDb250ZW50UG9saWN5RXJyb3IoXCJ2aWRlb1wiKTtcbiAgY29uc3QgdGlja3MgPSBzdGF0dXMudXNhZ2U/LmNvc3RfaW5fdXNkX3RpY2tzO1xuXG4gIGNvbnN0IGJhc2U6IE9taXQ8R3Jva1ZpZGVvU3VtbWFyeSwgXCJzdGF0dXNcIj4gPSB7IG1pbWVUeXBlOiBcInZpZGVvL21wNFwiIH07XG5cbiAgaWYgKHRpY2tzICE9PSB1bmRlZmluZWQpIGJhc2UudXNhZ2VUaWNrcyA9IHRpY2tzO1xuXG4gIGlmIChzdGF0dXMuc3RhdHVzID09PSBcImV4cGlyZWRcIilcbiAgICByZXR1cm4geyAuLi5iYXNlLCBzdGF0dXM6IFwiZmFpbGVkXCIsIGVycm9yOiBcIlZpZGVvIGdlbmVyYXRpb24gcmVxdWVzdCBleHBpcmVkLlwiIH07XG5cbiAgaWYgKHN0YXR1cy5zdGF0dXMgPT09IFwiZmFpbGVkXCIpIHtcbiAgICBjb25zdCBlcnJvciA9IGV4dHJhcy5lcnJvcj8ubWVzc2FnZSA/PyBleHRyYXMuZXJyb3I/LmNvZGUgPz8gXCJWaWRlbyBnZW5lcmF0aW9uIGZhaWxlZC5cIjtcblxuICAgIHJldHVybiB7IC4uLmJhc2UsIHN0YXR1czogXCJmYWlsZWRcIiwgZXJyb3IgfTtcbiAgfVxuXG4gIGlmIChzdGF0dXMuc3RhdHVzID09PSBcImRvbmVcIikge1xuICAgIGNvbnN0IHVybCA9IGdyb2tWaWRlb1VybChzdGF0dXMpO1xuXG4gICAgaWYgKCF1cmwpXG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5iYXNlLFxuICAgICAgICBzdGF0dXM6IFwiZmFpbGVkXCIsXG4gICAgICAgIGVycm9yOiBcIlZpZGVvIGdlbmVyYXRpb24gY29tcGxldGVkIGJ1dCBubyB2aWRlbyBVUkwgd2FzIHJldHVybmVkLlwiLFxuICAgICAgfTtcblxuICAgIHJldHVybiB7IC4uLmJhc2UsIHN0YXR1czogXCJkb25lXCIsIHVybCB9O1xuICB9XG5cbiAgcmV0dXJuIHsgLi4uYmFzZSwgc3RhdHVzOiBcInBlbmRpbmdcIiB9O1xufVxuXG5pbnRlcmZhY2UgTWVkaWFDYWxsIHtcbiAgbWV0aG9kOiBcIkdFVFwiIHwgXCJQT1NUXCI7XG4gIHBhdGg6IHN0cmluZztcbiAgYXV0aDogR3Jva01lZGlhQXV0aDtcbiAgYm9keT86IEdyb2tJbWFnZUJvZHkgfCBHcm9rVmlkZW9Cb2R5O1xuICB0b3RhbE1zOiBudW1iZXI7XG4gIHJlYWRNczogbnVtYmVyO1xuICBtYXhCeXRlczogbnVtYmVyO1xuICBzaWduYWw6IEFib3J0U2lnbmFsIHwgdW5kZWZpbmVkO1xufVxuXG5pbnRlcmZhY2UgTWVkaWFSZXBseSB7XG4gIHJlc3BvbnNlOiBSZXNwb25zZTtcbiAgdGV4dDogc3RyaW5nO1xufVxuXG5jbGFzcyBCb2R5TGltaXRFcnJvciBleHRlbmRzIEVycm9yIHt9XG5cbmV4cG9ydCBjbGFzcyBHcm9rTWVkaWFDbGllbnQgaW1wbGVtZW50cyBHcm9rTWVkaWFQb3J0IHtcbiAgcmVhZG9ubHkgZmV0Y2hJbXBsOiB0eXBlb2YgZmV0Y2g7XG4gIHJlYWRvbmx5IGJhc2VVcmw6IHN0cmluZztcbiAgcmVhZG9ubHkgdGltZW91dHM6IEdyb2tNZWRpYVRpbWVvdXRzO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IEdyb2tNZWRpYUNsaWVudE9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMuZmV0Y2hJbXBsID0gb3B0aW9ucy5mZXRjaCA/PyBmZXRjaDtcbiAgICB0aGlzLmJhc2VVcmwgPSAob3B0aW9ucy5iYXNlVXJsID8/IEdST0tfUFVCTElDX0FQSV9VUkwpLnJlcGxhY2UoL1xcLyskLywgXCJcIik7XG4gICAgdGhpcy50aW1lb3V0cyA9IHsgLi4uREVGQVVMVF9USU1FT1VUUywgLi4ub3B0aW9ucy50aW1lb3V0cyB9O1xuICB9XG5cbiAgYXN5bmMgZ2VuZXJhdGVJbWFnZXMoXG4gICAgYXV0aDogR3Jva01lZGlhQXV0aCxcbiAgICByZXF1ZXN0OiBHcm9rSW1hZ2VHZW5lcmF0ZVJlcXVlc3QsXG4gICk6IFByb21pc2U8R3Jva0ltYWdlUmVzcG9uc2U+IHtcbiAgICBjb25zdCBib2R5ID0gaW1hZ2VCb2R5KHJlcXVlc3QsIHJlcXVlc3QubW9kZWwudHJpbSgpIHx8IEdST0tfSU1BR0VfREVGQVVMVF9NT0RFTCk7XG5cbiAgICByZXR1cm4gdGhpcy5wb3N0SW1hZ2VzKFwiL2ltYWdlcy9nZW5lcmF0aW9uc1wiLCBhdXRoLCBib2R5LCByZXF1ZXN0LnNpZ25hbCk7XG4gIH1cblxuICBhc3luYyBlZGl0SW1hZ2VzKGF1dGg6IEdyb2tNZWRpYUF1dGgsIHJlcXVlc3Q6IEdyb2tJbWFnZUVkaXRSZXF1ZXN0KTogUHJvbWlzZTxHcm9rSW1hZ2VSZXNwb25zZT4ge1xuICAgIGlmIChyZXF1ZXN0LmltYWdlcy5sZW5ndGggPT09IDApXG4gICAgICB0aHJvdyBuZXcgR3Jva0ludmFsaWRSZXF1ZXN0RXJyb3IoXCJHcm9rIGltYWdlIGVkaXQgbmVlZHMgYXQgbGVhc3Qgb25lIHJlZmVyZW5jZSBpbWFnZVwiKTtcblxuICAgIGNvbnN0IHVybHMgPSByZXF1ZXN0LmltYWdlcy5tYXAoKHVybCkgPT4ge1xuICAgICAgaWYgKCF1cmwudHJpbSgpKVxuICAgICAgICB0aHJvdyBuZXcgR3Jva0ludmFsaWRSZXF1ZXN0RXJyb3IoXCJHcm9rIGltYWdlIGVkaXQgcmVmZXJlbmNlIG11c3QgYmUgYSBub24tZW1wdHkgVVJMXCIpO1xuXG4gICAgICByZXR1cm4geyB1cmwgfTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGJvZHkgPSBpbWFnZUJvZHkocmVxdWVzdCwgcmVxdWVzdC5tb2RlbC50cmltKCkgfHwgR1JPS19JTUFHRV9FRElUX0RFRkFVTFRfTU9ERUwpO1xuXG4gICAgLy8gaW1hZ2VfZWRpdC9tb2QucnM6MzcxLTM5Njogb25lIHJlZmVyZW5jZSBpcyBgaW1hZ2U6IHt1cmx9YCwgc2V2ZXJhbCBhcmUgYGltYWdlczogW3t1cmx9XWAuXG4gICAgaWYgKHVybHMubGVuZ3RoID09PSAxKSBib2R5LmltYWdlID0gdXJsc1swXTtcbiAgICBlbHNlIGJvZHkuaW1hZ2VzID0gdXJscztcblxuICAgIHJldHVybiB0aGlzLnBvc3RJbWFnZXMoXCIvaW1hZ2VzL2VkaXRzXCIsIGF1dGgsIGJvZHksIHJlcXVlc3Quc2lnbmFsKTtcbiAgfVxuXG4gIGFzeW5jIHN0YXJ0VmlkZW8oYXV0aDogR3Jva01lZGlhQXV0aCwgcmVxdWVzdDogR3Jva1ZpZGVvU3RhcnRSZXF1ZXN0KTogUHJvbWlzZTxHcm9rVmlkZW9TdGFydD4ge1xuICAgIGNvbnN0IGJvZHkgPSB2aWRlb0JvZHkocmVxdWVzdCk7XG5cbiAgICBjb25zdCB7IHRleHQgfSA9IGF3YWl0IHRoaXMuY2FsbCh7XG4gICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgcGF0aDogXCIvdmlkZW9zL2dlbmVyYXRpb25zXCIsXG4gICAgICBhdXRoLFxuICAgICAgYm9keSxcbiAgICAgIHRvdGFsTXM6IHRoaXMudGltZW91dHMudmlkZW9TdGFydE1zLFxuICAgICAgcmVhZE1zOiB0aGlzLnRpbWVvdXRzLnZpZGVvU3RhcnRNcyxcbiAgICAgIG1heEJ5dGVzOiBNQVhfSlNPTl9SRVNQT05TRV9CWVRFUyxcbiAgICAgIHNpZ25hbDogcmVxdWVzdC5zaWduYWwsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gcGFyc2VKc29uKEdyb2tWaWRlb1N0YXJ0LCB0ZXh0LCBcInZpZGVvIHN0YXJ0XCIpO1xuICB9XG5cbiAgYXN5bmMgZ2V0VmlkZW8oXG4gICAgYXV0aDogR3Jva01lZGlhQXV0aCxcbiAgICByZXF1ZXN0SWQ6IHN0cmluZyxcbiAgICBzaWduYWw/OiBBYm9ydFNpZ25hbCxcbiAgKTogUHJvbWlzZTxHcm9rVmlkZW9TdGF0dXM+IHtcbiAgICBpZiAoIXJlcXVlc3RJZC50cmltKCkpIHRocm93IG5ldyBUeXBlRXJyb3IoXCJHcm9rIHZpZGVvIHJlcXVlc3QgaWQgbXVzdCBiZSBub24tZW1wdHlcIik7XG5cbiAgICBjb25zdCB7IHJlc3BvbnNlLCB0ZXh0IH0gPSBhd2FpdCB0aGlzLmNhbGwoe1xuICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgcGF0aDogYC92aWRlb3MvJHtlbmNvZGVVUklDb21wb25lbnQocmVxdWVzdElkKX1gLFxuICAgICAgYXV0aCxcbiAgICAgIHRvdGFsTXM6IHRoaXMudGltZW91dHMudmlkZW9Qb2xsTXMsXG4gICAgICByZWFkTXM6IHRoaXMudGltZW91dHMudmlkZW9Qb2xsTXMsXG4gICAgICBtYXhCeXRlczogTUFYX0pTT05fUkVTUE9OU0VfQllURVMsXG4gICAgICBzaWduYWwsXG4gICAgfSk7XG5cbiAgICBjb25zdCBzdGF0dXMgPSBwYXJzZVZpZGVvU3RhdHVzKHJlc3BvbnNlLnN0YXR1cywgdGV4dCk7XG5cbiAgICBpZiAoVmlkZW9TdGF0dXNFeHRyYXMucGFyc2Uoc3RhdHVzKS52aWRlbz8ucmVzcGVjdF9tb2RlcmF0aW9uID09PSBmYWxzZSlcbiAgICAgIHRocm93IG5ldyBHcm9rQ29udGVudFBvbGljeUVycm9yKFwidmlkZW9cIik7XG5cbiAgICByZXR1cm4gc3RhdHVzO1xuICB9XG5cbiAgYXN5bmMgcG9zdEltYWdlcyhcbiAgICBwYXRoOiBzdHJpbmcsXG4gICAgYXV0aDogR3Jva01lZGlhQXV0aCxcbiAgICBib2R5OiBHcm9rSW1hZ2VCb2R5LFxuICAgIHNpZ25hbDogQWJvcnRTaWduYWwgfCB1bmRlZmluZWQsXG4gICk6IFByb21pc2U8R3Jva0ltYWdlUmVzcG9uc2U+IHtcbiAgICBjb25zdCB7IHRleHQgfSA9IGF3YWl0IHRoaXMuY2FsbCh7XG4gICAgICBtZXRob2Q6IFwiUE9TVFwiLFxuICAgICAgcGF0aCxcbiAgICAgIGF1dGgsXG4gICAgICBib2R5LFxuICAgICAgdG90YWxNczogdGhpcy50aW1lb3V0cy5pbWFnZVRvdGFsTXMsXG4gICAgICByZWFkTXM6IHRoaXMudGltZW91dHMuaW1hZ2VSZWFkTXMsXG4gICAgICBtYXhCeXRlczogTUFYX0lNQUdFX1JFU1BPTlNFX0JZVEVTLFxuICAgICAgc2lnbmFsLFxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBwYXJzZUpzb24oR3Jva0ltYWdlUmVzcG9uc2UsIHRleHQsIFwiaW1hZ2VcIik7XG4gICAgYXNzZXJ0SW1hZ2VzQWxsb3dlZChyZXNwb25zZSk7XG5cbiAgICByZXR1cm4gcmVzcG9uc2U7XG4gIH1cblxuICAvKiogT25lIEhUVFAgZXhjaGFuZ2Ugd2l0aCB0b3RhbCBhbmQgcmVhZCB0aW1lb3V0cyBjb21wb3NlZCB3aXRoIHRoZSBjYWxsZXIncyBzaWduYWwuICovXG4gIGFzeW5jIGNhbGwoY2FsbDogTWVkaWFDYWxsKTogUHJvbWlzZTxNZWRpYVJlcGx5PiB7XG4gICAgY29uc3QgeyBzaWduYWwgfSA9IGNhbGw7XG5cbiAgICBpZiAoc2lnbmFsPy5hYm9ydGVkKSB0aHJvdyBhYm9ydFJlYXNvbihzaWduYWwpO1xuXG4gICAgY29uc3QgaGVhZGVycyA9IHtcbiAgICAgIFwiY29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiLFxuICAgICAgLi4uYnVpbGRHcm9rTWVkaWFIZWFkZXJzKHsgYmVhcmVyOiBjYWxsLmF1dGguYmVhcmVyLCBzZXNzaW9uSWQ6IGNhbGwuYXV0aC5zZXNzaW9uSWQgfSksXG4gICAgfTtcblxuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgbGV0IHRpbWVvdXQ6IEdyb2tNZWRpYVRpbWVvdXRFcnJvciB8IHVuZGVmaW5lZDtcblxuICAgIGNvbnN0IGZpcmUgPSAoZXJyb3I6IEdyb2tNZWRpYVRpbWVvdXRFcnJvcikgPT4ge1xuICAgICAgaWYgKHRpbWVvdXQgfHwgY29udHJvbGxlci5zaWduYWwuYWJvcnRlZCkgcmV0dXJuO1xuICAgICAgdGltZW91dCA9IGVycm9yO1xuICAgICAgY29udHJvbGxlci5hYm9ydChlcnJvcik7XG4gICAgfTtcblxuICAgIGNvbnN0IHRvdGFsVGltZXIgPSBzZXRUaW1lb3V0KFxuICAgICAgKCkgPT4gZmlyZShuZXcgR3Jva01lZGlhVGltZW91dEVycm9yKFwidG90YWxcIiwgY2FsbC50b3RhbE1zKSksXG4gICAgICBjYWxsLnRvdGFsTXMsXG4gICAgKTtcblxuICAgIGxldCByZWFkVGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgdW5kZWZpbmVkO1xuXG4gICAgY29uc3QgYXJtUmVhZCA9ICgpID0+IHtcbiAgICAgIGNsZWFyVGltZW91dChyZWFkVGltZXIpO1xuICAgICAgcmVhZFRpbWVyID0gc2V0VGltZW91dChcbiAgICAgICAgKCkgPT4gZmlyZShuZXcgR3Jva01lZGlhVGltZW91dEVycm9yKFwicmVhZFwiLCBjYWxsLnJlYWRNcykpLFxuICAgICAgICBjYWxsLnJlYWRNcyxcbiAgICAgICk7XG4gICAgfTtcblxuICAgIGNvbnN0IG9uQWJvcnQgPSAoKSA9PiBjb250cm9sbGVyLmFib3J0KHNpZ25hbD8ucmVhc29uKTtcbiAgICBzaWduYWw/LmFkZEV2ZW50TGlzdGVuZXIoXCJhYm9ydFwiLCBvbkFib3J0LCB7IG9uY2U6IHRydWUgfSk7XG5cbiAgICAvLyBDYWxsZWQgZm9yIGV2ZXJ5IGZhaWx1cmU6IGEgY2FsbGVyIGFib3J0IG9yIGEgdGltZW91dCB3aW5zIG92ZXIgdGhlIHRyYW5zcG9ydCBlcnJvci5cbiAgICBjb25zdCBzZXR0bGUgPSAoY2F1c2U6IHVua25vd24sIHJlc3BvbmRlZDogYm9vbGVhbik6IEVycm9yID0+IHtcbiAgICAgIGlmIChzaWduYWw/LmFib3J0ZWQpIHJldHVybiBhYm9ydFJlYXNvbihzaWduYWwpO1xuXG4gICAgICBpZiAodGltZW91dCkgcmV0dXJuIHRpbWVvdXQ7XG5cbiAgICAgIGlmIChjYXVzZSBpbnN0YW5jZW9mIEdyb2tQcm90b2NvbEVycm9yIHx8IGNhdXNlIGluc3RhbmNlb2YgR3Jva0h0dHBFcnJvcikgcmV0dXJuIGNhdXNlO1xuXG4gICAgICBpZiAoY2FsbC5tZXRob2QgPT09IFwiR0VUXCIpIHJldHVybiBjb25uZWN0RmFpbHVyZShjYXVzZSk7XG5cbiAgICAgIGlmICghcmVzcG9uZGVkICYmIFBSRV9TRU5EX0VSUk9SX0NPREVTLmhhcyhlcnJvckNvZGUoY2F1c2UpID8/IFwiXCIpKVxuICAgICAgICByZXR1cm4gY29ubmVjdEZhaWx1cmUoY2F1c2UpO1xuXG4gICAgICByZXR1cm4gbmV3IEdyb2tNZWRpYURlbGl2ZXJ5RXJyb3IoZXJyb3JNZXNzYWdlKGNhdXNlKSwgeyBjYXVzZSB9KTtcbiAgICB9O1xuXG4gICAgdHJ5IHtcbiAgICAgIGFybVJlYWQoKTtcbiAgICAgIGxldCByZXNwb25zZTogUmVzcG9uc2U7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy5mZXRjaEltcGwoYCR7dGhpcy5iYXNlVXJsfSR7Y2FsbC5wYXRofWAsIHtcbiAgICAgICAgICBtZXRob2Q6IGNhbGwubWV0aG9kLFxuICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgYm9keTogY2FsbC5ib2R5ID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBKU09OLnN0cmluZ2lmeShjYWxsLmJvZHkpLFxuICAgICAgICAgIHNpZ25hbDogY29udHJvbGxlci5zaWduYWwsXG4gICAgICAgIH0pO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdGhyb3cgc2V0dGxlKGVycm9yLCBmYWxzZSk7XG4gICAgICB9XG5cbiAgICAgIGFybVJlYWQoKTtcblxuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgICAgICAgIGNvbnN0IGJvZHlUZXh0ID0gYXdhaXQgcmVhZEJvZHkocmVzcG9uc2UsIE1BWF9FUlJPUl9CT0RZX0JZVEVTLCBhcm1SZWFkLCB0cnVlKTtcbiAgICAgICAgICB0aHJvdyBuZXcgR3Jva0h0dHBFcnJvcihcbiAgICAgICAgICAgIGNsYXNzaWZ5R3Jva0h0dHBFcnJvcihyZXNwb25zZS5zdGF0dXMsIGJvZHlUZXh0LCByZXNwb25zZS5oZWFkZXJzKSxcbiAgICAgICAgICAgIGJvZHlUZXh0LFxuICAgICAgICAgICAgcmVhZEdyb2tSZXNwb25zZUhlYWRlcnMocmVzcG9uc2UuaGVhZGVycyksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZWFkQm9keShyZXNwb25zZSwgY2FsbC5tYXhCeXRlcywgYXJtUmVhZCwgZmFsc2UpO1xuXG4gICAgICAgIHJldHVybiB7IHJlc3BvbnNlLCB0ZXh0IH07XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBCb2R5TGltaXRFcnJvcikgdGhyb3cgbmV3IEdyb2tQcm90b2NvbEVycm9yKGVycm9yLm1lc3NhZ2UpO1xuICAgICAgICB0aHJvdyBzZXR0bGUoZXJyb3IsIHRydWUpO1xuICAgICAgfVxuICAgIH0gZmluYWxseSB7XG4gICAgICBjbGVhclRpbWVvdXQodG90YWxUaW1lcik7XG4gICAgICBjbGVhclRpbWVvdXQocmVhZFRpbWVyKTtcbiAgICAgIHNpZ25hbD8ucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImFib3J0XCIsIG9uQWJvcnQpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEltYWdlIHJlcXVlc3QgYm9keS4gT3B0aW9uYWwgbWVtYmVycyBhcmUgbGVmdCBgdW5kZWZpbmVkYCwgd2hpY2ggSlNPTi5zdHJpbmdpZnkgb21pdHMsIHNvIHRoZVxuICogc2VyaWFsaXplZCBrZXkgb3JkZXIgc3RheXMgdGhhdCBvZiB0aGUgdmVyaWZpZWQgcmVxdWVzdC5cbiAqL1xuaW50ZXJmYWNlIEdyb2tJbWFnZUJvZHkge1xuICBtb2RlbDogc3RyaW5nO1xuICBwcm9tcHQ6IHN0cmluZztcbiAgbjogbnVtYmVyO1xuICBhc3BlY3RfcmF0aW8/OiBHcm9rSW1hZ2VHZW5lcmF0ZVJlcXVlc3RbXCJhc3BlY3RSYXRpb1wiXTtcbiAgcmVzb2x1dGlvbjogTm9uTnVsbGFibGU8R3Jva0ltYWdlR2VuZXJhdGVSZXF1ZXN0W1wicmVzb2x1dGlvblwiXT47XG4gIHJlc3BvbnNlX2Zvcm1hdDogXCJiNjRfanNvblwiO1xuICBxdWFsaXR5PzogR3Jva0ltYWdlR2VuZXJhdGVSZXF1ZXN0W1wicXVhbGl0eVwiXTtcbiAgb3V0cHV0X2Zvcm1hdD86IEdyb2tJbWFnZUdlbmVyYXRlUmVxdWVzdFtcIm91dHB1dEZvcm1hdFwiXTtcbiAgaW1hZ2U/OiB7IHVybDogc3RyaW5nIH07XG4gIGltYWdlcz86IEFycmF5PHsgdXJsOiBzdHJpbmcgfT47XG59XG5cbi8qKiBWaWRlbyByZXF1ZXN0IGJvZHk7IGB1bmRlZmluZWRgIG1lbWJlcnMgYXJlIG9taXR0ZWQgZnJvbSB0aGUgc2VyaWFsaXplZCBKU09OLiAqL1xuaW50ZXJmYWNlIEdyb2tWaWRlb0JvZHkge1xuICBtb2RlbDogc3RyaW5nO1xuICBwcm9tcHQ6IHN0cmluZztcbiAgaW1hZ2U/OiB7IHVybDogc3RyaW5nIH07XG4gIGR1cmF0aW9uPzogbnVtYmVyO1xuICBhc3BlY3RfcmF0aW8/OiBHcm9rVmlkZW9TdGFydFJlcXVlc3RbXCJhc3BlY3RSYXRpb1wiXTtcbiAgcmVzb2x1dGlvbj86IEdyb2tWaWRlb1N0YXJ0UmVxdWVzdFtcInJlc29sdXRpb25cIl07XG4gIHJlZmVyZW5jZV9pbWFnZXM/OiBBcnJheTx7IHVybDogc3RyaW5nIH0+O1xuICBsYXN0X2ZyYW1lPzogeyB1cmw6IHN0cmluZyB9O1xufVxuXG5mdW5jdGlvbiBpbWFnZUJvZHkocmVxdWVzdDogR3Jva0ltYWdlR2VuZXJhdGVSZXF1ZXN0LCBtb2RlbDogc3RyaW5nKTogR3Jva0ltYWdlQm9keSB7XG4gIGNvbnN0IG4gPSByZXF1ZXN0Lm4gPz8gMTtcblxuICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKG4pIHx8IG4gPCAxIHx8IG4gPiBHUk9LX0lNQUdFX01BWF9QRVJfQ0FMTClcbiAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcihcbiAgICAgIGBHcm9rIGltYWdlIGNvdW50IG11c3QgYmUgYW4gaW50ZWdlciBmcm9tIDEgdG8gJHtHUk9LX0lNQUdFX01BWF9QRVJfQ0FMTH1gLFxuICAgICk7XG5cbiAgLy8gS2V5IG9yZGVyIG9mIHRoZSBVMC12ZXJpZmllZCByZXF1ZXN0IChpbWFnZV9nZW4vbW9kLnJzOjIzMS0yMzgpOyBTREsgb3B0aW9ucyBmb2xsb3cuXG4gIGNvbnN0IGJvZHk6IEdyb2tJbWFnZUJvZHkgPSB7XG4gICAgbW9kZWwsXG4gICAgcHJvbXB0OiByZXF1ZXN0LnByb21wdCxcbiAgICBuLFxuICAgIGFzcGVjdF9yYXRpbzogcmVxdWVzdC5hc3BlY3RSYXRpbyxcbiAgICByZXNvbHV0aW9uOiByZXF1ZXN0LnJlc29sdXRpb24gPz8gR1JPS19JTUFHRV9ERUZBVUxUX1JFU09MVVRJT04sXG4gICAgcmVzcG9uc2VfZm9ybWF0OiBcImI2NF9qc29uXCIsXG4gICAgcXVhbGl0eTogcmVxdWVzdC5xdWFsaXR5LFxuICAgIG91dHB1dF9mb3JtYXQ6IHJlcXVlc3Qub3V0cHV0Rm9ybWF0LFxuICB9O1xuXG4gIHJldHVybiBib2R5O1xufVxuXG5mdW5jdGlvbiB2aWRlb0JvZHkocmVxdWVzdDogR3Jva1ZpZGVvU3RhcnRSZXF1ZXN0KTogR3Jva1ZpZGVvQm9keSB7XG4gIC8vIGBlZGl0LXZpZGVvYCAvIGBleHRlbmQtdmlkZW9gIGFyZSBub3QgaW4gdGhlIHBvcnQgdHlwZTogdGhleSBwb3N0IHRvIC92aWRlb3MvZWRpdHMgYW5kXG4gIC8vIC92aWRlb3MvZXh0ZW5zaW9ucyB3aXRoIGEgc291cmNlIGB2aWRlbzoge3VybH1gICh4YWktdmlkZW8tbW9kZWwudHM6NTg2LTU5MywgMzkxLTM5NiksIGFuZCB0aGVcbiAgLy8gcG9ydCByZXF1ZXN0IGNhcnJpZXMgbm8gdmlkZW8gVVJMLlxuICBjb25zdCByZWZlcmVuY2VzID0gcmVxdWVzdC5yZWZlcmVuY2VJbWFnZXMgPz8gW107XG5cbiAgaWYgKHJlcXVlc3QubW9kZSA9PT0gXCJyZWZlcmVuY2UtdG8tdmlkZW9cIiAmJiByZWZlcmVuY2VzLmxlbmd0aCA9PT0gMClcbiAgICB0aHJvdyBuZXcgR3Jva0ludmFsaWRSZXF1ZXN0RXJyb3IoXCJHcm9rIHJlZmVyZW5jZS10by12aWRlbyBuZWVkcyBhdCBsZWFzdCBvbmUgcmVmZXJlbmNlIGltYWdlXCIpO1xuICBjb25zdCB7IGR1cmF0aW9uIH0gPSByZXF1ZXN0O1xuXG4gIGlmIChcbiAgICBkdXJhdGlvbiAhPT0gdW5kZWZpbmVkICYmXG4gICAgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihkdXJhdGlvbikgfHwgZHVyYXRpb24gPCAxIHx8IGR1cmF0aW9uID4gR1JPS19WSURFT19NQVhfRFVSQVRJT05fU0VDKVxuICApXG4gICAgdGhyb3cgbmV3IEdyb2tJbnZhbGlkUmVxdWVzdEVycm9yKFxuICAgICAgYEdyb2sgdmlkZW8gZHVyYXRpb24gbXVzdCBiZSBhbiBpbnRlZ2VyIGZyb20gMSB0byAke0dST0tfVklERU9fTUFYX0RVUkFUSU9OX1NFQ31gLFxuICAgICk7XG5cbiAgLy8gRmllbGQgb3JkZXIgb2YgZ3Jvay1idWlsZCBHZW5lcmF0ZVZpZGVvUGF5bG9hZCAodmlkZW9fZ2VuL21vZC5yczo4MTEtODI3KS4gYG1vZGVgIHNlbGVjdHMgdGhlXG4gIC8vIGVuZHBvaW50IGluIEBhaS1zZGsveGFpIGFuZCBpcyBuZXZlciBhIGJvZHkgZmllbGQ7IHJlZmVyZW5jZS10by12aWRlbyBpcyBpbmZlcnJlZCB1cHN0cmVhbVxuICAvLyBmcm9tIGByZWZlcmVuY2VfaW1hZ2VzYCAoeGFpLXZpZGVvLW1vZGVsLnRzOjE2OS0xOTQpLlxuICBjb25zdCBib2R5OiBHcm9rVmlkZW9Cb2R5ID0ge1xuICAgIG1vZGVsOiByZXF1ZXN0Lm1vZGVsLnRyaW0oKSB8fCBHUk9LX1ZJREVPX0RFRkFVTFRfTU9ERUwsXG4gICAgcHJvbXB0OiByZXF1ZXN0LnByb21wdCxcbiAgICBpbWFnZTogcmVxdWVzdC5pbWFnZSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogeyB1cmw6IHJlcXVlc3QuaW1hZ2UgfSxcbiAgICBkdXJhdGlvbixcbiAgICBhc3BlY3RfcmF0aW86IHJlcXVlc3QuYXNwZWN0UmF0aW8sXG4gICAgcmVzb2x1dGlvbjogcmVxdWVzdC5yZXNvbHV0aW9uLFxuICAgIHJlZmVyZW5jZV9pbWFnZXM6IHJlZmVyZW5jZXMubGVuZ3RoID09PSAwID8gdW5kZWZpbmVkIDogcmVmZXJlbmNlcy5tYXAoKHVybCkgPT4gKHsgdXJsIH0pKSxcbiAgICBsYXN0X2ZyYW1lOiByZXF1ZXN0Lmxhc3RGcmFtZSA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogeyB1cmw6IHJlcXVlc3QubGFzdEZyYW1lIH0sXG4gIH07XG5cbiAgcmV0dXJuIGJvZHk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlSnNvblRleHQodGV4dDogc3RyaW5nLCB3aGF0OiBzdHJpbmcpOiBKc29uVmFsdWUge1xuICB0cnkge1xuICAgIC8vIEpTT04ucGFyc2Ugd2l0aG91dCBhIHJldml2ZXIgeWllbGRzIG9ubHkgSlNPTiB2YWx1ZXMuXG4gICAgY29uc3QganNvbjogSnNvblZhbHVlID0gSlNPTi5wYXJzZSh0ZXh0KTtcblxuICAgIHJldHVybiBqc29uO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBuZXcgR3Jva1Byb3RvY29sRXJyb3IoYEdyb2sgJHt3aGF0fSByZXNwb25zZSBpcyBub3QgSlNPTmApO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhcnNlSnNvbjxUPihzY2hlbWE6IHouWm9kVHlwZTxUPiwgdGV4dDogc3RyaW5nLCB3aGF0OiBzdHJpbmcpOiBUIHtcbiAgY29uc3QgcGFyc2VkID0gc2NoZW1hLnNhZmVQYXJzZShwYXJzZUpzb25UZXh0KHRleHQsIHdoYXQpKTtcblxuICBpZiAoIXBhcnNlZC5zdWNjZXNzKSB0aHJvdyBuZXcgR3Jva1Byb3RvY29sRXJyb3IoYEdyb2sgJHt3aGF0fSByZXNwb25zZSBoYXMgYW4gdW5leHBlY3RlZCBzaGFwZWApO1xuXG4gIHJldHVybiBwYXJzZWQuZGF0YTtcbn1cblxuY29uc3QgSnNvbk9iamVjdCA9IHoucmVjb3JkKHouc3RyaW5nKCksIHoudW5rbm93bigpKTtcblxuY29uc3QgTG9vc2VWaWRlb1N0YXR1cyA9IHoubG9vc2VPYmplY3Qoe1xuICBzdGF0dXM6IHouc3RyaW5nKCkubnVsbGlzaCgpLFxuICB2aWRlbzogei5sb29zZU9iamVjdCh7IHVybDogei5zdHJpbmcoKS5udWxsaXNoKCkgfSkubnVsbGlzaCgpLFxufSk7XG5cbi8qKlxuICogMjAyIG1lYW5zIHBlbmRpbmcsIHBvc3NpYmx5IHdpdGggYW4gZW1wdHkgb3IgcGFydGlhbCBib2R5ICh4YWktdmlkZW8tbW9kZWwudHM6ODc2LTg5NDtcbiAqIGdyb2stYnVpbGQgdmlkZW9fZ2VuL21vZC5yczo0NDIgYWNjZXB0cyBpdCB0b28pLiBBIDIwMCB3aXRob3V0IGBzdGF0dXNgIGJ1dCB3aXRoIGEgdmlkZW8gVVJMXG4gKiBpcyBkb25lICh4YWktdmlkZW8tbW9kZWwudHM6NjczLTY3NikuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlVmlkZW9TdGF0dXMoaHR0cFN0YXR1czogbnVtYmVyLCB0ZXh0OiBzdHJpbmcpOiBHcm9rVmlkZW9TdGF0dXMge1xuICBpZiAoaHR0cFN0YXR1cyA9PT0gMjAyKSB7XG4gICAgaWYgKCF0ZXh0LnRyaW0oKSkgcmV0dXJuIHsgc3RhdHVzOiBcInBlbmRpbmdcIiB9O1xuICAgIGxldCBqc29uOiB1bmtub3duO1xuXG4gICAgdHJ5IHtcbiAgICAgIGpzb24gPSBKU09OLnBhcnNlKHRleHQpO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHsgc3RhdHVzOiBcInBlbmRpbmdcIiB9O1xuICAgIH1cblxuICAgIGNvbnN0IG9iamVjdCA9IEpzb25PYmplY3Quc2FmZVBhcnNlKGpzb24pO1xuICAgIGNvbnN0IGxvb3NlID0gTG9vc2VWaWRlb1N0YXR1cy5zYWZlUGFyc2UoanNvbik7XG5cbiAgICBpZiAoIW9iamVjdC5zdWNjZXNzIHx8ICFsb29zZS5zdWNjZXNzKSByZXR1cm4geyBzdGF0dXM6IFwicGVuZGluZ1wiIH07XG5cbiAgICBjb25zdCBwYXJzZWQgPSBHcm9rVmlkZW9TdGF0dXMuc2FmZVBhcnNlKHtcbiAgICAgIC4uLm9iamVjdC5kYXRhLFxuICAgICAgc3RhdHVzOiBsb29zZS5kYXRhLnN0YXR1cyA/PyBcInBlbmRpbmdcIixcbiAgICB9KTtcblxuICAgIHJldHVybiBwYXJzZWQuc3VjY2VzcyA/IHBhcnNlZC5kYXRhIDogeyBzdGF0dXM6IFwicGVuZGluZ1wiIH07XG4gIH1cblxuICBjb25zdCBqc29uID0gcGFyc2VKc29uVGV4dCh0ZXh0LCBcInZpZGVvIHN0YXR1c1wiKTtcbiAgY29uc3Qgb2JqZWN0ID0gSnNvbk9iamVjdC5zYWZlUGFyc2UoanNvbik7XG4gIGNvbnN0IGxvb3NlID0gTG9vc2VWaWRlb1N0YXR1cy5zYWZlUGFyc2UoanNvbik7XG5cbiAgaWYgKCFvYmplY3Quc3VjY2VzcyB8fCAhbG9vc2Uuc3VjY2VzcylcbiAgICB0aHJvdyBuZXcgR3Jva1Byb3RvY29sRXJyb3IoXCJHcm9rIHZpZGVvIHN0YXR1cyByZXNwb25zZSBoYXMgYW4gdW5leHBlY3RlZCBzaGFwZVwiKTtcbiAgY29uc3Qgc3RhdHVzID0gbG9vc2UuZGF0YS5zdGF0dXMgPz8gKGxvb3NlLmRhdGEudmlkZW8/LnVybCA/IFwiZG9uZVwiIDogXCJwZW5kaW5nXCIpO1xuICBjb25zdCBwYXJzZWQgPSBHcm9rVmlkZW9TdGF0dXMuc2FmZVBhcnNlKHsgLi4ub2JqZWN0LmRhdGEsIHN0YXR1cyB9KTtcblxuICBpZiAoIXBhcnNlZC5zdWNjZXNzKVxuICAgIHRocm93IG5ldyBHcm9rUHJvdG9jb2xFcnJvcihcIkdyb2sgdmlkZW8gc3RhdHVzIHJlc3BvbnNlIGhhcyBhbiB1bmV4cGVjdGVkIHNoYXBlXCIpO1xuXG4gIHJldHVybiBwYXJzZWQuZGF0YTtcbn1cblxuLyoqIFJlYWRzIHRoZSBib2R5LCByZS1hcm1pbmcgdGhlIHJlYWQgdGltZXIgcGVyIGNodW5rLiBgdHJ1bmNhdGVgIGNhcHMgaW5zdGVhZCBvZiBmYWlsaW5nLiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVhZEJvZHkoXG4gIHJlc3BvbnNlOiBSZXNwb25zZSxcbiAgbWF4Qnl0ZXM6IG51bWJlcixcbiAgb25DaHVuazogKCkgPT4gdm9pZCxcbiAgdHJ1bmNhdGU6IGJvb2xlYW4sXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBpZiAoIXJlc3BvbnNlLmJvZHkpIHJldHVybiBcIlwiO1xuICBjb25zdCByZWFkZXIgPSByZXNwb25zZS5ib2R5LmdldFJlYWRlcigpO1xuICBjb25zdCBkZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCk7XG4gIGxldCB0ZXh0ID0gXCJcIjtcbiAgbGV0IHRvdGFsID0gMDtcblxuICBmb3IgKDs7KSB7XG4gICAgY29uc3QgeyBkb25lLCB2YWx1ZSB9ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcblxuICAgIGlmIChkb25lKSBicmVhaztcbiAgICBvbkNodW5rKCk7XG4gICAgdG90YWwgKz0gdmFsdWUuYnl0ZUxlbmd0aDtcblxuICAgIGlmICh0b3RhbCA+IG1heEJ5dGVzKSB7XG4gICAgICBhd2FpdCByZWFkZXIuY2FuY2VsKCkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcblxuICAgICAgaWYgKHRydW5jYXRlKVxuICAgICAgICByZXR1cm4gdGV4dCArIGRlY29kZXIuZGVjb2RlKHZhbHVlLnN1YmFycmF5KDAsIG1heEJ5dGVzIC0gKHRvdGFsIC0gdmFsdWUuYnl0ZUxlbmd0aCkpKTtcbiAgICAgIHRocm93IG5ldyBCb2R5TGltaXRFcnJvcihgR3JvayBtZWRpYSByZXNwb25zZSBleGNlZWRlZCAke21heEJ5dGVzfSBieXRlc2ApO1xuICAgIH1cblxuICAgIHRleHQgKz0gZGVjb2Rlci5kZWNvZGUodmFsdWUsIHsgc3RyZWFtOiB0cnVlIH0pO1xuICB9XG5cbiAgcmV0dXJuIHRleHQgKyBkZWNvZGVyLmRlY29kZSgpO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7OztBQTBDQSxNQUFhLDhCQUE4QjtBQUMzQyxNQUFhLDZCQUE2QjtBQUcxQyxNQUFhLDhCQUE4QjtBQUMzQyxNQUFhLDZCQUE2QjtBQUcxQyxNQUFhLDBCQUEwQjtBQUd2QyxNQUFNLGdDQUFnQztBQUd0QyxNQUFNLGdDQUFnQztBQUd0QyxNQUFNLDhCQUE4QjtBQUVwQyxNQUFNLDJCQUEyQixLQUFLLE9BQU87QUFDN0MsTUFBTSwwQkFBMEIsT0FBTztBQUN2QyxNQUFNLHVCQUF1QixLQUFLO0FBU2xDLE1BQU0sbUJBQXNDO0NBQzFDLGNBQWM7Q0FDZCxhQUFhO0NBQ2IsY0FBYztDQUNkLGFBQWE7QUFDZjs7QUFHQSxJQUFhLHlCQUFiLGNBQTRDLE1BQU07Q0FDaEQsWUFBWSxNQUF5QjtFQUNuQyxNQUNFLEdBQUcsU0FBUyxVQUFVLFVBQVUsUUFBUSwyREFDMUM7RUFDQSxLQUFLLE9BQU87Q0FDZDtBQUNGOztBQUdBLElBQWEsd0JBQWIsY0FBMkMsTUFB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