@cartanova/qgrid-cli 2.10.10 → 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.
- package/bundle/dist/_virtual/_rolldown/runtime.js +1 -10
- package/bundle/dist/application/monit/log-buffer.js +12 -6
- package/bundle/dist/application/monit/monit.frame.js +11 -3
- package/bundle/dist/application/monit/monit.types.js +1 -1
- package/bundle/dist/application/qgrid/conv-routing.js +9 -6
- package/bundle/dist/application/qgrid/expired-token-reminder.js +2 -2
- package/bundle/dist/application/qgrid/oauth.js +31 -4
- package/bundle/dist/application/qgrid/qgrid-image-generation.js +1 -1
- package/bundle/dist/application/qgrid/qgrid-response-format.js +21 -19
- package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +40 -33
- package/bundle/dist/application/qgrid/qgrid.dispatcher.js +128 -93
- package/bundle/dist/application/qgrid/qgrid.frame.js +930 -49
- package/bundle/dist/application/qgrid/qgrid.types.js +212 -5
- package/bundle/dist/application/qgrid/schema-prompt.js +75 -48
- package/bundle/dist/application/qgrid/slack-user-map.js +1 -1
- package/bundle/dist/application/qgrid/token-death.js +1 -1
- package/bundle/dist/application/qgrid/token-subscriber.js +83 -30
- package/bundle/dist/application/qgrid/token-trigger-setup.js +1 -1
- package/bundle/dist/application/qgrid/token-window-keepalive.js +8 -6
- package/bundle/dist/application/qgrid/tool-emulation-schema.js +13 -13
- package/bundle/dist/application/qgrid/tool-emulation.js +19 -15
- package/bundle/dist/application/request-log/json-schema-type-text.js +29 -12
- package/bundle/dist/application/request-log/request-log.model.js +83 -70
- package/bundle/dist/application/request-log/request-log.types.js +1 -1
- package/bundle/dist/application/request-log/zod-code-format.js +1 -1
- package/bundle/dist/application/request-log-step/request-log-step.model.js +1 -1
- package/bundle/dist/application/request-log-step/request-log-step.types.js +1 -1
- package/bundle/dist/application/setting/setting.constant.js +1 -1
- package/bundle/dist/application/setting/setting.model.js +2 -2
- package/bundle/dist/application/setting/setting.store.js +2 -2
- package/bundle/dist/application/setting/setting.types.js +1 -1
- package/bundle/dist/application/sonamu.generated.js +32 -16
- package/bundle/dist/application/sonamu.generated.sso.js +1 -1
- package/bundle/dist/application/token/token.model.js +26 -9
- package/bundle/dist/application/token/token.types.js +20 -3
- package/bundle/dist/i18n/en.js +15 -1
- package/bundle/dist/i18n/ko.js +15 -1
- package/bundle/dist/i18n/sd.generated.js +1 -1
- package/bundle/dist/migrations/20260807133553_manual__backfill_request_log_cost.js +8 -6
- package/bundle/dist/server-bootstrap.js +4 -2
- package/bundle/dist/server-error-handler.js +1 -1
- package/bundle/dist/sonamu.config.js +37 -8
- package/bundle/dist/startup-migrations.js +17 -7
- package/bundle/dist/testing/global.js +1 -1
- package/bundle/dist/testing/schema-bench.js +0 -0
- package/bundle/dist/testing/test-database-name.js +1 -1
- package/bundle/dist/utils/providers/anthropic/anthropic-constants.js +1 -1
- package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +11 -5
- package/bundle/dist/utils/providers/anthropic/anthropic-quota.js +4 -4
- package/bundle/dist/utils/providers/anthropic/anthropic-thinking.js +1 -1
- package/bundle/dist/utils/providers/anthropic/claude-session.js +20 -19
- package/bundle/dist/utils/providers/anthropic/fence-strip.js +1 -1
- package/bundle/dist/utils/providers/anthropic/stream-json-adapter.js +49 -23
- package/bundle/dist/utils/providers/common/credentials.js +5 -1
- package/bundle/dist/utils/providers/common/effort.js +3 -3
- package/bundle/dist/utils/providers/common/model-cost.js +69 -14
- package/bundle/dist/utils/providers/common/provider-types.js +29 -1
- package/bundle/dist/utils/providers/common/schema-validation.js +78 -40
- package/bundle/dist/utils/providers/common/smooth-weighted-round-robin.js +1 -1
- package/bundle/dist/utils/providers/common/strictifier.js +62 -43
- package/bundle/dist/utils/providers/common/thinking.js +3 -2
- package/bundle/dist/utils/providers/common/ttft.js +1 -1
- package/bundle/dist/utils/providers/grok/grok-backend-protocol.js +427 -0
- package/bundle/dist/utils/providers/grok/grok-constants.js +55 -0
- package/bundle/dist/utils/providers/grok/grok-direct-client.js +196 -0
- package/bundle/dist/utils/providers/grok/grok-dispatcher.js +1313 -0
- package/bundle/dist/utils/providers/grok/grok-headers.js +118 -0
- package/bundle/dist/utils/providers/grok/grok-media-client.js +420 -0
- package/bundle/dist/utils/providers/grok/grok-models.js +114 -0
- package/bundle/dist/utils/providers/grok/grok-oauth.js +455 -0
- package/bundle/dist/utils/providers/grok/grok-quota.js +119 -0
- package/bundle/dist/utils/providers/grok/grok-refresh.js +192 -0
- package/bundle/dist/utils/providers/grok/grok-types.js +186 -0
- package/bundle/dist/utils/providers/grok/grok-voice-client.js +199 -0
- package/bundle/dist/utils/providers/grok/index.js +11 -0
- package/bundle/dist/utils/providers/openai/openai-backend-protocol.js +111 -83
- package/bundle/dist/utils/providers/openai/openai-callback-relay.js +3 -2
- package/bundle/dist/utils/providers/openai/openai-constants.js +1 -1
- package/bundle/dist/utils/providers/openai/openai-direct-client.js +23 -7
- package/bundle/dist/utils/providers/openai/openai-dispatcher.js +143 -106
- package/bundle/dist/utils/providers/openai/openai-image-generation.js +48 -33
- package/bundle/dist/utils/providers/openai/openai-oauth.js +28 -13
- package/bundle/dist/utils/providers/openai/openai-quota.js +38 -27
- package/bundle/dist/utils/providers/openai/openai-refresh.js +17 -9
- package/bundle/dist/utils/providers/openai/openai-sse.js +1 -1
- package/bundle/dist/utils/providers/openai/openai-transport-config.js +1 -1
- package/bundle/dist/utils/quiet-hours.js +1 -1
- package/bundle/dist/utils/slack-notify.js +14 -8
- package/bundle/dist/utils/subset-loaders.js +4 -5
- package/bundle/src/application/monit/log-buffer.ts +23 -9
- package/bundle/src/application/monit/monit.frame.ts +22 -5
- package/bundle/src/application/monit/monit.types.ts +6 -0
- package/bundle/src/application/qgrid/conv-routing.test.ts +76 -4
- package/bundle/src/application/qgrid/conv-routing.ts +35 -9
- package/bundle/src/application/qgrid/expired-token-reminder.ts +9 -1
- package/bundle/src/application/qgrid/oauth.ts +51 -15
- package/bundle/src/application/qgrid/qgrid-image-generation.ts +9 -0
- package/bundle/src/application/qgrid/qgrid-response-format.ts +50 -25
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +19 -0
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +84 -40
- package/bundle/src/application/qgrid/qgrid.dispatcher.test.ts +97 -0
- package/bundle/src/application/qgrid/qgrid.dispatcher.ts +274 -126
- package/bundle/src/application/qgrid/qgrid.frame.test.ts +1013 -3
- package/bundle/src/application/qgrid/qgrid.frame.ts +1415 -60
- package/bundle/src/application/qgrid/qgrid.types.ts +335 -0
- package/bundle/src/application/qgrid/schema-prompt.ts +105 -41
- package/bundle/src/application/qgrid/slack-user-map.ts +5 -0
- package/bundle/src/application/qgrid/token-death.ts +4 -0
- package/bundle/src/application/qgrid/token-subscriber.test.ts +21 -19
- package/bundle/src/application/qgrid/token-subscriber.ts +186 -53
- package/bundle/src/application/qgrid/token-trigger-setup.ts +2 -0
- package/bundle/src/application/qgrid/token-window-keepalive.ts +49 -6
- package/bundle/src/application/qgrid/tool-emulation-schema.ts +33 -29
- package/bundle/src/application/qgrid/tool-emulation.ts +52 -27
- package/bundle/src/application/request-log/json-schema-type-text.test.ts +5 -5
- package/bundle/src/application/request-log/json-schema-type-text.ts +81 -26
- package/bundle/src/application/request-log/request-log.model.test.ts +111 -4
- package/bundle/src/application/request-log/request-log.model.ts +277 -146
- package/bundle/src/application/request-log/request-log.types.ts +6 -0
- package/bundle/src/application/request-log/zod-code-format.ts +11 -0
- package/bundle/src/application/request-log-step/request-log-step.model.ts +1 -0
- package/bundle/src/application/request-log-step/request-log-step.types.ts +2 -0
- package/bundle/src/application/setting/setting.constant.ts +9 -0
- package/bundle/src/application/setting/setting.model.ts +12 -2
- package/bundle/src/application/setting/setting.store.ts +5 -1
- package/bundle/src/application/setting/setting.types.ts +8 -0
- package/bundle/src/application/sonamu.generated.http +133 -0
- package/bundle/src/application/sonamu.generated.sso.ts +2 -0
- package/bundle/src/application/sonamu.generated.ts +15 -0
- package/bundle/src/application/token/token.identity.test.ts +20 -0
- package/bundle/src/application/token/token.model.ts +66 -7
- package/bundle/src/application/token/token.types.ts +24 -1
- package/bundle/src/i18n/en.ts +19 -0
- package/bundle/src/i18n/ko.ts +21 -0
- package/bundle/src/i18n/sd.generated.ts +23 -2
- package/bundle/src/migrations/20260807133553_manual__backfill_request_log_cost.ts +16 -8
- package/bundle/src/server-bootstrap.ts +4 -2
- package/bundle/src/server-error-handler.ts +1 -0
- package/bundle/src/sonamu.config.ts +69 -7
- package/bundle/src/startup-migrations.ts +27 -9
- package/bundle/src/testing/global.ts +20 -0
- package/bundle/src/testing/schema-bench.ts +105 -30
- package/bundle/src/testing/test-database-name.ts +2 -0
- package/bundle/src/utils/providers/anthropic/anthropic-constants.ts +8 -0
- package/bundle/src/utils/providers/anthropic/anthropic-dispatcher.ts +41 -6
- package/bundle/src/utils/providers/anthropic/anthropic-quota.ts +7 -3
- package/bundle/src/utils/providers/anthropic/anthropic-thinking.ts +6 -0
- package/bundle/src/utils/providers/anthropic/claude-session.ts +58 -24
- package/bundle/src/utils/providers/anthropic/fence-strip.ts +11 -0
- package/bundle/src/utils/providers/anthropic/stream-json-adapter.ts +110 -45
- package/bundle/src/utils/providers/common/credentials.ts +8 -0
- package/bundle/src/utils/providers/common/effort.ts +9 -2
- package/bundle/src/utils/providers/common/model-cost.test.ts +48 -1
- package/bundle/src/utils/providers/common/model-cost.ts +259 -158
- package/bundle/src/utils/providers/common/provider-dispatcher.ts +98 -2
- package/bundle/src/utils/providers/common/provider-types.ts +46 -3
- package/bundle/src/utils/providers/common/schema-validation.test.ts +5 -1
- package/bundle/src/utils/providers/common/schema-validation.ts +124 -56
- package/bundle/src/utils/providers/common/smooth-weighted-round-robin.ts +4 -0
- package/bundle/src/utils/providers/common/strictifier.ts +185 -59
- package/bundle/src/utils/providers/common/thinking.ts +2 -2
- package/bundle/src/utils/providers/common/ttft.ts +4 -2
- package/bundle/src/utils/providers/grok/__fixtures__/golden-responses-1.0.60.json +164 -0
- package/bundle/src/utils/providers/grok/grok-backend-protocol.test.ts +325 -0
- package/bundle/src/utils/providers/grok/grok-backend-protocol.ts +721 -0
- package/bundle/src/utils/providers/grok/grok-constants.ts +105 -0
- package/bundle/src/utils/providers/grok/grok-direct-client.test.ts +179 -0
- package/bundle/src/utils/providers/grok/grok-direct-client.ts +313 -0
- package/bundle/src/utils/providers/grok/grok-dispatcher.test.ts +1395 -0
- package/bundle/src/utils/providers/grok/grok-dispatcher.ts +2105 -0
- package/bundle/src/utils/providers/grok/grok-headers.test.ts +149 -0
- package/bundle/src/utils/providers/grok/grok-headers.ts +199 -0
- package/bundle/src/utils/providers/grok/grok-media-client.test.ts +446 -0
- package/bundle/src/utils/providers/grok/grok-media-client.ts +703 -0
- package/bundle/src/utils/providers/grok/grok-models.test.ts +96 -0
- package/bundle/src/utils/providers/grok/grok-models.ts +161 -0
- package/bundle/src/utils/providers/grok/grok-oauth.test.ts +406 -0
- package/bundle/src/utils/providers/grok/grok-oauth.ts +771 -0
- package/bundle/src/utils/providers/grok/grok-quota.test.ts +142 -0
- package/bundle/src/utils/providers/grok/grok-quota.ts +198 -0
- package/bundle/src/utils/providers/grok/grok-refresh.test.ts +239 -0
- package/bundle/src/utils/providers/grok/grok-refresh.ts +325 -0
- package/bundle/src/utils/providers/grok/grok-types.test.ts +252 -0
- package/bundle/src/utils/providers/grok/grok-types.ts +374 -0
- package/bundle/src/utils/providers/grok/grok-voice-client.test.ts +321 -0
- package/bundle/src/utils/providers/grok/grok-voice-client.ts +284 -0
- package/bundle/src/utils/providers/grok/index.ts +20 -0
- package/bundle/src/utils/providers/openai/openai-backend-protocol.ts +221 -137
- package/bundle/src/utils/providers/openai/openai-callback-relay.ts +12 -1
- package/bundle/src/utils/providers/openai/openai-constants.ts +2 -0
- package/bundle/src/utils/providers/openai/openai-direct-client.ts +111 -21
- package/bundle/src/utils/providers/openai/openai-dispatcher.ts +322 -169
- package/bundle/src/utils/providers/openai/openai-image-generation.ts +116 -36
- package/bundle/src/utils/providers/openai/openai-oauth.ts +48 -20
- package/bundle/src/utils/providers/openai/openai-quota.ts +77 -46
- package/bundle/src/utils/providers/openai/openai-refresh.ts +42 -18
- package/bundle/src/utils/providers/openai/openai-sse.ts +27 -3
- package/bundle/src/utils/providers/openai/openai-transport-config.ts +2 -0
- package/bundle/src/utils/quiet-hours.ts +12 -1
- package/bundle/src/utils/slack-notify.ts +44 -13
- package/bundle/src/utils/subset-loaders.ts +7 -7
- package/bundle/web-dist/client/assets/clsx-5XM_pHvN.js +1 -0
- package/bundle/web-dist/client/assets/index-BA7uQ-6c.js +31 -0
- package/bundle/web-dist/client/assets/index-Be2qCZmI.css +1 -0
- package/bundle/web-dist/client/assets/logs-C47OJGEI.js +1 -0
- package/bundle/web-dist/client/assets/monit-BS9no0dU.js +4 -0
- package/bundle/web-dist/client/assets/plus-sdACTfH0.js +1 -0
- package/bundle/web-dist/client/assets/refresh-cw-CY8o_1cT.js +1 -0
- package/bundle/web-dist/client/assets/request-model-BRtFuZvj.js +1 -0
- package/bundle/web-dist/client/assets/routes-kqgkUxE8.js +5 -0
- package/bundle/web-dist/client/assets/{services.generated-NP-ValHd.js → services.generated-CefiDXEv.js} +5 -5
- package/bundle/web-dist/client/assets/settings-DNDvFGSw.js +1 -0
- package/bundle/web-dist/client/assets/show-u8Np69q3.js +2 -0
- package/bundle/web-dist/client/assets/tokens-QvP410NW.js +1 -0
- package/bundle/web-dist/client/assets/total-cost-MnfKU8IN.js +1 -0
- package/bundle/web-dist/client/assets/use-oauth-login-flow-Bzdh28Ws.js +1 -0
- package/bundle/web-dist/client/assets/use-update-token-mutation-CfJKaxmR.js +1 -0
- package/bundle/web-dist/client/assets/vendor-react-CUFFrVN9.js +244 -0
- package/bundle/web-dist/client/assets/vendor-tanstack-Bf_jag9G.js +1 -0
- package/bundle/web-dist/client/index.html +6 -6
- package/bundle/web-dist/server/assets/clsx-D_N5PN_2.js +16 -0
- package/bundle/web-dist/server/assets/{lazyRouteComponent-CgBdabgd.js → lazyRouteComponent-D8iTIHyn.js} +129 -2
- package/bundle/web-dist/server/assets/logs-B3OTd9hy.js +825 -0
- package/bundle/web-dist/server/assets/{monit-ZPt66W5M.js → monit-B2hqorPe.js} +385 -126
- package/bundle/web-dist/server/assets/plus-DwG7h9kq.js +28 -0
- package/bundle/web-dist/server/assets/{react-dom-Ds75e4Jl.js → react-dom-BIYQzBqG.js} +2 -129
- package/bundle/web-dist/server/assets/refresh-cw-mMBkwOq0.js +44 -0
- package/bundle/web-dist/server/assets/{request-model-DjGldb-h.js → request-model-I6OdODSH.js} +15 -6
- package/bundle/web-dist/server/assets/{routes-Ct-k7nBA.js → routes-B95YlUv2.js} +760 -213
- package/bundle/web-dist/server/assets/{services.generated-BA4AcAf5.js → services.generated-DQATJ6qf.js} +12820 -12194
- package/bundle/web-dist/server/assets/settings-C3gbGk0m.js +830 -0
- package/bundle/web-dist/server/assets/{show-LSFIzvO2.js → show-Bxaj3rhH.js} +1350 -418
- package/bundle/web-dist/server/assets/tokens-CZjH3cB7.js +1038 -0
- package/bundle/web-dist/server/assets/total-cost-fTE9Xy82.js +18 -0
- package/bundle/web-dist/server/assets/use-oauth-login-flow-CKDHgc3U.js +2379 -0
- package/bundle/web-dist/server/assets/{use-update-token-mutation-pkArIzCP.js → use-update-token-mutation-BEbgOzaa.js} +1 -1
- package/bundle/web-dist/server/entry-server.generated.js +4295 -22810
- package/dist/cli.js +9 -9
- package/package.json +4 -11
- package/postinstall.mjs +12 -0
- package/skills/qgrid/SKILL.md +1 -0
- package/skills/qgrid/references/cli-env-and-server-boot.md +4 -1
- package/skills/qgrid/references/decision-rationale.md +23 -0
- package/skills/qgrid/references/grok-runtime.md +89 -0
- package/skills/qgrid/references/provider-runtime-differences.md +30 -29
- package/skills/qgrid/references/repo-map.md +10 -0
- package/skills/qgrid/references/token-auth-quota-lifecycle.md +56 -3
- package/bundle/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +0 -406
- package/bundle/dist/node_modules/.pnpm/@vitest_expect@4.1.10/node_modules/@vitest/expect/dist/index.js +0 -1507
- package/bundle/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.10/node_modules/@vitest/pretty-format/dist/index.js +0 -887
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2756
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/index.js +0 -8
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/utils.js +0 -8
- package/bundle/dist/node_modules/.pnpm/@vitest_snapshot@4.1.10/node_modules/@vitest/snapshot/dist/index.js +0 -922
- package/bundle/dist/node_modules/.pnpm/@vitest_spy@4.1.10/node_modules/@vitest/spy/dist/index.js +0 -386
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -121
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/constants.js +0 -51
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/diff.js +0 -1317
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/display.js +0 -561
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js +0 -40
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js +0 -272
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/offset.js +0 -27
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/serialize.js +0 -77
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/source-map.js +0 -381
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/timers.js +0 -51
- package/bundle/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +0 -2986
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +0 -10
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +0 -109
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +0 -10
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +0 -10
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +0 -10
- package/bundle/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +0 -1126
- package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +0 -21
- package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +0 -432
- package/bundle/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +0 -517
- package/bundle/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +0 -101
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/bundle/dist/testing/setup-mocks.js +0 -16
- package/bundle/src/testing/setup-mocks.ts +0 -44
- package/bundle/web-dist/client/assets/index-Bw2s88Ot.css +0 -1
- package/bundle/web-dist/client/assets/index-DZwzUfI-.js +0 -106
- package/bundle/web-dist/client/assets/logs-Cog79DU5.js +0 -1
- package/bundle/web-dist/client/assets/monit-2auznBys.js +0 -1
- package/bundle/web-dist/client/assets/plus-B62CuqT8.js +0 -1
- package/bundle/web-dist/client/assets/refresh-cw-NNcU0Cmq.js +0 -1
- package/bundle/web-dist/client/assets/request-model-CojtinqK.js +0 -1
- package/bundle/web-dist/client/assets/routes-B0lTeLK-.js +0 -5
- package/bundle/web-dist/client/assets/settings-D8ZxZGSJ.js +0 -1
- package/bundle/web-dist/client/assets/show-CFSERlnM.js +0 -2
- package/bundle/web-dist/client/assets/tokens-CZXUyI7O.js +0 -1
- package/bundle/web-dist/client/assets/use-oauth-login-flow-hboOs3wG.js +0 -1
- package/bundle/web-dist/client/assets/use-update-token-mutation-BQHS0byG.js +0 -1
- package/bundle/web-dist/client/assets/vendor-react-DH4kUfK2.js +0 -9
- package/bundle/web-dist/client/assets/vendor-tanstack-DJRQAbrY.js +0 -1
- package/bundle/web-dist/server/assets/logs-BMyR98rU.js +0 -509
- package/bundle/web-dist/server/assets/plus-BZ9I0VgC.js +0 -19
- package/bundle/web-dist/server/assets/refresh-cw-CztCFis-.js +0 -23
- package/bundle/web-dist/server/assets/settings-CBUZ47Xx.js +0 -461
- package/bundle/web-dist/server/assets/tokens-DxrBW512.js +0 -448
- package/bundle/web-dist/server/assets/use-oauth-login-flow-Gn8flMK5.js +0 -178
- package/dist/cli.d.ts +0 -10
- /package/bundle/web-dist/client/assets/{cost-DH2jZbrw.js → cost-DB3HbU7T.js} +0 -0
- /package/bundle/web-dist/client/assets/{preload-helper-ca-nBW7U.js → preload-helper-DWTEM3RW.js} +0 -0
- /package/bundle/web-dist/server/assets/{cost-eEHeTRT5.js → cost-BC9yzyA9.js} +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { resolveOpenAITransportKind } from "./openai-transport-config.js";
|
|
2
|
+
import { isOpenAICredentials } from "../common/credentials.js";
|
|
3
|
+
import { isJsonObject, jsonString } from "../common/provider-types.js";
|
|
2
4
|
import { QuotaThresholdExceededError } from "../../../application/qgrid/qgrid.types.js";
|
|
3
5
|
import { TokenModel } from "../../../application/token/token.model.js";
|
|
4
6
|
import { resolveOpenAIEffort } from "../common/effort.js";
|
|
@@ -8,6 +10,7 @@ import { imageMimeType } from "./openai-backend-protocol.js";
|
|
|
8
10
|
import { OpenAIDirectClient } from "./openai-direct-client.js";
|
|
9
11
|
import { readOpenAIQuotaUsage } from "./openai-quota.js";
|
|
10
12
|
import { handleChatgptAuthTokensRefresh } from "./openai-refresh.js";
|
|
13
|
+
import { z } from "zod";
|
|
11
14
|
import { getLogger } from "@logtape/logtape";
|
|
12
15
|
//#region src/utils/providers/openai/openai-dispatcher.ts
|
|
13
16
|
const logger = getLogger(["qgrid", "openai-dispatcher"]);
|
|
@@ -21,6 +24,20 @@ const THINKING_OFF_MODELS = /* @__PURE__ */ new Set([
|
|
|
21
24
|
]);
|
|
22
25
|
const DEFAULT_REQUEST_TIMEOUT_MS = 6e5;
|
|
23
26
|
const IMAGE_TOOL = "generate_image";
|
|
27
|
+
const ImageToolArgumentsSchema = z.strictObject({
|
|
28
|
+
prompt: z.string().refine((prompt) => prompt.trim().length > 0),
|
|
29
|
+
transparent_background: z.boolean(),
|
|
30
|
+
num_last_images_to_include: z.number().int().min(0).max(5)
|
|
31
|
+
});
|
|
32
|
+
function generatedImageFrom(event) {
|
|
33
|
+
const image = {
|
|
34
|
+
data: event.base64,
|
|
35
|
+
mediaType: event.mimeType,
|
|
36
|
+
revisedPrompt: event.revisedPrompt ?? null
|
|
37
|
+
};
|
|
38
|
+
if (event.generation) image.generation = event.generation;
|
|
39
|
+
return image;
|
|
40
|
+
}
|
|
24
41
|
var ImageGenerationError = class extends Error {
|
|
25
42
|
kind;
|
|
26
43
|
completedDriver;
|
|
@@ -70,12 +87,14 @@ function inputItems(req) {
|
|
|
70
87
|
}
|
|
71
88
|
function imageReferences(req) {
|
|
72
89
|
return inputItems(req).flatMap((item) => {
|
|
73
|
-
if (item
|
|
90
|
+
if (!isJsonObject(item)) return [];
|
|
91
|
+
const result = jsonString(item.result);
|
|
92
|
+
if (item.type === "image_generation_call" && result !== void 0) return [{
|
|
74
93
|
type: "input_image",
|
|
75
|
-
image_url: `data:${imageMimeType(
|
|
94
|
+
image_url: `data:${imageMimeType(result, item.output_format)};base64,${result}`
|
|
76
95
|
}];
|
|
77
96
|
if (!Array.isArray(item.content)) return [];
|
|
78
|
-
return item.content.filter((part) => part
|
|
97
|
+
return item.content.filter(isJsonObject).filter((part) => part.type === "input_image" || part.type === "image_url");
|
|
79
98
|
});
|
|
80
99
|
}
|
|
81
100
|
function asReasoning(req) {
|
|
@@ -83,62 +102,67 @@ function asReasoning(req) {
|
|
|
83
102
|
const summary = req.reasoningSummary && req.reasoningSummary !== "none" ? req.reasoningSummary : void 0;
|
|
84
103
|
const effort = resolveOpenAIEffort(req.model ?? "", req.effort) ?? (req.thinking === true ? "low" : void 0);
|
|
85
104
|
if (!effort && !summary) return void 0;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
105
|
+
const reasoning = {};
|
|
106
|
+
if (effort) reasoning.effort = effort;
|
|
107
|
+
if (summary) reasoning.summary = summary;
|
|
108
|
+
return reasoning;
|
|
90
109
|
}
|
|
110
|
+
const AUTO_IMAGE_INSTRUCTIONS = "Use generate_image when image generation or editing is needed; otherwise reply with text. Call it at most once per response. Supply a complete, self-contained prompt with all relevant conversation instructions. Set transparent_background to true only when a transparent background is requested. Set num_last_images_to_include to 0 for a new image without references. For editing or reference-based generation, choose the smallest number of recent conversation images that includes all needed references, at most 5. References retain their chronological order. Do not select images for an unrelated new request.";
|
|
111
|
+
const AUTO_IMAGE_TOOL = {
|
|
112
|
+
type: "function",
|
|
113
|
+
name: IMAGE_TOOL,
|
|
114
|
+
description: "Generate or edit an image, optionally with a transparent background or recent conversation images as references.",
|
|
115
|
+
strict: false,
|
|
116
|
+
parameters: {
|
|
117
|
+
type: "object",
|
|
118
|
+
properties: {
|
|
119
|
+
prompt: {
|
|
120
|
+
type: "string",
|
|
121
|
+
minLength: 1,
|
|
122
|
+
description: "Complete, self-contained instructions for the image generation or edit."
|
|
123
|
+
},
|
|
124
|
+
transparent_background: { type: "boolean" },
|
|
125
|
+
num_last_images_to_include: {
|
|
126
|
+
type: "integer",
|
|
127
|
+
minimum: 0,
|
|
128
|
+
maximum: 5
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
required: [
|
|
132
|
+
"prompt",
|
|
133
|
+
"transparent_background",
|
|
134
|
+
"num_last_images_to_include"
|
|
135
|
+
],
|
|
136
|
+
additionalProperties: false
|
|
137
|
+
}
|
|
138
|
+
};
|
|
91
139
|
function requestOptions(req) {
|
|
92
140
|
const { outputFormat, ...imageControls } = req.imageGenerationOptions ?? {};
|
|
93
141
|
const auto = req.imageGeneration === "auto";
|
|
94
142
|
if (auto && req.outputSchema) throw new ImageGenerationError("gate", "Automatic image generation does not support structured output or external tools");
|
|
95
143
|
if (auto && outputFormat && outputFormat !== "png") throw new ImageGenerationError("gate", "Automatic image generation only supports PNG output");
|
|
96
|
-
|
|
144
|
+
const options = {
|
|
97
145
|
model: req.model ?? "",
|
|
98
|
-
|
|
99
|
-
...auto ? {
|
|
100
|
-
instructions: [req.systemPrompt, "Use generate_image when image generation or editing is needed; otherwise reply with text. Call it at most once per response. Supply a complete, self-contained prompt with all relevant conversation instructions. Set transparent_background to true only when a transparent background is requested. Set num_last_images_to_include to 0 for a new image without references. For editing or reference-based generation, choose the smallest number of recent conversation images that includes all needed references, at most 5. References retain their chronological order. Do not select images for an unrelated new request."].filter(Boolean).join("\n\n"),
|
|
101
|
-
parallelToolCalls: false,
|
|
102
|
-
tools: [{
|
|
103
|
-
type: "function",
|
|
104
|
-
name: IMAGE_TOOL,
|
|
105
|
-
description: "Generate or edit an image, optionally with a transparent background or recent conversation images as references.",
|
|
106
|
-
strict: false,
|
|
107
|
-
parameters: {
|
|
108
|
-
type: "object",
|
|
109
|
-
properties: {
|
|
110
|
-
prompt: {
|
|
111
|
-
type: "string",
|
|
112
|
-
minLength: 1,
|
|
113
|
-
description: "Complete, self-contained instructions for the image generation or edit."
|
|
114
|
-
},
|
|
115
|
-
transparent_background: { type: "boolean" },
|
|
116
|
-
num_last_images_to_include: {
|
|
117
|
-
type: "integer",
|
|
118
|
-
minimum: 0,
|
|
119
|
-
maximum: 5
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
|
-
required: [
|
|
123
|
-
"prompt",
|
|
124
|
-
"transparent_background",
|
|
125
|
-
"num_last_images_to_include"
|
|
126
|
-
],
|
|
127
|
-
additionalProperties: false
|
|
128
|
-
}
|
|
129
|
-
}]
|
|
130
|
-
} : {},
|
|
131
|
-
history: inputItems(req),
|
|
132
|
-
...asReasoning(req) ? { reasoning: asReasoning(req) } : {},
|
|
133
|
-
...req.verbosity ? { verbosity: req.verbosity } : {},
|
|
134
|
-
...req.serviceTier ? { serviceTier: req.serviceTier === "fast" ? "priority" : req.serviceTier } : {},
|
|
135
|
-
...req.promptCacheKey ? { promptCacheKey: req.promptCacheKey } : {},
|
|
136
|
-
...req.outputSchema ? { outputSchema: { schema: req.outputSchema } } : {},
|
|
137
|
-
...req.imageGeneration && !auto ? { imageGeneration: req.imageGenerationOptions ? {
|
|
138
|
-
...imageControls,
|
|
139
|
-
...outputFormat ? { output_format: outputFormat } : {}
|
|
140
|
-
} : true } : {}
|
|
146
|
+
history: inputItems(req)
|
|
141
147
|
};
|
|
148
|
+
if (req.systemPrompt) options.instructions = req.systemPrompt;
|
|
149
|
+
if (auto) {
|
|
150
|
+
options.instructions = [req.systemPrompt, AUTO_IMAGE_INSTRUCTIONS].filter(Boolean).join("\n\n");
|
|
151
|
+
options.parallelToolCalls = false;
|
|
152
|
+
options.tools = [AUTO_IMAGE_TOOL];
|
|
153
|
+
}
|
|
154
|
+
const reasoning = asReasoning(req);
|
|
155
|
+
if (reasoning) options.reasoning = reasoning;
|
|
156
|
+
if (req.verbosity) options.verbosity = req.verbosity;
|
|
157
|
+
if (req.serviceTier) options.serviceTier = req.serviceTier === "fast" ? "priority" : req.serviceTier;
|
|
158
|
+
if (req.promptCacheKey) options.promptCacheKey = req.promptCacheKey;
|
|
159
|
+
if (req.outputSchema) options.outputSchema = { schema: req.outputSchema };
|
|
160
|
+
if (req.imageGeneration && !auto) if (req.imageGenerationOptions) {
|
|
161
|
+
const controls = { ...imageControls };
|
|
162
|
+
if (outputFormat) controls.output_format = outputFormat;
|
|
163
|
+
options.imageGeneration = controls;
|
|
164
|
+
} else options.imageGeneration = true;
|
|
165
|
+
return options;
|
|
142
166
|
}
|
|
143
167
|
var OpenAIDispatcher = class OpenAIDispatcher {
|
|
144
168
|
tokenMetadata = /* @__PURE__ */ new Map();
|
|
@@ -160,9 +184,14 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
160
184
|
}
|
|
161
185
|
async start() {
|
|
162
186
|
const { rows } = await TokenModel.findMany("A");
|
|
163
|
-
|
|
187
|
+
for (const row of rows) {
|
|
188
|
+
if (row.provider !== "openai") continue;
|
|
189
|
+
if (!isOpenAICredentials(row.credentials)) {
|
|
190
|
+
logger.warn(`skipping token ${row.name}: credentials are not OpenAI OAuth credentials`);
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
164
193
|
this.setToken(row.id, row.name, row.credentials, row.quota_threshold, row.weight, row.active);
|
|
165
|
-
}
|
|
194
|
+
}
|
|
166
195
|
logger.info(`started direct OpenAI runtime with ${this.tokenMetadata.size} tokens`);
|
|
167
196
|
}
|
|
168
197
|
async stop() {
|
|
@@ -212,7 +241,7 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
212
241
|
try {
|
|
213
242
|
cb.onComplete(await this.run(req, cb.onDelta));
|
|
214
243
|
} catch (error) {
|
|
215
|
-
cb.onError(error);
|
|
244
|
+
cb.onError(error instanceof Error ? error : new Error(String(error)));
|
|
216
245
|
throw error;
|
|
217
246
|
}
|
|
218
247
|
}
|
|
@@ -258,24 +287,29 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
258
287
|
let driverCompleted = false;
|
|
259
288
|
let servingModel = req.model ?? "";
|
|
260
289
|
const metadata = selection.metadata;
|
|
261
|
-
const driverResult = () =>
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
290
|
+
const driverResult = () => {
|
|
291
|
+
const result = {
|
|
292
|
+
text,
|
|
293
|
+
tokenName: metadata.name,
|
|
294
|
+
usage,
|
|
295
|
+
durationMs: Date.now() - startedAt,
|
|
296
|
+
ttftMs: firstDeltaAt === void 0 ? null : firstDeltaAt - startedAt,
|
|
297
|
+
model: servingModel,
|
|
298
|
+
threadCoord: {
|
|
299
|
+
workerId: selection.tokenId,
|
|
300
|
+
threadId: req.promptCacheKey ?? "",
|
|
301
|
+
epoch: -1
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
if (servingModel !== req.model) result.requestedModel = req.model;
|
|
305
|
+
return result;
|
|
306
|
+
};
|
|
275
307
|
const clientEntry = this.acquireClient(selection);
|
|
276
308
|
try {
|
|
277
309
|
for await (const event of clientEntry.client.responses(requestOptions(req), req.abortSignal)) {
|
|
278
|
-
|
|
310
|
+
const itemId = event.type === "output-item" ? jsonString(event.item.id) : void 0;
|
|
311
|
+
const itemPhase = event.type === "output-item" ? jsonString(event.item.phase) : void 0;
|
|
312
|
+
if (req.stopAfterOutputMessage && event.type === "output-item" && event.item.type === "message" && itemId !== void 0 && itemPhase !== void 0) messagePhases.set(itemId, itemPhase);
|
|
279
313
|
if (event.type === "text-delta") {
|
|
280
314
|
if (outputMessageAccepted) continue;
|
|
281
315
|
if (req.stopAfterOutputMessage && event.itemId) {
|
|
@@ -286,24 +320,22 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
286
320
|
text += event.text;
|
|
287
321
|
onDelta?.(event.text);
|
|
288
322
|
} else if (event.type === "output-item" && event.completed && event.item.type === "message" && !outputMessageAccepted && req.stopAfterOutputMessage && Array.isArray(event.item.content)) {
|
|
289
|
-
const messageText = event.item.content.
|
|
290
|
-
|
|
323
|
+
const messageText = event.item.content.flatMap((part) => {
|
|
324
|
+
const partText = isJsonObject(part) && part.type === "output_text" ? jsonString(part.text) : void 0;
|
|
325
|
+
return partText === void 0 ? [] : [partText];
|
|
326
|
+
}).join("");
|
|
327
|
+
const phase = itemPhase;
|
|
291
328
|
if (messageText) outputMessageAccepted = req.stopAfterOutputMessage(messageText, phase);
|
|
292
|
-
if (
|
|
329
|
+
if (itemId !== void 0 && !streamedMessageIds.has(itemId) && (phase !== "commentary" || outputMessageAccepted) && messageText) {
|
|
293
330
|
firstDeltaAt ??= Date.now();
|
|
294
331
|
text += messageText;
|
|
295
332
|
onDelta?.(messageText);
|
|
296
|
-
streamedMessageIds.add(
|
|
333
|
+
streamedMessageIds.add(itemId);
|
|
297
334
|
}
|
|
298
335
|
} else if (event.type === "image") {
|
|
299
336
|
if (auto) throw new ImageGenerationError("incomplete", "Unexpected hosted image generation");
|
|
300
337
|
imageAttempted = true;
|
|
301
|
-
images.push(
|
|
302
|
-
data: event.base64,
|
|
303
|
-
mediaType: event.mimeType,
|
|
304
|
-
revisedPrompt: event.revisedPrompt ?? null,
|
|
305
|
-
...event.generation ? { generation: event.generation } : {}
|
|
306
|
-
});
|
|
338
|
+
images.push(generatedImageFrom(event));
|
|
307
339
|
} else if (event.type === "output-item" && event.item.type === "image_generation_call") {
|
|
308
340
|
if (auto) throw new ImageGenerationError("incomplete", "Unexpected hosted image generation");
|
|
309
341
|
imageAttempted = true;
|
|
@@ -312,14 +344,18 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
312
344
|
imageToolAttempted = true;
|
|
313
345
|
imageCallIds.add(event.item.call_id);
|
|
314
346
|
if (!event.completed) continue;
|
|
315
|
-
const id = event.item.call_id;
|
|
316
|
-
|
|
347
|
+
const id = jsonString(event.item.call_id);
|
|
348
|
+
const rawArguments = jsonString(event.item.arguments);
|
|
349
|
+
let decoded;
|
|
317
350
|
try {
|
|
318
|
-
|
|
351
|
+
if (rawArguments === void 0) throw new Error("missing arguments");
|
|
352
|
+
decoded = JSON.parse(rawArguments);
|
|
319
353
|
} catch {
|
|
320
354
|
throw new ImageGenerationError("incomplete", "Invalid image tool arguments");
|
|
321
355
|
}
|
|
322
|
-
|
|
356
|
+
const parsedArgs = ImageToolArgumentsSchema.safeParse(decoded);
|
|
357
|
+
if (!id || !parsedArgs.success) throw new ImageGenerationError("incomplete", "Invalid image tool arguments");
|
|
358
|
+
const args = parsedArgs.data;
|
|
323
359
|
const previous = imageCalls.get(id);
|
|
324
360
|
if (previous && (previous.prompt !== args.prompt || previous.transparent_background !== args.transparent_background || previous.num_last_images_to_include !== args.num_last_images_to_include)) throw new ImageGenerationError("incomplete", "Conflicting image tool calls");
|
|
325
361
|
imageCalls.set(id, {
|
|
@@ -341,12 +377,15 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
341
377
|
};
|
|
342
378
|
if (event.imageGeneration) {
|
|
343
379
|
const hostedImages = images.filter((image) => image.generation?.route === "codex-responses");
|
|
344
|
-
for (const [index, image] of hostedImages.entries())
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
380
|
+
for (const [index, image] of hostedImages.entries()) {
|
|
381
|
+
const generation = {
|
|
382
|
+
route: "codex-responses",
|
|
383
|
+
...image.generation
|
|
384
|
+
};
|
|
385
|
+
if (generation.model === void 0 && event.imageGeneration.model) generation.model = event.imageGeneration.model;
|
|
386
|
+
if (index === 0 && event.imageGeneration.usage) generation.usage = event.imageGeneration.usage;
|
|
387
|
+
image.generation = generation;
|
|
388
|
+
}
|
|
350
389
|
}
|
|
351
390
|
} else if (event.type === "error") {
|
|
352
391
|
if (req.imageGeneration) throw new ImageGenerationError("incomplete", event.error.message);
|
|
@@ -377,12 +416,7 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
377
416
|
output_format: "png",
|
|
378
417
|
background: args.transparent_background ? "transparent" : "opaque"
|
|
379
418
|
}
|
|
380
|
-
}, req.abortSignal)) if (event.type === "image") images.push(
|
|
381
|
-
data: event.base64,
|
|
382
|
-
mediaType: event.mimeType,
|
|
383
|
-
revisedPrompt: event.revisedPrompt ?? null,
|
|
384
|
-
...event.generation ? { generation: event.generation } : {}
|
|
385
|
-
});
|
|
419
|
+
}, req.abortSignal)) if (event.type === "image") images.push(generatedImageFrom(event));
|
|
386
420
|
else if (event.type === "completed") imageCompleted = true;
|
|
387
421
|
else if (event.type === "error") throw new ImageGenerationError("incomplete", event.error.message, { cause: event.error });
|
|
388
422
|
imageAttempted = true;
|
|
@@ -402,10 +436,9 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
402
436
|
} finally {
|
|
403
437
|
this.releaseClient(clientEntry);
|
|
404
438
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
};
|
|
439
|
+
const result = driverResult();
|
|
440
|
+
if (images.length) result.images = images;
|
|
441
|
+
return result;
|
|
409
442
|
}
|
|
410
443
|
/** 세대가 바뀐 client 는 사용 중인 요청이 끝난 뒤에 닫는다. */
|
|
411
444
|
acquireClient(selection) {
|
|
@@ -467,17 +500,21 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
467
500
|
}]));
|
|
468
501
|
}
|
|
469
502
|
}
|
|
470
|
-
const
|
|
503
|
+
const activeTokens = [...this.tokenMetadata.entries()].filter(([, token]) => token.active);
|
|
504
|
+
const checks = await Promise.all(activeTokens.map(async ([id, token]) => ({
|
|
471
505
|
id,
|
|
472
506
|
token,
|
|
473
507
|
eligible: await this.isQuotaEligible(id, token, signal)
|
|
474
508
|
})));
|
|
475
509
|
const eligible = new Set(checks.filter((c) => c.eligible).map((c) => c.id));
|
|
476
510
|
if (eligible.size === 0) {
|
|
477
|
-
const over = checks.
|
|
478
|
-
|
|
479
|
-
threshold:
|
|
480
|
-
|
|
511
|
+
const over = checks.flatMap((c) => {
|
|
512
|
+
const threshold = c.token.quotaThreshold;
|
|
513
|
+
return c.eligible || threshold === null || threshold === void 0 ? [] : [{
|
|
514
|
+
name: c.token.name,
|
|
515
|
+
threshold
|
|
516
|
+
}];
|
|
517
|
+
});
|
|
481
518
|
if (over.length) {
|
|
482
519
|
logger.warn("quota_threshold gate: all_exceeded", {
|
|
483
520
|
provider: "openai",
|
|
@@ -530,7 +567,7 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
530
567
|
credentials: token.credentials,
|
|
531
568
|
refreshCredentials: () => this.refreshCredentials(tokenId),
|
|
532
569
|
fetch: this.fetchImpl,
|
|
533
|
-
|
|
570
|
+
signal
|
|
534
571
|
});
|
|
535
572
|
if (result.kind === "lookup_failed") throw new Error(result.reason);
|
|
536
573
|
if (!result.raw) throw new Error("OpenAI quota response missing raw rate limits");
|
|
@@ -620,4 +657,4 @@ var OpenAIDispatcher = class OpenAIDispatcher {
|
|
|
620
657
|
//#endregion
|
|
621
658
|
export { ImageGenerationError, OpenAIDispatcher };
|
|
622
659
|
|
|
623
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLWRpc3BhdGNoZXIuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9vcGVuYWkvb3BlbmFpLWRpc3BhdGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcblxuaW1wb3J0IHsgUXVvdGFUaHJlc2hvbGRFeGNlZWRlZEVycm9yIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLnR5cGVzXCI7XG5pbXBvcnQgeyBUb2tlbk1vZGVsIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLm1vZGVsXCI7XG5pbXBvcnQgeyB0eXBlIE9wZW5BSUNyZWRlbnRpYWxzIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLnR5cGVzXCI7XG5pbXBvcnQgeyByZXNvbHZlT3BlbkFJRWZmb3J0IH0gZnJvbSBcIi4uL2NvbW1vbi9lZmZvcnRcIjtcbmltcG9ydCB7XG4gIHR5cGUgR2VuZXJhdGVSZXF1ZXN0LFxuICB0eXBlIEdlbmVyYXRlUmVzdWx0LFxuICB0eXBlIEdlbmVyYXRlU3RyZWFtQ2FsbGJhY2tzLFxuICB0eXBlIEdlbmVyYXRlZEltYWdlLFxuICB0eXBlIFByb3ZpZGVyRGlzcGF0Y2hlcixcbn0gZnJvbSBcIi4uL2NvbW1vbi9wcm92aWRlci1kaXNwYXRjaGVyXCI7XG5pbXBvcnQgeyBTbW9vdGhXZWlnaHRlZFJvdW5kUm9iaW4gfSBmcm9tIFwiLi4vY29tbW9uL3Ntb290aC13ZWlnaHRlZC1yb3VuZC1yb2JpblwiO1xuaW1wb3J0IHsgVGhpbmtpbmdWYWxpZGF0aW9uRXJyb3IgfSBmcm9tIFwiLi4vY29tbW9uL3RoaW5raW5nXCI7XG5pbXBvcnQge1xuICBpbWFnZU1pbWVUeXBlLFxuICB0eXBlIEpzb25WYWx1ZSxcbiAgdHlwZSBPcGVuQUlSZXNwb25zZUl0ZW0sXG4gIHR5cGUgT3BlbkFJUmVzcG9uc2VzT3B0aW9ucyxcbn0gZnJvbSBcIi4vb3BlbmFpLWJhY2tlbmQtcHJvdG9jb2xcIjtcbmltcG9ydCB7IE9wZW5BSURpcmVjdENsaWVudCwgdHlwZSBPcGVuQUlEaXJlY3RDbGllbnRPcHRpb25zIH0gZnJvbSBcIi4vb3BlbmFpLWRpcmVjdC1jbGllbnRcIjtcbmltcG9ydCB7IHJlYWRPcGVuQUlRdW90YVVzYWdlLCB0eXBlIE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YSB9IGZyb20gXCIuL29wZW5haS1xdW90YVwiO1xuaW1wb3J0IHsgaGFuZGxlQ2hhdGdwdEF1dGhUb2tlbnNSZWZyZXNoIH0gZnJvbSBcIi4vb3BlbmFpLXJlZnJlc2hcIjtcbmltcG9ydCB7IHR5cGUgT3BlbkFJVHJhbnNwb3J0S2luZCwgcmVzb2x2ZU9wZW5BSVRyYW5zcG9ydEtpbmQgfSBmcm9tIFwiLi9vcGVuYWktdHJhbnNwb3J0LWNvbmZpZ1wiO1xuXG5jb25zdCBsb2dnZXIgPSBnZXRMb2dnZXIoW1wicWdyaWRcIiwgXCJvcGVuYWktZGlzcGF0Y2hlclwiXSk7XG4vLyBWZXJpZmllZCB3aXRoIHRoZSBzdWJzY3JpcHRpb24gUmVzcG9uc2VzIGJhY2tlbmQ7IHB1YmxpYyBBUEkgc3VwcG9ydCBpcyBub3Qgc3VmZmljaWVudC5cbmNvbnN0IFRISU5LSU5HX09GRl9NT0RFTFMgPSBuZXcgU2V0KFtcbiAgXCJncHQtNi1zb2xcIixcbiAgXCJncHQtNi1sdW5hXCIsXG4gIFwiZ3B0LTUuNi1zb2xcIixcbiAgXCJncHQtNS42LXRlcnJhXCIsXG4gIFwiZ3B0LTUuNi1sdW5hXCIsXG4gIFwiZ3B0LTUuNVwiLFxuXSk7XG5jb25zdCBERUZBVUxUX1JFUVVFU1RfVElNRU9VVF9NUyA9IDYwMF8wMDA7XG5jb25zdCBJTUFHRV9UT09MID0gXCJnZW5lcmF0ZV9pbWFnZVwiO1xuXG50eXBlIEltYWdlVG9vbEFyZ3VtZW50cyA9IHtcbiAgcHJvbXB0OiBzdHJpbmc7XG4gIHRyYW5zcGFyZW50X2JhY2tncm91bmQ6IGJvb2xlYW47XG4gIG51bV9sYXN0X2ltYWdlc190b19pbmNsdWRlOiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBJbWFnZUZhaWx1cmVLaW5kID0gXCJnYXRlXCIgfCBcIm5vdF9jYWxsZWRcIiB8IFwiaW5jb21wbGV0ZVwiO1xuXG5leHBvcnQgY2xhc3MgSW1hZ2VHZW5lcmF0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbXBsZXRlZERyaXZlcj86IEdlbmVyYXRlUmVzdWx0O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHJlYWRvbmx5IGtpbmQ6IEltYWdlRmFpbHVyZUtpbmQsXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBFcnJvck9wdGlvbnMsXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UsIG9wdGlvbnMpO1xuICAgIHRoaXMubmFtZSA9IFwiSW1hZ2VHZW5lcmF0aW9uRXJyb3JcIjtcbiAgfVxufVxuXG50eXBlIFRva2VuTWV0YWRhdGEgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzO1xuICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGw7XG4gIHdlaWdodDogbnVtYmVyO1xuICBhY3RpdmU6IGJvb2xlYW47XG4gIGdlbmVyYXRpb246IG51bWJlcjtcbn07XG5cbnR5cGUgVG9rZW5TZWxlY3Rpb24gPSB7IHRva2VuSWQ6IG51bWJlcjsgbWV0YWRhdGE6IFRva2VuTWV0YWRhdGEgfTtcblxuZXhwb3J0IHR5cGUgT3BlbkFJRGlyZWN0Q2xpZW50RmFjdG9yeSA9IChcbiAgb3B0aW9uczogT3BlbkFJRGlyZWN0Q2xpZW50T3B0aW9ucyxcbiAgdG9rZW5JZDogbnVtYmVyLFxuKSA9PiBQaWNrPE9wZW5BSURpcmVjdENsaWVudCwgXCJyZXNwb25zZXNcIj4gJiB7IGNsb3NlPzogKCkgPT4gdm9pZCB9O1xuXG50eXBlIENsaWVudEVudHJ5ID0ge1xuICBnZW5lcmF0aW9uOiBudW1iZXI7XG4gIGNsaWVudDogUGljazxPcGVuQUlEaXJlY3RDbGllbnQsIFwicmVzcG9uc2VzXCI+ICYgeyBjbG9zZT86ICgpID0+IHZvaWQgfTtcbiAgaW5GbGlnaHQ6IG51bWJlcjtcbiAgcmV0aXJlZDogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlbkFJRGlzcGF0Y2hlckRlcGVuZGVuY2llcyB7XG4gIGNsaWVudEZhY3Rvcnk/OiBPcGVuQUlEaXJlY3RDbGllbnRGYWN0b3J5O1xuICBmZXRjaD86IHR5cGVvZiBmZXRjaDtcbn1cblxuZnVuY3Rpb24gYWJvcnRFcnJvcihzaWduYWw6IEFib3J0U2lnbmFsKTogRXJyb3Ige1xuICBjb25zdCByZWFzb24gPSBzaWduYWwucmVhc29uO1xuICByZXR1cm4gcmVhc29uIGluc3RhbmNlb2YgRXJyb3IgPyByZWFzb24gOiBuZXcgRE9NRXhjZXB0aW9uKFwiQWJvcnRlZFwiLCBcIkFib3J0RXJyb3JcIik7XG59XG5cbmZ1bmN0aW9uIGFjdGl2ZVNpZ25hbChzaWduYWw/OiBBYm9ydFNpZ25hbCwgdGltZW91dE1zPzogbnVtYmVyKTogQWJvcnRTaWduYWwge1xuICBjb25zdCB0aW1lb3V0ID0gQWJvcnRTaWduYWwudGltZW91dCh0aW1lb3V0TXMgPz8gREVGQVVMVF9SRVFVRVNUX1RJTUVPVVRfTVMpO1xuICByZXR1cm4gc2lnbmFsID8gQWJvcnRTaWduYWwuYW55KFtzaWduYWwsIHRpbWVvdXRdKSA6IHRpbWVvdXQ7XG59XG5cbmZ1bmN0aW9uIHF1b3RhTWVzc2FnZShlbnRyaWVzOiBBcnJheTx7IG5hbWU6IHN0cmluZzsgdGhyZXNob2xkOiBudW1iZXIgfT4pOiBzdHJpbmcge1xuICBjb25zdCBkZXRhaWwgPSBlbnRyaWVzLm1hcCgoZSkgPT4gYCR7ZS5uYW1lfSAodGhyZXNob2xkICR7ZS50aHJlc2hvbGR9JSlgKS5qb2luKFwiLCBcIik7XG4gIHJldHVybiBkZXRhaWxcbiAgICA/IGBBbGwgb3BlbmFpIHRva2VucyBleGNlZWRlZCBxdW90YSB0aHJlc2hvbGQ6ICR7ZGV0YWlsfWBcbiAgICA6IFwiQWxsIG9wZW5haSB0b2tlbnMgZXhjZWVkZWQgcXVvdGEgdGhyZXNob2xkXCI7XG59XG5cbmZ1bmN0aW9uIGlucHV0SXRlbXMocmVxOiBHZW5lcmF0ZVJlcXVlc3QpOiBPcGVuQUlSZXNwb25zZUl0ZW1bXSB7XG4gIGNvbnN0IGhpc3RvcnkgPSAocmVxLmNvbGRIaXN0b3J5ID8/IFtdKSBhcyBPcGVuQUlSZXNwb25zZUl0ZW1bXTtcbiAgY29uc3QgY29udGVudDogT3BlbkFJUmVzcG9uc2VJdGVtW10gPSByZXEuY29sZElucHV0Lm1hcCgoaW5wdXQpID0+IHtcbiAgICBpZiAoaW5wdXQudHlwZSA9PT0gXCJ0ZXh0XCIpIHJldHVybiB7IHR5cGU6IFwiaW5wdXRfdGV4dFwiLCB0ZXh0OiBpbnB1dC50ZXh0IH07XG4gICAgaWYgKGlucHV0LnR5cGUgPT09IFwiaW1hZ2VcIikgcmV0dXJuIHsgdHlwZTogXCJpbnB1dF9pbWFnZVwiLCBpbWFnZV91cmw6IGlucHV0LnVybCB9O1xuICAgIGlmIChpbnB1dC50eXBlID09PSBcImxvY2FsSW1hZ2VcIikgcmV0dXJuIHsgdHlwZTogXCJpbnB1dF9pbWFnZVwiLCBpbWFnZV91cmw6IGlucHV0LnBhdGggfTtcbiAgICByZXR1cm4geyB0eXBlOiBcImlucHV0X3RleHRcIiwgdGV4dDogYCR7aW5wdXQubmFtZX06ICR7aW5wdXQucGF0aH1gIH07XG4gIH0pO1xuICByZXR1cm4gWy4uLmhpc3RvcnksIHsgdHlwZTogXCJtZXNzYWdlXCIsIHJvbGU6IFwidXNlclwiLCBjb250ZW50IH1dO1xufVxuXG5mdW5jdGlvbiBpbWFnZVJlZmVyZW5jZXMocmVxOiBHZW5lcmF0ZVJlcXVlc3QpOiBPcGVuQUlSZXNwb25zZUl0ZW1bXSB7XG4gIHJldHVybiBpbnB1dEl0ZW1zKHJlcSkuZmxhdE1hcCgoaXRlbSkgPT4ge1xuICAgIGlmIChpdGVtLnR5cGUgPT09IFwiaW1hZ2VfZ2VuZXJhdGlvbl9jYWxsXCIgJiYgdHlwZW9mIGl0ZW0ucmVzdWx0ID09PSBcInN0cmluZ1wiKSB7XG4gICAgICByZXR1cm4gW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogXCJpbnB1dF9pbWFnZVwiLFxuICAgICAgICAgIGltYWdlX3VybDogYGRhdGE6JHtpbWFnZU1pbWVUeXBlKGl0ZW0ucmVzdWx0LCBpdGVtLm91dHB1dF9mb3JtYXQpfTtiYXNlNjQsJHtpdGVtLnJlc3VsdH1gLFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICB9XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGl0ZW0uY29udGVudCkpIHJldHVybiBbXTtcbiAgICByZXR1cm4gaXRlbS5jb250ZW50LmZpbHRlcihcbiAgICAgIChwYXJ0KTogcGFydCBpcyBPcGVuQUlSZXNwb25zZUl0ZW0gPT5cbiAgICAgICAgcGFydCAhPT0gbnVsbCAmJlxuICAgICAgICB0eXBlb2YgcGFydCA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgICAocGFydC50eXBlID09PSBcImlucHV0X2ltYWdlXCIgfHwgcGFydC50eXBlID09PSBcImltYWdlX3VybFwiKSxcbiAgICApO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gYXNSZWFzb25pbmcocmVxOiBHZW5lcmF0ZVJlcXVlc3QpOiBPcGVuQUlSZXNwb25zZXNPcHRpb25zW1wicmVhc29uaW5nXCJdIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHJlcS50aGlua2luZyA9PT0gZmFsc2UpIHJldHVybiB7IGVmZm9ydDogXCJub25lXCIgfTtcbiAgY29uc3Qgc3VtbWFyeSA9XG4gICAgcmVxLnJlYXNvbmluZ1N1bW1hcnkgJiYgcmVxLnJlYXNvbmluZ1N1bW1hcnkgIT09IFwibm9uZVwiID8gcmVxLnJlYXNvbmluZ1N1bW1hcnkgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IGVmZm9ydCA9XG4gICAgcmVzb2x2ZU9wZW5BSUVmZm9ydChyZXEubW9kZWwgPz8gXCJcIiwgcmVxLmVmZm9ydCkgPz8gKHJlcS50aGlua2luZyA9PT0gdHJ1ZSA/IFwibG93XCIgOiB1bmRlZmluZWQpO1xuICBpZiAoIWVmZm9ydCAmJiAhc3VtbWFyeSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgcmV0dXJuIHtcbiAgICAuLi4oZWZmb3J0ID8geyBlZmZvcnQgfSA6IHt9KSxcbiAgICAuLi4oc3VtbWFyeVxuICAgICAgPyB7XG4gICAgICAgICAgc3VtbWFyeTogc3VtbWFyeSBhcyBOb25OdWxsYWJsZTxPcGVuQUlSZXNwb25zZXNPcHRpb25zW1wicmVhc29uaW5nXCJdPltcInN1bW1hcnlcIl0sXG4gICAgICAgIH1cbiAgICAgIDoge30pLFxuICB9O1xufVxuXG5mdW5jdGlvbiByZXF1ZXN0T3B0aW9ucyhyZXE6IEdlbmVyYXRlUmVxdWVzdCk6IE9wZW5BSVJlc3BvbnNlc09wdGlvbnMge1xuICBjb25zdCB7IG91dHB1dEZvcm1hdCwgLi4uaW1hZ2VDb250cm9scyB9ID0gcmVxLmltYWdlR2VuZXJhdGlvbk9wdGlvbnMgPz8ge307XG4gIGNvbnN0IGF1dG8gPSByZXEuaW1hZ2VHZW5lcmF0aW9uID09PSBcImF1dG9cIjtcbiAgaWYgKGF1dG8gJiYgcmVxLm91dHB1dFNjaGVtYSkge1xuICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcbiAgICAgIFwiZ2F0ZVwiLFxuICAgICAgXCJBdXRvbWF0aWMgaW1hZ2UgZ2VuZXJhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IHN0cnVjdHVyZWQgb3V0cHV0IG9yIGV4dGVybmFsIHRvb2xzXCIsXG4gICAgKTtcbiAgfVxuICBpZiAoYXV0byAmJiBvdXRwdXRGb3JtYXQgJiYgb3V0cHV0Rm9ybWF0ICE9PSBcInBuZ1wiKSB7XG4gICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiZ2F0ZVwiLCBcIkF1dG9tYXRpYyBpbWFnZSBnZW5lcmF0aW9uIG9ubHkgc3VwcG9ydHMgUE5HIG91dHB1dFwiKTtcbiAgfVxuICByZXR1cm4ge1xuICAgIG1vZGVsOiByZXEubW9kZWwgPz8gXCJcIixcbiAgICAuLi4ocmVxLnN5c3RlbVByb21wdCA/IHsgaW5zdHJ1Y3Rpb25zOiByZXEuc3lzdGVtUHJvbXB0IH0gOiB7fSksXG4gICAgLi4uKGF1dG9cbiAgICAgID8ge1xuICAgICAgICAgIGluc3RydWN0aW9uczogW1xuICAgICAgICAgICAgcmVxLnN5c3RlbVByb21wdCxcbiAgICAgICAgICAgIFwiVXNlIGdlbmVyYXRlX2ltYWdlIHdoZW4gaW1hZ2UgZ2VuZXJhdGlvbiBvciBlZGl0aW5nIGlzIG5lZWRlZDsgb3RoZXJ3aXNlIHJlcGx5IHdpdGggdGV4dC4gQ2FsbCBpdCBhdCBtb3N0IG9uY2UgcGVyIHJlc3BvbnNlLiBTdXBwbHkgYSBjb21wbGV0ZSwgc2VsZi1jb250YWluZWQgcHJvbXB0IHdpdGggYWxsIHJlbGV2YW50IGNvbnZlcnNhdGlvbiBpbnN0cnVjdGlvbnMuIFNldCB0cmFuc3BhcmVudF9iYWNrZ3JvdW5kIHRvIHRydWUgb25seSB3aGVuIGEgdHJhbnNwYXJlbnQgYmFja2dyb3VuZCBpcyByZXF1ZXN0ZWQuIFNldCBudW1fbGFzdF9pbWFnZXNfdG9faW5jbHVkZSB0byAwIGZvciBhIG5ldyBpbWFnZSB3aXRob3V0IHJlZmVyZW5jZXMuIEZvciBlZGl0aW5nIG9yIHJlZmVyZW5jZS1iYXNlZCBnZW5lcmF0aW9uLCBjaG9vc2UgdGhlIHNtYWxsZXN0IG51bWJlciBvZiByZWNlbnQgY29udmVyc2F0aW9uIGltYWdlcyB0aGF0IGluY2x1ZGVzIGFsbCBuZWVkZWQgcmVmZXJlbmNlcywgYXQgbW9zdCA1LiBSZWZlcmVuY2VzIHJldGFpbiB0aGVpciBjaHJvbm9sb2dpY2FsIG9yZGVyLiBEbyBub3Qgc2VsZWN0IGltYWdlcyBmb3IgYW4gdW5yZWxhdGVkIG5ldyByZXF1ZXN0LlwiLFxuICAgICAgICAgIF1cbiAgICAgICAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgICAgICAgIC5qb2luKFwiXFxuXFxuXCIpLFxuICAgICAgICAgIHBhcmFsbGVsVG9vbENhbGxzOiBmYWxzZSxcbiAgICAgICAgICB0b29sczogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0eXBlOiBcImZ1bmN0aW9uXCIsXG4gICAgICAgICAgICAgIG5hbWU6IElNQUdFX1RPT0wsXG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgICAgICAgIFwiR2VuZXJhdGUgb3IgZWRpdCBhbiBpbWFnZSwgb3B0aW9uYWxseSB3aXRoIGEgdHJhbnNwYXJlbnQgYmFja2dyb3VuZCBvciByZWNlbnQgY29udmVyc2F0aW9uIGltYWdlcyBhcyByZWZlcmVuY2VzLlwiLFxuICAgICAgICAgICAgICAvLyBBc3RyYSdzIHN1YnNjcmlwdGlvbiBiYWNrZW5kIHJlamVjdHMgc3RyaWN0IHRvb2xzOyB2YWxpZGF0ZSBhcmd1bWVudHMgbG9jYWxseS5cbiAgICAgICAgICAgICAgc3RyaWN0OiBmYWxzZSxcbiAgICAgICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgICAgcHJvbXB0OiB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICAgICAgICAgIG1pbkxlbmd0aDogMSxcbiAgICAgICAgICAgICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICAgICAgICAgICAgXCJDb21wbGV0ZSwgc2VsZi1jb250YWluZWQgaW5zdHJ1Y3Rpb25zIGZvciB0aGUgaW1hZ2UgZ2VuZXJhdGlvbiBvciBlZGl0LlwiLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIHRyYW5zcGFyZW50X2JhY2tncm91bmQ6IHsgdHlwZTogXCJib29sZWFuXCIgfSxcbiAgICAgICAgICAgICAgICAgIG51bV9sYXN0X2ltYWdlc190b19pbmNsdWRlOiB7IHR5cGU6IFwiaW50ZWdlclwiLCBtaW5pbXVtOiAwLCBtYXhpbXVtOiA1IH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICByZXF1aXJlZDogW1wicHJvbXB0XCIsIFwidHJhbnNwYXJlbnRfYmFja2dyb3VuZFwiLCBcIm51bV9sYXN0X2ltYWdlc190b19pbmNsdWRlXCJdLFxuICAgICAgICAgICAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfVxuICAgICAgOiB7fSksXG4gICAgaGlzdG9yeTogaW5wdXRJdGVtcyhyZXEpLFxuICAgIC4uLihhc1JlYXNvbmluZyhyZXEpID8geyByZWFzb25pbmc6IGFzUmVhc29uaW5nKHJlcSkgfSA6IHt9KSxcbiAgICAuLi4ocmVxLnZlcmJvc2l0eSA/IHsgdmVyYm9zaXR5OiByZXEudmVyYm9zaXR5IGFzIE9wZW5BSVJlc3BvbnNlc09wdGlvbnNbXCJ2ZXJib3NpdHlcIl0gfSA6IHt9KSxcbiAgICAuLi4ocmVxLnNlcnZpY2VUaWVyXG4gICAgICA/IHsgc2VydmljZVRpZXI6IHJlcS5zZXJ2aWNlVGllciA9PT0gXCJmYXN0XCIgPyBcInByaW9yaXR5XCIgOiByZXEuc2VydmljZVRpZXIgfVxuICAgICAgOiB7fSksXG4gICAgLi4uKHJlcS5wcm9tcHRDYWNoZUtleSA/IHsgcHJvbXB0Q2FjaGVLZXk6IHJlcS5wcm9tcHRDYWNoZUtleSB9IDoge30pLFxuICAgIC4uLihyZXEub3V0cHV0U2NoZW1hID8geyBvdXRwdXRTY2hlbWE6IHsgc2NoZW1hOiByZXEub3V0cHV0U2NoZW1hIGFzIEpzb25WYWx1ZSB9IH0gOiB7fSksXG4gICAgLi4uKHJlcS5pbWFnZUdlbmVyYXRpb24gJiYgIWF1dG9cbiAgICAgID8ge1xuICAgICAgICAgIGltYWdlR2VuZXJhdGlvbjogcmVxLmltYWdlR2VuZXJhdGlvbk9wdGlvbnNcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIC4uLmltYWdlQ29udHJvbHMsXG4gICAgICAgICAgICAgICAgLi4uKG91dHB1dEZvcm1hdCA/IHsgb3V0cHV0X2Zvcm1hdDogb3V0cHV0Rm9ybWF0IH0gOiB7fSksXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDogdHJ1ZSxcbiAgICAgICAgfVxuICAgICAgOiB7fSksXG4gIH07XG59XG5cbi8vIHF1b3Rh7JmAIGNhY2hlIGFmZmluaXR566GcIO2GoO2BsOydhCDshKDtg53tlbQgSFRUUFMvV1ProZwg7KCE7Iah7ZWc64ukLiDroZzsu6wg64+Z7Iuc7ISxIOygnO2VnOydgCDsl4bri6QuXG5leHBvcnQgY2xhc3MgT3BlbkFJRGlzcGF0Y2hlciBpbXBsZW1lbnRzIFByb3ZpZGVyRGlzcGF0Y2hlciB7XG4gIHJlYWRvbmx5IHRva2VuTWV0YWRhdGEgPSBuZXcgTWFwPG51bWJlciwgVG9rZW5NZXRhZGF0YT4oKTtcbiAgcmVhZG9ubHkgdHJhbnNwb3J0S2luZDogT3BlbkFJVHJhbnNwb3J0S2luZDtcbiAgcmVhZG9ubHkgcmF0ZUxpbWl0c0NhY2hlID0gbmV3IE1hcDxudW1iZXIsIE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YSAmIHsgZ2VuZXJhdGlvbjogbnVtYmVyIH0+KCk7XG4gIHJlYWRvbmx5IHBlbmRpbmdSYXRlTGltaXRzID0gbmV3IE1hcDxcbiAgICBudW1iZXIsXG4gICAgeyB0b2tlbjogVG9rZW5NZXRhZGF0YTsgZ2VuZXJhdGlvbjogbnVtYmVyOyBwcm9taXNlOiBQcm9taXNlPE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YT4gfVxuICA+KCk7XG4gIHJlYWRvbmx5IGNsaWVudHMgPSBuZXcgTWFwPG51bWJlciwgQ2xpZW50RW50cnk+KCk7XG4gIHJlYWRvbmx5IHJldGlyZWRDbGllbnRzID0gbmV3IFNldDxDbGllbnRFbnRyeT4oKTtcbiAgc3RhdGljIHJlYWRvbmx5IFJBVEVfTElNSVRTX0NBQ0hFX1RUTCA9IDYwXzAwMDtcblxuICByZWFkb25seSBzZWxlY3RvciA9IG5ldyBTbW9vdGhXZWlnaHRlZFJvdW5kUm9iaW4oKTtcbiAgcmVhZG9ubHkgY2xpZW50RmFjdG9yeTogT3BlbkFJRGlyZWN0Q2xpZW50RmFjdG9yeTtcbiAgcmVhZG9ubHkgZmV0Y2hJbXBsOiB0eXBlb2YgZmV0Y2g7XG4gIHJlYWRvbmx5IHF1b3RhQmxvY2tlZCA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICBpbkZsaWdodCA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgdHJhbnNwb3J0S2luZDogT3BlbkFJVHJhbnNwb3J0S2luZCA9IHJlc29sdmVPcGVuQUlUcmFuc3BvcnRLaW5kKCksXG4gICAgZGVwZW5kZW5jaWVzOiBPcGVuQUlEaXNwYXRjaGVyRGVwZW5kZW5jaWVzID0ge30sXG4gICkge1xuICAgIHRoaXMudHJhbnNwb3J0S2luZCA9IHRyYW5zcG9ydEtpbmQ7XG4gICAgdGhpcy5jbGllbnRGYWN0b3J5ID1cbiAgICAgIGRlcGVuZGVuY2llcy5jbGllbnRGYWN0b3J5ID8/ICgob3B0aW9ucykgPT4gbmV3IE9wZW5BSURpcmVjdENsaWVudChvcHRpb25zKSk7XG4gICAgdGhpcy5mZXRjaEltcGwgPSBkZXBlbmRlbmNpZXMuZmV0Y2ggPz8gZmV0Y2g7XG4gIH1cblxuICBhc3luYyBzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IHJvd3MgfSA9IGF3YWl0IFRva2VuTW9kZWwuZmluZE1hbnkoXCJBXCIpO1xuICAgIHJvd3NcbiAgICAgIC5maWx0ZXIoKHJvdykgPT4gcm93LnByb3ZpZGVyID09PSBcIm9wZW5haVwiKVxuICAgICAgLmZvckVhY2goKHJvdykgPT4ge1xuICAgICAgICB0aGlzLnNldFRva2VuKFxuICAgICAgICAgIHJvdy5pZCxcbiAgICAgICAgICByb3cubmFtZSxcbiAgICAgICAgICByb3cuY3JlZGVudGlhbHMgYXMgT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgICAgICAgcm93LnF1b3RhX3RocmVzaG9sZCxcbiAgICAgICAgICByb3cud2VpZ2h0LFxuICAgICAgICAgIHJvdy5hY3RpdmUsXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICBsb2dnZXIuaW5mbyhgc3RhcnRlZCBkaXJlY3QgT3BlbkFJIHJ1bnRpbWUgd2l0aCAke3RoaXMudG9rZW5NZXRhZGF0YS5zaXplfSB0b2tlbnNgKTtcbiAgfVxuXG4gIGFzeW5jIHN0b3AoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5jbGllbnRzLmZvckVhY2goKHsgY2xpZW50IH0pID0+IGNsaWVudC5jbG9zZT8uKCkpO1xuICAgIHRoaXMuY2xpZW50cy5jbGVhcigpO1xuICAgIHRoaXMucmV0aXJlZENsaWVudHMuZm9yRWFjaCgoZW50cnkpID0+IGVudHJ5LmNsaWVudC5jbG9zZT8uKCkpO1xuICAgIHRoaXMucmV0aXJlZENsaWVudHMuY2xlYXIoKTtcbiAgICB0aGlzLnRva2VuTWV0YWRhdGEuY2xlYXIoKTtcbiAgICB0aGlzLnJhdGVMaW1pdHNDYWNoZS5jbGVhcigpO1xuICAgIHRoaXMucXVvdGFCbG9ja2VkLmNsZWFyKCk7XG4gICAgdGhpcy5zZWxlY3Rvci5yZXNldFNjb3JlcygpO1xuICB9XG5cbiAgYXN5bmMgb25Ub2tlbkFkZGVkKFxuICAgIGlkOiBudW1iZXIsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscyxcbiAgICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGwsXG4gICAgd2VpZ2h0ID0gMSxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5zZXRUb2tlbihpZCwgbmFtZSwgY3JlZGVudGlhbHMsIHF1b3RhVGhyZXNob2xkLCB3ZWlnaHQsIHRydWUpO1xuICB9XG5cbiAgYXN5bmMgb25Ub2tlblVwZGF0ZWQoXG4gICAgaWQ6IG51bWJlcixcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgIHF1b3RhVGhyZXNob2xkPzogbnVtYmVyIHwgbnVsbCxcbiAgICB3ZWlnaHQgPSAxLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBvbGQgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICB0aGlzLnNldFRva2VuKGlkLCBuYW1lLCBjcmVkZW50aWFscywgcXVvdGFUaHJlc2hvbGQsIHdlaWdodCwgb2xkPy5hY3RpdmUgPz8gdHJ1ZSk7XG4gIH1cblxuICBhc3luYyBvblRva2VuUmVtb3ZlZChpZDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5yZXRpcmVDbGllbnQoaWQpO1xuICAgIHRoaXMudG9rZW5NZXRhZGF0YS5kZWxldGUoaWQpO1xuICAgIHRoaXMuc2VsZWN0b3IucmVtb3ZlVG9rZW4oaWQpO1xuICAgIHRoaXMuaW52YWxpZGF0ZVJhdGVMaW1pdHNDYWNoZShpZCk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWQuZGVsZXRlKGlkKTtcbiAgfVxuXG4gIG9uVG9rZW5EZWFjdGl2YXRlZChpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICBpZiAodG9rZW4pIHRva2VuLmFjdGl2ZSA9IGZhbHNlO1xuICAgIHRoaXMuc2VsZWN0b3IucmVzZXRTY29yZXMoKTtcbiAgfVxuXG4gIG9uVG9rZW5BY3RpdmF0ZWQoaWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHRva2VuID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldChpZCk7XG4gICAgaWYgKHRva2VuKSB0b2tlbi5hY3RpdmUgPSB0cnVlO1xuICAgIHRoaXMuc2VsZWN0b3IucmVzZXRTY29yZXMoKTtcbiAgfVxuXG4gIGFzeW5jIHJlcGxhY2VUb2tlbnMoXG4gICAgcm93czogQXJyYXk8e1xuICAgICAgaWQ6IG51bWJlcjtcbiAgICAgIG5hbWU6IHN0cmluZztcbiAgICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscztcbiAgICAgIHF1b3RhVGhyZXNob2xkPzogbnVtYmVyIHwgbnVsbDtcbiAgICAgIHdlaWdodDogbnVtYmVyO1xuICAgIH0+LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBpZHMgPSBuZXcgU2V0KHJvd3MubWFwKChyKSA9PiByLmlkKSk7XG4gICAgZm9yIChjb25zdCBpZCBvZiB0aGlzLnRva2VuTWV0YWRhdGEua2V5cygpKSBpZiAoIWlkcy5oYXMoaWQpKSBhd2FpdCB0aGlzLm9uVG9rZW5SZW1vdmVkKGlkKTtcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKVxuICAgICAgYXdhaXQgdGhpcy5vblRva2VuVXBkYXRlZChyb3cuaWQsIHJvdy5uYW1lLCByb3cuY3JlZGVudGlhbHMsIHJvdy5xdW90YVRocmVzaG9sZCwgcm93LndlaWdodCk7XG4gIH1cblxuICBhc3luYyBnZW5lcmF0ZShyZXE6IEdlbmVyYXRlUmVxdWVzdCk6IFByb21pc2U8R2VuZXJhdGVSZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5ydW4ocmVxKTtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlU3RyZWFtKHJlcTogR2VuZXJhdGVSZXF1ZXN0LCBjYjogR2VuZXJhdGVTdHJlYW1DYWxsYmFja3MpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAocmVxLmltYWdlR2VuZXJhdGlvbilcbiAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcbiAgICAgICAgXCJnYXRlXCIsXG4gICAgICAgIFwiaW1hZ2UgZ2VuZXJhdGlvbiBpcyBub3Qgc3VwcG9ydGVkIG9uIHRoZSBzdHJlYW1pbmcgcGF0aFwiLFxuICAgICAgKTtcbiAgICB0cnkge1xuICAgICAgY2Iub25Db21wbGV0ZShhd2FpdCB0aGlzLnJ1bihyZXEsIGNiLm9uRGVsdGEpKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY2Iub25FcnJvcihlcnJvciBhcyBFcnJvcik7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBhc3luYyBydW4ocmVxOiBHZW5lcmF0ZVJlcXVlc3QsIG9uRGVsdGE/OiAodGV4dDogc3RyaW5nKSA9PiB2b2lkKTogUHJvbWlzZTxHZW5lcmF0ZVJlc3VsdD4ge1xuICAgIGlmIChyZXEudGhpbmtpbmcgPT09IGZhbHNlKSB7XG4gICAgICBjb25zdCBtb2RlbCA9IHJlcS5tb2RlbCA/PyBcIlwiO1xuICAgICAgaWYgKCFUSElOS0lOR19PRkZfTU9ERUxTLmhhcyhtb2RlbCkpIHtcbiAgICAgICAgY29uc3QgcmVhc29uID1cbiAgICAgICAgICBtb2RlbCA9PT0gXCJncHQtNi1hc3RyYVwiIHx8IG1vZGVsID09PSBcImdwdC02LjEtc29sXCJcbiAgICAgICAgICAgID8gXCJ0aGUgc3Vic2NyaXB0aW9uIGJhY2tlbmQgcmVxdWlyZXMgdGhpbmtpbmdcIlxuICAgICAgICAgICAgOiBcInRoaW5raW5nLW9mZiBzdXBwb3J0IGhhcyBub3QgYmVlbiB2ZXJpZmllZCBvbiB0aGUgc3Vic2NyaXB0aW9uIGJhY2tlbmRcIjtcbiAgICAgICAgdGhyb3cgbmV3IFRoaW5raW5nVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgIGB0aGlua2luZzpmYWxzZSBpcyB1bmF2YWlsYWJsZSBmb3IgT3BlbkFJIG1vZGVsICR7bW9kZWwgfHwgXCI8ZGVmYXVsdD5cIn06ICR7cmVhc29ufWAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIGNvbnN0IHNpZ25hbCA9IGFjdGl2ZVNpZ25hbChyZXEuYWJvcnRTaWduYWwsIHJlcS50aW1lb3V0TXMpO1xuICAgIGlmIChzaWduYWwuYWJvcnRlZCkgdGhyb3cgYWJvcnRFcnJvcihzaWduYWwpO1xuICAgIGNvbnN0IHNlbGVjdGlvbiA9IGF3YWl0IHRoaXMuc2VsZWN0VG9rZW4oXG4gICAgICByZXEucHJlZmVycmVkVG9rZW5JZCxcbiAgICAgIHJlcS5yZXF1aXJlUHJlZmVycmVkVG9rZW4gPz8gZmFsc2UsXG4gICAgICBzaWduYWwsXG4gICAgKTtcbiAgICB0aGlzLmluRmxpZ2h0Kys7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChzaWduYWwuYWJvcnRlZCkgdGhyb3cgYWJvcnRFcnJvcihzaWduYWwpO1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucnVuRGlyZWN0KHNlbGVjdGlvbiwgeyAuLi5yZXEsIGFib3J0U2lnbmFsOiBzaWduYWwgfSwgb25EZWx0YSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuaW5GbGlnaHQtLTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBydW5EaXJlY3QoXG4gICAgc2VsZWN0aW9uOiBUb2tlblNlbGVjdGlvbixcbiAgICByZXE6IEdlbmVyYXRlUmVxdWVzdCxcbiAgICBvbkRlbHRhPzogKHRleHQ6IHN0cmluZykgPT4gdm9pZCxcbiAgKTogUHJvbWlzZTxHZW5lcmF0ZVJlc3VsdD4ge1xuICAgIGNvbnN0IHN0YXJ0ZWRBdCA9IERhdGUubm93KCk7XG4gICAgbGV0IGZpcnN0RGVsdGFBdDogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgIGxldCB0ZXh0ID0gXCJcIjtcbiAgICBsZXQgb3V0cHV0TWVzc2FnZUFjY2VwdGVkID0gZmFsc2U7XG4gICAgY29uc3QgbWVzc2FnZVBoYXNlcyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gICAgY29uc3Qgc3RyZWFtZWRNZXNzYWdlSWRzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgbGV0IHVzYWdlID0ge1xuICAgICAgdG90YWxUb2tlbnM6IDAsXG4gICAgICBpbnB1dFRva2VuczogMCxcbiAgICAgIG91dHB1dFRva2VuczogMCxcbiAgICAgIGNhY2hlZElucHV0VG9rZW5zOiAwLFxuICAgICAgcmVhc29uaW5nT3V0cHV0VG9rZW5zOiAwLFxuICAgIH07XG4gICAgY29uc3QgaW1hZ2VzOiBHZW5lcmF0ZWRJbWFnZVtdID0gW107XG4gICAgbGV0IGltYWdlQXR0ZW1wdGVkID0gZmFsc2U7XG4gICAgY29uc3QgYXV0byA9IHJlcS5pbWFnZUdlbmVyYXRpb24gPT09IFwiYXV0b1wiO1xuICAgIGNvbnN0IGltYWdlQ2FsbHMgPSBuZXcgTWFwPHN0cmluZywgSW1hZ2VUb29sQXJndW1lbnRzPigpO1xuICAgIGNvbnN0IGltYWdlQ2FsbElkcyA9IG5ldyBTZXQ8dW5rbm93bj4oKTtcbiAgICBsZXQgaW1hZ2VUb29sQXR0ZW1wdGVkID0gZmFsc2U7XG4gICAgbGV0IGRyaXZlckNvbXBsZXRlZCA9IGZhbHNlO1xuICAgIGxldCBzZXJ2aW5nTW9kZWwgPSByZXEubW9kZWwgPz8gXCJcIjtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHNlbGVjdGlvbi5tZXRhZGF0YTtcbiAgICBjb25zdCBkcml2ZXJSZXN1bHQgPSAoKTogR2VuZXJhdGVSZXN1bHQgPT4gKHtcbiAgICAgIHRleHQsXG4gICAgICB0b2tlbk5hbWU6IG1ldGFkYXRhLm5hbWUsXG4gICAgICB1c2FnZSxcbiAgICAgIGR1cmF0aW9uTXM6IERhdGUubm93KCkgLSBzdGFydGVkQXQsXG4gICAgICB0dGZ0TXM6IGZpcnN0RGVsdGFBdCA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGZpcnN0RGVsdGFBdCAtIHN0YXJ0ZWRBdCxcbiAgICAgIG1vZGVsOiBzZXJ2aW5nTW9kZWwsXG4gICAgICAuLi4oc2VydmluZ01vZGVsICE9PSByZXEubW9kZWwgPyB7IHJlcXVlc3RlZE1vZGVsOiByZXEubW9kZWwgfSA6IHt9KSxcbiAgICAgIHRocmVhZENvb3JkOiB7IHdvcmtlcklkOiBzZWxlY3Rpb24udG9rZW5JZCwgdGhyZWFkSWQ6IHJlcS5wcm9tcHRDYWNoZUtleSA/PyBcIlwiLCBlcG9jaDogLTEgfSxcbiAgICB9KTtcbiAgICBjb25zdCBjbGllbnRFbnRyeSA9IHRoaXMuYWNxdWlyZUNsaWVudChzZWxlY3Rpb24pO1xuICAgIHRyeSB7XG4gICAgICBmb3IgYXdhaXQgKGNvbnN0IGV2ZW50IG9mIGNsaWVudEVudHJ5LmNsaWVudC5yZXNwb25zZXMoXG4gICAgICAgIHJlcXVlc3RPcHRpb25zKHJlcSksXG4gICAgICAgIHJlcS5hYm9ydFNpZ25hbCxcbiAgICAgICkpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHJlcS5zdG9wQWZ0ZXJPdXRwdXRNZXNzYWdlICYmXG4gICAgICAgICAgZXZlbnQudHlwZSA9PT0gXCJvdXRwdXQtaXRlbVwiICYmXG4gICAgICAgICAgZXZlbnQuaXRlbS50eXBlID09PSBcIm1lc3NhZ2VcIiAmJlxuICAgICAgICAgIHR5cGVvZiBldmVudC5pdGVtLmlkID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgdHlwZW9mIGV2ZW50Lml0ZW0ucGhhc2UgPT09IFwic3RyaW5nXCJcbiAgICAgICAgKSB7XG4gICAgICAgICAgbWVzc2FnZVBoYXNlcy5zZXQoZXZlbnQuaXRlbS5pZCwgZXZlbnQuaXRlbS5waGFzZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IFwidGV4dC1kZWx0YVwiKSB7XG4gICAgICAgICAgaWYgKG91dHB1dE1lc3NhZ2VBY2NlcHRlZCkgY29udGludWU7XG4gICAgICAgICAgaWYgKHJlcS5zdG9wQWZ0ZXJPdXRwdXRNZXNzYWdlICYmIGV2ZW50Lml0ZW1JZCkge1xuICAgICAgICAgICAgLy8gQnVmZmVyIGNvbW1lbnRhcnkvdW5jbGFzc2lmaWVkIG1lc3NhZ2VzIHVudGlsIHRoZWlyIGNvbXBsZXRlZCBpdGVtLlxuICAgICAgICAgICAgLy8gS25vd24gZmluYWwgYW5zd2VycyByZXRhaW4gaW5jcmVtZW50YWwgc3RyZWFtaW5nLlxuICAgICAgICAgICAgaWYgKG1lc3NhZ2VQaGFzZXMuZ2V0KGV2ZW50Lml0ZW1JZCkgIT09IFwiZmluYWxfYW5zd2VyXCIpIGNvbnRpbnVlO1xuICAgICAgICAgICAgc3RyZWFtZWRNZXNzYWdlSWRzLmFkZChldmVudC5pdGVtSWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBmaXJzdERlbHRhQXQgPz89IERhdGUubm93KCk7XG4gICAgICAgICAgdGV4dCArPSBldmVudC50ZXh0O1xuICAgICAgICAgIG9uRGVsdGE/LihldmVudC50ZXh0KTtcbiAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICBldmVudC50eXBlID09PSBcIm91dHB1dC1pdGVtXCIgJiZcbiAgICAgICAgICBldmVudC5jb21wbGV0ZWQgJiZcbiAgICAgICAgICBldmVudC5pdGVtLnR5cGUgPT09IFwibWVzc2FnZVwiICYmXG4gICAgICAgICAgIW91dHB1dE1lc3NhZ2VBY2NlcHRlZCAmJlxuICAgICAgICAgIHJlcS5zdG9wQWZ0ZXJPdXRwdXRNZXNzYWdlICYmXG4gICAgICAgICAgQXJyYXkuaXNBcnJheShldmVudC5pdGVtLmNvbnRlbnQpXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IG1lc3NhZ2VUZXh0ID0gZXZlbnQuaXRlbS5jb250ZW50XG4gICAgICAgICAgICAuZmlsdGVyKChwYXJ0KSA9PiBwYXJ0Py50eXBlID09PSBcIm91dHB1dF90ZXh0XCIgJiYgdHlwZW9mIHBhcnQudGV4dCA9PT0gXCJzdHJpbmdcIilcbiAgICAgICAgICAgIC5tYXAoKHBhcnQpID0+IHBhcnQudGV4dClcbiAgICAgICAgICAgIC5qb2luKFwiXCIpO1xuICAgICAgICAgIC8vIEEgdmFsaWQgY2xpZW50IHRvb2wgcmVxdWVzdCBlbmRzIHRoaXMgYXBwbGljYXRpb24gdHVybi4gTGF0ZXIgYW5zd2VycyBjYW5ub3RcbiAgICAgICAgICAvLyBrbm93IGl0cyByZXN1bHQgeWV0LiBOZXZlciBzcGxpdC9yZXBhaXIgbWFsZm9ybWVkIEpTT04gd2l0aGluIGEgbWVzc2FnZS5cbiAgICAgICAgICBjb25zdCBwaGFzZSA9IHR5cGVvZiBldmVudC5pdGVtLnBoYXNlID09PSBcInN0cmluZ1wiID8gZXZlbnQuaXRlbS5waGFzZSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICBpZiAobWVzc2FnZVRleHQpIG91dHB1dE1lc3NhZ2VBY2NlcHRlZCA9IHJlcS5zdG9wQWZ0ZXJPdXRwdXRNZXNzYWdlKG1lc3NhZ2VUZXh0LCBwaGFzZSk7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgdHlwZW9mIGV2ZW50Lml0ZW0uaWQgPT09IFwic3RyaW5nXCIgJiZcbiAgICAgICAgICAgICFzdHJlYW1lZE1lc3NhZ2VJZHMuaGFzKGV2ZW50Lml0ZW0uaWQpICYmXG4gICAgICAgICAgICAocGhhc2UgIT09IFwiY29tbWVudGFyeVwiIHx8IG91dHB1dE1lc3NhZ2VBY2NlcHRlZCkgJiZcbiAgICAgICAgICAgIG1lc3NhZ2VUZXh0XG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBmaXJzdERlbHRhQXQgPz89IERhdGUubm93KCk7XG4gICAgICAgICAgICB0ZXh0ICs9IG1lc3NhZ2VUZXh0O1xuICAgICAgICAgICAgb25EZWx0YT8uKG1lc3NhZ2VUZXh0KTtcbiAgICAgICAgICAgIHN0cmVhbWVkTWVzc2FnZUlkcy5hZGQoZXZlbnQuaXRlbS5pZCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwiaW1hZ2VcIikge1xuICAgICAgICAgIGlmIChhdXRvKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBcIlVuZXhwZWN0ZWQgaG9zdGVkIGltYWdlIGdlbmVyYXRpb25cIik7XG4gICAgICAgICAgaW1hZ2VBdHRlbXB0ZWQgPSB0cnVlO1xuICAgICAgICAgIGltYWdlcy5wdXNoKHtcbiAgICAgICAgICAgIGRhdGE6IGV2ZW50LmJhc2U2NCxcbiAgICAgICAgICAgIG1lZGlhVHlwZTogZXZlbnQubWltZVR5cGUsXG4gICAgICAgICAgICByZXZpc2VkUHJvbXB0OiBldmVudC5yZXZpc2VkUHJvbXB0ID8/IG51bGwsXG4gICAgICAgICAgICAuLi4oZXZlbnQuZ2VuZXJhdGlvbiA/IHsgZ2VuZXJhdGlvbjogZXZlbnQuZ2VuZXJhdGlvbiB9IDoge30pLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwib3V0cHV0LWl0ZW1cIiAmJiBldmVudC5pdGVtLnR5cGUgPT09IFwiaW1hZ2VfZ2VuZXJhdGlvbl9jYWxsXCIpIHtcbiAgICAgICAgICBpZiAoYXV0bylcbiAgICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcImluY29tcGxldGVcIiwgXCJVbmV4cGVjdGVkIGhvc3RlZCBpbWFnZSBnZW5lcmF0aW9uXCIpO1xuICAgICAgICAgIGltYWdlQXR0ZW1wdGVkID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmIChhdXRvICYmIGV2ZW50LnR5cGUgPT09IFwib3V0cHV0LWl0ZW1cIiAmJiBldmVudC5pdGVtLnR5cGUgPT09IFwiZnVuY3Rpb25fY2FsbFwiKSB7XG4gICAgICAgICAgaWYgKGV2ZW50Lml0ZW0ubmFtZSAhPT0gSU1BR0VfVE9PTCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBcIlVuZXhwZWN0ZWQgYXV0b21hdGljIGltYWdlIHRvb2wgY2FsbFwiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaW1hZ2VUb29sQXR0ZW1wdGVkID0gdHJ1ZTtcbiAgICAgICAgICBpbWFnZUNhbGxJZHMuYWRkKGV2ZW50Lml0ZW0uY2FsbF9pZCk7XG4gICAgICAgICAgaWYgKCFldmVudC5jb21wbGV0ZWQpIGNvbnRpbnVlO1xuICAgICAgICAgIGNvbnN0IGlkID0gZXZlbnQuaXRlbS5jYWxsX2lkO1xuICAgICAgICAgIGxldCBhcmdzOiB1bmtub3duO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBhcmdzID0gSlNPTi5wYXJzZShTdHJpbmcoZXZlbnQuaXRlbS5hcmd1bWVudHMpKTtcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcImluY29tcGxldGVcIiwgXCJJbnZhbGlkIGltYWdlIHRvb2wgYXJndW1lbnRzXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICB0eXBlb2YgaWQgIT09IFwic3RyaW5nXCIgfHxcbiAgICAgICAgICAgICFpZCB8fFxuICAgICAgICAgICAgIWFyZ3MgfHxcbiAgICAgICAgICAgIHR5cGVvZiBhcmdzICE9PSBcIm9iamVjdFwiIHx8XG4gICAgICAgICAgICBBcnJheS5pc0FycmF5KGFyZ3MpIHx8XG4gICAgICAgICAgICBPYmplY3Qua2V5cyhhcmdzKS5sZW5ndGggIT09IDMgfHxcbiAgICAgICAgICAgICEoXCJwcm9tcHRcIiBpbiBhcmdzKSB8fFxuICAgICAgICAgICAgdHlwZW9mIGFyZ3MucHJvbXB0ICE9PSBcInN0cmluZ1wiIHx8XG4gICAgICAgICAgICAhYXJncy5wcm9tcHQudHJpbSgpIHx8XG4gICAgICAgICAgICAhKFwidHJhbnNwYXJlbnRfYmFja2dyb3VuZFwiIGluIGFyZ3MpIHx8XG4gICAgICAgICAgICB0eXBlb2YgYXJncy50cmFuc3BhcmVudF9iYWNrZ3JvdW5kICE9PSBcImJvb2xlYW5cIiB8fFxuICAgICAgICAgICAgIShcIm51bV9sYXN0X2ltYWdlc190b19pbmNsdWRlXCIgaW4gYXJncykgfHxcbiAgICAgICAgICAgIHR5cGVvZiBhcmdzLm51bV9sYXN0X2ltYWdlc190b19pbmNsdWRlICE9PSBcIm51bWJlclwiIHx8XG4gICAgICAgICAgICAhTnVtYmVyLmlzSW50ZWdlcihhcmdzLm51bV9sYXN0X2ltYWdlc190b19pbmNsdWRlKSB8fFxuICAgICAgICAgICAgYXJncy5udW1fbGFzdF9pbWFnZXNfdG9faW5jbHVkZSA8IDAgfHxcbiAgICAgICAgICAgIGFyZ3MubnVtX2xhc3RfaW1hZ2VzX3RvX2luY2x1ZGUgPiA1XG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXCJpbmNvbXBsZXRlXCIsIFwiSW52YWxpZCBpbWFnZSB0b29sIGFyZ3VtZW50c1wiKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgcHJldmlvdXMgPSBpbWFnZUNhbGxzLmdldChpZCk7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgcHJldmlvdXMgJiZcbiAgICAgICAgICAgIChwcmV2aW91cy5wcm9tcHQgIT09IGFyZ3MucHJvbXB0IHx8XG4gICAgICAgICAgICAgIHByZXZpb3VzLnRyYW5zcGFyZW50X2JhY2tncm91bmQgIT09IGFyZ3MudHJhbnNwYXJlbnRfYmFja2dyb3VuZCB8fFxuICAgICAgICAgICAgICBwcmV2aW91cy5udW1fbGFzdF9pbWFnZXNfdG9faW5jbHVkZSAhPT0gYXJncy5udW1fbGFzdF9pbWFnZXNfdG9faW5jbHVkZSlcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcImluY29tcGxldGVcIiwgXCJDb25mbGljdGluZyBpbWFnZSB0b29sIGNhbGxzXCIpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpbWFnZUNhbGxzLnNldChpZCwge1xuICAgICAgICAgICAgcHJvbXB0OiBhcmdzLnByb21wdCxcbiAgICAgICAgICAgIHRyYW5zcGFyZW50X2JhY2tncm91bmQ6IGFyZ3MudHJhbnNwYXJlbnRfYmFja2dyb3VuZCxcbiAgICAgICAgICAgIG51bV9sYXN0X2ltYWdlc190b19pbmNsdWRlOiBhcmdzLm51bV9sYXN0X2ltYWdlc190b19pbmNsdWRlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwiY29tcGxldGVkXCIpIHtcbiAgICAgICAgICBjb25zdCBpbWFnZVVzYWdlID0gZXZlbnQuaW1hZ2VHZW5lcmF0aW9uPy51c2FnZTtcbiAgICAgICAgICAvLyBUaGUgYmFja2VuZCBhbHNvIHJlcG9ydHMgYWxsLXplcm8gaW1hZ2UgdXNhZ2UgZm9yIHRleHQtb25seSByZXNwb25zZXMuXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgYXV0byAmJlxuICAgICAgICAgICAgaW1hZ2VVc2FnZSAmJlxuICAgICAgICAgICAgKGltYWdlVXNhZ2UuaW5wdXRfdG9rZW5zID4gMCB8fFxuICAgICAgICAgICAgICBpbWFnZVVzYWdlLm91dHB1dF90b2tlbnMgPiAwIHx8XG4gICAgICAgICAgICAgIGltYWdlVXNhZ2UudG90YWxfdG9rZW5zID4gMClcbiAgICAgICAgICApXG4gICAgICAgICAgICB0aHJvdyBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXCJpbmNvbXBsZXRlXCIsIFwiVW5leHBlY3RlZCBob3N0ZWQgaW1hZ2UgZ2VuZXJhdGlvblwiKTtcbiAgICAgICAgICBkcml2ZXJDb21wbGV0ZWQgPSB0cnVlO1xuICAgICAgICAgIHNlcnZpbmdNb2RlbCA9IGV2ZW50Lm1vZGVsID8/IHNlcnZpbmdNb2RlbDtcbiAgICAgICAgICBpZiAoZXZlbnQudXNhZ2UpIHtcbiAgICAgICAgICAgIHVzYWdlID0ge1xuICAgICAgICAgICAgICB0b3RhbFRva2VuczogZXZlbnQudXNhZ2UudG90YWxUb2tlbnMsXG4gICAgICAgICAgICAgIGlucHV0VG9rZW5zOiBldmVudC51c2FnZS5pbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgb3V0cHV0VG9rZW5zOiBldmVudC51c2FnZS5vdXRwdXRUb2tlbnMsXG4gICAgICAgICAgICAgIGNhY2hlZElucHV0VG9rZW5zOiBldmVudC51c2FnZS5jYWNoZWRJbnB1dFRva2VucyxcbiAgICAgICAgICAgICAgcmVhc29uaW5nT3V0cHV0VG9rZW5zOiBldmVudC51c2FnZS5yZWFzb25pbmdUb2tlbnMsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZXZlbnQuaW1hZ2VHZW5lcmF0aW9uKSB7XG4gICAgICAgICAgICBjb25zdCBob3N0ZWRJbWFnZXMgPSBpbWFnZXMuZmlsdGVyKFxuICAgICAgICAgICAgICAoaW1hZ2UpID0+IGltYWdlLmdlbmVyYXRpb24/LnJvdXRlID09PSBcImNvZGV4LXJlc3BvbnNlc1wiLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgW2luZGV4LCBpbWFnZV0gb2YgaG9zdGVkSW1hZ2VzLmVudHJpZXMoKSkge1xuICAgICAgICAgICAgICBpbWFnZS5nZW5lcmF0aW9uID0ge1xuICAgICAgICAgICAgICAgIHJvdXRlOiBcImNvZGV4LXJlc3BvbnNlc1wiLFxuICAgICAgICAgICAgICAgIC4uLihldmVudC5pbWFnZUdlbmVyYXRpb24ubW9kZWwgPyB7IG1vZGVsOiBldmVudC5pbWFnZUdlbmVyYXRpb24ubW9kZWwgfSA6IHt9KSxcbiAgICAgICAgICAgICAgICAuLi5pbWFnZS5nZW5lcmF0aW9uLFxuICAgICAgICAgICAgICAgIC8vIFRvb2wgdXNhZ2UgY292ZXJzIHRoZSB3aG9sZSByZXNwb25zZSwgbm90IGVhY2ggcmV0dXJuZWQgaW1hZ2UuXG4gICAgICAgICAgICAgICAgLi4uKGluZGV4ID09PSAwICYmIGV2ZW50LmltYWdlR2VuZXJhdGlvbi51c2FnZVxuICAgICAgICAgICAgICAgICAgPyB7IHVzYWdlOiBldmVudC5pbWFnZUdlbmVyYXRpb24udXNhZ2UgfVxuICAgICAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwiZXJyb3JcIikge1xuICAgICAgICAgIGlmIChyZXEuaW1hZ2VHZW5lcmF0aW9uKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBldmVudC5lcnJvci5tZXNzYWdlKTtcbiAgICAgICAgICB0aHJvdyBldmVudC5lcnJvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGF1dG8gJiYgaW1hZ2VUb29sQXR0ZW1wdGVkKSB7XG4gICAgICAgIGlmICghZHJpdmVyQ29tcGxldGVkIHx8IGltYWdlQ2FsbHMuc2l6ZSAhPT0gMSB8fCBpbWFnZUNhbGxJZHMuc2l6ZSAhPT0gMSkge1xuICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcImluY29tcGxldGVcIiwgXCJFeHBlY3RlZCBvbmUgY29tcGxldGVkIGltYWdlIHRvb2wgY2FsbFwiKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVxLmFib3J0U2lnbmFsPy5hYm9ydGVkKSB0aHJvdyBhYm9ydEVycm9yKHJlcS5hYm9ydFNpZ25hbCk7XG4gICAgICAgIGNvbnN0IGFyZ3MgPSBbLi4uaW1hZ2VDYWxscy52YWx1ZXMoKV1bMF0hO1xuICAgICAgICBjb25zdCByZWZlcmVuY2VDb3VudCA9IGFyZ3MubnVtX2xhc3RfaW1hZ2VzX3RvX2luY2x1ZGU7XG4gICAgICAgIGNvbnN0IHJlZmVyZW5jZXMgPSByZWZlcmVuY2VDb3VudCA/IGltYWdlUmVmZXJlbmNlcyhyZXEpIDogW107XG4gICAgICAgIGlmIChyZWZlcmVuY2VDb3VudCA+IHJlZmVyZW5jZXMubGVuZ3RoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFxuICAgICAgICAgICAgXCJpbmNvbXBsZXRlXCIsXG4gICAgICAgICAgICBcIlJlcXVlc3RlZCBpbWFnZSByZWZlcmVuY2VzIGFyZSB1bmF2YWlsYWJsZVwiLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGltYWdlQ29tcGxldGVkID0gZmFsc2U7XG4gICAgICAgIGZvciBhd2FpdCAoY29uc3QgZXZlbnQgb2YgY2xpZW50RW50cnkuY2xpZW50LnJlc3BvbnNlcyhcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtb2RlbDogXCJncHQtaW1hZ2UtMlwiLFxuICAgICAgICAgICAgaGlzdG9yeTogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdHlwZTogXCJtZXNzYWdlXCIsXG4gICAgICAgICAgICAgICAgcm9sZTogXCJ1c2VyXCIsXG4gICAgICAgICAgICAgICAgY29udGVudDogW1xuICAgICAgICAgICAgICAgICAgeyB0eXBlOiBcImlucHV0X3RleHRcIiwgdGV4dDogYXJncy5wcm9tcHQgfSxcbiAgICAgICAgICAgICAgICAgIC4uLihyZWZlcmVuY2VDb3VudCA/IHJlZmVyZW5jZXMuc2xpY2UoLXJlZmVyZW5jZUNvdW50KSA6IFtdKSxcbiAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIGltYWdlR2VuZXJhdGlvbjoge1xuICAgICAgICAgICAgICBxdWFsaXR5OiByZXEuaW1hZ2VHZW5lcmF0aW9uT3B0aW9ucz8ucXVhbGl0eSxcbiAgICAgICAgICAgICAgc2l6ZTogcmVxLmltYWdlR2VuZXJhdGlvbk9wdGlvbnM/LnNpemUsXG4gICAgICAgICAgICAgIG91dHB1dF9mb3JtYXQ6IFwicG5nXCIsXG4gICAgICAgICAgICAgIGJhY2tncm91bmQ6IGFyZ3MudHJhbnNwYXJlbnRfYmFja2dyb3VuZCA/IFwidHJhbnNwYXJlbnRcIiA6IFwib3BhcXVlXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVxLmFib3J0U2lnbmFsLFxuICAgICAgICApKSB7XG4gICAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IFwiaW1hZ2VcIilcbiAgICAgICAgICAgIGltYWdlcy5wdXNoKHtcbiAgICAgICAgICAgICAgZGF0YTogZXZlbnQuYmFzZTY0LFxuICAgICAgICAgICAgICBtZWRpYVR5cGU6IGV2ZW50Lm1pbWVUeXBlLFxuICAgICAgICAgICAgICByZXZpc2VkUHJvbXB0OiBldmVudC5yZXZpc2VkUHJvbXB0ID8/IG51bGwsXG4gICAgICAgICAgICAgIC4uLihldmVudC5nZW5lcmF0aW9uID8geyBnZW5lcmF0aW9uOiBldmVudC5nZW5lcmF0aW9uIH0gOiB7fSksXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICBlbHNlIGlmIChldmVudC50eXBlID09PSBcImNvbXBsZXRlZFwiKSBpbWFnZUNvbXBsZXRlZCA9IHRydWU7XG4gICAgICAgICAgZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gXCJlcnJvclwiKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBldmVudC5lcnJvci5tZXNzYWdlLCB7XG4gICAgICAgICAgICAgIGNhdXNlOiBldmVudC5lcnJvcixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGltYWdlQXR0ZW1wdGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKCFpbWFnZUNvbXBsZXRlZClcbiAgICAgICAgICB0aHJvdyBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXCJpbmNvbXBsZXRlXCIsIFwiSW1hZ2UgZ2VuZXJhdGlvbiBkaWQgbm90IGNvbXBsZXRlXCIpO1xuICAgICAgfVxuICAgICAgaWYgKGF1dG8gJiYgaW1hZ2VBdHRlbXB0ZWQgJiYgIWRyaXZlckNvbXBsZXRlZClcbiAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBcIkltYWdlIGdlbmVyYXRpb24gcmVzcG9uc2UgZGlkIG5vdCBjb21wbGV0ZVwiKTtcbiAgICAgIGlmIChyZXEuYWJvcnRTaWduYWw/LmFib3J0ZWQpIHRocm93IGFib3J0RXJyb3IocmVxLmFib3J0U2lnbmFsKTtcbiAgICAgIGlmICgocmVxLmltYWdlR2VuZXJhdGlvbiA9PT0gdHJ1ZSB8fCAoYXV0byAmJiBpbWFnZUF0dGVtcHRlZCkpICYmIGltYWdlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFxuICAgICAgICAgIGltYWdlQXR0ZW1wdGVkID8gXCJpbmNvbXBsZXRlXCIgOiBcIm5vdF9jYWxsZWRcIixcbiAgICAgICAgICBpbWFnZUF0dGVtcHRlZFxuICAgICAgICAgICAgPyBcImltYWdlIGdlbmVyYXRpb24gZGlkIG5vdCBjb21wbGV0ZVwiXG4gICAgICAgICAgICA6IFwibW9kZWwgZGlkIG5vdCBjYWxsIGltYWdlIGdlbmVyYXRpb25cIixcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGF1dG8gJiYgZHJpdmVyQ29tcGxldGVkICYmIGltYWdlVG9vbEF0dGVtcHRlZCkge1xuICAgICAgICBjb25zdCBmYWlsdXJlID1cbiAgICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEltYWdlR2VuZXJhdGlvbkVycm9yXG4gICAgICAgICAgICA/IGVycm9yXG4gICAgICAgICAgICA6IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcbiAgICAgICAgICAgICAgICBcImluY29tcGxldGVcIixcbiAgICAgICAgICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgICAgICAgICAgICAgeyBjYXVzZTogZXJyb3IgfSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIGZhaWx1cmUubmFtZSA9IGVycm9yLm5hbWU7XG4gICAgICAgIC8vIE9ubHkgdGhlIGNvbXBsZXRlZCBjaGF0IHN0YWdlIGlzIGNoYXJnZWFibGUgaGVyZTsgZGlzY2FyZCBwYXJ0aWFsIGltYWdlIG91dHB1dC5cbiAgICAgICAgZmFpbHVyZS5jb21wbGV0ZWREcml2ZXIgPSBkcml2ZXJSZXN1bHQoKTtcbiAgICAgICAgdGhyb3cgZmFpbHVyZTtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLnJlbGVhc2VDbGllbnQoY2xpZW50RW50cnkpO1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgLi4uZHJpdmVyUmVzdWx0KCksXG4gICAgICAuLi4oaW1hZ2VzLmxlbmd0aCA/IHsgaW1hZ2VzIH0gOiB7fSksXG4gICAgfTtcbiAgfVxuXG4gIC8qKiDshLjrjIDqsIAg67CU64CQIGNsaWVudCDripQg7IKs7JqpIOykkeyduCDsmpTssq3snbQg64Gd64KcIOuSpOyXkCDri6vripTri6QuICovXG4gIGFjcXVpcmVDbGllbnQoc2VsZWN0aW9uOiBUb2tlblNlbGVjdGlvbik6IENsaWVudEVudHJ5IHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHNlbGVjdGlvbi5tZXRhZGF0YTtcbiAgICBsZXQgZW50cnkgPSB0aGlzLmNsaWVudHMuZ2V0KHNlbGVjdGlvbi50b2tlbklkKTtcbiAgICBpZiAoZW50cnkgJiYgZW50cnkuZ2VuZXJhdGlvbiAhPT0gbWV0YWRhdGEuZ2VuZXJhdGlvbikge1xuICAgICAgdGhpcy5yZXRpcmVDbGllbnQoc2VsZWN0aW9uLnRva2VuSWQpO1xuICAgICAgZW50cnkgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGlmICghZW50cnkpIHtcbiAgICAgIGNvbnN0IGNsaWVudCA9IHRoaXMuY2xpZW50RmFjdG9yeShcbiAgICAgICAge1xuICAgICAgICAgIGNyZWRlbnRpYWxzOiB7XG4gICAgICAgICAgICBhY2Nlc3NUb2tlbjogbWV0YWRhdGEuY3JlZGVudGlhbHMuYWNjZXNzVG9rZW4sXG4gICAgICAgICAgICBhY2NvdW50SWQ6IG1ldGFkYXRhLmNyZWRlbnRpYWxzLmFjY291bnRJZCxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRyYW5zcG9ydEtpbmQ6IHRoaXMudHJhbnNwb3J0S2luZCxcbiAgICAgICAgICBmZXRjaDogdGhpcy5mZXRjaEltcGwsXG4gICAgICAgICAgcmVmcmVzaENyZWRlbnRpYWxzOiAoKSA9PiB0aGlzLnJlZnJlc2hDcmVkZW50aWFscyhzZWxlY3Rpb24udG9rZW5JZCksXG4gICAgICAgIH0sXG4gICAgICAgIHNlbGVjdGlvbi50b2tlbklkLFxuICAgICAgKTtcbiAgICAgIGVudHJ5ID0geyBnZW5lcmF0aW9uOiBtZXRhZGF0YS5nZW5lcmF0aW9uLCBjbGllbnQsIGluRmxpZ2h0OiAwLCByZXRpcmVkOiBmYWxzZSB9O1xuICAgICAgdGhpcy5jbGllbnRzLnNldChzZWxlY3Rpb24udG9rZW5JZCwgZW50cnkpO1xuICAgIH1cbiAgICBlbnRyeS5pbkZsaWdodCsrO1xuICAgIHJldHVybiBlbnRyeTtcbiAgfVxuXG4gIHJlbGVhc2VDbGllbnQoZW50cnk6IENsaWVudEVudHJ5KTogdm9pZCB7XG4gICAgZW50cnkuaW5GbGlnaHQgPSBNYXRoLm1heCgwLCBlbnRyeS5pbkZsaWdodCAtIDEpO1xuICAgIGlmIChlbnRyeS5yZXRpcmVkICYmIGVudHJ5LmluRmxpZ2h0ID09PSAwKSB7XG4gICAgICB0aGlzLnJldGlyZWRDbGllbnRzLmRlbGV0ZShlbnRyeSk7XG4gICAgICBlbnRyeS5jbGllbnQuY2xvc2U/LigpO1xuICAgIH1cbiAgfVxuXG4gIHJldGlyZUNsaWVudCh0b2tlbklkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBlbnRyeSA9IHRoaXMuY2xpZW50cy5nZXQodG9rZW5JZCk7XG4gICAgaWYgKCFlbnRyeSkgcmV0dXJuO1xuICAgIHRoaXMuY2xpZW50cy5kZWxldGUodG9rZW5JZCk7XG4gICAgZW50cnkucmV0aXJlZCA9IHRydWU7XG4gICAgaWYgKGVudHJ5LmluRmxpZ2h0ID09PSAwKSBlbnRyeS5jbGllbnQuY2xvc2U/LigpO1xuICAgIGVsc2UgdGhpcy5yZXRpcmVkQ2xpZW50cy5hZGQoZW50cnkpO1xuICB9XG5cbiAgLy8g7ISg7Zi4IO2GoO2BsOydtCBxdW90YeulvCDthrXqs7ztlZjrqbQg64uk66W4IO2GoO2BsCDsobDtmozsmYAgd2VpZ2h0ZWQg7IOB7YOcIOuzgOqyveydhCDsg53rnrXtlZzri6QuXG4gIGFzeW5jIHNlbGVjdFRva2VuKFxuICAgIHByZWZlcnJlZFRva2VuSWQ6IG51bWJlciB8IHVuZGVmaW5lZCxcbiAgICByZXF1aXJlUHJlZmVycmVkVG9rZW46IGJvb2xlYW4sXG4gICAgc2lnbmFsOiBBYm9ydFNpZ25hbCxcbiAgKTogUHJvbWlzZTxUb2tlblNlbGVjdGlvbj4ge1xuICAgIGlmIChwcmVmZXJyZWRUb2tlbklkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNvbnN0IHByZWZlcnJlZCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQocHJlZmVycmVkVG9rZW5JZCk7XG4gICAgICBpZiAocHJlZmVycmVkPy5hY3RpdmUgJiYgKGF3YWl0IHRoaXMuaXNRdW90YUVsaWdpYmxlKHByZWZlcnJlZFRva2VuSWQsIHByZWZlcnJlZCwgc2lnbmFsKSkpIHtcbiAgICAgICAgcmV0dXJuIHsgdG9rZW5JZDogcHJlZmVycmVkVG9rZW5JZCwgbWV0YWRhdGE6IHByZWZlcnJlZCB9O1xuICAgICAgfVxuICAgICAgaWYgKHJlcXVpcmVQcmVmZXJyZWRUb2tlbikge1xuICAgICAgICBpZiAoIXByZWZlcnJlZD8uYWN0aXZlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQcmVmZXJyZWQgb3BlbmFpIHRva2VuICR7cHJlZmVycmVkVG9rZW5JZH0gaXMgbm90IGF2YWlsYWJsZWApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRocmVzaG9sZCA9IHByZWZlcnJlZC5xdW90YVRocmVzaG9sZDtcbiAgICAgICAgaWYgKHRocmVzaG9sZCAhPT0gbnVsbCAmJiB0aHJlc2hvbGQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBRdW90YVRocmVzaG9sZEV4Y2VlZGVkRXJyb3IoXG4gICAgICAgICAgICBxdW90YU1lc3NhZ2UoW3sgbmFtZTogcHJlZmVycmVkLm5hbWUsIHRocmVzaG9sZCB9XSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIOy9nOuTnCDsupDsi5zsl5DshJwg7Yag7YGwIOyImOunjO2BvCDsobDtmowg7KeA7Jew7J20IOyMk+ydtOyngCDslYrrj4TroZ0g67OR66CsIO2MkOygle2VnOuLpC5cbiAgICBjb25zdCBjaGVja3MgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIFsuLi50aGlzLnRva2VuTWV0YWRhdGEuZW50cmllcygpXVxuICAgICAgICAuZmlsdGVyKChbLCB0b2tlbl0pID0+IHRva2VuLmFjdGl2ZSlcbiAgICAgICAgLm1hcChhc3luYyAoW2lkLCB0b2tlbl0pID0+ICh7XG4gICAgICAgICAgaWQsXG4gICAgICAgICAgdG9rZW4sXG4gICAgICAgICAgZWxpZ2libGU6IGF3YWl0IHRoaXMuaXNRdW90YUVsaWdpYmxlKGlkLCB0b2tlbiwgc2lnbmFsKSxcbiAgICAgICAgfSkpLFxuICAgICk7XG4gICAgY29uc3QgZWxpZ2libGUgPSBuZXcgU2V0KGNoZWNrcy5maWx0ZXIoKGMpID0+IGMuZWxpZ2libGUpLm1hcCgoYykgPT4gYy5pZCkpO1xuICAgIGlmIChlbGlnaWJsZS5zaXplID09PSAwKSB7XG4gICAgICBjb25zdCBvdmVyID0gY2hlY2tzXG4gICAgICAgIC5maWx0ZXIoXG4gICAgICAgICAgKGMpID0+XG4gICAgICAgICAgICAhYy5lbGlnaWJsZSAmJiBjLnRva2VuLnF1b3RhVGhyZXNob2xkICE9PSBudWxsICYmIGMudG9rZW4ucXVvdGFUaHJlc2hvbGQgIT09IHVuZGVmaW5lZCxcbiAgICAgICAgKVxuICAgICAgICAubWFwKChjKSA9PiAoeyBuYW1lOiBjLnRva2VuLm5hbWUsIHRocmVzaG9sZDogYy50b2tlbi5xdW90YVRocmVzaG9sZCBhcyBudW1iZXIgfSkpO1xuICAgICAgaWYgKG92ZXIubGVuZ3RoKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKFwicXVvdGFfdGhyZXNob2xkIGdhdGU6IGFsbF9leGNlZWRlZFwiLCB7XG4gICAgICAgICAgcHJvdmlkZXI6IFwib3BlbmFpXCIsXG4gICAgICAgICAgb3ZlclRocmVzaG9sZFRva2Vuczogb3ZlcixcbiAgICAgICAgfSk7XG4gICAgICAgIHRocm93IG5ldyBRdW90YVRocmVzaG9sZEV4Y2VlZGVkRXJyb3IocXVvdGFNZXNzYWdlKG92ZXIpKTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5PX09QRU5BSV9XT1JLRVJTXCIpO1xuICAgIH1cbiAgICBjb25zdCBzZWxlY3RlZCA9IHRoaXMuc2VsZWN0b3Iuc2VsZWN0KGVsaWdpYmxlKTtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHNlbGVjdGVkICE9PSBudWxsID8gdGhpcy50b2tlbk1ldGFkYXRhLmdldChzZWxlY3RlZCkgOiB1bmRlZmluZWQ7XG4gICAgaWYgKHNlbGVjdGVkID09PSBudWxsIHx8ICFtZXRhZGF0YSkgdGhyb3cgbmV3IEVycm9yKFwiTk9fT1BFTkFJX1dPUktFUlNcIik7XG4gICAgcmV0dXJuIHsgdG9rZW5JZDogc2VsZWN0ZWQsIG1ldGFkYXRhIH07XG4gIH1cblxuICBzZXRUb2tlbihcbiAgICBpZDogbnVtYmVyLFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHMsXG4gICAgcXVvdGFUaHJlc2hvbGQ6IG51bWJlciB8IG51bGwgfCB1bmRlZmluZWQsXG4gICAgd2VpZ2h0OiBudW1iZXIsXG4gICAgYWN0aXZlOiBib29sZWFuLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBvbGQgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICBpZiAob2xkKSB7XG4gICAgICBPYmplY3QuYXNzaWduKG9sZCwge1xuICAgICAgICBuYW1lLFxuICAgICAgICBjcmVkZW50aWFscyxcbiAgICAgICAgcXVvdGFUaHJlc2hvbGQsXG4gICAgICAgIHdlaWdodCxcbiAgICAgICAgYWN0aXZlLFxuICAgICAgICBnZW5lcmF0aW9uOiBvbGQuZ2VuZXJhdGlvbiArIDEsXG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy50b2tlbk1ldGFkYXRhLnNldChpZCwge1xuICAgICAgICBuYW1lLFxuICAgICAgICBjcmVkZW50aWFscyxcbiAgICAgICAgcXVvdGFUaHJlc2hvbGQsXG4gICAgICAgIHdlaWdodCxcbiAgICAgICAgYWN0aXZlLFxuICAgICAgICBnZW5lcmF0aW9uOiAxLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuc2VsZWN0b3Iuc2V0VG9rZW4oaWQsIHdlaWdodCk7XG4gICAgdGhpcy5pbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKGlkKTtcbiAgICB0aGlzLnF1b3RhQmxvY2tlZC5kZWxldGUoaWQpO1xuICB9XG5cbiAgYXN5bmMgZ2V0UmF0ZUxpbWl0c0J5VG9rZW5JZChcbiAgICB0b2tlbklkOiBudW1iZXIsXG4gICAgc2lnbmFsPzogQWJvcnRTaWduYWwsXG4gICk6IFByb21pc2U8T3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhPiB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpO1xuICAgIGlmICghdG9rZW4pIHRocm93IG5ldyBFcnJvcihgb3BlbmFpIHRva2VuICR7dG9rZW5JZH0gbm90IGZvdW5kYCk7XG4gICAgY29uc3QgZ2VuZXJhdGlvbiA9IHRva2VuLmdlbmVyYXRpb247XG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5yYXRlTGltaXRzQ2FjaGUuZ2V0KHRva2VuSWQpO1xuICAgIGlmIChcbiAgICAgIGNhY2hlZCAmJlxuICAgICAgY2FjaGVkLmdlbmVyYXRpb24gPT09IHRva2VuLmdlbmVyYXRpb24gJiZcbiAgICAgIERhdGUubm93KCkgLSBjYWNoZWQuY2FjaGVkQXQgPCBPcGVuQUlEaXNwYXRjaGVyLlJBVEVfTElNSVRTX0NBQ0hFX1RUTFxuICAgIClcbiAgICAgIHJldHVybiBjYWNoZWQ7XG5cbiAgICAvLyBUVEwg66eM66OMIOyLnCDsobDtmozrpbwg6rO17Jyg7ZWc64ukLiDstZzstIgg7Zi47Lac7J6Q7J2YIGFib3J066GcIOyLpO2MqO2VtOuPhCBpc1F1b3RhRWxpZ2libGXsnYAgZmFpbC1vcGVu7ZWc64ukLlxuICAgIGNvbnN0IHBlbmRpbmcgPSB0aGlzLnBlbmRpbmdSYXRlTGltaXRzLmdldCh0b2tlbklkKTtcbiAgICBpZiAocGVuZGluZz8udG9rZW4gPT09IHRva2VuICYmIHBlbmRpbmcuZ2VuZXJhdGlvbiA9PT0gZ2VuZXJhdGlvbikgcmV0dXJuIHBlbmRpbmcucHJvbWlzZTtcbiAgICBjb25zdCBmZXRjaFByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVhZE9wZW5BSVF1b3RhVXNhZ2Uoe1xuICAgICAgICBjcmVkZW50aWFsczogdG9rZW4uY3JlZGVudGlhbHMsXG4gICAgICAgIHJlZnJlc2hDcmVkZW50aWFsczogKCkgPT4gdGhpcy5yZWZyZXNoQ3JlZGVudGlhbHModG9rZW5JZCksXG4gICAgICAgIGZldGNoOiB0aGlzLmZldGNoSW1wbCxcbiAgICAgICAgLi4uKHNpZ25hbCA/IHsgc2lnbmFsIH0gOiB7fSksXG4gICAgICB9KTtcbiAgICAgIGlmIChyZXN1bHQua2luZCA9PT0gXCJsb29rdXBfZmFpbGVkXCIpIHRocm93IG5ldyBFcnJvcihyZXN1bHQucmVhc29uKTtcbiAgICAgIGlmICghcmVzdWx0LnJhdykgdGhyb3cgbmV3IEVycm9yKFwiT3BlbkFJIHF1b3RhIHJlc3BvbnNlIG1pc3NpbmcgcmF3IHJhdGUgbGltaXRzXCIpO1xuICAgICAgY29uc3QgZW50cnkgPSB7IGRhdGE6IHJlc3VsdC5yYXcsIGNhY2hlZEF0OiBEYXRlLm5vdygpLCBnZW5lcmF0aW9uIH07XG4gICAgICBpZiAodGhpcy50b2tlbk1ldGFkYXRhLmdldCh0b2tlbklkKSA9PT0gdG9rZW4gJiYgdG9rZW4uZ2VuZXJhdGlvbiA9PT0gZ2VuZXJhdGlvbikge1xuICAgICAgICB0aGlzLnJhdGVMaW1pdHNDYWNoZS5zZXQodG9rZW5JZCwgZW50cnkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGVudHJ5O1xuICAgIH0pKCkuZmluYWxseSgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5wZW5kaW5nUmF0ZUxpbWl0cy5nZXQodG9rZW5JZCk/LnByb21pc2UgPT09IGZldGNoUHJvbWlzZSkge1xuICAgICAgICB0aGlzLnBlbmRpbmdSYXRlTGltaXRzLmRlbGV0ZSh0b2tlbklkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLnBlbmRpbmdSYXRlTGltaXRzLnNldCh0b2tlbklkLCB7IHRva2VuLCBnZW5lcmF0aW9uLCBwcm9taXNlOiBmZXRjaFByb21pc2UgfSk7XG4gICAgcmV0dXJuIGZldGNoUHJvbWlzZTtcbiAgfVxuXG4gIGFzeW5jIHJlZnJlc2hDcmVkZW50aWFscyh0b2tlbklkOiBudW1iZXIpIHtcbiAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCk7XG4gICAgY29uc3QgZ2VuZXJhdGlvbiA9IHByZXZpb3VzPy5nZW5lcmF0aW9uO1xuICAgIGNvbnN0IHJlZnJlc2hlZCA9IGF3YWl0IGhhbmRsZUNoYXRncHRBdXRoVG9rZW5zUmVmcmVzaCh0b2tlbklkKTtcbiAgICBjb25zdCBjcmVkZW50aWFscyA9IHtcbiAgICAgIGFjY2Vzc1Rva2VuOiByZWZyZXNoZWQuYWNjZXNzVG9rZW4sXG4gICAgICBhY2NvdW50SWQ6IHJlZnJlc2hlZC5jaGF0Z3B0QWNjb3VudElkLFxuICAgIH07XG4gICAgY29uc3QgY3VycmVudCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCk7XG4gICAgaWYgKCFjdXJyZW50Py5hY3RpdmUpIHRocm93IG5ldyBFcnJvcihgb3BlbmFpIHRva2VuICR7dG9rZW5JZH0gaXMgbm8gbG9uZ2VyIGFjdGl2ZWApO1xuICAgIC8vIEEgc3Vic2NyaWJlciB1cGRhdGUgbWF5IGFscmVhZHkgY29udGFpbiBuZXdlciBjcmVkZW50aWFscy4gTmV2ZXIgb3ZlcndyaXRlIGl0XG4gICAgLy8gd2l0aCB0aGUgcmVzdWx0IG9mIGEgcmVmcmVzaCB0aGF0IHN0YXJ0ZWQgYWdhaW5zdCBhbiBvbGRlciBnZW5lcmF0aW9uLlxuICAgIGlmIChjdXJyZW50ID09PSBwcmV2aW91cyAmJiBjdXJyZW50LmdlbmVyYXRpb24gPT09IGdlbmVyYXRpb24pIHtcbiAgICAgIGN1cnJlbnQuY3JlZGVudGlhbHMgPSB7IC4uLmN1cnJlbnQuY3JlZGVudGlhbHMsIC4uLmNyZWRlbnRpYWxzIH07XG4gICAgICB0aGlzLnJldGlyZUNsaWVudCh0b2tlbklkKTtcbiAgICAgIHRoaXMuaW52YWxpZGF0ZVJhdGVMaW1pdHNDYWNoZSh0b2tlbklkKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGFjY2Vzc1Rva2VuOiBjdXJyZW50LmNyZWRlbnRpYWxzLmFjY2Vzc1Rva2VuLFxuICAgICAgYWNjb3VudElkOiBjdXJyZW50LmNyZWRlbnRpYWxzLmFjY291bnRJZCxcbiAgICB9O1xuICB9XG5cbiAgYXN5bmMgaXNRdW90YUVsaWdpYmxlKGlkOiBudW1iZXIsIHRva2VuOiBUb2tlbk1ldGFkYXRhLCBzaWduYWw/OiBBYm9ydFNpZ25hbCk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICh0b2tlbi5xdW90YVRocmVzaG9sZCA9PT0gbnVsbCB8fCB0b2tlbi5xdW90YVRocmVzaG9sZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdHJ1ZTtcbiAgICBjb25zdCBnZW5lcmF0aW9uID0gdG9rZW4uZ2VuZXJhdGlvbjtcbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZWFkT3BlbkFJUXVvdGFVc2FnZShhc3luYyAoKSA9PiB0aGlzLmdldFJhdGVMaW1pdHNCeVRva2VuSWQoaWQsIHNpZ25hbCkpO1xuICAgIGlmICh0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKSAhPT0gdG9rZW4gfHwgdG9rZW4uZ2VuZXJhdGlvbiAhPT0gZ2VuZXJhdGlvbikgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChyZXN1bHQua2luZCA9PT0gXCJsb29rdXBfZmFpbGVkXCIpIHtcbiAgICAgIHRoaXMucXVvdGFCbG9ja2VkLmRlbGV0ZShpZCk7XG4gICAgICBsb2dnZXIud2FybihcInF1b3RhX3RocmVzaG9sZCBnYXRlOiBsb29rdXBfZmFpbF9vcGVuXCIsIHtcbiAgICAgICAgdG9rZW5JZDogaWQsXG4gICAgICAgIHRva2VuTmFtZTogdG9rZW4ubmFtZSxcbiAgICAgICAgbG9va3VwUmVhc29uOiByZXN1bHQucmVhc29uLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKHJlc3VsdC51dGlsaXphdGlvblBjdCA+PSB0b2tlbi5xdW90YVRocmVzaG9sZCkge1xuICAgICAgaWYgKCF0aGlzLnF1b3RhQmxvY2tlZC5oYXMoaWQpKVxuICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICBgcXVvdGFfdGhyZXNob2xkIGdhdGU6IG92ZXJfdGhyZXNob2xkICR7dG9rZW4ubmFtZX1bJHtpZH1dICgke3Jlc3VsdC51dGlsaXphdGlvblBjdH0lID49ICR7dG9rZW4ucXVvdGFUaHJlc2hvbGR9JSlgLFxuICAgICAgICApO1xuICAgICAgdGhpcy5xdW90YUJsb2NrZWQuYWRkKGlkKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKHRoaXMucXVvdGFCbG9ja2VkLmRlbGV0ZShpZCkpXG4gICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgYHF1b3RhX3RocmVzaG9sZCBnYXRlOiByZWNvdmVyZWQgJHt0b2tlbi5uYW1lfVske2lkfV0gKCR7cmVzdWx0LnV0aWxpemF0aW9uUGN0fSUgPCAke3Rva2VuLnF1b3RhVGhyZXNob2xkfSUpYCxcbiAgICAgICk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnJhdGVMaW1pdHNDYWNoZS5kZWxldGUoaWQpO1xuICB9XG5cbiAgY291bnRBY3RpdmVUb2tlbnMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gWy4uLnRoaXMudG9rZW5NZXRhZGF0YS52YWx1ZXMoKV0uZmlsdGVyKCh0KSA9PiB0LmFjdGl2ZSkubGVuZ3RoO1xuICB9XG5cbiAgLy8g66qo64uI7YSw66eBIO2PtOungeydgCBUVEwg64K0IOy6kOyLnOunjCDsnb3qs6AgZmV0Y2jtlZjsp4Ag7JWK64qU64ukLiDrr7jsobDtmowg7Yag7YGw7J2AIHVzZWRQZXJjZW506rCAIG51bGzsnbTri6QuXG4gIGdldFF1b3RhU25hcHNob3QoKTogQXJyYXk8e1xuICAgIG5hbWU6IHN0cmluZztcbiAgICB1c2VkUGVyY2VudDogbnVtYmVyIHwgbnVsbDtcbiAgICB0aHJlc2hvbGQ6IG51bWJlciB8IG51bGw7XG4gICAgYmxvY2tlZDogYm9vbGVhbjtcbiAgICByZXNldHNBdDogbnVtYmVyIHwgbnVsbDtcbiAgfT4ge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgcmV0dXJuIFsuLi50aGlzLnRva2VuTWV0YWRhdGEuZW50cmllcygpXVxuICAgICAgLm1hcCgoW2lkLCB0XSkgPT4ge1xuICAgICAgICBjb25zdCBjYWNoZWQgPSB0aGlzLnJhdGVMaW1pdHNDYWNoZS5nZXQoaWQpO1xuICAgICAgICBjb25zdCBmcmVzaCA9XG4gICAgICAgICAgY2FjaGVkICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgICBjYWNoZWQuZ2VuZXJhdGlvbiA9PT0gdC5nZW5lcmF0aW9uICYmXG4gICAgICAgICAgbm93IC0gY2FjaGVkLmNhY2hlZEF0IDwgT3BlbkFJRGlzcGF0Y2hlci5SQVRFX0xJTUlUU19DQUNIRV9UVEw7XG4gICAgICAgIGNvbnN0IHByaW1hcnkgPSBmcmVzaCA/IGNhY2hlZC5kYXRhLnJhdGVMaW1pdHM/LnByaW1hcnkgOiB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbmFtZTogdC5uYW1lLFxuICAgICAgICAgIHVzZWRQZXJjZW50OiBwcmltYXJ5Py51c2VkUGVyY2VudCA/PyBudWxsLFxuICAgICAgICAgIHRocmVzaG9sZDogdC5xdW90YVRocmVzaG9sZCA/PyBudWxsLFxuICAgICAgICAgIGJsb2NrZWQ6IHRoaXMucXVvdGFCbG9ja2VkLmhhcyhpZCksXG4gICAgICAgICAgLy8gd2hhbeydmCBVbml4IOy0iOulvCBlcG9jaCBtc+uhnCDrs4DtmZjtlZzri6QuXG4gICAgICAgICAgcmVzZXRzQXQ6XG4gICAgICAgICAgICBwcmltYXJ5Py5yZXNldHNBdCAhPT0gbnVsbCAmJiBwcmltYXJ5Py5yZXNldHNBdCAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgICAgID8gcHJpbWFyeS5yZXNldHNBdCAqIDEwMDBcbiAgICAgICAgICAgICAgOiBudWxsLFxuICAgICAgICB9O1xuICAgICAgfSlcbiAgICAgIC50b1NvcnRlZCgoYSwgYikgPT4gYS5uYW1lLmxvY2FsZUNvbXBhcmUoYi5u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
|
|
660
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3BlbmFpLWRpc3BhdGNoZXIuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL3V0aWxzL3Byb3ZpZGVycy9vcGVuYWkvb3BlbmFpLWRpc3BhdGNoZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZ2V0TG9nZ2VyIH0gZnJvbSBcIkBsb2d0YXBlL2xvZ3RhcGVcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmltcG9ydCB7XG4gIHR5cGUgSW1hZ2VHZW5lcmF0aW9uTWV0YWRhdGEsXG4gIFF1b3RhVGhyZXNob2xkRXhjZWVkZWRFcnJvcixcbn0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3FncmlkL3FncmlkLnR5cGVzXCI7XG5pbXBvcnQgeyBUb2tlbk1vZGVsIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLm1vZGVsXCI7XG5pbXBvcnQgeyB0eXBlIE9wZW5BSUNyZWRlbnRpYWxzIH0gZnJvbSBcIi4uLy4uLy4uL2FwcGxpY2F0aW9uL3Rva2VuL3Rva2VuLnR5cGVzXCI7XG5pbXBvcnQgeyBpc09wZW5BSUNyZWRlbnRpYWxzIH0gZnJvbSBcIi4uL2NvbW1vbi9jcmVkZW50aWFsc1wiO1xuaW1wb3J0IHsgcmVzb2x2ZU9wZW5BSUVmZm9ydCB9IGZyb20gXCIuLi9jb21tb24vZWZmb3J0XCI7XG5pbXBvcnQge1xuICB0eXBlIEdlbmVyYXRlUmVxdWVzdCxcbiAgdHlwZSBHZW5lcmF0ZVJlc3VsdCxcbiAgdHlwZSBHZW5lcmF0ZVN0cmVhbUNhbGxiYWNrcyxcbiAgdHlwZSBHZW5lcmF0ZWRJbWFnZSxcbiAgdHlwZSBQcm92aWRlckRpc3BhdGNoZXIsXG59IGZyb20gXCIuLi9jb21tb24vcHJvdmlkZXItZGlzcGF0Y2hlclwiO1xuaW1wb3J0IHsgaXNKc29uT2JqZWN0LCBqc29uU3RyaW5nIH0gZnJvbSBcIi4uL2NvbW1vbi9wcm92aWRlci10eXBlc1wiO1xuaW1wb3J0IHsgU21vb3RoV2VpZ2h0ZWRSb3VuZFJvYmluIH0gZnJvbSBcIi4uL2NvbW1vbi9zbW9vdGgtd2VpZ2h0ZWQtcm91bmQtcm9iaW5cIjtcbmltcG9ydCB7IFRoaW5raW5nVmFsaWRhdGlvbkVycm9yIH0gZnJvbSBcIi4uL2NvbW1vbi90aGlua2luZ1wiO1xuaW1wb3J0IHtcbiAgaW1hZ2VNaW1lVHlwZSxcbiAgdHlwZSBKc29uVmFsdWUsXG4gIHR5cGUgT3BlbkFJTm9ybWFsaXplZEV2ZW50LFxuICB0eXBlIE9wZW5BSVJlc3BvbnNlSXRlbSxcbiAgdHlwZSBPcGVuQUlSZXNwb25zZXNPcHRpb25zLFxufSBmcm9tIFwiLi9vcGVuYWktYmFja2VuZC1wcm90b2NvbFwiO1xuaW1wb3J0IHsgT3BlbkFJRGlyZWN0Q2xpZW50LCB0eXBlIE9wZW5BSURpcmVjdENsaWVudE9wdGlvbnMgfSBmcm9tIFwiLi9vcGVuYWktZGlyZWN0LWNsaWVudFwiO1xuaW1wb3J0IHsgcmVhZE9wZW5BSVF1b3RhVXNhZ2UsIHR5cGUgT3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhIH0gZnJvbSBcIi4vb3BlbmFpLXF1b3RhXCI7XG5pbXBvcnQgeyBoYW5kbGVDaGF0Z3B0QXV0aFRva2Vuc1JlZnJlc2ggfSBmcm9tIFwiLi9vcGVuYWktcmVmcmVzaFwiO1xuaW1wb3J0IHsgdHlwZSBPcGVuQUlUcmFuc3BvcnRLaW5kLCByZXNvbHZlT3BlbkFJVHJhbnNwb3J0S2luZCB9IGZyb20gXCIuL29wZW5haS10cmFuc3BvcnQtY29uZmlnXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGdldExvZ2dlcihbXCJxZ3JpZFwiLCBcIm9wZW5haS1kaXNwYXRjaGVyXCJdKTtcblxuLy8gVmVyaWZpZWQgd2l0aCB0aGUgc3Vic2NyaXB0aW9uIFJlc3BvbnNlcyBiYWNrZW5kOyBwdWJsaWMgQVBJIHN1cHBvcnQgaXMgbm90IHN1ZmZpY2llbnQuXG5jb25zdCBUSElOS0lOR19PRkZfTU9ERUxTID0gbmV3IFNldChbXG4gIFwiZ3B0LTYtc29sXCIsXG4gIFwiZ3B0LTYtbHVuYVwiLFxuICBcImdwdC01LjYtc29sXCIsXG4gIFwiZ3B0LTUuNi10ZXJyYVwiLFxuICBcImdwdC01LjYtbHVuYVwiLFxuICBcImdwdC01LjVcIixcbl0pO1xuXG5jb25zdCBERUZBVUxUX1JFUVVFU1RfVElNRU9VVF9NUyA9IDYwMF8wMDA7XG5jb25zdCBJTUFHRV9UT09MID0gXCJnZW5lcmF0ZV9pbWFnZVwiO1xuXG50eXBlIEltYWdlVG9vbEFyZ3VtZW50cyA9IHtcbiAgcHJvbXB0OiBzdHJpbmc7XG4gIHRyYW5zcGFyZW50X2JhY2tncm91bmQ6IGJvb2xlYW47XG4gIG51bV9sYXN0X2ltYWdlc190b19pbmNsdWRlOiBudW1iZXI7XG59O1xuXG4vLyBFeGFjdGx5IHRoZXNlIHRocmVlIGtleXM7IHRoZSBiYWNrZW5kIHJlamVjdHMgc3RyaWN0IHRvb2xzLCBzbyBhcmd1bWVudHMgYXJlIHZhbGlkYXRlZCBoZXJlLlxuY29uc3QgSW1hZ2VUb29sQXJndW1lbnRzU2NoZW1hID0gei5zdHJpY3RPYmplY3Qoe1xuICBwcm9tcHQ6IHouc3RyaW5nKCkucmVmaW5lKChwcm9tcHQpID0+IHByb21wdC50cmltKCkubGVuZ3RoID4gMCksXG4gIHRyYW5zcGFyZW50X2JhY2tncm91bmQ6IHouYm9vbGVhbigpLFxuICBudW1fbGFzdF9pbWFnZXNfdG9faW5jbHVkZTogei5udW1iZXIoKS5pbnQoKS5taW4oMCkubWF4KDUpLFxufSk7XG5cbmZ1bmN0aW9uIGdlbmVyYXRlZEltYWdlRnJvbShcbiAgZXZlbnQ6IEV4dHJhY3Q8T3BlbkFJTm9ybWFsaXplZEV2ZW50LCB7IHR5cGU6IFwiaW1hZ2VcIiB9Pixcbik6IEdlbmVyYXRlZEltYWdlIHtcbiAgY29uc3QgaW1hZ2U6IEdlbmVyYXRlZEltYWdlID0ge1xuICAgIGRhdGE6IGV2ZW50LmJhc2U2NCxcbiAgICBtZWRpYVR5cGU6IGV2ZW50Lm1pbWVUeXBlLFxuICAgIHJldmlzZWRQcm9tcHQ6IGV2ZW50LnJldmlzZWRQcm9tcHQgPz8gbnVsbCxcbiAgfTtcblxuICBpZiAoZXZlbnQuZ2VuZXJhdGlvbikgaW1hZ2UuZ2VuZXJhdGlvbiA9IGV2ZW50LmdlbmVyYXRpb247XG5cbiAgcmV0dXJuIGltYWdlO1xufVxuXG5leHBvcnQgdHlwZSBJbWFnZUZhaWx1cmVLaW5kID0gXCJnYXRlXCIgfCBcIm5vdF9jYWxsZWRcIiB8IFwiaW5jb21wbGV0ZVwiO1xuXG5leHBvcnQgY2xhc3MgSW1hZ2VHZW5lcmF0aW9uRXJyb3IgZXh0ZW5kcyBFcnJvciB7XG4gIGNvbXBsZXRlZERyaXZlcj86IEdlbmVyYXRlUmVzdWx0O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHJlYWRvbmx5IGtpbmQ6IEltYWdlRmFpbHVyZUtpbmQsXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICAgIG9wdGlvbnM/OiBFcnJvck9wdGlvbnMsXG4gICkge1xuICAgIHN1cGVyKG1lc3NhZ2UsIG9wdGlvbnMpO1xuICAgIHRoaXMubmFtZSA9IFwiSW1hZ2VHZW5lcmF0aW9uRXJyb3JcIjtcbiAgfVxufVxuXG50eXBlIFRva2VuTWV0YWRhdGEgPSB7XG4gIG5hbWU6IHN0cmluZztcbiAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzO1xuICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGw7XG4gIHdlaWdodDogbnVtYmVyO1xuICBhY3RpdmU6IGJvb2xlYW47XG4gIGdlbmVyYXRpb246IG51bWJlcjtcbn07XG5cbnR5cGUgVG9rZW5TZWxlY3Rpb24gPSB7IHRva2VuSWQ6IG51bWJlcjsgbWV0YWRhdGE6IFRva2VuTWV0YWRhdGEgfTtcblxuZXhwb3J0IHR5cGUgT3BlbkFJRGlyZWN0Q2xpZW50RmFjdG9yeSA9IChcbiAgb3B0aW9uczogT3BlbkFJRGlyZWN0Q2xpZW50T3B0aW9ucyxcbiAgdG9rZW5JZDogbnVtYmVyLFxuKSA9PiBQaWNrPE9wZW5BSURpcmVjdENsaWVudCwgXCJyZXNwb25zZXNcIj4gJiB7IGNsb3NlPzogKCkgPT4gdm9pZCB9O1xuXG50eXBlIENsaWVudEVudHJ5ID0ge1xuICBnZW5lcmF0aW9uOiBudW1iZXI7XG4gIGNsaWVudDogUGljazxPcGVuQUlEaXJlY3RDbGllbnQsIFwicmVzcG9uc2VzXCI+ICYgeyBjbG9zZT86ICgpID0+IHZvaWQgfTtcbiAgaW5GbGlnaHQ6IG51bWJlcjtcbiAgcmV0aXJlZDogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlbkFJRGlzcGF0Y2hlckRlcGVuZGVuY2llcyB7XG4gIGNsaWVudEZhY3Rvcnk/OiBPcGVuQUlEaXJlY3RDbGllbnRGYWN0b3J5O1xuICBmZXRjaD86IHR5cGVvZiBmZXRjaDtcbn1cblxuZnVuY3Rpb24gYWJvcnRFcnJvcihzaWduYWw6IEFib3J0U2lnbmFsKTogRXJyb3Ige1xuICBjb25zdCByZWFzb24gPSBzaWduYWwucmVhc29uO1xuXG4gIHJldHVybiByZWFzb24gaW5zdGFuY2VvZiBFcnJvciA/IHJlYXNvbiA6IG5ldyBET01FeGNlcHRpb24oXCJBYm9ydGVkXCIsIFwiQWJvcnRFcnJvclwiKTtcbn1cblxuZnVuY3Rpb24gYWN0aXZlU2lnbmFsKHNpZ25hbD86IEFib3J0U2lnbmFsLCB0aW1lb3V0TXM/OiBudW1iZXIpOiBBYm9ydFNpZ25hbCB7XG4gIGNvbnN0IHRpbWVvdXQgPSBBYm9ydFNpZ25hbC50aW1lb3V0KHRpbWVvdXRNcyA/PyBERUZBVUxUX1JFUVVFU1RfVElNRU9VVF9NUyk7XG5cbiAgcmV0dXJuIHNpZ25hbCA/IEFib3J0U2lnbmFsLmFueShbc2lnbmFsLCB0aW1lb3V0XSkgOiB0aW1lb3V0O1xufVxuXG5mdW5jdGlvbiBxdW90YU1lc3NhZ2UoZW50cmllczogQXJyYXk8eyBuYW1lOiBzdHJpbmc7IHRocmVzaG9sZDogbnVtYmVyIH0+KTogc3RyaW5nIHtcbiAgY29uc3QgZGV0YWlsID0gZW50cmllcy5tYXAoKGUpID0+IGAke2UubmFtZX0gKHRocmVzaG9sZCAke2UudGhyZXNob2xkfSUpYCkuam9pbihcIiwgXCIpO1xuXG4gIHJldHVybiBkZXRhaWxcbiAgICA/IGBBbGwgb3BlbmFpIHRva2VucyBleGNlZWRlZCBxdW90YSB0aHJlc2hvbGQ6ICR7ZGV0YWlsfWBcbiAgICA6IFwiQWxsIG9wZW5haSB0b2tlbnMgZXhjZWVkZWQgcXVvdGEgdGhyZXNob2xkXCI7XG59XG5cbmZ1bmN0aW9uIGlucHV0SXRlbXMocmVxOiBHZW5lcmF0ZVJlcXVlc3QpOiBKc29uVmFsdWVbXSB7XG4gIGNvbnN0IGhpc3RvcnkgPSByZXEuY29sZEhpc3RvcnkgPz8gW107XG5cbiAgY29uc3QgY29udGVudDogT3BlbkFJUmVzcG9uc2VJdGVtW10gPSByZXEuY29sZElucHV0Lm1hcCgoaW5wdXQpID0+IHtcbiAgICBpZiAoaW5wdXQudHlwZSA9PT0gXCJ0ZXh0XCIpIHJldHVybiB7IHR5cGU6IFwiaW5wdXRfdGV4dFwiLCB0ZXh0OiBpbnB1dC50ZXh0IH07XG5cbiAgICBpZiAoaW5wdXQudHlwZSA9PT0gXCJpbWFnZVwiKSByZXR1cm4geyB0eXBlOiBcImlucHV0X2ltYWdlXCIsIGltYWdlX3VybDogaW5wdXQudXJsIH07XG5cbiAgICBpZiAoaW5wdXQudHlwZSA9PT0gXCJsb2NhbEltYWdlXCIpIHJldHVybiB7IHR5cGU6IFwiaW5wdXRfaW1hZ2VcIiwgaW1hZ2VfdXJsOiBpbnB1dC5wYXRoIH07XG5cbiAgICByZXR1cm4geyB0eXBlOiBcImlucHV0X3RleHRcIiwgdGV4dDogYCR7aW5wdXQubmFtZX06ICR7aW5wdXQucGF0aH1gIH07XG4gIH0pO1xuXG4gIHJldHVybiBbLi4uaGlzdG9yeSwgeyB0eXBlOiBcIm1lc3NhZ2VcIiwgcm9sZTogXCJ1c2VyXCIsIGNvbnRlbnQgfV07XG59XG5cbmZ1bmN0aW9uIGltYWdlUmVmZXJlbmNlcyhyZXE6IEdlbmVyYXRlUmVxdWVzdCk6IE9wZW5BSVJlc3BvbnNlSXRlbVtdIHtcbiAgcmV0dXJuIGlucHV0SXRlbXMocmVxKS5mbGF0TWFwKChpdGVtKSA9PiB7XG4gICAgaWYgKCFpc0pzb25PYmplY3QoaXRlbSkpIHJldHVybiBbXTtcbiAgICBjb25zdCByZXN1bHQgPSBqc29uU3RyaW5nKGl0ZW0ucmVzdWx0KTtcblxuICAgIGlmIChpdGVtLnR5cGUgPT09IFwiaW1hZ2VfZ2VuZXJhdGlvbl9jYWxsXCIgJiYgcmVzdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0eXBlOiBcImlucHV0X2ltYWdlXCIsXG4gICAgICAgICAgaW1hZ2VfdXJsOiBgZGF0YToke2ltYWdlTWltZVR5cGUocmVzdWx0LCBpdGVtLm91dHB1dF9mb3JtYXQpfTtiYXNlNjQsJHtyZXN1bHR9YCxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgfVxuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGl0ZW0uY29udGVudCkpIHJldHVybiBbXTtcblxuICAgIHJldHVybiBpdGVtLmNvbnRlbnRcbiAgICAgIC5maWx0ZXIoaXNKc29uT2JqZWN0KVxuICAgICAgLmZpbHRlcigocGFydCkgPT4gcGFydC50eXBlID09PSBcImlucHV0X2ltYWdlXCIgfHwgcGFydC50eXBlID09PSBcImltYWdlX3VybFwiKTtcbiAgfSk7XG59XG5cbnR5cGUgT3BlbkFJUmVhc29uaW5nID0gTm9uTnVsbGFibGU8T3BlbkFJUmVzcG9uc2VzT3B0aW9uc1tcInJlYXNvbmluZ1wiXT47XG5cbmZ1bmN0aW9uIGFzUmVhc29uaW5nKHJlcTogR2VuZXJhdGVSZXF1ZXN0KTogT3BlbkFJUmVhc29uaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHJlcS50aGlua2luZyA9PT0gZmFsc2UpIHJldHVybiB7IGVmZm9ydDogXCJub25lXCIgfTtcblxuICBjb25zdCBzdW1tYXJ5ID1cbiAgICByZXEucmVhc29uaW5nU3VtbWFyeSAmJiByZXEucmVhc29uaW5nU3VtbWFyeSAhPT0gXCJub25lXCIgPyByZXEucmVhc29uaW5nU3VtbWFyeSA6IHVuZGVmaW5lZDtcblxuICBjb25zdCBlZmZvcnQgPVxuICAgIHJlc29sdmVPcGVuQUlFZmZvcnQocmVxLm1vZGVsID8/IFwiXCIsIHJlcS5lZmZvcnQpID8/IChyZXEudGhpbmtpbmcgPT09IHRydWUgPyBcImxvd1wiIDogdW5kZWZpbmVkKTtcblxuICBpZiAoIWVmZm9ydCAmJiAhc3VtbWFyeSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICBjb25zdCByZWFzb25pbmc6IE9wZW5BSVJlYXNvbmluZyA9IHt9O1xuXG4gIGlmIChlZmZvcnQpIHJlYXNvbmluZy5lZmZvcnQgPSBlZmZvcnQ7XG5cbiAgaWYgKHN1bW1hcnkpIHJlYXNvbmluZy5zdW1tYXJ5ID0gc3VtbWFyeTtcblxuICByZXR1cm4gcmVhc29uaW5nO1xufVxuXG5jb25zdCBBVVRPX0lNQUdFX0lOU1RSVUNUSU9OUyA9XG4gIFwiVXNlIGdlbmVyYXRlX2ltYWdlIHdoZW4gaW1hZ2UgZ2VuZXJhdGlvbiBvciBlZGl0aW5nIGlzIG5lZWRlZDsgb3RoZXJ3aXNlIHJlcGx5IHdpdGggdGV4dC4gQ2FsbCBpdCBhdCBtb3N0IG9uY2UgcGVyIHJlc3BvbnNlLiBTdXBwbHkgYSBjb21wbGV0ZSwgc2VsZi1jb250YWluZWQgcHJvbXB0IHdpdGggYWxsIHJlbGV2YW50IGNvbnZlcnNhdGlvbiBpbnN0cnVjdGlvbnMuIFNldCB0cmFuc3BhcmVudF9iYWNrZ3JvdW5kIHRvIHRydWUgb25seSB3aGVuIGEgdHJhbnNwYXJlbnQgYmFja2dyb3VuZCBpcyByZXF1ZXN0ZWQuIFNldCBudW1fbGFzdF9pbWFnZXNfdG9faW5jbHVkZSB0byAwIGZvciBhIG5ldyBpbWFnZSB3aXRob3V0IHJlZmVyZW5jZXMuIEZvciBlZGl0aW5nIG9yIHJlZmVyZW5jZS1iYXNlZCBnZW5lcmF0aW9uLCBjaG9vc2UgdGhlIHNtYWxsZXN0IG51bWJlciBvZiByZWNlbnQgY29udmVyc2F0aW9uIGltYWdlcyB0aGF0IGluY2x1ZGVzIGFsbCBuZWVkZWQgcmVmZXJlbmNlcywgYXQgbW9zdCA1LiBSZWZlcmVuY2VzIHJldGFpbiB0aGVpciBjaHJvbm9sb2dpY2FsIG9yZGVyLiBEbyBub3Qgc2VsZWN0IGltYWdlcyBmb3IgYW4gdW5yZWxhdGVkIG5ldyByZXF1ZXN0LlwiO1xuXG5jb25zdCBBVVRPX0lNQUdFX1RPT0w6IE9wZW5BSVJlc3BvbnNlSXRlbSA9IHtcbiAgdHlwZTogXCJmdW5jdGlvblwiLFxuICBuYW1lOiBJTUFHRV9UT09MLFxuICBkZXNjcmlwdGlvbjpcbiAgICBcIkdlbmVyYXRlIG9yIGVkaXQgYW4gaW1hZ2UsIG9wdGlvbmFsbHkgd2l0aCBhIHRyYW5zcGFyZW50IGJhY2tncm91bmQgb3IgcmVjZW50IGNvbnZlcnNhdGlvbiBpbWFnZXMgYXMgcmVmZXJlbmNlcy5cIixcbiAgLy8gQXN0cmEncyBzdWJzY3JpcHRpb24gYmFja2VuZCByZWplY3RzIHN0cmljdCB0b29sczsgdmFsaWRhdGUgYXJndW1lbnRzIGxvY2FsbHkuXG4gIHN0cmljdDogZmFsc2UsXG4gIHBhcmFtZXRlcnM6IHtcbiAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgIHByb3BlcnRpZXM6IHtcbiAgICAgIHByb21wdDoge1xuICAgICAgICB0eXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBtaW5MZW5ndGg6IDEsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIkNvbXBsZXRlLCBzZWxmLWNvbnRhaW5lZCBpbnN0cnVjdGlvbnMgZm9yIHRoZSBpbWFnZSBnZW5lcmF0aW9uIG9yIGVkaXQuXCIsXG4gICAgICB9LFxuICAgICAgdHJhbnNwYXJlbnRfYmFja2dyb3VuZDogeyB0eXBlOiBcImJvb2xlYW5cIiB9LFxuICAgICAgbnVtX2xhc3RfaW1hZ2VzX3RvX2luY2x1ZGU6IHsgdHlwZTogXCJpbnRlZ2VyXCIsIG1pbmltdW06IDAsIG1heGltdW06IDUgfSxcbiAgICB9LFxuICAgIHJlcXVpcmVkOiBbXCJwcm9tcHRcIiwgXCJ0cmFuc3BhcmVudF9iYWNrZ3JvdW5kXCIsIFwibnVtX2xhc3RfaW1hZ2VzX3RvX2luY2x1ZGVcIl0sXG4gICAgYWRkaXRpb25hbFByb3BlcnRpZXM6IGZhbHNlLFxuICB9LFxufTtcblxuZnVuY3Rpb24gcmVxdWVzdE9wdGlvbnMocmVxOiBHZW5lcmF0ZVJlcXVlc3QpOiBPcGVuQUlSZXNwb25zZXNPcHRpb25zIHtcbiAgY29uc3QgeyBvdXRwdXRGb3JtYXQsIC4uLmltYWdlQ29udHJvbHMgfSA9IHJlcS5pbWFnZUdlbmVyYXRpb25PcHRpb25zID8/IHt9O1xuICBjb25zdCBhdXRvID0gcmVxLmltYWdlR2VuZXJhdGlvbiA9PT0gXCJhdXRvXCI7XG5cbiAgaWYgKGF1dG8gJiYgcmVxLm91dHB1dFNjaGVtYSkge1xuICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcbiAgICAgIFwiZ2F0ZVwiLFxuICAgICAgXCJBdXRvbWF0aWMgaW1hZ2UgZ2VuZXJhdGlvbiBkb2VzIG5vdCBzdXBwb3J0IHN0cnVjdHVyZWQgb3V0cHV0IG9yIGV4dGVybmFsIHRvb2xzXCIsXG4gICAgKTtcbiAgfVxuXG4gIGlmIChhdXRvICYmIG91dHB1dEZvcm1hdCAmJiBvdXRwdXRGb3JtYXQgIT09IFwicG5nXCIpIHtcbiAgICB0aHJvdyBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXCJnYXRlXCIsIFwiQXV0b21hdGljIGltYWdlIGdlbmVyYXRpb24gb25seSBzdXBwb3J0cyBQTkcgb3V0cHV0XCIpO1xuICB9XG5cbiAgY29uc3Qgb3B0aW9uczogT3BlbkFJUmVzcG9uc2VzT3B0aW9ucyA9IHsgbW9kZWw6IHJlcS5tb2RlbCA/PyBcIlwiLCBoaXN0b3J5OiBpbnB1dEl0ZW1zKHJlcSkgfTtcblxuICBpZiAocmVxLnN5c3RlbVByb21wdCkgb3B0aW9ucy5pbnN0cnVjdGlvbnMgPSByZXEuc3lzdGVtUHJvbXB0O1xuXG4gIGlmIChhdXRvKSB7XG4gICAgb3B0aW9ucy5pbnN0cnVjdGlvbnMgPSBbcmVxLnN5c3RlbVByb21wdCwgQVVUT19JTUFHRV9JTlNUUlVDVElPTlNdLmZpbHRlcihCb29sZWFuKS5qb2luKFwiXFxuXFxuXCIpO1xuICAgIG9wdGlvbnMucGFyYWxsZWxUb29sQ2FsbHMgPSBmYWxzZTtcbiAgICBvcHRpb25zLnRvb2xzID0gW0FVVE9fSU1BR0VfVE9PTF07XG4gIH1cblxuICBjb25zdCByZWFzb25pbmcgPSBhc1JlYXNvbmluZyhyZXEpO1xuXG4gIGlmIChyZWFzb25pbmcpIG9wdGlvbnMucmVhc29uaW5nID0gcmVhc29uaW5nO1xuXG4gIGlmIChyZXEudmVyYm9zaXR5KSBvcHRpb25zLnZlcmJvc2l0eSA9IHJlcS52ZXJib3NpdHk7XG5cbiAgaWYgKHJlcS5zZXJ2aWNlVGllcikge1xuICAgIG9wdGlvbnMuc2VydmljZVRpZXIgPSByZXEuc2VydmljZVRpZXIgPT09IFwiZmFzdFwiID8gXCJwcmlvcml0eVwiIDogcmVxLnNlcnZpY2VUaWVyO1xuICB9XG5cbiAgaWYgKHJlcS5wcm9tcHRDYWNoZUtleSkgb3B0aW9ucy5wcm9tcHRDYWNoZUtleSA9IHJlcS5wcm9tcHRDYWNoZUtleTtcblxuICBpZiAocmVxLm91dHB1dFNjaGVtYSkgb3B0aW9ucy5vdXRwdXRTY2hlbWEgPSB7IHNjaGVtYTogcmVxLm91dHB1dFNjaGVtYSB9O1xuXG4gIGlmIChyZXEuaW1hZ2VHZW5lcmF0aW9uICYmICFhdXRvKSB7XG4gICAgaWYgKHJlcS5pbWFnZUdlbmVyYXRpb25PcHRpb25zKSB7XG4gICAgICBjb25zdCBjb250cm9sczogT3BlbkFJUmVzcG9uc2VJdGVtID0geyAuLi5pbWFnZUNvbnRyb2xzIH07XG5cbiAgICAgIGlmIChvdXRwdXRGb3JtYXQpIGNvbnRyb2xzLm91dHB1dF9mb3JtYXQgPSBvdXRwdXRGb3JtYXQ7XG4gICAgICBvcHRpb25zLmltYWdlR2VuZXJhdGlvbiA9IGNvbnRyb2xzO1xuICAgIH0gZWxzZSB7XG4gICAgICBvcHRpb25zLmltYWdlR2VuZXJhdGlvbiA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9wdGlvbnM7XG59XG5cbi8vIHF1b3Rh7JmAIGNhY2hlIGFmZmluaXR566GcIO2GoO2BsOydhCDshKDtg53tlbQgSFRUUFMvV1ProZwg7KCE7Iah7ZWc64ukLiDroZzsu6wg64+Z7Iuc7ISxIOygnO2VnOydgCDsl4bri6QuXG5leHBvcnQgY2xhc3MgT3BlbkFJRGlzcGF0Y2hlciBpbXBsZW1lbnRzIFByb3ZpZGVyRGlzcGF0Y2hlciB7XG4gIHJlYWRvbmx5IHRva2VuTWV0YWRhdGEgPSBuZXcgTWFwPG51bWJlciwgVG9rZW5NZXRhZGF0YT4oKTtcbiAgcmVhZG9ubHkgdHJhbnNwb3J0S2luZDogT3BlbkFJVHJhbnNwb3J0S2luZDtcbiAgcmVhZG9ubHkgcmF0ZUxpbWl0c0NhY2hlID0gbmV3IE1hcDxudW1iZXIsIE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YSAmIHsgZ2VuZXJhdGlvbjogbnVtYmVyIH0+KCk7XG4gIHJlYWRvbmx5IHBlbmRpbmdSYXRlTGltaXRzID0gbmV3IE1hcDxcbiAgICBudW1iZXIsXG4gICAgeyB0b2tlbjogVG9rZW5NZXRhZGF0YTsgZ2VuZXJhdGlvbjogbnVtYmVyOyBwcm9taXNlOiBQcm9taXNlPE9wZW5BSVJhdGVMaW1pdHNXaXRoTWV0YT4gfVxuICA+KCk7XG4gIHJlYWRvbmx5IGNsaWVudHMgPSBuZXcgTWFwPG51bWJlciwgQ2xpZW50RW50cnk+KCk7XG4gIHJlYWRvbmx5IHJldGlyZWRDbGllbnRzID0gbmV3IFNldDxDbGllbnRFbnRyeT4oKTtcbiAgc3RhdGljIHJlYWRvbmx5IFJBVEVfTElNSVRTX0NBQ0hFX1RUTCA9IDYwXzAwMDtcblxuICByZWFkb25seSBzZWxlY3RvciA9IG5ldyBTbW9vdGhXZWlnaHRlZFJvdW5kUm9iaW4oKTtcbiAgcmVhZG9ubHkgY2xpZW50RmFjdG9yeTogT3BlbkFJRGlyZWN0Q2xpZW50RmFjdG9yeTtcbiAgcmVhZG9ubHkgZmV0Y2hJbXBsOiB0eXBlb2YgZmV0Y2g7XG4gIHJlYWRvbmx5IHF1b3RhQmxvY2tlZCA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICBpbkZsaWdodCA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgdHJhbnNwb3J0S2luZDogT3BlbkFJVHJhbnNwb3J0S2luZCA9IHJlc29sdmVPcGVuQUlUcmFuc3BvcnRLaW5kKCksXG4gICAgZGVwZW5kZW5jaWVzOiBPcGVuQUlEaXNwYXRjaGVyRGVwZW5kZW5jaWVzID0ge30sXG4gICkge1xuICAgIHRoaXMudHJhbnNwb3J0S2luZCA9IHRyYW5zcG9ydEtpbmQ7XG4gICAgdGhpcy5jbGllbnRGYWN0b3J5ID1cbiAgICAgIGRlcGVuZGVuY2llcy5jbGllbnRGYWN0b3J5ID8/ICgob3B0aW9ucykgPT4gbmV3IE9wZW5BSURpcmVjdENsaWVudChvcHRpb25zKSk7XG4gICAgdGhpcy5mZXRjaEltcGwgPSBkZXBlbmRlbmNpZXMuZmV0Y2ggPz8gZmV0Y2g7XG4gIH1cblxuICBhc3luYyBzdGFydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IHJvd3MgfSA9IGF3YWl0IFRva2VuTW9kZWwuZmluZE1hbnkoXCJBXCIpO1xuXG4gICAgZm9yIChjb25zdCByb3cgb2Ygcm93cykge1xuICAgICAgaWYgKHJvdy5wcm92aWRlciAhPT0gXCJvcGVuYWlcIikgY29udGludWU7XG5cbiAgICAgIGlmICghaXNPcGVuQUlDcmVkZW50aWFscyhyb3cuY3JlZGVudGlhbHMpKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKGBza2lwcGluZyB0b2tlbiAke3Jvdy5uYW1lfTogY3JlZGVudGlhbHMgYXJlIG5vdCBPcGVuQUkgT0F1dGggY3JlZGVudGlhbHNgKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2V0VG9rZW4ocm93LmlkLCByb3cubmFtZSwgcm93LmNyZWRlbnRpYWxzLCByb3cucXVvdGFfdGhyZXNob2xkLCByb3cud2VpZ2h0LCByb3cuYWN0aXZlKTtcbiAgICB9XG5cbiAgICBsb2dnZXIuaW5mbyhgc3RhcnRlZCBkaXJlY3QgT3BlbkFJIHJ1bnRpbWUgd2l0aCAke3RoaXMudG9rZW5NZXRhZGF0YS5zaXplfSB0b2tlbnNgKTtcbiAgfVxuXG4gIGFzeW5jIHN0b3AoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5jbGllbnRzLmZvckVhY2goKHsgY2xpZW50IH0pID0+IGNsaWVudC5jbG9zZT8uKCkpO1xuICAgIHRoaXMuY2xpZW50cy5jbGVhcigpO1xuICAgIHRoaXMucmV0aXJlZENsaWVudHMuZm9yRWFjaCgoZW50cnkpID0+IGVudHJ5LmNsaWVudC5jbG9zZT8uKCkpO1xuICAgIHRoaXMucmV0aXJlZENsaWVudHMuY2xlYXIoKTtcbiAgICB0aGlzLnRva2VuTWV0YWRhdGEuY2xlYXIoKTtcbiAgICB0aGlzLnJhdGVMaW1pdHNDYWNoZS5jbGVhcigpO1xuICAgIHRoaXMucXVvdGFCbG9ja2VkLmNsZWFyKCk7XG4gICAgdGhpcy5zZWxlY3Rvci5yZXNldFNjb3JlcygpO1xuICB9XG5cbiAgYXN5bmMgb25Ub2tlbkFkZGVkKFxuICAgIGlkOiBudW1iZXIsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscyxcbiAgICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGwsXG4gICAgd2VpZ2h0ID0gMSxcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5zZXRUb2tlbihpZCwgbmFtZSwgY3JlZGVudGlhbHMsIHF1b3RhVGhyZXNob2xkLCB3ZWlnaHQsIHRydWUpO1xuICB9XG5cbiAgYXN5bmMgb25Ub2tlblVwZGF0ZWQoXG4gICAgaWQ6IG51bWJlcixcbiAgICBuYW1lOiBzdHJpbmcsXG4gICAgY3JlZGVudGlhbHM6IE9wZW5BSUNyZWRlbnRpYWxzLFxuICAgIHF1b3RhVGhyZXNob2xkPzogbnVtYmVyIHwgbnVsbCxcbiAgICB3ZWlnaHQgPSAxLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBvbGQgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcbiAgICB0aGlzLnNldFRva2VuKGlkLCBuYW1lLCBjcmVkZW50aWFscywgcXVvdGFUaHJlc2hvbGQsIHdlaWdodCwgb2xkPy5hY3RpdmUgPz8gdHJ1ZSk7XG4gIH1cblxuICBhc3luYyBvblRva2VuUmVtb3ZlZChpZDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5yZXRpcmVDbGllbnQoaWQpO1xuICAgIHRoaXMudG9rZW5NZXRhZGF0YS5kZWxldGUoaWQpO1xuICAgIHRoaXMuc2VsZWN0b3IucmVtb3ZlVG9rZW4oaWQpO1xuICAgIHRoaXMuaW52YWxpZGF0ZVJhdGVMaW1pdHNDYWNoZShpZCk7XG4gICAgdGhpcy5xdW90YUJsb2NrZWQuZGVsZXRlKGlkKTtcbiAgfVxuXG4gIG9uVG9rZW5EZWFjdGl2YXRlZChpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcblxuICAgIGlmICh0b2tlbikgdG9rZW4uYWN0aXZlID0gZmFsc2U7XG4gICAgdGhpcy5zZWxlY3Rvci5yZXNldFNjb3JlcygpO1xuICB9XG5cbiAgb25Ub2tlbkFjdGl2YXRlZChpZDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKTtcblxuICAgIGlmICh0b2tlbikgdG9rZW4uYWN0aXZlID0gdHJ1ZTtcbiAgICB0aGlzLnNlbGVjdG9yLnJlc2V0U2NvcmVzKCk7XG4gIH1cblxuICBhc3luYyByZXBsYWNlVG9rZW5zKFxuICAgIHJvd3M6IEFycmF5PHtcbiAgICAgIGlkOiBudW1iZXI7XG4gICAgICBuYW1lOiBzdHJpbmc7XG4gICAgICBjcmVkZW50aWFsczogT3BlbkFJQ3JlZGVudGlhbHM7XG4gICAgICBxdW90YVRocmVzaG9sZD86IG51bWJlciB8IG51bGw7XG4gICAgICB3ZWlnaHQ6IG51bWJlcjtcbiAgICB9PixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgaWRzID0gbmV3IFNldChyb3dzLm1hcCgocikgPT4gci5pZCkpO1xuXG4gICAgZm9yIChjb25zdCBpZCBvZiB0aGlzLnRva2VuTWV0YWRhdGEua2V5cygpKSBpZiAoIWlkcy5oYXMoaWQpKSBhd2FpdCB0aGlzLm9uVG9rZW5SZW1vdmVkKGlkKTtcblxuICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpXG4gICAgICBhd2FpdCB0aGlzLm9uVG9rZW5VcGRhdGVkKHJvdy5pZCwgcm93Lm5hbWUsIHJvdy5jcmVkZW50aWFscywgcm93LnF1b3RhVGhyZXNob2xkLCByb3cud2VpZ2h0KTtcbiAgfVxuXG4gIGFzeW5jIGdlbmVyYXRlKHJlcTogR2VuZXJhdGVSZXF1ZXN0KTogUHJvbWlzZTxHZW5lcmF0ZVJlc3VsdD4ge1xuICAgIHJldHVybiB0aGlzLnJ1bihyZXEpO1xuICB9XG5cbiAgYXN5bmMgZ2VuZXJhdGVTdHJlYW0ocmVxOiBHZW5lcmF0ZVJlcXVlc3QsIGNiOiBHZW5lcmF0ZVN0cmVhbUNhbGxiYWNrcyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmIChyZXEuaW1hZ2VHZW5lcmF0aW9uKVxuICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFxuICAgICAgICBcImdhdGVcIixcbiAgICAgICAgXCJpbWFnZSBnZW5lcmF0aW9uIGlzIG5vdCBzdXBwb3J0ZWQgb24gdGhlIHN0cmVhbWluZyBwYXRoXCIsXG4gICAgICApO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNiLm9uQ29tcGxldGUoYXdhaXQgdGhpcy5ydW4ocmVxLCBjYi5vbkRlbHRhKSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNiLm9uRXJyb3IoZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpKTtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHJ1bihyZXE6IEdlbmVyYXRlUmVxdWVzdCwgb25EZWx0YT86ICh0ZXh0OiBzdHJpbmcpID0+IHZvaWQpOiBQcm9taXNlPEdlbmVyYXRlUmVzdWx0PiB7XG4gICAgaWYgKHJlcS50aGlua2luZyA9PT0gZmFsc2UpIHtcbiAgICAgIGNvbnN0IG1vZGVsID0gcmVxLm1vZGVsID8/IFwiXCI7XG5cbiAgICAgIGlmICghVEhJTktJTkdfT0ZGX01PREVMUy5oYXMobW9kZWwpKSB7XG4gICAgICAgIGNvbnN0IHJlYXNvbiA9XG4gICAgICAgICAgbW9kZWwgPT09IFwiZ3B0LTYtYXN0cmFcIiB8fCBtb2RlbCA9PT0gXCJncHQtNi4xLXNvbFwiXG4gICAgICAgICAgICA/IFwidGhlIHN1YnNjcmlwdGlvbiBiYWNrZW5kIHJlcXVpcmVzIHRoaW5raW5nXCJcbiAgICAgICAgICAgIDogXCJ0aGlua2luZy1vZmYgc3VwcG9ydCBoYXMgbm90IGJlZW4gdmVyaWZpZWQgb24gdGhlIHN1YnNjcmlwdGlvbiBiYWNrZW5kXCI7XG5cbiAgICAgICAgdGhyb3cgbmV3IFRoaW5raW5nVmFsaWRhdGlvbkVycm9yKFxuICAgICAgICAgIGB0aGlua2luZzpmYWxzZSBpcyB1bmF2YWlsYWJsZSBmb3IgT3BlbkFJIG1vZGVsICR7bW9kZWwgfHwgXCI8ZGVmYXVsdD5cIn06ICR7cmVhc29ufWAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgc2lnbmFsID0gYWN0aXZlU2lnbmFsKHJlcS5hYm9ydFNpZ25hbCwgcmVxLnRpbWVvdXRNcyk7XG5cbiAgICBpZiAoc2lnbmFsLmFib3J0ZWQpIHRocm93IGFib3J0RXJyb3Ioc2lnbmFsKTtcblxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IGF3YWl0IHRoaXMuc2VsZWN0VG9rZW4oXG4gICAgICByZXEucHJlZmVycmVkVG9rZW5JZCxcbiAgICAgIHJlcS5yZXF1aXJlUHJlZmVycmVkVG9rZW4gPz8gZmFsc2UsXG4gICAgICBzaWduYWwsXG4gICAgKTtcblxuICAgIHRoaXMuaW5GbGlnaHQrKztcblxuICAgIHRyeSB7XG4gICAgICBpZiAoc2lnbmFsLmFib3J0ZWQpIHRocm93IGFib3J0RXJyb3Ioc2lnbmFsKTtcblxuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucnVuRGlyZWN0KHNlbGVjdGlvbiwgeyAuLi5yZXEsIGFib3J0U2lnbmFsOiBzaWduYWwgfSwgb25EZWx0YSk7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuaW5GbGlnaHQtLTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBydW5EaXJlY3QoXG4gICAgc2VsZWN0aW9uOiBUb2tlblNlbGVjdGlvbixcbiAgICByZXE6IEdlbmVyYXRlUmVxdWVzdCxcbiAgICBvbkRlbHRhPzogKHRleHQ6IHN0cmluZykgPT4gdm9pZCxcbiAgKTogUHJvbWlzZTxHZW5lcmF0ZVJlc3VsdD4ge1xuICAgIGNvbnN0IHN0YXJ0ZWRBdCA9IERhdGUubm93KCk7XG4gICAgbGV0IGZpcnN0RGVsdGFBdDogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgIGxldCB0ZXh0ID0gXCJcIjtcbiAgICBsZXQgb3V0cHV0TWVzc2FnZUFjY2VwdGVkID0gZmFsc2U7XG4gICAgY29uc3QgbWVzc2FnZVBoYXNlcyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gICAgY29uc3Qgc3RyZWFtZWRNZXNzYWdlSWRzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBsZXQgdXNhZ2UgPSB7XG4gICAgICB0b3RhbFRva2VuczogMCxcbiAgICAgIGlucHV0VG9rZW5zOiAwLFxuICAgICAgb3V0cHV0VG9rZW5zOiAwLFxuICAgICAgY2FjaGVkSW5wdXRUb2tlbnM6IDAsXG4gICAgICByZWFzb25pbmdPdXRwdXRUb2tlbnM6IDAsXG4gICAgfTtcblxuICAgIGNvbnN0IGltYWdlczogR2VuZXJhdGVkSW1hZ2VbXSA9IFtdO1xuICAgIGxldCBpbWFnZUF0dGVtcHRlZCA9IGZhbHNlO1xuICAgIGNvbnN0IGF1dG8gPSByZXEuaW1hZ2VHZW5lcmF0aW9uID09PSBcImF1dG9cIjtcbiAgICBjb25zdCBpbWFnZUNhbGxzID0gbmV3IE1hcDxzdHJpbmcsIEltYWdlVG9vbEFyZ3VtZW50cz4oKTtcbiAgICBjb25zdCBpbWFnZUNhbGxJZHMgPSBuZXcgU2V0PEpzb25WYWx1ZSB8IHVuZGVmaW5lZD4oKTtcbiAgICBsZXQgaW1hZ2VUb29sQXR0ZW1wdGVkID0gZmFsc2U7XG4gICAgbGV0IGRyaXZlckNvbXBsZXRlZCA9IGZhbHNlO1xuICAgIGxldCBzZXJ2aW5nTW9kZWwgPSByZXEubW9kZWwgPz8gXCJcIjtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHNlbGVjdGlvbi5tZXRhZGF0YTtcblxuICAgIGNvbnN0IGRyaXZlclJlc3VsdCA9ICgpOiBHZW5lcmF0ZVJlc3VsdCA9PiB7XG4gICAgICBjb25zdCByZXN1bHQ6IEdlbmVyYXRlUmVzdWx0ID0ge1xuICAgICAgICB0ZXh0LFxuICAgICAgICB0b2tlbk5hbWU6IG1ldGFkYXRhLm5hbWUsXG4gICAgICAgIHVzYWdlLFxuICAgICAgICBkdXJhdGlvbk1zOiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0LFxuICAgICAgICB0dGZ0TXM6IGZpcnN0RGVsdGFBdCA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGZpcnN0RGVsdGFBdCAtIHN0YXJ0ZWRBdCxcbiAgICAgICAgbW9kZWw6IHNlcnZpbmdNb2RlbCxcbiAgICAgICAgdGhyZWFkQ29vcmQ6IHtcbiAgICAgICAgICB3b3JrZXJJZDogc2VsZWN0aW9uLnRva2VuSWQsXG4gICAgICAgICAgdGhyZWFkSWQ6IHJlcS5wcm9tcHRDYWNoZUtleSA/PyBcIlwiLFxuICAgICAgICAgIGVwb2NoOiAtMSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGlmIChzZXJ2aW5nTW9kZWwgIT09IHJlcS5tb2RlbCkgcmVzdWx0LnJlcXVlc3RlZE1vZGVsID0gcmVxLm1vZGVsO1xuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH07XG5cbiAgICBjb25zdCBjbGllbnRFbnRyeSA9IHRoaXMuYWNxdWlyZUNsaWVudChzZWxlY3Rpb24pO1xuXG4gICAgdHJ5IHtcbiAgICAgIGZvciBhd2FpdCAoY29uc3QgZXZlbnQgb2YgY2xpZW50RW50cnkuY2xpZW50LnJlc3BvbnNlcyhcbiAgICAgICAgcmVxdWVzdE9wdGlvbnMocmVxKSxcbiAgICAgICAgcmVxLmFib3J0U2lnbmFsLFxuICAgICAgKSkge1xuICAgICAgICBjb25zdCBpdGVtSWQgPSBldmVudC50eXBlID09PSBcIm91dHB1dC1pdGVtXCIgPyBqc29uU3RyaW5nKGV2ZW50Lml0ZW0uaWQpIDogdW5kZWZpbmVkO1xuICAgICAgICBjb25zdCBpdGVtUGhhc2UgPSBldmVudC50eXBlID09PSBcIm91dHB1dC1pdGVtXCIgPyBqc29uU3RyaW5nKGV2ZW50Lml0ZW0ucGhhc2UpIDogdW5kZWZpbmVkO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICByZXEuc3RvcEFmdGVyT3V0cHV0TWVzc2FnZSAmJlxuICAgICAgICAgIGV2ZW50LnR5cGUgPT09IFwib3V0cHV0LWl0ZW1cIiAmJlxuICAgICAgICAgIGV2ZW50Lml0ZW0udHlwZSA9PT0gXCJtZXNzYWdlXCIgJiZcbiAgICAgICAgICBpdGVtSWQgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgIGl0ZW1QaGFzZSAhPT0gdW5kZWZpbmVkXG4gICAgICAgICkge1xuICAgICAgICAgIG1lc3NhZ2VQaGFzZXMuc2V0KGl0ZW1JZCwgaXRlbVBoYXNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChldmVudC50eXBlID09PSBcInRleHQtZGVsdGFcIikge1xuICAgICAgICAgIGlmIChvdXRwdXRNZXNzYWdlQWNjZXB0ZWQpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgaWYgKHJlcS5zdG9wQWZ0ZXJPdXRwdXRNZXNzYWdlICYmIGV2ZW50Lml0ZW1JZCkge1xuICAgICAgICAgICAgLy8gQnVmZmVyIGNvbW1lbnRhcnkvdW5jbGFzc2lmaWVkIG1lc3NhZ2VzIHVudGlsIHRoZWlyIGNvbXBsZXRlZCBpdGVtLlxuICAgICAgICAgICAgLy8gS25vd24gZmluYWwgYW5zd2VycyByZXRhaW4gaW5jcmVtZW50YWwgc3RyZWFtaW5nLlxuICAgICAgICAgICAgaWYgKG1lc3NhZ2VQaGFzZXMuZ2V0KGV2ZW50Lml0ZW1JZCkgIT09IFwiZmluYWxfYW5zd2VyXCIpIGNvbnRpbnVlO1xuICAgICAgICAgICAgc3RyZWFtZWRNZXNzYWdlSWRzLmFkZChldmVudC5pdGVtSWQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGZpcnN0RGVsdGFBdCA/Pz0gRGF0ZS5ub3coKTtcbiAgICAgICAgICB0ZXh0ICs9IGV2ZW50LnRleHQ7XG4gICAgICAgICAgb25EZWx0YT8uKGV2ZW50LnRleHQpO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgIGV2ZW50LnR5cGUgPT09IFwib3V0cHV0LWl0ZW1cIiAmJlxuICAgICAgICAgIGV2ZW50LmNvbXBsZXRlZCAmJlxuICAgICAgICAgIGV2ZW50Lml0ZW0udHlwZSA9PT0gXCJtZXNzYWdlXCIgJiZcbiAgICAgICAgICAhb3V0cHV0TWVzc2FnZUFjY2VwdGVkICYmXG4gICAgICAgICAgcmVxLnN0b3BBZnRlck91dHB1dE1lc3NhZ2UgJiZcbiAgICAgICAgICBBcnJheS5pc0FycmF5KGV2ZW50Lml0ZW0uY29udGVudClcbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgbWVzc2FnZVRleHQgPSBldmVudC5pdGVtLmNvbnRlbnRcbiAgICAgICAgICAgIC5mbGF0TWFwKChwYXJ0KSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHBhcnRUZXh0ID1cbiAgICAgICAgICAgICAgICBpc0pzb25PYmplY3QocGFydCkgJiYgcGFydC50eXBlID09PSBcIm91dHB1dF90ZXh0XCJcbiAgICAgICAgICAgICAgICAgID8ganNvblN0cmluZyhwYXJ0LnRleHQpXG4gICAgICAgICAgICAgICAgICA6IHVuZGVmaW5lZDtcblxuICAgICAgICAgICAgICByZXR1cm4gcGFydFRleHQgPT09IHVuZGVmaW5lZCA/IFtdIDogW3BhcnRUZXh0XTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuam9pbihcIlwiKTtcblxuICAgICAgICAgIC8vIEEgdmFsaWQgY2xpZW50IHRvb2wgcmVxdWVzdCBlbmRzIHRoaXMgYXBwbGljYXRpb24gdHVybi4gTGF0ZXIgYW5zd2VycyBjYW5ub3RcbiAgICAgICAgICAvLyBrbm93IGl0cyByZXN1bHQgeWV0LiBOZXZlciBzcGxpdC9yZXBhaXIgbWFsZm9ybWVkIEpTT04gd2l0aGluIGEgbWVzc2FnZS5cbiAgICAgICAgICBjb25zdCBwaGFzZSA9IGl0ZW1QaGFzZTtcblxuICAgICAgICAgIGlmIChtZXNzYWdlVGV4dCkgb3V0cHV0TWVzc2FnZUFjY2VwdGVkID0gcmVxLnN0b3BBZnRlck91dHB1dE1lc3NhZ2UobWVzc2FnZVRleHQsIHBoYXNlKTtcblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIGl0ZW1JZCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgICAhc3RyZWFtZWRNZXNzYWdlSWRzLmhhcyhpdGVtSWQpICYmXG4gICAgICAgICAgICAocGhhc2UgIT09IFwiY29tbWVudGFyeVwiIHx8IG91dHB1dE1lc3NhZ2VBY2NlcHRlZCkgJiZcbiAgICAgICAgICAgIG1lc3NhZ2VUZXh0XG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBmaXJzdERlbHRhQXQgPz89IERhdGUubm93KCk7XG4gICAgICAgICAgICB0ZXh0ICs9IG1lc3NhZ2VUZXh0O1xuICAgICAgICAgICAgb25EZWx0YT8uKG1lc3NhZ2VUZXh0KTtcbiAgICAgICAgICAgIHN0cmVhbWVkTWVzc2FnZUlkcy5hZGQoaXRlbUlkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gXCJpbWFnZVwiKSB7XG4gICAgICAgICAgaWYgKGF1dG8pXG4gICAgICAgICAgICB0aHJvdyBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXCJpbmNvbXBsZXRlXCIsIFwiVW5leHBlY3RlZCBob3N0ZWQgaW1hZ2UgZ2VuZXJhdGlvblwiKTtcbiAgICAgICAgICBpbWFnZUF0dGVtcHRlZCA9IHRydWU7XG4gICAgICAgICAgaW1hZ2VzLnB1c2goZ2VuZXJhdGVkSW1hZ2VGcm9tKGV2ZW50KSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gXCJvdXRwdXQtaXRlbVwiICYmIGV2ZW50Lml0ZW0udHlwZSA9PT0gXCJpbWFnZV9nZW5lcmF0aW9uX2NhbGxcIikge1xuICAgICAgICAgIGlmIChhdXRvKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBcIlVuZXhwZWN0ZWQgaG9zdGVkIGltYWdlIGdlbmVyYXRpb25cIik7XG4gICAgICAgICAgaW1hZ2VBdHRlbXB0ZWQgPSB0cnVlO1xuICAgICAgICB9IGVsc2UgaWYgKGF1dG8gJiYgZXZlbnQudHlwZSA9PT0gXCJvdXRwdXQtaXRlbVwiICYmIGV2ZW50Lml0ZW0udHlwZSA9PT0gXCJmdW5jdGlvbl9jYWxsXCIpIHtcbiAgICAgICAgICBpZiAoZXZlbnQuaXRlbS5uYW1lICE9PSBJTUFHRV9UT09MKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXCJpbmNvbXBsZXRlXCIsIFwiVW5leHBlY3RlZCBhdXRvbWF0aWMgaW1hZ2UgdG9vbCBjYWxsXCIpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGltYWdlVG9vbEF0dGVtcHRlZCA9IHRydWU7XG4gICAgICAgICAgaW1hZ2VDYWxsSWRzLmFkZChldmVudC5pdGVtLmNhbGxfaWQpO1xuXG4gICAgICAgICAgaWYgKCFldmVudC5jb21wbGV0ZWQpIGNvbnRpbnVlO1xuICAgICAgICAgIGNvbnN0IGlkID0ganNvblN0cmluZyhldmVudC5pdGVtLmNhbGxfaWQpO1xuICAgICAgICAgIGNvbnN0IHJhd0FyZ3VtZW50cyA9IGpzb25TdHJpbmcoZXZlbnQuaXRlbS5hcmd1bWVudHMpO1xuICAgICAgICAgIGxldCBkZWNvZGVkOiBKc29uVmFsdWU7XG5cbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHJhd0FyZ3VtZW50cyA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoXCJtaXNzaW5nIGFyZ3VtZW50c1wiKTtcbiAgICAgICAgICAgIC8vIEpTT04ucGFyc2Ugd2l0aG91dCBhIHJldml2ZXIgeWllbGRzIG9ubHkgSlNPTiB2YWx1ZXMuXG4gICAgICAgICAgICBkZWNvZGVkID0gSlNPTi5wYXJzZShyYXdBcmd1bWVudHMpO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBcIkludmFsaWQgaW1hZ2UgdG9vbCBhcmd1bWVudHNcIik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgcGFyc2VkQXJncyA9IEltYWdlVG9vbEFyZ3VtZW50c1NjaGVtYS5zYWZlUGFyc2UoZGVjb2RlZCk7XG5cbiAgICAgICAgICBpZiAoIWlkIHx8ICFwYXJzZWRBcmdzLnN1Y2Nlc3MpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcImluY29tcGxldGVcIiwgXCJJbnZhbGlkIGltYWdlIHRvb2wgYXJndW1lbnRzXCIpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGFyZ3MgPSBwYXJzZWRBcmdzLmRhdGE7XG5cbiAgICAgICAgICBjb25zdCBwcmV2aW91cyA9IGltYWdlQ2FsbHMuZ2V0KGlkKTtcblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHByZXZpb3VzICYmXG4gICAgICAgICAgICAocHJldmlvdXMucHJvbXB0ICE9PSBhcmdzLnByb21wdCB8fFxuICAgICAgICAgICAgICBwcmV2aW91cy50cmFuc3BhcmVudF9iYWNrZ3JvdW5kICE9PSBhcmdzLnRyYW5zcGFyZW50X2JhY2tncm91bmQgfHxcbiAgICAgICAgICAgICAgcHJldmlvdXMubnVtX2xhc3RfaW1hZ2VzX3RvX2luY2x1ZGUgIT09IGFyZ3MubnVtX2xhc3RfaW1hZ2VzX3RvX2luY2x1ZGUpXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXCJpbmNvbXBsZXRlXCIsIFwiQ29uZmxpY3RpbmcgaW1hZ2UgdG9vbCBjYWxsc1wiKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpbWFnZUNhbGxzLnNldChpZCwge1xuICAgICAgICAgICAgcHJvbXB0OiBhcmdzLnByb21wdCxcbiAgICAgICAgICAgIHRyYW5zcGFyZW50X2JhY2tncm91bmQ6IGFyZ3MudHJhbnNwYXJlbnRfYmFja2dyb3VuZCxcbiAgICAgICAgICAgIG51bV9sYXN0X2ltYWdlc190b19pbmNsdWRlOiBhcmdzLm51bV9sYXN0X2ltYWdlc190b19pbmNsdWRlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09IFwiY29tcGxldGVkXCIpIHtcbiAgICAgICAgICBjb25zdCBpbWFnZVVzYWdlID0gZXZlbnQuaW1hZ2VHZW5lcmF0aW9uPy51c2FnZTtcblxuICAgICAgICAgIC8vIFRoZSBiYWNrZW5kIGFsc28gcmVwb3J0cyBhbGwtemVybyBpbWFnZSB1c2FnZSBmb3IgdGV4dC1vbmx5IHJlc3BvbnNlcy5cbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICBhdXRvICYmXG4gICAgICAgICAgICBpbWFnZVVzYWdlICYmXG4gICAgICAgICAgICAoaW1hZ2VVc2FnZS5pbnB1dF90b2tlbnMgPiAwIHx8XG4gICAgICAgICAgICAgIGltYWdlVXNhZ2Uub3V0cHV0X3Rva2VucyA+IDAgfHxcbiAgICAgICAgICAgICAgaW1hZ2VVc2FnZS50b3RhbF90b2tlbnMgPiAwKVxuICAgICAgICAgIClcbiAgICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcImluY29tcGxldGVcIiwgXCJVbmV4cGVjdGVkIGhvc3RlZCBpbWFnZSBnZW5lcmF0aW9uXCIpO1xuICAgICAgICAgIGRyaXZlckNvbXBsZXRlZCA9IHRydWU7XG4gICAgICAgICAgc2VydmluZ01vZGVsID0gZXZlbnQubW9kZWwgPz8gc2VydmluZ01vZGVsO1xuXG4gICAgICAgICAgaWYgKGV2ZW50LnVzYWdlKSB7XG4gICAgICAgICAgICB1c2FnZSA9IHtcbiAgICAgICAgICAgICAgdG90YWxUb2tlbnM6IGV2ZW50LnVzYWdlLnRvdGFsVG9rZW5zLFxuICAgICAgICAgICAgICBpbnB1dFRva2VuczogZXZlbnQudXNhZ2UuaW5wdXRUb2tlbnMsXG4gICAgICAgICAgICAgIG91dHB1dFRva2VuczogZXZlbnQudXNhZ2Uub3V0cHV0VG9rZW5zLFxuICAgICAgICAgICAgICBjYWNoZWRJbnB1dFRva2VuczogZXZlbnQudXNhZ2UuY2FjaGVkSW5wdXRUb2tlbnMsXG4gICAgICAgICAgICAgIHJlYXNvbmluZ091dHB1dFRva2VuczogZXZlbnQudXNhZ2UucmVhc29uaW5nVG9rZW5zLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoZXZlbnQuaW1hZ2VHZW5lcmF0aW9uKSB7XG4gICAgICAgICAgICBjb25zdCBob3N0ZWRJbWFnZXMgPSBpbWFnZXMuZmlsdGVyKFxuICAgICAgICAgICAgICAoaW1hZ2UpID0+IGltYWdlLmdlbmVyYXRpb24/LnJvdXRlID09PSBcImNvZGV4LXJlc3BvbnNlc1wiLFxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgZm9yIChjb25zdCBbaW5kZXgsIGltYWdlXSBvZiBob3N0ZWRJbWFnZXMuZW50cmllcygpKSB7XG4gICAgICAgICAgICAgIGNvbnN0IGdlbmVyYXRpb246IEltYWdlR2VuZXJhdGlvbk1ldGFkYXRhID0ge1xuICAgICAgICAgICAgICAgIHJvdXRlOiBcImNvZGV4LXJlc3BvbnNlc1wiLFxuICAgICAgICAgICAgICAgIC4uLmltYWdlLmdlbmVyYXRpb24sXG4gICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgLy8gVGhlIGltYWdlJ3Mgb3duIG1vZGVsIHdpbnM7IHRoZSByZXNwb25zZS1sZXZlbCBtb2RlbCBvbmx5IGZpbGxzIGEgZ2FwLlxuICAgICAgICAgICAgICBpZiAoZ2VuZXJhdGlvbi5tb2RlbCA9PT0gdW5kZWZpbmVkICYmIGV2ZW50LmltYWdlR2VuZXJhdGlvbi5tb2RlbCkge1xuICAgICAgICAgICAgICAgIGdlbmVyYXRpb24ubW9kZWwgPSBldmVudC5pbWFnZUdlbmVyYXRpb24ubW9kZWw7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBUb29sIHVzYWdlIGNvdmVycyB0aGUgd2hvbGUgcmVzcG9uc2UsIG5vdCBlYWNoIHJldHVybmVkIGltYWdlLlxuICAgICAgICAgICAgICBpZiAoaW5kZXggPT09IDAgJiYgZXZlbnQuaW1hZ2VHZW5lcmF0aW9uLnVzYWdlKSB7XG4gICAgICAgICAgICAgICAgZ2VuZXJhdGlvbi51c2FnZSA9IGV2ZW50LmltYWdlR2VuZXJhdGlvbi51c2FnZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGltYWdlLmdlbmVyYXRpb24gPSBnZW5lcmF0aW9uO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChldmVudC50eXBlID09PSBcImVycm9yXCIpIHtcbiAgICAgICAgICBpZiAocmVxLmltYWdlR2VuZXJhdGlvbilcbiAgICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcImluY29tcGxldGVcIiwgZXZlbnQuZXJyb3IubWVzc2FnZSk7XG4gICAgICAgICAgdGhyb3cgZXZlbnQuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKGF1dG8gJiYgaW1hZ2VUb29sQXR0ZW1wdGVkKSB7XG4gICAgICAgIGlmICghZHJpdmVyQ29tcGxldGVkIHx8IGltYWdlQ2FsbHMuc2l6ZSAhPT0gMSB8fCBpbWFnZUNhbGxJZHMuc2l6ZSAhPT0gMSkge1xuICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcImluY29tcGxldGVcIiwgXCJFeHBlY3RlZCBvbmUgY29tcGxldGVkIGltYWdlIHRvb2wgY2FsbFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChyZXEuYWJvcnRTaWduYWw/LmFib3J0ZWQpIHRocm93IGFib3J0RXJyb3IocmVxLmFib3J0U2lnbmFsKTtcbiAgICAgICAgY29uc3QgYXJncyA9IFsuLi5pbWFnZUNhbGxzLnZhbHVlcygpXVswXSE7XG4gICAgICAgIGNvbnN0IHJlZmVyZW5jZUNvdW50ID0gYXJncy5udW1fbGFzdF9pbWFnZXNfdG9faW5jbHVkZTtcbiAgICAgICAgY29uc3QgcmVmZXJlbmNlcyA9IHJlZmVyZW5jZUNvdW50ID8gaW1hZ2VSZWZlcmVuY2VzKHJlcSkgOiBbXTtcblxuICAgICAgICBpZiAocmVmZXJlbmNlQ291bnQgPiByZWZlcmVuY2VzLmxlbmd0aCkge1xuICAgICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcbiAgICAgICAgICAgIFwiaW5jb21wbGV0ZVwiLFxuICAgICAgICAgICAgXCJSZXF1ZXN0ZWQgaW1hZ2UgcmVmZXJlbmNlcyBhcmUgdW5hdmFpbGFibGVcIixcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGltYWdlQ29tcGxldGVkID0gZmFsc2U7XG5cbiAgICAgICAgZm9yIGF3YWl0IChjb25zdCBldmVudCBvZiBjbGllbnRFbnRyeS5jbGllbnQucmVzcG9uc2VzKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1vZGVsOiBcImdwdC1pbWFnZS0yXCIsXG4gICAgICAgICAgICBoaXN0b3J5OiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBcIm1lc3NhZ2VcIixcbiAgICAgICAgICAgICAgICByb2xlOiBcInVzZXJcIixcbiAgICAgICAgICAgICAgICBjb250ZW50OiBbXG4gICAgICAgICAgICAgICAgICB7IHR5cGU6IFwiaW5wdXRfdGV4dFwiLCB0ZXh0OiBhcmdzLnByb21wdCB9LFxuICAgICAgICAgICAgICAgICAgLi4uKHJlZmVyZW5jZUNvdW50ID8gcmVmZXJlbmNlcy5zbGljZSgtcmVmZXJlbmNlQ291bnQpIDogW10pLFxuICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgICAgaW1hZ2VHZW5lcmF0aW9uOiB7XG4gICAgICAgICAgICAgIHF1YWxpdHk6IHJlcS5pbWFnZUdlbmVyYXRpb25PcHRpb25zPy5xdWFsaXR5LFxuICAgICAgICAgICAgICBzaXplOiByZXEuaW1hZ2VHZW5lcmF0aW9uT3B0aW9ucz8uc2l6ZSxcbiAgICAgICAgICAgICAgb3V0cHV0X2Zvcm1hdDogXCJwbmdcIixcbiAgICAgICAgICAgICAgYmFja2dyb3VuZDogYXJncy50cmFuc3BhcmVudF9iYWNrZ3JvdW5kID8gXCJ0cmFuc3BhcmVudFwiIDogXCJvcGFxdWVcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICByZXEuYWJvcnRTaWduYWwsXG4gICAgICAgICkpIHtcbiAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gXCJpbWFnZVwiKSBpbWFnZXMucHVzaChnZW5lcmF0ZWRJbWFnZUZyb20oZXZlbnQpKTtcbiAgICAgICAgICBlbHNlIGlmIChldmVudC50eXBlID09PSBcImNvbXBsZXRlZFwiKSBpbWFnZUNvbXBsZXRlZCA9IHRydWU7XG4gICAgICAgICAgZWxzZSBpZiAoZXZlbnQudHlwZSA9PT0gXCJlcnJvclwiKVxuICAgICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBldmVudC5lcnJvci5tZXNzYWdlLCB7XG4gICAgICAgICAgICAgIGNhdXNlOiBldmVudC5lcnJvcixcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaW1hZ2VBdHRlbXB0ZWQgPSB0cnVlO1xuXG4gICAgICAgIGlmICghaW1hZ2VDb21wbGV0ZWQpXG4gICAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBcIkltYWdlIGdlbmVyYXRpb24gZGlkIG5vdCBjb21wbGV0ZVwiKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGF1dG8gJiYgaW1hZ2VBdHRlbXB0ZWQgJiYgIWRyaXZlckNvbXBsZXRlZClcbiAgICAgICAgdGhyb3cgbmV3IEltYWdlR2VuZXJhdGlvbkVycm9yKFwiaW5jb21wbGV0ZVwiLCBcIkltYWdlIGdlbmVyYXRpb24gcmVzcG9uc2UgZGlkIG5vdCBjb21wbGV0ZVwiKTtcblxuICAgICAgaWYgKHJlcS5hYm9ydFNpZ25hbD8uYWJvcnRlZCkgdGhyb3cgYWJvcnRFcnJvcihyZXEuYWJvcnRTaWduYWwpO1xuXG4gICAgICBpZiAoKHJlcS5pbWFnZUdlbmVyYXRpb24gPT09IHRydWUgfHwgKGF1dG8gJiYgaW1hZ2VBdHRlbXB0ZWQpKSAmJiBpbWFnZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBJbWFnZUdlbmVyYXRpb25FcnJvcihcbiAgICAgICAgICBpbWFnZUF0dGVtcHRlZCA/IFwiaW5jb21wbGV0ZVwiIDogXCJub3RfY2FsbGVkXCIsXG4gICAgICAgICAgaW1hZ2VBdHRlbXB0ZWRcbiAgICAgICAgICAgID8gXCJpbWFnZSBnZW5lcmF0aW9uIGRpZCBub3QgY29tcGxldGVcIlxuICAgICAgICAgICAgOiBcIm1vZGVsIGRpZCBub3QgY2FsbCBpbWFnZSBnZW5lcmF0aW9uXCIsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChhdXRvICYmIGRyaXZlckNvbXBsZXRlZCAmJiBpbWFnZVRvb2xBdHRlbXB0ZWQpIHtcbiAgICAgICAgY29uc3QgZmFpbHVyZSA9XG4gICAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBJbWFnZUdlbmVyYXRpb25FcnJvclxuICAgICAgICAgICAgPyBlcnJvclxuICAgICAgICAgICAgOiBuZXcgSW1hZ2VHZW5lcmF0aW9uRXJyb3IoXG4gICAgICAgICAgICAgICAgXCJpbmNvbXBsZXRlXCIsXG4gICAgICAgICAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICAgICAgICAgIHsgY2F1c2U6IGVycm9yIH0sXG4gICAgICAgICAgICAgICk7XG5cbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgRXJyb3IpIGZhaWx1cmUubmFtZSA9IGVycm9yLm5hbWU7XG4gICAgICAgIC8vIE9ubHkgdGhlIGNvbXBsZXRlZCBjaGF0IHN0YWdlIGlzIGNoYXJnZWFibGUgaGVyZTsgZGlzY2FyZCBwYXJ0aWFsIGltYWdlIG91dHB1dC5cbiAgICAgICAgZmFpbHVyZS5jb21wbGV0ZWREcml2ZXIgPSBkcml2ZXJSZXN1bHQoKTtcbiAgICAgICAgdGhyb3cgZmFpbHVyZTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMucmVsZWFzZUNsaWVudChjbGllbnRFbnRyeSk7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gZHJpdmVyUmVzdWx0KCk7XG5cbiAgICBpZiAoaW1hZ2VzLmxlbmd0aCkgcmVzdWx0LmltYWdlcyA9IGltYWdlcztcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKiog7IS464yA6rCAIOuwlOuAkCBjbGllbnQg64qUIOyCrOyaqSDspJHsnbgg7JqU7LKt7J20IOuBneuCnCDrkqTsl5Ag64ur64qU64ukLiAqL1xuICBhY3F1aXJlQ2xpZW50KHNlbGVjdGlvbjogVG9rZW5TZWxlY3Rpb24pOiBDbGllbnRFbnRyeSB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBzZWxlY3Rpb24ubWV0YWRhdGE7XG4gICAgbGV0IGVudHJ5ID0gdGhpcy5jbGllbnRzLmdldChzZWxlY3Rpb24udG9rZW5JZCk7XG5cbiAgICBpZiAoZW50cnkgJiYgZW50cnkuZ2VuZXJhdGlvbiAhPT0gbWV0YWRhdGEuZ2VuZXJhdGlvbikge1xuICAgICAgdGhpcy5yZXRpcmVDbGllbnQoc2VsZWN0aW9uLnRva2VuSWQpO1xuICAgICAgZW50cnkgPSB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgaWYgKCFlbnRyeSkge1xuICAgICAgY29uc3QgY2xpZW50ID0gdGhpcy5jbGllbnRGYWN0b3J5KFxuICAgICAgICB7XG4gICAgICAgICAgY3JlZGVudGlhbHM6IHtcbiAgICAgICAgICAgIGFjY2Vzc1Rva2VuOiBtZXRhZGF0YS5jcmVkZW50aWFscy5hY2Nlc3NUb2tlbixcbiAgICAgICAgICAgIGFjY291bnRJZDogbWV0YWRhdGEuY3JlZGVudGlhbHMuYWNjb3VudElkLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdHJhbnNwb3J0S2luZDogdGhpcy50cmFuc3BvcnRLaW5kLFxuICAgICAgICAgIGZldGNoOiB0aGlzLmZldGNoSW1wbCxcbiAgICAgICAgICByZWZyZXNoQ3JlZGVudGlhbHM6ICgpID0+IHRoaXMucmVmcmVzaENyZWRlbnRpYWxzKHNlbGVjdGlvbi50b2tlbklkKSxcbiAgICAgICAgfSxcbiAgICAgICAgc2VsZWN0aW9uLnRva2VuSWQsXG4gICAgICApO1xuXG4gICAgICBlbnRyeSA9IHsgZ2VuZXJhdGlvbjogbWV0YWRhdGEuZ2VuZXJhdGlvbiwgY2xpZW50LCBpbkZsaWdodDogMCwgcmV0aXJlZDogZmFsc2UgfTtcbiAgICAgIHRoaXMuY2xpZW50cy5zZXQoc2VsZWN0aW9uLnRva2VuSWQsIGVudHJ5KTtcbiAgICB9XG5cbiAgICBlbnRyeS5pbkZsaWdodCsrO1xuXG4gICAgcmV0dXJuIGVudHJ5O1xuICB9XG5cbiAgcmVsZWFzZUNsaWVudChlbnRyeTogQ2xpZW50RW50cnkpOiB2b2lkIHtcbiAgICBlbnRyeS5pbkZsaWdodCA9IE1hdGgubWF4KDAsIGVudHJ5LmluRmxpZ2h0IC0gMSk7XG5cbiAgICBpZiAoZW50cnkucmV0aXJlZCAmJiBlbnRyeS5pbkZsaWdodCA9PT0gMCkge1xuICAgICAgdGhpcy5yZXRpcmVkQ2xpZW50cy5kZWxldGUoZW50cnkpO1xuICAgICAgZW50cnkuY2xpZW50LmNsb3NlPy4oKTtcbiAgICB9XG4gIH1cblxuICByZXRpcmVDbGllbnQodG9rZW5JZDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgZW50cnkgPSB0aGlzLmNsaWVudHMuZ2V0KHRva2VuSWQpO1xuXG4gICAgaWYgKCFlbnRyeSkgcmV0dXJuO1xuICAgIHRoaXMuY2xpZW50cy5kZWxldGUodG9rZW5JZCk7XG4gICAgZW50cnkucmV0aXJlZCA9IHRydWU7XG5cbiAgICBpZiAoZW50cnkuaW5GbGlnaHQgPT09IDApIGVudHJ5LmNsaWVudC5jbG9zZT8uKCk7XG4gICAgZWxzZSB0aGlzLnJldGlyZWRDbGllbnRzLmFkZChlbnRyeSk7XG4gIH1cblxuICAvLyDshKDtmLgg7Yag7YGw7J20IHF1b3Rh66W8IO2GteqzvO2VmOuptCDri6Trpbgg7Yag7YGwIOyhsO2ajOyZgCB3ZWlnaHRlZCDsg4Htg5wg67OA6rK97J2EIOyDneuete2VnOuLpC5cbiAgYXN5bmMgc2VsZWN0VG9rZW4oXG4gICAgcHJlZmVycmVkVG9rZW5JZDogbnVtYmVyIHwgdW5kZWZpbmVkLFxuICAgIHJlcXVpcmVQcmVmZXJyZWRUb2tlbjogYm9vbGVhbixcbiAgICBzaWduYWw6IEFib3J0U2lnbmFsLFxuICApOiBQcm9taXNlPFRva2VuU2VsZWN0aW9uPiB7XG4gICAgaWYgKHByZWZlcnJlZFRva2VuSWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgcHJlZmVycmVkID0gdGhpcy50b2tlbk1ldGFkYXRhLmdldChwcmVmZXJyZWRUb2tlbklkKTtcblxuICAgICAgaWYgKHByZWZlcnJlZD8uYWN0aXZlICYmIChhd2FpdCB0aGlzLmlzUXVvdGFFbGlnaWJsZShwcmVmZXJyZWRUb2tlbklkLCBwcmVmZXJyZWQsIHNpZ25hbCkpKSB7XG4gICAgICAgIHJldHVybiB7IHRva2VuSWQ6IHByZWZlcnJlZFRva2VuSWQsIG1ldGFkYXRhOiBwcmVmZXJyZWQgfTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJlcXVpcmVQcmVmZXJyZWRUb2tlbikge1xuICAgICAgICBpZiAoIXByZWZlcnJlZD8uYWN0aXZlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBQcmVmZXJyZWQgb3BlbmFpIHRva2VuICR7cHJlZmVycmVkVG9rZW5JZH0gaXMgbm90IGF2YWlsYWJsZWApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGhyZXNob2xkID0gcHJlZmVycmVkLnF1b3RhVGhyZXNob2xkO1xuXG4gICAgICAgIGlmICh0aHJlc2hvbGQgIT09IG51bGwgJiYgdGhyZXNob2xkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUXVvdGFUaHJlc2hvbGRFeGNlZWRlZEVycm9yKFxuICAgICAgICAgICAgcXVvdGFNZXNzYWdlKFt7IG5hbWU6IHByZWZlcnJlZC5uYW1lLCB0aHJlc2hvbGQgfV0pLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyDsvZzrk5wg7LqQ7Iuc7JeQ7IScIO2GoO2BsCDsiJjrp4ztgbwg7KGw7ZqMIOyngOyXsOydtCDsjJPsnbTsp4Ag7JWK64+E66GdIOuzkeugrCDtjJDsoJXtlZzri6QuXG4gICAgY29uc3QgYWN0aXZlVG9rZW5zID0gWy4uLnRoaXMudG9rZW5NZXRhZGF0YS5lbnRyaWVzKCldLmZpbHRlcigoWywgdG9rZW5dKSA9PiB0b2tlbi5hY3RpdmUpO1xuXG4gICAgY29uc3QgY2hlY2tzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBhY3RpdmVUb2tlbnMubWFwKGFzeW5jIChbaWQsIHRva2VuXSkgPT4gKHtcbiAgICAgICAgaWQsXG4gICAgICAgIHRva2VuLFxuICAgICAgICBlbGlnaWJsZTogYXdhaXQgdGhpcy5pc1F1b3RhRWxpZ2libGUoaWQsIHRva2VuLCBzaWduYWwpLFxuICAgICAgfSkpLFxuICAgICk7XG5cbiAgICBjb25zdCBlbGlnaWJsZSA9IG5ldyBTZXQoY2hlY2tzLmZpbHRlcigoYykgPT4gYy5lbGlnaWJsZSkubWFwKChjKSA9PiBjLmlkKSk7XG5cbiAgICBpZiAoZWxpZ2libGUuc2l6ZSA9PT0gMCkge1xuICAgICAgY29uc3Qgb3ZlciA9IGNoZWNrcy5mbGF0TWFwKChjKSA9PiB7XG4gICAgICAgIGNvbnN0IHRocmVzaG9sZCA9IGMudG9rZW4ucXVvdGFUaHJlc2hvbGQ7XG5cbiAgICAgICAgcmV0dXJuIGMuZWxpZ2libGUgfHwgdGhyZXNob2xkID09PSBudWxsIHx8IHRocmVzaG9sZCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyBbXVxuICAgICAgICAgIDogW3sgbmFtZTogYy50b2tlbi5uYW1lLCB0aHJlc2hvbGQgfV07XG4gICAgICB9KTtcblxuICAgICAgaWYgKG92ZXIubGVuZ3RoKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKFwicXVvdGFfdGhyZXNob2xkIGdhdGU6IGFsbF9leGNlZWRlZFwiLCB7XG4gICAgICAgICAgcHJvdmlkZXI6IFwib3BlbmFpXCIsXG4gICAgICAgICAgb3ZlclRocmVzaG9sZFRva2Vuczogb3ZlcixcbiAgICAgICAgfSk7XG4gICAgICAgIHRocm93IG5ldyBRdW90YVRocmVzaG9sZEV4Y2VlZGVkRXJyb3IocXVvdGFNZXNzYWdlKG92ZXIpKTtcbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTk9fT1BFTkFJX1dPUktFUlNcIik7XG4gICAgfVxuXG4gICAgY29uc3Qgc2VsZWN0ZWQgPSB0aGlzLnNlbGVjdG9yLnNlbGVjdChlbGlnaWJsZSk7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBzZWxlY3RlZCAhPT0gbnVsbCA/IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoc2VsZWN0ZWQpIDogdW5kZWZpbmVkO1xuXG4gICAgaWYgKHNlbGVjdGVkID09PSBudWxsIHx8ICFtZXRhZGF0YSkgdGhyb3cgbmV3IEVycm9yKFwiTk9fT1BFTkFJX1dPUktFUlNcIik7XG5cbiAgICByZXR1cm4geyB0b2tlbklkOiBzZWxlY3RlZCwgbWV0YWRhdGEgfTtcbiAgfVxuXG4gIHNldFRva2VuKFxuICAgIGlkOiBudW1iZXIsXG4gICAgbmFtZTogc3RyaW5nLFxuICAgIGNyZWRlbnRpYWxzOiBPcGVuQUlDcmVkZW50aWFscyxcbiAgICBxdW90YVRocmVzaG9sZDogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgICB3ZWlnaHQ6IG51bWJlcixcbiAgICBhY3RpdmU6IGJvb2xlYW4sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IG9sZCA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQoaWQpO1xuXG4gICAgaWYgKG9sZCkge1xuICAgICAgT2JqZWN0LmFzc2lnbihvbGQsIHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgY3JlZGVudGlhbHMsXG4gICAgICAgIHF1b3RhVGhyZXNob2xkLFxuICAgICAgICB3ZWlnaHQsXG4gICAgICAgIGFjdGl2ZSxcbiAgICAgICAgZ2VuZXJhdGlvbjogb2xkLmdlbmVyYXRpb24gKyAxLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMudG9rZW5NZXRhZGF0YS5zZXQoaWQsIHtcbiAgICAgICAgbmFtZSxcbiAgICAgICAgY3JlZGVudGlhbHMsXG4gICAgICAgIHF1b3RhVGhyZXNob2xkLFxuICAgICAgICB3ZWlnaHQsXG4gICAgICAgIGFjdGl2ZSxcbiAgICAgICAgZ2VuZXJhdGlvbjogMSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMuc2VsZWN0b3Iuc2V0VG9rZW4oaWQsIHdlaWdodCk7XG4gICAgdGhpcy5pbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKGlkKTtcbiAgICB0aGlzLnF1b3RhQmxvY2tlZC5kZWxldGUoaWQpO1xuICB9XG5cbiAgYXN5bmMgZ2V0UmF0ZUxpbWl0c0J5VG9rZW5JZChcbiAgICB0b2tlbklkOiBudW1iZXIsXG4gICAgc2lnbmFsPzogQWJvcnRTaWduYWwsXG4gICk6IFByb21pc2U8T3BlbkFJUmF0ZUxpbWl0c1dpdGhNZXRhPiB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpO1xuXG4gICAgaWYgKCF0b2tlbikgdGhyb3cgbmV3IEVycm9yKGBvcGVuYWkgdG9rZW4gJHt0b2tlbklkfSBub3QgZm91bmRgKTtcbiAgICBjb25zdCBnZW5lcmF0aW9uID0gdG9rZW4uZ2VuZXJhdGlvbjtcbiAgICBjb25zdCBjYWNoZWQgPSB0aGlzLnJhdGVMaW1pdHNDYWNoZS5nZXQodG9rZW5JZCk7XG5cbiAgICBpZiAoXG4gICAgICBjYWNoZWQgJiZcbiAgICAgIGNhY2hlZC5nZW5lcmF0aW9uID09PSB0b2tlbi5nZW5lcmF0aW9uICYmXG4gICAgICBEYXRlLm5vdygpIC0gY2FjaGVkLmNhY2hlZEF0IDwgT3BlbkFJRGlzcGF0Y2hlci5SQVRFX0xJTUlUU19DQUNIRV9UVExcbiAgICApXG4gICAgICByZXR1cm4gY2FjaGVkO1xuXG4gICAgLy8gVFRMIOunjOujjCDsi5wg7KGw7ZqM66W8IOqzteycoO2VnOuLpC4g7LWc7LSIIO2YuOy2nOyekOydmCBhYm9ydOuhnCDsi6TtjKjtlbTrj4QgaXNRdW90YUVsaWdpYmxl7J2AIGZhaWwtb3Blbu2VnOuLpC5cbiAgICBjb25zdCBwZW5kaW5nID0gdGhpcy5wZW5kaW5nUmF0ZUxpbWl0cy5nZXQodG9rZW5JZCk7XG5cbiAgICBpZiAocGVuZGluZz8udG9rZW4gPT09IHRva2VuICYmIHBlbmRpbmcuZ2VuZXJhdGlvbiA9PT0gZ2VuZXJhdGlvbikgcmV0dXJuIHBlbmRpbmcucHJvbWlzZTtcblxuICAgIGNvbnN0IGZldGNoUHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCByZWFkT3BlbkFJUXVvdGFVc2FnZSh7XG4gICAgICAgIGNyZWRlbnRpYWxzOiB0b2tlbi5jcmVkZW50aWFscyxcbiAgICAgICAgcmVmcmVzaENyZWRlbnRpYWxzOiAoKSA9PiB0aGlzLnJlZnJlc2hDcmVkZW50aWFscyh0b2tlbklkKSxcbiAgICAgICAgZmV0Y2g6IHRoaXMuZmV0Y2hJbXBsLFxuICAgICAgICBzaWduYWwsXG4gICAgICB9KTtcblxuICAgICAgaWYgKHJlc3VsdC5raW5kID09PSBcImxvb2t1cF9mYWlsZWRcIikgdGhyb3cgbmV3IEVycm9yKHJlc3VsdC5yZWFzb24pO1xuXG4gICAgICBpZiAoIXJlc3VsdC5yYXcpIHRocm93IG5ldyBFcnJvcihcIk9wZW5BSSBxdW90YSByZXNwb25zZSBtaXNzaW5nIHJhdyByYXRlIGxpbWl0c1wiKTtcbiAgICAgIGNvbnN0IGVudHJ5ID0geyBkYXRhOiByZXN1bHQucmF3LCBjYWNoZWRBdDogRGF0ZS5ub3coKSwgZ2VuZXJhdGlvbiB9O1xuXG4gICAgICBpZiAodGhpcy50b2tlbk1ldGFkYXRhLmdldCh0b2tlbklkKSA9PT0gdG9rZW4gJiYgdG9rZW4uZ2VuZXJhdGlvbiA9PT0gZ2VuZXJhdGlvbikge1xuICAgICAgICB0aGlzLnJhdGVMaW1pdHNDYWNoZS5zZXQodG9rZW5JZCwgZW50cnkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZW50cnk7XG4gICAgfSkoKS5maW5hbGx5KCgpID0+IHtcbiAgICAgIGlmICh0aGlzLnBlbmRpbmdSYXRlTGltaXRzLmdldCh0b2tlbklkKT8ucHJvbWlzZSA9PT0gZmV0Y2hQcm9taXNlKSB7XG4gICAgICAgIHRoaXMucGVuZGluZ1JhdGVMaW1pdHMuZGVsZXRlKHRva2VuSWQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5wZW5kaW5nUmF0ZUxpbWl0cy5zZXQodG9rZW5JZCwgeyB0b2tlbiwgZ2VuZXJhdGlvbiwgcHJvbWlzZTogZmV0Y2hQcm9taXNlIH0pO1xuXG4gICAgcmV0dXJuIGZldGNoUHJvbWlzZTtcbiAgfVxuXG4gIGFzeW5jIHJlZnJlc2hDcmVkZW50aWFscyh0b2tlbklkOiBudW1iZXIpIHtcbiAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMudG9rZW5NZXRhZGF0YS5nZXQodG9rZW5JZCk7XG4gICAgY29uc3QgZ2VuZXJhdGlvbiA9IHByZXZpb3VzPy5nZW5lcmF0aW9uO1xuICAgIGNvbnN0IHJlZnJlc2hlZCA9IGF3YWl0IGhhbmRsZUNoYXRncHRBdXRoVG9rZW5zUmVmcmVzaCh0b2tlbklkKTtcblxuICAgIGNvbnN0IGNyZWRlbnRpYWxzID0ge1xuICAgICAgYWNjZXNzVG9rZW46IHJlZnJlc2hlZC5hY2Nlc3NUb2tlbixcbiAgICAgIGFjY291bnRJZDogcmVmcmVzaGVkLmNoYXRncHRBY2NvdW50SWQsXG4gICAgfTtcblxuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KHRva2VuSWQpO1xuXG4gICAgaWYgKCFjdXJyZW50Py5hY3RpdmUpIHRocm93IG5ldyBFcnJvcihgb3BlbmFpIHRva2VuICR7dG9rZW5JZH0gaXMgbm8gbG9uZ2VyIGFjdGl2ZWApO1xuXG4gICAgLy8gQSBzdWJzY3JpYmVyIHVwZGF0ZSBtYXkgYWxyZWFkeSBjb250YWluIG5ld2VyIGNyZWRlbnRpYWxzLiBOZXZlciBvdmVyd3JpdGUgaXRcbiAgICAvLyB3aXRoIHRoZSByZXN1bHQgb2YgYSByZWZyZXNoIHRoYXQgc3RhcnRlZCBhZ2FpbnN0IGFuIG9sZGVyIGdlbmVyYXRpb24uXG4gICAgaWYgKGN1cnJlbnQgPT09IHByZXZpb3VzICYmIGN1cnJlbnQuZ2VuZXJhdGlvbiA9PT0gZ2VuZXJhdGlvbikge1xuICAgICAgY3VycmVudC5jcmVkZW50aWFscyA9IHsgLi4uY3VycmVudC5jcmVkZW50aWFscywgLi4uY3JlZGVudGlhbHMgfTtcbiAgICAgIHRoaXMucmV0aXJlQ2xpZW50KHRva2VuSWQpO1xuICAgICAgdGhpcy5pbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKHRva2VuSWQpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBhY2Nlc3NUb2tlbjogY3VycmVudC5jcmVkZW50aWFscy5hY2Nlc3NUb2tlbixcbiAgICAgIGFjY291bnRJZDogY3VycmVudC5jcmVkZW50aWFscy5hY2NvdW50SWQsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIGlzUXVvdGFFbGlnaWJsZShpZDogbnVtYmVyLCB0b2tlbjogVG9rZW5NZXRhZGF0YSwgc2lnbmFsPzogQWJvcnRTaWduYWwpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAodG9rZW4ucXVvdGFUaHJlc2hvbGQgPT09IG51bGwgfHwgdG9rZW4ucXVvdGFUaHJlc2hvbGQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHRydWU7XG4gICAgY29uc3QgZ2VuZXJhdGlvbiA9IHRva2VuLmdlbmVyYXRpb247XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgcmVhZE9wZW5BSVF1b3RhVXNhZ2UoYXN5bmMgKCkgPT4gdGhpcy5nZXRSYXRlTGltaXRzQnlUb2tlbklkKGlkLCBzaWduYWwpKTtcblxuICAgIGlmICh0aGlzLnRva2VuTWV0YWRhdGEuZ2V0KGlkKSAhPT0gdG9rZW4gfHwgdG9rZW4uZ2VuZXJhdGlvbiAhPT0gZ2VuZXJhdGlvbikgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKHJlc3VsdC5raW5kID09PSBcImxvb2t1cF9mYWlsZWRcIikge1xuICAgICAgdGhpcy5xdW90YUJsb2NrZWQuZGVsZXRlKGlkKTtcbiAgICAgIGxvZ2dlci53YXJuKFwicXVvdGFfdGhyZXNob2xkIGdhdGU6IGxvb2t1cF9mYWlsX29wZW5cIiwge1xuICAgICAgICB0b2tlbklkOiBpZCxcbiAgICAgICAgdG9rZW5OYW1lOiB0b2tlbi5uYW1lLFxuICAgICAgICBsb29rdXBSZWFzb246IHJlc3VsdC5yZWFzb24sXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKHJlc3VsdC51dGlsaXphdGlvblBjdCA+PSB0b2tlbi5xdW90YVRocmVzaG9sZCkge1xuICAgICAgaWYgKCF0aGlzLnF1b3RhQmxvY2tlZC5oYXMoaWQpKVxuICAgICAgICBsb2dnZXIuaW5mbyhcbiAgICAgICAgICBgcXVvdGFfdGhyZXNob2xkIGdhdGU6IG92ZXJfdGhyZXNob2xkICR7dG9rZW4ubmFtZX1bJHtpZH1dICgke3Jlc3VsdC51dGlsaXphdGlvblBjdH0lID49ICR7dG9rZW4ucXVvdGFUaHJlc2hvbGR9JSlgLFxuICAgICAgICApO1xuICAgICAgdGhpcy5xdW90YUJsb2NrZWQuYWRkKGlkKTtcblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnF1b3RhQmxvY2tlZC5kZWxldGUoaWQpKVxuICAgICAgbG9nZ2VyLmluZm8oXG4gICAgICAgIGBxdW90YV90aHJlc2hvbGQgZ2F0ZTogcmVjb3ZlcmVkICR7dG9rZW4ubmFtZX1bJHtpZH1dICgke3Jlc3VsdC51dGlsaXphdGlvblBjdH0lIDwgJHt0b2tlbi5xdW90YVRocmVzaG9sZH0lKWAsXG4gICAgICApO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBpbnZhbGlkYXRlUmF0ZUxpbWl0c0NhY2hlKGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnJhdGVMaW1pdHNDYWNoZS5kZWxldGUoaWQpO1xuICB9XG5cbiAgY291bnRBY3RpdmVUb2tlbnMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gWy4uLnRoaXMudG9rZW5NZXRhZGF0YS52YWx1ZXMoKV0uZmlsdGVyKCh0KSA9PiB0LmFjdGl2ZSkubGVuZ3RoO1xuICB9XG5cbiAgLy8g66qo64uI7YSw66eBIO2PtOungeydgCBUVEwg64K0IOy6kOyLnOunjCDsnb3qs6AgZmV0Y2jtlZjsp4Ag7JWK64qU64ukLiDrr7jsobDtmowg7Yag7YGw7J2AIHVzZWRQZXJjZW506rCAIG51bGzsnbTri6QuXG4gIGdldFF1b3RhU25hcHNob3QoKTogQXJyYXk8e1xuICAgIG5hbWU6IHN0cmluZztcbiAgICB1c2VkUGVyY2VudDogbnVtYmVyIHwgbnVsbDtcbiAgICB0aHJlc2hvbGQ6IG51bWJlciB8IG51bGw7XG4gICAgYmxvY2tlZDogYm9vbGVhbjtcbiAgICByZXNldHNBdDogbnVtYmVyIHwgbnVsbDtcbiAgfT4ge1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG5cbiAgICByZXR1cm4gWy4uLnRoaXMudG9rZW5NZXRhZGF0YS5lbnRyaWVzKCldXG4gICAgICAubWFwKChbaWQsIHRdKSA9PiB7XG4gICAgICAgIGNvbnN0IGNhY2hlZCA9IHRoaXMucmF0ZUxpbWl0c0NhY2hlLmdldChpZCk7XG5cbiAgICAgICAgY29uc3QgZnJlc2ggPVxuICAgICAgICAgIGNhY2hlZCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAgICAgY2FjaGVkLmdlbmVyYXRpb24gPT09IHQuZ2VuZXJhdGlvbiAmJlxuICAgICAgICAgIG5vdyAtIGNhY2hlZC5jYWNoZWRBdCA8IE9wZW5BSURpc3BhdGNoZXIuUkFURV9MSU1JVFNfQ0FDSEVfVFRMO1xuXG4gICAgICAgIGNvbnN0IHByaW1hcnkgPSBmcmVzaCA/IGNhY2hlZC5kYXRhLnJhdGVMaW1pdHM/LnByaW1hcnkgOiB1bmRlZmluZWQ7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBuYW1lOiB0Lm5hbWUsXG4gICAgICAgICAgdXNlZFBlcmNlbnQ6IHByaW1hcnk/LnVzZWRQZXJjZW50ID8/IG51bGwsXG4gICAgICAgICAgdGhyZXNob2xkOiB0LnF1b3RhVGhyZXNob2xkID8/IG51bGwsXG4gICAgICAgICAgYmxvY2tlZDogdGhpcy5xdW90YUJsb2NrZWQuaGFzKGlkKSxcbiAgICAgICAgICAvLyB3aGFt7J2YIFVuaXgg7LSI66W8IGVwb2NoIG1z66GcIOuzgO2ZmO2VnOuLpC5cbiAgICAgICAgICByZXNldHNBdDpcbiAgICAgICAgICAgIHByaW1hcnk/LnJlc2V0c0F0ICE9PSBudWxsICYmIHByaW1hcnk/LnJlc2V0c0F0ICE9PSB1bmRlZmluZWRcbiAgICAgICAgICAgICAgPyBwcmltYXJ5LnJlc2V0c0F0ICogMTAwMFxuICAgICAgICAgICAgICA6IG51bGwsXG4gICAgICAgIH07XG4gICAgICB9KVxuICAgICAgLnRvU29ydGVkKChhLCBiKSA9PiBhLm5hbWUubG9jYWxlQ29tcGFyZShiLm5hbWUpKTtcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFpQ0EsTUFBTSxTQUFTLFVBQVUsQ0FBQyxTQUFTLG1CQUFtQixDQUFDO0FBR3ZELE1BQU0sc0NBQXNCLElBQUksSUFBSTtDQUNsQztDQUNBO0NBQ0E7Q0FDQTtDQUNBO0NBQ0E7QUFD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
|