sonamu 0.10.12 → 0.10.13
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/dist/ai/agents/agent.d.ts +1 -1
- package/dist/ai/agents/agent.d.ts.map +1 -1
- package/dist/ai/agents/agent.js +5 -6
- package/dist/ai/agents/types.d.ts +1 -1
- package/dist/ai/agents/types.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/api.js +18 -18
- package/dist/ai/providers/rtzr/error.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/error.js +17 -15
- package/dist/ai/providers/rtzr/model.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/model.js +3 -2
- package/dist/ai/providers/rtzr/options.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/options.js +16 -16
- package/dist/ai/providers/rtzr/provider.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/provider.js +9 -9
- package/dist/ai/providers/rtzr/utils.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/utils.js +1 -1
- package/dist/api/caster.d.ts.map +1 -1
- package/dist/api/caster.js +17 -17
- package/dist/api/code-converters.d.ts +4 -2
- package/dist/api/code-converters.d.ts.map +1 -1
- package/dist/api/code-converters.js +100 -19
- package/dist/api/config.d.ts +16 -1
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +28 -21
- package/dist/api/context.d.ts +2 -2
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +1 -1
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +18 -11
- package/dist/api/http-validator.d.ts +36 -0
- package/dist/api/http-validator.d.ts.map +1 -0
- package/dist/api/http-validator.js +72 -0
- package/dist/api/index.js +6 -4
- package/dist/api/sonamu.d.ts +59 -20
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +250 -106
- package/dist/api/websocket-helpers.d.ts +7 -5
- package/dist/api/websocket-helpers.d.ts.map +1 -1
- package/dist/api/websocket-helpers.js +6 -6
- package/dist/auth/audit-log/builders.d.ts.map +1 -1
- package/dist/auth/audit-log/builders.js +1 -1
- package/dist/auth/audit-log/client-ip.d.ts +1 -1
- package/dist/auth/audit-log/client-ip.d.ts.map +1 -1
- package/dist/auth/audit-log/client-ip.js +4 -2
- package/dist/auth/audit-log/events.d.ts +5 -1
- package/dist/auth/audit-log/events.d.ts.map +1 -1
- package/dist/auth/audit-log/events.js +1 -1
- package/dist/auth/audit-log/plugin.d.ts +0 -8
- package/dist/auth/audit-log/plugin.d.ts.map +1 -1
- package/dist/auth/audit-log/plugin.js +48 -52
- package/dist/auth/audit-log-ingestor.d.ts.map +1 -1
- package/dist/auth/audit-log-ingestor.js +16 -12
- package/dist/auth/auth-generator.d.ts.map +1 -1
- package/dist/auth/auth-generator.js +1 -1
- package/dist/auth/better-auth-request.d.ts.map +1 -1
- package/dist/auth/better-auth-request.js +6 -5
- package/dist/auth/knex-adapter.js +1 -1
- package/dist/auth/plugins/entity-definitions/index.d.ts +13 -1
- package/dist/auth/plugins/entity-definitions/index.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/index.js +1 -1
- package/dist/auth/plugins/wrappers/admin.d.ts +1 -1
- package/dist/bin/build-config.d.ts +25 -0
- package/dist/bin/build-config.d.ts.map +1 -1
- package/dist/bin/build-config.js +105 -2
- package/dist/bin/cli.js +131 -27
- package/dist/bin/compiler-policy.d.ts +3 -0
- package/dist/bin/compiler-policy.d.ts.map +1 -0
- package/dist/bin/compiler-policy.js +24 -0
- package/dist/bin/fixture.d.ts.map +1 -1
- package/dist/bin/fixture.js +5 -3
- package/dist/bin/test-command.d.ts +22 -1
- package/dist/bin/test-command.d.ts.map +1 -1
- package/dist/bin/test-command.js +18 -10
- package/dist/bin/ts-loader-registration.d.ts +7 -1
- package/dist/bin/ts-loader-registration.d.ts.map +1 -1
- package/dist/bin/ts-loader-registration.js +13 -4
- package/dist/cache/decorator.d.ts.map +1 -1
- package/dist/cache/decorator.js +11 -4
- package/dist/compress/compress.d.ts.map +1 -1
- package/dist/compress/compress.js +1 -1
- package/dist/cone/cone-generator.d.ts +14 -1
- package/dist/cone/cone-generator.d.ts.map +1 -1
- package/dist/cone/cone-generator.js +13 -9
- package/dist/database/_batch_update.js +1 -1
- package/dist/database/base-model.d.ts +22 -10
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.js +26 -16
- package/dist/database/base-model.types.d.ts +15 -3
- package/dist/database/base-model.types.d.ts.map +1 -1
- package/dist/database/db.d.ts +12 -2
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +10 -7
- package/dist/database/knex.d.ts.map +1 -1
- package/dist/database/knex.js +17 -14
- package/dist/database/puri.d.ts +11 -9
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +93 -79
- package/dist/database/puri.types.d.ts +21 -21
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/puri.types.js +1 -1
- package/dist/database/upsert-builder.d.ts +12 -10
- package/dist/database/upsert-builder.d.ts.map +1 -1
- package/dist/database/upsert-builder.js +20 -12
- package/dist/dict/sd.d.ts.map +1 -1
- package/dist/dict/sd.js +1 -1
- package/dist/dict/sonamu-dictionary.d.ts.map +1 -1
- package/dist/dict/sonamu-dictionary.js +1 -1
- package/dist/dict/utils.d.ts.map +1 -1
- package/dist/dict/utils.js +7 -2
- package/dist/entity/entity-manager.d.ts +13 -4
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +19 -11
- package/dist/entity/entity-template-cone.d.ts +73 -5
- package/dist/entity/entity-template-cone.d.ts.map +1 -1
- package/dist/entity/entity-template-cone.js +4 -2
- package/dist/entity/entity.d.ts +6 -2
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +30 -28
- package/dist/env.d.ts +3 -1
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +1 -1
- package/dist/exceptions/error-handler.d.ts.map +1 -1
- package/dist/exceptions/error-handler.js +7 -2
- package/dist/exceptions/so-exceptions.d.ts +24 -20
- package/dist/exceptions/so-exceptions.d.ts.map +1 -1
- package/dist/exceptions/so-exceptions.js +4 -2
- package/dist/filter/utils.d.ts +7 -2
- package/dist/filter/utils.d.ts.map +1 -1
- package/dist/filter/utils.js +8 -6
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -6
- package/dist/logger/configure.d.ts.map +1 -1
- package/dist/logger/configure.js +10 -10
- package/dist/migration/code-generation.d.ts.map +1 -1
- package/dist/migration/code-generation.js +50 -46
- package/dist/migration/index-where-predicate.d.ts.map +1 -1
- package/dist/migration/index-where-predicate.js +22 -8
- package/dist/migration/migration-set.d.ts.map +1 -1
- package/dist/migration/migration-set.js +1 -1
- package/dist/migration/migrator.d.ts +3 -2
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +27 -21
- package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
- package/dist/migration/postgresql-schema-reader.js +51 -36
- package/dist/migration/slack-confirm.d.ts.map +1 -1
- package/dist/migration/slack-confirm.js +1 -1
- package/dist/naite/naite-reporter.js +2 -2
- package/dist/naite/naite.d.ts +74 -15
- package/dist/naite/naite.d.ts.map +1 -1
- package/dist/naite/naite.js +5 -19
- package/dist/runtime-type.d.ts +6 -0
- package/dist/runtime-type.d.ts.map +1 -0
- package/dist/runtime-type.js +26 -0
- package/dist/ssr/hmr-opt-out.d.ts +26 -0
- package/dist/ssr/hmr-opt-out.d.ts.map +1 -0
- package/dist/ssr/hmr-opt-out.js +59 -0
- package/dist/ssr/renderer.d.ts.map +1 -1
- package/dist/ssr/renderer.js +4 -1
- package/dist/storage/base-file.js +14 -14
- package/dist/storage/buffered-file.d.ts +2 -2
- package/dist/storage/buffered-file.d.ts.map +1 -1
- package/dist/storage/buffered-file.js +12 -12
- package/dist/storage/s3-driver.d.ts.map +1 -1
- package/dist/storage/s3-driver.js +1 -1
- package/dist/storage/uploaded-file.d.ts +2 -2
- package/dist/storage/uploaded-file.d.ts.map +1 -1
- package/dist/storage/uploaded-file.js +8 -8
- package/dist/stream/sse.js +11 -11
- package/dist/stream/ws-core.d.ts +1 -1
- package/dist/stream/ws-core.d.ts.map +1 -1
- package/dist/stream/ws-delivery.d.ts +1 -1
- package/dist/stream/ws-delivery.d.ts.map +1 -1
- package/dist/stream/ws-delivery.js +6 -4
- package/dist/stream/ws-local-connection-store.d.ts.map +1 -1
- package/dist/stream/ws-local-connection-store.js +4 -2
- package/dist/stream/ws-presence-store.js +1 -1
- package/dist/stream/ws-registry.d.ts +4 -4
- package/dist/stream/ws-registry.d.ts.map +1 -1
- package/dist/stream/ws-registry.js +4 -2
- package/dist/stream/ws-telemetry.d.ts +16 -12
- package/dist/stream/ws-telemetry.d.ts.map +1 -1
- package/dist/stream/ws-telemetry.js +22 -18
- package/dist/stream/ws.d.ts +18 -12
- package/dist/stream/ws.d.ts.map +1 -1
- package/dist/stream/ws.js +26 -22
- package/dist/syncer/api-parser.js +1 -1
- package/dist/syncer/checksum.d.ts.map +1 -1
- package/dist/syncer/checksum.js +7 -8
- package/dist/syncer/code-generator.d.ts.map +1 -1
- package/dist/syncer/code-generator.js +13 -14
- package/dist/syncer/entity-operations.d.ts.map +1 -1
- package/dist/syncer/entity-operations.js +5 -6
- package/dist/syncer/file-copy.d.ts +5 -0
- package/dist/syncer/file-copy.d.ts.map +1 -0
- package/dist/syncer/file-copy.js +36 -0
- package/dist/syncer/file-patterns.d.ts +1 -0
- package/dist/syncer/file-patterns.d.ts.map +1 -1
- package/dist/syncer/file-patterns.js +5 -2
- package/dist/syncer/file-tracking.d.ts.map +1 -1
- package/dist/syncer/file-tracking.js +5 -4
- package/dist/syncer/filesystem-dependencies.d.ts +15 -0
- package/dist/syncer/filesystem-dependencies.d.ts.map +1 -0
- package/dist/syncer/filesystem-dependencies.js +53 -0
- package/dist/syncer/module-loader.d.ts +1 -1
- package/dist/syncer/module-loader.d.ts.map +1 -1
- package/dist/syncer/module-loader.js +6 -4
- package/dist/syncer/syncer-actions.d.ts +4 -0
- package/dist/syncer/syncer-actions.d.ts.map +1 -1
- package/dist/syncer/syncer-actions.js +34 -17
- package/dist/syncer/syncer.d.ts +17 -6
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +71 -29
- package/dist/syncer/watcher.d.ts.map +1 -1
- package/dist/syncer/watcher.js +3 -3
- package/dist/tasks/decorator.d.ts +6 -6
- package/dist/tasks/decorator.d.ts.map +1 -1
- package/dist/tasks/decorator.js +4 -4
- package/dist/tasks/step-wrapper.d.ts +6 -4
- package/dist/tasks/step-wrapper.d.ts.map +1 -1
- package/dist/tasks/step-wrapper.js +5 -5
- package/dist/tasks/workflow-manager.d.ts.map +1 -1
- package/dist/tasks/workflow-manager.js +13 -7
- package/dist/template/entity-converter.d.ts +1 -1
- package/dist/template/entity-converter.d.ts.map +1 -1
- package/dist/template/entity-converter.js +2 -2
- package/dist/template/helpers.d.ts +8 -6
- package/dist/template/helpers.d.ts.map +1 -1
- package/dist/template/helpers.js +1 -1
- package/dist/template/implementations/generated.template.d.ts.map +1 -1
- package/dist/template/implementations/generated.template.js +4 -4
- package/dist/template/implementations/generated_http.template.d.ts +7 -4
- package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_http.template.js +21 -21
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_sso.template.js +6 -3
- package/dist/template/implementations/http_validators.template.d.ts +18 -0
- package/dist/template/implementations/http_validators.template.d.ts.map +1 -0
- package/dist/template/implementations/http_validators.template.js +127 -0
- package/dist/template/implementations/model.template.d.ts.map +1 -1
- package/dist/template/implementations/model.template.js +1 -1
- package/dist/template/implementations/queries.template.js +1 -1
- package/dist/template/implementations/sd.template.d.ts.map +1 -1
- package/dist/template/implementations/sd.template.js +79 -39
- package/dist/template/implementations/services.template.d.ts.map +1 -1
- package/dist/template/implementations/services.template.js +6 -4
- package/dist/template/implementations/view_form.template.d.ts +6 -1
- package/dist/template/implementations/view_form.template.d.ts.map +1 -1
- package/dist/template/implementations/view_form.template.js +23 -15
- package/dist/template/implementations/view_list.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list.template.js +11 -6
- package/dist/template/template-manager.d.ts.map +1 -1
- package/dist/template/template-manager.js +9 -7
- package/dist/template/template-types.d.ts +12 -5
- package/dist/template/template-types.d.ts.map +1 -1
- package/dist/template/template-types.js +1 -1
- package/dist/template/template.d.ts +2 -2
- package/dist/template/template.d.ts.map +1 -1
- package/dist/template/template.js +6 -4
- package/dist/template/zod-converter.d.ts +0 -19
- package/dist/template/zod-converter.d.ts.map +1 -1
- package/dist/template/zod-converter.js +100 -84
- package/dist/testing/_relation-graph.d.ts.map +1 -1
- package/dist/testing/_relation-graph.js +2 -1
- package/dist/testing/bootstrap.d.ts.map +1 -1
- package/dist/testing/bootstrap.js +9 -6
- package/dist/testing/data-explorer.d.ts +32 -7
- package/dist/testing/data-explorer.d.ts.map +1 -1
- package/dist/testing/data-explorer.js +77 -31
- package/dist/testing/dev-test-routes.d.ts +8 -1
- package/dist/testing/dev-test-routes.d.ts.map +1 -1
- package/dist/testing/dev-test-routes.js +125 -108
- package/dist/testing/dev-vitest-manager.d.ts +54 -8
- package/dist/testing/dev-vitest-manager.d.ts.map +1 -1
- package/dist/testing/dev-vitest-manager.js +24 -9
- package/dist/testing/faker-mappings.d.ts +412 -1
- package/dist/testing/faker-mappings.d.ts.map +1 -1
- package/dist/testing/faker-mappings.js +1 -1
- package/dist/testing/filesystem.d.ts +2 -0
- package/dist/testing/filesystem.d.ts.map +1 -0
- package/dist/testing/filesystem.js +7 -0
- package/dist/testing/fixture-generator.d.ts +25 -8
- package/dist/testing/fixture-generator.d.ts.map +1 -1
- package/dist/testing/fixture-generator.js +132 -73
- package/dist/testing/fixture-loader.d.ts +3 -1
- package/dist/testing/fixture-loader.d.ts.map +1 -1
- package/dist/testing/fixture-loader.js +1 -20
- package/dist/testing/fixture-manager.d.ts +8 -7
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +91 -59
- package/dist/testing/global-setup.d.ts.map +1 -1
- package/dist/testing/global-setup.js +5 -2
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +6 -3
- package/dist/types/types.d.ts +101 -99
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +234 -225
- package/dist/ui/ai-api.d.ts.map +1 -1
- package/dist/ui/ai-api.js +1 -1
- package/dist/ui/ai-client.d.ts.map +1 -1
- package/dist/ui/ai-client.js +28 -18
- package/dist/ui/api.d.ts.map +1 -1
- package/dist/ui/api.js +135 -128
- package/dist/ui/async-route.d.ts +3 -0
- package/dist/ui/async-route.d.ts.map +1 -0
- package/dist/ui/async-route.js +12 -0
- package/dist/ui/cdd-service.d.ts +9 -7
- package/dist/ui/cdd-service.d.ts.map +1 -1
- package/dist/ui/cdd-service.js +7 -5
- package/dist/ui/migrations-api.d.ts.map +1 -1
- package/dist/ui/migrations-api.js +17 -15
- package/dist/ui-web/assets/index-DV1AAq6W.js +178 -0
- package/dist/ui-web/index.html +1 -1
- package/dist/utils/formatter.d.ts.map +1 -1
- package/dist/utils/formatter.js +7 -5
- package/dist/utils/fs-utils.d.ts +3 -3
- package/dist/utils/fs-utils.d.ts.map +1 -1
- package/dist/utils/fs-utils.js +6 -6
- package/dist/utils/model.d.ts +3 -5
- package/dist/utils/model.d.ts.map +1 -1
- package/dist/utils/model.js +1 -1
- package/dist/utils/object-utils.d.ts +1 -1
- package/dist/utils/object-utils.d.ts.map +1 -1
- package/dist/utils/object-utils.js +17 -16
- package/dist/utils/process-utils.d.ts.map +1 -1
- package/dist/utils/process-utils.js +4 -2
- package/dist/utils/runtime-value.d.ts +13 -0
- package/dist/utils/runtime-value.d.ts.map +1 -0
- package/dist/utils/runtime-value.js +40 -0
- package/dist/utils/sql-parser.d.ts +8 -1
- package/dist/utils/sql-parser.d.ts.map +1 -1
- package/dist/utils/sql-parser.js +6 -3
- package/dist/utils/type-utils.d.ts.map +1 -1
- package/dist/utils/type-utils.js +10 -8
- package/dist/utils/utils.d.ts +2 -2
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +11 -8
- package/dist/utils/zod-error.d.ts.map +1 -1
- package/dist/utils/zod-error.js +7 -4
- package/dist/vector/chunking.d.ts.map +1 -1
- package/dist/vector/chunking.js +1 -1
- package/dist/vector/embedding.d.ts.map +1 -1
- package/dist/vector/embedding.js +1 -1
- package/dist/vector/types.d.ts +3 -2
- package/dist/vector/types.d.ts.map +1 -1
- package/package.json +5 -3
- package/src/ai/agents/agent.ts +5 -5
- package/src/ai/agents/types.ts +1 -1
- package/src/ai/providers/rtzr/__tests__/model.test.ts +2 -2
- package/src/ai/providers/rtzr/error.ts +5 -3
- package/src/ai/providers/rtzr/model.ts +3 -2
- package/src/ai/providers/rtzr/options.ts +10 -5
- package/src/ai/providers/rtzr/provider.ts +10 -10
- package/src/ai/providers/rtzr/utils.ts +3 -1
- package/src/api/__tests__/config.test.ts +11 -21
- package/src/api/__tests__/sonamu.http-validator.test.ts +512 -0
- package/src/api/__tests__/sonamu.websocket.test.ts +51 -41
- package/src/api/__tests__/zod-compiler-policy.test.ts +95 -0
- package/src/api/caster.ts +6 -8
- package/src/api/code-converters.ts +136 -36
- package/src/api/config.ts +62 -4
- package/src/api/context.ts +3 -3
- package/src/api/decorators.ts +28 -17
- package/src/api/http-validator.ts +149 -0
- package/src/api/sonamu.ts +459 -152
- package/src/api/websocket-helpers.ts +24 -17
- package/src/auth/audit-log/builders.ts +3 -2
- package/src/auth/audit-log/client-ip.ts +4 -2
- package/src/auth/audit-log/events.ts +15 -1
- package/src/auth/audit-log/plugin.ts +129 -200
- package/src/auth/audit-log-ingestor.ts +19 -15
- package/src/auth/auth-generator.ts +10 -5
- package/src/auth/better-auth-request.ts +4 -3
- package/src/auth/knex-adapter.ts +8 -2
- package/src/auth/plugins/entity-definitions/index.ts +6 -5
- package/src/bin/__tests__/http-validator-benchmark.test.ts +94 -0
- package/src/bin/__tests__/test-command.test.ts +9 -15
- package/src/bin/__tests__/ts-loader-register.test.ts +15 -17
- package/src/bin/__tests__/zod-compiler-build.test.ts +307 -0
- package/src/bin/build-config.ts +167 -0
- package/src/bin/cli.ts +153 -36
- package/src/bin/compiler-policy.ts +35 -0
- package/src/bin/fixture.ts +14 -3
- package/src/bin/test-command.ts +74 -29
- package/src/bin/ts-loader-registration.ts +22 -4
- package/src/cache/decorator.ts +10 -3
- package/src/compress/compress.ts +17 -4
- package/src/cone/cone-generator.ts +34 -6
- package/src/database/__tests__/db.test.ts +1 -0
- package/src/database/__tests__/puri.test.ts +16 -15
- package/src/database/__tests__/transaction-scope.test.ts +5 -0
- package/src/database/_batch_update.ts +1 -0
- package/src/database/base-model.ts +81 -50
- package/src/database/base-model.types.ts +6 -6
- package/src/database/db.ts +29 -19
- package/src/database/knex.ts +30 -17
- package/src/database/puri-subset.test-d.ts +17 -0
- package/src/database/puri.ts +181 -143
- package/src/database/puri.types.test-d.ts +31 -1
- package/src/database/puri.types.ts +23 -21
- package/src/database/upsert-builder.ts +75 -53
- package/src/dict/sd.ts +15 -5
- package/src/dict/sonamu-dictionary.ts +6 -6
- package/src/dict/utils.ts +9 -1
- package/src/entity/entity-manager.ts +26 -9
- package/src/entity/entity-template-cone.ts +5 -10
- package/src/entity/entity.ts +50 -34
- package/src/env.ts +7 -3
- package/src/exceptions/error-handler.ts +17 -2
- package/src/exceptions/so-exceptions.ts +26 -20
- package/src/filter/utils.ts +21 -11
- package/src/index.ts +3 -0
- package/src/logger/configure.ts +26 -18
- package/src/migration/__tests__/migrator.test.ts +50 -57
- package/src/migration/code-generation.ts +132 -104
- package/src/migration/index-where-predicate.ts +51 -24
- package/src/migration/migration-set.ts +11 -5
- package/src/migration/migrator.ts +68 -41
- package/src/migration/postgresql-schema-reader.ts +52 -47
- package/src/migration/slack-confirm.ts +17 -15
- package/src/naite/naite-reporter.ts +1 -1
- package/src/naite/naite.ts +97 -24
- package/src/runtime-type.ts +34 -0
- package/src/ssr/hmr-opt-out.ts +78 -0
- package/src/ssr/renderer.ts +6 -0
- package/src/storage/base-file.ts +13 -13
- package/src/storage/buffered-file.ts +11 -11
- package/src/storage/s3-driver.ts +4 -1
- package/src/storage/uploaded-file.ts +8 -8
- package/src/stream/__tests__/ws-contracts.test.ts +4 -2
- package/src/stream/__tests__/ws-telemetry.test.ts +1 -1
- package/src/stream/__tests__/ws.test.ts +30 -6
- package/src/stream/sse.ts +12 -11
- package/src/stream/ws-core.ts +1 -1
- package/src/stream/ws-delivery.ts +16 -7
- package/src/stream/ws-local-connection-store.ts +2 -3
- package/src/stream/ws-presence-store.ts +6 -1
- package/src/stream/ws-registry.ts +16 -7
- package/src/stream/ws-telemetry.ts +66 -43
- package/src/stream/ws.ts +73 -39
- package/src/syncer/__tests__/api-parser.websocket-type-ref.test.ts +3 -2
- package/src/syncer/__tests__/http-validator-registry.test.ts +137 -0
- package/src/syncer/api-parser.ts +67 -27
- package/src/syncer/checksum.ts +17 -11
- package/src/syncer/code-generator.ts +25 -17
- package/src/syncer/entity-operations.ts +3 -5
- package/src/syncer/file-copy.ts +46 -0
- package/src/syncer/file-patterns.ts +11 -8
- package/src/syncer/file-tracking.ts +3 -4
- package/src/syncer/filesystem-dependencies.ts +73 -0
- package/src/syncer/module-loader.ts +8 -4
- package/src/syncer/syncer-actions.ts +56 -18
- package/src/syncer/syncer.ts +116 -43
- package/src/syncer/watcher.ts +8 -4
- package/src/tasks/decorator.ts +20 -12
- package/src/tasks/step-wrapper.ts +19 -9
- package/src/tasks/workflow-manager.ts +15 -9
- package/src/template/__tests__/http_validators.template.test.ts +160 -0
- package/src/template/__tests__/services.template.mutation.test.ts +24 -23
- package/src/template/__tests__/services.template.websocket.test.ts +21 -25
- package/src/template/entity-converter.ts +5 -2
- package/src/template/helpers.ts +8 -9
- package/src/template/implementations/generated.template.ts +5 -4
- package/src/template/implementations/generated_http.template.ts +61 -15
- package/src/template/implementations/generated_sso.template.ts +15 -4
- package/src/template/implementations/http_validators.template.ts +175 -0
- package/src/template/implementations/model.template.ts +3 -1
- package/src/template/implementations/sd.template.ts +81 -41
- package/src/template/implementations/services.template.ts +2 -2
- package/src/template/implementations/view_form.template.ts +56 -39
- package/src/template/implementations/view_list.template.ts +31 -23
- package/src/template/template-manager.ts +15 -13
- package/src/template/template-types.ts +13 -5
- package/src/template/template.ts +4 -3
- package/src/template/zod-converter.ts +206 -91
- package/src/testing/__tests__/dev-test-routes.test.ts +85 -25
- package/src/testing/__tests__/dev-vitest-manager.test.ts +15 -15
- package/src/testing/_relation-graph.ts +4 -1
- package/src/testing/bootstrap.ts +12 -5
- package/src/testing/data-explorer.ts +102 -53
- package/src/testing/dev-test-routes.ts +87 -50
- package/src/testing/dev-vitest-manager.ts +88 -32
- package/src/testing/faker-mappings.ts +2 -2
- package/src/testing/filesystem.ts +1 -0
- package/src/testing/fixture-generator.ts +191 -131
- package/src/testing/fixture-loader.ts +5 -1
- package/src/testing/fixture-manager.ts +129 -90
- package/src/testing/global-setup.ts +7 -3
- package/src/testing/index.ts +5 -0
- package/src/types/__tests__/entity-json-schema-search-text.test.ts +9 -3
- package/src/types/types.ts +184 -158
- package/src/ui/ai-api.ts +9 -7
- package/src/ui/ai-client.ts +61 -56
- package/src/ui/api.ts +727 -616
- package/src/ui/async-route.ts +4 -0
- package/src/ui/cdd-service.ts +35 -12
- package/src/ui/migrations-api.ts +63 -51
- package/src/utils/formatter.ts +7 -3
- package/src/utils/fs-utils.ts +5 -5
- package/src/utils/model.ts +4 -5
- package/src/utils/object-utils.ts +32 -22
- package/src/utils/process-utils.ts +4 -1
- package/src/utils/runtime-value.ts +43 -0
- package/src/utils/sql-parser.ts +13 -6
- package/src/utils/type-utils.ts +9 -7
- package/src/utils/utils.ts +19 -21
- package/src/utils/zod-error.ts +4 -2
- package/src/vector/chunking.ts +6 -1
- package/src/vector/embedding.ts +2 -1
- package/src/vector/types.ts +4 -2
- package/tsdown.api.config.ts +5 -2
- package/dist/ui-web/assets/index-C0m1pk6K.js +0 -177
|
@@ -1,19 +1,40 @@
|
|
|
1
1
|
import { __esmMin, __toCommonJS } from "../_virtual/_rolldown/runtime.js";
|
|
2
|
+
import { init_runtime_value, isFunctionValue } from "../utils/runtime-value.js";
|
|
2
3
|
import { init_controller, isTest } from "../utils/controller.js";
|
|
3
4
|
import { init_types, isBelongsToOneRelationProp, isOneToOneRelationProp, isRelationProp } from "../types/types.js";
|
|
4
5
|
import { api_exports, init_api } from "../api/index.js";
|
|
6
|
+
import { DataExplorer, dataExplorerRecordSchema, dataExplorerValueSchema, dataSourceConfigSchema, init_data_explorer } from "./data-explorer.js";
|
|
5
7
|
import { FixtureManager, init_fixture_manager } from "./fixture-manager.js";
|
|
6
|
-
import { DataExplorer, init_data_explorer } from "./data-explorer.js";
|
|
7
8
|
import { fakerMappings, init_faker_mappings } from "./faker-mappings.js";
|
|
9
|
+
import { z } from "zod";
|
|
8
10
|
import chalk from "chalk";
|
|
9
11
|
//#region src/testing/fixture-generator.ts
|
|
10
|
-
|
|
12
|
+
function parseFixtureSourceRecord(record) {
|
|
13
|
+
return {
|
|
14
|
+
...record,
|
|
15
|
+
id: fixtureRecordIdSchema.parse(record.id)
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
var fakerFunctionSchema, fakerNamespaceObjectSchema, dynamicNamespaceSchema, generatorArgumentsSchema, fixtureRecordIdSchema, fixtureWhereValueSchema, FixtureGenerator;
|
|
11
19
|
var init_fixture_generator = __esmMin((() => {
|
|
12
20
|
init_types();
|
|
13
21
|
init_controller();
|
|
22
|
+
init_runtime_value();
|
|
14
23
|
init_data_explorer();
|
|
15
24
|
init_faker_mappings();
|
|
16
25
|
init_fixture_manager();
|
|
26
|
+
fakerFunctionSchema = z.custom(isFunctionValue, "Faker 경로의 마지막 값은 함수여야 합니다.");
|
|
27
|
+
fakerNamespaceObjectSchema = z.object({});
|
|
28
|
+
dynamicNamespaceSchema = z.custom((candidate) => fakerNamespaceObjectSchema.safeParse(candidate).success, "Faker 경로는 객체 namespace여야 합니다.");
|
|
29
|
+
generatorArgumentsSchema = z.array(dataExplorerValueSchema);
|
|
30
|
+
fixtureRecordIdSchema = z.union([z.number(), z.string()]);
|
|
31
|
+
fixtureWhereValueSchema = z.union([
|
|
32
|
+
z.string(),
|
|
33
|
+
z.number(),
|
|
34
|
+
z.boolean(),
|
|
35
|
+
z.date(),
|
|
36
|
+
z.null()
|
|
37
|
+
]);
|
|
17
38
|
FixtureGenerator = class {
|
|
18
39
|
sourceDb;
|
|
19
40
|
targetDbName;
|
|
@@ -35,14 +56,16 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
35
56
|
locale: options?.locale || "ko",
|
|
36
57
|
useLLM: options?.useLLM || false,
|
|
37
58
|
enableLLMCache: options?.enableLLMCache !== false,
|
|
38
|
-
llmModel: options?.llmModel || "claude-sonnet-4-6"
|
|
59
|
+
llmModel: options?.llmModel || "claude-sonnet-4-6",
|
|
60
|
+
generateText: options?.generateText
|
|
39
61
|
};
|
|
40
62
|
}
|
|
41
63
|
/**
|
|
42
64
|
* Fixture 생성 (단일)
|
|
43
65
|
* @returns 생성된 fixture 데이터 (메모리 상)
|
|
44
66
|
*/
|
|
45
|
-
async generate(entityName, overrides
|
|
67
|
+
async generate(entityName, overrides, context = this.createContext()) {
|
|
68
|
+
const parsedOverrides = dataExplorerRecordSchema.parse(overrides ?? {});
|
|
46
69
|
let entity = this.entityCache.get(entityName);
|
|
47
70
|
if (!entity) {
|
|
48
71
|
entity = this.entityManager.get(entityName);
|
|
@@ -54,7 +77,7 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
54
77
|
for (const prop of entity.props) {
|
|
55
78
|
if ("virtual" in prop && prop.virtual) continue;
|
|
56
79
|
if (prop.name === "id") {
|
|
57
|
-
if (prop.type === "integer" || prop.type === "bigInteger" || prop.type === "string" && "dbDefault" in prop &&
|
|
80
|
+
if (prop.type === "integer" || prop.type === "bigInteger" || prop.type === "string" && "dbDefault" in prop && z.string().safeParse(prop.dbDefault).data?.includes("nextval") === true) continue;
|
|
58
81
|
if (prop.type === "string") {
|
|
59
82
|
const { faker: _faker } = await import("@faker-js/faker");
|
|
60
83
|
fixture[prop.name] = _faker.string.alphanumeric(32);
|
|
@@ -67,15 +90,15 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
67
90
|
}
|
|
68
91
|
continue;
|
|
69
92
|
}
|
|
70
|
-
if (prop.name in
|
|
71
|
-
fixture[prop.name] =
|
|
93
|
+
if (prop.name in parsedOverrides) {
|
|
94
|
+
fixture[prop.name] = parsedOverrides[prop.name];
|
|
72
95
|
continue;
|
|
73
96
|
}
|
|
74
97
|
const cone = prop.cone;
|
|
75
98
|
if (isRelationProp(prop)) {
|
|
76
99
|
const fkColName = `${prop.name}_id`;
|
|
77
|
-
if (fkColName in
|
|
78
|
-
fixture[fkColName] =
|
|
100
|
+
if (fkColName in parsedOverrides && (isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop) && prop.hasJoinColumn)) {
|
|
101
|
+
fixture[fkColName] = parsedOverrides[fkColName];
|
|
79
102
|
continue;
|
|
80
103
|
}
|
|
81
104
|
const relationValue = await this.generateRelationValue(entity, prop, context);
|
|
@@ -85,7 +108,9 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
85
108
|
}
|
|
86
109
|
if (cone?.note && this.options.useLLM) try {
|
|
87
110
|
const llmValue = await this.generateWithLLM(cone.note, prop, entity, rowKey);
|
|
88
|
-
|
|
111
|
+
const llmText = z.string().safeParse(llmValue);
|
|
112
|
+
const maxLength = "length" in prop ? z.number().safeParse(prop.length) : void 0;
|
|
113
|
+
if (llmText.success && maxLength?.success && llmText.data.length > maxLength.data) fixture[prop.name] = llmText.data.slice(0, maxLength.data);
|
|
89
114
|
else fixture[prop.name] = llmValue;
|
|
90
115
|
continue;
|
|
91
116
|
} catch (error) {
|
|
@@ -96,19 +121,22 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
96
121
|
continue;
|
|
97
122
|
}
|
|
98
123
|
if (cone?.fixtureDefault !== void 0) {
|
|
99
|
-
fixture[prop.name] = cone.fixtureDefault;
|
|
124
|
+
fixture[prop.name] = dataExplorerValueSchema.parse(cone.fixtureDefault);
|
|
100
125
|
continue;
|
|
101
126
|
}
|
|
102
127
|
fixture[prop.name] = await this.generateDefaultValue(prop, entity);
|
|
103
128
|
}
|
|
104
|
-
|
|
129
|
+
const email = z.string().safeParse(fixture.email);
|
|
130
|
+
if (email.success && !("email" in parsedOverrides)) {
|
|
105
131
|
const nameValue = fixture.name || fixture.username || fixture.full_name || fixture.name_en;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
132
|
+
const parsedName = z.string().safeParse(nameValue);
|
|
133
|
+
if (parsedName.success) {
|
|
134
|
+
const domain = email.data.split("@")[1] || "example.com";
|
|
135
|
+
fixture.email = `${await this.romanizeName(parsedName.data)}@${domain}`;
|
|
109
136
|
}
|
|
110
137
|
}
|
|
111
|
-
|
|
138
|
+
const password = z.string().safeParse(fixture.password);
|
|
139
|
+
if (password.success && password.data.length > 0) fixture.password = await (await import("bcrypt")).hash(password.data, 10);
|
|
112
140
|
context.fixtures.set(tempId, fixture);
|
|
113
141
|
return fixture;
|
|
114
142
|
}
|
|
@@ -122,18 +150,22 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
122
150
|
if (dataSource) {
|
|
123
151
|
const cacheKey = `${prop.with}:${JSON.stringify(dataSource)}`;
|
|
124
152
|
if (!context.referenceCache.has(cacheKey)) {
|
|
153
|
+
const dataSourceConfig = dataSourceConfigSchema.parse(dataSource.config ?? {});
|
|
125
154
|
const exploreResult = await this.dataExplorer.exploreWithRelations(prop.with, {
|
|
126
155
|
strategy: dataSource.strategy,
|
|
127
|
-
limit:
|
|
156
|
+
limit: dataSourceConfig.limit ?? 10,
|
|
128
157
|
includeRelations: true,
|
|
129
158
|
maxDepth: 3,
|
|
130
|
-
...
|
|
159
|
+
...dataSourceConfig
|
|
131
160
|
});
|
|
132
161
|
context.referenceCache.set(cacheKey, exploreResult.main.records);
|
|
133
162
|
await this.importExploreResult(exploreResult, context);
|
|
134
163
|
}
|
|
135
164
|
const candidates = context.referenceCache.get(cacheKey);
|
|
136
|
-
if (candidates && candidates.length > 0)
|
|
165
|
+
if (candidates && candidates.length > 0) {
|
|
166
|
+
const selected = candidates[Math.floor(Math.random() * candidates.length)];
|
|
167
|
+
return z.union([z.number(), z.string()]).parse(selected.id);
|
|
168
|
+
}
|
|
137
169
|
}
|
|
138
170
|
const autoKey = `${prop.with}:auto`;
|
|
139
171
|
if (!context.referenceCache.has(autoKey)) {
|
|
@@ -147,7 +179,10 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
147
179
|
if (autoExploreResult.main.records.length > 0) await this.importExploreResult(autoExploreResult, context);
|
|
148
180
|
}
|
|
149
181
|
const autoCandidates = context.referenceCache.get(autoKey);
|
|
150
|
-
if (autoCandidates && autoCandidates.length > 0)
|
|
182
|
+
if (autoCandidates && autoCandidates.length > 0) {
|
|
183
|
+
const selected = autoCandidates[Math.floor(Math.random() * autoCandidates.length)];
|
|
184
|
+
return z.union([z.number(), z.string()]).parse(selected.id);
|
|
185
|
+
}
|
|
151
186
|
if (prop.nullable) return null;
|
|
152
187
|
throw new Error(`FixtureGenerator: ${entity.id}.${prop.name}에 필요한 ${prop.with} 데이터가 없습니다. 먼저 ${prop.with}를 생성하거나 cone.dataSource를 설정하세요.`);
|
|
153
188
|
}
|
|
@@ -172,8 +207,8 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
172
207
|
}
|
|
173
208
|
if (recordsToImport.length > 0) for (const record of recordsToImport) {
|
|
174
209
|
!isTest() && console.log(chalk.gray(` - Processing ${entityId} record:`, JSON.stringify(record).slice(0, 100)));
|
|
175
|
-
const fixtureRecords = await FixtureManager.createFixtureRecord(entity, record, {
|
|
176
|
-
|
|
210
|
+
const fixtureRecords = await FixtureManager.createFixtureRecord(entity, parseFixtureSourceRecord(record), {
|
|
211
|
+
db: this.sourceDb,
|
|
177
212
|
singleRecord: true
|
|
178
213
|
});
|
|
179
214
|
allFixtureRecords.push(...fixtureRecords);
|
|
@@ -191,8 +226,8 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
191
226
|
}
|
|
192
227
|
if (mainRecordsToImport.length > 0) for (const record of mainRecordsToImport) {
|
|
193
228
|
!isTest() && console.log(chalk.gray(` - Processing ${exploreResult.main.entityId} record:`, JSON.stringify(record).slice(0, 100)));
|
|
194
|
-
const fixtureRecords = await FixtureManager.createFixtureRecord(mainEntity, record, {
|
|
195
|
-
|
|
229
|
+
const fixtureRecords = await FixtureManager.createFixtureRecord(mainEntity, parseFixtureSourceRecord(record), {
|
|
230
|
+
db: this.sourceDb,
|
|
196
231
|
singleRecord: true
|
|
197
232
|
});
|
|
198
233
|
allFixtureRecords.push(...fixtureRecords);
|
|
@@ -220,13 +255,16 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
220
255
|
if (!match) throw new Error(`FixtureGenerator: Invalid faker expression for ${prop.name}: ${generator}`);
|
|
221
256
|
const [, path, argsStr] = match;
|
|
222
257
|
const parts = path.split(".");
|
|
223
|
-
let
|
|
224
|
-
for (const part of parts)
|
|
225
|
-
|
|
226
|
-
|
|
258
|
+
let member = dynamicNamespaceSchema.parse(faker);
|
|
259
|
+
for (const part of parts) {
|
|
260
|
+
if (!(part in member)) throw new Error(`FixtureGenerator: Invalid faker path for ${prop.name}: faker.${path}`);
|
|
261
|
+
const nextMember = member[part];
|
|
262
|
+
if (part !== parts.at(-1)) member = dynamicNamespaceSchema.parse(nextMember);
|
|
263
|
+
}
|
|
264
|
+
const fn = fakerFunctionSchema.parse(member[parts.at(-1) ?? ""]);
|
|
227
265
|
let args = [];
|
|
228
266
|
if (argsStr?.trim()) args = this.parseGeneratorArgs(argsStr, prop.name);
|
|
229
|
-
return fn(...args);
|
|
267
|
+
return dataExplorerValueSchema.parse(fn(...args));
|
|
230
268
|
} catch (error) {
|
|
231
269
|
!isTest() && console.log(chalk.yellow(`Failed to execute generator "${generator}" for ${prop.name}, falling back to default:`), error);
|
|
232
270
|
return this.generateDefaultValue(prop, entity);
|
|
@@ -442,7 +480,7 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
442
480
|
const fakerJA = fakerModule.fakerJA;
|
|
443
481
|
/** Faker 표현식이 아닌 리터럴 값은 JSON으로 파싱합니다 */
|
|
444
482
|
if (!expression.startsWith("faker")) try {
|
|
445
|
-
return JSON.parse(expression);
|
|
483
|
+
return dataExplorerValueSchema.parse(JSON.parse(expression));
|
|
446
484
|
} catch {
|
|
447
485
|
return expression;
|
|
448
486
|
}
|
|
@@ -456,13 +494,16 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
456
494
|
const [, path, argsStr] = funcMatch;
|
|
457
495
|
const parts = path.split(".");
|
|
458
496
|
/** 점 표기법(dot notation)으로 Faker 함수를 찾아갑니다 */
|
|
459
|
-
let
|
|
460
|
-
for (const part of parts)
|
|
461
|
-
|
|
462
|
-
|
|
497
|
+
let member = dynamicNamespaceSchema.parse(selectedFaker);
|
|
498
|
+
for (const part of parts) {
|
|
499
|
+
if (!(part in member)) throw new Error(`Invalid faker path for ${prop.name}: ${fakerName}.${path}`);
|
|
500
|
+
const nextMember = member[part];
|
|
501
|
+
if (part !== parts.at(-1)) member = dynamicNamespaceSchema.parse(nextMember);
|
|
502
|
+
}
|
|
503
|
+
const fn = fakerFunctionSchema.parse(member[parts.at(-1) ?? ""]);
|
|
463
504
|
let args = [];
|
|
464
505
|
if (argsStr?.trim()) args = this.parseGeneratorArgs(argsStr, prop.name);
|
|
465
|
-
return fn(...args);
|
|
506
|
+
return dataExplorerValueSchema.parse(fn(...args));
|
|
466
507
|
}
|
|
467
508
|
/**
|
|
468
509
|
* fixtureHint를 LLM에게 전달하여 현실적인 테스트 데이터를 생성합니다.
|
|
@@ -490,13 +531,13 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
490
531
|
}
|
|
491
532
|
const apiKey = this.getApiKey();
|
|
492
533
|
const { createAnthropic } = await import("@ai-sdk/anthropic");
|
|
493
|
-
const
|
|
494
|
-
const rowResponse = await generateText({
|
|
534
|
+
const rowResponse = await (await this.getTextGenerator())({
|
|
495
535
|
model: createAnthropic({ apiKey })(this.options.llmModel || "claude-sonnet-4-6"),
|
|
496
536
|
prompt: this.buildRowLLMPrompt(llmProps, entity)
|
|
497
537
|
});
|
|
498
|
-
|
|
499
|
-
|
|
538
|
+
const rowResponseText = z.string().safeParse(rowResponse?.text);
|
|
539
|
+
if (!rowResponseText.success) throw new Error("Invalid LLM response");
|
|
540
|
+
const rowResult = this.parseRowLLMResponse(rowResponseText.data, llmProps);
|
|
500
541
|
for (const [fieldName, value] of Object.entries(rowResult)) this.llmCache.set(`${rowKey}:${fieldName}`, value);
|
|
501
542
|
if (this.llmCache.has(rowCacheKey)) return this.llmCache.get(rowCacheKey);
|
|
502
543
|
return this.generateSingleWithLLM(fixtureHint, prop, entity);
|
|
@@ -511,16 +552,21 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
511
552
|
if (this.options.enableLLMCache && this.llmCache.has(cacheKey)) return this.llmCache.get(cacheKey);
|
|
512
553
|
const apiKey = this.getApiKey();
|
|
513
554
|
const { createAnthropic } = await import("@ai-sdk/anthropic");
|
|
514
|
-
const
|
|
515
|
-
const singleResponse = await generateText({
|
|
555
|
+
const singleResponse = await (await this.getTextGenerator())({
|
|
516
556
|
model: createAnthropic({ apiKey })(this.options.llmModel || "claude-sonnet-4-6"),
|
|
517
557
|
prompt: this.buildLLMPrompt(fixtureHint, prop, entity)
|
|
518
558
|
});
|
|
519
|
-
|
|
520
|
-
|
|
559
|
+
const singleResponseText = z.string().safeParse(singleResponse?.text);
|
|
560
|
+
if (!singleResponseText.success) throw new Error("Invalid LLM response");
|
|
561
|
+
const value = this.parseLLMResponse(singleResponseText.data, prop.type);
|
|
521
562
|
if (this.options.enableLLMCache) this.llmCache.set(cacheKey, value);
|
|
522
563
|
return value;
|
|
523
564
|
}
|
|
565
|
+
async getTextGenerator() {
|
|
566
|
+
if (this.options.generateText) return this.options.generateText;
|
|
567
|
+
const ai = await import("ai");
|
|
568
|
+
return async (request) => ai.generateText(request);
|
|
569
|
+
}
|
|
524
570
|
/**
|
|
525
571
|
* row 전체를 한 번에 생성하는 LLM 프롬프트를 만듭니다.
|
|
526
572
|
*/
|
|
@@ -545,7 +591,7 @@ var init_fixture_generator = __esmMin((() => {
|
|
|
545
591
|
return desc;
|
|
546
592
|
}).join("\n");
|
|
547
593
|
const otherPropsContext = otherProps ? `\n\nOther fields in this entity (for context, do NOT generate these):\n${otherProps}` : "";
|
|
548
|
-
const
|
|
594
|
+
const resultTemplate = props.map((p) => ` "${p.name}": <${p.type}>`).join(",\n");
|
|
549
595
|
const entityContext = entity.cone?.note ? `\nEntity description: ${entity.cone.note}` : "";
|
|
550
596
|
return `Generate test fixture data for the ${entity.id} entity. All fields must be coherent and consistent with each other.
|
|
551
597
|
|
|
@@ -563,7 +609,7 @@ Rules:
|
|
|
563
609
|
|
|
564
610
|
Return exactly this JSON shape:
|
|
565
611
|
{
|
|
566
|
-
${
|
|
612
|
+
${resultTemplate}
|
|
567
613
|
}`;
|
|
568
614
|
}
|
|
569
615
|
/**
|
|
@@ -573,12 +619,12 @@ ${outputShape}
|
|
|
573
619
|
const jsonText = text.trim().replace(/^```json\s*/i, "").replace(/```\s*$/, "").trim();
|
|
574
620
|
let parsed;
|
|
575
621
|
try {
|
|
576
|
-
const
|
|
577
|
-
if (
|
|
622
|
+
const parsedRecord = dataExplorerRecordSchema.safeParse(JSON.parse(jsonText));
|
|
623
|
+
if (!parsedRecord.success) {
|
|
578
624
|
!isTest() && console.warn("[FixtureGenerator] Row LLM response is not a plain object:", text);
|
|
579
625
|
return {};
|
|
580
626
|
}
|
|
581
|
-
parsed =
|
|
627
|
+
parsed = parsedRecord.data;
|
|
582
628
|
} catch {
|
|
583
629
|
!isTest() && console.warn("[FixtureGenerator] Failed to parse row LLM response:", text);
|
|
584
630
|
return {};
|
|
@@ -613,11 +659,11 @@ Rules:
|
|
|
613
659
|
parseLLMResponse(text, propType) {
|
|
614
660
|
const cleaned = text.trim();
|
|
615
661
|
if (propType.endsWith("[]")) try {
|
|
616
|
-
const parsed = JSON.parse(cleaned);
|
|
662
|
+
const parsed = dataExplorerValueSchema.parse(JSON.parse(cleaned));
|
|
617
663
|
const baseType = propType.slice(0, -2);
|
|
618
664
|
if (Array.isArray(parsed)) return parsed.map((item) => {
|
|
619
665
|
if (item === null || item === void 0) return this.getDefaultValueForType(baseType);
|
|
620
|
-
if (
|
|
666
|
+
if (dataExplorerRecordSchema.safeParse(item).success || Array.isArray(item)) return baseType === "json" ? item : this.parseScalarValue(JSON.stringify(item), baseType);
|
|
621
667
|
return this.parseScalarValue(String(item), baseType);
|
|
622
668
|
});
|
|
623
669
|
if (parsed === null || parsed === void 0) return [this.getDefaultValueForType(baseType)];
|
|
@@ -665,7 +711,7 @@ Rules:
|
|
|
665
711
|
return Number.isNaN(date.getTime()) ? /* @__PURE__ */ new Date() : date;
|
|
666
712
|
}
|
|
667
713
|
case "json": try {
|
|
668
|
-
return JSON.parse(cleaned);
|
|
714
|
+
return dataExplorerValueSchema.parse(JSON.parse(cleaned));
|
|
669
715
|
} catch {
|
|
670
716
|
return cleaned;
|
|
671
717
|
}
|
|
@@ -683,15 +729,20 @@ Rules:
|
|
|
683
729
|
* 3. 단순 단일 인자 폴백 (숫자, 문자열)
|
|
684
730
|
*/
|
|
685
731
|
parseGeneratorArgs(argsStr, propName) {
|
|
732
|
+
let parsedArguments;
|
|
686
733
|
try {
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
734
|
+
parsedArguments = generatorArgumentsSchema.parse(JSON.parse(`[${argsStr}]`));
|
|
735
|
+
} catch {
|
|
736
|
+
parsedArguments = null;
|
|
737
|
+
}
|
|
738
|
+
if (parsedArguments) return parsedArguments;
|
|
690
739
|
try {
|
|
691
740
|
const jsonStr = this.convertJsLiteralToJson(argsStr);
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
741
|
+
parsedArguments = generatorArgumentsSchema.parse(JSON.parse(`[${jsonStr}]`));
|
|
742
|
+
} catch {
|
|
743
|
+
parsedArguments = null;
|
|
744
|
+
}
|
|
745
|
+
if (parsedArguments) return parsedArguments;
|
|
695
746
|
const trimmed = argsStr.trim();
|
|
696
747
|
if (!Number.isNaN(Number(trimmed))) return [Number(trimmed)];
|
|
697
748
|
if (trimmed.startsWith("\"") && trimmed.endsWith("\"") || trimmed.startsWith("'") && trimmed.endsWith("'")) return [trimmed.slice(1, -1)];
|
|
@@ -723,6 +774,11 @@ Rules:
|
|
|
723
774
|
if (!apiKey) throw new Error("ANTHROPIC_API_KEY not found. Set it in environment variables or Sonamu.secret.anthropic_api_key");
|
|
724
775
|
return apiKey;
|
|
725
776
|
}
|
|
777
|
+
hasSequenceDefault(prop) {
|
|
778
|
+
if (!("dbDefault" in prop)) return false;
|
|
779
|
+
const dbDefault = z.string().safeParse(prop.dbDefault);
|
|
780
|
+
return dbDefault.success && dbDefault.data.includes("nextval");
|
|
781
|
+
}
|
|
726
782
|
getExpectedFormat(propType) {
|
|
727
783
|
if (propType.endsWith("[]")) {
|
|
728
784
|
const baseType = propType.slice(0, -2);
|
|
@@ -918,7 +974,7 @@ Rules:
|
|
|
918
974
|
const parentOverrides = specEntity.props.find((p) => p.name === "id")?.cone?.fixtureParentOverrides ?? {};
|
|
919
975
|
const parentEntity = this.entityManager.get(specEntity.parentId);
|
|
920
976
|
let query = this.sourceDb(parentEntity.table).select(`${parentEntity.table}.id`);
|
|
921
|
-
for (const [col, val] of Object.entries(parentOverrides)) query = query.where(`${parentEntity.table}.${col}`, val);
|
|
977
|
+
for (const [col, val] of Object.entries(parentOverrides)) query = query.where(`${parentEntity.table}.${col}`, fixtureWhereValueSchema.parse(val));
|
|
922
978
|
query = query.leftJoin(specEntity.table, `${specEntity.table}.id`, `${parentEntity.table}.id`).whereNull(`${specEntity.table}.id`).limit(spec.count);
|
|
923
979
|
const availableIds = (await query).map((r) => r.id);
|
|
924
980
|
if (availableIds.length === 0) !isTest() && console.warn(chalk.yellow(`[parentId] ${spec.entity}: 서브타입이 없는 부모 레코드가 부족합니다. 건너뜁니다.`));
|
|
@@ -943,11 +999,11 @@ Rules:
|
|
|
943
999
|
for (const { entity: entityName, data, explicitId } of generatedFixtures) {
|
|
944
1000
|
const entity = this.entityManager.get(entityName);
|
|
945
1001
|
const idProp = entity.props.find((p) => p.name === "id");
|
|
946
|
-
const dataForRecord = !explicitId && (idProp?.type === "integer" || idProp?.type === "bigInteger" || idProp?.type === "string" &&
|
|
1002
|
+
const dataForRecord = !explicitId && (idProp?.type === "integer" || idProp?.type === "bigInteger" || idProp?.type === "string" && this.hasSequenceDefault(idProp)) ? {
|
|
947
1003
|
...data,
|
|
948
1004
|
id: Math.floor(Math.random() * 1e6)
|
|
949
1005
|
} : data;
|
|
950
|
-
const records = await FixtureManager.createFixtureRecord(entity, dataForRecord, { singleRecord: true });
|
|
1006
|
+
const records = await FixtureManager.createFixtureRecord(entity, parseFixtureSourceRecord(dataForRecord), { singleRecord: true });
|
|
951
1007
|
fixtureRecords.push(...records);
|
|
952
1008
|
}
|
|
953
1009
|
const results = await FixtureManager.insertFixtures(this.targetDbName, fixtureRecords);
|
|
@@ -981,12 +1037,12 @@ Rules:
|
|
|
981
1037
|
}
|
|
982
1038
|
const fkColName = `${fkProp.name}_id`;
|
|
983
1039
|
const companionIdProp = companionEntity.props.find((p) => p.name === "id");
|
|
984
|
-
const usesSequence = companionIdProp?.type === "integer" || companionIdProp?.type === "bigInteger" || companionIdProp?.type === "string" &&
|
|
1040
|
+
const usesSequence = companionIdProp?.type === "integer" || companionIdProp?.type === "bigInteger" || companionIdProp?.type === "string" && this.hasSequenceDefault(companionIdProp);
|
|
985
1041
|
const companionCount = companion.count ?? 1;
|
|
986
1042
|
const context = this.createContext();
|
|
987
1043
|
const companionFixtureRecords = [];
|
|
988
1044
|
for (const parentResult of entityResults) {
|
|
989
|
-
const resolvedOverrides = this.resolveTemplateOverrides(companion.overrides ?? {}, parentResult.data);
|
|
1045
|
+
const resolvedOverrides = this.resolveTemplateOverrides(dataExplorerRecordSchema.parse(companion.overrides ?? {}), parentResult.data);
|
|
990
1046
|
resolvedOverrides[fkColName] = parentResult.data.id;
|
|
991
1047
|
for (let i = 0; i < companionCount; i++) {
|
|
992
1048
|
const fixture = await this.generate(companion.entity, resolvedOverrides, context);
|
|
@@ -994,7 +1050,7 @@ Rules:
|
|
|
994
1050
|
...fixture,
|
|
995
1051
|
id: Math.floor(Math.random() * 1e6)
|
|
996
1052
|
} : fixture;
|
|
997
|
-
const records = await FixtureManager.createFixtureRecord(companionEntity, dataForRecord, { singleRecord: true });
|
|
1053
|
+
const records = await FixtureManager.createFixtureRecord(companionEntity, parseFixtureSourceRecord(dataForRecord), { singleRecord: true });
|
|
998
1054
|
companionFixtureRecords.push(...records);
|
|
999
1055
|
}
|
|
1000
1056
|
}
|
|
@@ -1012,11 +1068,14 @@ Rules:
|
|
|
1012
1068
|
*/
|
|
1013
1069
|
resolveTemplateOverrides(overrides, parentData) {
|
|
1014
1070
|
const resolved = {};
|
|
1015
|
-
for (const [key, value] of Object.entries(overrides))
|
|
1016
|
-
const
|
|
1017
|
-
if (
|
|
1018
|
-
|
|
1019
|
-
|
|
1071
|
+
for (const [key, value] of Object.entries(overrides)) {
|
|
1072
|
+
const template = z.string().safeParse(value);
|
|
1073
|
+
if (template.success && template.data.startsWith("{{") && template.data.endsWith("}}")) {
|
|
1074
|
+
const fieldName = template.data.slice(2, -2).trim();
|
|
1075
|
+
if (!(fieldName in parentData)) throw new Error(`템플릿 필드 "${fieldName}"이(가) 부모 fixture 데이터에 존재하지 않습니다 (override key: "${key}")`);
|
|
1076
|
+
resolved[key] = parentData[fieldName];
|
|
1077
|
+
} else resolved[key] = value;
|
|
1078
|
+
}
|
|
1020
1079
|
return resolved;
|
|
1021
1080
|
}
|
|
1022
1081
|
/**
|
|
@@ -1051,8 +1110,8 @@ Rules:
|
|
|
1051
1110
|
const fixtureRecords = [];
|
|
1052
1111
|
const mainEntity = this.entityManager.get(entityName);
|
|
1053
1112
|
for (const record of exploreResult.main.records) {
|
|
1054
|
-
const records = await FixtureManager.createFixtureRecord(mainEntity, record, {
|
|
1055
|
-
|
|
1113
|
+
const records = await FixtureManager.createFixtureRecord(mainEntity, parseFixtureSourceRecord(record), {
|
|
1114
|
+
db: this.sourceDb,
|
|
1056
1115
|
singleRecord: true
|
|
1057
1116
|
});
|
|
1058
1117
|
fixtureRecords.push(...records);
|
|
@@ -1060,8 +1119,8 @@ Rules:
|
|
|
1060
1119
|
for (const [relatedEntityName, relatedRecords] of exploreResult.related.entries()) {
|
|
1061
1120
|
const relatedEntity = this.entityManager.get(relatedEntityName);
|
|
1062
1121
|
for (const record of relatedRecords) {
|
|
1063
|
-
const records = await FixtureManager.createFixtureRecord(relatedEntity, record, {
|
|
1064
|
-
|
|
1122
|
+
const records = await FixtureManager.createFixtureRecord(relatedEntity, parseFixtureSourceRecord(record), {
|
|
1123
|
+
db: this.sourceDb,
|
|
1065
1124
|
singleRecord: true
|
|
1066
1125
|
});
|
|
1067
1126
|
fixtureRecords.push(...records);
|
|
@@ -1078,4 +1137,4 @@ Rules:
|
|
|
1078
1137
|
init_fixture_generator();
|
|
1079
1138
|
export { FixtureGenerator, init_fixture_generator };
|
|
1080
1139
|
|
|
1081
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZS1nZW5lcmF0b3IuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3RpbmcvZml4dHVyZS1nZW5lcmF0b3IudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNoYWxrIGZyb20gXCJjaGFsa1wiO1xuaW1wb3J0IHsgdHlwZSBLbmV4IH0gZnJvbSBcImtuZXhcIjtcblxuaW1wb3J0IHsgdHlwZSBTb25hbXVEQlByZXNldCB9IGZyb20gXCIuLi9kYXRhYmFzZS9kYlwiO1xuaW1wb3J0IHsgdHlwZSBFbnRpdHkgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eVwiO1xuaW1wb3J0IHsgdHlwZSBFbnRpdHlNYW5hZ2VyIH0gZnJvbSBcIi4uL2VudGl0eS9lbnRpdHktbWFuYWdlclwiO1xuaW1wb3J0IHsgdHlwZSBFbnRpdHlQcm9wLCB0eXBlIEZpeHR1cmVJbXBvcnRSZXN1bHQsIHR5cGUgRml4dHVyZVJlY29yZCB9IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AsIGlzT25lVG9PbmVSZWxhdGlvblByb3AsIGlzUmVsYXRpb25Qcm9wIH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgeyBpc1Rlc3QgfSBmcm9tIFwiLi4vdXRpbHMvY29udHJvbGxlclwiO1xuaW1wb3J0IHsgRGF0YUV4cGxvcmVyIH0gZnJvbSBcIi4vZGF0YS1leHBsb3JlclwiO1xuaW1wb3J0IHsgdHlwZSBFeHBsb3JlV2l0aFJlbGF0aW9uc09wdGlvbnMsIHR5cGUgRXhwbG9yZVdpdGhSZWxhdGlvbnNSZXN1bHQgfSBmcm9tIFwiLi9kYXRhLWV4cGxvcmVyXCI7XG5pbXBvcnQgeyBmYWtlck1hcHBpbmdzIH0gZnJvbSBcIi4vZmFrZXItbWFwcGluZ3NcIjtcbmltcG9ydCB7IHR5cGUgRmFrZXJNYXBwaW5ncyB9IGZyb20gXCIuL2Zha2VyLW1hcHBpbmdzXCI7XG5pbXBvcnQgeyBGaXh0dXJlTWFuYWdlciB9IGZyb20gXCIuL2ZpeHR1cmUtbWFuYWdlclwiO1xuXG5leHBvcnQgdHlwZSBMb2NhbGUgPSBcImtvXCIgfCBcImVuXCIgfCBcImphXCI7XG5cbmV4cG9ydCB0eXBlIEZpeHR1cmVHZW5lcmF0b3JPcHRpb25zID0ge1xuICBsb2NhbGU/OiBMb2NhbGU7XG4gIHVzZUxMTT86IGJvb2xlYW47XG4gIGVuYWJsZUxMTUNhY2hlPzogYm9vbGVhbjtcbiAgbGxtTW9kZWw/OiBzdHJpbmc7XG59O1xuXG5leHBvcnQgdHlwZSBHZW5lcmF0b3JDb250ZXh0ID0ge1xuICAvKiog7IOd7ISxIOykkeyduCBmaXh0dXJl65OkICjrqZTrqqjrpqwg7IOBKSAqL1xuICBmaXh0dXJlczogTWFwPHN0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuXG4gIC8qKiDssLjsobAg642w7J207YSwIOy6kOyLnCAoRGF0YUV4cGxvcmVyIOqysOqzvCkgKi9cbiAgcmVmZXJlbmNlQ2FjaGU6IE1hcDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIHVua25vd24+W10+O1xuXG4gIC8qKiDsnbTrr7ggaW1wb3J065CcIOugiOy9lOuTnOulvCDstpTsoIHtlZjsl6wg7KSR67O1IGltcG9ydOulvCDrsKnsp4Dtlanri4jri6QgKi9cbiAgaW1wb3J0ZWRSZWNvcmRzOiBTZXQ8c3RyaW5nPjsgLy8gXCJVc2VyIzEyM1wiXG59O1xuXG5leHBvcnQgY2xhc3MgRml4dHVyZUdlbmVyYXRvciB7XG4gIHByaXZhdGUgZGF0YUV4cGxvcmVyOiBEYXRhRXhwbG9yZXI7XG4gIHByaXZhdGUgbG9jYWxlOiBMb2NhbGU7XG4gIHByaXZhdGUgbWFwcGluZ3M6IEZha2VyTWFwcGluZ3M7XG4gIHByaXZhdGUgbGxtQ2FjaGU6IE1hcDxzdHJpbmcsIHVua25vd24+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIGVudGl0eUNhY2hlOiBNYXA8c3RyaW5nLCBFbnRpdHk+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIG9wdGlvbnM6IEZpeHR1cmVHZW5lcmF0b3JPcHRpb25zO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgc291cmNlRGI6IEtuZXgsXG4gICAgLy8gRml4dHVyZU1hbmFnZXIuaW5zZXJ0Rml4dHVyZXPqsIAgZGJOYW1lIOusuOyekOyXtOydhCDrsJvquLAg65WM66y47JeQIOyngeygkSDsgqzsmqntlZjsp4Ag7JWK7Iq164uI64ukXG4gICAgLy8g66+4656YIO2ZleyepeyEseydhCDsnITtlbQgQVBJIOyLnOq3uOuLiOyymOyXkOuKlCDtj6ztlajsi5zsvLDsirXri4jri6RcbiAgICBfdGFyZ2V0RGI6IEtuZXgsXG4gICAgcHJpdmF0ZSB0YXJnZXREYk5hbWU6IFNvbmFtdURCUHJlc2V0LFxuICAgIHByaXZhdGUgZW50aXR5TWFuYWdlcjogdHlwZW9mIEVudGl0eU1hbmFnZXIsXG4gICAgb3B0aW9ucz86IEZpeHR1cmVHZW5lcmF0b3JPcHRpb25zLFxuICApIHtcbiAgICB0aGlzLmRhdGFFeHBsb3JlciA9IG5ldyBEYXRhRXhwbG9yZXIoc291cmNlRGIsIGVudGl0eU1hbmFnZXIpO1xuICAgIHRoaXMubG9jYWxlID0gb3B0aW9ucz8ubG9jYWxlIHx8IFwia29cIjtcbiAgICB0aGlzLm1hcHBpbmdzID0gZmFrZXJNYXBwaW5ncztcbiAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICBsb2NhbGU6IG9wdGlvbnM/LmxvY2FsZSB8fCBcImtvXCIsXG4gICAgICB1c2VMTE06IG9wdGlvbnM/LnVzZUxMTSB8fCBmYWxzZSxcbiAgICAgIGVuYWJsZUxMTUNhY2hlOiBvcHRpb25zPy5lbmFibGVMTE1DYWNoZSAhPT0gZmFsc2UsXG4gICAgICBsbG1Nb2RlbDogb3B0aW9ucz8ubGxtTW9kZWwgfHwgXCJjbGF1ZGUtc29ubmV0LTQtNlwiLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogRml4dHVyZSDsg53shLEgKOuLqOydvClcbiAgICogQHJldHVybnMg7IOd7ISx65CcIGZpeHR1cmUg642w7J207YSwICjrqZTrqqjrpqwg7IOBKVxuICAgKi9cbiAgYXN5bmMgZ2VuZXJhdGUoXG4gICAgZW50aXR5TmFtZTogc3RyaW5nLFxuICAgIG92ZXJyaWRlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fSxcbiAgICBjb250ZXh0OiBHZW5lcmF0b3JDb250ZXh0ID0gdGhpcy5jcmVhdGVDb250ZXh0KCksXG4gICk6IFByb21pc2U8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+IHtcbiAgICAvLyBFbnRpdHkg7LqQ7IuxOiDthYzsiqTtirjsl5DshJwgZW50aXR5IGNvbmUg7IiY7KCV7J20IOuwmOyYgeuQmOuPhOuhnSDrs7TsnqVcbiAgICBsZXQgZW50aXR5ID0gdGhpcy5lbnRpdHlDYWNoZS5nZXQoZW50aXR5TmFtZSk7XG4gICAgaWYgKCFlbnRpdHkpIHtcbiAgICAgIGVudGl0eSA9IHRoaXMuZW50aXR5TWFuYWdlci5nZXQoZW50aXR5TmFtZSk7XG4gICAgICB0aGlzLmVudGl0eUNhY2hlLnNldChlbnRpdHlOYW1lLCBlbnRpdHkpO1xuICAgIH1cblxuICAgIGNvbnN0IHRlbXBJZCA9IGAke2VudGl0eU5hbWV9I3RlbXAjJHtEYXRlLm5vdygpfWA7IC8vIOyehOyLnCBJRFxuXG4gICAgLy8gTExNIHJvdyDri6jsnIQg7IOd7ISx7J2EIOychO2VnCDqs6DsnKAg7YKkICjqsJnsnYAgcm937J2YIO2VhOuTnOuTpOydtCDrj5nsnbztlZwgcm93S2V566W8IOqzteycoClcbiAgICBjb25zdCByb3dLZXkgPSB0aGlzLm9wdGlvbnMudXNlTExNID8gYCR7ZW50aXR5TmFtZX0jcm93IyR7RGF0ZS5ub3coKX1gIDogdW5kZWZpbmVkO1xuXG4gICAgLy8g6rCBIHByb3Drs4Qg6rCSIOyDneyEsVxuICAgIGNvbnN0IGZpeHR1cmU6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG5cbiAgICBmb3IgKGNvbnN0IHByb3Agb2YgZW50aXR5LnByb3BzKSB7XG4gICAgICAvLyBWaXJ0dWFsIHByb3DsnYAg7Iqk7YK1XG4gICAgICBpZiAoXCJ2aXJ0dWFsXCIgaW4gcHJvcCAmJiBwcm9wLnZpcnR1YWwpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIGlkIHByb3Ag7LKY66asXG4gICAgICBpZiAocHJvcC5uYW1lID09PSBcImlkXCIpIHtcbiAgICAgICAgLy8gREIgc2VxdWVuY2XqsIAg7J6Q64+ZIO2VoOuLuTogaW50ZWdlci9iaWdJbnRlZ2Vy7J206rGw64KYLCBzdHJpbmfsnbTsp4Drp4wgZGJEZWZhdWx07JeQIG5leHR2YWzsnbQg7J6I64qUIOqyveyasFxuICAgICAgICBjb25zdCBoYXNEYlNlcXVlbmNlID1cbiAgICAgICAgICBwcm9wLnR5cGUgPT09IFwiaW50ZWdlclwiIHx8XG4gICAgICAgICAgcHJvcC50eXBlID09PSBcImJpZ0ludGVnZXJcIiB8fFxuICAgICAgICAgIChwcm9wLnR5cGUgPT09IFwic3RyaW5nXCIgJiZcbiAgICAgICAgICAgIFwiZGJEZWZhdWx0XCIgaW4gcHJvcCAmJlxuICAgICAgICAgICAgdHlwZW9mIHByb3AuZGJEZWZhdWx0ID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgICBwcm9wLmRiRGVmYXVsdC5pbmNsdWRlcyhcIm5leHR2YWxcIikpO1xuICAgICAgICBpZiAoaGFzRGJTZXF1ZW5jZSkge1xuICAgICAgICAgIC8vIGdlbmVyYXRlQmF0Y2jsl5DshJwg7LKY66as7ZWY66+A66GcIOyXrOq4sOyEoCDsiqTtgrVcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcC50eXBlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgLy8gc3RyaW5nIFBLOiBhbHBoYW51bWVyaWMgMzLsnpAg7IOd7ISxIChiZXR0ZXItYXV0aCDsiqTtg4DsnbwpXG4gICAgICAgICAgY29uc3QgeyBmYWtlcjogX2Zha2VyIH0gPSBhd2FpdCBpbXBvcnQoXCJAZmFrZXItanMvZmFrZXJcIik7XG4gICAgICAgICAgZml4dHVyZVtwcm9wLm5hbWVdID0gX2Zha2VyLnN0cmluZy5hbHBoYW51bWVyaWMoMzIpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wLnR5cGUgPT09IFwidXVpZFwiKSB7XG4gICAgICAgICAgY29uc3QgeyBmYWtlcjogX2Zha2VyIH0gPSBhd2FpdCBpbXBvcnQoXCJAZmFrZXItanMvZmFrZXJcIik7XG4gICAgICAgICAgZml4dHVyZVtwcm9wLm5hbWVdID0gX2Zha2VyLnN0cmluZy51dWlkKCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIG92ZXJyaWRl6rCAIOyeiOycvOuptCDsgqzsmqlcbiAgICAgIGlmIChwcm9wLm5hbWUgaW4gb3ZlcnJpZGVzKSB7XG4gICAgICAgIGZpeHR1cmVbcHJvcC5uYW1lXSA9IG92ZXJyaWRlc1twcm9wLm5hbWVdO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gY29uZeyXkOyEnCDsg53shLEg7KCE6561IO2ZleyduFxuICAgICAgY29uc3QgY29uZSA9IHByb3AuY29uZTtcblxuICAgICAgLy8gMS4gUmVsYXRpb24gcHJvcCDsspjrpqxcbiAgICAgIGlmIChpc1JlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICAvLyBCZWxvbmdzVG9PbmUgLyBPbmVUb09uZShoYXNKb2luQ29sdW1uKeydgCBGSyDsu6zrn7zrqoUoe3Byb3AubmFtZX1faWQp7Jy866Gc64+EIG92ZXJyaWRl66W8IOuwm+uKlOuLpFxuICAgICAgICBjb25zdCBma0NvbE5hbWUgPSBgJHtwcm9wLm5hbWV9X2lkYDtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGZrQ29sTmFtZSBpbiBvdmVycmlkZXMgJiZcbiAgICAgICAgICAoaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocHJvcCkgfHwgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocHJvcCkgJiYgcHJvcC5oYXNKb2luQ29sdW1uKSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgZml4dHVyZVtma0NvbE5hbWVdID0gb3ZlcnJpZGVzW2ZrQ29sTmFtZV07XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZWxhdGlvblZhbHVlID0gYXdhaXQgdGhpcy5nZW5lcmF0ZVJlbGF0aW9uVmFsdWUoZW50aXR5LCBwcm9wLCBjb250ZXh0KTtcbiAgICAgICAgLy8gQmVsb25nc1RvT25lLCBPbmVUb09uZShoYXNKb2luQ29sdW1uKeydmCDqsr3smrAgZm9yZWlnbiBrZXkg7Lus65+866qF7Jy866GcIOyggOyepVxuICAgICAgICBpZiAoXG4gICAgICAgICAgaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocHJvcCkgfHxcbiAgICAgICAgICAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChwcm9wKSAmJiBwcm9wLmhhc0pvaW5Db2x1bW4pXG4gICAgICAgICkge1xuICAgICAgICAgIGZpeHR1cmVbYCR7cHJvcC5uYW1lfV9pZGBdID0gcmVsYXRpb25WYWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmaXh0dXJlW3Byb3AubmFtZV0gPSByZWxhdGlvblZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyAyLiBjb25lLm5vdGUgKyBMTE0g7IKs7JqpICh1c2VMTE3snbTrqbQgZml4dHVyZUdlbmVyYXRvcuuztOuLpCDsmrDshKApXG4gICAgICBpZiAoY29uZT8ubm90ZSAmJiB0aGlzLm9wdGlvbnMudXNlTExNKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgbGxtVmFsdWUgPSBhd2FpdCB0aGlzLmdlbmVyYXRlV2l0aExMTShjb25lLm5vdGUsIHByb3AsIGVudGl0eSwgcm93S2V5KTtcbiAgICAgICAgICAvLyBzdHJpbmcg7YOA7J6F7J206rOgIGxlbmd0aCDsoJzslb3snbQg7J6I7Jy866m0IOy0iOqzvCDsi5wgdHJ1bmNhdGlvblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHR5cGVvZiBsbG1WYWx1ZSA9PT0gXCJzdHJpbmdcIiAmJlxuICAgICAgICAgICAgXCJsZW5ndGhcIiBpbiBwcm9wICYmXG4gICAgICAgICAgICB0eXBlb2YgcHJvcC5sZW5ndGggPT09IFwibnVtYmVyXCIgJiZcbiAgICAgICAgICAgIGxsbVZhbHVlLmxlbmd0aCA+IHByb3AubGVuZ3RoXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBmaXh0dXJlW3Byb3AubmFtZV0gPSBsbG1WYWx1ZS5zbGljZSgwLCBwcm9wLmxlbmd0aCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZpeHR1cmVbcHJvcC5uYW1lXSA9IGxsbVZhbHVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICBgW0ZpeHR1cmVHZW5lcmF0b3JdIExMTSBnZW5lcmF0aW9uIGZhaWxlZCBmb3IgJHtlbnRpdHkuaWR9LiR7cHJvcC5uYW1lfSwgZmFsbGluZyBiYWNrIHRvIGZpeHR1cmVHZW5lcmF0b3Igb3IgZGVmYXVsdGAsXG4gICAgICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IGVycm9yLFxuICAgICAgICAgICk7XG4gICAgICAgICAgLy8gZmFsbGJhY2s6IGZpeHR1cmVHZW5lcmF0b3Ig4oaSIGZpeHR1cmVEZWZhdWx0IOKGkiDquLDrs7jqsJLsnLzroZwg6rOE7IaNXG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gMy4gZml4dHVyZUdlbmVyYXRvciDsgqzsmqlcbiAgICAgIGlmIChjb25lPy5maXh0dXJlR2VuZXJhdG9yKSB7XG4gICAgICAgIGZpeHR1cmVbcHJvcC5uYW1lXSA9IGF3YWl0IHRoaXMuZXhlY3V0ZUdlbmVyYXRvcihjb25lLmZpeHR1cmVHZW5lcmF0b3IsIHByb3AsIGVudGl0eSk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyA0LiBmaXh0dXJlRGVmYXVsdCDsgqzsmqlcbiAgICAgIGlmIChjb25lPy5maXh0dXJlRGVmYXVsdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGZpeHR1cmVbcHJvcC5uYW1lXSA9IGNvbmUuZml4dHVyZURlZmF1bHQ7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyA1LiDtg4DsnoXrs4Qg6riw67O4IOyDneyEsVxuICAgICAgZml4dHVyZVtwcm9wLm5hbWVdID0gYXdhaXQgdGhpcy5nZW5lcmF0ZURlZmF1bHRWYWx1ZShwcm9wLCBlbnRpdHkpO1xuICAgIH1cblxuICAgIC8vIDYuIGVtYWlsIO2VhOuTnOqwgCDsnojqs6AgbmFtZSDtlYTrk5zqsIAg7J6I7Jy866m0LCBlbWFpbOydmCDroZzsu6wg7YyM7Yq466W8IG5hbWUg6riw67CY7Jy866GcIOuztOyglVxuICAgIGlmIChcImVtYWlsXCIgaW4gZml4dHVyZSAmJiB0eXBlb2YgZml4dHVyZS5lbWFpbCA9PT0gXCJzdHJpbmdcIiAmJiAhKFwiZW1haWxcIiBpbiBvdmVycmlkZXMpKSB7XG4gICAgICBjb25zdCBuYW1lVmFsdWUgPSBmaXh0dXJlLm5hbWUgfHwgZml4dHVyZS51c2VybmFtZSB8fCBmaXh0dXJlLmZ1bGxfbmFtZSB8fCBmaXh0dXJlLm5hbWVfZW47XG4gICAgICBpZiAobmFtZVZhbHVlICYmIHR5cGVvZiBuYW1lVmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgY29uc3QgZG9tYWluID0gZml4dHVyZS5lbWFpbC5zcGxpdChcIkBcIilbMV0gfHwgXCJleGFtcGxlLmNvbVwiO1xuICAgICAgICBjb25zdCByb21hbml6ZWQgPSBhd2FpdCB0aGlzLnJvbWFuaXplTmFtZShuYW1lVmFsdWUpO1xuICAgICAgICBmaXh0dXJlLmVtYWlsID0gYCR7cm9tYW5pemVkfUAke2RvbWFpbn1gO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIDcuIHBhc3N3b3JkIO2VhOuTnCDslZTtmLjtmZRcbiAgICBpZiAoXCJwYXNzd29yZFwiIGluIGZpeHR1cmUgJiYgZml4dHVyZS5wYXNzd29yZCAmJiB0eXBlb2YgZml4dHVyZS5wYXNzd29yZCA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgY29uc3QgYmNyeXB0ID0gYXdhaXQgaW1wb3J0KFwiYmNyeXB0XCIpO1xuICAgICAgZml4dHVyZS5wYXNzd29yZCA9IGF3YWl0IGJjcnlwdC5oYXNoKGZpeHR1cmUucGFzc3dvcmQsIDEwKTtcbiAgICB9XG5cbiAgICBjb250ZXh0LmZpeHR1cmVzLnNldCh0ZW1wSWQsIGZpeHR1cmUpO1xuICAgIHJldHVybiBmaXh0dXJlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGF0aW9uIOqwkiDsg53shLEgKyDsnpDrj5kgSW1wb3J0XG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdlbmVyYXRlUmVsYXRpb25WYWx1ZShcbiAgICBlbnRpdHk6IEVudGl0eSxcbiAgICBwcm9wOiBFbnRpdHlQcm9wLFxuICAgIGNvbnRleHQ6IEdlbmVyYXRvckNvbnRleHQsXG4gICk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD4ge1xuICAgIGlmICghaXNSZWxhdGlvblByb3AocHJvcCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRml4dHVyZUdlbmVyYXRvcjogJHtlbnRpdHkuaWR9LiR7cHJvcC5uYW1lfSBpcyBub3QgYSByZWxhdGlvbiBwcm9wYCk7XG4gICAgfVxuXG4gICAgLy8gQmVsb25nc1RvT25lLCBPbmVUb09uZShoYXNKb2luQ29sdW1uKeunjCDsspjrpqxcbiAgICBpZiAoXG4gICAgICAhaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocHJvcCkgJiZcbiAgICAgICEoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChwcm9wKSAmJiBwcm9wLmhhc0pvaW5Db2x1bW4pXG4gICAgKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBjb25lID0gcHJvcC5jb25lO1xuICAgIGNvbnN0IGRhdGFTb3VyY2UgPSBjb25lPy5kYXRhU291cmNlO1xuXG4gICAgLy8gRGF0YUV4cGxvcmVy66GcIOywuOyhsCDrjbDsnbTthLAg7KGw7ZqMIChzb3VyY2VEYilcbiAgICAvLyDqtIDqs4Qg7LK07J247J2EIOuUsOudvOqwgOq4sCDsnITtlbQgZXhwbG9yZVdpdGhSZWxhdGlvbnMg7IKs7JqpXG4gICAgaWYgKGRhdGFTb3VyY2UpIHtcbiAgICAgIGNvbnN0IGNhY2hlS2V5ID0gYCR7cHJvcC53aXRofToke0pTT04uc3RyaW5naWZ5KGRhdGFTb3VyY2UpfWA7XG5cbiAgICAgIGlmICghY29udGV4dC5yZWZlcmVuY2VDYWNoZS5oYXMoY2FjaGVLZXkpKSB7XG4gICAgICAgIGNvbnN0IGV4cGxvcmVSZXN1bHQgPSBhd2FpdCB0aGlzLmRhdGFFeHBsb3Jlci5leHBsb3JlV2l0aFJlbGF0aW9ucyhwcm9wLndpdGgsIHtcbiAgICAgICAgICBzdHJhdGVneTogZGF0YVNvdXJjZS5zdHJhdGVneSxcbiAgICAgICAgICBsaW1pdDpcbiAgICAgICAgICAgICgoZGF0YVNvdXJjZS5jb25maWcgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQpPy5saW1pdCBhc1xuICAgICAgICAgICAgICB8IG51bWJlclxuICAgICAgICAgICAgICB8IHVuZGVmaW5lZCkgfHwgMTAsXG4gICAgICAgICAgaW5jbHVkZVJlbGF0aW9uczogdHJ1ZSxcbiAgICAgICAgICBtYXhEZXB0aDogMyxcbiAgICAgICAgICAuLi4oZGF0YVNvdXJjZS5jb25maWcgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCB1bmRlZmluZWQpLFxuICAgICAgICB9KTtcbiAgICAgICAgY29udGV4dC5yZWZlcmVuY2VDYWNoZS5zZXQoY2FjaGVLZXksIGV4cGxvcmVSZXN1bHQubWFpbi5yZWNvcmRzKTtcblxuICAgICAgICAvLyDsobDtmoztlZwg642w7J207YSw7JmAIOq0gOqzhOuQnCDrqqjrk6Ag7JeU7Yuw7Yuw66W8IHRhcmdldERi7JeQIGltcG9ydFxuICAgICAgICBhd2FpdCB0aGlzLmltcG9ydEV4cGxvcmVSZXN1bHQoZXhwbG9yZVJlc3VsdCwgY29udGV4dCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNhbmRpZGF0ZXMgPSBjb250ZXh0LnJlZmVyZW5jZUNhY2hlLmdldChjYWNoZUtleSk7XG4gICAgICBpZiAoY2FuZGlkYXRlcyAmJiBjYW5kaWRhdGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8g656c642k7ZWY6rKMIO2VmOuCmCDshKDtg51cbiAgICAgICAgY29uc3Qgc2VsZWN0ZWQgPSBjYW5kaWRhdGVzW01hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGNhbmRpZGF0ZXMubGVuZ3RoKV07XG4gICAgICAgIHJldHVybiBzZWxlY3RlZC5pZCBhcyBudW1iZXI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZGF0YVNvdXJjZeqwgCDsl4bsnYQg65WMIOyekOuPmeycvOuhnCBmaXh0dXJlIERC7JeQ7IScIOyhsO2ajCDsi5zrj4RcbiAgICAvLyDqtIDqs4Qg7LK07J247J2EIOuUsOudvOqwgOq4sCDsnITtlbQgZXhwbG9yZVdpdGhSZWxhdGlvbnMg7IKs7JqpXG4gICAgY29uc3QgYXV0b0tleSA9IGAke3Byb3Aud2l0aH06YXV0b2A7XG4gICAgaWYgKCFjb250ZXh0LnJlZmVyZW5jZUNhY2hlLmhhcyhhdXRvS2V5KSkge1xuICAgICAgLy8gZml4dHVyZSBEQihzb3VyY2VEYinsl5DshJwg7J6Q64+ZIOyhsO2ajCAo6rSA6rOEIO2PrO2VqClcbiAgICAgIGNvbnN0IGF1dG9FeHBsb3JlUmVzdWx0ID0gYXdhaXQgdGhpcy5kYXRhRXhwbG9yZXIuZXhwbG9yZVdpdGhSZWxhdGlvbnMocHJvcC53aXRoLCB7XG4gICAgICAgIHN0cmF0ZWd5OiBcInJhbmRvbVwiLFxuICAgICAgICBsaW1pdDogMTAsXG4gICAgICAgIGluY2x1ZGVSZWxhdGlvbnM6IHRydWUsXG4gICAgICAgIG1heERlcHRoOiAzLFxuICAgICAgfSk7XG4gICAgICBjb250ZXh0LnJlZmVyZW5jZUNhY2hlLnNldChhdXRvS2V5LCBhdXRvRXhwbG9yZVJlc3VsdC5tYWluLnJlY29yZHMpO1xuXG4gICAgICAvLyDsobDtmoztlZwg642w7J207YSw7JmAIOq0gOqzhOuQnCDrqqjrk6Ag7JeU7Yuw7Yuw66W8IHRhcmdldERi7JeQIGltcG9ydFxuICAgICAgaWYgKGF1dG9FeHBsb3JlUmVzdWx0Lm1haW4ucmVjb3Jkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW1wb3J0RXhwbG9yZVJlc3VsdChhdXRvRXhwbG9yZVJlc3VsdCwgY29udGV4dCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgYXV0b0NhbmRpZGF0ZXMgPSBjb250ZXh0LnJlZmVyZW5jZUNhY2hlLmdldChhdXRvS2V5KTtcbiAgICBpZiAoYXV0b0NhbmRpZGF0ZXMgJiYgYXV0b0NhbmRpZGF0ZXMubGVuZ3RoID4gMCkge1xuICAgICAgLy8g656c642k7ZWY6rKMIO2VmOuCmCDshKDtg51cbiAgICAgIGNvbnN0IHNlbGVjdGVkID0gYXV0b0NhbmRpZGF0ZXNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogYXV0b0NhbmRpZGF0ZXMubGVuZ3RoKV07XG4gICAgICByZXR1cm4gc2VsZWN0ZWQuaWQgYXMgbnVtYmVyO1xuICAgIH1cblxuICAgIC8vIOywuOyhsCDrjbDsnbTthLDqsIAg7JeG7Jy866m0IG51bGwg67CY7ZmYIChudWxsYWJsZeyduCDqsr3smrApXG4gICAgaWYgKHByb3AubnVsbGFibGUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIG51bGxhYmxl7J20IOyVhOuLiOqzoCDrjbDsnbTthLDrj4Qg7JeG7Jy866m0IOyXkOufrFxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBGaXh0dXJlR2VuZXJhdG9yOiAke2VudGl0eS5pZH0uJHtwcm9wLm5hbWV97JeQIO2VhOyalO2VnCAke3Byb3Aud2l0aH0g642w7J207YSw6rCAIOyXhuyKteuLiOuLpC4gYCArXG4gICAgICAgIGDrqLzsoIAgJHtwcm9wLndpdGh966W8IOyDneyEse2VmOqxsOuCmCBjb25lLmRhdGFTb3VyY2Xrpbwg7ISk7KCV7ZWY7IS47JqULmAsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBsb3JlV2l0aFJlbGF0aW9ucyDqsrDqs7zrpbwgdGFyZ2V0RGLsl5AgaW1wb3J0XG4gICAqXG4gICAqIOq0gOqzhCDssrTsnbjsnYQg65Sw65286rCEIOqysOqzvChtYWluICsgcmVsYXRlZCnrpbwg66qo65GQIGltcG9ydO2VqeuLiOuLpC5cbiAgICog7J2Y7KG07ISxIOyInOyEnOuKlCBGaXh0dXJlTWFuYWdlci5pbnNlcnRGaXh0dXJlc+qwgCDsnpDrj5nsnLzroZwg7LKY66as7ZWp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBpbXBvcnRFeHBsb3JlUmVzdWx0KFxuICAgIGV4cGxvcmVSZXN1bHQ6IEV4cGxvcmVXaXRoUmVsYXRpb25zUmVzdWx0LFxuICAgIGNvbnRleHQ6IEdlbmVyYXRvckNvbnRleHQsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGFsbEZpeHR1cmVSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gPSBbXTtcblxuICAgIC8vIDEuIFJlbGF0ZWQgZW50aXRpZXMgaW1wb3J0IChDb21wYW55LCBEZXBhcnRtZW50IOuTsSlcbiAgICBmb3IgKGNvbnN0IFtlbnRpdHlJZCwgcmVjb3Jkc10gb2YgZXhwbG9yZVJlc3VsdC5yZWxhdGVkLmVudHJpZXMoKSkge1xuICAgICAgY29uc3QgZW50aXR5ID0gdGhpcy5lbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICBjb25zdCByZWNvcmRzVG9JbXBvcnQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+W10gPSBbXTtcblxuICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgIGNoYWxrLmN5YW4oYEltcG9ydGluZyByZWxhdGVkIGVudGl0eTogJHtlbnRpdHlJZH0gKCR7cmVjb3Jkcy5sZW5ndGh9IHJlY29yZHMpYCksXG4gICAgICAgICk7XG5cbiAgICAgIGZvciAoY29uc3QgcmVjb3JkIG9mIHJlY29yZHMpIHtcbiAgICAgICAgY29uc3QgcmVjb3JkS2V5ID0gYCR7ZW50aXR5SWR9IyR7cmVjb3JkLmlkfWA7XG4gICAgICAgIGlmICghY29udGV4dC5pbXBvcnRlZFJlY29yZHMuaGFzKHJlY29yZEtleSkpIHtcbiAgICAgICAgICByZWNvcmRzVG9JbXBvcnQucHVzaChyZWNvcmQpO1xuICAgICAgICAgIGNvbnRleHQuaW1wb3J0ZWRSZWNvcmRzLmFkZChyZWNvcmRLZXkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChyZWNvcmRzVG9JbXBvcnQubGVuZ3RoID4gMCkge1xuICAgICAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiByZWNvcmRzVG9JbXBvcnQpIHtcbiAgICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICBjaGFsay5ncmF5KFxuICAgICAgICAgICAgICAgIGAgIC0gUHJvY2Vzc2luZyAke2VudGl0eUlkfSByZWNvcmQ6YCxcbiAgICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShyZWNvcmQpLnNsaWNlKDAsIDEwMCksXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICApO1xuICAgICAgICAgIGNvbnN0IGZpeHR1cmVSZWNvcmRzID0gYXdhaXQgRml4dHVyZU1hbmFnZXIuY3JlYXRlRml4dHVyZVJlY29yZChcbiAgICAgICAgICAgIGVudGl0eSxcbiAgICAgICAgICAgIHJlY29yZCBhcyB7IGlkOiBudW1iZXIgfCBzdHJpbmc7IFtrZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBudWxsIH0sXG4gICAgICAgICAgICB7IF9kYjogdGhpcy5zb3VyY2VEYiwgc2luZ2xlUmVjb3JkOiB0cnVlIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgICBhbGxGaXh0dXJlUmVjb3Jkcy5wdXNoKC4uLmZpeHR1cmVSZWNvcmRzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIDIuIE1haW4gZW50aXR5IGltcG9ydCAoRW1wbG95ZWUg65OxKVxuICAgIGNvbnN0IG1haW5FbnRpdHkgPSB0aGlzLmVudGl0eU1hbmFnZXIuZ2V0KGV4cGxvcmVSZXN1bHQubWFpbi5lbnRpdHlJZCk7XG4gICAgY29uc3QgbWFpblJlY29yZHNUb0ltcG9ydDogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSA9IFtdO1xuXG4gICAgIWlzVGVzdCgpICYmXG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgY2hhbGsuY3lhbihcbiAgICAgICAgICBgSW1wb3J0aW5nIG1haW4gZW50aXR5OiAke2V4cGxvcmVSZXN1bHQubWFpbi5lbnRpdHlJZH0gKCR7ZXhwbG9yZVJlc3VsdC5tYWluLnJlY29yZHMubGVuZ3RofSByZWNvcmRzKWAsXG4gICAgICAgICksXG4gICAgICApO1xuXG4gICAgZm9yIChjb25zdCByZWNvcmQgb2YgZXhwbG9yZVJlc3VsdC5tYWluLnJlY29yZHMpIHtcbiAgICAgIGNvbnN0IHJlY29yZEtleSA9IGAke2V4cGxvcmVSZXN1bHQubWFpbi5lbnRpdHlJZH0jJHtyZWNvcmQuaWR9YDtcbiAgICAgIGlmICghY29udGV4dC5pbXBvcnRlZFJlY29yZHMuaGFzKHJlY29yZEtleSkpIHtcbiAgICAgICAgbWFpblJlY29yZHNUb0ltcG9ydC5wdXNoKHJlY29yZCk7XG4gICAgICAgIGNvbnRleHQuaW1wb3J0ZWRSZWNvcmRzLmFkZChyZWNvcmRLZXkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtYWluUmVjb3Jkc1RvSW1wb3J0Lmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAoY29uc3QgcmVjb3JkIG9mIG1haW5SZWNvcmRzVG9JbXBvcnQpIHtcbiAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBjaGFsay5ncmF5KFxuICAgICAgICAgICAgICBgICAtIFByb2Nlc3NpbmcgJHtleHBsb3JlUmVzdWx0Lm1haW4uZW50aXR5SWR9IHJlY29yZDpgLFxuICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShyZWNvcmQpLnNsaWNlKDAsIDEwMCksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICk7XG4gICAgICAgIGNvbnN0IGZpeHR1cmVSZWNvcmRzID0gYXdhaXQgRml4dHVyZU1hbmFnZXIuY3JlYXRlRml4dHVyZVJlY29yZChcbiAgICAgICAgICBtYWluRW50aXR5LFxuICAgICAgICAgIHJlY29yZCBhcyB7IGlkOiBudW1iZXIgfCBzdHJpbmc7IFtrZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBudWxsIH0sXG4gICAgICAgICAgeyBfZGI6IHRoaXMuc291cmNlRGIsIHNpbmdsZVJlY29yZDogdHJ1ZSB9LFxuICAgICAgICApO1xuICAgICAgICBhbGxGaXh0dXJlUmVjb3Jkcy5wdXNoKC4uLmZpeHR1cmVSZWNvcmRzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAzLiDrqqjrk6AgZml4dHVyZeulvCDtlZwg67KI7JeQIOyCveyehSAo7J2Y7KG07ISxIOyInOyEnCDsnpDrj5kg7LKY66asKVxuICAgIGlmIChhbGxGaXh0dXJlUmVjb3Jkcy5sZW5ndGggPiAwKSB7XG4gICAgICBhd2FpdCBGaXh0dXJlTWFuYWdlci5pbnNlcnRGaXh0dXJlcyh0aGlzLnRhcmdldERiTmFtZSwgYWxsRml4dHVyZVJlY29yZHMpO1xuXG4gICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgY2hhbGsuZ3JlZW4oXG4gICAgICAgICAgICBgQXV0by1pbXBvcnRlZCAke2V4cGxvcmVSZXN1bHQubWFpbi5lbnRpdHlJZH0gd2l0aCByZWxhdGlvbnM6IGAgK1xuICAgICAgICAgICAgICBgJHtleHBsb3JlUmVzdWx0Lm1haW4ucmVjb3Jkcy5sZW5ndGh9IG1haW4gKyAke2V4cGxvcmVSZXN1bHQucmVsYXRlZC5zaXplfSByZWxhdGVkIGVudGl0aWVzYCxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBmaXh0dXJlR2VuZXJhdG9yIOyLpO2WiSAoRmFrZXIuanPrp4wg7KeA7JuQKVxuICAgKlxuICAgKiBmYWtlci4qIO2YleyLneydmCDtkZztmITsi53snYQg7JWI7KCE7ZWY6rKMIO2MjOyLse2VmOyXrCDsi6Ttlontlanri4jri6QuXG4gICAqIOyYiDogXCJmYWtlci5pbnRlcm5ldC5lbWFpbCgpXCIg4oaSIGZha2VyLmludGVybmV0LmVtYWlsKClcbiAgICog7JiIOiBcImZha2VyLmxvcmVtLndvcmRzKDMpXCIg4oaSIGZha2VyLmxvcmVtLndvcmRzKDMpXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVHZW5lcmF0b3IoXG4gICAgZ2VuZXJhdG9yOiBzdHJpbmcsXG4gICAgcHJvcDogRW50aXR5UHJvcCxcbiAgICBlbnRpdHk6IEVudGl0eSxcbiAgKTogUHJvbWlzZTx1bmtub3duPiB7XG4gICAgLy8gRmFrZXIuanMg7ZGc7ZiE7Iud66eMIOyngOybkFxuICAgIGlmIChnZW5lcmF0b3Iuc3RhcnRzV2l0aChcImZha2VyLlwiKSkge1xuICAgICAgLy8gdXNlcm5hbWXsnbTrgpggbmFtZSDtlYTrk5zripQg7ZWc6rWt7Ja0IGZha2VyIOyCrOyaqVxuICAgICAgY29uc3QgaXNOYW1lRmllbGQgPSBwcm9wLm5hbWUgPT09IFwidXNlcm5hbWVcIiB8fCBwcm9wLm5hbWUgPT09IFwibmFtZVwiO1xuICAgICAgY29uc3QgZmFrZXJNb2R1bGUgPSBhd2FpdCBpbXBvcnQoXCJAZmFrZXItanMvZmFrZXJcIik7XG4gICAgICBjb25zdCBmYWtlciA9IGlzTmFtZUZpZWxkID8gZmFrZXJNb2R1bGUuZmFrZXJLTyA6IGZha2VyTW9kdWxlLmZha2VyO1xuICAgICAgY29uc3QgZXhwciA9IGdlbmVyYXRvci5zbGljZSg2KTsgLy8gXCJmYWtlci5cIiDsoJzqsbBcblxuICAgICAgdHJ5IHtcbiAgICAgICAgLy8g7ZWo7IiYIOqyveuhnOyZgCDsnbjsnpAg7YyM7IuxXG4gICAgICAgIGNvbnN0IG1hdGNoID0gZXhwci5tYXRjaCgvXihbXFx3Ll0rKSg/OlxcKCguKj8pXFwpKT8kLyk7XG4gICAgICAgIGlmICghbWF0Y2gpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgRml4dHVyZUdlbmVyYXRvcjogSW52YWxpZCBmYWtlciBleHByZXNzaW9uIGZvciAke3Byb3AubmFtZX06ICR7Z2VuZXJhdG9yfWAsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IFssIHBhdGgsIGFyZ3NTdHJdID0gbWF0Y2g7XG4gICAgICAgIGNvbnN0IHBhcnRzID0gcGF0aC5zcGxpdChcIi5cIik7XG5cbiAgICAgICAgLy8gZmFrZXIg6rCd7LK07JeQ7IScIO2VqOyImCDssL7quLBcbiAgICAgICAgbGV0IGZuOiB1bmtub3duID0gZmFrZXI7XG4gICAgICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgICAgICAgIGlmICh0eXBlb2YgZm4gPT09IFwib2JqZWN0XCIgJiYgZm4gIT09IG51bGwgJiYgcGFydCBpbiBmbikge1xuICAgICAgICAgICAgZm4gPSAoZm4gYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW3BhcnRdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZpeHR1cmVHZW5lcmF0b3I6IEludmFsaWQgZmFrZXIgcGF0aCBmb3IgJHtwcm9wLm5hbWV9OiBmYWtlci4ke3BhdGh9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8g7ZWo7IiY6rCAIOyVhOuLiOuptCDsl5Drn6xcbiAgICAgICAgaWYgKHR5cGVvZiBmbiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGaXh0dXJlR2VuZXJhdG9yOiBmYWtlci4ke3BhdGh9IGlzIG5vdCBhIGZ1bmN0aW9uIChmb3IgJHtwcm9wLm5hbWV9KWApO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IGFyZ3M6IHVua25vd25bXSA9IFtdO1xuICAgICAgICBpZiAoYXJnc1N0cj8udHJpbSgpKSB7XG4gICAgICAgICAgYXJncyA9IHRoaXMucGFyc2VHZW5lcmF0b3JBcmdzKGFyZ3NTdHIsIHByb3AubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZm4oLi4uYXJncyk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGNoYWxrLnllbGxvdyhcbiAgICAgICAgICAgICAgYEZhaWxlZCB0byBleGVjdXRlIGdlbmVyYXRvciBcIiR7Z2VuZXJhdG9yfVwiIGZvciAke3Byb3AubmFtZX0sIGZhbGxpbmcgYmFjayB0byBkZWZhdWx0OmAsXG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2VuZXJhdGVEZWZhdWx0VmFsdWUocHJvcCwgZW50aXR5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBmYWtlciDsnbTsmbjsnZgg7ZGc7ZiE7Iud7J2AIOyngOybkO2VmOyngCDslYrsnYxcbiAgICAhaXNUZXN0KCkgJiZcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBjaGFsay55ZWxsb3coXG4gICAgICAgICAgYFVuc3VwcG9ydGVkIGdlbmVyYXRvciBleHByZXNzaW9uIGZvciAke3Byb3AubmFtZX06ICR7Z2VuZXJhdG9yfS4gT25seSBmYWtlci4qIGV4cHJlc3Npb25zIGFyZSBzdXBwb3J0ZWQuIFVzaW5nIGRlZmF1bHQgdmFsdWUuYCxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgcmV0dXJuIHRoaXMuZ2VuZXJhdGVEZWZhdWx0VmFsdWUocHJvcCwgZW50aXR5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDtlYTrk5zsnZgg7YOA7J6F6rO8IOydtOumhOydhCDrtoTshJ3tlZjsl6wg7KCB7KCI7ZWcIOq4sOuzuOqwkuydhCDsg53shLHtlanri4jri6QuXG4gICAqXG4gICAqIOyasOyEoOyInOychDpcbiAgICogMS4g7ZWE65Oc66qFIO2MqO2EtCDrp6Tsua0gKHNhbGFyeSwgYnVkZ2V0IOuTsSDsnZjrr7jsnojripQg642w7J207YSwKVxuICAgKiAyLiDtirnsiJgg7LyA7J207IqkIChEZXBhcnRtZW50IG5hbWUg65OxIOuPhOuplOyduCDsp4Dsi50pXG4gICAqIDMuIOuwsOyXtCDtg4DsnoUgKEpTT04g67Cw7Je0KVxuICAgKiA0LiBFbnVtIO2DgOyehVxuICAgKiA1LiDtg4DsnoXrs4Qg6riw67O46rCSXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdlbmVyYXRlRGVmYXVsdFZhbHVlKHByb3A6IEVudGl0eVByb3AsIGVudGl0eT86IEVudGl0eSk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIGNvbnN0IGZha2VyTW9kdWxlID0gYXdhaXQgaW1wb3J0KFwiQGZha2VyLWpzL2Zha2VyXCIpO1xuICAgIGNvbnN0IGZha2VyID0gZmFrZXJNb2R1bGUuZmFrZXI7XG4gICAgY29uc3QgZmFrZXJLTyA9IGZha2VyTW9kdWxlLmZha2VyS087XG4gICAgY29uc3QgZmFrZXJKQSA9IGZha2VyTW9kdWxlLmZha2VySkE7XG5cbiAgICBjb25zdCBsb2NhbGVGYWtlciA9IHRoaXMubG9jYWxlID09PSBcImtvXCIgPyBmYWtlcktPIDogdGhpcy5sb2NhbGUgPT09IFwiamFcIiA/IGZha2VySkEgOiBmYWtlcjtcblxuICAgIC8qKlxuICAgICAqIDEuIEVudGl0eS1zcGVjaWZpYyDtirnsiJgg7LyA7J207Iqk66W8IOuovOyggCDsspjrpqztlanri4jri6QuXG4gICAgICogZmllbGRfcGF0dGVybnPrs7Tri6Qg7Jqw7ISg7ZWY7JesLCDtirnsoJUg7JeU7Yuw7Yuw7J2YIO2VhOuTnOyXkCDrj4TrqZTsnbjsl5Ag66ee64qUIOqwkuydhCDsg53shLHtlanri4jri6QuXG4gICAgICog7JiIOiBEZXBhcnRtZW50Lm5hbWUg4oaSIO2VnOq1reyWtCDrtoDshJzrqoUgKOyCrOuejCDsnbTrpoTsnbQg7JWE64uYKVxuICAgICAqL1xuXG4gICAgLyoqXG4gICAgICogRGVwYXJ0bWVudCBuYW1l7J2AIO2VnOq1reyWtCDrtoDshJzrqoUg66qp66Gd7JeQ7IScIOyEoO2Dne2VqeuLiOuLpC5cbiAgICAgKiDqs6DsnKDshLHsnYQg7JyE7ZW0IDcwJSDtmZXrpaDroZwgcHJlZml4L3N1ZmZpeOulvCDstpTqsIDtlanri4jri6QuXG4gICAgICovXG4gICAgaWYgKGVudGl0eT8uaWQgPT09IFwiRGVwYXJ0bWVudFwiICYmIHByb3AubmFtZSA9PT0gXCJuYW1lXCIpIHtcbiAgICAgIGNvbnN0IGRlcGFydG1lbnRzID0gW1xuICAgICAgICBcIuqwnOuwnO2MgFwiLFxuICAgICAgICBcIuq4sO2aje2MgFwiLFxuICAgICAgICBcIuuniOy8gO2Mhe2MgFwiLFxuICAgICAgICBcIuyYgeyXhe2MgFwiLFxuICAgICAgICBcIuyduOyCrO2MgFwiLFxuICAgICAgICBcIuy0neustO2MgFwiLFxuICAgICAgICBcIuyerOustO2MgFwiLFxuICAgICAgICBcIu2ajOqzhO2MgFwiLFxuICAgICAgICBcIuuyleustO2MgFwiLFxuICAgICAgICBcIuuUlOyekOyduO2MgFwiLFxuICAgICAgICBcIklU7YyAXCIsXG4gICAgICAgIFwi6rOg6rCd7KeA7JuQ7YyAXCIsXG4gICAgICAgIFwi7ZKI7KeI6rSA66as7YyAXCIsXG4gICAgICAgIFwi7Jew6rWs6rCc67Cc7YyAXCIsXG4gICAgICAgIFwi7IOd7IKw7YyAXCIsXG4gICAgICAgIFwi6rWs66ek7YyAXCIsXG4gICAgICAgIFwi66y866WY7YyAXCIsXG4gICAgICBdO1xuICAgICAgY29uc3QgcHJlZml4ZXMgPSBbXCLsi6Dqt5xcIiwgXCLthrXtlalcIiwgXCLsoITrnrVcIiwgXCLquIDroZzrsoxcIiwgXCLrlJTsp4DthLhcIiwgXCLtlbXsi6xcIl07XG4gICAgICBjb25zdCBzdWZmaXhlcyA9IFtcIjHtjIBcIiwgXCIy7YyAXCIsIFwiM+2MgFwiLCBcIkHtjIBcIiwgXCJC7YyAXCIsIFwi67O467aAXCIsIFwi7IS87YSwXCIsIFwi6re466O5XCJdO1xuXG4gICAgICBjb25zdCBkZXB0ID0gZmFrZXIuaGVscGVycy5hcnJheUVsZW1lbnQoZGVwYXJ0bWVudHMpO1xuXG4gICAgICBjb25zdCByYW5kb20gPSBNYXRoLnJhbmRvbSgpO1xuICAgICAgaWYgKHJhbmRvbSA+IDAuNykge1xuICAgICAgICBjb25zdCBwcmVmaXggPSBmYWtlci5oZWxwZXJzLmFycmF5RWxlbWVudChwcmVmaXhlcyk7XG4gICAgICAgIHJldHVybiBgJHtwcmVmaXh9ICR7ZGVwdH1gO1xuICAgICAgfVxuICAgICAgaWYgKHJhbmRvbSA+IDAuNCkge1xuICAgICAgICBjb25zdCBzdWZmaXggPSBmYWtlci5oZWxwZXJzLmFycmF5RWxlbWVudChzdWZmaXhlcyk7XG4gICAgICAgIHJldHVybiBgJHtkZXB0fSAke3N1ZmZpeH1gO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRlcHQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogMi4g7ZWE65Oc66qF7JeQ7IScIOydmOuvuOulvCDstpTroaDtlZjsl6wg7ZiE7Iuk7KCB7J24IOuNsOydtO2EsOulvCDsg53shLHtlanri4jri6QuXG4gICAgICog7JiIOiBzYWxhcnkg4oaSIDMwTX4xNTBNICjtlZzqta0g7Jew67SJIOuylOychClcbiAgICAgKiAgICAgYnVkZ2V0IOKGkiAxME1+NTAwTSAo7ZSE66Gc7KCd7Yq4IOyYiOyCsCDrspTsnIQpXG4gICAgICovXG4gICAgY29uc3QgbG9jYWxlTWFwcGluZ3MgPSB0aGlzLm1hcHBpbmdzW3RoaXMubG9jYWxlXSB8fCB0aGlzLm1hcHBpbmdzLmVuO1xuICAgIGNvbnN0IG5vcm1hbGl6ZWROYW1lID0gcHJvcC5uYW1lLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvXy9nLCBcIlwiKTtcblxuICAgIGZvciAoY29uc3QgW3BhdHRlcm4sIGNvbmZpZ10gb2YgT2JqZWN0LmVudHJpZXMobG9jYWxlTWFwcGluZ3MuZmllbGRfcGF0dGVybnMpKSB7XG4gICAgICBpZiAobm9ybWFsaXplZE5hbWUuaW5jbHVkZXMocGF0dGVybi50b0xvd2VyQ2FzZSgpKSkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmV4ZWN1dGVGYWtlckV4cHJlc3Npb24oY29uZmlnLmZha2VyLCBwcm9wKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICBjaGFsay55ZWxsb3coXG4gICAgICAgICAgICAgICAgYEZhaWxlZCB0byBleGVjdXRlIGZpZWxkIHBhdHRlcm4gXCIke3BhdHRlcm59XCIgZm9yICR7cHJvcC5uYW1lfSwgZmFsbGluZyBiYWNrOmAsXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIDMuIEpTT04g7YOA7J6F7J2066m07IScIOuwsOyXtOyduCDqsr3smrAgKFNvbmFtdUZpbGVbXSwgc3RyaW5nW10g65OxKVxuICAgICAqIO2VhOuTnOuqhSDtjKjthLTsnYQg67O06rOgIOyggeygiO2VnCDrsLDsl7Qg642w7J207YSw66W8IOyDneyEse2VqeuLiOuLpC5cbiAgICAgKi9cbiAgICBpZiAocHJvcC50eXBlID09PSBcImpzb25cIiAmJiBcImlkXCIgaW4gcHJvcCAmJiBwcm9wLmlkKSB7XG4gICAgICBpZiAocHJvcC5pZC5lbmRzV2l0aChcIltdXCIpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdlbmVyYXRlQXJyYXlWYWx1ZShwcm9wLCBlbnRpdHksIGZha2VyLCBsb2NhbGVGYWtlcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqIDQuIEVudW0g7YOA7J6F7J2AIOygleydmOuQnCDqsJIg7KSRIO2VmOuCmOulvCDrnpzrjaQg7ISg7YOd7ZWp64uI64ukICovXG4gICAgaWYgKHByb3AudHlwZSA9PT0gXCJlbnVtXCIpIHtcbiAgICAgIGxldCBlbnVtVmFsdWVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBpZiAoXCJlbnVtXCIgaW4gcHJvcCAmJiBBcnJheS5pc0FycmF5KHByb3AuZW51bSkgJiYgcHJvcC5lbnVtLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZW51bVZhbHVlcyA9IHByb3AuZW51bTtcbiAgICAgIH0gZWxzZSBpZiAoXCJpZFwiIGluIHByb3AgJiYgcHJvcC5pZCAmJiBlbnRpdHk/LmVudW1MYWJlbHM/Lltwcm9wLmlkXSkge1xuICAgICAgICBlbnVtVmFsdWVzID0gT2JqZWN0LmtleXMoZW50aXR5LmVudW1MYWJlbHNbcHJvcC5pZF0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZW51bVZhbHVlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiBmYWtlci5oZWxwZXJzLmFycmF5RWxlbWVudChlbnVtVmFsdWVzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBwcm9wLm51bGxhYmxlID8gbnVsbCA6IFwiVU5LTk9XTlwiO1xuICAgIH1cblxuICAgIGlmIChwcm9wLnR5cGUgPT09IFwiZW51bVtdXCIpIHtcbiAgICAgIGxldCBlbnVtVmFsdWVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBpZiAoXCJlbnVtXCIgaW4gcHJvcCAmJiBBcnJheS5pc0FycmF5KHByb3AuZW51bSkgJiYgcHJvcC5lbnVtLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZW51bVZhbHVlcyA9IHByb3AuZW51bTtcbiAgICAgIH0gZWxzZSBpZiAoXCJpZFwiIGluIHByb3AgJiYgcHJvcC5pZCAmJiBlbnRpdHk/LmVudW1MYWJlbHM/Lltwcm9wLmlkXSkge1xuICAgICAgICBlbnVtVmFsdWVzID0gT2JqZWN0LmtleXMoZW50aXR5LmVudW1MYWJlbHNbcHJvcC5pZF0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZW51bVZhbHVlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiBbZmFrZXIuaGVscGVycy5hcnJheUVsZW1lbnQoZW51bVZhbHVlcyldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIDUuIFZlY3RvciDtg4DsnoXsnYAg7ZiE7J6sIOyngOybkO2VmOyngCDslYrsnLzrr4DroZwgbnVsbOydhCDrsJjtmZjtlanri4jri6QuXG4gICAgICog7Zal7ZuEIEFJIGVtYmVkZGluZyDsg53shLEg6riw64qlIOy2lOqwgCDsi5wg6rWs7ZiEIOyYiOygleyeheuLiOuLpC5cbiAgICAgKi9cbiAgICBpZiAocHJvcC50eXBlID09PSBcInZlY3RvclwiIHx8IHByb3AudHlwZSA9PT0gXCJ2ZWN0b3JbXVwiIHx8IHByb3AudHlwZSA9PT0gXCJ0c3ZlY3RvclwiKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvKiogNi4g7YOA7J6F67OEIOq4sOuzuCBGYWtlciDtkZztmITsi53snYQg7Iuk7ZaJ7ZWp64uI64ukICovXG4gICAgY29uc3QgdHlwZURlZmF1bHQgPSBsb2NhbGVNYXBwaW5ncy50eXBlX2RlZmF1bHRzW3Byb3AudHlwZV07XG4gICAgaWYgKHR5cGVEZWZhdWx0KSB7XG4gICAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5leGVjdXRlRmFrZXJFeHByZXNzaW9uKHR5cGVEZWZhdWx0LmZha2VyLCBwcm9wKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICFpc1Rlc3QoKSAmJlxuICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgY2hhbGsueWVsbG93KGBGYWlsZWQgdG8gZXhlY3V0ZSB0eXBlIGRlZmF1bHQgZm9yICR7cHJvcC50eXBlfSwgdXNpbmcgZmFsbGJhY2s6YCwgZXJyb3IpLFxuICAgICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqIDcuIOunpO2VkeuQmOyngCDslYrsnYAg7YOA7J6F7J2AIOq4sOuzuCBGYWtlciDtlajsiJjroZwg7LKY66as7ZWp64uI64ukICovXG4gICAgc3dpdGNoIChwcm9wLnR5cGUpIHtcbiAgICAgIGNhc2UgXCJzdHJpbmdcIjpcbiAgICAgIGNhc2UgXCJzdHJpbmdbXVwiOlxuICAgICAgICByZXR1cm4gZmFrZXIubG9yZW0ud29yZHMoMyk7XG4gICAgICBjYXNlIFwiaW50ZWdlclwiOlxuICAgICAgICByZXR1cm4gZmFrZXIubnVtYmVyLmludCh7IG1pbjogMSwgbWF4OiAxMDAwIH0pO1xuICAgICAgY2FzZSBcImludGVnZXJbXVwiOlxuICAgICAgICByZXR1cm4gW2Zha2VyLm51bWJlci5pbnQoeyBtaW46IDEsIG1heDogMTAwMCB9KV07XG4gICAgICBjYXNlIFwiYmlnSW50ZWdlclwiOlxuICAgICAgICByZXR1cm4gZmFrZXIubnVtYmVyLmJpZ0ludCh7IG1pbjogMW4sIG1heDogMTAwMG4gfSk7XG4gICAgICBjYXNlIFwiYmlnSW50ZWdlcltdXCI6XG4gICAgICAgIHJldHVybiBbZmFrZXIubnVtYmVyLmJpZ0ludCh7IG1pbjogMW4sIG1heDogMTAwMG4gfSldO1xuICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgY2FzZSBcIm51bWVyaWNcIjpcbiAgICAgICAgcmV0dXJuIGZha2VyLm51bWJlci5mbG9hdCh7IG1pbjogMCwgbWF4OiAxMDAwIH0pO1xuICAgICAgY2FzZSBcIm51bWJlcltdXCI6XG4gICAgICBjYXNlIFwibnVtZXJpY1tdXCI6XG4gICAgICAgIHJldHVybiBbZmFrZXIubnVtYmVyLmZsb2F0KHsgbWluOiAwLCBtYXg6IDEwMDAgfSldO1xuICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgICAgcmV0dXJuIGZha2VyLmRhdGF0eXBlLmJvb2xlYW4oKTtcbiAgICAgIGNhc2UgXCJib29sZWFuW11cIjpcbiAgICAgICAgcmV0dXJuIFtmYWtlci5kYXRhdHlwZS5ib29sZWFuKCldO1xuICAgICAgY2FzZSBcImRhdGVcIjpcbiAgICAgIGNhc2UgXCJkYXRlW11cIjpcbiAgICAgICAgcmV0dXJuIGZha2VyLmRhdGUucGFzdCgpO1xuICAgICAgY2FzZSBcImpzb25cIjpcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgY2FzZSBcInV1aWRcIjpcbiAgICAgIGNhc2UgXCJ1dWlkW11cIjpcbiAgICAgICAgcmV0dXJuIGZha2VyLnN0cmluZy51dWlkKCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog67Cw7Je0IO2DgOyeheydmCDqsJLsnYQg7IOd7ISx7ZWp64uI64ukLlxuICAgKlxuICAgKiDtg4DsnoUgSUTsmYAg7ZWE65Oc66qFIO2MqO2EtOydhCDrtoTshJ3tlZjsl6wg7KCB7KCI7ZWcIOuwsOyXtCDrjbDsnbTthLDrpbwg7IOd7ISx7ZWp64uI64ukLlxuICAgKiDsmIg6IGltYWdlX3VybHMg4oaSIFt7dXJsLCBuYW1lLCBtaW1lX3R5cGV9LCAuLi5dXG4gICAqICAgICB0YWdfaWRzIOKGkiBbMSwgMjMsIDQ1XVxuICAgKi9cbiAgcHJpdmF0ZSBnZW5lcmF0ZUFycmF5VmFsdWUoXG4gICAgcHJvcDogRW50aXR5UHJvcCxcbiAgICBfZW50aXR5OiBFbnRpdHkgfCB1bmRlZmluZWQsXG4gICAgZmFrZXI6IHR5cGVvZiBpbXBvcnQoXCJAZmFrZXItanMvZmFrZXJcIikuZmFrZXIsXG4gICAgX2xvY2FsZUZha2VyOiB0eXBlb2YgaW1wb3J0KFwiQGZha2VyLWpzL2Zha2VyXCIpLmZha2VyLFxuICApOiB1bmtub3duW10ge1xuICAgIGNvbnN0IGNvdW50ID0gZmFrZXIubnVtYmVyLmludCh7IG1pbjogMSwgbWF4OiAzIH0pO1xuXG4gICAgLyoqIFNvbmFtdUZpbGVbXeydgCBTb25hbXUg64K07J6lIO2DgOyeheycvOuhnCDqtazsobDqsIAg7KCV7ZW07KC4IOyeiOyKteuLiOuLpCAqL1xuICAgIGlmIChcImlkXCIgaW4gcHJvcCAmJiBwcm9wLmlkID09PSBcIlNvbmFtdUZpbGVbXVwiKSB7XG4gICAgICByZXR1cm4gQXJyYXkuZnJvbSh7IGxlbmd0aDogY291bnQgfSwgKCkgPT4gKHtcbiAgICAgICAgdXJsOiBmYWtlci5pbWFnZS51cmwoKSxcbiAgICAgICAgbmFtZTogZmFrZXIuc3lzdGVtLmZpbGVOYW1lKCksXG4gICAgICAgIG1pbWVfdHlwZTogZmFrZXIuaGVscGVycy5hcnJheUVsZW1lbnQoW1xuICAgICAgICAgIFwiaW1hZ2UvanBlZ1wiLFxuICAgICAgICAgIFwiaW1hZ2UvcG5nXCIsXG4gICAgICAgICAgXCJpbWFnZS9naWZcIixcbiAgICAgICAgICBcImFwcGxpY2F0aW9uL3BkZlwiLFxuICAgICAgICBdKSxcbiAgICAgIH0pKTtcbiAgICB9XG5cbiAgICAvKiog7ZWE65Oc66qF7JeQ7IScIOuwsOyXtOydmCDsmqnrj4Trpbwg7LaU66Gg7ZWp64uI64ukICovXG4gICAgY29uc3Qgbm9ybWFsaXplZE5hbWUgPSBwcm9wLm5hbWUudG9Mb3dlckNhc2UoKS5yZXBsYWNlKC9fL2csIFwiXCIpO1xuXG4gICAgaWYgKG5vcm1hbGl6ZWROYW1lLmluY2x1ZGVzKFwidXJsXCIpIHx8IG5vcm1hbGl6ZWROYW1lLmluY2x1ZGVzKFwiaW1hZ2VcIikpIHtcbiAgICAgIHJldHVybiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBjb3VudCB9LCAoKSA9PiBmYWtlci5pbnRlcm5ldC51cmwoKSk7XG4gICAgfVxuXG4gICAgaWYgKG5vcm1hbGl6ZWROYW1lLmluY2x1ZGVzKFwiaWRcIikgJiYgbm9ybWFsaXplZE5hbWUuZW5kc1dpdGgoXCJzXCIpKSB7XG4gICAgICByZXR1cm4gQXJyYXkuZnJvbSh7IGxlbmd0aDogY291bnQgfSwgKCkgPT4gZmFrZXIubnVtYmVyLmludCh7IG1pbjogMSwgbWF4OiAxMDAgfSkpO1xuICAgIH1cblxuICAgIGlmIChub3JtYWxpemVkTmFtZS5pbmNsdWRlcyhcInRhZ1wiKSB8fCBub3JtYWxpemVkTmFtZS5pbmNsdWRlcyhcIm5hbWVcIikpIHtcbiAgICAgIHJldHVybiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBjb3VudCB9LCAoKSA9PiBmYWtlci5sb3JlbS53b3JkKCkpO1xuICAgIH1cblxuICAgIC8qKiDtjKjthLQg66ek7Lmt65CY7KeAIOyViuycvOuptCDruYgg67Cw7Je07J2EIOuwmO2ZmO2VqeuLiOuLpCAqL1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBKU09OIOunpO2VkeydmCBGYWtlciDtkZztmITsi53snYQg7YyM7Iux7ZWY7JesIOyLpO2Wie2VqeuLiOuLpC5cbiAgICpcbiAgICog7ZGc7ZiE7IudIOyYiOyLnDpcbiAgICogLSBcImZha2VyLmludGVybmV0LmVtYWlsKClcIiDihpIg7J247J6QIOyXhuydjFxuICAgKiAtIFwiZmFrZXIubnVtYmVyLmludCh7IG1pbjogMSwgbWF4OiAxMDAgfSlcIiDihpIgSlNPTiDsnbjsnpBcbiAgICogLSBcInt9XCIg4oaSIOumrO2EsOuftCDqsJIgKEpTT04ucGFyc2UpXG4gICAqXG4gICAqIGZha2VyS08sIGZha2VySkHrj4Qg7KeA7JuQ7ZWY7JesIOuLpOq1reyWtCDrjbDsnbTthLDrpbwg7IOd7ISx7ZWp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBleGVjdXRlRmFrZXJFeHByZXNzaW9uKGV4cHJlc3Npb246IHN0cmluZywgcHJvcDogRW50aXR5UHJvcCk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIGNvbnN0IGZha2VyTW9kdWxlID0gYXdhaXQgaW1wb3J0KFwiQGZha2VyLWpzL2Zha2VyXCIpO1xuICAgIGNvbnN0IGZha2VyID0gZmFrZXJNb2R1bGUuZmFrZXI7XG4gICAgY29uc3QgZmFrZXJLTyA9IGZha2VyTW9kdWxlLmZha2VyS087XG4gICAgY29uc3QgZmFrZXJKQSA9IGZha2VyTW9kdWxlLmZha2VySkE7XG5cbiAgICAvKiogRmFrZXIg7ZGc7ZiE7Iud7J20IOyVhOuLjCDrpqzthLDrn7Qg6rCS7J2AIEpTT07snLzroZwg7YyM7Iux7ZWp64uI64ukICovXG4gICAgaWYgKCFleHByZXNzaW9uLnN0YXJ0c1dpdGgoXCJmYWtlclwiKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoZXhwcmVzc2lvbik7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIGV4cHJlc3Npb247XG4gICAgICB9XG4gICAgfVxuXG4gICAgLyoqIO2RnO2YhOyLneyXkOyEnCBGYWtlciDqsJ3ssrTsmYAg6rK966Gc66W8IOy2lOy2nO2VqeuLiOuLpCAqL1xuICAgIGNvbnN0IG1hdGNoID0gZXhwcmVzc2lvbi5tYXRjaCgvXihmYWtlcnxmYWtlcktPfGZha2VySkEpXFwuKC4qPykkLyk7XG4gICAgaWYgKCFtYXRjaCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGZha2VyIGV4cHJlc3Npb246ICR7ZXhwcmVzc2lvbn1gKTtcbiAgICB9XG5cbiAgICBjb25zdCBbLCBmYWtlck5hbWUsIGV4cHJdID0gbWF0Y2g7XG4gICAgY29uc3Qgc2VsZWN0ZWRGYWtlciA9XG4gICAgICBmYWtlck5hbWUgPT09IFwiZmFrZXJLT1wiID8gZmFrZXJLTyA6IGZha2VyTmFtZSA9PT0gXCJmYWtlckpBXCIgPyBmYWtlckpBIDogZmFrZXI7XG5cbiAgICBjb25zdCBmdW5jTWF0Y2ggPSBleHByLm1hdGNoKC9eKFtcXHcuXSspKD86XFwoKC4qPylcXCkpPyQvKTtcbiAgICBpZiAoIWZ1bmNNYXRjaCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIGZha2VyIGV4cHJlc3Npb24gZm9yICR7cHJvcC5uYW1lfTogJHtleHByZXNzaW9ufWApO1xuICAgIH1cblxuICAgIGNvbnN0IFssIHBhdGgsIGFyZ3NTdHJdID0gZnVuY01hdGNoO1xuICAgIGNvbnN0IHBhcnRzID0gcGF0aC5zcGxpdChcIi5cIik7XG5cbiAgICAvKiog7KCQIO2RnOq4sOuylShkb3Qgbm90YXRpb24p7Jy866GcIEZha2VyIO2VqOyImOulvCDssL7slYTqsJHri4jri6QgKi9cbiAgICBsZXQgZm46IHVua25vd24gPSBzZWxlY3RlZEZha2VyO1xuICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgICAgaWYgKHR5cGVvZiBmbiA9PT0gXCJvYmplY3RcIiAmJiBmbiAhPT0gbnVsbCAmJiBwYXJ0IGluIGZuKSB7XG4gICAgICAgIGZuID0gKGZuIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtwYXJ0XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBmYWtlciBwYXRoIGZvciAke3Byb3AubmFtZX06ICR7ZmFrZXJOYW1lfS4ke3BhdGh9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBmbiAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZmFrZXJOYW1lfS4ke3BhdGh9IGlzIG5vdCBhIGZ1bmN0aW9uIChmb3IgJHtwcm9wLm5hbWV9KWApO1xuICAgIH1cblxuICAgIGxldCBhcmdzOiB1bmtub3duW10gPSBbXTtcbiAgICBpZiAoYXJnc1N0cj8udHJpbSgpKSB7XG4gICAgICBhcmdzID0gdGhpcy5wYXJzZUdlbmVyYXRvckFyZ3MoYXJnc1N0ciwgcHJvcC5uYW1lKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZm4oLi4uYXJncyk7XG4gIH1cblxuICAvKipcbiAgICogZml4dHVyZUhpbnTrpbwgTExN7JeQ6rKMIOyghOuLrO2VmOyXrCDtmITsi6TsoIHsnbgg7YWM7Iqk7Yq4IOuNsOydtO2EsOulvCDsg53shLHtlanri4jri6QuXG4gICAqXG4gICAqIGZha2VyLmpz66Gc64qUIOyDneyEse2VmOq4sCDslrTroKTsmrQg67O17J6h7ZWcIO2FjeyKpO2KuCjsnpDquLDshozqsJwsIOyEpOuqheusuCDrk7Ep66W8XG4gICAqIExMTeydhCDtmZzsmqntlZjsl6wg7IOd7ISx7ZWp64uI64ukLiDrj5nsnbztlZwgaGludOyXkCDrjIDtlZwg7KSR67O1IO2YuOy2nOydhCDrsKnsp4DtlZjquLAg7JyE7ZW0XG4gICAqIOy6kOyLseydhCDquLDrs7jsnLzroZwg7KeA7JuQ7ZWp64uI64ukIChMTE0gQVBJIOu5hOyaqSDsoIjqsJApLlxuICAgKlxuICAgKiBhaSDtjKjtgqTsp4DripQgZHluYW1pYyBpbXBvcnTroZwg67aI65+s7Jik66+A66GcLCB1c2VMTE3snbQgZmFsc2Xsnbgg6rK97JqwXG4gICAqIOydmOyhtOyEseydtCDshKTsuZjrkJjsp4Ag7JWK7JWE64+EIGZpeHR1cmUg7IOd7ISx7J20IOygleyDgSDrj5nsnpHtlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdlbmVyYXRlV2l0aExMTShcbiAgICBmaXh0dXJlSGludDogc3RyaW5nLFxuICAgIHByb3A6IEVudGl0eVByb3AsXG4gICAgZW50aXR5OiBFbnRpdHksXG4gICAgcm93S2V5Pzogc3RyaW5nLFxuICApOiBQcm9taXNlPHVua25vd24+IHtcbiAgICAvLyByb3dLZXnqsIAg7J6I7Jy866m0IHJvdyDri6jsnIQg7IOd7ISxIOyghOuetSDsgqzsmqlcbiAgICBpZiAocm93S2V5KSB7XG4gICAgICBjb25zdCByb3dDYWNoZUtleSA9IGAke3Jvd0tleX06JHtwcm9wLm5hbWV9YDtcblxuICAgICAgLy8g7J2066+4IOydtCByb3fsl5Ag64yA7ZWcIExMTSDtmLjstpzsnbQg7JmE66OM65CcIOqyveyasCDsupDsi5zsl5DshJwg67CU66GcIOuwmO2ZmFxuICAgICAgaWYgKHRoaXMubGxtQ2FjaGUuaGFzKHJvd0NhY2hlS2V5KSkge1xuICAgICAgICByZXR1cm4gdGhpcy5sbG1DYWNoZS5nZXQocm93Q2FjaGVLZXkpO1xuICAgICAgfVxuXG4gICAgICAvLyDsg4ggcm93OiBMTE0g64yA7IOBIHByb3Ag7KCE7LK066W8IO2VnCDrsojsl5Ag7IOd7ISxXG4gICAgICBjb25zdCBsbG1Qcm9wcyA9IGVudGl0eS5wcm9wcy5maWx0ZXIoKHApID0+IHtcbiAgICAgICAgaWYgKGlzUmVsYXRpb25Qcm9wKHApKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChwLmNvbmU/LmZpeHR1cmVHZW5lcmF0b3IpIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKHAubmFtZSA9PT0gXCJpZFwiKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiAhIXAuY29uZT8ubm90ZTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBsbG1Qcm9wc+qwgCDruYTslrTsnojsnLzrqbQg64uo7J28IO2VhOuTnCDrsKnsi53snLzroZwgZmFsbGJhY2tcbiAgICAgIGlmIChsbG1Qcm9wcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBgW0ZpeHR1cmVHZW5lcmF0b3JdIGxsbVByb3BzIGlzIGVtcHR5IGZvciAke2VudGl0eS5pZH0uJHtwcm9wLm5hbWV9LCB1c2luZyBzaW5nbGUgZmllbGQgZmFsbGJhY2tgLFxuICAgICAgICAgICk7XG4gICAgICAgIHJldHVybiB0aGlzLmdlbmVyYXRlU2luZ2xlV2l0aExMTShmaXh0dXJlSGludCwgcHJvcCwgZW50aXR5KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYXBpS2V5ID0gdGhpcy5nZXRBcGlLZXkoKTtcbiAgICAgIGNvbnN0IHsgY3JlYXRlQW50aHJvcGljIH0gPSBhd2FpdCBpbXBvcnQoXCJAYWktc2RrL2FudGhyb3BpY1wiKTtcbiAgICAgIGNvbnN0IHsgZ2VuZXJhdGVUZXh0IH0gPSBhd2FpdCBpbXBvcnQoXCJhaVwiKTtcblxuICAgICAgY29uc3Qgcm93UmVzcG9uc2UgPSBhd2FpdCBnZW5lcmF0ZVRleHQoe1xuICAgICAgICBtb2RlbDogY3JlYXRlQW50aHJvcGljKHsgYXBpS2V5IH0pKHRoaXMub3B0aW9ucy5sbG1Nb2RlbCB8fCBcImNsYXVkZS1zb25uZXQtNC02XCIpLFxuICAgICAgICBwcm9tcHQ6IHRoaXMuYnVpbGRSb3dMTE1Qcm9tcHQobGxtUHJvcHMsIGVudGl0eSksXG4gICAgICB9KTtcbiAgICAgIGlmICghcm93UmVzcG9uc2UgfHwgdHlwZW9mIHJvd1Jlc3BvbnNlLnRleHQgIT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBMTE0gcmVzcG9uc2VcIik7XG4gICAgICB9XG5cbiAgICAgIC8vIOydkeuLteydhCDtjIzsi7HtlZjsl6wg6rCBIO2VhOuTnOyXkCDrjIDtlZwg6rKw6rO866W8IOy6kOyLnOyXkCDsoIDsnqVcbiAgICAgIGNvbnN0IHJvd1Jlc3VsdCA9IHRoaXMucGFyc2VSb3dMTE1SZXNwb25zZShyb3dSZXNwb25zZS50ZXh0LCBsbG1Qcm9wcyk7XG4gICAgICBmb3IgKGNvbnN0IFtmaWVsZE5hbWUsIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhyb3dSZXN1bHQpKSB7XG4gICAgICAgIHRoaXMubGxtQ2FjaGUuc2V0KGAke3Jvd0tleX06JHtmaWVsZE5hbWV9YCwgdmFsdWUpO1xuICAgICAgfVxuXG4gICAgICAvLyDsmpTssq3tlZwg7ZWE65Oc7J2YIOqwkiDrsJjtmZggKOyXhuycvOuptCDri6jsnbwg7ZWE65OcIGZhbGxiYWNrKVxuICAgICAgaWYgKHRoaXMubGxtQ2FjaGUuaGFzKHJvd0NhY2hlS2V5KSkge1xuICAgICAgICByZXR1cm4gdGhpcy5sbG1DYWNoZS5nZXQocm93Q2FjaGVLZXkpO1xuICAgICAgfVxuXG4gICAgICAvLyDrp4zslb0gcm93IOydkeuLteyXkCDsnbQg7ZWE65Oc6rCAIOuIhOudveuQnCDqsr3smrAg64uo7J28IO2VhOuTnCBmYWxsYmFja1xuICAgICAgcmV0dXJuIHRoaXMuZ2VuZXJhdGVTaW5nbGVXaXRoTExNKGZpeHR1cmVIaW50LCBwcm9wLCBlbnRpdHkpO1xuICAgIH1cblxuICAgIC8vIHJvd0tleeqwgCDsl4bsnLzrqbQg6riw7KG0IOuLqOydvCDtlYTrk5wg67Cp7IudXG4gICAgcmV0dXJuIHRoaXMuZ2VuZXJhdGVTaW5nbGVXaXRoTExNKGZpeHR1cmVIaW50LCBwcm9wLCBlbnRpdHkpO1xuICB9XG5cbiAgLyoqXG4gICAqIOuLqOydvCDtlYTrk5zrpbwgTExN7Jy866GcIOyDneyEse2VqeuLiOuLpCAocm93S2V5IOyXhuydhCDrlYwgZmFsbGJhY2vsmqkpXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdlbmVyYXRlU2luZ2xlV2l0aExMTShcbiAgICBmaXh0dXJlSGludDogc3RyaW5nLFxuICAgIHByb3A6IEVudGl0eVByb3AsXG4gICAgZW50aXR5OiBFbnRpdHksXG4gICk6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIGNvbnN0IGNhY2hlS2V5ID0gYCR7ZW50aXR5LmlkfToke3Byb3AubmFtZX06JHtmaXh0dXJlSGludH1gO1xuICAgIGlmICh0aGlzLm9wdGlvbnMuZW5hYmxlTExNQ2FjaGUgJiYgdGhpcy5sbG1DYWNoZS5oYXMoY2FjaGVLZXkpKSB7XG4gICAgICByZXR1cm4gdGhpcy5sbG1DYWNoZS5nZXQoY2FjaGVLZXkpO1xuICAgIH1cblxuICAgIGNvbnN0IGFwaUtleSA9IHRoaXMuZ2V0QXBpS2V5KCk7XG4gICAgY29uc3QgeyBjcmVhdGVBbnRocm9waWMgfSA9IGF3YWl0IGltcG9ydChcIkBhaS1zZGsvYW50aHJvcGljXCIpO1xuICAgIGNvbnN0IHsgZ2VuZXJhdGVUZXh0IH0gPSBhd2FpdCBpbXBvcnQoXCJhaVwiKTtcblxuICAgIGNvbnN0IHNpbmdsZVJlc3BvbnNlID0gYXdhaXQgZ2VuZXJhdGVUZXh0KHtcbiAgICAgIG1vZGVsOiBjcmVhdGVBbnRocm9waWMoeyBhcGlLZXkgfSkodGhpcy5vcHRpb25zLmxsbU1vZGVsIHx8IFwiY2xhdWRlLXNvbm5ldC00LTZcIiksXG4gICAgICBwcm9tcHQ6IHRoaXMuYnVpbGRMTE1Qcm9tcHQoZml4dHVyZUhpbnQsIHByb3AsIGVudGl0eSksXG4gICAgfSk7XG4gICAgaWYgKCFzaW5nbGVSZXNwb25zZSB8fCB0eXBlb2Ygc2luZ2xlUmVzcG9uc2UudGV4dCAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBMTE0gcmVzcG9uc2VcIik7XG4gICAgfVxuXG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLnBhcnNlTExNUmVzcG9uc2Uoc2luZ2xlUmVzcG9uc2UudGV4dCwgcHJvcC50eXBlKTtcbiAgICBpZiAodGhpcy5vcHRpb25zLmVuYWJsZUxMTUNhY2hlKSB7XG4gICAgICB0aGlzLmxsbUNhY2hlLnNldChjYWNoZUtleSwgdmFsdWUpO1xuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiByb3cg7KCE7LK066W8IO2VnCDrsojsl5Ag7IOd7ISx7ZWY64qUIExMTSDtlITroaztlITtirjrpbwg66eM65Ot64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZFJvd0xMTVByb21wdChwcm9wczogRW50aXR5UHJvcFtdLCBlbnRpdHk6IEVudGl0eSk6IHN0cmluZyB7XG4gICAgY29uc3QgbG9jYWxlID0gdGhpcy5vcHRpb25zLmxvY2FsZSB8fCBcImtvXCI7XG4gICAgY29uc3QgbGFuZ3VhZ2UgPSBsb2NhbGUgPT09IFwia29cIiA/IFwiS29yZWFuXCIgOiBsb2NhbGUgPT09IFwiamFcIiA/IFwiSmFwYW5lc2VcIiA6IFwiRW5nbGlzaFwiO1xuXG4gICAgY29uc3QgZmllbGREZXNjcmlwdGlvbnMgPSBwcm9wc1xuICAgICAgLm1hcCgocCkgPT4ge1xuICAgICAgICBsZXQgZGVzYyA9IGAtICR7cC5uYW1lfSAoJHtwLnR5cGV9KTogJHtwLmNvbmU/Lm5vdGUgPz8gXCJcIn1gO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgKHAudHlwZSA9PT0gXCJlbnVtXCIgfHwgcC50eXBlID09PSBcImVudW1bXVwiKSAmJlxuICAgICAgICAgIFwiaWRcIiBpbiBwICYmXG4gICAgICAgICAgcC5pZCAmJlxuICAgICAgICAgIGVudGl0eS5lbnVtTGFiZWxzPy5bcC5pZF1cbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWVzID0gT2JqZWN0LmtleXMoZW50aXR5LmVudW1MYWJlbHNbcC5pZF0pLmpvaW4oXCIsIFwiKTtcbiAgICAgICAgICBkZXNjICs9IGAgW2FsbG93ZWQgdmFsdWVzOiAke3ZhbHVlc31dYDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVzYztcbiAgICAgIH0pXG4gICAgICAuam9pbihcIlxcblwiKTtcblxuICAgIC8vIExMTSDrjIDsg4HsnbQg7JWE64uMIHByb3Drk6Trj4Qg66el65297Jy866GcIOygnOqztSAocmVsYXRpb24g7KCc7Jm4KVxuICAgIGNvbnN0IG90aGVyUHJvcHMgPSBlbnRpdHkucHJvcHNcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChwKSA9PlxuICAgICAgICAgICFwcm9wcy5pbmNsdWRlcyhwKSAmJlxuICAgICAgICAgICFpc1JlbGF0aW9uUHJvcChwKSAmJlxuICAgICAgICAgIHAubmFtZSAhPT0gXCJpZFwiICYmXG4gICAgICAgICAgIShcInZpcnR1YWxcIiBpbiBwICYmIHAudmlydHVhbCksXG4gICAgICApXG4gICAgICAubWFwKChwKSA9PiB7XG4gICAgICAgIGxldCBkZXNjID0gYC0gJHtwLm5hbWV9ICgke3AudHlwZX0pYDtcbiAgICAgICAgaWYgKHAuY29uZT8ubm90ZSkgZGVzYyArPSBgOiAke3AuY29uZS5ub3RlfWA7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAocC50eXBlID09PSBcImVudW1cIiB8fCBwLnR5cGUgPT09IFwiZW51bVtdXCIpICYmXG4gICAgICAgICAgXCJpZFwiIGluIHAgJiZcbiAgICAgICAgICBwLmlkICYmXG4gICAgICAgICAgZW50aXR5LmVudW1MYWJlbHM/LltwLmlkXVxuICAgICAgICApIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZXMgPSBPYmplY3Qua2V5cyhlbnRpdHkuZW51bUxhYmVsc1twLmlkXSkuam9pbihcIiwgXCIpO1xuICAgICAgICAgIGRlc2MgKz0gYCBbYWxsb3dlZCB2YWx1ZXM6ICR7dmFsdWVzfV1gO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBkZXNjO1xuICAgICAgfSlcbiAgICAgIC5qb2luKFwiXFxuXCIpO1xuICAgIGNvbnN0IG90aGVyUHJvcHNDb250ZXh0ID0gb3RoZXJQcm9wc1xuICAgICAgPyBgXFxuXFxuT3RoZXIgZmllbGRzIGluIHRoaXMgZW50aXR5IChmb3IgY29udGV4dCwgZG8gTk9UIGdlbmVyYXRlIHRoZXNlKTpcXG4ke290aGVyUHJvcHN9YFxuICAgICAgOiBcIlwiO1xuXG4gICAgY29uc3Qgb3V0cHV0U2hhcGUgPSBwcm9wcy5tYXAoKHApID0+IGAgIFwiJHtwLm5hbWV9XCI6IDwke3AudHlwZX0+YCkuam9pbihcIixcXG5cIik7XG5cbiAgICBjb25zdCBlbnRpdHlDb250ZXh0ID0gZW50aXR5LmNvbmU/Lm5vdGUgPyBgXFxuRW50aXR5IGRlc2NyaXB0aW9uOiAke2VudGl0eS5jb25lLm5vdGV9YCA6IFwiXCI7XG5cbiAgICByZXR1cm4gYEdlbmVyYXRlIHRlc3QgZml4dHVyZSBkYXRhIGZvciB0aGUgJHtlbnRpdHkuaWR9IGVudGl0eS4gQWxsIGZpZWxkcyBtdXN0IGJlIGNvaGVyZW50IGFuZCBjb25zaXN0ZW50IHdpdGggZWFjaCBvdGhlci5cblxuRW50aXR5OiAke2VudGl0eS5pZH0ke2VudGl0eUNvbnRleHR9XG5Mb2NhbGU6ICR7bG9jYWxlfSAodXNlICR7bGFuZ3VhZ2V9IGZvciB0ZXh0IGZpZWxkcylcblxuRmllbGRzIHRvIGdlbmVyYXRlOlxuJHtmaWVsZERlc2NyaXB0aW9uc30ke290aGVyUHJvcHNDb250ZXh0fVxuXG5SdWxlczpcbi0gQWxsIGZpZWxkcyBpbiBhIHNpbmdsZSByb3cgbXVzdCBiZSBsb2dpY2FsbHkgY29uc2lzdGVudCAoZS5nLiBuYW1lL25hbWVfZW4vbmFtZV9jbiBzaG91bGQgcmVwcmVzZW50IHRoZSBzYW1lIHBlcnNvbilcbi0gUmV0dXJuIE9OTFkgdmFsaWQgSlNPTiwgbm8gbWFya2Rvd24gb3IgZXhwbGFuYXRpb25cbi0gRGF0ZXMgaW4gSVNPIDg2MDEgZm9ybWF0XG4tIFVzZSAke2xhbmd1YWdlfSBmb3IgdGV4dCB1bmxlc3MgZmllbGQgZGVzY3JpcHRpb24gc2F5cyBvdGhlcndpc2VcblxuUmV0dXJuIGV4YWN0bHkgdGhpcyBKU09OIHNoYXBlOlxue1xuJHtvdXRwdXRTaGFwZX1cbn1gO1xuICB9XG5cbiAgLyoqXG4gICAqIHJvdyBMTE0g7J2R64u17J2EIO2MjOyLse2VmOyXrCDtlYTrk5zrs4Qg6rCS7Jy866GcIOuzgO2ZmO2VqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgcGFyc2VSb3dMTE1SZXNwb25zZSh0ZXh0OiBzdHJpbmcsIHByb3BzOiBFbnRpdHlQcm9wW10pOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgY29uc3QganNvblRleHQgPSB0ZXh0XG4gICAgICAudHJpbSgpXG4gICAgICAucmVwbGFjZSgvXmBgYGpzb25cXHMqL2ksIFwiXCIpXG4gICAgICAucmVwbGFjZSgvYGBgXFxzKiQvLCBcIlwiKVxuICAgICAgLnRyaW0oKTtcblxuICAgIGxldCBwYXJzZWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByYXcgPSBKU09OLnBhcnNlKGpzb25UZXh0KTtcbiAgICAgIGlmICh0eXBlb2YgcmF3ICE9PSBcIm9iamVjdFwiIHx8IHJhdyA9PT0gbnVsbCB8fCBBcnJheS5pc0FycmF5KHJhdykpIHtcbiAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgY29uc29sZS53YXJuKFwiW0ZpeHR1cmVHZW5lcmF0b3JdIFJvdyBMTE0gcmVzcG9uc2UgaXMgbm90IGEgcGxhaW4gb2JqZWN0OlwiLCB0ZXh0KTtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgfVxuICAgICAgcGFyc2VkID0gcmF3IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgIH0gY2F0Y2gge1xuICAgICAgIWlzVGVzdCgpICYmIGNvbnNvbGUud2FybihcIltGaXh0dXJlR2VuZXJhdG9yXSBGYWlsZWQgdG8gcGFyc2Ugcm93IExMTSByZXNwb25zZTpcIiwgdGV4dCk7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHt9O1xuICAgIGZvciAoY29uc3QgcHJvcCBvZiBwcm9wcykge1xuICAgICAgaWYgKHByb3AubmFtZSBpbiBwYXJzZWQpIHtcbiAgICAgICAgcmVzdWx0W3Byb3AubmFtZV0gPSB0aGlzLnBhcnNlTExNUmVzcG9uc2UoU3RyaW5nKHBhcnNlZFtwcm9wLm5hbWVdID8/IFwiXCIpLCBwcm9wLnR5cGUpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZExMTVByb21wdChoaW50OiBzdHJpbmcsIHByb3A6IEVudGl0eVByb3AsIGVudGl0eTogRW50aXR5KTogc3RyaW5nIHtcbiAgICBjb25zdCBsb2NhbGUgPSB0aGlzLm9wdGlvbnMubG9jYWxlIHx8IFwia29cIjtcbiAgICBjb25zdCBsYW5ndWFnZSA9IGxvY2FsZSA9PT0gXCJrb1wiID8gXCJLb3JlYW5cIiA6IGxvY2FsZSA9PT0gXCJqYVwiID8gXCJKYXBhbmVzZVwiIDogXCJFbmdsaXNoXCI7XG5cbiAgICBjb25zdCBlbnRpdHlDb250ZXh0ID0gZW50aXR5LmNvbmU/Lm5vdGUgPyBgXFxuRW50aXR5IGNvbnRleHQ6ICR7ZW50aXR5LmNvbmUubm90ZX1gIDogXCJcIjtcblxuICAgIGNvbnN0IG90aGVyRmllbGRzID0gZW50aXR5LnByb3BzXG4gICAgICAuZmlsdGVyKChwKSA9PiBwLm5hbWUgIT09IHByb3AubmFtZSAmJiAhaXNSZWxhdGlvblByb3AocCkgJiYgcC5jb25lPy5ub3RlKVxuICAgICAgLm1hcCgocCkgPT4gYC0gJHtwLm5hbWV9ICgke3AudHlwZX0pOiAke3AuY29uZT8ubm90ZX1gKVxuICAgICAgLmpvaW4oXCJcXG5cIik7XG4gICAgY29uc3Qgb3RoZXJGaWVsZHNDb250ZXh0ID0gb3RoZXJGaWVsZHNcbiAgICAgID8gYFxcblxcbk90aGVyIGZpZWxkcyBpbiB0aGlzIGVudGl0eSAoZm9yIGNvbnRleHQpOlxcbiR7b3RoZXJGaWVsZHN9YFxuICAgICAgOiBcIlwiO1xuXG4gICAgbGV0IHByb21wdCA9IGBHZW5lcmF0ZSB0ZXN0IGRhdGEgZm9yICR7ZW50aXR5LmlkfS4ke3Byb3AubmFtZX0gKHR5cGU6ICR7cHJvcC50eXBlfSkke2VudGl0eUNvbnRleHR9JHtvdGhlckZpZWxkc0NvbnRleHR9XG5cblJlcXVpcmVtZW50OiAke2hpbnR9XG5cblJ1bGVzOlxuLSBSZXR1cm4gT05MWSB0aGUgdmFsdWUsIG5vIGV4cGxhbmF0aW9uIG9yIG1hcmtkb3duXG4tIFVzZSAke2xhbmd1YWdlfSBsYW5ndWFnZSBpZiBhcHBsaWNhYmxlXG4tIEZvcm1hdDogJHt0aGlzLmdldEV4cGVjdGVkRm9ybWF0KHByb3AudHlwZSl9YDtcblxuICAgIC8vIGVudW0g7YOA7J6F7J24IOqyveyasCDqsIDriqXtlZwg6rCSIOuqqeuhnSDstpTqsIBcbiAgICBpZiAocHJvcC50eXBlID09PSBcImVudW1cIiB8fCBwcm9wLnR5cGUgPT09IFwiZW51bVtdXCIpIHtcbiAgICAgIGxldCBlbnVtVmFsdWVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBpZiAoXCJlbnVtXCIgaW4gcHJvcCAmJiBBcnJheS5pc0FycmF5KHByb3AuZW51bSkgJiYgcHJvcC5lbnVtLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZW51bVZhbHVlcyA9IHByb3AuZW51bTtcbiAgICAgIH0gZWxzZSBpZiAoXCJpZFwiIGluIHByb3AgJiYgcHJvcC5pZCAmJiBlbnRpdHk/LmVudW1MYWJlbHM/Lltwcm9wLmlkXSkge1xuICAgICAgICBlbnVtVmFsdWVzID0gT2JqZWN0LmtleXMoZW50aXR5LmVudW1MYWJlbHNbcHJvcC5pZF0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZW51bVZhbHVlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHByb21wdCArPSBgXFxuLSBJTVBPUlRBTlQ6IENob29zZSBPTkxZIGZyb20gdGhlc2UgYWxsb3dlZCB2YWx1ZXM6ICR7ZW51bVZhbHVlcy5qb2luKFwiLCBcIil9YDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcm9tcHQgKz0gYFxcblxcbkV4YW1wbGU6ICR7dGhpcy5nZXRFeGFtcGxlRm9yVHlwZShwcm9wLnR5cGUsIGxvY2FsZSl9YDtcblxuICAgIHJldHVybiBwcm9tcHQ7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlTExNUmVzcG9uc2UodGV4dDogc3RyaW5nLCBwcm9wVHlwZTogc3RyaW5nKTogdW5rbm93biB7XG4gICAgY29uc3QgY2xlYW5lZCA9IHRleHQudHJpbSgpO1xuXG4gICAgLy8g67Cw7Je0IO2DgOyehSDsspjrpqxcbiAgICBpZiAocHJvcFR5cGUuZW5kc1dpdGgoXCJbXVwiKSkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZShjbGVhbmVkKTtcbiAgICAgICAgY29uc3QgYmFzZVR5cGUgPSBwcm9wVHlwZS5zbGljZSgwLCAtMik7IC8vIFwiaW50ZWdlcltdXCIgLT4gXCJpbnRlZ2VyXCJcblxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShwYXJzZWQpKSB7XG4gICAgICAgICAgcmV0dXJuIHBhcnNlZC5tYXAoKGl0ZW0pID0+IHtcbiAgICAgICAgICAgIC8vIG51bGwvdW5kZWZpbmVk64qUIO2DgOyeheuzhCDquLDrs7jqsJLsnLzroZxcbiAgICAgICAgICAgIGlmIChpdGVtID09PSBudWxsIHx8IGl0ZW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXREZWZhdWx0VmFsdWVGb3JUeXBlKGJhc2VUeXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIOqwneyytOuKlCBKU09OLnN0cmluZ2lmeSDtm4Qg7YyM7IuxIChqc29uIO2DgOyeheyduCDqsr3smrApXG4gICAgICAgICAgICBpZiAodHlwZW9mIGl0ZW0gPT09IFwib2JqZWN0XCIpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGJhc2VUeXBlID09PSBcImpzb25cIlxuICAgICAgICAgICAgICAgID8gaXRlbVxuICAgICAgICAgICAgICAgIDogdGhpcy5wYXJzZVNjYWxhclZhbHVlKEpTT04uc3RyaW5naWZ5KGl0ZW0pLCBiYXNlVHlwZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBwcmltaXRpdmUg6rCS7J2AIOusuOyekOyXtOuhnCDrs4DtmZgg7ZuEIO2MjOyLsVxuICAgICAgICAgICAgcmV0dXJuIHRoaXMucGFyc2VTY2FsYXJWYWx1ZShTdHJpbmcoaXRlbSksIGJhc2VUeXBlKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOuLqOydvCDqsJLsnbQg7JioIOqyveyasCDrsLDsl7TroZwg6rCQ7Iu46riwXG4gICAgICAgIGlmIChwYXJzZWQgPT09IG51bGwgfHwgcGFyc2VkID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXR1cm4gW3RoaXMuZ2V0RGVmYXVsdFZhbHVlRm9yVHlwZShiYXNlVHlwZSldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbdGhpcy5wYXJzZVNjYWxhclZhbHVlKFN0cmluZyhwYXJzZWQpLCBiYXNlVHlwZSldO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5wYXJzZVNjYWxhclZhbHVlKGNsZWFuZWQsIHByb3BUeXBlKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RGVmYXVsdFZhbHVlRm9yVHlwZShwcm9wVHlwZTogc3RyaW5nKTogdW5rbm93biB7XG4gICAgc3dpdGNoIChwcm9wVHlwZSkge1xuICAgICAgY2FzZSBcImludGVnZXJcIjpcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICBjYXNlIFwiYmlnSW50ZWdlclwiOlxuICAgICAgICByZXR1cm4gMG47XG4gICAgICBjYXNlIFwiZmxvYXRcIjpcbiAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgIGNhc2UgXCJudW1lcmljXCI6XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgY2FzZSBcImRhdGVcIjpcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKCk7XG4gICAgICBjYXNlIFwianNvblwiOlxuICAgICAgICByZXR1cm4ge307XG4gICAgICBjYXNlIFwidXVpZFwiOlxuICAgICAgICByZXR1cm4gXCIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIjtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBcIlwiO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VTY2FsYXJWYWx1ZSh0ZXh0OiBzdHJpbmcsIHByb3BUeXBlOiBzdHJpbmcpOiB1bmtub3duIHtcbiAgICBjb25zdCBjbGVhbmVkID0gdGV4dC50cmltKCk7XG5cbiAgICBzd2l0Y2ggKHByb3BUeXBlKSB7XG4gICAgICBjYXNlIFwiaW50ZWdlclwiOiB7XG4gICAgICAgIGNvbnN0IG51bSA9IHBhcnNlSW50KGNsZWFuZWQsIDEwKTtcbiAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihudW0pID8gMCA6IG51bTtcbiAgICAgIH1cbiAgICAgIGNhc2UgXCJiaWdJbnRlZ2VyXCI6IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gQmlnSW50KGNsZWFuZWQpO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICByZXR1cm4gMG47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNhc2UgXCJmbG9hdFwiOlxuICAgICAgY2FzZSBcIm51bWJlclwiOlxuICAgICAgY2FzZSBcIm51bWVyaWNcIjoge1xuICAgICAgICBjb25zdCBudW0gPSBwYXJzZUZsb2F0KGNsZWFuZWQpO1xuICAgICAgICByZXR1cm4gTnVtYmVyLmlzTmFOKG51bSkgPyAwIDogbnVtO1xuICAgICAgfVxuICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgICAgcmV0dXJuIGNsZWFuZWQudG9Mb3dlckNhc2UoKSA9PT0gXCJ0cnVlXCI7XG4gICAgICBjYXNlIFwiZGF0ZVwiOiB7XG4gICAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZShjbGVhbmVkKTtcbiAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihkYXRlLmdldFRpbWUoKSkgPyBuZXcgRGF0ZSgpIDogZGF0ZTtcbiAgICAgIH1cbiAgICAgIGNhc2UgXCJqc29uXCI6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIEpTT04ucGFyc2UoY2xlYW5lZCk7XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIHJldHVybiBjbGVhbmVkO1xuICAgICAgICB9XG4gICAgICBjYXNlIFwidXVpZFwiOlxuICAgICAgY2FzZSBcImVudW1cIjpcbiAgICAgICAgcmV0dXJuIGNsZWFuZWQ7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gY2xlYW5lZDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogZmFrZXIg7ZWo7IiYIOyduOyekCDrrLjsnpDsl7TsnYQg7YyM7Iux7ZWY7JesIOyduOyekCDrsLDsl7TroZwg67CY7ZmY7ZWp64uI64ukLlxuICAgKlxuICAgKiAz64uo6rOEIOyghOuetTpcbiAgICogMS4gSlNPTiDsp4HsoJEg7YyM7IuxICjtkZzspIAgSlNPTiDtkZztmITsi50pXG4gICAqIDIuIEpTIOqwneyytCDrpqzthLDrn7Qg4oaSIEpTT04g67OA7ZmYIO2bhCDsnqzsi5zrj4QgKHNpbmdsZSBxdW90ZSwgdW5xdW90ZWQga2V5IOyymOumrClcbiAgICogMy4g64uo7IicIOuLqOydvCDsnbjsnpAg7Y+067CxICjsiKvsnpAsIOusuOyekOyXtClcbiAgICovXG4gIHByaXZhdGUgcGFyc2VHZW5lcmF0b3JBcmdzKGFyZ3NTdHI6IHN0cmluZywgcHJvcE5hbWU6IHN0cmluZyk6IHVua25vd25bXSB7XG4gICAgLy8gMS4gSlNPTiDsp4HsoJEg7YyM7IuxXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoYFske2FyZ3NTdHJ9XWApIGFzIHVua25vd247XG4gICAgICByZXR1cm4gQXJyYXkuaXNBcnJheShwYXJzZWQpID8gcGFyc2VkIDogW3BhcnNlZF07XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyDqs4Tsho1cbiAgICB9XG5cbiAgICAvLyAyLiBKUyDqsJ3ssrQg66as7YSw65+0IOKGkiBKU09OIOuzgO2ZmCDtm4Qg7J6s7Iuc64+EXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGpzb25TdHIgPSB0aGlzLmNvbnZlcnRKc0xpdGVyYWxUb0pzb24oYXJnc1N0cik7XG4gICAgICBjb25zdCBwYXJzZWQgPSBKU09OLnBhcnNlKGBbJHtqc29uU3RyfV1gKSBhcyB1bmtub3duO1xuICAgICAgcmV0dXJuIEFycmF5LmlzQXJyYXkocGFyc2VkKSA/IHBhcnNlZCA6IFtwYXJzZWRdO1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8g6rOE7IaNXG4gICAgfVxuXG4gICAgLy8gMy4g64uo7IicIOuLqOydvCDsnbjsnpAg7Y+067CxXG4gICAgY29uc3QgdHJpbW1lZCA9IGFyZ3NTdHIudHJpbSgpO1xuICAgIGlmICghTnVtYmVyLmlzTmFOKE51bWJlcih0cmltbWVkKSkpIHtcbiAgICAgIHJldHVybiBbTnVtYmVyKHRyaW1tZWQpXTtcbiAgICB9XG4gICAgaWYgKFxuICAgICAgKHRyaW1tZWQuc3RhcnRzV2l0aCgnXCInKSAmJiB0cmltbWVkLmVuZHNXaXRoKCdcIicpKSB8fFxuICAgICAgKHRyaW1tZWQuc3RhcnRzV2l0aChcIidcIikgJiYgdHJpbW1lZC5lbmRzV2l0aChcIidcIikpXG4gICAgKSB7XG4gICAgICByZXR1cm4gW3RyaW1tZWQuc2xpY2UoMSwgLTEpXTtcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoYEZpeHR1cmVHZW5lcmF0b3I6IENhbm5vdCBwYXJzZSBhcmd1bWVudHMgZm9yICR7cHJvcE5hbWV9OiAke2FyZ3NTdHJ9YCk7XG4gIH1cblxuICAvKipcbiAgICogSlMg6rCd7LK0IOumrO2EsOuftOydhCBKU09O7Jy866GcIOuzgO2ZmO2VqeuLiOuLpC5cbiAgICpcbiAgICog65GQIOqwgOyngCDrs4DtmZg6XG4gICAqIDEuIFNpbmdsZS1xdW90ZWQg66y47J6Q7Je0IOKGkiBkb3VibGUtcXVvdGVkICjsnbTsiqTsvIDsnbTtlIQg7LKY66asIO2PrO2VqClcbiAgICogMi4gVW5xdW90ZWQg6rCd7LK0IO2CpCDihpIgZG91YmxlLXF1b3RlZFxuICAgKi9cbiAgcHJpdmF0ZSBjb252ZXJ0SnNMaXRlcmFsVG9Kc29uKGlucHV0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIC8vIDEuICd2YWx1ZScg4oaSIFwidmFsdWVcIiAo64K067aAIFwiIOydtOyKpOy8gOydtO2UhCwgXFwnIOKGkiAnKVxuICAgIGNvbnN0IHdpdGhEb3VibGVRdW90ZXMgPSBpbnB1dC5yZXBsYWNlKFxuICAgICAgLycoW14nXFxcXF0qKD86XFxcXC5bXidcXFxcXSopKiknL2csXG4gICAgICAoXywgY29udGVudDogc3RyaW5nKSA9PiBgXCIke2NvbnRlbnQucmVwbGFjZSgvXCIvZywgJ1xcXFxcIicpLnJlcGxhY2UoL1xcXFwnL2csIFwiJ1wiKX1cImAsXG4gICAgKTtcblxuICAgIC8vIDIuIHsga2V5OiDihpIgeyBcImtleVwiOlxuICAgIHJldHVybiB3aXRoRG91YmxlUXVvdGVzLnJlcGxhY2UoLyhbeyxdXFxzKikoW2EtekEtWl8kXVtcXHckXSopKFxccyo6KS9nLCAnJDFcIiQyXCIkMycpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNvbmFtdS5zZWNyZXTsnYQg7Jqw7ISg7Jy866GcIO2VmOqzoCwg7JeG7Jy866m0IO2ZmOqyveuzgOyImOyXkOyEnCBBUEkg7YKk66W8IOydveyKteuLiOuLpC5cbiAgICpcbiAgICogU29uYW11LnNlY3JldOydgCDtlITroZzsoJ3tirjrs4Qg7ISk7KCVKHNvbmFtdS5jb25maWcudHMp7J2066+A66GcIOuNlCDrhpLsnYAg7Jqw7ISg7Iic7JyE66W8IOqwgOyngOupsCxcbiAgICog7ZmY6rK967OA7IiY64qUIOqwnOuwnCDtmZjqsr3snbTrgpggQ0kvQ0Tsl5DshJwgZmFsbGJhY2vsnLzroZwg7IKs7Jqp65Cp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRBcGlLZXkoKTogc3RyaW5nIHtcbiAgICBsZXQgYXBpS2V5OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBTb25hbXUgfSA9IHJlcXVpcmUoXCIuLi9hcGlcIik7XG4gICAgICBhcGlLZXkgPSBTb25hbXUuc2VjcmV0cz8uYW50aHJvcGljX2FwaV9rZXk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBTb25hbXXqsIAg7LSI6riw7ZmU65CY7KeAIOyViuydgCDqsr3smrAgKO2FjOyKpO2KuCDtmZjqsr0g65OxKVxuICAgIH1cblxuICAgIGlmICghYXBpS2V5KSB7XG4gICAgICBhcGlLZXkgPSBwcm9jZXNzLmVudi5BTlRIUk9QSUNfQVBJX0tFWTtcbiAgICB9XG5cbiAgICBpZiAoIWFwaUtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIkFOVEhST1BJQ19BUElfS0VZIG5vdCBmb3VuZC4gU2V0IGl0IGluIGVudmlyb25tZW50IHZhcmlhYmxlcyBvciBTb25hbXUuc2VjcmV0LmFudGhyb3BpY19hcGlfa2V5XCIsXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBhcGlLZXk7XG4gIH1cblxuICBwcml2YXRlIGdldEV4cGVjdGVkRm9ybWF0KHByb3BUeXBlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIC8vIOuwsOyXtCDtg4DsnoUg7LKY66asXG4gICAgaWYgKHByb3BUeXBlLmVuZHNXaXRoKFwiW11cIikpIHtcbiAgICAgIGNvbnN0IGJhc2VUeXBlID0gcHJvcFR5cGUuc2xpY2UoMCwgLTIpO1xuICAgICAgY29uc3QgYmFzZUZvcm1hdCA9IHRoaXMuZ2V0U2NhbGFyRm9ybWF0KGJhc2VUeXBlKTtcbiAgICAgIHJldHVybiBgSlNPTiBhcnJheSBvZiAke2Jhc2VGb3JtYXR9IChlLmcuLCBbJHt0aGlzLmdldEV4YW1wbGVGb3JUeXBlKGJhc2VUeXBlLCBcImVuXCIpfSwgLi4uXSlgO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmdldFNjYWxhckZvcm1hdChwcm9wVHlwZSk7XG4gIH1cblxuICBwcml2YXRlIGdldFNjYWxhckZvcm1hdChwcm9wVHlwZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBzd2l0Y2ggKHByb3BUeXBlKSB7XG4gICAgICBjYXNlIFwiaW50ZWdlclwiOlxuICAgICAgY2FzZSBcImJpZ0ludGVnZXJcIjpcbiAgICAgICAgcmV0dXJuIFwiaW50ZWdlciBudW1iZXJzXCI7XG4gICAgICBjYXNlIFwiZmxvYXRcIjpcbiAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgIGNhc2UgXCJudW1lcmljXCI6XG4gICAgICAgIHJldHVybiBcImRlY2ltYWwgbnVtYmVyc1wiO1xuICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgICAgcmV0dXJuIFwiYm9vbGVhbnMgKHRydWUgb3IgZmFsc2UpXCI7XG4gICAgICBjYXNlIFwiZGF0ZVwiOlxuICAgICAgICByZXR1cm4gXCJJU08gODYwMSBkYXRlIHN0cmluZ3NcIjtcbiAgICAgIGNhc2UgXCJqc29uXCI6XG4gICAgICAgIHJldHVybiBcInZhbGlkIEpTT04gb2JqZWN0IG9yIGFycmF5XCI7XG4gICAgICBjYXNlIFwidXVpZFwiOlxuICAgICAgICByZXR1cm4gXCJVVUlEIHN0cmluZ3NcIjtcbiAgICAgIGNhc2UgXCJlbnVtXCI6XG4gICAgICAgIHJldHVybiBcIm9uZSBvZiB0aGUgYWxsb3dlZCBlbnVtIHZhbHVlc1wiO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIFwicGxhaW4gdGV4dCBzdHJpbmdzXCI7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRFeGFtcGxlRm9yVHlwZShwcm9wVHlwZTogc3RyaW5nLCBsb2NhbGU6IExvY2FsZSk6IHN0cmluZyB7XG4gICAgLy8g67Cw7Je0IO2DgOyehSDsspjrpqxcbiAgICBpZiAocHJvcFR5cGUuZW5kc1dpdGgoXCJbXVwiKSkge1xuICAgICAgY29uc3QgYmFzZVR5cGUgPSBwcm9wVHlwZS5zbGljZSgwLCAtMik7XG4gICAgICBjb25zdCBiYXNlRXhhbXBsZSA9IHRoaXMuZ2V0U2NhbGFyRXhhbXBsZShiYXNlVHlwZSwgbG9jYWxlKTtcbiAgICAgIHJldHVybiBgWyR7YmFzZUV4YW1wbGV9XWA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZ2V0U2NhbGFyRXhhbXBsZShwcm9wVHlwZSwgbG9jYWxlKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U2NhbGFyRXhhbXBsZShwcm9wVHlwZTogc3RyaW5nLCBsb2NhbGU6IExvY2FsZSk6IHN0cmluZyB7XG4gICAgY29uc3QgaXNLb3JlYW4gPSBsb2NhbGUgPT09IFwia29cIjtcblxuICAgIHN3aXRjaCAocHJvcFR5cGUpIHtcbiAgICAgIGNhc2UgXCJpbnRlZ2VyXCI6XG4gICAgICBjYXNlIFwiYmlnSW50ZWdlclwiOlxuICAgICAgICByZXR1cm4gXCI0MlwiO1xuICAgICAgY2FzZSBcImZsb2F0XCI6XG4gICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICBjYXNlIFwibnVtZXJpY1wiOlxuICAgICAgICByZXR1cm4gXCIzLjE0XCI7XG4gICAgICBjYXNlIFwiYm9vbGVhblwiOlxuICAgICAgICByZXR1cm4gXCJ0cnVlXCI7XG4gICAgICBjYXNlIFwiZGF0ZVwiOlxuICAgICAgICByZXR1cm4gXCIyMDI0LTAxLTAxXCI7XG4gICAgICBjYXNlIFwianNvblwiOlxuICAgICAgICByZXR1cm4gJ3tcImtleVwiOiBcInZhbHVlXCJ9JztcbiAgICAgIGNhc2UgXCJ1dWlkXCI6XG4gICAgICAgIHJldHVybiBcIjU1MGU4NDAwLWUyOWItNDFkNC1hNzE2LTQ0NjY1NTQ0MDAwMFwiO1xuICAgICAgY2FzZSBcImVudW1cIjpcbiAgICAgICAgcmV0dXJuIFwiRU5VTV9WQUxVRVwiO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGlzS29yZWFuID8gXCLslYjrhZXtlZjshLjsmpRcIiA6IFwiSGVsbG9cIjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog7J2066aE7J2EIOydtOuplOydvCDroZzsu6wg7YyM7Yq47JqpIOuhnOuniOuCmOydtOymiOuTnCDrrLjsnpDsl7TroZwg67OA7ZmY7ZWp64uI64ukLlxuICAgKlxuICAgKiDtlZzquIAg7J2066aE7J2AIOy0iOyEsS3spJHshLEt7KKF7ISxIOu2hO2VtCDtm4Qg66Gc66eI64KY7J207KaIIOyymOumrO2VqeuLiOuLpC5cbiAgICog7JiB66y4IOydtOumhOydgCDshozrrLjsnpDroZwg67OA7ZmY7ZWY6rOgIOqzteuwseydhCDsoJAoLilcXHVjNzNj66GcIOy5mO2ZmO2VqeuLiOuLpC5cbiAgICog7JiIOiBcIuq5gOyyoOyImFwiIOKGkiBcImNoZW9sc3Uua2ltXCIsIFwiSm9obiBEb2VcIiDihpIgXCJqb2huLmRvZVwiXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJvbWFuaXplTmFtZShuYW1lOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIC8vIO2VnOq4gCDtj6ztlagg7Jes67aAIO2ZleyduFxuICAgIGlmICgvW1xcdUFDMDAtXFx1RDdBRl0vLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiB0aGlzLnJvbWFuaXplS29yZWFuTmFtZShuYW1lKTtcbiAgICB9XG4gICAgLy8g7JiB66y4OiDshozrrLjsnpAgKyDsoJAg6rWs67aEXG4gICAgcmV0dXJuIG5hbWVcbiAgICAgIC50b0xvd2VyQ2FzZSgpXG4gICAgICAucmVwbGFjZSgvXFxzKy9nLCBcIi5cIilcbiAgICAgIC5yZXBsYWNlKC9bXmEtejAtOS5dL2csIFwiXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VnOq4gCDsnbTrpoTsnYQg66Gc66eI64KY7J207KaIIOyymOumrO2VqeuLiOuLpC5cbiAgICpcbiAgICog7LSI7ISxL+ykkeyEsS/sooXshLEg66ek7ZWRIO2FjOydtOu4lOydhCDsgqzsmqntlZjsl6wg7ZWc6riA7J2EIOuhnOuniOyekOuhnCDrs4DtmZjtlanri4jri6QuXG4gICAqIOyyqyDquIDsnpDrpbwg7ISx7Jy866GcIOqwhOyjvO2VmOyXrCBcIuq5gOyyoOyImFwiIOKGkiBcImNoZW9sc3Uua2ltXCIg7ZiV7YOc66GcIOy2nOugpe2VqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgcm9tYW5pemVLb3JlYW5OYW1lKG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgQ0hPU0VPTkcgPSBbXG4gICAgICBcImdcIixcbiAgICAgIFwia2tcIixcbiAgICAgIFwiblwiLFxuICAgICAgXCJkXCIsXG4gICAgICBcInR0XCIsXG4gICAgICBcInJcIixcbiAgICAgIFwibVwiLFxuICAgICAgXCJiXCIsXG4gICAgICBcInBwXCIsXG4gICAgICBcInNcIixcbiAgICAgIFwic3NcIixcbiAgICAgIFwiXCIsXG4gICAgICBcImpcIixcbiAgICAgIFwiampcIixcbiAgICAgIFwiY2hcIixcbiAgICAgIFwia1wiLFxuICAgICAgXCJ0XCIsXG4gICAgICBcInBcIixcbiAgICAgIFwiaFwiLFxuICAgIF07XG4gICAgY29uc3QgSlVOR1NFT05HID0gW1xuICAgICAgXCJhXCIsXG4gICAgICBcImFlXCIsXG4gICAgICBcInlhXCIsXG4gICAgICBcInlhZVwiLFxuICAgICAgXCJlb1wiLFxuICAgICAgXCJlXCIsXG4gICAgICBcInllb1wiLFxuICAgICAgXCJ5ZVwiLFxuICAgICAgXCJvXCIsXG4gICAgICBcIndhXCIsXG4gICAgICBcIndhZVwiLFxuICAgICAgXCJvZVwiLFxuICAgICAgXCJ5b1wiLFxuICAgICAgXCJ1XCIsXG4gICAgICBcIndvXCIsXG4gICAgICBcIndlXCIsXG4gICAgICBcIndpXCIsXG4gICAgICBcInl1XCIsXG4gICAgICBcImV1XCIsXG4gICAgICBcInVpXCIsXG4gICAgICBcImlcIixcbiAgICBdO1xuICAgIGNvbnN0IEpPTkdTRU9ORyA9IFtcbiAgICAgIFwiXCIsXG4gICAgICBcImtcIixcbiAgICAgIFwia1wiLFxuICAgICAgXCJrXCIsXG4gICAgICBcIm5cIixcbiAgICAgIFwiblwiLFxuICAgICAgXCJuXCIsXG4gICAgICBcInRcIixcbiAgICAgIFwibFwiLFxuICAgICAgXCJsXCIsXG4gICAgICBcImxcIixcbiAgICAgIFwibFwiLFxuICAgICAgXCJsXCIsXG4gICAgICBcImxcIixcbiAgICAgIFwibFwiLFxuICAgICAgXCJsXCIsXG4gICAgICBcIm1cIixcbiAgICAgIFwicFwiLFxuICAgICAgXCJwXCIsXG4gICAgICBcInRcIixcbiAgICAgIFwidFwiLFxuICAgICAgXCJuZ1wiLFxuICAgICAgXCJ0XCIsXG4gICAgICBcInRcIixcbiAgICAgIFwia1wiLFxuICAgICAgXCJ0XCIsXG4gICAgICBcInBcIixcbiAgICAgIFwidFwiLFxuICAgIF07XG5cbiAgICBjb25zdCByb21hbml6ZSA9IChjaGFyOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgICAgY29uc3QgY29kZSA9IGNoYXIuY2hhckNvZGVBdCgwKTtcbiAgICAgIGlmIChjb2RlIDwgMHhhYzAwIHx8IGNvZGUgPiAweGQ3YWYpIHJldHVybiBjaGFyO1xuICAgICAgY29uc3Qgb2Zmc2V0ID0gY29kZSAtIDB4YWMwMDtcbiAgICAgIGNvbnN0IGNobyA9IE1hdGguZmxvb3Iob2Zmc2V0IC8gNTg4KTtcbiAgICAgIGNvbnN0IGp1bmcgPSBNYXRoLmZsb29yKChvZmZzZXQgJSA1ODgpIC8gMjgpO1xuICAgICAgY29uc3Qgam9uZyA9IG9mZnNldCAlIDI4O1xuICAgICAgcmV0dXJuIENIT1NFT05HW2Nob10gKyBKVU5HU0VPTkdbanVuZ10gKyBKT05HU0VPTkdbam9uZ107XG4gICAgfTtcblxuICAgIGNvbnN0IGNoYXJzID0gWy4uLm5hbWVdO1xuICAgIC8vIOyyqyDquIDsnpDrpbwg7ISxKOWnkynsnLzroZwg6rCE7KO8XG4gICAgY29uc3QgZmFtaWx5TmFtZSA9IHJvbWFuaXplKGNoYXJzWzBdKTtcbiAgICBjb25zdCBnaXZlbk5hbWUgPSBjaGFycy5zbGljZSgxKS5tYXAocm9tYW5pemUpLmpvaW4oXCJcIik7XG5cbiAgICBpZiAoZ2l2ZW5OYW1lKSB7XG4gICAgICByZXR1cm4gYCR7Z2l2ZW5OYW1lfS4ke2ZhbWlseU5hbWV9YDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbWlseU5hbWU7XG4gIH1cblxuICAvKipcbiAgICogTExNIOy6kOyLnCDthrXqs4Trpbwg67CY7ZmY7ZWp64uI64ukLlxuICAgKi9cbiAgZ2V0TExNQ2FjaGVTdGF0cygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2l6ZTogdGhpcy5sbG1DYWNoZS5zaXplLFxuICAgICAgZW5hYmxlZDogdGhpcy5vcHRpb25zLmVuYWJsZUxMTUNhY2hlLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogTExNIOy6kOyLnOulvCDstIjquLDtmZTtlanri4jri6QuXG4gICAqL1xuICBjbGVhckxMTUNhY2hlKCkge1xuICAgIHRoaXMubGxtQ2FjaGUuY2xlYXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDsu6jthY3siqTtirgg7IOd7ISxXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZUNvbnRleHQoKTogR2VuZXJhdG9yQ29udGV4dCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGZpeHR1cmVzOiBuZXcgTWFwKCksXG4gICAgICByZWZlcmVuY2VDYWNoZTogbmV3IE1hcCgpLFxuICAgICAgaW1wb3J0ZWRSZWNvcmRzOiBuZXcgU2V0KCksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrsLDsuZgg7IOd7ISxIOuwjyDsnpDrj5kg7KCA7J6lXG4gICAqXG4gICAqIDEuIOqwgSBzcGVj67OE66GcIGZpeHR1cmUg7IOd7ISxICjrqZTrqqjrpqwpXG4gICAqIDIuIEZpeHR1cmVSZWNvcmTroZwg67OA7ZmYXG4gICAqIDMuIEZpeHR1cmVNYW5hZ2VyLmluc2VydEZpeHR1cmVzKCnroZwgdGFyZ2V0RGLsl5Ag7KCA7J6lXG4gICAqXG4gICAqIEByZXR1cm5zIOyggOyepeuQnCBmaXh0dXJlIOuNsOydtO2EsCAo7Iuk7KCcIERCIElEIO2PrO2VqClcbiAgICovXG4gIGFzeW5jIGdlbmVyYXRlQmF0Y2goXG4gICAgc3BlY3M6IEFycmF5PHsgZW50aXR5OiBzdHJpbmc7IGNvdW50OiBudW1iZXI7IG92ZXJyaWRlcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+IH0+LFxuICApOiBQcm9taXNlPEZpeHR1cmVJbXBvcnRSZXN1bHRbXT4ge1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmNyZWF0ZUNvbnRleHQoKTtcbiAgICBjb25zdCBnZW5lcmF0ZWRGaXh0dXJlczogQXJyYXk8e1xuICAgICAgZW50aXR5OiBzdHJpbmc7XG4gICAgICBkYXRhOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgIGV4cGxpY2l0SWQ/OiBib29sZWFuO1xuICAgIH0+ID0gW107XG5cbiAgICAvLyAxLiDqsIEgc3BlY+uzhOuhnCBmaXh0dXJlIOyDneyEsVxuICAgIGZvciAoY29uc3Qgc3BlYyBvZiBzcGVjcykge1xuICAgICAgY29uc3Qgc3BlY0VudGl0eSA9IHRoaXMuZW50aXR5TWFuYWdlci5nZXQoc3BlYy5lbnRpdHkpO1xuXG4gICAgICBpZiAoc3BlY0VudGl0eS5wYXJlbnRJZCkge1xuICAgICAgICAvLyBwYXJlbnRJZCDsl5Tti7Dti7A6IERC7JeQ7IScIOyEnOu4jO2DgOyehSDtlonsnbQg7JeG64qUIOu2gOuqqCBpZOulvCDsobDtmoztlZjsl6wg7IKs7JqpXG4gICAgICAgIC8vICjsg4gg67aA66qoIOyDneyEsSDrjIDsi6Ag6riw7KG0IOuNsOydtO2EsCDsnqztmZzsmqkpXG4gICAgICAgIGNvbnN0IGlkUHJvcCA9IHNwZWNFbnRpdHkucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBcImlkXCIpO1xuICAgICAgICBjb25zdCBwYXJlbnRPdmVycmlkZXMgPSBpZFByb3A/LmNvbmU/LmZpeHR1cmVQYXJlbnRPdmVycmlkZXMgPz8ge307XG4gICAgICAgIGNvbnN0IHBhcmVudEVudGl0eSA9IHRoaXMuZW50aXR5TWFuYWdlci5nZXQoc3BlY0VudGl0eS5wYXJlbnRJZCk7XG5cbiAgICAgICAgLy8g67aA66qoIO2FjOydtOu4lOyXkOyEnCDshJzruIztg4DsnoUg7YWM7J2067iU7JeQIOyXhuuKlCBpZOulvCDsobDtmoxcbiAgICAgICAgbGV0IHF1ZXJ5ID0gdGhpcy5zb3VyY2VEYihwYXJlbnRFbnRpdHkudGFibGUpLnNlbGVjdChgJHtwYXJlbnRFbnRpdHkudGFibGV9LmlkYCk7XG4gICAgICAgIGZvciAoY29uc3QgW2NvbCwgdmFsXSBvZiBPYmplY3QuZW50cmllcyhwYXJlbnRPdmVycmlkZXMpKSB7XG4gICAgICAgICAgcXVlcnkgPSBxdWVyeS53aGVyZShcbiAgICAgICAgICAgIGAke3BhcmVudEVudGl0eS50YWJsZX0uJHtjb2x9YCxcbiAgICAgICAgICAgIHZhbCBhcyBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgbnVsbCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHF1ZXJ5ID0gcXVlcnlcbiAgICAgICAgICAubGVmdEpvaW4oc3BlY0VudGl0eS50YWJsZSwgYCR7c3BlY0VudGl0eS50YWJsZX0uaWRgLCBgJHtwYXJlbnRFbnRpdHkudGFibGV9LmlkYClcbiAgICAgICAgICAud2hlcmVOdWxsKGAke3NwZWNFbnRpdHkudGFibGV9LmlkYClcbiAgICAgICAgICAubGltaXQoc3BlYy5jb3VudCk7XG5cbiAgICAgICAgY29uc3Qgcm93cyA9IGF3YWl0IHF1ZXJ5O1xuICAgICAgICBjb25zdCBhdmFpbGFibGVJZHM6IG51bWJlcltdID0gcm93cy5tYXAoKHI6IHsgaWQ6IG51bWJlciB9KSA9PiByLmlkKTtcblxuICAgICAgICBpZiAoYXZhaWxhYmxlSWRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICFpc1Rlc3QoKSAmJlxuICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICBjaGFsay55ZWxsb3coXG4gICAgICAgICAgICAgICAgYFtwYXJlbnRJZF0gJHtzcGVjLmVudGl0eX06IOyEnOu4jO2DgOyeheydtCDsl4bripQg67aA66qoIOugiOy9lOuTnOqwgCDrtoDsobHtlanri4jri6QuIOqxtOuEiOucgeuLiOuLpC5gLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmb3IgKGNvbnN0IHBhcmVudElkIG9mIGF2YWlsYWJsZUlkcykge1xuICAgICAgICAgICAgY29uc3QgZml4dHVyZSA9IGF3YWl0IHRoaXMuZ2VuZXJhdGUoc3BlYy5lbnRpdHksIHNwZWMub3ZlcnJpZGVzIHx8IHt9LCBjb250ZXh0KTtcbiAgICAgICAgICAgIGZpeHR1cmUuaWQgPSBwYXJlbnRJZDtcbiAgICAgICAgICAgIGdlbmVyYXRlZEZpeHR1cmVzLnB1c2goeyBlbnRpdHk6IHNwZWMuZW50aXR5LCBkYXRhOiBmaXh0dXJlLCBleHBsaWNpdElkOiB0cnVlIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzcGVjLmNvdW50OyBpKyspIHtcbiAgICAgICAgICBjb25zdCBmaXh0dXJlID0gYXdhaXQgdGhpcy5nZW5lcmF0ZShzcGVjLmVudGl0eSwgc3BlYy5vdmVycmlkZXMgfHwge30sIGNvbnRleHQpO1xuICAgICAgICAgIGdlbmVyYXRlZEZpeHR1cmVzLnB1c2goe1xuICAgICAgICAgICAgZW50aXR5OiBzcGVjLmVudGl0eSxcbiAgICAgICAgICAgIGRhdGE6IGZpeHR1cmUsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAyLiBGaXh0dXJlUmVjb3Jk66GcIOuzgO2ZmFxuICAgIGNvbnN0IGZpeHR1cmVSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHsgZW50aXR5OiBlbnRpdHlOYW1lLCBkYXRhLCBleHBsaWNpdElkIH0gb2YgZ2VuZXJhdGVkRml4dHVyZXMpIHtcbiAgICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZW50aXR5TWFuYWdlci5nZXQoZW50aXR5TmFtZSk7XG5cbiAgICAgIC8vIGludGVnZXIvYmlnSW50ZWdlciBQS+uKlCDsnoTsi5wgSUQg7IOd7ISxIChEQiDsi5ztgIDsiqTqsIAg7Iuk7KCcIElEIO2VoOuLuSlcbiAgICAgIC8vIHN0cmluZyBQSyB3aXRoIGRiRGVmYXVsdCBuZXh0dmFs64+EIOuPmeydvO2VmOqyjCDsspjrpqxcbiAgICAgIC8vIOq3uCDsmbggc3RyaW5nL3V1aWQgUEvripQgZ2VuZXJhdGUoKeyXkOyEnCDsnbTrr7gg7IOd7ISx65CcIGlkIOqwkuydhCDqt7jrjIDroZwg7IKs7JqpXG4gICAgICAvLyBwYXJlbnRJZCDsl5Tti7Dti7DripQg67aA66qo7J2YIOyLpOygnCBpZOulvCDqt7jrjIDroZwg7IKs7JqpICjsi5ztgIDsiqQg66+47IKs7JqpKVxuICAgICAgY29uc3QgaWRQcm9wID0gZW50aXR5LnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gXCJpZFwiKTtcbiAgICAgIGNvbnN0IHVzZXNTZXF1ZW5jZSA9XG4gICAgICAgICFleHBsaWNpdElkICYmXG4gICAgICAgIChpZFByb3A/LnR5cGUgPT09IFwiaW50ZWdlclwiIHx8XG4gICAgICAgICAgaWRQcm9wPy50eXBlID09PSBcImJpZ0ludGVnZXJcIiB8fFxuICAgICAgICAgIChpZFByb3A/LnR5cGUgPT09IFwic3RyaW5nXCIgJiZcbiAgICAgICAgICAgIFwiZGJEZWZhdWx0XCIgaW4gKGlkUHJvcCA/PyB7fSkgJiZcbiAgICAgICAgICAgIHR5cGVvZiAoaWRQcm9wIGFzIHsgZGJEZWZhdWx0PzogdW5rbm93biB9KT8uZGJEZWZhdWx0ID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgICAoKGlkUHJvcCBhcyB7IGRiRGVmYXVsdD86IHN0cmluZyB9KT8uZGJEZWZhdWx0ID8/IFwiXCIpLmluY2x1ZGVzKFwibmV4dHZhbFwiKSkpO1xuXG4gICAgICBjb25zdCBkYXRhRm9yUmVjb3JkID0gdXNlc1NlcXVlbmNlXG4gICAgICAgID8geyAuLi5kYXRhLCBpZDogTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTAwMDAwMCkgfVxuICAgICAgICA6IGRhdGE7XG5cbiAgICAgIGNvbnN0IHJlY29yZHMgPSBhd2FpdCBGaXh0dXJlTWFuYWdlci5jcmVhdGVGaXh0dXJlUmVjb3JkKFxuICAgICAgICBlbnRpdHksXG4gICAgICAgIGRhdGFGb3JSZWNvcmQgYXMgeyBpZDogbnVtYmVyIHwgc3RyaW5nOyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgbnVsbCB9LFxuICAgICAgICB7IHNpbmdsZVJlY29yZDogdHJ1ZSB9LFxuICAgICAgKTtcbiAgICAgIGZpeHR1cmVSZWNvcmRzLnB1c2goLi4ucmVjb3Jkcyk7XG4gICAgfVxuXG4gICAgLy8gMy4gdGFyZ2V0RGLsl5Ag7IK97J6FIChGaXh0dXJlTWFuYWdlcuqwgCDsnZjsobTshLEg7KCV66CsIOyymOumrClcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgRml4dHVyZU1hbmFnZXIuaW5zZXJ0Rml4dHVyZXModGhpcy50YXJnZXREYk5hbWUsIGZpeHR1cmVSZWNvcmRzKTtcblxuICAgIC8vIDQuIGNvbXBhbmlvbiBmaXh0dXJlcyDsg53shLEgKGZpeHR1cmVDb21wYW5pb25z6rCAIOyEoOyWuOuQnCDqsr3smrApXG4gICAgY29uc3QgY29tcGFuaW9uUmVzdWx0cyA9IGF3YWl0IHRoaXMuZ2VuZXJhdGVDb21wYW5pb25zKHNwZWNzLCByZXN1bHRzKTtcblxuICAgIGNvbnN0IHRvdGFsID0gcmVzdWx0cy5sZW5ndGggKyBjb21wYW5pb25SZXN1bHRzLmxlbmd0aDtcbiAgICAhaXNUZXN0KCkgJiZcbiAgICAgIGNvbnNvbGUubG9nKGNoYWxrLmdyZWVuKGBHZW5lcmF0ZWQgYW5kIHNhdmVkICR7dG90YWx9IGZpeHR1cmVzIHRvICR7dGhpcy50YXJnZXREYk5hbWV9YCkpO1xuICAgIHJldHVybiBbLi4ucmVzdWx0cywgLi4uY29tcGFuaW9uUmVzdWx0c107XG4gIH1cblxuICAvKipcbiAgICog67aA66qoIGZpeHR1cmUg6rKw6rO866W8IOq4sOuwmOycvOuhnCBmaXh0dXJlQ29tcGFuaW9uc+yXkCDshKDslrjrkJwgY29tcGFuaW9uIEVudGl0eeulvCDsg53shLHtlanri4jri6QuXG4gICAqXG4gICAqIGdlbmVyYXRlQmF0Y2goKeyXkOyEnOunjCDtmLjstpzrkJjrqbAsIGNvbXBhbmlvbiDsg53shLEg7IucIOyerOq3gOulvCDrsKnsp4DtlZjquLAg7JyE7ZW0XG4gICAqIGdlbmVyYXRlQmF0Y2goKeulvCDri6Tsi5wg7Zi47Lac7ZWY7KeAIOyViuqzoCDsp4HsoJEg7IK97J6F7ZWp64uI64ukLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZW5lcmF0ZUNvbXBhbmlvbnMoXG4gICAgc3BlY3M6IEFycmF5PHsgZW50aXR5OiBzdHJpbmc7IGNvdW50OiBudW1iZXI7IG92ZXJyaWRlcz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+IH0+LFxuICAgIHBhcmVudFJlc3VsdHM6IEZpeHR1cmVJbXBvcnRSZXN1bHRbXSxcbiAgKTogUHJvbWlzZTxGaXh0dXJlSW1wb3J0UmVzdWx0W10+IHtcbiAgICBjb25zdCBhbGxSZXN1bHRzOiBGaXh0dXJlSW1wb3J0UmVzdWx0W10gPSBbXTtcbiAgICBjb25zdCBwcm9jZXNzZWRFbnRpdGllcyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgZm9yIChjb25zdCBzcGVjIG9mIHNwZWNzKSB7XG4gICAgICBpZiAocHJvY2Vzc2VkRW50aXRpZXMuaGFzKHNwZWMuZW50aXR5KSkgY29udGludWU7XG4gICAgICBwcm9jZXNzZWRFbnRpdGllcy5hZGQoc3BlYy5lbnRpdHkpO1xuXG4gICAgICBjb25zdCBlbnRpdHkgPSB0aGlzLmVudGl0eU1hbmFnZXIuZ2V0KHNwZWMuZW50aXR5KTtcbiAgICAgIGNvbnN0IGlkUHJvcCA9IGVudGl0eS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IFwiaWRcIik7XG4gICAgICBjb25zdCBjb21wYW5pb25zID0gaWRQcm9wPy5jb25lPy5maXh0dXJlQ29tcGFuaW9ucztcbiAgICAgIGlmICghY29tcGFuaW9ucyB8fCBjb21wYW5pb25zLmxlbmd0aCA9PT0gMCkgY29udGludWU7XG5cbiAgICAgIGNvbnN0IGVudGl0eVJlc3VsdHMgPSBwYXJlbnRSZXN1bHRzLmZpbHRlcigocikgPT4gci5lbnRpdHlJZCA9PT0gc3BlYy5lbnRpdHkpO1xuICAgICAgaWYgKGVudGl0eVJlc3VsdHMubGVuZ3RoID09PSAwKSBjb250aW51ZTtcblxuICAgICAgZm9yIChjb25zdCBjb21wYW5pb24gb2YgY29tcGFuaW9ucykge1xuICAgICAgICAvLyBjb21wYW5pb24gZW50aXR57JeQ7IScIOu2gOuqqCBlbnRpdHnroZzsnZggQmVsb25nc1RvT25lIEZLIOy7rOufvOuqhSDtjIzslYVcbiAgICAgICAgY29uc3QgY29tcGFuaW9uRW50aXR5ID0gdGhpcy5lbnRpdHlNYW5hZ2VyLmdldChjb21wYW5pb24uZW50aXR5KTtcbiAgICAgICAgY29uc3QgZmtQcm9wID0gY29tcGFuaW9uRW50aXR5LnByb3BzLmZpbmQoXG4gICAgICAgICAgKHApID0+IGlzUmVsYXRpb25Qcm9wKHApICYmIGlzQmVsb25nc1RvT25lUmVsYXRpb25Qcm9wKHApICYmIHAud2l0aCA9PT0gc3BlYy5lbnRpdHksXG4gICAgICAgICk7XG4gICAgICAgIGlmICghZmtQcm9wKSB7XG4gICAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgIGNoYWxrLnllbGxvdyhcbiAgICAgICAgICAgICAgICBgW0NvbXBhbmlvbl0gTm8gQmVsb25nc1RvT25lIHJlbGF0aW9uIGZyb20gJHtjb21wYW5pb24uZW50aXR5fSB0byAke3NwZWMuZW50aXR5fS4gU2tpcHBpbmcuYCxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZmtDb2xOYW1lID0gYCR7ZmtQcm9wLm5hbWV9X2lkYDtcblxuICAgICAgICAvLyBjb21wYW5pb27snZggaWRQcm9wLCB1c2VzU2VxdWVuY2UsIGNvdW5064qUIGNvbXBhbmlvbiDri6jsnITroZwg6rOg7KCVXG4gICAgICAgIGNvbnN0IGNvbXBhbmlvbklkUHJvcCA9IGNvbXBhbmlvbkVudGl0eS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IFwiaWRcIik7XG4gICAgICAgIGNvbnN0IHVzZXNTZXF1ZW5jZSA9XG4gICAgICAgICAgY29tcGFuaW9uSWRQcm9wPy50eXBlID09PSBcImludGVnZXJcIiB8fFxuICAgICAgICAgIGNvbXBhbmlvbklkUHJvcD8udHlwZSA9PT0gXCJiaWdJbnRlZ2VyXCIgfHxcbiAgICAgICAgICAoY29tcGFuaW9uSWRQcm9wPy50eXBlID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgICBcImRiRGVmYXVsdFwiIGluIChjb21wYW5pb25JZFByb3AgPz8ge30pICYmXG4gICAgICAgICAgICB0eXBlb2YgKGNvbXBhbmlvbklkUHJvcCBhcyB7IGRiRGVmYXVsdD86IHVua25vd24gfSk/LmRiRGVmYXVsdCA9PT0gXCJzdHJpbmdcIiAmJlxuICAgICAgICAgICAgKChjb21wYW5pb25JZFByb3AgYXMgeyBkYkRlZmF1bHQ/OiBzdHJpbmcgfSk/LmRiRGVmYXVsdCA/PyBcIlwiKS5pbmNsdWRlcyhcIm5leHR2YWxcIikpO1xuICAgICAgICBjb25zdCBjb21wYW5pb25Db3VudCA9IGNvbXBhbmlvbi5jb3VudCA/PyAxO1xuXG4gICAgICAgIC8vIOqwgSBwYXJlbnQgcmVzdWx07JeQIOuMgO2VtCBjb21wYW5pb24gZml4dHVyZSDsg53shLFcbiAgICAgICAgY29uc3QgY29udGV4dCA9IHRoaXMuY3JlYXRlQ29udGV4dCgpO1xuICAgICAgICBjb25zdCBjb21wYW5pb25GaXh0dXJlUmVjb3JkczogRml4dHVyZVJlY29yZFtdID0gW107XG5cbiAgICAgICAgZm9yIChjb25zdCBwYXJlbnRSZXN1bHQgb2YgZW50aXR5UmVzdWx0cykge1xuICAgICAgICAgIGNvbnN0IHJlc29sdmVkT3ZlcnJpZGVzID0gdGhpcy5yZXNvbHZlVGVtcGxhdGVPdmVycmlkZXMoXG4gICAgICAgICAgICBjb21wYW5pb24ub3ZlcnJpZGVzID8/IHt9LFxuICAgICAgICAgICAgcGFyZW50UmVzdWx0LmRhdGEsXG4gICAgICAgICAgKTtcbiAgICAgICAgICByZXNvbHZlZE92ZXJyaWRlc1tma0NvbE5hbWVdID0gcGFyZW50UmVzdWx0LmRhdGEuaWQ7XG5cbiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbXBhbmlvbkNvdW50OyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IGZpeHR1cmUgPSBhd2FpdCB0aGlzLmdlbmVyYXRlKGNvbXBhbmlvbi5lbnRpdHksIHJlc29sdmVkT3ZlcnJpZGVzLCBjb250ZXh0KTtcblxuICAgICAgICAgICAgY29uc3QgZGF0YUZvclJlY29yZCA9IHVzZXNTZXF1ZW5jZVxuICAgICAgICAgICAgICA/IHsgLi4uZml4dHVyZSwgaWQ6IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDEwMDAwMDApIH1cbiAgICAgICAgICAgICAgOiBmaXh0dXJlO1xuXG4gICAgICAgICAgICBjb25zdCByZWNvcmRzID0gYXdhaXQgRml4dHVyZU1hbmFnZXIuY3JlYXRlRml4dHVyZVJlY29yZChcbiAgICAgICAgICAgICAgY29tcGFuaW9uRW50aXR5LFxuICAgICAgICAgICAgICBkYXRhRm9yUmVjb3JkIGFzIHtcbiAgICAgICAgICAgICAgICBpZDogbnVtYmVyIHwgc3RyaW5nO1xuICAgICAgICAgICAgICAgIFtrZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBudWxsO1xuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7IHNpbmdsZVJlY29yZDogdHJ1ZSB9LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbXBhbmlvbkZpeHR1cmVSZWNvcmRzLnB1c2goLi4ucmVjb3Jkcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29tcGFuaW9uUmVzdWx0cyA9IGF3YWl0IEZpeHR1cmVNYW5hZ2VyLmluc2VydEZpeHR1cmVzKFxuICAgICAgICAgIHRoaXMudGFyZ2V0RGJOYW1lLFxuICAgICAgICAgIGNvbXBhbmlvbkZpeHR1cmVSZWNvcmRzLFxuICAgICAgICApO1xuICAgICAgICBhbGxSZXN1bHRzLnB1c2goLi4uY29tcGFuaW9uUmVzdWx0cyk7XG5cbiAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBjaGFsay5ncmVlbihcbiAgICAgICAgICAgICAgYFtDb21wYW5pb25dIEdlbmVyYXRlZCAke2NvbXBhbmlvblJlc3VsdHMubGVuZ3RofSAke2NvbXBhbmlvbi5lbnRpdHl9IGZpeHR1cmVzYCxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYWxsUmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBvdmVycmlkZXMg6rCS7J2YIFwie3tmaWVsZE5hbWV9fVwiIO2FnO2UjOumv+ydhCDrtoDrqqggZml4dHVyZSDrjbDsnbTthLDroZwg7LmY7ZmY7ZWp64uI64ukLlxuICAgKlxuICAgKiDsmIg6IHsgXCJhY2NvdW50X2lkXCI6IFwie3tlbWFpbH19XCIgfSDihpIgeyBcImFjY291bnRfaWRcIjogXCJ1c2VyQGV4YW1wbGUuY29tXCIgfVxuICAgKi9cbiAgcHJpdmF0ZSByZXNvbHZlVGVtcGxhdGVPdmVycmlkZXMoXG4gICAgb3ZlcnJpZGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICBwYXJlbnREYXRhOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBEYXRlIHwgbnVsbCB9LFxuICApOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgY29uc3QgcmVzb2x2ZWQ6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMob3ZlcnJpZGVzKSkge1xuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZS5zdGFydHNXaXRoKFwie3tcIikgJiYgdmFsdWUuZW5kc1dpdGgoXCJ9fVwiKSkge1xuICAgICAgICBjb25zdCBmaWVsZE5hbWUgPSB2YWx1ZS5zbGljZSgyLCAtMikudHJpbSgpO1xuICAgICAgICBpZiAoIShmaWVsZE5hbWUgaW4gcGFyZW50RGF0YSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBg7YWc7ZSM66a/IO2VhOuTnCBcIiR7ZmllbGROYW1lfVwi7J20KOqwgCkg67aA66qoIGZpeHR1cmUg642w7J207YSw7JeQIOyhtOyerO2VmOyngCDslYrsirXri4jri6QgKG92ZXJyaWRlIGtleTogXCIke2tleX1cIilgLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZWRba2V5XSA9IHBhcmVudERhdGFbZmllbGROYW1lXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc29sdmVkW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc29sdmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIOyLpOygnCBEQihzb3VyY2VEYinsl5DshJwg642w7J207YSw66W8IOyhsO2ajO2VmOyXrCBmaXh0dXJlIERCKHRhcmdldERiKeyXkCBpbXBvcnTtlanri4jri6QuXG4gICAqXG4gICAqIDEuIERhdGFFeHBsb3JlcuuhnCBzb3VyY2VEYuyXkOyEnCDrjbDsnbTthLAg7KGw7ZqMICjqtIDroKgg642w7J207YSwIO2PrO2VqClcbiAgICogMi4gRml4dHVyZVJlY29yZOuhnCDrs4DtmZhcbiAgICogMy4gdGFyZ2V0RGLsl5Ag7IK97J6FXG4gICAqXG4gICAqIEBwYXJhbSBlbnRpdHlOYW1lIC0g7KGw7ZqM7ZWgIGVudGl0eSDsnbTrpoRcbiAgICogQHBhcmFtIG9wdGlvbnMgLSDsobDtmowg7Ji17IWYIChzdHJhdGVneSwgbGltaXQsIGluY2x1ZGVSZWxhdGlvbnMg65OxKVxuICAgKiBAcmV0dXJucyDsoIDsnqXrkJwgZml4dHVyZSDrjbDsnbTthLAgKOyLpOygnCBEQiBJRCDtj6ztlagpXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIO2UhOuhnOuNleyFmCBEQuyXkOyEnCBVc2VyIDEw66qFICsg6rSA66CoIEVtcGxveWVlLCBEZXBhcnRtZW50IOqwgOyguOyYpOq4sFxuICAgKiBhd2FpdCBnZW5lcmF0b3IuaW1wb3J0RnJvbVNvdXJjZShcIlVzZXJcIiwge1xuICAgKiAgIHN0cmF0ZWd5OiBcInNhbXBsZVwiLFxuICAgKiAgIGxpbWl0OiAxMCxcbiAgICogICBpbmNsdWRlUmVsYXRpb25zOiB0cnVlLFxuICAgKiAgIG1heERlcHRoOiAyXG4gICAqIH0pO1xuICAgKi9cbiAgYXN5bmMgaW1wb3J0RnJvbVNvdXJjZShcbiAgICBlbnRpdHlOYW1lOiBzdHJpbmcsXG4gICAgb3B0aW9uczogRXhwbG9yZVdpdGhSZWxhdGlvbnNPcHRpb25zLFxuICApOiBQcm9taXNlPEZpeHR1cmVJbXBvcnRSZXN1bHRbXT4ge1xuICAgICFpc1Rlc3QoKSAmJlxuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIGNoYWxrLmJsdWUoXG4gICAgICAgICAgYEltcG9ydGluZyAke2VudGl0eU5hbWV9IGZyb20gc291cmNlIERCIHdpdGggb3B0aW9uczogJHtKU09OLnN0cmluZ2lmeSh7IHN0cmF0ZWd5OiBvcHRpb25zLnN0cmF0ZWd5LCBsaW1pdDogb3B0aW9ucy5saW1pdCwgaW5jbHVkZVJlbGF0aW9uczogb3B0aW9ucy5pbmNsdWRlUmVsYXRpb25zLCBtYXhEZXB0aDogb3B0aW9ucy5tYXhEZXB0aCB9KX1gLFxuICAgICAgICApLFxuICAgICAgKTtcblxuICAgIC8vIDEuIERhdGFFeHBsb3JlcuuhnCBzb3VyY2VEYuyXkOyEnCDrjbDsnbTthLAg7KGw7ZqMICjqtIDroKgg642w7J207YSwIO2PrO2VqClcbiAgICBjb25zdCBleHBsb3JlUmVzdWx0ID0gYXdhaXQgdGhpcy5kYXRhRXhwbG9yZXIuZXhwbG9yZVdpdGhSZWxhdGlvbnMoZW50aXR5TmFtZSwgb3B0aW9ucyk7XG5cbiAgICAhaXNUZXN0KCkgJiZcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBjaGFsay5jeWFuKFxuICAgICAgICAgIGBGb3VuZCAke2V4cGxvcmVSZXN1bHQubWFpbi5yZWNvcmRzLmxlbmd0aH0gJHtlbnRpdHlOYW1lfSByZWNvcmRzIGFuZCAke2V4cGxvcmVSZXN1bHQucmVsYXRlZC5zaXplfSByZWxhdGVkIGVudGl0aWVzYCxcbiAgICAgICAgKSxcbiAgICAgICk7XG5cbiAgICAvLyAyLiBGaXh0dXJlUmVjb3Jk66GcIOuzgO2ZmFxuICAgIGNvbnN0IGZpeHR1cmVSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gPSBbXTtcblxuICAgIC8vIOuplOyduCBlbnRpdHnsnZggcmVjb3Jkc+ulvCBGaXh0dXJlUmVjb3Jk66GcIOuzgO2ZmFxuICAgIGNvbnN0IG1haW5FbnRpdHkgPSB0aGlzLmVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eU5hbWUpO1xuICAgIGZvciAoY29uc3QgcmVjb3JkIG9mIGV4cGxvcmVSZXN1bHQubWFpbi5yZWNvcmRzKSB7XG4gICAgICBjb25zdCByZWNvcmRzID0gYXdhaXQgRml4dHVyZU1hbmFnZXIuY3JlYXRlRml4dHVyZVJlY29yZChcbiAgICAgICAgbWFpbkVudGl0eSxcbiAgICAgICAgcmVjb3JkIGFzIHsgaWQ6IG51bWJlciB8IHN0cmluZzsgW2tleTogc3RyaW5nXTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IG51bGwgfSxcbiAgICAgICAgeyBfZGI6IHRoaXMuc291cmNlRGIsIHNpbmdsZVJlY29yZDogdHJ1ZSB9LFxuICAgICAgKTtcbiAgICAgIGZpeHR1cmVSZWNvcmRzLnB1c2goLi4ucmVjb3Jkcyk7XG4gICAgfVxuXG4gICAgLy8g6rSA66CoIGVudGl0eeydmCByZWNvcmRz66W8IEZpeHR1cmVSZWNvcmTroZwg67OA7ZmYXG4gICAgZm9yIChjb25zdCBbcmVsYXRlZEVudGl0eU5hbWUsIHJlbGF0ZWRSZWNvcmRzXSBvZiBleHBsb3JlUmVzdWx0LnJlbGF0ZWQuZW50cmllcygpKSB7XG4gICAgICBjb25zdCByZWxhdGVkRW50aXR5ID0gdGhpcy5lbnRpdHlNYW5hZ2VyLmdldChyZWxhdGVkRW50aXR5TmFtZSk7XG4gICAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiByZWxhdGVkUmVjb3Jkcykge1xuICAgICAgICBjb25zdCByZWNvcmRzID0gYXdhaXQgRml4dHVyZU1hbmFnZXIuY3JlYXRlRml4dHVyZVJlY29yZChcbiAgICAgICAgICByZWxhdGVkRW50aXR5LFxuICAgICAgICAgIHJlY29yZCBhcyB7IGlkOiBudW1iZXIgfCBzdHJpbmc7IFtrZXk6IHN0cmluZ106IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBudWxsIH0sXG4gICAgICAgICAgeyBfZGI6IHRoaXMuc291cmNlRGIsIHNpbmdsZVJlY29yZDogdHJ1ZSB9LFxuICAgICAgICApO1xuICAgICAgICBmaXh0dXJlUmVjb3Jkcy5wdXNoKC4uLnJlY29yZHMpO1xuICAgICAgfVxuXG4gICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JheShgICAtICR7cmVsYXRlZEVudGl0eU5hbWV9OiAke3JlbGF0ZWRSZWNvcmRzLmxlbmd0aH0gcmVjb3Jkc2ApKTtcbiAgICB9XG5cbiAgICAvLyAzLiB0YXJnZXREYuyXkCDsgr3snoUgKEZpeHR1cmVNYW5hZ2Vy6rCAIOydmOyhtOyEsSDsoJXroKwg7LKY66asKVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBGaXh0dXJlTWFuYWdlci5pbnNlcnRGaXh0dXJlcyh0aGlzLnRhcmdldERiTmFtZSwgZml4dHVyZVJlY29yZHMpO1xuXG4gICAgIWlzVGVzdCgpICYmXG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgY2hhbGsuZ3JlZW4oXG4gICAgICAgICAgYFN1Y2Nlc3NmdWxseSBpbXBvcnRlZCAke3Jlc3VsdHMubGVuZ3RofSByZWNvcmRzIHRvICR7dGhpcy50YXJnZXREYk5hbWV9ICgke2V4cGxvcmVSZXN1bHQubWFpbi5yZWNvcmRzLmxlbmd0aH0gJHtlbnRpdHlOYW1lfSArICR7cmVzdWx0cy5sZW5ndGggLSBleHBsb3JlUmVzdWx0Lm1haW4ucmVjb3Jkcy5sZW5ndGh9IHJlbGF0ZWQpYCxcbiAgICAgICAgKSxcbiAgICAgICk7XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztZQU9tRztpQkFDdkQ7b0JBQ0U7cUJBRUU7c0JBRUU7Q0FzQnJDLG1CQUFiLE1BQThCO0VBU2xCO0VBSUE7RUFDQTtFQWJWO0VBQ0E7RUFDQTtFQUNBLDJCQUF5QyxJQUFJLElBQUk7RUFDakQsOEJBQTJDLElBQUksSUFBSTtFQUNuRDtFQUVBLFlBQ0UsVUFHQSxXQUNBLGNBQ0EsZUFDQSxTQUNBO0dBUFEsS0FBQSxXQUFBO0dBSUEsS0FBQSxlQUFBO0dBQ0EsS0FBQSxnQkFBQTtHQUdSLEtBQUssZUFBZSxJQUFJLGFBQWEsVUFBVSxhQUFhO0dBQzVELEtBQUssU0FB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
|
|
1140
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZml4dHVyZS1nZW5lcmF0b3IuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3Rlc3RpbmcvZml4dHVyZS1nZW5lcmF0b3IudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdHlwZSBMYW5ndWFnZU1vZGVsIH0gZnJvbSBcImFpXCI7XG5pbXBvcnQgY2hhbGsgZnJvbSBcImNoYWxrXCI7XG5pbXBvcnQgeyB0eXBlIEtuZXggfSBmcm9tIFwia25leFwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcblxuaW1wb3J0IHsgdHlwZSBTb25hbXVEQlByZXNldCB9IGZyb20gXCIuLi9kYXRhYmFzZS9kYlwiO1xuaW1wb3J0IHsgdHlwZSBFbnRpdHkgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eVwiO1xuaW1wb3J0IHsgdHlwZSBFbnRpdHlNYW5hZ2VyIH0gZnJvbSBcIi4uL2VudGl0eS9lbnRpdHktbWFuYWdlclwiO1xuaW1wb3J0IHsgdHlwZSBFbnRpdHlQcm9wLCB0eXBlIEZpeHR1cmVJbXBvcnRSZXN1bHQsIHR5cGUgRml4dHVyZVJlY29yZCB9IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AsIGlzT25lVG9PbmVSZWxhdGlvblByb3AsIGlzUmVsYXRpb25Qcm9wIH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgeyBpc1Rlc3QgfSBmcm9tIFwiLi4vdXRpbHMvY29udHJvbGxlclwiO1xuaW1wb3J0IHsgaXNGdW5jdGlvblZhbHVlIH0gZnJvbSBcIi4uL3V0aWxzL3J1bnRpbWUtdmFsdWVcIjtcbmltcG9ydCB7IERhdGFFeHBsb3JlciwgZGF0YUV4cGxvcmVyUmVjb3JkU2NoZW1hLCBkYXRhRXhwbG9yZXJWYWx1ZVNjaGVtYSB9IGZyb20gXCIuL2RhdGEtZXhwbG9yZXJcIjtcbmltcG9ydCB7IGRhdGFTb3VyY2VDb25maWdTY2hlbWEgfSBmcm9tIFwiLi9kYXRhLWV4cGxvcmVyXCI7XG5pbXBvcnQgeyB0eXBlIERhdGFFeHBsb3JlclJlY29yZCwgdHlwZSBEYXRhRXhwbG9yZXJWYWx1ZSB9IGZyb20gXCIuL2RhdGEtZXhwbG9yZXJcIjtcbmltcG9ydCB7IHR5cGUgRXhwbG9yZVdpdGhSZWxhdGlvbnNPcHRpb25zLCB0eXBlIEV4cGxvcmVXaXRoUmVsYXRpb25zUmVzdWx0IH0gZnJvbSBcIi4vZGF0YS1leHBsb3JlclwiO1xuaW1wb3J0IHsgZmFrZXJNYXBwaW5ncyB9IGZyb20gXCIuL2Zha2VyLW1hcHBpbmdzXCI7XG5pbXBvcnQgeyB0eXBlIEZha2VyTWFwcGluZ3MgfSBmcm9tIFwiLi9mYWtlci1tYXBwaW5nc1wiO1xuaW1wb3J0IHsgRml4dHVyZU1hbmFnZXIgfSBmcm9tIFwiLi9maXh0dXJlLW1hbmFnZXJcIjtcbmltcG9ydCB7IHR5cGUgRml4dHVyZVNvdXJjZVJlY29yZCB9IGZyb20gXCIuL2ZpeHR1cmUtbWFuYWdlclwiO1xuXG5leHBvcnQgdHlwZSBMb2NhbGUgPSBcImtvXCIgfCBcImVuXCIgfCBcImphXCI7XG5leHBvcnQgdHlwZSBGaXh0dXJlT3ZlcnJpZGVzID0gb2JqZWN0O1xuXG50eXBlIEZha2VyRnVuY3Rpb24gPSAoLi4uYXJnczogRGF0YUV4cGxvcmVyVmFsdWVbXSkgPT4gRGF0YUV4cGxvcmVyVmFsdWU7XG50eXBlIEZha2VyTmFtZXNwYWNlTWVtYmVyID0gRmFrZXJGdW5jdGlvbiB8IEZha2VyTmFtZXNwYWNlO1xudHlwZSBGYWtlck5hbWVzcGFjZSA9IHsgW25hbWU6IHN0cmluZ106IEZha2VyTmFtZXNwYWNlTWVtYmVyIH07XG5cbmNvbnN0IGZha2VyRnVuY3Rpb25TY2hlbWEgPSB6LmN1c3RvbTxGYWtlckZ1bmN0aW9uPihcbiAgaXNGdW5jdGlvblZhbHVlLFxuICBcIkZha2VyIOqyveuhnOydmCDrp4jsp4Drp4kg6rCS7J2AIO2VqOyImOyXrOyVvCDtlanri4jri6QuXCIsXG4pO1xuY29uc3QgZmFrZXJOYW1lc3BhY2VPYmplY3RTY2hlbWEgPSB6Lm9iamVjdCh7fSk7XG5jb25zdCBkeW5hbWljTmFtZXNwYWNlU2NoZW1hID0gei5jdXN0b208RmFrZXJOYW1lc3BhY2U+KFxuICAoY2FuZGlkYXRlKSA9PiBmYWtlck5hbWVzcGFjZU9iamVjdFNjaGVtYS5zYWZlUGFyc2UoY2FuZGlkYXRlKS5zdWNjZXNzLFxuICBcIkZha2VyIOqyveuhnOuKlCDqsJ3ssrQgbmFtZXNwYWNl7Jes7JW8IO2VqeuLiOuLpC5cIixcbik7XG5jb25zdCBnZW5lcmF0b3JBcmd1bWVudHNTY2hlbWEgPSB6LmFycmF5KGRhdGFFeHBsb3JlclZhbHVlU2NoZW1hKTtcbmNvbnN0IGZpeHR1cmVSZWNvcmRJZFNjaGVtYSA9IHoudW5pb24oW3oubnVtYmVyKCksIHouc3RyaW5nKCldKTtcbmNvbnN0IGZpeHR1cmVXaGVyZVZhbHVlU2NoZW1hID0gei51bmlvbihbei5zdHJpbmcoKSwgei5udW1iZXIoKSwgei5ib29sZWFuKCksIHouZGF0ZSgpLCB6Lm51bGwoKV0pO1xuXG5leHBvcnQgdHlwZSBGaXh0dXJlR2VuZXJhdGlvblNwZWMgPSB7XG4gIGVudGl0eTogc3RyaW5nO1xuICBjb3VudDogbnVtYmVyO1xuICBvdmVycmlkZXM/OiBGaXh0dXJlT3ZlcnJpZGVzO1xufTtcblxudHlwZSBHZW5lcmF0ZWRGaXh0dXJlID0ge1xuICBlbnRpdHk6IHN0cmluZztcbiAgZGF0YTogRGF0YUV4cGxvcmVyUmVjb3JkO1xuICBleHBsaWNpdElkPzogYm9vbGVhbjtcbn07XG5cbmZ1bmN0aW9uIHBhcnNlRml4dHVyZVNvdXJjZVJlY29yZChyZWNvcmQ6IERhdGFFeHBsb3JlclJlY29yZCk6IEZpeHR1cmVTb3VyY2VSZWNvcmQge1xuICByZXR1cm4ge1xuICAgIC4uLnJlY29yZCxcbiAgICBpZDogZml4dHVyZVJlY29yZElkU2NoZW1hLnBhcnNlKHJlY29yZC5pZCksXG4gIH07XG59XG5cbmV4cG9ydCB0eXBlIEZpeHR1cmVHZW5lcmF0b3JPcHRpb25zID0ge1xuICBsb2NhbGU/OiBMb2NhbGU7XG4gIHVzZUxMTT86IGJvb2xlYW47XG4gIGVuYWJsZUxMTUNhY2hlPzogYm9vbGVhbjtcbiAgbGxtTW9kZWw/OiBzdHJpbmc7XG4gIC8qKiDthYzsiqTtirjrgpgg64yA7LK0IExMTSDqs7XquInsnpDrpbwg7JyE7ZWcIO2FjeyKpO2KuCDsg53shLEg6rWs7ZiEICovXG4gIGdlbmVyYXRlVGV4dD86IEZpeHR1cmVUZXh0R2VuZXJhdG9yO1xufTtcblxuZXhwb3J0IHR5cGUgRml4dHVyZVRleHRHZW5lcmF0b3IgPSAocmVxdWVzdDoge1xuICBtb2RlbDogTGFuZ3VhZ2VNb2RlbDtcbiAgcHJvbXB0OiBzdHJpbmc7XG59KSA9PiBQcm9taXNlPHsgdGV4dDogc3RyaW5nOyB1c2FnZT86IHsgdG90YWxUb2tlbnM/OiBudW1iZXIgfSB9PjtcblxuZXhwb3J0IHR5cGUgR2VuZXJhdG9yQ29udGV4dCA9IHtcbiAgLyoqIOyDneyEsSDspJHsnbggZml4dHVyZeuTpCAo66mU66qo66asIOyDgSkgKi9cbiAgZml4dHVyZXM6IE1hcDxzdHJpbmcsIERhdGFFeHBsb3JlclJlY29yZD47XG5cbiAgLyoqIOywuOyhsCDrjbDsnbTthLAg7LqQ7IucIChEYXRhRXhwbG9yZXIg6rKw6rO8KSAqL1xuICByZWZlcmVuY2VDYWNoZTogTWFwPHN0cmluZywgRGF0YUV4cGxvcmVyUmVjb3JkW10+O1xuXG4gIC8qKiDsnbTrr7ggaW1wb3J065CcIOugiOy9lOuTnOulvCDstpTsoIHtlZjsl6wg7KSR67O1IGltcG9ydOulvCDrsKnsp4Dtlanri4jri6QgKi9cbiAgaW1wb3J0ZWRSZWNvcmRzOiBTZXQ8c3RyaW5nPjsgLy8gXCJVc2VyIzEyM1wiXG59O1xuXG5leHBvcnQgY2xhc3MgRml4dHVyZUdlbmVyYXRvciB7XG4gIHByaXZhdGUgZGF0YUV4cGxvcmVyOiBEYXRhRXhwbG9yZXI7XG4gIHByaXZhdGUgbG9jYWxlOiBMb2NhbGU7XG4gIHByaXZhdGUgbWFwcGluZ3M6IEZha2VyTWFwcGluZ3M7XG4gIHByaXZhdGUgbGxtQ2FjaGU6IE1hcDxzdHJpbmcsIERhdGFFeHBsb3JlclZhbHVlPiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBlbnRpdHlDYWNoZTogTWFwPHN0cmluZywgRW50aXR5PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSBvcHRpb25zOiBGaXh0dXJlR2VuZXJhdG9yT3B0aW9ucztcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHNvdXJjZURiOiBLbmV4LFxuICAgIC8vIEZpeHR1cmVNYW5hZ2VyLmluc2VydEZpeHR1cmVz6rCAIGRiTmFtZSDrrLjsnpDsl7TsnYQg67Cb6riwIOuVjOusuOyXkCDsp4HsoJEg7IKs7Jqp7ZWY7KeAIOyViuyKteuLiOuLpFxuICAgIC8vIOuvuOuemCDtmZXsnqXshLHsnYQg7JyE7ZW0IEFQSSDsi5zqt7jri4jsspjsl5DripQg7Y+s7ZWo7Iuc7Lyw7Iq164uI64ukXG4gICAgX3RhcmdldERiOiBLbmV4LFxuICAgIHByaXZhdGUgdGFyZ2V0RGJOYW1lOiBTb25hbXVEQlByZXNldCxcbiAgICBwcml2YXRlIGVudGl0eU1hbmFnZXI6IHR5cGVvZiBFbnRpdHlNYW5hZ2VyLFxuICAgIG9wdGlvbnM/OiBGaXh0dXJlR2VuZXJhdG9yT3B0aW9ucyxcbiAgKSB7XG4gICAgdGhpcy5kYXRhRXhwbG9yZXIgPSBuZXcgRGF0YUV4cGxvcmVyKHNvdXJjZURiLCBlbnRpdHlNYW5hZ2VyKTtcbiAgICB0aGlzLmxvY2FsZSA9IG9wdGlvbnM/LmxvY2FsZSB8fCBcImtvXCI7XG4gICAgdGhpcy5tYXBwaW5ncyA9IGZha2VyTWFwcGluZ3M7XG4gICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgbG9jYWxlOiBvcHRpb25zPy5sb2NhbGUgfHwgXCJrb1wiLFxuICAgICAgdXNlTExNOiBvcHRpb25zPy51c2VMTE0gfHwgZmFsc2UsXG4gICAgICBlbmFibGVMTE1DYWNoZTogb3B0aW9ucz8uZW5hYmxlTExNQ2FjaGUgIT09IGZhbHNlLFxuICAgICAgbGxtTW9kZWw6IG9wdGlvbnM/LmxsbU1vZGVsIHx8IFwiY2xhdWRlLXNvbm5ldC00LTZcIixcbiAgICAgIGdlbmVyYXRlVGV4dDogb3B0aW9ucz8uZ2VuZXJhdGVUZXh0LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogRml4dHVyZSDsg53shLEgKOuLqOydvClcbiAgICogQHJldHVybnMg7IOd7ISx65CcIGZpeHR1cmUg642w7J207YSwICjrqZTrqqjrpqwg7IOBKVxuICAgKi9cbiAgYXN5bmMgZ2VuZXJhdGU8T3ZlcnJpZGVzID0gdW5kZWZpbmVkPihcbiAgICBlbnRpdHlOYW1lOiBzdHJpbmcsXG4gICAgb3ZlcnJpZGVzPzogT3ZlcnJpZGVzLFxuICAgIGNvbnRleHQ6IEdlbmVyYXRvckNvbnRleHQgPSB0aGlzLmNyZWF0ZUNvbnRleHQoKSxcbiAgKTogUHJvbWlzZTxEYXRhRXhwbG9yZXJSZWNvcmQ+IHtcbiAgICBjb25zdCBwYXJzZWRPdmVycmlkZXMgPSBkYXRhRXhwbG9yZXJSZWNvcmRTY2hlbWEucGFyc2Uob3ZlcnJpZGVzID8/IHt9KTtcbiAgICAvLyBFbnRpdHkg7LqQ7IuxOiDthYzsiqTtirjsl5DshJwgZW50aXR5IGNvbmUg7IiY7KCV7J20IOuwmOyYgeuQmOuPhOuhnSDrs7TsnqVcbiAgICBsZXQgZW50aXR5ID0gdGhpcy5lbnRpdHlDYWNoZS5nZXQoZW50aXR5TmFtZSk7XG4gICAgaWYgKCFlbnRpdHkpIHtcbiAgICAgIGVudGl0eSA9IHRoaXMuZW50aXR5TWFuYWdlci5nZXQoZW50aXR5TmFtZSk7XG4gICAgICB0aGlzLmVudGl0eUNhY2hlLnNldChlbnRpdHlOYW1lLCBlbnRpdHkpO1xuICAgIH1cblxuICAgIGNvbnN0IHRlbXBJZCA9IGAke2VudGl0eU5hbWV9I3RlbXAjJHtEYXRlLm5vdygpfWA7IC8vIOyehOyLnCBJRFxuXG4gICAgLy8gTExNIHJvdyDri6jsnIQg7IOd7ISx7J2EIOychO2VnCDqs6DsnKAg7YKkICjqsJnsnYAgcm937J2YIO2VhOuTnOuTpOydtCDrj5nsnbztlZwgcm93S2V566W8IOqzteycoClcbiAgICBjb25zdCByb3dLZXkgPSB0aGlzLm9wdGlvbnMudXNlTExNID8gYCR7ZW50aXR5TmFtZX0jcm93IyR7RGF0ZS5ub3coKX1gIDogdW5kZWZpbmVkO1xuXG4gICAgLy8g6rCBIHByb3Drs4Qg6rCSIOyDneyEsVxuICAgIGNvbnN0IGZpeHR1cmU6IERhdGFFeHBsb3JlclJlY29yZCA9IHt9O1xuXG4gICAgZm9yIChjb25zdCBwcm9wIG9mIGVudGl0eS5wcm9wcykge1xuICAgICAgLy8gVmlydHVhbCBwcm9w7J2AIOyKpO2CtVxuICAgICAgaWYgKFwidmlydHVhbFwiIGluIHByb3AgJiYgcHJvcC52aXJ0dWFsKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBpZCBwcm9wIOyymOumrFxuICAgICAgaWYgKHByb3AubmFtZSA9PT0gXCJpZFwiKSB7XG4gICAgICAgIC8vIERCIHNlcXVlbmNl6rCAIOyekOuPmSDtlaDri7k6IGludGVnZXIvYmlnSW50ZWdlcuydtOqxsOuCmCwgc3RyaW5n7J207KeA66eMIGRiRGVmYXVsdOyXkCBuZXh0dmFs7J20IOyeiOuKlCDqsr3smrBcbiAgICAgICAgY29uc3QgaGFzRGJTZXF1ZW5jZSA9XG4gICAgICAgICAgcHJvcC50eXBlID09PSBcImludGVnZXJcIiB8fFxuICAgICAgICAgIHByb3AudHlwZSA9PT0gXCJiaWdJbnRlZ2VyXCIgfHxcbiAgICAgICAgICAocHJvcC50eXBlID09PSBcInN0cmluZ1wiICYmXG4gICAgICAgICAgICBcImRiRGVmYXVsdFwiIGluIHByb3AgJiZcbiAgICAgICAgICAgIHouc3RyaW5nKCkuc2FmZVBhcnNlKHByb3AuZGJEZWZhdWx0KS5kYXRhPy5pbmNsdWRlcyhcIm5leHR2YWxcIikgPT09IHRydWUpO1xuICAgICAgICBpZiAoaGFzRGJTZXF1ZW5jZSkge1xuICAgICAgICAgIC8vIGdlbmVyYXRlQmF0Y2jsl5DshJwg7LKY66as7ZWY66+A66GcIOyXrOq4sOyEoCDsiqTtgrVcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcC50eXBlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgLy8gc3RyaW5nIFBLOiBhbHBoYW51bWVyaWMgMzLsnpAg7IOd7ISxIChiZXR0ZXItYXV0aCDsiqTtg4DsnbwpXG4gICAgICAgICAgY29uc3QgeyBmYWtlcjogX2Zha2VyIH0gPSBhd2FpdCBpbXBvcnQoXCJAZmFrZXItanMvZmFrZXJcIik7XG4gICAgICAgICAgZml4dHVyZVtwcm9wLm5hbWVdID0gX2Zha2VyLnN0cmluZy5hbHBoYW51bWVyaWMoMzIpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wLnR5cGUgPT09IFwidXVpZFwiKSB7XG4gICAgICAgICAgY29uc3QgeyBmYWtlcjogX2Zha2VyIH0gPSBhd2FpdCBpbXBvcnQoXCJAZmFrZXItanMvZmFrZXJcIik7XG4gICAgICAgICAgZml4dHVyZVtwcm9wLm5hbWVdID0gX2Zha2VyLnN0cmluZy51dWlkKCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIG92ZXJyaWRl6rCAIOyeiOycvOuptCDsgqzsmqlcbiAgICAgIGlmIChwcm9wLm5hbWUgaW4gcGFyc2VkT3ZlcnJpZGVzKSB7XG4gICAgICAgIGZpeHR1cmVbcHJvcC5uYW1lXSA9IHBhcnNlZE92ZXJyaWRlc1twcm9wLm5hbWVdO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gY29uZeyXkOyEnCDsg53shLEg7KCE6561IO2ZleyduFxuICAgICAgY29uc3QgY29uZSA9IHByb3AuY29uZTtcblxuICAgICAgLy8gMS4gUmVsYXRpb24gcHJvcCDsspjrpqxcbiAgICAgIGlmIChpc1JlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICAvLyBCZWxvbmdzVG9PbmUgLyBPbmVUb09uZShoYXNKb2luQ29sdW1uKeydgCBGSyDsu6zrn7zrqoUoe3Byb3AubmFtZX1faWQp7Jy866Gc64+EIG92ZXJyaWRl66W8IOuwm+uKlOuLpFxuICAgICAgICBjb25zdCBma0NvbE5hbWUgPSBgJHtwcm9wLm5hbWV9X2lkYDtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGZrQ29sTmFtZSBpbiBwYXJzZWRPdmVycmlkZXMgJiZcbiAgICAgICAgICAoaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocHJvcCkgfHwgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocHJvcCkgJiYgcHJvcC5oYXNKb2luQ29sdW1uKSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgZml4dHVyZVtma0NvbE5hbWVdID0gcGFyc2VkT3ZlcnJpZGVzW2ZrQ29sTmFtZV07XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZWxhdGlvblZhbHVlID0gYXdhaXQgdGhpcy5nZW5lcmF0ZVJlbGF0aW9uVmFsdWUoZW50aXR5LCBwcm9wLCBjb250ZXh0KTtcbiAgICAgICAgLy8gQmVsb25nc1RvT25lLCBPbmVUb09uZShoYXNKb2luQ29sdW1uKeydmCDqsr3smrAgZm9yZWlnbiBrZXkg7Lus65+866qF7Jy866GcIOyggOyepVxuICAgICAgICBpZiAoXG4gICAgICAgICAgaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocHJvcCkgfHxcbiAgICAgICAgICAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChwcm9wKSAmJiBwcm9wLmhhc0pvaW5Db2x1bW4pXG4gICAgICAgICkge1xuICAgICAgICAgIGZpeHR1cmVbYCR7cHJvcC5uYW1lfV9pZGBdID0gcmVsYXRpb25WYWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBmaXh0dXJlW3Byb3AubmFtZV0gPSByZWxhdGlvblZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyAyLiBjb25lLm5vdGUgKyBMTE0g7IKs7JqpICh1c2VMTE3snbTrqbQgZml4dHVyZUdlbmVyYXRvcuuztOuLpCDsmrDshKApXG4gICAgICBpZiAoY29uZT8ubm90ZSAmJiB0aGlzLm9wdGlvbnMudXNlTExNKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgbGxtVmFsdWUgPSBhd2FpdCB0aGlzLmdlbmVyYXRlV2l0aExMTShjb25lLm5vdGUsIHByb3AsIGVudGl0eSwgcm93S2V5KTtcbiAgICAgICAgICAvLyBzdHJpbmcg7YOA7J6F7J206rOgIGxlbmd0aCDsoJzslb3snbQg7J6I7Jy866m0IOy0iOqzvCDsi5wgdHJ1bmNhdGlvblxuICAgICAgICAgIGNvbnN0IGxsbVRleHQgPSB6LnN0cmluZygpLnNhZmVQYXJzZShsbG1WYWx1ZSk7XG4gICAgICAgICAgY29uc3QgbWF4TGVuZ3RoID0gXCJsZW5ndGhcIiBpbiBwcm9wID8gei5udW1iZXIoKS5zYWZlUGFyc2UocHJvcC5sZW5ndGgpIDogdW5kZWZpbmVkO1xuICAgICAgICAgIGlmIChsbG1UZXh0LnN1Y2Nlc3MgJiYgbWF4TGVuZ3RoPy5zdWNjZXNzICYmIGxsbVRleHQuZGF0YS5sZW5ndGggPiBtYXhMZW5ndGguZGF0YSkge1xuICAgICAgICAgICAgZml4dHVyZVtwcm9wLm5hbWVdID0gbGxtVGV4dC5kYXRhLnNsaWNlKDAsIG1heExlbmd0aC5kYXRhKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZml4dHVyZVtwcm9wLm5hbWVdID0gbGxtVmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgIGBbRml4dHVyZUdlbmVyYXRvcl0gTExNIGdlbmVyYXRpb24gZmFpbGVkIGZvciAke2VudGl0eS5pZH0uJHtwcm9wLm5hbWV9LCBmYWxsaW5nIGJhY2sgdG8gZml4dHVyZUdlbmVyYXRvciBvciBkZWZhdWx0YCxcbiAgICAgICAgICAgIGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogZXJyb3IsXG4gICAgICAgICAgKTtcbiAgICAgICAgICAvLyBmYWxsYmFjazogZml4dHVyZUdlbmVyYXRvciDihpIgZml4dHVyZURlZmF1bHQg4oaSIOq4sOuzuOqwkuycvOuhnCDqs4Tsho1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyAzLiBmaXh0dXJlR2VuZXJhdG9yIOyCrOyaqVxuICAgICAgaWYgKGNvbmU/LmZpeHR1cmVHZW5lcmF0b3IpIHtcbiAgICAgICAgZml4dHVyZVtwcm9wLm5hbWVdID0gYXdhaXQgdGhpcy5leGVjdXRlR2VuZXJhdG9yKGNvbmUuZml4dHVyZUdlbmVyYXRvciwgcHJvcCwgZW50aXR5KTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIDQuIGZpeHR1cmVEZWZhdWx0IOyCrOyaqVxuICAgICAgaWYgKGNvbmU/LmZpeHR1cmVEZWZhdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgZml4dHVyZVtwcm9wLm5hbWVdID0gZGF0YUV4cGxvcmVyVmFsdWVTY2hlbWEucGFyc2UoY29uZS5maXh0dXJlRGVmYXVsdCk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyA1LiDtg4DsnoXrs4Qg6riw67O4IOyDneyEsVxuICAgICAgZml4dHVyZVtwcm9wLm5hbWVdID0gYXdhaXQgdGhpcy5nZW5lcmF0ZURlZmF1bHRWYWx1ZShwcm9wLCBlbnRpdHkpO1xuICAgIH1cblxuICAgIC8vIDYuIGVtYWlsIO2VhOuTnOqwgCDsnojqs6AgbmFtZSDtlYTrk5zqsIAg7J6I7Jy866m0LCBlbWFpbOydmCDroZzsu6wg7YyM7Yq466W8IG5hbWUg6riw67CY7Jy866GcIOuztOyglVxuICAgIGNvbnN0IGVtYWlsID0gei5zdHJpbmcoKS5zYWZlUGFyc2UoZml4dHVyZS5lbWFpbCk7XG4gICAgaWYgKGVtYWlsLnN1Y2Nlc3MgJiYgIShcImVtYWlsXCIgaW4gcGFyc2VkT3ZlcnJpZGVzKSkge1xuICAgICAgY29uc3QgbmFtZVZhbHVlID0gZml4dHVyZS5uYW1lIHx8IGZpeHR1cmUudXNlcm5hbWUgfHwgZml4dHVyZS5mdWxsX25hbWUgfHwgZml4dHVyZS5uYW1lX2VuO1xuICAgICAgY29uc3QgcGFyc2VkTmFtZSA9IHouc3RyaW5nKCkuc2FmZVBhcnNlKG5hbWVWYWx1ZSk7XG4gICAgICBpZiAocGFyc2VkTmFtZS5zdWNjZXNzKSB7XG4gICAgICAgIGNvbnN0IGRvbWFpbiA9IGVtYWlsLmRhdGEuc3BsaXQoXCJAXCIpWzFdIHx8IFwiZXhhbXBsZS5jb21cIjtcbiAgICAgICAgY29uc3Qgcm9tYW5pemVkID0gYXdhaXQgdGhpcy5yb21hbml6ZU5hbWUocGFyc2VkTmFtZS5kYXRhKTtcbiAgICAgICAgZml4dHVyZS5lbWFpbCA9IGAke3JvbWFuaXplZH1AJHtkb21haW59YDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyA3LiBwYXNzd29yZCDtlYTrk5wg7JWU7Zi47ZmUXG4gICAgY29uc3QgcGFzc3dvcmQgPSB6LnN0cmluZygpLnNhZmVQYXJzZShmaXh0dXJlLnBhc3N3b3JkKTtcbiAgICBpZiAocGFzc3dvcmQuc3VjY2VzcyAmJiBwYXNzd29yZC5kYXRhLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGJjcnlwdCA9IGF3YWl0IGltcG9ydChcImJjcnlwdFwiKTtcbiAgICAgIGZpeHR1cmUucGFzc3dvcmQgPSBhd2FpdCBiY3J5cHQuaGFzaChwYXNzd29yZC5kYXRhLCAxMCk7XG4gICAgfVxuXG4gICAgY29udGV4dC5maXh0dXJlcy5zZXQodGVtcElkLCBmaXh0dXJlKTtcbiAgICByZXR1cm4gZml4dHVyZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWxhdGlvbiDqsJIg7IOd7ISxICsg7J6Q64+ZIEltcG9ydFxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBnZW5lcmF0ZVJlbGF0aW9uVmFsdWUoXG4gICAgZW50aXR5OiBFbnRpdHksXG4gICAgcHJvcDogRW50aXR5UHJvcCxcbiAgICBjb250ZXh0OiBHZW5lcmF0b3JDb250ZXh0LFxuICApOiBQcm9taXNlPG51bWJlciB8IHN0cmluZyB8IG51bGw+IHtcbiAgICBpZiAoIWlzUmVsYXRpb25Qcm9wKHByb3ApKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZpeHR1cmVHZW5lcmF0b3I6ICR7ZW50aXR5LmlkfS4ke3Byb3AubmFtZX0gaXMgbm90IGEgcmVsYXRpb24gcHJvcGApO1xuICAgIH1cblxuICAgIC8vIEJlbG9uZ3NUb09uZSwgT25lVG9PbmUoaGFzSm9pbkNvbHVtbinrp4wg7LKY66asXG4gICAgaWYgKFxuICAgICAgIWlzQmVsb25nc1RvT25lUmVsYXRpb25Qcm9wKHByb3ApICYmXG4gICAgICAhKGlzT25lVG9PbmVSZWxhdGlvblByb3AocHJvcCkgJiYgcHJvcC5oYXNKb2luQ29sdW1uKVxuICAgICkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgY29uZSA9IHByb3AuY29uZTtcbiAgICBjb25zdCBkYXRhU291cmNlID0gY29uZT8uZGF0YVNvdXJjZTtcblxuICAgIC8vIERhdGFFeHBsb3JlcuuhnCDssLjsobAg642w7J207YSwIOyhsO2ajCAoc291cmNlRGIpXG4gICAgLy8g6rSA6rOEIOyytOyduOydhCDrlLDrnbzqsIDquLAg7JyE7ZW0IGV4cGxvcmVXaXRoUmVsYXRpb25zIOyCrOyaqVxuICAgIGlmIChkYXRhU291cmNlKSB7XG4gICAgICBjb25zdCBjYWNoZUtleSA9IGAke3Byb3Aud2l0aH06JHtKU09OLnN0cmluZ2lmeShkYXRhU291cmNlKX1gO1xuXG4gICAgICBpZiAoIWNvbnRleHQucmVmZXJlbmNlQ2FjaGUuaGFzKGNhY2hlS2V5KSkge1xuICAgICAgICBjb25zdCBkYXRhU291cmNlQ29uZmlnID0gZGF0YVNvdXJjZUNvbmZpZ1NjaGVtYS5wYXJzZShkYXRhU291cmNlLmNvbmZpZyA/PyB7fSk7XG4gICAgICAgIGNvbnN0IGV4cGxvcmVSZXN1bHQgPSBhd2FpdCB0aGlzLmRhdGFFeHBsb3Jlci5leHBsb3JlV2l0aFJlbGF0aW9ucyhwcm9wLndpdGgsIHtcbiAgICAgICAgICBzdHJhdGVneTogZGF0YVNvdXJjZS5zdHJhdGVneSxcbiAgICAgICAgICBsaW1pdDogZGF0YVNvdXJjZUNvbmZpZy5saW1pdCA/PyAxMCxcbiAgICAgICAgICBpbmNsdWRlUmVsYXRpb25zOiB0cnVlLFxuICAgICAgICAgIG1heERlcHRoOiAzLFxuICAgICAgICAgIC4uLmRhdGFTb3VyY2VDb25maWcsXG4gICAgICAgIH0pO1xuICAgICAgICBjb250ZXh0LnJlZmVyZW5jZUNhY2hlLnNldChjYWNoZUtleSwgZXhwbG9yZVJlc3VsdC5tYWluLnJlY29yZHMpO1xuXG4gICAgICAgIC8vIOyhsO2ajO2VnCDrjbDsnbTthLDsmYAg6rSA6rOE65CcIOuqqOuToCDsl5Tti7Dti7DrpbwgdGFyZ2V0RGLsl5AgaW1wb3J0XG4gICAgICAgIGF3YWl0IHRoaXMuaW1wb3J0RXhwbG9yZVJlc3VsdChleHBsb3JlUmVzdWx0LCBjb250ZXh0KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2FuZGlkYXRlcyA9IGNvbnRleHQucmVmZXJlbmNlQ2FjaGUuZ2V0KGNhY2hlS2V5KTtcbiAgICAgIGlmIChjYW5kaWRhdGVzICYmIGNhbmRpZGF0ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAvLyDrnpzrjaTtlZjqsowg7ZWY64KYIOyEoO2DnVxuICAgICAgICBjb25zdCBzZWxlY3RlZCA9IGNhbmRpZGF0ZXNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogY2FuZGlkYXRlcy5sZW5ndGgpXTtcbiAgICAgICAgcmV0dXJuIHoudW5pb24oW3oubnVtYmVyKCksIHouc3RyaW5nKCldKS5wYXJzZShzZWxlY3RlZC5pZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZGF0YVNvdXJjZeqwgCDsl4bsnYQg65WMIOyekOuPmeycvOuhnCBmaXh0dXJlIERC7JeQ7IScIOyhsO2ajCDsi5zrj4RcbiAgICAvLyDqtIDqs4Qg7LK07J247J2EIOuUsOudvOqwgOq4sCDsnITtlbQgZXhwbG9yZVdpdGhSZWxhdGlvbnMg7IKs7JqpXG4gICAgY29uc3QgYXV0b0tleSA9IGAke3Byb3Aud2l0aH06YXV0b2A7XG4gICAgaWYgKCFjb250ZXh0LnJlZmVyZW5jZUNhY2hlLmhhcyhhdXRvS2V5KSkge1xuICAgICAgLy8gZml4dHVyZSBEQihzb3VyY2VEYinsl5DshJwg7J6Q64+ZIOyhsO2ajCAo6rSA6rOEIO2PrO2VqClcbiAgICAgIGNvbnN0IGF1dG9FeHBsb3JlUmVzdWx0ID0gYXdhaXQgdGhpcy5kYXRhRXhwbG9yZXIuZXhwbG9yZVdpdGhSZWxhdGlvbnMocHJvcC53aXRoLCB7XG4gICAgICAgIHN0cmF0ZWd5OiBcInJhbmRvbVwiLFxuICAgICAgICBsaW1pdDogMTAsXG4gICAgICAgIGluY2x1ZGVSZWxhdGlvbnM6IHRydWUsXG4gICAgICAgIG1heERlcHRoOiAzLFxuICAgICAgfSk7XG4gICAgICBjb250ZXh0LnJlZmVyZW5jZUNhY2hlLnNldChhdXRvS2V5LCBhdXRvRXhwbG9yZVJlc3VsdC5tYWluLnJlY29yZHMpO1xuXG4gICAgICAvLyDsobDtmoztlZwg642w7J207YSw7JmAIOq0gOqzhOuQnCDrqqjrk6Ag7JeU7Yuw7Yuw66W8IHRhcmdldERi7JeQIGltcG9ydFxuICAgICAgaWYgKGF1dG9FeHBsb3JlUmVzdWx0Lm1haW4ucmVjb3Jkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuaW1wb3J0RXhwbG9yZVJlc3VsdChhdXRvRXhwbG9yZVJlc3VsdCwgY29udGV4dCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgYXV0b0NhbmRpZGF0ZXMgPSBjb250ZXh0LnJlZmVyZW5jZUNhY2hlLmdldChhdXRvS2V5KTtcbiAgICBpZiAoYXV0b0NhbmRpZGF0ZXMgJiYgYXV0b0NhbmRpZGF0ZXMubGVuZ3RoID4gMCkge1xuICAgICAgLy8g656c642k7ZWY6rKMIO2VmOuCmCDshKDtg51cbiAgICAgIGNvbnN0IHNlbGVjdGVkID0gYXV0b0NhbmRpZGF0ZXNbTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogYXV0b0NhbmRpZGF0ZXMubGVuZ3RoKV07XG4gICAgICByZXR1cm4gei51bmlvbihbei5udW1iZXIoKSwgei5zdHJpbmcoKV0pLnBhcnNlKHNlbGVjdGVkLmlkKTtcbiAgICB9XG5cbiAgICAvLyDssLjsobAg642w7J207YSw6rCAIOyXhuycvOuptCBudWxsIOuwmO2ZmCAobnVsbGFibGXsnbgg6rK97JqwKVxuICAgIGlmIChwcm9wLm51bGxhYmxlKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyBudWxsYWJsZeydtCDslYTri4jqs6Ag642w7J207YSw64+EIOyXhuycvOuptCDsl5Drn6xcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgRml4dHVyZUdlbmVyYXRvcjogJHtlbnRpdHkuaWR9LiR7cHJvcC5uYW1lfeyXkCDtlYTsmpTtlZwgJHtwcm9wLndpdGh9IOuNsOydtO2EsOqwgCDsl4bsirXri4jri6QuIGAgK1xuICAgICAgICBg66i87KCAICR7cHJvcC53aXRofeulvCDsg53shLHtlZjqsbDrgpggY29uZS5kYXRhU291cmNl66W8IOyEpOygle2VmOyEuOyalC5gLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogRXhwbG9yZVdpdGhSZWxhdGlvbnMg6rKw6rO866W8IHRhcmdldERi7JeQIGltcG9ydFxuICAgKlxuICAgKiDqtIDqs4Qg7LK07J247J2EIOuUsOudvOqwhCDqsrDqs7wobWFpbiArIHJlbGF0ZWQp66W8IOuqqOuRkCBpbXBvcnTtlanri4jri6QuXG4gICAqIOydmOyhtOyEsSDsiJzshJzripQgRml4dHVyZU1hbmFnZXIuaW5zZXJ0Rml4dHVyZXPqsIAg7J6Q64+Z7Jy866GcIOyymOumrO2VqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgaW1wb3J0RXhwbG9yZVJlc3VsdChcbiAgICBleHBsb3JlUmVzdWx0OiBFeHBsb3JlV2l0aFJlbGF0aW9uc1Jlc3VsdCxcbiAgICBjb250ZXh0OiBHZW5lcmF0b3JDb250ZXh0LFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBhbGxGaXh0dXJlUmVjb3JkczogRml4dHVyZVJlY29yZFtdID0gW107XG5cbiAgICAvLyAxLiBSZWxhdGVkIGVudGl0aWVzIGltcG9ydCAoQ29tcGFueSwgRGVwYXJ0bWVudCDrk7EpXG4gICAgZm9yIChjb25zdCBbZW50aXR5SWQsIHJlY29yZHNdIG9mIGV4cGxvcmVSZXN1bHQucmVsYXRlZC5lbnRyaWVzKCkpIHtcbiAgICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgY29uc3QgcmVjb3Jkc1RvSW1wb3J0OiBEYXRhRXhwbG9yZXJSZWNvcmRbXSA9IFtdO1xuXG4gICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgY2hhbGsuY3lhbihgSW1wb3J0aW5nIHJlbGF0ZWQgZW50aXR5OiAke2VudGl0eUlkfSAoJHtyZWNvcmRzLmxlbmd0aH0gcmVjb3JkcylgKSxcbiAgICAgICAgKTtcblxuICAgICAgZm9yIChjb25zdCByZWNvcmQgb2YgcmVjb3Jkcykge1xuICAgICAgICBjb25zdCByZWNvcmRLZXkgPSBgJHtlbnRpdHlJZH0jJHtyZWNvcmQuaWR9YDtcbiAgICAgICAgaWYgKCFjb250ZXh0LmltcG9ydGVkUmVjb3Jkcy5oYXMocmVjb3JkS2V5KSkge1xuICAgICAgICAgIHJlY29yZHNUb0ltcG9ydC5wdXNoKHJlY29yZCk7XG4gICAgICAgICAgY29udGV4dC5pbXBvcnRlZFJlY29yZHMuYWRkKHJlY29yZEtleSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHJlY29yZHNUb0ltcG9ydC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZvciAoY29uc3QgcmVjb3JkIG9mIHJlY29yZHNUb0ltcG9ydCkge1xuICAgICAgICAgICFpc1Rlc3QoKSAmJlxuICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgIGNoYWxrLmdyYXkoXG4gICAgICAgICAgICAgICAgYCAgLSBQcm9jZXNzaW5nICR7ZW50aXR5SWR9IHJlY29yZDpgLFxuICAgICAgICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHJlY29yZCkuc2xpY2UoMCwgMTAwKSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgY29uc3QgZml4dHVyZVJlY29yZHMgPSBhd2FpdCBGaXh0dXJlTWFuYWdlci5jcmVhdGVGaXh0dXJlUmVjb3JkKFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgcGFyc2VGaXh0dXJlU291cmNlUmVjb3JkKHJlY29yZCksXG4gICAgICAgICAgICB7IGRiOiB0aGlzLnNvdXJjZURiLCBzaW5nbGVSZWNvcmQ6IHRydWUgfSxcbiAgICAgICAgICApO1xuICAgICAgICAgIGFsbEZpeHR1cmVSZWNvcmRzLnB1c2goLi4uZml4dHVyZVJlY29yZHMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gMi4gTWFpbiBlbnRpdHkgaW1wb3J0IChFbXBsb3llZSDrk7EpXG4gICAgY29uc3QgbWFpbkVudGl0eSA9IHRoaXMuZW50aXR5TWFuYWdlci5nZXQoZXhwbG9yZVJlc3VsdC5tYWluLmVudGl0eUlkKTtcbiAgICBjb25zdCBtYWluUmVjb3Jkc1RvSW1wb3J0OiBEYXRhRXhwbG9yZXJSZWNvcmRbXSA9IFtdO1xuXG4gICAgIWlzVGVzdCgpICYmXG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgY2hhbGsuY3lhbihcbiAgICAgICAgICBgSW1wb3J0aW5nIG1haW4gZW50aXR5OiAke2V4cGxvcmVSZXN1bHQubWFpbi5lbnRpdHlJZH0gKCR7ZXhwbG9yZVJlc3VsdC5tYWluLnJlY29yZHMubGVuZ3RofSByZWNvcmRzKWAsXG4gICAgICAgICksXG4gICAgICApO1xuXG4gICAgZm9yIChjb25zdCByZWNvcmQgb2YgZXhwbG9yZVJlc3VsdC5tYWluLnJlY29yZHMpIHtcbiAgICAgIGNvbnN0IHJlY29yZEtleSA9IGAke2V4cGxvcmVSZXN1bHQubWFpbi5lbnRpdHlJZH0jJHtyZWNvcmQuaWR9YDtcbiAgICAgIGlmICghY29udGV4dC5pbXBvcnRlZFJlY29yZHMuaGFzKHJlY29yZEtleSkpIHtcbiAgICAgICAgbWFpblJlY29yZHNUb0ltcG9ydC5wdXNoKHJlY29yZCk7XG4gICAgICAgIGNvbnRleHQuaW1wb3J0ZWRSZWNvcmRzLmFkZChyZWNvcmRLZXkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtYWluUmVjb3Jkc1RvSW1wb3J0Lmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAoY29uc3QgcmVjb3JkIG9mIG1haW5SZWNvcmRzVG9JbXBvcnQpIHtcbiAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBjaGFsay5ncmF5KFxuICAgICAgICAgICAgICBgICAtIFByb2Nlc3NpbmcgJHtleHBsb3JlUmVzdWx0Lm1haW4uZW50aXR5SWR9IHJlY29yZDpgLFxuICAgICAgICAgICAgICBKU09OLnN0cmluZ2lmeShyZWNvcmQpLnNsaWNlKDAsIDEwMCksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICk7XG4gICAgICAgIGNvbnN0IGZpeHR1cmVSZWNvcmRzID0gYXdhaXQgRml4dHVyZU1hbmFnZXIuY3JlYXRlRml4dHVyZVJlY29yZChcbiAgICAgICAgICBtYWluRW50aXR5LFxuICAgICAgICAgIHBhcnNlRml4dHVyZVNvdXJjZVJlY29yZChyZWNvcmQpLFxuICAgICAgICAgIHsgZGI6IHRoaXMuc291cmNlRGIsIHNpbmdsZVJlY29yZDogdHJ1ZSB9LFxuICAgICAgICApO1xuICAgICAgICBhbGxGaXh0dXJlUmVjb3Jkcy5wdXNoKC4uLmZpeHR1cmVSZWNvcmRzKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAzLiDrqqjrk6AgZml4dHVyZeulvCDtlZwg67KI7JeQIOyCveyehSAo7J2Y7KG07ISxIOyInOyEnCDsnpDrj5kg7LKY66asKVxuICAgIGlmIChhbGxGaXh0dXJlUmVjb3Jkcy5sZW5ndGggPiAwKSB7XG4gICAgICBhd2FpdCBGaXh0dXJlTWFuYWdlci5pbnNlcnRGaXh0dXJlcyh0aGlzLnRhcmdldERiTmFtZSwgYWxsRml4dHVyZVJlY29yZHMpO1xuXG4gICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgY2hhbGsuZ3JlZW4oXG4gICAgICAgICAgICBgQXV0by1pbXBvcnRlZCAke2V4cGxvcmVSZXN1bHQubWFpbi5lbnRpdHlJZH0gd2l0aCByZWxhdGlvbnM6IGAgK1xuICAgICAgICAgICAgICBgJHtleHBsb3JlUmVzdWx0Lm1haW4ucmVjb3Jkcy5sZW5ndGh9IG1haW4gKyAke2V4cGxvcmVSZXN1bHQucmVsYXRlZC5zaXplfSByZWxhdGVkIGVudGl0aWVzYCxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBmaXh0dXJlR2VuZXJhdG9yIOyLpO2WiSAoRmFrZXIuanPrp4wg7KeA7JuQKVxuICAgKlxuICAgKiBmYWtlci4qIO2YleyLneydmCDtkZztmITsi53snYQg7JWI7KCE7ZWY6rKMIO2MjOyLse2VmOyXrCDsi6Ttlontlanri4jri6QuXG4gICAqIOyYiDogXCJmYWtlci5pbnRlcm5ldC5lbWFpbCgpXCIg4oaSIGZha2VyLmludGVybmV0LmVtYWlsKClcbiAgICog7JiIOiBcImZha2VyLmxvcmVtLndvcmRzKDMpXCIg4oaSIGZha2VyLmxvcmVtLndvcmRzKDMpXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVHZW5lcmF0b3IoXG4gICAgZ2VuZXJhdG9yOiBzdHJpbmcsXG4gICAgcHJvcDogRW50aXR5UHJvcCxcbiAgICBlbnRpdHk6IEVudGl0eSxcbiAgKTogUHJvbWlzZTxEYXRhRXhwbG9yZXJWYWx1ZT4ge1xuICAgIC8vIEZha2VyLmpzIO2RnO2YhOyLneunjCDsp4Dsm5BcbiAgICBpZiAoZ2VuZXJhdG9yLnN0YXJ0c1dpdGgoXCJmYWtlci5cIikpIHtcbiAgICAgIC8vIHVzZXJuYW1l7J2064KYIG5hbWUg7ZWE65Oc64qUIO2VnOq1reyWtCBmYWtlciDsgqzsmqlcbiAgICAgIGNvbnN0IGlzTmFtZUZpZWxkID0gcHJvcC5uYW1lID09PSBcInVzZXJuYW1lXCIgfHwgcHJvcC5uYW1lID09PSBcIm5hbWVcIjtcbiAgICAgIGNvbnN0IGZha2VyTW9kdWxlID0gYXdhaXQgaW1wb3J0KFwiQGZha2VyLWpzL2Zha2VyXCIpO1xuICAgICAgY29uc3QgZmFrZXIgPSBpc05hbWVGaWVsZCA/IGZha2VyTW9kdWxlLmZha2VyS08gOiBmYWtlck1vZHVsZS5mYWtlcjtcbiAgICAgIGNvbnN0IGV4cHIgPSBnZW5lcmF0b3Iuc2xpY2UoNik7IC8vIFwiZmFrZXIuXCIg7KCc6rGwXG5cbiAgICAgIHRyeSB7XG4gICAgICAgIC8vIO2VqOyImCDqsr3roZzsmYAg7J247J6QIO2MjOyLsVxuICAgICAgICBjb25zdCBtYXRjaCA9IGV4cHIubWF0Y2goL14oW1xcdy5dKykoPzpcXCgoLio/KVxcKSk/JC8pO1xuICAgICAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYEZpeHR1cmVHZW5lcmF0b3I6IEludmFsaWQgZmFrZXIgZXhwcmVzc2lvbiBmb3IgJHtwcm9wLm5hbWV9OiAke2dlbmVyYXRvcn1gLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBbLCBwYXRoLCBhcmdzU3RyXSA9IG1hdGNoO1xuICAgICAgICBjb25zdCBwYXJ0cyA9IHBhdGguc3BsaXQoXCIuXCIpO1xuXG4gICAgICAgIC8vIGZha2VyIOqwneyytOyXkOyEnCDtlajsiJgg7LC+6riwXG4gICAgICAgIGxldCBtZW1iZXIgPSBkeW5hbWljTmFtZXNwYWNlU2NoZW1hLnBhcnNlKGZha2VyKTtcbiAgICAgICAgZm9yIChjb25zdCBwYXJ0IG9mIHBhcnRzKSB7XG4gICAgICAgICAgaWYgKCEocGFydCBpbiBtZW1iZXIpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZpeHR1cmVHZW5lcmF0b3I6IEludmFsaWQgZmFrZXIgcGF0aCBmb3IgJHtwcm9wLm5hbWV9OiBmYWtlci4ke3BhdGh9YCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IG5leHRNZW1iZXIgPSBtZW1iZXJbcGFydF07XG4gICAgICAgICAgaWYgKHBhcnQgIT09IHBhcnRzLmF0KC0xKSkge1xuICAgICAgICAgICAgbWVtYmVyID0gZHluYW1pY05hbWVzcGFjZVNjaGVtYS5wYXJzZShuZXh0TWVtYmVyKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmbiA9IGZha2VyRnVuY3Rpb25TY2hlbWEucGFyc2UobWVtYmVyW3BhcnRzLmF0KC0xKSA/PyBcIlwiXSk7XG5cbiAgICAgICAgbGV0IGFyZ3M6IERhdGFFeHBsb3JlclZhbHVlW10gPSBbXTtcbiAgICAgICAgaWYgKGFyZ3NTdHI/LnRyaW0oKSkge1xuICAgICAgICAgIGFyZ3MgPSB0aGlzLnBhcnNlR2VuZXJhdG9yQXJncyhhcmdzU3RyLCBwcm9wLm5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRhdGFFeHBsb3JlclZhbHVlU2NoZW1hLnBhcnNlKGZuKC4uLmFyZ3MpKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICFpc1Rlc3QoKSAmJlxuICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgY2hhbGsueWVsbG93KFxuICAgICAgICAgICAgICBgRmFpbGVkIHRvIGV4ZWN1dGUgZ2VuZXJhdG9yIFwiJHtnZW5lcmF0b3J9XCIgZm9yICR7cHJvcC5uYW1lfSwgZmFsbGluZyBiYWNrIHRvIGRlZmF1bHQ6YCxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICApO1xuICAgICAgICByZXR1cm4gdGhpcy5nZW5lcmF0ZURlZmF1bHRWYWx1ZShwcm9wLCBlbnRpdHkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGZha2VyIOydtOyZuOydmCDtkZztmITsi53snYAg7KeA7JuQ7ZWY7KeAIOyViuydjFxuICAgICFpc1Rlc3QoKSAmJlxuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIGNoYWxrLnllbGxvdyhcbiAgICAgICAgICBgVW5zdXBwb3J0ZWQgZ2VuZXJhdG9yIGV4cHJlc3Npb24gZm9yICR7cHJvcC5uYW1lfTogJHtnZW5lcmF0b3J9LiBPbmx5IGZha2VyLiogZXhwcmVzc2lvbnMgYXJlIHN1cHBvcnRlZC4gVXNpbmcgZGVmYXVsdCB2YWx1ZS5gLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICByZXR1cm4gdGhpcy5nZW5lcmF0ZURlZmF1bHRWYWx1ZShwcm9wLCBlbnRpdHkpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VhOuTnOydmCDtg4DsnoXqs7wg7J2066aE7J2EIOu2hOyEne2VmOyXrCDsoIHsoIjtlZwg6riw67O46rCS7J2EIOyDneyEse2VqeuLiOuLpC5cbiAgICpcbiAgICog7Jqw7ISg7Iic7JyEOlxuICAgKiAxLiDtlYTrk5zrqoUg7Yyo7YS0IOunpOy5rSAoc2FsYXJ5LCBidWRnZXQg65OxIOydmOuvuOyeiOuKlCDrjbDsnbTthLApXG4gICAqIDIuIO2KueyImCDsvIDsnbTsiqQgKERlcGFydG1lbnQgbmFtZSDrk7Eg64+E66mU7J24IOyngOyLnSlcbiAgICogMy4g67Cw7Je0IO2DgOyehSAoSlNPTiDrsLDsl7QpXG4gICAqIDQuIEVudW0g7YOA7J6FXG4gICAqIDUuIO2DgOyeheuzhCDquLDrs7jqsJJcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2VuZXJhdGVEZWZhdWx0VmFsdWUoXG4gICAgcHJvcDogRW50aXR5UHJvcCxcbiAgICBlbnRpdHk/OiBFbnRpdHksXG4gICk6IFByb21pc2U8RGF0YUV4cGxvcmVyVmFsdWU+IHtcbiAgICBjb25zdCBmYWtlck1vZHVsZSA9IGF3YWl0IGltcG9ydChcIkBmYWtlci1qcy9mYWtlclwiKTtcbiAgICBjb25zdCBmYWtlciA9IGZha2VyTW9kdWxlLmZha2VyO1xuICAgIGNvbnN0IGZha2VyS08gPSBmYWtlck1vZHVsZS5mYWtlcktPO1xuICAgIGNvbnN0IGZha2VySkEgPSBmYWtlck1vZHVsZS5mYWtlckpBO1xuXG4gICAgY29uc3QgbG9jYWxlRmFrZXIgPSB0aGlzLmxvY2FsZSA9PT0gXCJrb1wiID8gZmFrZXJLTyA6IHRoaXMubG9jYWxlID09PSBcImphXCIgPyBmYWtlckpBIDogZmFrZXI7XG5cbiAgICAvKipcbiAgICAgKiAxLiBFbnRpdHktc3BlY2lmaWMg7Yq57IiYIOy8gOydtOyKpOulvCDrqLzsoIAg7LKY66as7ZWp64uI64ukLlxuICAgICAqIGZpZWxkX3BhdHRlcm5z67O064ukIOyasOyEoO2VmOyXrCwg7Yq57KCVIOyXlO2LsO2LsOydmCDtlYTrk5zsl5Ag64+E66mU7J247JeQIOunnuuKlCDqsJLsnYQg7IOd7ISx7ZWp64uI64ukLlxuICAgICAqIOyYiDogRGVwYXJ0bWVudC5uYW1lIOKGkiDtlZzqta3slrQg67aA7ISc66qFICjsgqzrnowg7J2066aE7J20IOyVhOuLmClcbiAgICAgKi9cblxuICAgIC8qKlxuICAgICAqIERlcGFydG1lbnQgbmFtZeydgCDtlZzqta3slrQg67aA7ISc66qFIOuqqeuhneyXkOyEnCDshKDtg53tlanri4jri6QuXG4gICAgICog6rOg7Jyg7ISx7J2EIOychO2VtCA3MCUg7ZmV66Wg66GcIHByZWZpeC9zdWZmaXjrpbwg7LaU6rCA7ZWp64uI64ukLlxuICAgICAqL1xuICAgIGlmIChlbnRpdHk/LmlkID09PSBcIkRlcGFydG1lbnRcIiAmJiBwcm9wLm5hbWUgPT09IFwibmFtZVwiKSB7XG4gICAgICBjb25zdCBkZXBhcnRtZW50cyA9IFtcbiAgICAgICAgXCLqsJzrsJztjIBcIixcbiAgICAgICAgXCLquLDtmo3tjIBcIixcbiAgICAgICAgXCLrp4jsvIDtjIXtjIBcIixcbiAgICAgICAgXCLsmIHsl4XtjIBcIixcbiAgICAgICAgXCLsnbjsgqztjIBcIixcbiAgICAgICAgXCLstJ3rrLTtjIBcIixcbiAgICAgICAgXCLsnqzrrLTtjIBcIixcbiAgICAgICAgXCLtmozqs4TtjIBcIixcbiAgICAgICAgXCLrspXrrLTtjIBcIixcbiAgICAgICAgXCLrlJTsnpDsnbjtjIBcIixcbiAgICAgICAgXCJJVO2MgFwiLFxuICAgICAgICBcIuqzoOqwneyngOybkO2MgFwiLFxuICAgICAgICBcIu2SiOyniOq0gOumrO2MgFwiLFxuICAgICAgICBcIuyXsOq1rOqwnOuwnO2MgFwiLFxuICAgICAgICBcIuyDneyCsO2MgFwiLFxuICAgICAgICBcIuq1rOunpO2MgFwiLFxuICAgICAgICBcIuusvOulmO2MgFwiLFxuICAgICAgXTtcbiAgICAgIGNvbnN0IHByZWZpeGVzID0gW1wi7Iug6recXCIsIFwi7Ya17ZWpXCIsIFwi7KCE6561XCIsIFwi6riA66Gc67KMXCIsIFwi65SU7KeA7YS4XCIsIFwi7ZW17IusXCJdO1xuICAgICAgY29uc3Qgc3VmZml4ZXMgPSBbXCIx7YyAXCIsIFwiMu2MgFwiLCBcIjPtjIBcIiwgXCJB7YyAXCIsIFwiQu2MgFwiLCBcIuuzuOu2gFwiLCBcIuyEvO2EsFwiLCBcIuq3uOujuVwiXTtcblxuICAgICAgY29uc3QgZGVwdCA9IGZha2VyLmhlbHBlcnMuYXJyYXlFbGVtZW50KGRlcGFydG1lbnRzKTtcblxuICAgICAgY29uc3QgcmFuZG9tID0gTWF0aC5yYW5kb20oKTtcbiAgICAgIGlmIChyYW5kb20gPiAwLjcpIHtcbiAgICAgICAgY29uc3QgcHJlZml4ID0gZmFrZXIuaGVscGVycy5hcnJheUVsZW1lbnQocHJlZml4ZXMpO1xuICAgICAgICByZXR1cm4gYCR7cHJlZml4fSAke2RlcHR9YDtcbiAgICAgIH1cbiAgICAgIGlmIChyYW5kb20gPiAwLjQpIHtcbiAgICAgICAgY29uc3Qgc3VmZml4ID0gZmFrZXIuaGVscGVycy5hcnJheUVsZW1lbnQoc3VmZml4ZXMpO1xuICAgICAgICByZXR1cm4gYCR7ZGVwdH0gJHtzdWZmaXh9YDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkZXB0O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIDIuIO2VhOuTnOuqheyXkOyEnCDsnZjrr7jrpbwg7LaU66Gg7ZWY7JesIO2YhOyLpOyggeyduCDrjbDsnbTthLDrpbwg7IOd7ISx7ZWp64uI64ukLlxuICAgICAqIOyYiDogc2FsYXJ5IOKGkiAzME1+MTUwTSAo7ZWc6rWtIOyXsOu0iSDrspTsnIQpXG4gICAgICogICAgIGJ1ZGdldCDihpIgMTBNfjUwME0gKO2UhOuhnOygne2KuCDsmIjsgrAg67KU7JyEKVxuICAgICAqL1xuICAgIGNvbnN0IGxvY2FsZU1hcHBpbmdzID0gdGhpcy5tYXBwaW5nc1t0aGlzLmxvY2FsZV0gfHwgdGhpcy5tYXBwaW5ncy5lbjtcbiAgICBjb25zdCBub3JtYWxpemVkTmFtZSA9IHByb3AubmFtZS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL18vZywgXCJcIik7XG5cbiAgICBmb3IgKGNvbnN0IFtwYXR0ZXJuLCBjb25maWddIG9mIE9iamVjdC5lbnRyaWVzKGxvY2FsZU1hcHBpbmdzLmZpZWxkX3BhdHRlcm5zKSkge1xuICAgICAgaWYgKG5vcm1hbGl6ZWROYW1lLmluY2x1ZGVzKHBhdHRlcm4udG9Mb3dlckNhc2UoKSkpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5leGVjdXRlRmFrZXJFeHByZXNzaW9uKGNvbmZpZy5mYWtlciwgcHJvcCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgICAgY2hhbGsueWVsbG93KFxuICAgICAgICAgICAgICAgIGBGYWlsZWQgdG8gZXhlY3V0ZSBmaWVsZCBwYXR0ZXJuIFwiJHtwYXR0ZXJufVwiIGZvciAke3Byb3AubmFtZX0sIGZhbGxpbmcgYmFjazpgLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICBlcnJvcixcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiAzLiBKU09OIO2DgOyeheydtOuptOyEnCDrsLDsl7Tsnbgg6rK97JqwIChTb25hbXVGaWxlW10sIHN0cmluZ1tdIOuTsSlcbiAgICAgKiDtlYTrk5zrqoUg7Yyo7YS07J2EIOuztOqzoCDsoIHsoIjtlZwg67Cw7Je0IOuNsOydtO2EsOulvCDsg53shLHtlanri4jri6QuXG4gICAgICovXG4gICAgaWYgKHByb3AudHlwZSA9PT0gXCJqc29uXCIgJiYgXCJpZFwiIGluIHByb3AgJiYgcHJvcC5pZCkge1xuICAgICAgaWYgKHByb3AuaWQuZW5kc1dpdGgoXCJbXVwiKSkge1xuICAgICAgICByZXR1cm4gdGhpcy5nZW5lcmF0ZUFycmF5VmFsdWUocHJvcCwgZW50aXR5LCBmYWtlciwgbG9jYWxlRmFrZXIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKiA0LiBFbnVtIO2DgOyeheydgCDsoJXsnZjrkJwg6rCSIOykkSDtlZjrgpjrpbwg656c642kIOyEoO2Dne2VqeuLiOuLpCAqL1xuICAgIGlmIChwcm9wLnR5cGUgPT09IFwiZW51bVwiKSB7XG4gICAgICBsZXQgZW51bVZhbHVlczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgaWYgKFwiZW51bVwiIGluIHByb3AgJiYgQXJyYXkuaXNBcnJheShwcm9wLmVudW0pICYmIHByb3AuZW51bS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVudW1WYWx1ZXMgPSBwcm9wLmVudW07XG4gICAgICB9IGVsc2UgaWYgKFwiaWRcIiBpbiBwcm9wICYmIHByb3AuaWQgJiYgZW50aXR5Py5lbnVtTGFiZWxzPy5bcHJvcC5pZF0pIHtcbiAgICAgICAgZW51bVZhbHVlcyA9IE9iamVjdC5rZXlzKGVudGl0eS5lbnVtTGFiZWxzW3Byb3AuaWRdKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVudW1WYWx1ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gZmFrZXIuaGVscGVycy5hcnJheUVsZW1lbnQoZW51bVZhbHVlcyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcHJvcC5udWxsYWJsZSA/IG51bGwgOiBcIlVOS05PV05cIjtcbiAgICB9XG5cbiAgICBpZiAocHJvcC50eXBlID09PSBcImVudW1bXVwiKSB7XG4gICAgICBsZXQgZW51bVZhbHVlczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgaWYgKFwiZW51bVwiIGluIHByb3AgJiYgQXJyYXkuaXNBcnJheShwcm9wLmVudW0pICYmIHByb3AuZW51bS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVudW1WYWx1ZXMgPSBwcm9wLmVudW07XG4gICAgICB9IGVsc2UgaWYgKFwiaWRcIiBpbiBwcm9wICYmIHByb3AuaWQgJiYgZW50aXR5Py5lbnVtTGFiZWxzPy5bcHJvcC5pZF0pIHtcbiAgICAgICAgZW51bVZhbHVlcyA9IE9iamVjdC5rZXlzKGVudGl0eS5lbnVtTGFiZWxzW3Byb3AuaWRdKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVudW1WYWx1ZXMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gW2Zha2VyLmhlbHBlcnMuYXJyYXlFbGVtZW50KGVudW1WYWx1ZXMpXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiA1LiBWZWN0b3Ig7YOA7J6F7J2AIO2YhOyerCDsp4Dsm5DtlZjsp4Ag7JWK7Jy866+A66GcIG51bGzsnYQg67CY7ZmY7ZWp64uI64ukLlxuICAgICAqIO2Wpe2bhCBBSSBlbWJlZGRpbmcg7IOd7ISxIOq4sOuKpSDstpTqsIAg7IucIOq1rO2YhCDsmIjsoJXsnoXri4jri6QuXG4gICAgICovXG4gICAgaWYgKHByb3AudHlwZSA9PT0gXCJ2ZWN0b3JcIiB8fCBwcm9wLnR5cGUgPT09IFwidmVjdG9yW11cIiB8fCBwcm9wLnR5cGUgPT09IFwidHN2ZWN0b3JcIikge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLyoqIDYuIO2DgOyeheuzhCDquLDrs7ggRmFrZXIg7ZGc7ZiE7Iud7J2EIOyLpO2Wie2VqeuLiOuLpCAqL1xuICAgIGNvbnN0IHR5cGVEZWZhdWx0ID0gbG9jYWxlTWFwcGluZ3MudHlwZV9kZWZhdWx0c1twcm9wLnR5cGVdO1xuICAgIGlmICh0eXBlRGVmYXVsdCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZXhlY3V0ZUZha2VyRXhwcmVzc2lvbih0eXBlRGVmYXVsdC5mYWtlciwgcHJvcCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgICAgIGNoYWxrLnllbGxvdyhgRmFpbGVkIHRvIGV4ZWN1dGUgdHlwZSBkZWZhdWx0IGZvciAke3Byb3AudHlwZX0sIHVzaW5nIGZhbGxiYWNrOmAsIGVycm9yKSxcbiAgICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8qKiA3LiDrp6TtlZHrkJjsp4Ag7JWK7J2AIO2DgOyeheydgCDquLDrs7ggRmFrZXIg7ZWo7IiY66GcIOyymOumrO2VqeuLiOuLpCAqL1xuICAgIHN3aXRjaCAocHJvcC50eXBlKSB7XG4gICAgICBjYXNlIFwic3RyaW5nXCI6XG4gICAgICBjYXNlIFwic3RyaW5nW11cIjpcbiAgICAgICAgcmV0dXJuIGZha2VyLmxvcmVtLndvcmRzKDMpO1xuICAgICAgY2FzZSBcImludGVnZXJcIjpcbiAgICAgICAgcmV0dXJuIGZha2VyLm51bWJlci5pbnQoeyBtaW46IDEsIG1heDogMTAwMCB9KTtcbiAgICAgIGNhc2UgXCJpbnRlZ2VyW11cIjpcbiAgICAgICAgcmV0dXJuIFtmYWtlci5udW1iZXIuaW50KHsgbWluOiAxLCBtYXg6IDEwMDAgfSldO1xuICAgICAgY2FzZSBcImJpZ0ludGVnZXJcIjpcbiAgICAgICAgcmV0dXJuIGZha2VyLm51bWJlci5iaWdJbnQoeyBtaW46IDFuLCBtYXg6IDEwMDBuIH0pO1xuICAgICAgY2FzZSBcImJpZ0ludGVnZXJbXVwiOlxuICAgICAgICByZXR1cm4gW2Zha2VyLm51bWJlci5iaWdJbnQoeyBtaW46IDFuLCBtYXg6IDEwMDBuIH0pXTtcbiAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgIGNhc2UgXCJudW1lcmljXCI6XG4gICAgICAgIHJldHVybiBmYWtlci5udW1iZXIuZmxvYXQoeyBtaW46IDAsIG1heDogMTAwMCB9KTtcbiAgICAgIGNhc2UgXCJudW1iZXJbXVwiOlxuICAgICAgY2FzZSBcIm51bWVyaWNbXVwiOlxuICAgICAgICByZXR1cm4gW2Zha2VyLm51bWJlci5mbG9hdCh7IG1pbjogMCwgbWF4OiAxMDAwIH0pXTtcbiAgICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICAgIHJldHVybiBmYWtlci5kYXRhdHlwZS5ib29sZWFuKCk7XG4gICAgICBjYXNlIFwiYm9vbGVhbltdXCI6XG4gICAgICAgIHJldHVybiBbZmFrZXIuZGF0YXR5cGUuYm9vbGVhbigpXTtcbiAgICAgIGNhc2UgXCJkYXRlXCI6XG4gICAgICBjYXNlIFwiZGF0ZVtdXCI6XG4gICAgICAgIHJldHVybiBmYWtlci5kYXRlLnBhc3QoKTtcbiAgICAgIGNhc2UgXCJqc29uXCI6XG4gICAgICAgIHJldHVybiB7fTtcbiAgICAgIGNhc2UgXCJ1dWlkXCI6XG4gICAgICBjYXNlIFwidXVpZFtdXCI6XG4gICAgICAgIHJldHVybiBmYWtlci5zdHJpbmcudXVpZCgpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIOuwsOyXtCDtg4DsnoXsnZgg6rCS7J2EIOyDneyEse2VqeuLiOuLpC5cbiAgICpcbiAgICog7YOA7J6FIElE7JmAIO2VhOuTnOuqhSDtjKjthLTsnYQg67aE7ISd7ZWY7JesIOyggeygiO2VnCDrsLDsl7Qg642w7J207YSw66W8IOyDneyEse2VqeuLiOuLpC5cbiAgICog7JiIOiBpbWFnZV91cmxzIOKGkiBbe3VybCwgbmFtZSwgbWltZV90eXBlfSwgLi4uXVxuICAgKiAgICAgdGFnX2lkcyDihpIgWzEsIDIzLCA0NV1cbiAgICovXG4gIHByaXZhdGUgZ2VuZXJhdGVBcnJheVZhbHVlKFxuICAgIHByb3A6IEVudGl0eVByb3AsXG4gICAgX2VudGl0eTogRW50aXR5IHwgdW5kZWZpbmVkLFxuICAgIGZha2VyOiB0eXBlb2YgaW1wb3J0KFwiQGZha2VyLWpzL2Zha2VyXCIpLmZha2VyLFxuICAgIF9sb2NhbGVGYWtlcjogdHlwZW9mIGltcG9ydChcIkBmYWtlci1qcy9mYWtlclwiKS5mYWtlcixcbiAgKTogRGF0YUV4cGxvcmVyVmFsdWVbXSB7XG4gICAgY29uc3QgY291bnQgPSBmYWtlci5udW1iZXIuaW50KHsgbWluOiAxLCBtYXg6IDMgfSk7XG5cbiAgICAvKiogU29uYW11RmlsZVtd7J2AIFNvbmFtdSDrgrTsnqUg7YOA7J6F7Jy866GcIOq1rOyhsOqwgCDsoJXtlbTsoLgg7J6I7Iq164uI64ukICovXG4gICAgaWYgKFwiaWRcIiBpbiBwcm9wICYmIHByb3AuaWQgPT09IFwiU29uYW11RmlsZVtdXCIpIHtcbiAgICAgIHJldHVybiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBjb3VudCB9LCAoKSA9PiAoe1xuICAgICAgICB1cmw6IGZha2VyLmltYWdlLnVybCgpLFxuICAgICAgICBuYW1lOiBmYWtlci5zeXN0ZW0uZmlsZU5hbWUoKSxcbiAgICAgICAgbWltZV90eXBlOiBmYWtlci5oZWxwZXJzLmFycmF5RWxlbWVudChbXG4gICAgICAgICAgXCJpbWFnZS9qcGVnXCIsXG4gICAgICAgICAgXCJpbWFnZS9wbmdcIixcbiAgICAgICAgICBcImltYWdlL2dpZlwiLFxuICAgICAgICAgIFwiYXBwbGljYXRpb24vcGRmXCIsXG4gICAgICAgIF0pLFxuICAgICAgfSkpO1xuICAgIH1cblxuICAgIC8qKiDtlYTrk5zrqoXsl5DshJwg67Cw7Je07J2YIOyaqeuPhOulvCDstpTroaDtlanri4jri6QgKi9cbiAgICBjb25zdCBub3JtYWxpemVkTmFtZSA9IHByb3AubmFtZS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL18vZywgXCJcIik7XG5cbiAgICBpZiAobm9ybWFsaXplZE5hbWUuaW5jbHVkZXMoXCJ1cmxcIikgfHwgbm9ybWFsaXplZE5hbWUuaW5jbHVkZXMoXCJpbWFnZVwiKSkge1xuICAgICAgcmV0dXJuIEFycmF5LmZyb20oeyBsZW5ndGg6IGNvdW50IH0sICgpID0+IGZha2VyLmludGVybmV0LnVybCgpKTtcbiAgICB9XG5cbiAgICBpZiAobm9ybWFsaXplZE5hbWUuaW5jbHVkZXMoXCJpZFwiKSAmJiBub3JtYWxpemVkTmFtZS5lbmRzV2l0aChcInNcIikpIHtcbiAgICAgIHJldHVybiBBcnJheS5mcm9tKHsgbGVuZ3RoOiBjb3VudCB9LCAoKSA9PiBmYWtlci5udW1iZXIuaW50KHsgbWluOiAxLCBtYXg6IDEwMCB9KSk7XG4gICAgfVxuXG4gICAgaWYgKG5vcm1hbGl6ZWROYW1lLmluY2x1ZGVzKFwidGFnXCIpIHx8IG5vcm1hbGl6ZWROYW1lLmluY2x1ZGVzKFwibmFtZVwiKSkge1xuICAgICAgcmV0dXJuIEFycmF5LmZyb20oeyBsZW5ndGg6IGNvdW50IH0sICgpID0+IGZha2VyLmxvcmVtLndvcmQoKSk7XG4gICAgfVxuXG4gICAgLyoqIO2MqO2EtCDrp6Tsua3rkJjsp4Ag7JWK7Jy866m0IOu5iCDrsLDsl7TsnYQg67CY7ZmY7ZWp64uI64ukICovXG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIEpTT04g66ek7ZWR7J2YIEZha2VyIO2RnO2YhOyLneydhCDtjIzsi7HtlZjsl6wg7Iuk7ZaJ7ZWp64uI64ukLlxuICAgKlxuICAgKiDtkZztmITsi50g7JiI7IucOlxuICAgKiAtIFwiZmFrZXIuaW50ZXJuZXQuZW1haWwoKVwiIOKGkiDsnbjsnpAg7JeG7J2MXG4gICAqIC0gXCJmYWtlci5udW1iZXIuaW50KHsgbWluOiAxLCBtYXg6IDEwMCB9KVwiIOKGkiBKU09OIOyduOyekFxuICAgKiAtIFwie31cIiDihpIg66as7YSw65+0IOqwkiAoSlNPTi5wYXJzZSlcbiAgICpcbiAgICogZmFrZXJLTywgZmFrZXJKQeuPhCDsp4Dsm5DtlZjsl6wg64uk6rWt7Ja0IOuNsOydtO2EsOulvCDsg53shLHtlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVGYWtlckV4cHJlc3Npb24oXG4gICAgZXhwcmVzc2lvbjogc3RyaW5nLFxuICAgIHByb3A6IEVudGl0eVByb3AsXG4gICk6IFByb21pc2U8RGF0YUV4cGxvcmVyVmFsdWU+IHtcbiAgICBjb25zdCBmYWtlck1vZHVsZSA9IGF3YWl0IGltcG9ydChcIkBmYWtlci1qcy9mYWtlclwiKTtcbiAgICBjb25zdCBmYWtlciA9IGZha2VyTW9kdWxlLmZha2VyO1xuICAgIGNvbnN0IGZha2VyS08gPSBmYWtlck1vZHVsZS5mYWtlcktPO1xuICAgIGNvbnN0IGZha2VySkEgPSBmYWtlck1vZHVsZS5mYWtlckpBO1xuXG4gICAgLyoqIEZha2VyIO2RnO2YhOyLneydtCDslYTri4wg66as7YSw65+0IOqwkuydgCBKU09O7Jy866GcIO2MjOyLse2VqeuLiOuLpCAqL1xuICAgIGlmICghZXhwcmVzc2lvbi5zdGFydHNXaXRoKFwiZmFrZXJcIikpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBkYXRhRXhwbG9yZXJWYWx1ZVNjaGVtYS5wYXJzZShKU09OLnBhcnNlKGV4cHJlc3Npb24pKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gZXhwcmVzc2lvbjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvKiog7ZGc7ZiE7Iud7JeQ7IScIEZha2VyIOqwneyytOyZgCDqsr3roZzrpbwg7LaU7Lac7ZWp64uI64ukICovXG4gICAgY29uc3QgbWF0Y2ggPSBleHByZXNzaW9uLm1hdGNoKC9eKGZha2VyfGZha2VyS098ZmFrZXJKQSlcXC4oLio/KSQvKTtcbiAgICBpZiAoIW1hdGNoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZmFrZXIgZXhwcmVzc2lvbjogJHtleHByZXNzaW9ufWApO1xuICAgIH1cblxuICAgIGNvbnN0IFssIGZha2VyTmFtZSwgZXhwcl0gPSBtYXRjaDtcbiAgICBjb25zdCBzZWxlY3RlZEZha2VyID1cbiAgICAgIGZha2VyTmFtZSA9PT0gXCJmYWtlcktPXCIgPyBmYWtlcktPIDogZmFrZXJOYW1lID09PSBcImZha2VySkFcIiA/IGZha2VySkEgOiBmYWtlcjtcblxuICAgIGNvbnN0IGZ1bmNNYXRjaCA9IGV4cHIubWF0Y2goL14oW1xcdy5dKykoPzpcXCgoLio/KVxcKSk/JC8pO1xuICAgIGlmICghZnVuY01hdGNoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgZmFrZXIgZXhwcmVzc2lvbiBmb3IgJHtwcm9wLm5hbWV9OiAke2V4cHJlc3Npb259YCk7XG4gICAgfVxuXG4gICAgY29uc3QgWywgcGF0aCwgYXJnc1N0cl0gPSBmdW5jTWF0Y2g7XG4gICAgY29uc3QgcGFydHMgPSBwYXRoLnNwbGl0KFwiLlwiKTtcblxuICAgIC8qKiDsoJAg7ZGc6riw67KVKGRvdCBub3RhdGlvbinsnLzroZwgRmFrZXIg7ZWo7IiY66W8IOywvuyVhOqwkeuLiOuLpCAqL1xuICAgIGxldCBtZW1iZXIgPSBkeW5hbWljTmFtZXNwYWNlU2NoZW1hLnBhcnNlKHNlbGVjdGVkRmFrZXIpO1xuICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cykge1xuICAgICAgaWYgKCEocGFydCBpbiBtZW1iZXIpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBmYWtlciBwYXRoIGZvciAke3Byb3AubmFtZX06ICR7ZmFrZXJOYW1lfS4ke3BhdGh9YCk7XG4gICAgICB9XG4gICAgICBjb25zdCBuZXh0TWVtYmVyID0gbWVtYmVyW3BhcnRdO1xuICAgICAgaWYgKHBhcnQgIT09IHBhcnRzLmF0KC0xKSkge1xuICAgICAgICBtZW1iZXIgPSBkeW5hbWljTmFtZXNwYWNlU2NoZW1hLnBhcnNlKG5leHRNZW1iZXIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGZuID0gZmFrZXJGdW5jdGlvblNjaGVtYS5wYXJzZShtZW1iZXJbcGFydHMuYXQoLTEpID8/IFwiXCJdKTtcblxuICAgIGxldCBhcmdzOiBEYXRhRXhwbG9yZXJWYWx1ZVtdID0gW107XG4gICAgaWYgKGFyZ3NTdHI/LnRyaW0oKSkge1xuICAgICAgYXJncyA9IHRoaXMucGFyc2VHZW5lcmF0b3JBcmdzKGFyZ3NTdHIsIHByb3AubmFtZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGFFeHBsb3JlclZhbHVlU2NoZW1hLnBhcnNlKGZuKC4uLmFyZ3MpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBmaXh0dXJlSGludOulvCBMTE3sl5Dqsowg7KCE64us7ZWY7JesIO2YhOyLpOyggeyduCDthYzsiqTtirgg642w7J207YSw66W8IOyDneyEse2VqeuLiOuLpC5cbiAgICpcbiAgICogZmFrZXIuanProZzripQg7IOd7ISx7ZWY6riwIOyWtOugpOyatCDrs7XsnqHtlZwg7YWN7Iqk7Yq4KOyekOq4sOyGjOqwnCwg7ISk66qF66y4IOuTsSnrpbxcbiAgICogTExN7J2EIO2ZnOyaqe2VmOyXrCDsg53shLHtlanri4jri6QuIOuPmeydvO2VnCBoaW507JeQIOuMgO2VnCDspJHrs7Ug7Zi47Lac7J2EIOuwqeyngO2VmOq4sCDsnITtlbRcbiAgICog7LqQ7Iux7J2EIOq4sOuzuOycvOuhnCDsp4Dsm5Dtlanri4jri6QgKExMTSBBUEkg67mE7JqpIOygiOqwkCkuXG4gICAqXG4gICAqIGFpIO2MqO2CpOyngOuKlCBkeW5hbWljIGltcG9ydOuhnCDrtojrn6zsmKTrr4DroZwsIHVzZUxMTeydtCBmYWxzZeyduCDqsr3smrBcbiAgICog7J2Y7KG07ISx7J20IOyEpOy5mOuQmOyngCDslYrslYTrj4QgZml4dHVyZSDsg53shLHsnbQg7KCV7IOBIOuPmeyeke2VqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2VuZXJhdGVXaXRoTExNKFxuICAgIGZpeHR1cmVIaW50OiBzdHJpbmcsXG4gICAgcHJvcDogRW50aXR5UHJvcCxcbiAgICBlbnRpdHk6IEVudGl0eSxcbiAgICByb3dLZXk/OiBzdHJpbmcsXG4gICk6IFByb21pc2U8RGF0YUV4cGxvcmVyVmFsdWU+IHtcbiAgICAvLyByb3dLZXnqsIAg7J6I7Jy866m0IHJvdyDri6jsnIQg7IOd7ISxIOyghOuetSDsgqzsmqlcbiAgICBpZiAocm93S2V5KSB7XG4gICAgICBjb25zdCByb3dDYWNoZUtleSA9IGAke3Jvd0tleX06JHtwcm9wLm5hbWV9YDtcblxuICAgICAgLy8g7J2066+4IOydtCByb3fsl5Ag64yA7ZWcIExMTSDtmLjstpzsnbQg7JmE66OM65CcIOqyveyasCDsupDsi5zsl5DshJwg67CU66GcIOuwmO2ZmFxuICAgICAgaWYgKHRoaXMubGxtQ2FjaGUuaGFzKHJvd0NhY2hlS2V5KSkge1xuICAgICAgICByZXR1cm4gdGhpcy5sbG1DYWNoZS5nZXQocm93Q2FjaGVLZXkpO1xuICAgICAgfVxuXG4gICAgICAvLyDsg4ggcm93OiBMTE0g64yA7IOBIHByb3Ag7KCE7LK066W8IO2VnCDrsojsl5Ag7IOd7ISxXG4gICAgICBjb25zdCBsbG1Qcm9wcyA9IGVudGl0eS5wcm9wcy5maWx0ZXIoKHApID0+IHtcbiAgICAgICAgaWYgKGlzUmVsYXRpb25Qcm9wKHApKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGlmIChwLmNvbmU/LmZpeHR1cmVHZW5lcmF0b3IpIHJldHVybiBmYWxzZTtcbiAgICAgICAgaWYgKHAubmFtZSA9PT0gXCJpZFwiKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIHJldHVybiAhIXAuY29uZT8ubm90ZTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBsbG1Qcm9wc+qwgCDruYTslrTsnojsnLzrqbQg64uo7J28IO2VhOuTnCDrsKnsi53snLzroZwgZmFsbGJhY2tcbiAgICAgIGlmIChsbG1Qcm9wcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBgW0ZpeHR1cmVHZW5lcmF0b3JdIGxsbVByb3BzIGlzIGVtcHR5IGZvciAke2VudGl0eS5pZH0uJHtwcm9wLm5hbWV9LCB1c2luZyBzaW5nbGUgZmllbGQgZmFsbGJhY2tgLFxuICAgICAgICAgICk7XG4gICAgICAgIHJldHVybiB0aGlzLmdlbmVyYXRlU2luZ2xlV2l0aExMTShmaXh0dXJlSGludCwgcHJvcCwgZW50aXR5KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgYXBpS2V5ID0gdGhpcy5nZXRBcGlLZXkoKTtcbiAgICAgIGNvbnN0IHsgY3JlYXRlQW50aHJvcGljIH0gPSBhd2FpdCBpbXBvcnQoXCJAYWktc2RrL2FudGhyb3BpY1wiKTtcbiAgICAgIGNvbnN0IGdlbmVyYXRlVGV4dCA9IGF3YWl0IHRoaXMuZ2V0VGV4dEdlbmVyYXRvcigpO1xuXG4gICAgICBjb25zdCByb3dSZXNwb25zZSA9IGF3YWl0IGdlbmVyYXRlVGV4dCh7XG4gICAgICAgIG1vZGVsOiBjcmVhdGVBbnRocm9waWMoeyBhcGlLZXkgfSkodGhpcy5vcHRpb25zLmxsbU1vZGVsIHx8IFwiY2xhdWRlLXNvbm5ldC00LTZcIiksXG4gICAgICAgIHByb21wdDogdGhpcy5idWlsZFJvd0xMTVByb21wdChsbG1Qcm9wcywgZW50aXR5KSxcbiAgICAgIH0pO1xuICAgICAgY29uc3Qgcm93UmVzcG9uc2VUZXh0ID0gei5zdHJpbmcoKS5zYWZlUGFyc2Uocm93UmVzcG9uc2U/LnRleHQpO1xuICAgICAgaWYgKCFyb3dSZXNwb25zZVRleHQuc3VjY2Vzcykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIExMTSByZXNwb25zZVwiKTtcbiAgICAgIH1cblxuICAgICAgLy8g7J2R64u17J2EIO2MjOyLse2VmOyXrCDqsIEg7ZWE65Oc7JeQIOuMgO2VnCDqsrDqs7zrpbwg7LqQ7Iuc7JeQIOyggOyepVxuICAgICAgY29uc3Qgcm93UmVzdWx0ID0gdGhpcy5wYXJzZVJvd0xMTVJlc3BvbnNlKHJvd1Jlc3BvbnNlVGV4dC5kYXRhLCBsbG1Qcm9wcyk7XG4gICAgICBmb3IgKGNvbnN0IFtmaWVsZE5hbWUsIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhyb3dSZXN1bHQpKSB7XG4gICAgICAgIHRoaXMubGxtQ2FjaGUuc2V0KGAke3Jvd0tleX06JHtmaWVsZE5hbWV9YCwgdmFsdWUpO1xuICAgICAgfVxuXG4gICAgICAvLyDsmpTssq3tlZwg7ZWE65Oc7J2YIOqwkiDrsJjtmZggKOyXhuycvOuptCDri6jsnbwg7ZWE65OcIGZhbGxiYWNrKVxuICAgICAgaWYgKHRoaXMubGxtQ2FjaGUuaGFzKHJvd0NhY2hlS2V5KSkge1xuICAgICAgICByZXR1cm4gdGhpcy5sbG1DYWNoZS5nZXQocm93Q2FjaGVLZXkpO1xuICAgICAgfVxuXG4gICAgICAvLyDrp4zslb0gcm93IOydkeuLteyXkCDsnbQg7ZWE65Oc6rCAIOuIhOudveuQnCDqsr3smrAg64uo7J28IO2VhOuTnCBmYWxsYmFja1xuICAgICAgcmV0dXJuIHRoaXMuZ2VuZXJhdGVTaW5nbGVXaXRoTExNKGZpeHR1cmVIaW50LCBwcm9wLCBlbnRpdHkpO1xuICAgIH1cblxuICAgIC8vIHJvd0tleeqwgCDsl4bsnLzrqbQg6riw7KG0IOuLqOydvCDtlYTrk5wg67Cp7IudXG4gICAgcmV0dXJuIHRoaXMuZ2VuZXJhdGVTaW5nbGVXaXRoTExNKGZpeHR1cmVIaW50LCBwcm9wLCBlbnRpdHkpO1xuICB9XG5cbiAgLyoqXG4gICAqIOuLqOydvCDtlYTrk5zrpbwgTExN7Jy866GcIOyDneyEse2VqeuLiOuLpCAocm93S2V5IOyXhuydhCDrlYwgZmFsbGJhY2vsmqkpXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdlbmVyYXRlU2luZ2xlV2l0aExMTShcbiAgICBmaXh0dXJlSGludDogc3RyaW5nLFxuICAgIHByb3A6IEVudGl0eVByb3AsXG4gICAgZW50aXR5OiBFbnRpdHksXG4gICk6IFByb21pc2U8RGF0YUV4cGxvcmVyVmFsdWU+IHtcbiAgICBjb25zdCBjYWNoZUtleSA9IGAke2VudGl0eS5pZH06JHtwcm9wLm5hbWV9OiR7Zml4dHVyZUhpbnR9YDtcbiAgICBpZiAodGhpcy5vcHRpb25zLmVuYWJsZUxMTUNhY2hlICYmIHRoaXMubGxtQ2FjaGUuaGFzKGNhY2hlS2V5KSkge1xuICAgICAgcmV0dXJuIHRoaXMubGxtQ2FjaGUuZ2V0KGNhY2hlS2V5KTtcbiAgICB9XG5cbiAgICBjb25zdCBhcGlLZXkgPSB0aGlzLmdldEFwaUtleSgpO1xuICAgIGNvbnN0IHsgY3JlYXRlQW50aHJvcGljIH0gPSBhd2FpdCBpbXBvcnQoXCJAYWktc2RrL2FudGhyb3BpY1wiKTtcbiAgICBjb25zdCBnZW5lcmF0ZVRleHQgPSBhd2FpdCB0aGlzLmdldFRleHRHZW5lcmF0b3IoKTtcblxuICAgIGNvbnN0IHNpbmdsZVJlc3BvbnNlID0gYXdhaXQgZ2VuZXJhdGVUZXh0KHtcbiAgICAgIG1vZGVsOiBjcmVhdGVBbnRocm9waWMoeyBhcGlLZXkgfSkodGhpcy5vcHRpb25zLmxsbU1vZGVsIHx8IFwiY2xhdWRlLXNvbm5ldC00LTZcIiksXG4gICAgICBwcm9tcHQ6IHRoaXMuYnVpbGRMTE1Qcm9tcHQoZml4dHVyZUhpbnQsIHByb3AsIGVudGl0eSksXG4gICAgfSk7XG4gICAgY29uc3Qgc2luZ2xlUmVzcG9uc2VUZXh0ID0gei5zdHJpbmcoKS5zYWZlUGFyc2Uoc2luZ2xlUmVzcG9uc2U/LnRleHQpO1xuICAgIGlmICghc2luZ2xlUmVzcG9uc2VUZXh0LnN1Y2Nlc3MpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgTExNIHJlc3BvbnNlXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5wYXJzZUxMTVJlc3BvbnNlKHNpbmdsZVJlc3BvbnNlVGV4dC5kYXRhLCBwcm9wLnR5cGUpO1xuICAgIGlmICh0aGlzLm9wdGlvbnMuZW5hYmxlTExNQ2FjaGUpIHtcbiAgICAgIHRoaXMubGxtQ2FjaGUuc2V0KGNhY2hlS2V5LCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBnZXRUZXh0R2VuZXJhdG9yKCk6IFByb21pc2U8Rml4dHVyZVRleHRHZW5lcmF0b3I+IHtcbiAgICBpZiAodGhpcy5vcHRpb25zLmdlbmVyYXRlVGV4dCkge1xuICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy5nZW5lcmF0ZVRleHQ7XG4gICAgfVxuICAgIGNvbnN0IGFpID0gYXdhaXQgaW1wb3J0KFwiYWlcIik7XG4gICAgcmV0dXJuIGFzeW5jIChyZXF1ZXN0KSA9PiBhaS5nZW5lcmF0ZVRleHQocmVxdWVzdCk7XG4gIH1cblxuICAvKipcbiAgICogcm93IOyghOyytOulvCDtlZwg67KI7JeQIOyDneyEse2VmOuKlCBMTE0g7ZSE66Gs7ZSE7Yq466W8IOunjOuTreuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgYnVpbGRSb3dMTE1Qcm9tcHQocHJvcHM6IEVudGl0eVByb3BbXSwgZW50aXR5OiBFbnRpdHkpOiBzdHJpbmcge1xuICAgIGNvbnN0IGxvY2FsZSA9IHRoaXMub3B0aW9ucy5sb2NhbGUgfHwgXCJrb1wiO1xuICAgIGNvbnN0IGxhbmd1YWdlID0gbG9jYWxlID09PSBcImtvXCIgPyBcIktvcmVhblwiIDogbG9jYWxlID09PSBcImphXCIgPyBcIkphcGFuZXNlXCIgOiBcIkVuZ2xpc2hcIjtcblxuICAgIGNvbnN0IGZpZWxkRGVzY3JpcHRpb25zID0gcHJvcHNcbiAgICAgIC5tYXAoKHApID0+IHtcbiAgICAgICAgbGV0IGRlc2MgPSBgLSAke3AubmFtZX0gKCR7cC50eXBlfSk6ICR7cC5jb25lPy5ub3RlID8/IFwiXCJ9YDtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIChwLnR5cGUgPT09IFwiZW51bVwiIHx8IHAudHlwZSA9PT0gXCJlbnVtW11cIikgJiZcbiAgICAgICAgICBcImlkXCIgaW4gcCAmJlxuICAgICAgICAgIHAuaWQgJiZcbiAgICAgICAgICBlbnRpdHkuZW51bUxhYmVscz8uW3AuaWRdXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IHZhbHVlcyA9IE9iamVjdC5rZXlzKGVudGl0eS5lbnVtTGFiZWxzW3AuaWRdKS5qb2luKFwiLCBcIik7XG4gICAgICAgICAgZGVzYyArPSBgIFthbGxvd2VkIHZhbHVlczogJHt2YWx1ZXN9XWA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGRlc2M7XG4gICAgICB9KVxuICAgICAgLmpvaW4oXCJcXG5cIik7XG5cbiAgICAvLyBMTE0g64yA7IOB7J20IOyVhOuLjCBwcm9w65Ok64+EIOunpeudveycvOuhnCDsoJzqs7UgKHJlbGF0aW9uIOygnOyZuClcbiAgICBjb25zdCBvdGhlclByb3BzID0gZW50aXR5LnByb3BzXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAocCkgPT5cbiAgICAgICAgICAhcHJvcHMuaW5jbHVkZXMocCkgJiZcbiAgICAgICAgICAhaXNSZWxhdGlvblByb3AocCkgJiZcbiAgICAgICAgICBwLm5hbWUgIT09IFwiaWRcIiAmJlxuICAgICAgICAgICEoXCJ2aXJ0dWFsXCIgaW4gcCAmJiBwLnZpcnR1YWwpLFxuICAgICAgKVxuICAgICAgLm1hcCgocCkgPT4ge1xuICAgICAgICBsZXQgZGVzYyA9IGAtICR7cC5uYW1lfSAoJHtwLnR5cGV9KWA7XG4gICAgICAgIGlmIChwLmNvbmU/Lm5vdGUpIGRlc2MgKz0gYDogJHtwLmNvbmUubm90ZX1gO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgKHAudHlwZSA9PT0gXCJlbnVtXCIgfHwgcC50eXBlID09PSBcImVudW1bXVwiKSAmJlxuICAgICAgICAgIFwiaWRcIiBpbiBwICYmXG4gICAgICAgICAgcC5pZCAmJlxuICAgICAgICAgIGVudGl0eS5lbnVtTGFiZWxzPy5bcC5pZF1cbiAgICAgICAgKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWVzID0gT2JqZWN0LmtleXMoZW50aXR5LmVudW1MYWJlbHNbcC5pZF0pLmpvaW4oXCIsIFwiKTtcbiAgICAgICAgICBkZXNjICs9IGAgW2FsbG93ZWQgdmFsdWVzOiAke3ZhbHVlc31dYDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZGVzYztcbiAgICAgIH0pXG4gICAgICAuam9pbihcIlxcblwiKTtcbiAgICBjb25zdCBvdGhlclByb3BzQ29udGV4dCA9IG90aGVyUHJvcHNcbiAgICAgID8gYFxcblxcbk90aGVyIGZpZWxkcyBpbiB0aGlzIGVudGl0eSAoZm9yIGNvbnRleHQsIGRvIE5PVCBnZW5lcmF0ZSB0aGVzZSk6XFxuJHtvdGhlclByb3BzfWBcbiAgICAgIDogXCJcIjtcblxuICAgIGNvbnN0IHJlc3VsdFRlbXBsYXRlID0gcHJvcHMubWFwKChwKSA9PiBgICBcIiR7cC5uYW1lfVwiOiA8JHtwLnR5cGV9PmApLmpvaW4oXCIsXFxuXCIpO1xuXG4gICAgY29uc3QgZW50aXR5Q29udGV4dCA9IGVudGl0eS5jb25lPy5ub3RlID8gYFxcbkVudGl0eSBkZXNjcmlwdGlvbjogJHtlbnRpdHkuY29uZS5ub3RlfWAgOiBcIlwiO1xuXG4gICAgcmV0dXJuIGBHZW5lcmF0ZSB0ZXN0IGZpeHR1cmUgZGF0YSBmb3IgdGhlICR7ZW50aXR5LmlkfSBlbnRpdHkuIEFsbCBmaWVsZHMgbXVzdCBiZSBjb2hlcmVudCBhbmQgY29uc2lzdGVudCB3aXRoIGVhY2ggb3RoZXIuXG5cbkVudGl0eTogJHtlbnRpdHkuaWR9JHtlbnRpdHlDb250ZXh0fVxuTG9jYWxlOiAke2xvY2FsZX0gKHVzZSAke2xhbmd1YWdlfSBmb3IgdGV4dCBmaWVsZHMpXG5cbkZpZWxkcyB0byBnZW5lcmF0ZTpcbiR7ZmllbGREZXNjcmlwdGlvbnN9JHtvdGhlclByb3BzQ29udGV4dH1cblxuUnVsZXM6XG4tIEFsbCBmaWVsZHMgaW4gYSBzaW5nbGUgcm93IG11c3QgYmUgbG9naWNhbGx5IGNvbnNpc3RlbnQgKGUuZy4gbmFtZS9uYW1lX2VuL25hbWVfY24gc2hvdWxkIHJlcHJlc2VudCB0aGUgc2FtZSBwZXJzb24pXG4tIFJldHVybiBPTkxZIHZhbGlkIEpTT04sIG5vIG1hcmtkb3duIG9yIGV4cGxhbmF0aW9uXG4tIERhdGVzIGluIElTTyA4NjAxIGZvcm1hdFxuLSBVc2UgJHtsYW5ndWFnZX0gZm9yIHRleHQgdW5sZXNzIGZpZWxkIGRlc2NyaXB0aW9uIHNheXMgb3RoZXJ3aXNlXG5cblJldHVybiBleGFjdGx5IHRoaXMgSlNPTiBzaGFwZTpcbntcbiR7cmVzdWx0VGVtcGxhdGV9XG59YDtcbiAgfVxuXG4gIC8qKlxuICAgKiByb3cgTExNIOydkeuLteydhCDtjIzsi7HtlZjsl6wg7ZWE65Oc67OEIOqwkuycvOuhnCDrs4DtmZjtlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIHBhcnNlUm93TExNUmVzcG9uc2UodGV4dDogc3RyaW5nLCBwcm9wczogRW50aXR5UHJvcFtdKTogRGF0YUV4cGxvcmVyUmVjb3JkIHtcbiAgICBjb25zdCBqc29uVGV4dCA9IHRleHRcbiAgICAgIC50cmltKClcbiAgICAgIC5yZXBsYWNlKC9eYGBganNvblxccyovaSwgXCJcIilcbiAgICAgIC5yZXBsYWNlKC9gYGBcXHMqJC8sIFwiXCIpXG4gICAgICAudHJpbSgpO1xuXG4gICAgbGV0IHBhcnNlZDogRGF0YUV4cGxvcmVyUmVjb3JkO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBwYXJzZWRSZWNvcmQgPSBkYXRhRXhwbG9yZXJSZWNvcmRTY2hlbWEuc2FmZVBhcnNlKEpTT04ucGFyc2UoanNvblRleHQpKTtcbiAgICAgIGlmICghcGFyc2VkUmVjb3JkLnN1Y2Nlc3MpIHtcbiAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgY29uc29sZS53YXJuKFwiW0ZpeHR1cmVHZW5lcmF0b3JdIFJvdyBMTE0gcmVzcG9uc2UgaXMgbm90IGEgcGxhaW4gb2JqZWN0OlwiLCB0ZXh0KTtcbiAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgfVxuICAgICAgcGFyc2VkID0gcGFyc2VkUmVjb3JkLmRhdGE7XG4gICAgfSBjYXRjaCB7XG4gICAgICAhaXNUZXN0KCkgJiYgY29uc29sZS53YXJuKFwiW0ZpeHR1cmVHZW5lcmF0b3JdIEZhaWxlZCB0byBwYXJzZSByb3cgTExNIHJlc3BvbnNlOlwiLCB0ZXh0KTtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQ6IERhdGFFeHBsb3JlclJlY29yZCA9IHt9O1xuICAgIGZvciAoY29uc3QgcHJvcCBvZiBwcm9wcykge1xuICAgICAgaWYgKHByb3AubmFtZSBpbiBwYXJzZWQpIHtcbiAgICAgICAgcmVzdWx0W3Byb3AubmFtZV0gPSB0aGlzLnBhcnNlTExNUmVzcG9uc2UoU3RyaW5nKHBhcnNlZFtwcm9wLm5hbWVdID8/IFwiXCIpLCBwcm9wLnR5cGUpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZExMTVByb21wdChoaW50OiBzdHJpbmcsIHByb3A6IEVudGl0eVByb3AsIGVudGl0eTogRW50aXR5KTogc3RyaW5nIHtcbiAgICBjb25zdCBsb2NhbGUgPSB0aGlzLm9wdGlvbnMubG9jYWxlIHx8IFwia29cIjtcbiAgICBjb25zdCBsYW5ndWFnZSA9IGxvY2FsZSA9PT0gXCJrb1wiID8gXCJLb3JlYW5cIiA6IGxvY2FsZSA9PT0gXCJqYVwiID8gXCJKYXBhbmVzZVwiIDogXCJFbmdsaXNoXCI7XG5cbiAgICBjb25zdCBlbnRpdHlDb250ZXh0ID0gZW50aXR5LmNvbmU/Lm5vdGUgPyBgXFxuRW50aXR5IGNvbnRleHQ6ICR7ZW50aXR5LmNvbmUubm90ZX1gIDogXCJcIjtcblxuICAgIGNvbnN0IG90aGVyRmllbGRzID0gZW50aXR5LnByb3BzXG4gICAgICAuZmlsdGVyKChwKSA9PiBwLm5hbWUgIT09IHByb3AubmFtZSAmJiAhaXNSZWxhdGlvblByb3AocCkgJiYgcC5jb25lPy5ub3RlKVxuICAgICAgLm1hcCgocCkgPT4gYC0gJHtwLm5hbWV9ICgke3AudHlwZX0pOiAke3AuY29uZT8ubm90ZX1gKVxuICAgICAgLmpvaW4oXCJcXG5cIik7XG4gICAgY29uc3Qgb3RoZXJGaWVsZHNDb250ZXh0ID0gb3RoZXJGaWVsZHNcbiAgICAgID8gYFxcblxcbk90aGVyIGZpZWxkcyBpbiB0aGlzIGVudGl0eSAoZm9yIGNvbnRleHQpOlxcbiR7b3RoZXJGaWVsZHN9YFxuICAgICAgOiBcIlwiO1xuXG4gICAgbGV0IHByb21wdCA9IGBHZW5lcmF0ZSB0ZXN0IGRhdGEgZm9yICR7ZW50aXR5LmlkfS4ke3Byb3AubmFtZX0gKHR5cGU6ICR7cHJvcC50eXBlfSkke2VudGl0eUNvbnRleHR9JHtvdGhlckZpZWxkc0NvbnRleHR9XG5cblJlcXVpcmVtZW50OiAke2hpbnR9XG5cblJ1bGVzOlxuLSBSZXR1cm4gT05MWSB0aGUgdmFsdWUsIG5vIGV4cGxhbmF0aW9uIG9yIG1hcmtkb3duXG4tIFVzZSAke2xhbmd1YWdlfSBsYW5ndWFnZSBpZiBhcHBsaWNhYmxlXG4tIEZvcm1hdDogJHt0aGlzLmdldEV4cGVjdGVkRm9ybWF0KHByb3AudHlwZSl9YDtcblxuICAgIC8vIGVudW0g7YOA7J6F7J24IOqyveyasCDqsIDriqXtlZwg6rCSIOuqqeuhnSDstpTqsIBcbiAgICBpZiAocHJvcC50eXBlID09PSBcImVudW1cIiB8fCBwcm9wLnR5cGUgPT09IFwiZW51bVtdXCIpIHtcbiAgICAgIGxldCBlbnVtVmFsdWVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBpZiAoXCJlbnVtXCIgaW4gcHJvcCAmJiBBcnJheS5pc0FycmF5KHByb3AuZW51bSkgJiYgcHJvcC5lbnVtLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZW51bVZhbHVlcyA9IHByb3AuZW51bTtcbiAgICAgIH0gZWxzZSBpZiAoXCJpZFwiIGluIHByb3AgJiYgcHJvcC5pZCAmJiBlbnRpdHk/LmVudW1MYWJlbHM/Lltwcm9wLmlkXSkge1xuICAgICAgICBlbnVtVmFsdWVzID0gT2JqZWN0LmtleXMoZW50aXR5LmVudW1MYWJlbHNbcHJvcC5pZF0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZW51bVZhbHVlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHByb21wdCArPSBgXFxuLSBJTVBPUlRBTlQ6IENob29zZSBPTkxZIGZyb20gdGhlc2UgYWxsb3dlZCB2YWx1ZXM6ICR7ZW51bVZhbHVlcy5qb2luKFwiLCBcIil9YDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBwcm9tcHQgKz0gYFxcblxcbkV4YW1wbGU6ICR7dGhpcy5nZXRFeGFtcGxlRm9yVHlwZShwcm9wLnR5cGUsIGxvY2FsZSl9YDtcblxuICAgIHJldHVybiBwcm9tcHQ7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlTExNUmVzcG9uc2UodGV4dDogc3RyaW5nLCBwcm9wVHlwZTogc3RyaW5nKTogRGF0YUV4cGxvcmVyVmFsdWUge1xuICAgIGNvbnN0IGNsZWFuZWQgPSB0ZXh0LnRyaW0oKTtcblxuICAgIC8vIOuwsOyXtCDtg4DsnoUg7LKY66asXG4gICAgaWYgKHByb3BUeXBlLmVuZHNXaXRoKFwiW11cIikpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZCA9IGRhdGFFeHBsb3JlclZhbHVlU2NoZW1hLnBhcnNlKEpTT04ucGFyc2UoY2xlYW5lZCkpO1xuICAgICAgICBjb25zdCBiYXNlVHlwZSA9IHByb3BUeXBlLnNsaWNlKDAsIC0yKTsgLy8gXCJpbnRlZ2VyW11cIiAtPiBcImludGVnZXJcIlxuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHBhcnNlZCkpIHtcbiAgICAgICAgICByZXR1cm4gcGFyc2VkLm1hcCgoaXRlbSkgPT4ge1xuICAgICAgICAgICAgLy8gbnVsbC91bmRlZmluZWTripQg7YOA7J6F67OEIOq4sOuzuOqwkuycvOuhnFxuICAgICAgICAgICAgaWYgKGl0ZW0gPT09IG51bGwgfHwgaXRlbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldERlZmF1bHRWYWx1ZUZvclR5cGUoYmFzZVR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8g6rCd7LK064qUIEpTT04uc3RyaW5naWZ5IO2bhCDtjIzsi7EgKGpzb24g7YOA7J6F7J24IOqyveyasClcbiAgICAgICAgICAgIGlmIChkYXRhRXhwbG9yZXJSZWNvcmRTY2hlbWEuc2FmZVBhcnNlKGl0ZW0pLnN1Y2Nlc3MgfHwgQXJyYXkuaXNBcnJheShpdGVtKSkge1xuICAgICAgICAgICAgICByZXR1cm4gYmFzZVR5cGUgPT09IFwianNvblwiXG4gICAgICAgICAgICAgICAgPyBpdGVtXG4gICAgICAgICAgICAgICAgOiB0aGlzLnBhcnNlU2NhbGFyVmFsdWUoSlNPTi5zdHJpbmdpZnkoaXRlbSksIGJhc2VUeXBlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHByaW1pdGl2ZSDqsJLsnYAg66y47J6Q7Je066GcIOuzgO2ZmCDtm4Qg7YyM7IuxXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wYXJzZVNjYWxhclZhbHVlKFN0cmluZyhpdGVtKSwgYmFzZVR5cGUpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8g64uo7J28IOqwkuydtCDsmKgg6rK97JqwIOuwsOyXtOuhnCDqsJDsi7jquLBcbiAgICAgICAgaWYgKHBhcnNlZCA9PT0gbnVsbCB8fCBwYXJzZWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHJldHVybiBbdGhpcy5nZXREZWZhdWx0VmFsdWVGb3JUeXBlKGJhc2VUeXBlKV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFt0aGlzLnBhcnNlU2NhbGFyVmFsdWUoU3RyaW5nKHBhcnNlZCksIGJhc2VUeXBlKV07XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnBhcnNlU2NhbGFyVmFsdWUoY2xlYW5lZCwgcHJvcFR5cGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXREZWZhdWx0VmFsdWVGb3JUeXBlKHByb3BUeXBlOiBzdHJpbmcpOiBEYXRhRXhwbG9yZXJWYWx1ZSB7XG4gICAgc3dpdGNoIChwcm9wVHlwZSkge1xuICAgICAgY2FzZSBcImludGVnZXJcIjpcbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICBjYXNlIFwiYmlnSW50ZWdlclwiOlxuICAgICAgICByZXR1cm4gMG47XG4gICAgICBjYXNlIFwiZmxvYXRcIjpcbiAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgIGNhc2UgXCJudW1lcmljXCI6XG4gICAgICAgIHJldHVybiAwO1xuICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgY2FzZSBcImRhdGVcIjpcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKCk7XG4gICAgICBjYXNlIFwianNvblwiOlxuICAgICAgICByZXR1cm4ge307XG4gICAgICBjYXNlIFwidXVpZFwiOlxuICAgICAgICByZXR1cm4gXCIwMDAwMDAwMC0wMDAwLTAwMDAtMDAwMC0wMDAwMDAwMDAwMDBcIjtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBcIlwiO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VTY2FsYXJWYWx1ZSh0ZXh0OiBzdHJpbmcsIHByb3BUeXBlOiBzdHJpbmcpOiBEYXRhRXhwbG9yZXJWYWx1ZSB7XG4gICAgY29uc3QgY2xlYW5lZCA9IHRleHQudHJpbSgpO1xuXG4gICAgc3dpdGNoIChwcm9wVHlwZSkge1xuICAgICAgY2FzZSBcImludGVnZXJcIjoge1xuICAgICAgICBjb25zdCBudW0gPSBwYXJzZUludChjbGVhbmVkLCAxMCk7XG4gICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4obnVtKSA/IDAgOiBudW07XG4gICAgICB9XG4gICAgICBjYXNlIFwiYmlnSW50ZWdlclwiOiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIEJpZ0ludChjbGVhbmVkKTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgcmV0dXJuIDBuO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjYXNlIFwiZmxvYXRcIjpcbiAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgIGNhc2UgXCJudW1lcmljXCI6IHtcbiAgICAgICAgY29uc3QgbnVtID0gcGFyc2VGbG9hdChjbGVhbmVkKTtcbiAgICAgICAgcmV0dXJuIE51bWJlci5pc05hTihudW0pID8gMCA6IG51bTtcbiAgICAgIH1cbiAgICAgIGNhc2UgXCJib29sZWFuXCI6XG4gICAgICAgIHJldHVybiBjbGVhbmVkLnRvTG93ZXJDYXNlKCkgPT09IFwidHJ1ZVwiO1xuICAgICAgY2FzZSBcImRhdGVcIjoge1xuICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoY2xlYW5lZCk7XG4gICAgICAgIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0ZS5nZXRUaW1lKCkpID8gbmV3IERhdGUoKSA6IGRhdGU7XG4gICAgICB9XG4gICAgICBjYXNlIFwianNvblwiOlxuICAgICAgICB0cnkge1xuICAgICAgICAgIHJldHVybiBkYXRhRXhwbG9yZXJWYWx1ZVNjaGVtYS5wYXJzZShKU09OLnBhcnNlKGNsZWFuZWQpKTtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgcmV0dXJuIGNsZWFuZWQ7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgXCJ1dWlkXCI6XG4gICAgICBjYXNlIFwiZW51bVwiOlxuICAgICAgICByZXR1cm4gY2xlYW5lZDtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBjbGVhbmVkO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBmYWtlciDtlajsiJgg7J247J6QIOusuOyekOyXtOydhCDtjIzsi7HtlZjsl6wg7J247J6QIOuwsOyXtOuhnCDrsJjtmZjtlanri4jri6QuXG4gICAqXG4gICAqIDPri6jqs4Qg7KCE6561OlxuICAgKiAxLiBKU09OIOyngeygkSDtjIzsi7EgKO2RnOykgCBKU09OIO2RnO2YhOyLnSlcbiAgICogMi4gSlMg6rCd7LK0IOumrO2EsOuftCDihpIgSlNPTiDrs4DtmZgg7ZuEIOyerOyLnOuPhCAoc2luZ2xlIHF1b3RlLCB1bnF1b3RlZCBrZXkg7LKY66asKVxuICAgKiAzLiDri6jsiJwg64uo7J28IOyduOyekCDtj7TrsLEgKOyIq+yekCwg66y47J6Q7Je0KVxuICAgKi9cbiAgcHJpdmF0ZSBwYXJzZUdlbmVyYXRvckFyZ3MoYXJnc1N0cjogc3RyaW5nLCBwcm9wTmFtZTogc3RyaW5nKTogRGF0YUV4cGxvcmVyVmFsdWVbXSB7XG4gICAgLy8gMS4gSlNPTiDsp4HsoJEg7YyM7IuxXG4gICAgbGV0IHBhcnNlZEFyZ3VtZW50czogRGF0YUV4cGxvcmVyVmFsdWVbXSB8IG51bGw7XG4gICAgdHJ5IHtcbiAgICAgIHBhcnNlZEFyZ3VtZW50cyA9IGdlbmVyYXRvckFyZ3VtZW50c1NjaGVtYS5wYXJzZShKU09OLnBhcnNlKGBbJHthcmdzU3RyfV1gKSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBwYXJzZWRBcmd1bWVudHMgPSBudWxsO1xuICAgIH1cbiAgICBpZiAocGFyc2VkQXJndW1lbnRzKSB7XG4gICAgICByZXR1cm4gcGFyc2VkQXJndW1lbnRzO1xuICAgIH1cblxuICAgIC8vIDIuIEpTIOqwneyytCDrpqzthLDrn7Qg4oaSIEpTT04g67OA7ZmYIO2bhCDsnqzsi5zrj4RcbiAgICB0cnkge1xuICAgICAgY29uc3QganNvblN0ciA9IHRoaXMuY29udmVydEpzTGl0ZXJhbFRvSnNvbihhcmdzU3RyKTtcbiAgICAgIHBhcnNlZEFyZ3VtZW50cyA9IGdlbmVyYXRvckFyZ3VtZW50c1NjaGVtYS5wYXJzZShKU09OLnBhcnNlKGBbJHtqc29uU3RyfV1gKSk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBwYXJzZWRBcmd1bWVudHMgPSBudWxsO1xuICAgIH1cbiAgICBpZiAocGFyc2VkQXJndW1lbnRzKSB7XG4gICAgICByZXR1cm4gcGFyc2VkQXJndW1lbnRzO1xuICAgIH1cblxuICAgIC8vIDMuIOuLqOyInCDri6jsnbwg7J247J6QIO2PtOuwsVxuICAgIGNvbnN0IHRyaW1tZWQgPSBhcmdzU3RyLnRyaW0oKTtcbiAgICBpZiAoIU51bWJlci5pc05hTihOdW1iZXIodHJpbW1lZCkpKSB7XG4gICAgICByZXR1cm4gW051bWJlcih0cmltbWVkKV07XG4gICAgfVxuICAgIGlmIChcbiAgICAgICh0cmltbWVkLnN0YXJ0c1dpdGgoJ1wiJykgJiYgdHJpbW1lZC5lbmRzV2l0aCgnXCInKSkgfHxcbiAgICAgICh0cmltbWVkLnN0YXJ0c1dpdGgoXCInXCIpICYmIHRyaW1tZWQuZW5kc1dpdGgoXCInXCIpKVxuICAgICkge1xuICAgICAgcmV0dXJuIFt0cmltbWVkLnNsaWNlKDEsIC0xKV07XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKGBGaXh0dXJlR2VuZXJhdG9yOiBDYW5ub3QgcGFyc2UgYXJndW1lbnRzIGZvciAke3Byb3BOYW1lfTogJHthcmdzU3RyfWApO1xuICB9XG5cbiAgLyoqXG4gICAqIEpTIOqwneyytCDrpqzthLDrn7TsnYQgSlNPTuycvOuhnCDrs4DtmZjtlanri4jri6QuXG4gICAqXG4gICAqIOuRkCDqsIDsp4Ag67OA7ZmYOlxuICAgKiAxLiBTaW5nbGUtcXVvdGVkIOusuOyekOyXtCDihpIgZG91YmxlLXF1b3RlZCAo7J207Iqk7LyA7J207ZSEIOyymOumrCDtj6ztlagpXG4gICAqIDIuIFVucXVvdGVkIOqwneyytCDtgqQg4oaSIGRvdWJsZS1xdW90ZWRcbiAgICovXG4gIHByaXZhdGUgY29udmVydEpzTGl0ZXJhbFRvSnNvbihpbnB1dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAvLyAxLiAndmFsdWUnIOKGkiBcInZhbHVlXCIgKOuCtOu2gCBcIiDsnbTsiqTsvIDsnbTtlIQsIFxcJyDihpIgJylcbiAgICBjb25zdCB3aXRoRG91YmxlUXVvdGVzID0gaW5wdXQucmVwbGFjZShcbiAgICAgIC8nKFteJ1xcXFxdKig/OlxcXFwuW14nXFxcXF0qKSopJy9nLFxuICAgICAgKF8sIGNvbnRlbnQ6IHN0cmluZykgPT4gYFwiJHtjb250ZW50LnJlcGxhY2UoL1wiL2csICdcXFxcXCInKS5yZXBsYWNlKC9cXFxcJy9nLCBcIidcIil9XCJgLFxuICAgICk7XG5cbiAgICAvLyAyLiB7IGtleTog4oaSIHsgXCJrZXlcIjpcbiAgICByZXR1cm4gd2l0aERvdWJsZVF1b3Rlcy5yZXBsYWNlKC8oW3ssXVxccyopKFthLXpBLVpfJF1bXFx3JF0qKShcXHMqOikvZywgJyQxXCIkMlwiJDMnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTb25hbXUuc2VjcmV07J2EIOyasOyEoOycvOuhnCDtlZjqs6AsIOyXhuycvOuptCDtmZjqsr3rs4DsiJjsl5DshJwgQVBJIO2CpOulvCDsnb3sirXri4jri6QuXG4gICAqXG4gICAqIFNvbmFtdS5zZWNyZXTsnYAg7ZSE66Gc7KCd7Yq467OEIOyEpOyglShzb25hbXUuY29uZmlnLnRzKeydtOuvgOuhnCDrjZQg64aS7J2AIOyasOyEoOyInOychOulvCDqsIDsp4DrqbAsXG4gICAqIO2ZmOqyveuzgOyImOuKlCDqsJzrsJwg7ZmY6rK97J2064KYIENJL0NE7JeQ7IScIGZhbGxiYWNr7Jy866GcIOyCrOyaqeuQqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgZ2V0QXBpS2V5KCk6IHN0cmluZyB7XG4gICAgbGV0IGFwaUtleTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgU29uYW11IH0gPSByZXF1aXJlKFwiLi4vYXBpXCIpO1xuICAgICAgYXBpS2V5ID0gU29uYW11LnNlY3JldHM/LmFudGhyb3BpY19hcGlfa2V5O1xuICAgIH0gY2F0Y2gge1xuICAgICAgLy8gU29uYW116rCAIOy0iOq4sO2ZlOuQmOyngCDslYrsnYAg6rK97JqwICjthYzsiqTtirgg7ZmY6rK9IOuTsSlcbiAgICB9XG5cbiAgICBpZiAoIWFwaUtleSkge1xuICAgICAgYXBpS2V5ID0gcHJvY2Vzcy5lbnYuQU5USFJPUElDX0FQSV9LRVk7XG4gICAgfVxuXG4gICAgaWYgKCFhcGlLZXkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJBTlRIUk9QSUNfQVBJX0tFWSBub3QgZm91bmQuIFNldCBpdCBpbiBlbnZpcm9ubWVudCB2YXJpYWJsZXMgb3IgU29uYW11LnNlY3JldC5hbnRocm9waWNfYXBpX2tleVwiLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICByZXR1cm4gYXBpS2V5O1xuICB9XG5cbiAgcHJpdmF0ZSBoYXNTZXF1ZW5jZURlZmF1bHQocHJvcDogRW50aXR5UHJvcCk6IGJvb2xlYW4ge1xuICAgIGlmICghKFwiZGJEZWZhdWx0XCIgaW4gcHJvcCkpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgY29uc3QgZGJEZWZhdWx0ID0gei5zdHJpbmcoKS5zYWZlUGFyc2UocHJvcC5kYkRlZmF1bHQpO1xuICAgIHJldHVybiBkYkRlZmF1bHQuc3VjY2VzcyAmJiBkYkRlZmF1bHQuZGF0YS5pbmNsdWRlcyhcIm5leHR2YWxcIik7XG4gIH1cblxuICBwcml2YXRlIGdldEV4cGVjdGVkRm9ybWF0KHByb3BUeXBlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIC8vIOuwsOyXtCDtg4DsnoUg7LKY66asXG4gICAgaWYgKHByb3BUeXBlLmVuZHNXaXRoKFwiW11cIikpIHtcbiAgICAgIGNvbnN0IGJhc2VUeXBlID0gcHJvcFR5cGUuc2xpY2UoMCwgLTIpO1xuICAgICAgY29uc3QgYmFzZUZvcm1hdCA9IHRoaXMuZ2V0U2NhbGFyRm9ybWF0KGJhc2VUeXBlKTtcbiAgICAgIHJldHVybiBgSlNPTiBhcnJheSBvZiAke2Jhc2VGb3JtYXR9IChlLmcuLCBbJHt0aGlzLmdldEV4YW1wbGVGb3JUeXBlKGJhc2VUeXBlLCBcImVuXCIpfSwgLi4uXSlgO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmdldFNjYWxhckZvcm1hdChwcm9wVHlwZSk7XG4gIH1cblxuICBwcml2YXRlIGdldFNjYWxhckZvcm1hdChwcm9wVHlwZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBzd2l0Y2ggKHByb3BUeXBlKSB7XG4gICAgICBjYXNlIFwiaW50ZWdlclwiOlxuICAgICAgY2FzZSBcImJpZ0ludGVnZXJcIjpcbiAgICAgICAgcmV0dXJuIFwiaW50ZWdlciBudW1iZXJzXCI7XG4gICAgICBjYXNlIFwiZmxvYXRcIjpcbiAgICAgIGNhc2UgXCJudW1iZXJcIjpcbiAgICAgIGNhc2UgXCJudW1lcmljXCI6XG4gICAgICAgIHJldHVybiBcImRlY2ltYWwgbnVtYmVyc1wiO1xuICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgICAgcmV0dXJuIFwiYm9vbGVhbnMgKHRydWUgb3IgZmFsc2UpXCI7XG4gICAgICBjYXNlIFwiZGF0ZVwiOlxuICAgICAgICByZXR1cm4gXCJJU08gODYwMSBkYXRlIHN0cmluZ3NcIjtcbiAgICAgIGNhc2UgXCJqc29uXCI6XG4gICAgICAgIHJldHVybiBcInZhbGlkIEpTT04gb2JqZWN0IG9yIGFycmF5XCI7XG4gICAgICBjYXNlIFwidXVpZFwiOlxuICAgICAgICByZXR1cm4gXCJVVUlEIHN0cmluZ3NcIjtcbiAgICAgIGNhc2UgXCJlbnVtXCI6XG4gICAgICAgIHJldHVybiBcIm9uZSBvZiB0aGUgYWxsb3dlZCBlbnVtIHZhbHVlc1wiO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIFwicGxhaW4gdGV4dCBzdHJpbmdzXCI7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRFeGFtcGxlRm9yVHlwZShwcm9wVHlwZTogc3RyaW5nLCBsb2NhbGU6IExvY2FsZSk6IHN0cmluZyB7XG4gICAgLy8g67Cw7Je0IO2DgOyehSDsspjrpqxcbiAgICBpZiAocHJvcFR5cGUuZW5kc1dpdGgoXCJbXVwiKSkge1xuICAgICAgY29uc3QgYmFzZVR5cGUgPSBwcm9wVHlwZS5zbGljZSgwLCAtMik7XG4gICAgICBjb25zdCBiYXNlRXhhbXBsZSA9IHRoaXMuZ2V0U2NhbGFyRXhhbXBsZShiYXNlVHlwZSwgbG9jYWxlKTtcbiAgICAgIHJldHVybiBgWyR7YmFzZUV4YW1wbGV9XWA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZ2V0U2NhbGFyRXhhbXBsZShwcm9wVHlwZSwgbG9jYWxlKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U2NhbGFyRXhhbXBsZShwcm9wVHlwZTogc3RyaW5nLCBsb2NhbGU6IExvY2FsZSk6IHN0cmluZyB7XG4gICAgY29uc3QgaXNLb3JlYW4gPSBsb2NhbGUgPT09IFwia29cIjtcblxuICAgIHN3aXRjaCAocHJvcFR5cGUpIHtcbiAgICAgIGNhc2UgXCJpbnRlZ2VyXCI6XG4gICAgICBjYXNlIFwiYmlnSW50ZWdlclwiOlxuICAgICAgICByZXR1cm4gXCI0MlwiO1xuICAgICAgY2FzZSBcImZsb2F0XCI6XG4gICAgICBjYXNlIFwibnVtYmVyXCI6XG4gICAgICBjYXNlIFwibnVtZXJpY1wiOlxuICAgICAgICByZXR1cm4gXCIzLjE0XCI7XG4gICAgICBjYXNlIFwiYm9vbGVhblwiOlxuICAgICAgICByZXR1cm4gXCJ0cnVlXCI7XG4gICAgICBjYXNlIFwiZGF0ZVwiOlxuICAgICAgICByZXR1cm4gXCIyMDI0LTAxLTAxXCI7XG4gICAgICBjYXNlIFwianNvblwiOlxuICAgICAgICByZXR1cm4gJ3tcImtleVwiOiBcInZhbHVlXCJ9JztcbiAgICAgIGNhc2UgXCJ1dWlkXCI6XG4gICAgICAgIHJldHVybiBcIjU1MGU4NDAwLWUyOWItNDFkNC1hNzE2LTQ0NjY1NTQ0MDAwMFwiO1xuICAgICAgY2FzZSBcImVudW1cIjpcbiAgICAgICAgcmV0dXJuIFwiRU5VTV9WQUxVRVwiO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGlzS29yZWFuID8gXCLslYjrhZXtlZjshLjsmpRcIiA6IFwiSGVsbG9cIjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog7J2066aE7J2EIOydtOuplOydvCDroZzsu6wg7YyM7Yq47JqpIOuhnOuniOuCmOydtOymiOuTnCDrrLjsnpDsl7TroZwg67OA7ZmY7ZWp64uI64ukLlxuICAgKlxuICAgKiDtlZzquIAg7J2066aE7J2AIOy0iOyEsS3spJHshLEt7KKF7ISxIOu2hO2VtCDtm4Qg66Gc66eI64KY7J207KaIIOyymOumrO2VqeuLiOuLpC5cbiAgICog7JiB66y4IOydtOumhOydgCDshozrrLjsnpDroZwg67OA7ZmY7ZWY6rOgIOqzteuwseydhCDsoJAoLilcXHVjNzNj66GcIOy5mO2ZmO2VqeuLiOuLpC5cbiAgICog7JiIOiBcIuq5gOyyoOyImFwiIOKGkiBcImNoZW9sc3Uua2ltXCIsIFwiSm9obiBEb2VcIiDihpIgXCJqb2huLmRvZVwiXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJvbWFuaXplTmFtZShuYW1lOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIC8vIO2VnOq4gCDtj6ztlagg7Jes67aAIO2ZleyduFxuICAgIGlmICgvW1xcdUFDMDAtXFx1RDdBRl0vLnRlc3QobmFtZSkpIHtcbiAgICAgIHJldHVybiB0aGlzLnJvbWFuaXplS29yZWFuTmFtZShuYW1lKTtcbiAgICB9XG4gICAgLy8g7JiB66y4OiDshozrrLjsnpAgKyDsoJAg6rWs67aEXG4gICAgcmV0dXJuIG5hbWVcbiAgICAgIC50b0xvd2VyQ2FzZSgpXG4gICAgICAucmVwbGFjZSgvXFxzKy9nLCBcIi5cIilcbiAgICAgIC5yZXBsYWNlKC9bXmEtejAtOS5dL2csIFwiXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VnOq4gCDsnbTrpoTsnYQg66Gc66eI64KY7J207KaIIOyymOumrO2VqeuLiOuLpC5cbiAgICpcbiAgICog7LSI7ISxL+ykkeyEsS/sooXshLEg66ek7ZWRIO2FjOydtOu4lOydhCDsgqzsmqntlZjsl6wg7ZWc6riA7J2EIOuhnOuniOyekOuhnCDrs4DtmZjtlanri4jri6QuXG4gICAqIOyyqyDquIDsnpDrpbwg7ISx7Jy866GcIOqwhOyjvO2VmOyXrCBcIuq5gOyyoOyImFwiIOKGkiBcImNoZW9sc3Uua2ltXCIg7ZiV7YOc66GcIOy2nOugpe2VqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgcm9tYW5pemVLb3JlYW5OYW1lKG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgQ0hPU0VPTkcgPSBbXG4gICAgICBcImdcIixcbiAgICAgIFwia2tcIixcbiAgICAgIFwiblwiLFxuICAgICAgXCJkXCIsXG4gICAgICBcInR0XCIsXG4gICAgICBcInJcIixcbiAgICAgIFwibVwiLFxuICAgICAgXCJiXCIsXG4gICAgICBcInBwXCIsXG4gICAgICBcInNcIixcbiAgICAgIFwic3NcIixcbiAgICAgIFwiXCIsXG4gICAgICBcImpcIixcbiAgICAgIFwiampcIixcbiAgICAgIFwiY2hcIixcbiAgICAgIFwia1wiLFxuICAgICAgXCJ0XCIsXG4gICAgICBcInBcIixcbiAgICAgIFwiaFwiLFxuICAgIF07XG4gICAgY29uc3QgSlVOR1NFT05HID0gW1xuICAgICAgXCJhXCIsXG4gICAgICBcImFlXCIsXG4gICAgICBcInlhXCIsXG4gICAgICBcInlhZVwiLFxuICAgICAgXCJlb1wiLFxuICAgICAgXCJlXCIsXG4gICAgICBcInllb1wiLFxuICAgICAgXCJ5ZVwiLFxuICAgICAgXCJvXCIsXG4gICAgICBcIndhXCIsXG4gICAgICBcIndhZVwiLFxuICAgICAgXCJvZVwiLFxuICAgICAgXCJ5b1wiLFxuICAgICAgXCJ1XCIsXG4gICAgICBcIndvXCIsXG4gICAgICBcIndlXCIsXG4gICAgICBcIndpXCIsXG4gICAgICBcInl1XCIsXG4gICAgICBcImV1XCIsXG4gICAgICBcInVpXCIsXG4gICAgICBcImlcIixcbiAgICBdO1xuICAgIGNvbnN0IEpPTkdTRU9ORyA9IFtcbiAgICAgIFwiXCIsXG4gICAgICBcImtcIixcbiAgICAgIFwia1wiLFxuICAgICAgXCJrXCIsXG4gICAgICBcIm5cIixcbiAgICAgIFwiblwiLFxuICAgICAgXCJuXCIsXG4gICAgICBcInRcIixcbiAgICAgIFwibFwiLFxuICAgICAgXCJsXCIsXG4gICAgICBcImxcIixcbiAgICAgIFwibFwiLFxuICAgICAgXCJsXCIsXG4gICAgICBcImxcIixcbiAgICAgIFwibFwiLFxuICAgICAgXCJsXCIsXG4gICAgICBcIm1cIixcbiAgICAgIFwicFwiLFxuICAgICAgXCJwXCIsXG4gICAgICBcInRcIixcbiAgICAgIFwidFwiLFxuICAgICAgXCJuZ1wiLFxuICAgICAgXCJ0XCIsXG4gICAgICBcInRcIixcbiAgICAgIFwia1wiLFxuICAgICAgXCJ0XCIsXG4gICAgICBcInBcIixcbiAgICAgIFwidFwiLFxuICAgIF07XG5cbiAgICBjb25zdCByb21hbml6ZSA9IChjaGFyOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICAgICAgY29uc3QgY29kZSA9IGNoYXIuY2hhckNvZGVBdCgwKTtcbiAgICAgIGlmIChjb2RlIDwgMHhhYzAwIHx8IGNvZGUgPiAweGQ3YWYpIHJldHVybiBjaGFyO1xuICAgICAgY29uc3Qgb2Zmc2V0ID0gY29kZSAtIDB4YWMwMDtcbiAgICAgIGNvbnN0IGNobyA9IE1hdGguZmxvb3Iob2Zmc2V0IC8gNTg4KTtcbiAgICAgIGNvbnN0IGp1bmcgPSBNYXRoLmZsb29yKChvZmZzZXQgJSA1ODgpIC8gMjgpO1xuICAgICAgY29uc3Qgam9uZyA9IG9mZnNldCAlIDI4O1xuICAgICAgcmV0dXJuIENIT1NFT05HW2Nob10gKyBKVU5HU0VPTkdbanVuZ10gKyBKT05HU0VPTkdbam9uZ107XG4gICAgfTtcblxuICAgIGNvbnN0IGNoYXJzID0gWy4uLm5hbWVdO1xuICAgIC8vIOyyqyDquIDsnpDrpbwg7ISxKOWnkynsnLzroZwg6rCE7KO8XG4gICAgY29uc3QgZmFtaWx5TmFtZSA9IHJvbWFuaXplKGNoYXJzWzBdKTtcbiAgICBjb25zdCBnaXZlbk5hbWUgPSBjaGFycy5zbGljZSgxKS5tYXAocm9tYW5pemUpLmpvaW4oXCJcIik7XG5cbiAgICBpZiAoZ2l2ZW5OYW1lKSB7XG4gICAgICByZXR1cm4gYCR7Z2l2ZW5OYW1lfS4ke2ZhbWlseU5hbWV9YDtcbiAgICB9XG4gICAgcmV0dXJuIGZhbWlseU5hbWU7XG4gIH1cblxuICAvKipcbiAgICogTExNIOy6kOyLnCDthrXqs4Trpbwg67CY7ZmY7ZWp64uI64ukLlxuICAgKi9cbiAgZ2V0TExNQ2FjaGVTdGF0cygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgc2l6ZTogdGhpcy5sbG1DYWNoZS5zaXplLFxuICAgICAgZW5hYmxlZDogdGhpcy5vcHRpb25zLmVuYWJsZUxMTUNhY2hlLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogTExNIOy6kOyLnOulvCDstIjquLDtmZTtlanri4jri6QuXG4gICAqL1xuICBjbGVhckxMTUNhY2hlKCkge1xuICAgIHRoaXMubGxtQ2FjaGUuY2xlYXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDsu6jthY3siqTtirgg7IOd7ISxXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZUNvbnRleHQoKTogR2VuZXJhdG9yQ29udGV4dCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGZpeHR1cmVzOiBuZXcgTWFwKCksXG4gICAgICByZWZlcmVuY2VDYWNoZTogbmV3IE1hcCgpLFxuICAgICAgaW1wb3J0ZWRSZWNvcmRzOiBuZXcgU2V0KCksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrsLDsuZgg7IOd7ISxIOuwjyDsnpDrj5kg7KCA7J6lXG4gICAqXG4gICAqIDEuIOqwgSBzcGVj67OE66GcIGZpeHR1cmUg7IOd7ISxICjrqZTrqqjrpqwpXG4gICAqIDIuIEZpeHR1cmVSZWNvcmTroZwg67OA7ZmYXG4gICAqIDMuIEZpeHR1cmVNYW5hZ2VyLmluc2VydEZpeHR1cmVzKCnroZwgdGFyZ2V0RGLsl5Ag7KCA7J6lXG4gICAqXG4gICAqIEByZXR1cm5zIOyggOyepeuQnCBmaXh0dXJlIOuNsOydtO2EsCAo7Iuk7KCcIERCIElEIO2PrO2VqClcbiAgICovXG4gIGFzeW5jIGdlbmVyYXRlQmF0Y2goc3BlY3M6IEZpeHR1cmVHZW5lcmF0aW9uU3BlY1tdKTogUHJvbWlzZTxGaXh0dXJlSW1wb3J0UmVzdWx0W10+IHtcbiAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5jcmVhdGVDb250ZXh0KCk7XG4gICAgY29uc3QgZ2VuZXJhdGVkRml4dHVyZXM6IEdlbmVyYXRlZEZpeHR1cmVbXSA9IFtdO1xuXG4gICAgLy8gMS4g6rCBIHNwZWPrs4TroZwgZml4dHVyZSDsg53shLFcbiAgICBmb3IgKGNvbnN0IHNwZWMgb2Ygc3BlY3MpIHtcbiAgICAgIGNvbnN0IHNwZWNFbnRpdHkgPSB0aGlzLmVudGl0eU1hbmFnZXIuZ2V0KHNwZWMuZW50aXR5KTtcblxuICAgICAgaWYgKHNwZWNFbnRpdHkucGFyZW50SWQpIHtcbiAgICAgICAgLy8gcGFyZW50SWQg7JeU7Yuw7YuwOiBEQuyXkOyEnCDshJzruIztg4DsnoUg7ZaJ7J20IOyXhuuKlCDrtoDrqqggaWTrpbwg7KGw7ZqM7ZWY7JesIOyCrOyaqVxuICAgICAgICAvLyAo7IOIIOu2gOuqqCDsg53shLEg64yA7IugIOq4sOyhtCDrjbDsnbTthLAg7J6s7Zmc7JqpKVxuICAgICAgICBjb25zdCBpZFByb3AgPSBzcGVjRW50aXR5LnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gXCJpZFwiKTtcbiAgICAgICAgY29uc3QgcGFyZW50T3ZlcnJpZGVzID0gaWRQcm9wPy5jb25lPy5maXh0dXJlUGFyZW50T3ZlcnJpZGVzID8/IHt9O1xuICAgICAgICBjb25zdCBwYXJlbnRFbnRpdHkgPSB0aGlzLmVudGl0eU1hbmFnZXIuZ2V0KHNwZWNFbnRpdHkucGFyZW50SWQpO1xuXG4gICAgICAgIC8vIOu2gOuqqCDthYzsnbTruJTsl5DshJwg7ISc67iM7YOA7J6FIO2FjOydtOu4lOyXkCDsl4bripQgaWTrpbwg7KGw7ZqMXG4gICAgICAgIGxldCBxdWVyeSA9IHRoaXMuc291cmNlRGIocGFyZW50RW50aXR5LnRhYmxlKS5zZWxlY3QoYCR7cGFyZW50RW50aXR5LnRhYmxlfS5pZGApO1xuICAgICAgICBmb3IgKGNvbnN0IFtjb2wsIHZhbF0gb2YgT2JqZWN0LmVudHJpZXMocGFyZW50T3ZlcnJpZGVzKSkge1xuICAgICAgICAgIHF1ZXJ5ID0gcXVlcnkud2hlcmUoYCR7cGFyZW50RW50aXR5LnRhYmxlfS4ke2NvbH1gLCBmaXh0dXJlV2hlcmVWYWx1ZVNjaGVtYS5wYXJzZSh2YWwpKTtcbiAgICAgICAgfVxuICAgICAgICBxdWVyeSA9IHF1ZXJ5XG4gICAgICAgICAgLmxlZnRKb2luKHNwZWNFbnRpdHkudGFibGUsIGAke3NwZWNFbnRpdHkudGFibGV9LmlkYCwgYCR7cGFyZW50RW50aXR5LnRhYmxlfS5pZGApXG4gICAgICAgICAgLndoZXJlTnVsbChgJHtzcGVjRW50aXR5LnRhYmxlfS5pZGApXG4gICAgICAgICAgLmxpbWl0KHNwZWMuY291bnQpO1xuXG4gICAgICAgIGNvbnN0IHJvd3MgPSBhd2FpdCBxdWVyeTtcbiAgICAgICAgY29uc3QgYXZhaWxhYmxlSWRzOiBudW1iZXJbXSA9IHJvd3MubWFwKChyOiB7IGlkOiBudW1iZXIgfSkgPT4gci5pZCk7XG5cbiAgICAgICAgaWYgKGF2YWlsYWJsZUlkcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgY2hhbGsueWVsbG93KFxuICAgICAgICAgICAgICAgIGBbcGFyZW50SWRdICR7c3BlYy5lbnRpdHl9OiDshJzruIztg4DsnoXsnbQg7JeG64qUIOu2gOuqqCDroIjsvZTrk5zqsIAg67aA7KGx7ZWp64uI64ukLiDqsbTrhIjrnIHri4jri6QuYCxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZm9yIChjb25zdCBwYXJlbnRJZCBvZiBhdmFpbGFibGVJZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGZpeHR1cmUgPSBhd2FpdCB0aGlzLmdlbmVyYXRlKHNwZWMuZW50aXR5LCBzcGVjLm92ZXJyaWRlcyB8fCB7fSwgY29udGV4dCk7XG4gICAgICAgICAgICBmaXh0dXJlLmlkID0gcGFyZW50SWQ7XG4gICAgICAgICAgICBnZW5lcmF0ZWRGaXh0dXJlcy5wdXNoKHsgZW50aXR5OiBzcGVjLmVudGl0eSwgZGF0YTogZml4dHVyZSwgZXhwbGljaXRJZDogdHJ1ZSB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3BlYy5jb3VudDsgaSsrKSB7XG4gICAgICAgICAgY29uc3QgZml4dHVyZSA9IGF3YWl0IHRoaXMuZ2VuZXJhdGUoc3BlYy5lbnRpdHksIHNwZWMub3ZlcnJpZGVzIHx8IHt9LCBjb250ZXh0KTtcbiAgICAgICAgICBnZW5lcmF0ZWRGaXh0dXJlcy5wdXNoKHtcbiAgICAgICAgICAgIGVudGl0eTogc3BlYy5lbnRpdHksXG4gICAgICAgICAgICBkYXRhOiBmaXh0dXJlLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gMi4gRml4dHVyZVJlY29yZOuhnCDrs4DtmZhcbiAgICBjb25zdCBmaXh0dXJlUmVjb3JkczogRml4dHVyZVJlY29yZFtdID0gW107XG4gICAgZm9yIChjb25zdCB7IGVudGl0eTogZW50aXR5TmFtZSwgZGF0YSwgZXhwbGljaXRJZCB9IG9mIGdlbmVyYXRlZEZpeHR1cmVzKSB7XG4gICAgICBjb25zdCBlbnRpdHkgPSB0aGlzLmVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eU5hbWUpO1xuXG4gICAgICAvLyBpbnRlZ2VyL2JpZ0ludGVnZXIgUEvripQg7J6E7IucIElEIOyDneyEsSAoREIg7Iuc7YCA7Iqk6rCAIOyLpOygnCBJRCDtlaDri7kpXG4gICAgICAvLyBzdHJpbmcgUEsgd2l0aCBkYkRlZmF1bHQgbmV4dHZhbOuPhCDrj5nsnbztlZjqsowg7LKY66asXG4gICAgICAvLyDqt7gg7Jm4IHN0cmluZy91dWlkIFBL64qUIGdlbmVyYXRlKCnsl5DshJwg7J2066+4IOyDneyEseuQnCBpZCDqsJLsnYQg6re464yA66GcIOyCrOyaqVxuICAgICAgLy8gcGFyZW50SWQg7JeU7Yuw7Yuw64qUIOu2gOuqqOydmCDsi6TsoJwgaWTrpbwg6re464yA66GcIOyCrOyaqSAo7Iuc7YCA7IqkIOuvuOyCrOyaqSlcbiAgICAgIGNvbnN0IGlkUHJvcCA9IGVudGl0eS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IFwiaWRcIik7XG4gICAgICBjb25zdCB1c2VzU2VxdWVuY2UgPVxuICAgICAgICAhZXhwbGljaXRJZCAmJlxuICAgICAgICAoaWRQcm9wPy50eXBlID09PSBcImludGVnZXJcIiB8fFxuICAgICAgICAgIGlkUHJvcD8udHlwZSA9PT0gXCJiaWdJbnRlZ2VyXCIgfHxcbiAgICAgICAgICAoaWRQcm9wPy50eXBlID09PSBcInN0cmluZ1wiICYmIHRoaXMuaGFzU2VxdWVuY2VEZWZhdWx0KGlkUHJvcCkpKTtcblxuICAgICAgY29uc3QgZGF0YUZvclJlY29yZCA9IHVzZXNTZXF1ZW5jZVxuICAgICAgICA/IHsgLi4uZGF0YSwgaWQ6IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIDEwMDAwMDApIH1cbiAgICAgICAgOiBkYXRhO1xuXG4gICAgICBjb25zdCByZWNvcmRzID0gYXdhaXQgRml4dHVyZU1hbmFnZXIuY3JlYXRlRml4dHVyZVJlY29yZChcbiAgICAgICAgZW50aXR5LFxuICAgICAgICBwYXJzZUZpeHR1cmVTb3VyY2VSZWNvcmQoZGF0YUZvclJlY29yZCksXG4gICAgICAgIHsgc2luZ2xlUmVjb3JkOiB0cnVlIH0sXG4gICAgICApO1xuICAgICAgZml4dHVyZVJlY29yZHMucHVzaCguLi5yZWNvcmRzKTtcbiAgICB9XG5cbiAgICAvLyAzLiB0YXJnZXREYuyXkCDsgr3snoUgKEZpeHR1cmVNYW5hZ2Vy6rCAIOydmOyhtOyEsSDsoJXroKwg7LKY66asKVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBGaXh0dXJlTWFuYWdlci5pbnNlcnRGaXh0dXJlcyh0aGlzLnRhcmdldERiTmFtZSwgZml4dHVyZVJlY29yZHMpO1xuXG4gICAgLy8gNC4gY29tcGFuaW9uIGZpeHR1cmVzIOyDneyEsSAoZml4dHVyZUNvbXBhbmlvbnPqsIAg7ISg7Ja465CcIOqyveyasClcbiAgICBjb25zdCBjb21wYW5pb25SZXN1bHRzID0gYXdhaXQgdGhpcy5nZW5lcmF0ZUNvbXBhbmlvbnMoc3BlY3MsIHJlc3VsdHMpO1xuXG4gICAgY29uc3QgdG90YWwgPSByZXN1bHRzLmxlbmd0aCArIGNvbXBhbmlvblJlc3VsdHMubGVuZ3RoO1xuICAgICFpc1Rlc3QoKSAmJlxuICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JlZW4oYEdlbmVyYXRlZCBhbmQgc2F2ZWQgJHt0b3RhbH0gZml4dHVyZXMgdG8gJHt0aGlzLnRhcmdldERiTmFtZX1gKSk7XG4gICAgcmV0dXJuIFsuLi5yZXN1bHRzLCAuLi5jb21wYW5pb25SZXN1bHRzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiDrtoDrqqggZml4dHVyZSDqsrDqs7zrpbwg6riw67CY7Jy866GcIGZpeHR1cmVDb21wYW5pb25z7JeQIOyEoOyWuOuQnCBjb21wYW5pb24gRW50aXR566W8IOyDneyEse2VqeuLiOuLpC5cbiAgICpcbiAgICogZ2VuZXJhdGVCYXRjaCgp7JeQ7ISc66eMIO2YuOy2nOuQmOupsCwgY29tcGFuaW9uIOyDneyEsSDsi5wg7J6s6reA66W8IOuwqeyngO2VmOq4sCDsnITtlbRcbiAgICogZ2VuZXJhdGVCYXRjaCgp66W8IOuLpOyLnCDtmLjstpztlZjsp4Ag7JWK6rOgIOyngeygkSDsgr3snoXtlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdlbmVyYXRlQ29tcGFuaW9ucyhcbiAgICBzcGVjczogRml4dHVyZUdlbmVyYXRpb25TcGVjW10sXG4gICAgcGFyZW50UmVzdWx0czogRml4dHVyZUltcG9ydFJlc3VsdFtdLFxuICApOiBQcm9taXNlPEZpeHR1cmVJbXBvcnRSZXN1bHRbXT4ge1xuICAgIGNvbnN0IGFsbFJlc3VsdHM6IEZpeHR1cmVJbXBvcnRSZXN1bHRbXSA9IFtdO1xuICAgIGNvbnN0IHByb2Nlc3NlZEVudGl0aWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBmb3IgKGNvbnN0IHNwZWMgb2Ygc3BlY3MpIHtcbiAgICAgIGlmIChwcm9jZXNzZWRFbnRpdGllcy5oYXMoc3BlYy5lbnRpdHkpKSBjb250aW51ZTtcbiAgICAgIHByb2Nlc3NlZEVudGl0aWVzLmFkZChzcGVjLmVudGl0eSk7XG5cbiAgICAgIGNvbnN0IGVudGl0eSA9IHRoaXMuZW50aXR5TWFuYWdlci5nZXQoc3BlYy5lbnRpdHkpO1xuICAgICAgY29uc3QgaWRQcm9wID0gZW50aXR5LnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gXCJpZFwiKTtcbiAgICAgIGNvbnN0IGNvbXBhbmlvbnMgPSBpZFByb3A/LmNvbmU/LmZpeHR1cmVDb21wYW5pb25zO1xuICAgICAgaWYgKCFjb21wYW5pb25zIHx8IGNvbXBhbmlvbnMubGVuZ3RoID09PSAwKSBjb250aW51ZTtcblxuICAgICAgY29uc3QgZW50aXR5UmVzdWx0cyA9IHBhcmVudFJlc3VsdHMuZmlsdGVyKChyKSA9PiByLmVudGl0eUlkID09PSBzcGVjLmVudGl0eSk7XG4gICAgICBpZiAoZW50aXR5UmVzdWx0cy5sZW5ndGggPT09IDApIGNvbnRpbnVlO1xuXG4gICAgICBmb3IgKGNvbnN0IGNvbXBhbmlvbiBvZiBjb21wYW5pb25zKSB7XG4gICAgICAgIC8vIGNvbXBhbmlvbiBlbnRpdHnsl5DshJwg67aA66qoIGVudGl0eeuhnOydmCBCZWxvbmdzVG9PbmUgRksg7Lus65+866qFIO2MjOyVhVxuICAgICAgICBjb25zdCBjb21wYW5pb25FbnRpdHkgPSB0aGlzLmVudGl0eU1hbmFnZXIuZ2V0KGNvbXBhbmlvbi5lbnRpdHkpO1xuICAgICAgICBjb25zdCBma1Byb3AgPSBjb21wYW5pb25FbnRpdHkucHJvcHMuZmluZChcbiAgICAgICAgICAocCkgPT4gaXNSZWxhdGlvblByb3AocCkgJiYgaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocCkgJiYgcC53aXRoID09PSBzcGVjLmVudGl0eSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCFma1Byb3ApIHtcbiAgICAgICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgY2hhbGsueWVsbG93KFxuICAgICAgICAgICAgICAgIGBbQ29tcGFuaW9uXSBObyBCZWxvbmdzVG9PbmUgcmVsYXRpb24gZnJvbSAke2NvbXBhbmlvbi5lbnRpdHl9IHRvICR7c3BlYy5lbnRpdHl9LiBTa2lwcGluZy5gLFxuICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBma0NvbE5hbWUgPSBgJHtma1Byb3AubmFtZX1faWRgO1xuXG4gICAgICAgIC8vIGNvbXBhbmlvbuydmCBpZFByb3AsIHVzZXNTZXF1ZW5jZSwgY291bnTripQgY29tcGFuaW9uIOuLqOychOuhnCDqs6DsoJVcbiAgICAgICAgY29uc3QgY29tcGFuaW9uSWRQcm9wID0gY29tcGFuaW9uRW50aXR5LnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gXCJpZFwiKTtcbiAgICAgICAgY29uc3QgdXNlc1NlcXVlbmNlID1cbiAgICAgICAgICBjb21wYW5pb25JZFByb3A/LnR5cGUgPT09IFwiaW50ZWdlclwiIHx8XG4gICAgICAgICAgY29tcGFuaW9uSWRQcm9wPy50eXBlID09PSBcImJpZ0ludGVnZXJcIiB8fFxuICAgICAgICAgIChjb21wYW5pb25JZFByb3A/LnR5cGUgPT09IFwic3RyaW5nXCIgJiYgdGhpcy5oYXNTZXF1ZW5jZURlZmF1bHQoY29tcGFuaW9uSWRQcm9wKSk7XG4gICAgICAgIGNvbnN0IGNvbXBhbmlvbkNvdW50ID0gY29tcGFuaW9uLmNvdW50ID8/IDE7XG5cbiAgICAgICAgLy8g6rCBIHBhcmVudCByZXN1bHTsl5Ag64yA7ZW0IGNvbXBhbmlvbiBmaXh0dXJlIOyDneyEsVxuICAgICAgICBjb25zdCBjb250ZXh0ID0gdGhpcy5jcmVhdGVDb250ZXh0KCk7XG4gICAgICAgIGNvbnN0IGNvbXBhbmlvbkZpeHR1cmVSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gPSBbXTtcblxuICAgICAgICBmb3IgKGNvbnN0IHBhcmVudFJlc3VsdCBvZiBlbnRpdHlSZXN1bHRzKSB7XG4gICAgICAgICAgY29uc3QgcmVzb2x2ZWRPdmVycmlkZXMgPSB0aGlzLnJlc29sdmVUZW1wbGF0ZU92ZXJyaWRlcyhcbiAgICAgICAgICAgIGRhdGFFeHBsb3JlclJlY29yZFNjaGVtYS5wYXJzZShjb21wYW5pb24ub3ZlcnJpZGVzID8/IHt9KSxcbiAgICAgICAgICAgIHBhcmVudFJlc3VsdC5kYXRhLFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmVzb2x2ZWRPdmVycmlkZXNbZmtDb2xOYW1lXSA9IHBhcmVudFJlc3VsdC5kYXRhLmlkO1xuXG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBjb21wYW5pb25Db3VudDsgaSsrKSB7XG4gICAgICAgICAgICBjb25zdCBmaXh0dXJlID0gYXdhaXQgdGhpcy5nZW5lcmF0ZShjb21wYW5pb24uZW50aXR5LCByZXNvbHZlZE92ZXJyaWRlcywgY29udGV4dCk7XG5cbiAgICAgICAgICAgIGNvbnN0IGRhdGFGb3JSZWNvcmQgPSB1c2VzU2VxdWVuY2VcbiAgICAgICAgICAgICAgPyB7IC4uLmZpeHR1cmUsIGlkOiBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAxMDAwMDAwKSB9XG4gICAgICAgICAgICAgIDogZml4dHVyZTtcblxuICAgICAgICAgICAgY29uc3QgcmVjb3JkcyA9IGF3YWl0IEZpeHR1cmVNYW5hZ2VyLmNyZWF0ZUZpeHR1cmVSZWNvcmQoXG4gICAgICAgICAgICAgIGNvbXBhbmlvbkVudGl0eSxcbiAgICAgICAgICAgICAgcGFyc2VGaXh0dXJlU291cmNlUmVjb3JkKGRhdGFGb3JSZWNvcmQpLFxuICAgICAgICAgICAgICB7IHNpbmdsZVJlY29yZDogdHJ1ZSB9LFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIGNvbXBhbmlvbkZpeHR1cmVSZWNvcmRzLnB1c2goLi4ucmVjb3Jkcyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY29tcGFuaW9uUmVzdWx0cyA9IGF3YWl0IEZpeHR1cmVNYW5hZ2VyLmluc2VydEZpeHR1cmVzKFxuICAgICAgICAgIHRoaXMudGFyZ2V0RGJOYW1lLFxuICAgICAgICAgIGNvbXBhbmlvbkZpeHR1cmVSZWNvcmRzLFxuICAgICAgICApO1xuICAgICAgICBhbGxSZXN1bHRzLnB1c2goLi4uY29tcGFuaW9uUmVzdWx0cyk7XG5cbiAgICAgICAgIWlzVGVzdCgpICYmXG4gICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICBjaGFsay5ncmVlbihcbiAgICAgICAgICAgICAgYFtDb21wYW5pb25dIEdlbmVyYXRlZCAke2NvbXBhbmlvblJlc3VsdHMubGVuZ3RofSAke2NvbXBhbmlvbi5lbnRpdHl9IGZpeHR1cmVzYCxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYWxsUmVzdWx0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBvdmVycmlkZXMg6rCS7J2YIFwie3tmaWVsZE5hbWV9fVwiIO2FnO2UjOumv+ydhCDrtoDrqqggZml4dHVyZSDrjbDsnbTthLDroZwg7LmY7ZmY7ZWp64uI64ukLlxuICAgKlxuICAgKiDsmIg6IHsgXCJhY2NvdW50X2lkXCI6IFwie3tlbWFpbH19XCIgfSDihpIgeyBcImFjY291bnRfaWRcIjogXCJ1c2VyQGV4YW1wbGUuY29tXCIgfVxuICAgKi9cbiAgcHJpdmF0ZSByZXNvbHZlVGVtcGxhdGVPdmVycmlkZXMoXG4gICAgb3ZlcnJpZGVzOiBEYXRhRXhwbG9yZXJSZWNvcmQsXG4gICAgcGFyZW50RGF0YTogeyBba2V5OiBzdHJpbmddOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHwgRGF0ZSB8IG51bGwgfSxcbiAgKTogRGF0YUV4cGxvcmVyUmVjb3JkIHtcbiAgICBjb25zdCByZXNvbHZlZDogRGF0YUV4cGxvcmVyUmVjb3JkID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMob3ZlcnJpZGVzKSkge1xuICAgICAgY29uc3QgdGVtcGxhdGUgPSB6LnN0cmluZygpLnNhZmVQYXJzZSh2YWx1ZSk7XG4gICAgICBpZiAodGVtcGxhdGUuc3VjY2VzcyAmJiB0ZW1wbGF0ZS5kYXRhLnN0YXJ0c1dpdGgoXCJ7e1wiKSAmJiB0ZW1wbGF0ZS5kYXRhLmVuZHNXaXRoKFwifX1cIikpIHtcbiAgICAgICAgY29uc3QgZmllbGROYW1lID0gdGVtcGxhdGUuZGF0YS5zbGljZSgyLCAtMikudHJpbSgpO1xuICAgICAgICBpZiAoIShmaWVsZE5hbWUgaW4gcGFyZW50RGF0YSkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBg7YWc7ZSM66a/IO2VhOuTnCBcIiR7ZmllbGROYW1lfVwi7J20KOqwgCkg67aA66qoIGZpeHR1cmUg642w7J207YSw7JeQIOyhtOyerO2VmOyngCDslYrsirXri4jri6QgKG92ZXJyaWRlIGtleTogXCIke2tleX1cIilgLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZWRba2V5XSA9IHBhcmVudERhdGFbZmllbGROYW1lXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc29sdmVkW2tleV0gPSB2YWx1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc29sdmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIOyLpOygnCBEQihzb3VyY2VEYinsl5DshJwg642w7J207YSw66W8IOyhsO2ajO2VmOyXrCBmaXh0dXJlIERCKHRhcmdldERiKeyXkCBpbXBvcnTtlanri4jri6QuXG4gICAqXG4gICAqIDEuIERhdGFFeHBsb3JlcuuhnCBzb3VyY2VEYuyXkOyEnCDrjbDsnbTthLAg7KGw7ZqMICjqtIDroKgg642w7J207YSwIO2PrO2VqClcbiAgICogMi4gRml4dHVyZVJlY29yZOuhnCDrs4DtmZhcbiAgICogMy4gdGFyZ2V0RGLsl5Ag7IK97J6FXG4gICAqXG4gICAqIEBwYXJhbSBlbnRpdHlOYW1lIC0g7KGw7ZqM7ZWgIGVudGl0eSDsnbTrpoRcbiAgICogQHBhcmFtIG9wdGlvbnMgLSDsobDtmowg7Ji17IWYIChzdHJhdGVneSwgbGltaXQsIGluY2x1ZGVSZWxhdGlvbnMg65OxKVxuICAgKiBAcmV0dXJucyDsoIDsnqXrkJwgZml4dHVyZSDrjbDsnbTthLAgKOyLpOygnCBEQiBJRCDtj6ztlagpXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIO2UhOuhnOuNleyFmCBEQuyXkOyEnCBVc2VyIDEw66qFICsg6rSA66CoIEVtcGxveWVlLCBEZXBhcnRtZW50IOqwgOyguOyYpOq4sFxuICAgKiBhd2FpdCBnZW5lcmF0b3IuaW1wb3J0RnJvbVNvdXJjZShcIlVzZXJcIiwge1xuICAgKiAgIHN0cmF0ZWd5OiBcInNhbXBsZVwiLFxuICAgKiAgIGxpbWl0OiAxMCxcbiAgICogICBpbmNsdWRlUmVsYXRpb25zOiB0cnVlLFxuICAgKiAgIG1heERlcHRoOiAyXG4gICAqIH0pO1xuICAgKi9cbiAgYXN5bmMgaW1wb3J0RnJvbVNvdXJjZShcbiAgICBlbnRpdHlOYW1lOiBzdHJpbmcsXG4gICAgb3B0aW9uczogRXhwbG9yZVdpdGhSZWxhdGlvbnNPcHRpb25zLFxuICApOiBQcm9taXNlPEZpeHR1cmVJbXBvcnRSZXN1bHRbXT4ge1xuICAgICFpc1Rlc3QoKSAmJlxuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIGNoYWxrLmJsdWUoXG4gICAgICAgICAgYEltcG9ydGluZyAke2VudGl0eU5hbWV9IGZyb20gc291cmNlIERCIHdpdGggb3B0aW9uczogJHtKU09OLnN0cmluZ2lmeSh7IHN0cmF0ZWd5OiBvcHRpb25zLnN0cmF0ZWd5LCBsaW1pdDogb3B0aW9ucy5saW1pdCwgaW5jbHVkZVJlbGF0aW9uczogb3B0aW9ucy5pbmNsdWRlUmVsYXRpb25zLCBtYXhEZXB0aDogb3B0aW9ucy5tYXhEZXB0aCB9KX1gLFxuICAgICAgICApLFxuICAgICAgKTtcblxuICAgIC8vIDEuIERhdGFFeHBsb3JlcuuhnCBzb3VyY2VEYuyXkOyEnCDrjbDsnbTthLAg7KGw7ZqMICjqtIDroKgg642w7J207YSwIO2PrO2VqClcbiAgICBjb25zdCBleHBsb3JlUmVzdWx0ID0gYXdhaXQgdGhpcy5kYXRhRXhwbG9yZXIuZXhwbG9yZVdpdGhSZWxhdGlvbnMoZW50aXR5TmFtZSwgb3B0aW9ucyk7XG5cbiAgICAhaXNUZXN0KCkgJiZcbiAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICBjaGFsay5jeWFuKFxuICAgICAgICAgIGBGb3VuZCAke2V4cGxvcmVSZXN1bHQubWFpbi5yZWNvcmRzLmxlbmd0aH0gJHtlbnRpdHlOYW1lfSByZWNvcmRzIGFuZCAke2V4cGxvcmVSZXN1bHQucmVsYXRlZC5zaXplfSByZWxhdGVkIGVudGl0aWVzYCxcbiAgICAgICAgKSxcbiAgICAgICk7XG5cbiAgICAvLyAyLiBGaXh0dXJlUmVjb3Jk66GcIOuzgO2ZmFxuICAgIGNvbnN0IGZpeHR1cmVSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gPSBbXTtcblxuICAgIC8vIOuplOyduCBlbnRpdHnsnZggcmVjb3Jkc+ulvCBGaXh0dXJlUmVjb3Jk66GcIOuzgO2ZmFxuICAgIGNvbnN0IG1haW5FbnRpdHkgPSB0aGlzLmVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eU5hbWUpO1xuICAgIGZvciAoY29uc3QgcmVjb3JkIG9mIGV4cGxvcmVSZXN1bHQubWFpbi5yZWNvcmRzKSB7XG4gICAgICBjb25zdCByZWNvcmRzID0gYXdhaXQgRml4dHVyZU1hbmFnZXIuY3JlYXRlRml4dHVyZVJlY29yZChcbiAgICAgICAgbWFpbkVudGl0eSxcbiAgICAgICAgcGFyc2VGaXh0dXJlU291cmNlUmVjb3JkKHJlY29yZCksXG4gICAgICAgIHsgZGI6IHRoaXMuc291cmNlRGIsIHNpbmdsZVJlY29yZDogdHJ1ZSB9LFxuICAgICAgKTtcbiAgICAgIGZpeHR1cmVSZWNvcmRzLnB1c2goLi4ucmVjb3Jkcyk7XG4gICAgfVxuXG4gICAgLy8g6rSA66CoIGVudGl0eeydmCByZWNvcmRz66W8IEZpeHR1cmVSZWNvcmTroZwg67OA7ZmYXG4gICAgZm9yIChjb25zdCBbcmVsYXRlZEVudGl0eU5hbWUsIHJlbGF0ZWRSZWNvcmRzXSBvZiBleHBsb3JlUmVzdWx0LnJlbGF0ZWQuZW50cmllcygpKSB7XG4gICAgICBjb25zdCByZWxhdGVkRW50aXR5ID0gdGhpcy5lbnRpdHlNYW5hZ2VyLmdldChyZWxhdGVkRW50aXR5TmFtZSk7XG4gICAgICBmb3IgKGNvbnN0IHJlY29yZCBvZiByZWxhdGVkUmVjb3Jkcykge1xuICAgICAgICBjb25zdCByZWNvcmRzID0gYXdhaXQgRml4dHVyZU1hbmFnZXIuY3JlYXRlRml4dHVyZVJlY29yZChcbiAgICAgICAgICByZWxhdGVkRW50aXR5LFxuICAgICAgICAgIHBhcnNlRml4dHVyZVNvdXJjZVJlY29yZChyZWNvcmQpLFxuICAgICAgICAgIHsgZGI6IHRoaXMuc291cmNlRGIsIHNpbmdsZVJlY29yZDogdHJ1ZSB9LFxuICAgICAgICApO1xuICAgICAgICBmaXh0dXJlUmVjb3Jkcy5wdXNoKC4uLnJlY29yZHMpO1xuICAgICAgfVxuXG4gICAgICAhaXNUZXN0KCkgJiZcbiAgICAgICAgY29uc29sZS5sb2coY2hhbGsuZ3JheShgICAtICR7cmVsYXRlZEVudGl0eU5hbWV9OiAke3JlbGF0ZWRSZWNvcmRzLmxlbmd0aH0gcmVjb3Jkc2ApKTtcbiAgICB9XG5cbiAgICAvLyAzLiB0YXJnZXREYuyXkCDsgr3snoUgKEZpeHR1cmVNYW5hZ2Vy6rCAIOydmOyhtOyEsSDsoJXroKwg7LKY66asKVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBGaXh0dXJlTWFuYWdlci5pbnNlcnRGaXh0dXJlcyh0aGlzLnRhcmdldERiTmFtZSwgZml4dHVyZVJlY29yZHMpO1xuXG4gICAgIWlzVGVzdCgpICYmXG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgY2hhbGsuZ3JlZW4oXG4gICAgICAgICAgYFN1Y2Nlc3NmdWxseSBpbXBvcnRlZCAke3Jlc3VsdHMubGVuZ3RofSByZWNvcmRzIHRvICR7dGhpcy50YXJnZXREYk5hbWV9ICgke2V4cGxvcmVSZXN1bHQubWFpbi5yZWNvcmRzLmxlbmd0aH0gJHtlbnRpdHlOYW1lfSArICR7cmVzdWx0cy5sZW5ndGggLSBleHBsb3JlUmVzdWx0Lm1haW4ucmVjb3Jkcy5sZW5ndGh9IHJlbGF0ZWQpYCxcbiAgICAgICAgKSxcbiAgICAgICk7XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQXFEQSxTQUFTLHlCQUF5QixRQUFpRDtDQUNqRixPQUFPO0VBQ0wsR0FBRztFQUNILElBQUksc0JBQXNCLE1BQU0sT0FBTyxFQUFFO0NBQzNDO0FBQ0Y7OztZQWpEbUc7aUJBQ3ZEO29CQUNZO29CQUN5QztxQkFJakQ7c0JBRUU7Q0FVNUMsc0JBQXNCLEVBQUUsT0FDNUIsaUJBQ0EsNEJBQ0Y7Q0FDTSw2QkFBNkIsRUFBRSxPQUFPLENBQUMsQ0FBQztDQUN4Qyx5QkFBeUIsRUFBRSxRQUM5QixjQUFjLDJCQUEyQixVQUFVLFNBQVMsQ0FBQyxDQUFDLFNBQy9ELCtCQUNGO0NBQ00sMkJBQTJCLEVBQUUsTUFBTSx1QkFBdUI7Q0FDMUQsd0JBQXdCLEVBQUUsTUFBTSxDQUFDLEVBQUUsT0FBTyxHQUFHLEVBQUUsT0FBTyxDQUFDLENBQUM7Q0FDeEQsMEJBQTBCLEVBQUUsTUFBTTtFQUFDLEVBQUUsT0FBTztFQUFHLEVBQUUsT0FBTztFQUFHLEVBQUUsUUFBUTtFQUFHLEVBQUUsS0FBSztFQUFHLEVBQUUsS0FBSztDQUFDLENBQUM7Q0E4Q3BGLG1CQUFiLE1BQThCO0VBU2xCO0VBSUE7RUFDQTtFQWJWO0VBQ0E7RUFDQTtFQUNBLDJCQUFtRCxJQUFJLElBQUk7RUFDM0QsOEJBQTJDLElBQUksSUFBSTtFQUNuRDtFQUVBLFlBQ0UsVUFHQSxXQUNBLGNBQ0EsZUFDQSxTQUNBO0dB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
|