sonamu 0.8.25 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +60 -13
- package/dist/_virtual/rolldown_runtime.js +39 -0
- package/dist/ai/agents/agent.d.ts +3 -3
- package/dist/ai/agents/agent.d.ts.map +1 -1
- package/dist/ai/agents/agent.js +76 -73
- package/dist/ai/agents/index.js +3 -3
- package/dist/ai/agents/types.d.ts +3 -3
- package/dist/ai/agents/types.d.ts.map +1 -1
- package/dist/ai/agents/types.js +1 -3
- package/dist/ai/index.js +3 -2
- package/dist/ai/providers/rtzr/api.js +25 -25
- package/dist/ai/providers/rtzr/error.js +25 -26
- package/dist/ai/providers/rtzr/index.js +5 -5
- package/dist/ai/providers/rtzr/model.d.ts +1 -1
- package/dist/ai/providers/rtzr/model.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/model.js +117 -133
- package/dist/ai/providers/rtzr/options.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/options.js +35 -41
- package/dist/ai/providers/rtzr/provider.d.ts +1 -1
- package/dist/ai/providers/rtzr/provider.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/provider.js +53 -51
- package/dist/ai/providers/rtzr/utils.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/utils.js +84 -84
- package/dist/api/base-frame.d.ts +2 -2
- package/dist/api/base-frame.d.ts.map +1 -1
- package/dist/api/base-frame.js +29 -19
- package/dist/api/caster.d.ts +1 -1
- package/dist/api/caster.d.ts.map +1 -1
- package/dist/api/caster.js +51 -61
- package/dist/api/code-converters.d.ts +4 -3
- package/dist/api/code-converters.d.ts.map +1 -1
- package/dist/api/code-converters.js +226 -249
- package/dist/api/config.d.ts +17 -17
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +37 -30
- package/dist/api/context.d.ts +10 -10
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +8 -2
- package/dist/api/decorators.d.ts +8 -8
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +245 -268
- package/dist/api/index.js +39 -7
- package/dist/api/secret.js +22 -15
- package/dist/api/sonamu.d.ts +15 -15
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +1012 -1131
- package/dist/api/validator.js +88 -79
- package/dist/auth/auth-generator.d.ts.map +1 -1
- package/dist/auth/auth-generator.js +203 -200
- package/dist/auth/better-auth-entities.d.ts +2 -2
- package/dist/auth/better-auth-entities.d.ts.map +1 -1
- package/dist/auth/better-auth-entities.js +369 -429
- package/dist/auth/index.js +21 -6
- package/dist/auth/knex-adapter.d.ts +2 -2
- package/dist/auth/knex-adapter.d.ts.map +1 -1
- package/dist/auth/knex-adapter.js +153 -153
- package/dist/auth/plugins/entity-definitions/admin.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/admin.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/admin.js +58 -56
- package/dist/auth/plugins/entity-definitions/anonymous.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/anonymous.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/anonymous.js +20 -20
- package/dist/auth/plugins/entity-definitions/api-key.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/api-key.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/api-key.js +185 -196
- package/dist/auth/plugins/entity-definitions/index.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/index.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/index.js +26 -29
- package/dist/auth/plugins/entity-definitions/jwt.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/jwt.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/jwt.js +62 -64
- package/dist/auth/plugins/entity-definitions/organization.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/organization.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/organization.js +362 -421
- package/dist/auth/plugins/entity-definitions/passkey.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/passkey.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/passkey.js +115 -126
- package/dist/auth/plugins/entity-definitions/phone-number.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/phone-number.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/phone-number.js +31 -40
- package/dist/auth/plugins/entity-definitions/sso.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/sso.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/sso.js +94 -107
- package/dist/auth/plugins/entity-definitions/two-factor.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/two-factor.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/two-factor.js +78 -92
- package/dist/auth/plugins/entity-definitions/types.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/types.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/types.js +1 -10
- package/dist/auth/plugins/entity-definitions/username.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/username.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/username.js +31 -40
- package/dist/auth/plugins/index.js +12 -3
- package/dist/auth/plugins/wrappers/admin.d.ts +2 -2
- package/dist/auth/plugins/wrappers/admin.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/admin.js +28 -29
- package/dist/auth/plugins/wrappers/anonymous.d.ts +2 -1
- package/dist/auth/plugins/wrappers/anonymous.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/anonymous.js +23 -22
- package/dist/auth/plugins/wrappers/api-key.d.ts +2 -1
- package/dist/auth/plugins/wrappers/api-key.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/api-key.js +39 -34
- package/dist/auth/plugins/wrappers/index.js +11 -11
- package/dist/auth/plugins/wrappers/jwt.d.ts +2 -1
- package/dist/auth/plugins/wrappers/jwt.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/jwt.js +31 -26
- package/dist/auth/plugins/wrappers/organization.d.ts +2 -1
- package/dist/auth/plugins/wrappers/organization.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/organization.js +65 -62
- package/dist/auth/plugins/wrappers/passkey.d.ts +2 -1
- package/dist/auth/plugins/wrappers/passkey.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/passkey.js +33 -28
- package/dist/auth/plugins/wrappers/phone-number.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/phone-number.js +26 -23
- package/dist/auth/plugins/wrappers/sso.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/sso.js +37 -31
- package/dist/auth/plugins/wrappers/two-factor.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/two-factor.js +31 -28
- package/dist/auth/plugins/wrappers/username.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/username.js +23 -23
- package/dist/bin/build-config.js +31 -31
- package/dist/bin/cli.js +1063 -1204
- package/dist/bin/fixture.d.ts.map +1 -1
- package/dist/bin/fixture.js +266 -259
- package/dist/bin/hmr-hook-register.d.ts.map +1 -1
- package/dist/bin/hmr-hook-register.js +19 -18
- package/dist/bin/test-command.d.ts.map +1 -1
- package/dist/bin/test-command.js +180 -177
- package/dist/bin/ts-loader-register.js +13 -6
- package/dist/bin/ts-loader-registration.d.ts.map +1 -1
- package/dist/bin/ts-loader-registration.js +28 -38
- package/dist/cache/cache-manager.d.ts +1 -1
- package/dist/cache/cache-manager.d.ts.map +1 -1
- package/dist/cache/cache-manager.js +20 -15
- package/dist/cache/decorator.d.ts +1 -1
- package/dist/cache/decorator.d.ts.map +1 -1
- package/dist/cache/decorator.js +84 -76
- package/dist/cache/drivers.js +21 -34
- package/dist/cache/index.js +10 -7
- package/dist/cache/types.d.ts +2 -2
- package/dist/cache/types.d.ts.map +1 -1
- package/dist/cache/types.js +1 -6
- package/dist/cache-control/cache-control.d.ts +2 -2
- package/dist/cache-control/cache-control.d.ts.map +1 -1
- package/dist/cache-control/cache-control.js +106 -122
- package/dist/cache-control/types.d.ts +2 -2
- package/dist/cache-control/types.d.ts.map +1 -1
- package/dist/cache-control/types.js +1 -19
- package/dist/compress/compress.d.ts +1 -1
- package/dist/compress/compress.d.ts.map +1 -1
- package/dist/compress/compress.js +58 -56
- package/dist/compress/index.js +7 -2
- package/dist/compress/types.js +1 -11
- package/dist/cone/cone-generator.d.ts +1 -1
- package/dist/cone/cone-generator.d.ts.map +1 -1
- package/dist/cone/cone-generator.js +216 -219
- package/dist/database/_batch_update.d.ts +1 -1
- package/dist/database/_batch_update.d.ts.map +1 -1
- package/dist/database/_batch_update.js +107 -102
- package/dist/database/base-model.d.ts +8 -9
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.js +371 -392
- package/dist/database/base-model.types.d.ts +5 -5
- package/dist/database/base-model.types.d.ts.map +1 -1
- package/dist/database/base-model.types.js +1 -20
- package/dist/database/db.d.ts +5 -2
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +185 -171
- package/dist/database/knex.d.ts +1 -1
- package/dist/database/knex.d.ts.map +1 -1
- package/dist/database/knex.js +48 -42
- package/dist/database/puri-subset.types.d.ts +7 -8
- package/dist/database/puri-subset.types.d.ts.map +1 -1
- package/dist/database/puri-subset.types.js +1 -16
- package/dist/database/puri-wrapper.d.ts +6 -6
- package/dist/database/puri-wrapper.d.ts.map +1 -1
- package/dist/database/puri-wrapper.js +99 -101
- package/dist/database/puri.d.ts +4 -5
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +1021 -1227
- package/dist/database/puri.types.d.ts +6 -6
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/puri.types.js +15 -6
- package/dist/database/transaction-context.d.ts +2 -2
- package/dist/database/transaction-context.d.ts.map +1 -1
- package/dist/database/transaction-context.js +22 -13
- package/dist/database/upsert-builder.d.ts +3 -3
- package/dist/database/upsert-builder.d.ts.map +1 -1
- package/dist/database/upsert-builder.js +405 -465
- package/dist/dict/en.js +72 -74
- package/dist/dict/index.js +13 -13
- package/dist/dict/ko.js +72 -74
- package/dist/dict/rc-keys.js +150 -168
- package/dist/dict/sd.d.ts +3 -1
- package/dist/dict/sd.d.ts.map +1 -1
- package/dist/dict/sd.js +54 -40
- package/dist/dict/sonamu-dictionary.d.ts +1 -1
- package/dist/dict/sonamu-dictionary.d.ts.map +1 -1
- package/dist/dict/sonamu-dictionary.js +887 -955
- package/dist/dict/types.js +1 -7
- package/dist/dict/utils.js +26 -24
- package/dist/entity/entity-manager.d.ts +9 -9
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +226 -223
- package/dist/entity/entity-template-cone.d.ts +1 -1
- package/dist/entity/entity-template-cone.d.ts.map +1 -1
- package/dist/entity/entity-template-cone.js +152 -151
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +952 -1089
- package/dist/exceptions/error-handler.d.ts +1 -1
- package/dist/exceptions/error-handler.d.ts.map +1 -1
- package/dist/exceptions/error-handler.js +32 -27
- package/dist/exceptions/so-exceptions.d.ts +1 -1
- package/dist/exceptions/so-exceptions.d.ts.map +1 -1
- package/dist/exceptions/so-exceptions.js +61 -68
- package/dist/filter/index.js +9 -3
- package/dist/filter/types.js +92 -88
- package/dist/filter/utils.d.ts +1 -1
- package/dist/filter/utils.d.ts.map +1 -1
- package/dist/filter/utils.js +147 -161
- package/dist/index.js +87 -40
- package/dist/logger/category.d.ts.map +1 -1
- package/dist/logger/category.js +30 -29
- package/dist/logger/configure.d.ts.map +1 -1
- package/dist/logger/configure.js +83 -107
- package/dist/migration/code-generation.d.ts +2 -2
- package/dist/migration/code-generation.d.ts.map +1 -1
- package/dist/migration/code-generation.js +1385 -1578
- package/dist/migration/migration-set.d.ts +1 -1
- package/dist/migration/migration-set.d.ts.map +1 -1
- package/dist/migration/migration-set.js +177 -227
- package/dist/migration/migrator.d.ts +4 -3
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +340 -345
- package/dist/migration/postgresql-schema-reader.d.ts +2 -2
- package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
- package/dist/migration/postgresql-schema-reader.js +506 -564
- package/dist/migration/slack-confirm.d.ts +2 -2
- package/dist/migration/slack-confirm.d.ts.map +1 -1
- package/dist/migration/slack-confirm.js +205 -193
- package/dist/migration/types.d.ts +2 -2
- package/dist/migration/types.d.ts.map +1 -1
- package/dist/migration/types.js +1 -3
- package/dist/naite/messaging-types.d.ts +1 -0
- package/dist/naite/messaging-types.d.ts.map +1 -1
- package/dist/naite/messaging-types.js +1 -7
- package/dist/naite/naite-reporter.d.ts +2 -2
- package/dist/naite/naite-reporter.d.ts.map +1 -1
- package/dist/naite/naite-reporter.js +127 -120
- package/dist/naite/naite.d.ts +3 -2
- package/dist/naite/naite.d.ts.map +1 -1
- package/dist/naite/naite.js +266 -300
- package/dist/ssr/index.d.ts +2 -2
- package/dist/ssr/index.d.ts.map +1 -1
- package/dist/ssr/index.js +13 -3
- package/dist/ssr/registry.d.ts +1 -1
- package/dist/ssr/registry.d.ts.map +1 -1
- package/dist/ssr/registry.js +45 -37
- package/dist/ssr/renderer.d.ts +4 -4
- package/dist/ssr/renderer.d.ts.map +1 -1
- package/dist/ssr/renderer.js +84 -91
- package/dist/ssr/types.d.ts +2 -2
- package/dist/ssr/types.d.ts.map +1 -1
- package/dist/ssr/types.js +1 -3
- package/dist/storage/base-file.js +54 -41
- 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 +51 -44
- package/dist/storage/drivers.d.ts +2 -2
- package/dist/storage/drivers.d.ts.map +1 -1
- package/dist/storage/drivers.js +12 -7
- package/dist/storage/index.js +14 -7
- package/dist/storage/s3-driver.d.ts +2 -2
- package/dist/storage/s3-driver.d.ts.map +1 -1
- package/dist/storage/s3-driver.js +52 -48
- package/dist/storage/storage-manager.d.ts +2 -2
- package/dist/storage/storage-manager.d.ts.map +1 -1
- package/dist/storage/storage-manager.js +33 -25
- package/dist/storage/types.d.ts +2 -2
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/types.js +1 -5
- package/dist/storage/uploaded-file.d.ts +1 -1
- package/dist/storage/uploaded-file.d.ts.map +1 -1
- package/dist/storage/uploaded-file.js +45 -35
- package/dist/stream/index.js +7 -2
- package/dist/stream/sse.d.ts +2 -2
- package/dist/stream/sse.d.ts.map +1 -1
- package/dist/stream/sse.js +72 -67
- package/dist/syncer/api-parser.d.ts +1 -1
- package/dist/syncer/api-parser.d.ts.map +1 -1
- package/dist/syncer/api-parser.js +224 -245
- package/dist/syncer/checksum.d.ts +1 -1
- package/dist/syncer/checksum.d.ts.map +1 -1
- package/dist/syncer/checksum.js +86 -72
- package/dist/syncer/code-generator.d.ts +2 -2
- package/dist/syncer/code-generator.d.ts.map +1 -1
- package/dist/syncer/code-generator.js +154 -160
- package/dist/syncer/entity-operations.d.ts +1 -1
- package/dist/syncer/entity-operations.d.ts.map +1 -1
- package/dist/syncer/entity-operations.js +63 -54
- package/dist/syncer/file-patterns.d.ts +1 -1
- package/dist/syncer/file-patterns.d.ts.map +1 -1
- package/dist/syncer/file-patterns.js +38 -38
- package/dist/syncer/index.js +19 -8
- package/dist/syncer/module-loader.d.ts +5 -5
- package/dist/syncer/module-loader.d.ts.map +1 -1
- package/dist/syncer/module-loader.js +83 -78
- package/dist/syncer/syncer-actions.d.ts +2 -2
- package/dist/syncer/syncer-actions.d.ts.map +1 -1
- package/dist/syncer/syncer-actions.js +76 -91
- package/dist/syncer/syncer.d.ts +7 -6
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +426 -492
- package/dist/tasks/decorator.d.ts +3 -3
- package/dist/tasks/decorator.d.ts.map +1 -1
- package/dist/tasks/decorator.js +32 -28
- package/dist/tasks/step-wrapper.d.ts +1 -1
- package/dist/tasks/step-wrapper.d.ts.map +1 -1
- package/dist/tasks/step-wrapper.js +42 -41
- package/dist/tasks/workflow-manager.d.ts +2 -2
- package/dist/tasks/workflow-manager.d.ts.map +1 -1
- package/dist/tasks/workflow-manager.js +192 -221
- 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 +103 -103
- package/dist/template/helpers.d.ts.map +1 -1
- package/dist/template/helpers.js +163 -163
- package/dist/template/implementations/entity.template.d.ts +1 -1
- package/dist/template/implementations/entity.template.d.ts.map +1 -1
- package/dist/template/implementations/entity.template.js +76 -85
- package/dist/template/implementations/entry-server.template.d.ts +1 -1
- package/dist/template/implementations/entry-server.template.d.ts.map +1 -1
- package/dist/template/implementations/entry-server.template.js +32 -27
- package/dist/template/implementations/generated.template.d.ts +1 -1
- package/dist/template/implementations/generated.template.d.ts.map +1 -1
- package/dist/template/implementations/generated.template.js +254 -275
- package/dist/template/implementations/generated_http.template.d.ts +2 -2
- package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_http.template.js +114 -133
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_sso.template.js +249 -275
- package/dist/template/implementations/init_types.template.d.ts +1 -1
- package/dist/template/implementations/init_types.template.d.ts.map +1 -1
- package/dist/template/implementations/init_types.template.js +40 -34
- package/dist/template/implementations/model.template.d.ts +1 -1
- package/dist/template/implementations/model.template.d.ts.map +1 -1
- package/dist/template/implementations/model.template.js +56 -53
- package/dist/template/implementations/model_test.template.d.ts +1 -1
- package/dist/template/implementations/model_test.template.d.ts.map +1 -1
- package/dist/template/implementations/model_test.template.js +32 -24
- package/dist/template/implementations/queries.template.d.ts +1 -1
- package/dist/template/implementations/queries.template.d.ts.map +1 -1
- package/dist/template/implementations/queries.template.js +84 -89
- package/dist/template/implementations/sd.template.d.ts +1 -1
- package/dist/template/implementations/sd.template.d.ts.map +1 -1
- package/dist/template/implementations/sd.template.js +137 -144
- package/dist/template/implementations/services.template.d.ts +1 -1
- package/dist/template/implementations/services.template.d.ts.map +1 -1
- package/dist/template/implementations/services.template.js +164 -189
- package/dist/template/implementations/view_form.template.d.ts +1 -1
- package/dist/template/implementations/view_form.template.d.ts.map +1 -1
- package/dist/template/implementations/view_form.template.js +258 -285
- package/dist/template/implementations/view_id_all_select.template.d.ts +1 -1
- package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -1
- package/dist/template/implementations/view_id_all_select.template.js +31 -25
- package/dist/template/implementations/view_list.template.d.ts +1 -1
- package/dist/template/implementations/view_list.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list.template.js +304 -355
- package/dist/template/implementations/view_search_input.template.d.ts +1 -1
- package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
- package/dist/template/implementations/view_search_input.template.js +31 -27
- package/dist/template/index.js +21 -7
- package/dist/template/template-manager.d.ts +1 -1
- package/dist/template/template-manager.d.ts.map +1 -1
- package/dist/template/template-manager.js +132 -123
- package/dist/template/template-types.js +8 -6
- package/dist/template/template.d.ts +2 -2
- package/dist/template/template.d.ts.map +1 -1
- package/dist/template/template.js +73 -68
- package/dist/template/zod-converter.d.ts.map +1 -1
- package/dist/template/zod-converter.js +603 -657
- package/dist/testing/_relation-graph.d.ts +1 -1
- package/dist/testing/_relation-graph.d.ts.map +1 -1
- package/dist/testing/_relation-graph.js +93 -88
- package/dist/testing/bootstrap.d.ts +22 -13
- package/dist/testing/bootstrap.d.ts.map +1 -1
- package/dist/testing/bootstrap.js +114 -114
- package/dist/testing/data-explorer.d.ts +3 -3
- package/dist/testing/data-explorer.d.ts.map +1 -1
- package/dist/testing/data-explorer.js +237 -265
- package/dist/testing/dev-test-routes.d.ts +2 -2
- package/dist/testing/dev-test-routes.d.ts.map +1 -1
- package/dist/testing/dev-test-routes.js +258 -249
- package/dist/testing/dev-vitest-manager.d.ts +1 -1
- package/dist/testing/dev-vitest-manager.d.ts.map +1 -1
- package/dist/testing/dev-vitest-manager.js +514 -539
- package/dist/testing/faker-mappings.js +422 -420
- package/dist/testing/fixture-generator.d.ts +3 -3
- package/dist/testing/fixture-generator.d.ts.map +1 -1
- package/dist/testing/fixture-generator.js +1216 -1346
- package/dist/testing/fixture-loader.js +26 -25
- package/dist/testing/fixture-manager.d.ts +3 -3
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +706 -776
- package/dist/testing/global-setup.js +53 -49
- package/dist/testing/index.js +19 -11
- package/dist/testing/naite-vitest-reporter.js +18 -13
- package/dist/testing/parallel-db-manager.d.ts +1 -1
- package/dist/testing/parallel-db-manager.d.ts.map +1 -1
- package/dist/testing/parallel-db-manager.js +63 -78
- package/dist/testing/vitest-helpers.d.ts +1 -1
- package/dist/testing/vitest-helpers.d.ts.map +1 -1
- package/dist/testing/vitest-helpers.js +37 -33
- package/dist/types/types.d.ts +28 -28
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +764 -890
- package/dist/ui/ai-api.d.ts +1 -1
- package/dist/ui/ai-api.d.ts.map +1 -1
- package/dist/ui/ai-api.js +52 -42
- package/dist/ui/ai-client.d.ts +1 -2
- package/dist/ui/ai-client.d.ts.map +1 -1
- package/dist/ui/ai-client.js +353 -388
- package/dist/ui/api.d.ts +1 -1
- package/dist/ui/api.d.ts.map +1 -1
- package/dist/ui/api.js +903 -1145
- package/dist/ui/cdd-service.d.ts +15 -18
- package/dist/ui/cdd-service.d.ts.map +1 -1
- package/dist/ui/cdd-service.js +406 -383
- package/dist/ui/cdd-types.d.ts +41 -68
- package/dist/ui/cdd-types.d.ts.map +1 -1
- package/dist/ui/cdd-types.js +1 -3
- package/dist/ui-web/assets/index-C-Zz-wYg.css +1 -0
- package/dist/ui-web/assets/index-DejDON8K.js +238 -0
- package/dist/ui-web/index.html +3 -3
- package/dist/utils/async-utils.js +57 -45
- package/dist/utils/console-util.d.ts.map +1 -1
- package/dist/utils/console-util.js +104 -87
- package/dist/utils/controller.js +26 -19
- package/dist/utils/esm-utils.js +49 -38
- package/dist/utils/formatter.d.ts +1 -2
- package/dist/utils/formatter.d.ts.map +1 -1
- package/dist/utils/formatter.js +89 -115
- package/dist/utils/fs-utils.d.ts.map +1 -1
- package/dist/utils/fs-utils.js +68 -65
- package/dist/utils/lodash-able.js +11 -4
- package/dist/utils/model.d.ts +1 -1
- package/dist/utils/model.d.ts.map +1 -1
- package/dist/utils/model.js +21 -19
- package/dist/utils/object-utils.js +148 -186
- package/dist/utils/path-utils.js +67 -57
- package/dist/utils/process-utils.d.ts.map +1 -1
- package/dist/utils/process-utils.js +37 -31
- package/dist/utils/sql-parser.d.ts +1 -1
- package/dist/utils/sql-parser.d.ts.map +1 -1
- package/dist/utils/sql-parser.js +40 -40
- package/dist/utils/type-utils.js +44 -43
- package/dist/utils/utils.d.ts +2 -3
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +81 -93
- package/dist/utils/zod-error.d.ts +1 -1
- package/dist/utils/zod-error.d.ts.map +1 -1
- package/dist/utils/zod-error.js +24 -17
- package/dist/vector/chunking.d.ts +1 -1
- package/dist/vector/chunking.d.ts.map +1 -1
- package/dist/vector/chunking.js +100 -94
- package/dist/vector/config.d.ts +1 -1
- package/dist/vector/config.d.ts.map +1 -1
- package/dist/vector/config.js +76 -78
- package/dist/vector/embedding.d.ts +1 -1
- package/dist/vector/embedding.d.ts.map +1 -1
- package/dist/vector/embedding.js +128 -125
- package/dist/vector/index.js +5 -5
- package/dist/vector/types.js +1 -5
- package/package.json +35 -36
- package/src/ai/agents/agent.ts +12 -5
- package/src/ai/agents/types.ts +5 -5
- package/src/ai/providers/rtzr/model.ts +8 -10
- package/src/ai/providers/rtzr/options.ts +2 -1
- package/src/ai/providers/rtzr/provider.ts +5 -3
- package/src/ai/providers/rtzr/utils.ts +2 -7
- package/src/api/__tests__/config.test.ts +15 -8
- package/src/api/base-frame.ts +5 -3
- package/src/api/caster.ts +7 -6
- package/src/api/code-converters.ts +23 -26
- package/src/api/config.ts +23 -17
- package/src/api/context.ts +18 -11
- package/src/api/decorators.ts +17 -18
- package/src/api/sonamu.ts +44 -49
- package/src/auth/auth-generator.ts +4 -6
- package/src/auth/better-auth-entities.ts +3 -2
- package/src/auth/knex-adapter.ts +9 -7
- package/src/auth/plugins/entity-definitions/admin.ts +1 -1
- package/src/auth/plugins/entity-definitions/anonymous.ts +1 -1
- package/src/auth/plugins/entity-definitions/api-key.ts +1 -1
- package/src/auth/plugins/entity-definitions/index.ts +1 -1
- package/src/auth/plugins/entity-definitions/jwt.ts +1 -1
- package/src/auth/plugins/entity-definitions/organization.ts +1 -1
- package/src/auth/plugins/entity-definitions/passkey.ts +1 -1
- package/src/auth/plugins/entity-definitions/phone-number.ts +1 -1
- package/src/auth/plugins/entity-definitions/sso.ts +1 -1
- package/src/auth/plugins/entity-definitions/two-factor.ts +1 -1
- package/src/auth/plugins/entity-definitions/types.ts +1 -1
- package/src/auth/plugins/entity-definitions/username.ts +1 -1
- package/src/auth/plugins/wrappers/admin.ts +3 -1
- package/src/auth/plugins/wrappers/anonymous.ts +3 -1
- package/src/auth/plugins/wrappers/api-key.ts +3 -1
- package/src/auth/plugins/wrappers/jwt.ts +3 -1
- package/src/auth/plugins/wrappers/organization.ts +3 -1
- package/src/auth/plugins/wrappers/passkey.ts +3 -1
- package/src/auth/plugins/wrappers/phone-number.ts +3 -1
- package/src/auth/plugins/wrappers/sso.ts +2 -1
- package/src/auth/plugins/wrappers/two-factor.ts +3 -1
- package/src/auth/plugins/wrappers/username.ts +3 -1
- package/src/bin/__tests__/ts-loader-register.test.ts +7 -12
- package/src/bin/build-config.ts +3 -3
- package/src/bin/cli.ts +27 -25
- package/src/bin/fixture.ts +4 -2
- package/src/bin/hmr-hook-register.ts +1 -0
- package/src/bin/test-command.ts +4 -2
- package/src/bin/ts-loader-registration.ts +6 -22
- package/src/cache/cache-manager.ts +2 -1
- package/src/cache/decorator.ts +2 -2
- package/src/cache/types.ts +3 -3
- package/src/cache-control/cache-control.ts +3 -2
- package/src/cache-control/types.ts +2 -2
- package/src/compress/compress.ts +1 -1
- package/src/cone/cone-generator.ts +7 -5
- package/src/database/_batch_update.ts +1 -1
- package/src/database/base-model.ts +20 -14
- package/src/database/base-model.types.ts +12 -11
- package/src/database/db.ts +56 -21
- package/src/database/knex.ts +2 -2
- package/src/database/puri-subset.test-d.ts +130 -27
- package/src/database/puri-subset.types.ts +7 -8
- package/src/database/puri-wrapper.ts +29 -26
- package/src/database/puri.ts +36 -34
- package/src/database/puri.types.test-d.ts +6 -5
- package/src/database/puri.types.ts +9 -12
- package/src/database/transaction-context.ts +2 -2
- package/src/database/upsert-builder.ts +17 -10
- package/src/dict/sd.ts +17 -4
- package/src/dict/sonamu-dictionary.ts +23 -17
- package/src/entity/entity-manager.ts +9 -7
- package/src/entity/entity-template-cone.ts +10 -3
- package/src/entity/entity.ts +20 -16
- package/src/exceptions/error-handler.ts +2 -1
- package/src/exceptions/so-exceptions.ts +1 -1
- package/src/filter/utils.ts +3 -2
- package/src/logger/category.ts +1 -0
- package/src/logger/configure.ts +5 -5
- package/src/migration/__tests__/code-generation.search-text.test.ts +2 -3
- package/src/migration/code-generation.ts +26 -25
- package/src/migration/migration-set.ts +16 -18
- package/src/migration/migrator.ts +38 -33
- package/src/migration/postgresql-schema-reader.ts +12 -12
- package/src/migration/slack-confirm.ts +5 -4
- package/src/migration/types.ts +2 -2
- package/src/naite/messaging-types.ts +1 -1
- package/src/naite/naite-reporter.ts +5 -3
- package/src/naite/naite.ts +12 -7
- package/src/shared/app.shared.ts.txt +2 -2
- package/src/shared/web.shared.ts.txt +2 -2
- package/src/skills/AGENTS.md +19 -18
- package/src/skills/commands/sonamu-skills.md +9 -9
- package/src/skills/sonamu/SKILL.md +126 -76
- package/src/skills/sonamu/ai-agents.md +27 -26
- package/src/skills/sonamu/api.md +81 -69
- package/src/skills/sonamu/auth-migration.md +13 -27
- package/src/skills/sonamu/auth-plugins.md +41 -31
- package/src/skills/sonamu/auth.md +30 -24
- package/src/skills/sonamu/cdd.md +26 -17
- package/src/skills/sonamu/cone.md +50 -50
- package/src/skills/sonamu/config.md +74 -51
- package/src/skills/sonamu/create-sonamu.md +31 -19
- package/src/skills/sonamu/database.md +43 -26
- package/src/skills/sonamu/entity-basic.md +61 -61
- package/src/skills/sonamu/entity-relations.md +84 -80
- package/src/skills/sonamu/entity-validation-checklist.md +19 -15
- package/src/skills/sonamu/fixture-cli.md +52 -30
- package/src/skills/sonamu/framework-change.md +9 -7
- package/src/skills/sonamu/frontend.md +64 -82
- package/src/skills/sonamu/i18n.md +45 -37
- package/src/skills/sonamu/migration.md +54 -31
- package/src/skills/sonamu/model.md +98 -66
- package/src/skills/sonamu/naite.md +34 -32
- package/src/skills/sonamu/project-init.md +28 -8
- package/src/skills/sonamu/puri.md +82 -91
- package/src/skills/sonamu/scaffolding.md +44 -32
- package/src/skills/sonamu/skill-contribution.md +50 -45
- package/src/skills/sonamu/subset.md +13 -13
- package/src/skills/sonamu/tasks.md +73 -58
- package/src/skills/sonamu/testing-devrunner.md +56 -36
- package/src/skills/sonamu/testing.md +23 -58
- package/src/skills/sonamu/upsert.md +32 -31
- package/src/skills/sonamu/vector.md +37 -36
- package/src/ssr/index.ts +2 -12
- package/src/ssr/registry.ts +1 -1
- package/src/ssr/renderer.ts +7 -5
- package/src/ssr/types.ts +2 -2
- package/src/storage/buffered-file.ts +4 -2
- package/src/storage/drivers.ts +3 -2
- package/src/storage/s3-driver.ts +7 -4
- package/src/storage/storage-manager.ts +3 -2
- package/src/storage/types.ts +3 -2
- package/src/storage/uploaded-file.ts +1 -1
- package/src/stream/sse.ts +2 -2
- package/src/syncer/api-parser.ts +8 -5
- package/src/syncer/checksum.ts +9 -5
- package/src/syncer/code-generator.ts +16 -8
- package/src/syncer/entity-operations.ts +5 -3
- package/src/syncer/file-patterns.ts +2 -1
- package/src/syncer/module-loader.ts +9 -6
- package/src/syncer/syncer-actions.ts +5 -3
- package/src/syncer/syncer.ts +18 -24
- package/src/tasks/decorator.ts +10 -8
- package/src/tasks/step-wrapper.ts +1 -1
- package/src/tasks/workflow-manager.ts +18 -15
- package/src/template/__tests__/generated.template.search-text.test.ts +1 -0
- package/src/template/entity-converter.ts +4 -2
- package/src/template/generated.template.test-d.ts +2 -1
- package/src/template/helpers.ts +5 -2
- package/src/template/implementations/entity.template.ts +9 -8
- package/src/template/implementations/entry-server.template.ts +1 -1
- package/src/template/implementations/generated.template.ts +21 -29
- package/src/template/implementations/generated_http.template.ts +9 -6
- package/src/template/implementations/generated_sso.template.ts +6 -4
- package/src/template/implementations/init_types.template.ts +3 -2
- package/src/template/implementations/model.template.ts +4 -2
- package/src/template/implementations/model_test.template.ts +3 -2
- package/src/template/implementations/queries.template.ts +6 -14
- package/src/template/implementations/sd.template.ts +4 -2
- package/src/template/implementations/services.template.ts +7 -11
- package/src/template/implementations/view_form.template.ts +5 -3
- package/src/template/implementations/view_id_all_select.template.ts +3 -2
- package/src/template/implementations/view_list.template.ts +7 -5
- package/src/template/implementations/view_search_input.template.ts +3 -2
- package/src/template/template-manager.ts +4 -3
- package/src/template/template.ts +4 -3
- package/src/template/zod-converter.ts +10 -7
- package/src/testing/__tests__/dev-test-routes.test.ts +3 -2
- package/src/testing/__tests__/dev-vitest-manager.test.ts +1 -0
- package/src/testing/_relation-graph.ts +2 -2
- package/src/testing/bootstrap.ts +55 -27
- package/src/testing/data-explorer.ts +5 -4
- package/src/testing/dev-test-routes.ts +8 -5
- package/src/testing/dev-vitest-manager.ts +13 -12
- package/src/testing/fixture-generator.ts +15 -21
- package/src/testing/fixture-manager.ts +21 -17
- package/src/testing/parallel-db-manager.ts +2 -1
- package/src/testing/vitest-helpers.ts +2 -1
- package/src/types/__tests__/entity-json-schema-search-text.test.ts +1 -0
- package/src/types/types.ts +8 -8
- package/src/typings/knex.d.ts +4 -4
- package/src/ui/ai-api.ts +5 -3
- package/src/ui/ai-client.ts +7 -6
- package/src/ui/api.ts +42 -39
- package/src/ui/cdd-service.ts +268 -257
- package/src/ui/cdd-types.ts +40 -75
- package/src/utils/console-util.ts +3 -1
- package/src/utils/formatter.ts +94 -102
- package/src/utils/fs-utils.ts +2 -1
- package/src/utils/model.ts +2 -2
- package/src/utils/object-utils.ts +3 -3
- package/src/utils/process-utils.ts +2 -1
- package/src/utils/sql-parser.ts +10 -1
- package/src/utils/type-utils.ts +3 -3
- package/src/utils/utils.ts +9 -7
- package/src/utils/zod-error.ts +1 -1
- package/src/vector/chunking.ts +1 -1
- package/src/vector/config.ts +1 -1
- package/src/vector/embedding.ts +11 -9
- package/tsdown.api.config.ts +50 -0
- package/.swcrc.project-default +0 -18
- package/dist/api/__tests__/config.test.js +0 -189
- package/dist/bin/__tests__/test-command.test.js +0 -112
- package/dist/bin/__tests__/ts-loader-register.test.js +0 -45
- package/dist/database/puri-subset.test-d.js +0 -81
- package/dist/database/puri.types.test-d.js +0 -129
- package/dist/migration/__tests__/code-generation.search-text.test.js +0 -435
- package/dist/template/__tests__/generated.template.search-text.test.js +0 -99
- package/dist/template/generated.template.test-d.js +0 -24
- package/dist/testing/__tests__/dev-test-routes.test.js +0 -144
- package/dist/testing/__tests__/dev-vitest-manager.test.js +0 -152
- package/dist/types/__tests__/entity-json-schema-search-text.test.js +0 -256
- package/dist/typings/knex.d.js +0 -3
- package/dist/ui-web/assets/index-BrQKU3j9.css +0 -1
- package/dist/ui-web/assets/index-CxiydzeC.js +0 -257
package/dist/ui/api.js
CHANGED
|
@@ -1,1149 +1,907 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { __esmMin } from "../_virtual/rolldown_runtime.js";
|
|
2
|
+
import { createKnexInstance, init_knex } from "../database/knex.js";
|
|
3
|
+
import { DB, init_db } from "../database/db.js";
|
|
4
|
+
import { SD, init_sd } from "../dict/sd.js";
|
|
5
|
+
import { BadRequestException, ServiceUnavailableException, init_so_exceptions, isSoException } from "../exceptions/so-exceptions.js";
|
|
6
|
+
import { init_utils, nonNullable } from "../utils/utils.js";
|
|
7
|
+
import { Sonamu, init_sonamu } from "../api/sonamu.js";
|
|
8
|
+
import { BUILT_IN_TYPE_IDS, TemplateKey, init_types } from "../types/types.js";
|
|
9
|
+
import { EntityManager, init_entity_manager } from "../entity/entity-manager.js";
|
|
10
|
+
import { Migrator, init_migrator } from "../migration/migrator.js";
|
|
11
|
+
import { FixtureManager, init_fixture_manager } from "../testing/fixture-manager.js";
|
|
12
|
+
import { DataExplorer, init_data_explorer } from "../testing/data-explorer.js";
|
|
13
|
+
import { FixtureGenerator, init_fixture_generator } from "../testing/fixture-generator.js";
|
|
14
|
+
import { init_sonamu_dictionary, sonamuDictionary } from "../dict/sonamu-dictionary.js";
|
|
15
|
+
import { TemplateManager, init_template_manager } from "../template/template-manager.js";
|
|
16
|
+
import { SlackConfirm, init_slack_confirm } from "../migration/slack-confirm.js";
|
|
17
|
+
import { init_ai_api, setAiApi } from "./ai-api.js";
|
|
18
|
+
import { addRule, editContent, getAcList, getCddTree, init_cdd_service, listRules, openSourceFile, readContent, readRule } from "./cdd-service.js";
|
|
3
19
|
import inflection from "inflection";
|
|
4
|
-
import path from "path";
|
|
5
20
|
import { range } from "radashi";
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
});
|
|
869
|
-
server.post("/api/i18n/checkUsage", async (request)=>{
|
|
870
|
-
return sonamuDictionary.checkUsage(request.body.keys);
|
|
871
|
-
});
|
|
872
|
-
// Tasks API
|
|
873
|
-
server.get("/api/tasks/status", async ()=>{
|
|
874
|
-
try {
|
|
875
|
-
Sonamu.workflows;
|
|
876
|
-
return {
|
|
877
|
-
active: true
|
|
878
|
-
};
|
|
879
|
-
} catch {
|
|
880
|
-
return {
|
|
881
|
-
active: false
|
|
882
|
-
};
|
|
883
|
-
}
|
|
884
|
-
});
|
|
885
|
-
server.get("/api/tasks/workflowDefinitions", async ()=>{
|
|
886
|
-
const definitions = Sonamu.workflows.workflowDefinitions;
|
|
887
|
-
return {
|
|
888
|
-
definitions
|
|
889
|
-
};
|
|
890
|
-
});
|
|
891
|
-
server.get("/api/tasks/workflowRuns", async (request)=>{
|
|
892
|
-
const backend = Sonamu.workflows.backend;
|
|
893
|
-
const { limit, after, before, order, status, workflowName, createdAfter, createdBefore } = request.query;
|
|
894
|
-
return backend.listWorkflowRuns({
|
|
895
|
-
limit: limit ? Number.parseInt(limit, 10) : undefined,
|
|
896
|
-
after,
|
|
897
|
-
before,
|
|
898
|
-
order,
|
|
899
|
-
status: status ? status.split(",") : undefined,
|
|
900
|
-
workflowName: workflowName || undefined,
|
|
901
|
-
createdAfter: createdAfter ? new Date(createdAfter) : undefined,
|
|
902
|
-
createdBefore: createdBefore ? new Date(createdBefore) : undefined
|
|
903
|
-
});
|
|
904
|
-
});
|
|
905
|
-
server.get("/api/tasks/workflowRuns/:id", async (request)=>{
|
|
906
|
-
const backend = Sonamu.workflows.backend;
|
|
907
|
-
const workflowRun = await backend.getWorkflowRun({
|
|
908
|
-
workflowRunId: request.params.id
|
|
909
|
-
});
|
|
910
|
-
if (!workflowRun) {
|
|
911
|
-
throw new Error(`Workflow run not found: ${request.params.id}`);
|
|
912
|
-
}
|
|
913
|
-
return workflowRun;
|
|
914
|
-
});
|
|
915
|
-
server.post("/api/tasks/workflowRuns/:id/cancel", async (request)=>{
|
|
916
|
-
const backend = Sonamu.workflows.backend;
|
|
917
|
-
return backend.cancelWorkflowRun({
|
|
918
|
-
workflowRunId: request.params.id
|
|
919
|
-
});
|
|
920
|
-
});
|
|
921
|
-
server.post("/api/tasks/workflowRuns/:id/pause", async (request)=>{
|
|
922
|
-
const backend = Sonamu.workflows.backend;
|
|
923
|
-
return backend.pauseWorkflowRun({
|
|
924
|
-
workflowRunId: request.params.id
|
|
925
|
-
});
|
|
926
|
-
});
|
|
927
|
-
server.post("/api/tasks/workflowRuns/:id/resume", async (request)=>{
|
|
928
|
-
const backend = Sonamu.workflows.backend;
|
|
929
|
-
return backend.resumeWorkflowRun({
|
|
930
|
-
workflowRunId: request.params.id
|
|
931
|
-
});
|
|
932
|
-
});
|
|
933
|
-
server.get("/api/tasks/workflowRuns/:id/steps", async (request)=>{
|
|
934
|
-
const backend = Sonamu.workflows.backend;
|
|
935
|
-
const { limit, after, before } = request.query;
|
|
936
|
-
return backend.listStepAttempts({
|
|
937
|
-
workflowRunId: request.params.id,
|
|
938
|
-
limit: limit ? Number.parseInt(limit, 10) : undefined,
|
|
939
|
-
after,
|
|
940
|
-
before
|
|
941
|
-
});
|
|
942
|
-
});
|
|
943
|
-
/**
|
|
944
|
-
* Health Check API
|
|
945
|
-
* MCP 도구가 Sonamu 서버를 자동 감지하기 위한 엔드포인트
|
|
946
|
-
*/ server.get("/api/sonamu/health", async (request)=>{
|
|
947
|
-
const address = request.server.server.address();
|
|
948
|
-
const port = address && typeof address === "object" ? address.port : 0;
|
|
949
|
-
return {
|
|
950
|
-
ok: true,
|
|
951
|
-
project: process.cwd().split("/").pop() || "unknown",
|
|
952
|
-
port,
|
|
953
|
-
timestamp: new Date().toISOString()
|
|
954
|
-
};
|
|
955
|
-
});
|
|
956
|
-
/**
|
|
957
|
-
* Fixture 생성 API
|
|
958
|
-
*/ server.post("/api/sonamu/fixture/generate", async (request, reply)=>{
|
|
959
|
-
const { entity, count = 1, overrides, targetDb = "fixture" } = request.body;
|
|
960
|
-
// 타겟 DB 설정 가져오기
|
|
961
|
-
const dbConfig = targetDb === "fixture" ? Sonamu.dbConfig.fixture : Sonamu.dbConfig.test;
|
|
962
|
-
// Knex 인스턴스 생성
|
|
963
|
-
const db = createKnexInstance(dbConfig);
|
|
964
|
-
try {
|
|
965
|
-
// FixtureGenerator 생성
|
|
966
|
-
const generator = new FixtureGenerator(db, db, targetDb, EntityManager);
|
|
967
|
-
// 단일 Entity 배치 생성
|
|
968
|
-
const fixtures = await generator.generateBatch([
|
|
969
|
-
{
|
|
970
|
-
entity,
|
|
971
|
-
count,
|
|
972
|
-
overrides: overrides ?? {}
|
|
973
|
-
}
|
|
974
|
-
]);
|
|
975
|
-
return {
|
|
976
|
-
success: true,
|
|
977
|
-
entity,
|
|
978
|
-
count: fixtures.length,
|
|
979
|
-
fixtures,
|
|
980
|
-
targetDb
|
|
981
|
-
};
|
|
982
|
-
} catch (error) {
|
|
983
|
-
reply.status(400);
|
|
984
|
-
return {
|
|
985
|
-
success: false,
|
|
986
|
-
error: error instanceof Error ? error.message : String(error)
|
|
987
|
-
};
|
|
988
|
-
} finally{
|
|
989
|
-
await db.destroy();
|
|
990
|
-
}
|
|
991
|
-
});
|
|
992
|
-
/**
|
|
993
|
-
* Fixture 데이터 탐색 API
|
|
994
|
-
*/ server.post("/api/sonamu/fixture/explore", async (request, reply)=>{
|
|
995
|
-
const { entity, strategy, limit = 10, where } = request.body;
|
|
996
|
-
// Fixture DB 설정 가져오기
|
|
997
|
-
const fixtureDbConfig = Sonamu.dbConfig.fixture;
|
|
998
|
-
// Knex 인스턴스 생성
|
|
999
|
-
const fixtureDb = createKnexInstance(fixtureDbConfig);
|
|
1000
|
-
try {
|
|
1001
|
-
// DataExplorer 생성
|
|
1002
|
-
const explorer = new DataExplorer(fixtureDb, EntityManager);
|
|
1003
|
-
const data = await explorer.explore(entity, {
|
|
1004
|
-
strategy,
|
|
1005
|
-
limit,
|
|
1006
|
-
where
|
|
1007
|
-
});
|
|
1008
|
-
return {
|
|
1009
|
-
success: true,
|
|
1010
|
-
entity,
|
|
1011
|
-
strategy,
|
|
1012
|
-
count: data.length,
|
|
1013
|
-
data
|
|
1014
|
-
};
|
|
1015
|
-
} catch (error) {
|
|
1016
|
-
reply.status(400);
|
|
1017
|
-
return {
|
|
1018
|
-
success: false,
|
|
1019
|
-
error: error instanceof Error ? error.message : String(error)
|
|
1020
|
-
};
|
|
1021
|
-
} finally{
|
|
1022
|
-
await fixtureDb.destroy();
|
|
1023
|
-
}
|
|
1024
|
-
});
|
|
1025
|
-
/**
|
|
1026
|
-
* Fixture 데이터 가져오기 (fetch) API
|
|
1027
|
-
* production/development DB에서 실제 데이터를 fixture DB로 import
|
|
1028
|
-
*/ server.post("/api/sonamu/fixture/fetch", async (request, reply)=>{
|
|
1029
|
-
const { entity, strategy = "recent", limit = 10, includeRelations = true, maxDepth = 2 } = request.body;
|
|
1030
|
-
// Source DB (production/development) - 읽기 전용
|
|
1031
|
-
const sourceDb = DB.getDB("r");
|
|
1032
|
-
// Target DB (fixture)
|
|
1033
|
-
const fixtureDb = createKnexInstance(Sonamu.dbConfig.fixture);
|
|
1034
|
-
try {
|
|
1035
|
-
// FixtureGenerator 생성
|
|
1036
|
-
const generator = new FixtureGenerator(sourceDb, fixtureDb, "fixture", EntityManager);
|
|
1037
|
-
// production 데이터를 fixture DB로 import
|
|
1038
|
-
const results = await generator.importFromSource(entity, {
|
|
1039
|
-
strategy,
|
|
1040
|
-
limit,
|
|
1041
|
-
includeRelations,
|
|
1042
|
-
maxDepth
|
|
1043
|
-
});
|
|
1044
|
-
return {
|
|
1045
|
-
success: true,
|
|
1046
|
-
entity,
|
|
1047
|
-
strategy,
|
|
1048
|
-
count: results.length,
|
|
1049
|
-
imported: results
|
|
1050
|
-
};
|
|
1051
|
-
} catch (error) {
|
|
1052
|
-
reply.status(400);
|
|
1053
|
-
return {
|
|
1054
|
-
success: false,
|
|
1055
|
-
error: error instanceof Error ? error.message : String(error)
|
|
1056
|
-
};
|
|
1057
|
-
} finally{
|
|
1058
|
-
// sourceDb는 Sonamu가 관리하므로 destroy하지 않음
|
|
1059
|
-
await fixtureDb.destroy();
|
|
1060
|
-
}
|
|
1061
|
-
});
|
|
1062
|
-
/**
|
|
1063
|
-
* Fixture 데이터 삭제 (clean) API
|
|
1064
|
-
* FK 순서를 고려하여 안전하게 삭제
|
|
1065
|
-
*/ server.post("/api/sonamu/fixture/clean", async (request, reply)=>{
|
|
1066
|
-
const { entities } = request.body;
|
|
1067
|
-
// Fixture DB 연결
|
|
1068
|
-
const fixtureDb = createKnexInstance(Sonamu.dbConfig.fixture);
|
|
1069
|
-
try {
|
|
1070
|
-
// 삭제할 Entity 목록 결정
|
|
1071
|
-
const targetEntities = entities && entities.length > 0 ? entities : EntityManager.getAllIds();
|
|
1072
|
-
// Entity ID를 테이블명으로 변환 (snake_case 복수형)
|
|
1073
|
-
const tableNames = targetEntities.map((entityId)=>{
|
|
1074
|
-
const entity = EntityManager.get(entityId);
|
|
1075
|
-
return entity.table;
|
|
1076
|
-
});
|
|
1077
|
-
// PostgreSQL: TRUNCATE CASCADE로 FK 순서 무관하게 안전하게 삭제
|
|
1078
|
-
// CASCADE 옵션으로 의존성 있는 데이터도 함께 삭제
|
|
1079
|
-
await fixtureDb.raw(`TRUNCATE TABLE ${tableNames.map((t)=>`"${t}"`).join(", ")} RESTART IDENTITY CASCADE`);
|
|
1080
|
-
return {
|
|
1081
|
-
success: true,
|
|
1082
|
-
cleaned: tableNames,
|
|
1083
|
-
count: tableNames.length
|
|
1084
|
-
};
|
|
1085
|
-
} catch (error) {
|
|
1086
|
-
reply.status(400);
|
|
1087
|
-
return {
|
|
1088
|
-
success: false,
|
|
1089
|
-
error: error instanceof Error ? error.message : String(error)
|
|
1090
|
-
};
|
|
1091
|
-
} finally{
|
|
1092
|
-
await fixtureDb.destroy();
|
|
1093
|
-
}
|
|
1094
|
-
});
|
|
1095
|
-
// CDD API
|
|
1096
|
-
server.get("/api/cdd/dashboard", async ()=>{
|
|
1097
|
-
return getDashboard();
|
|
1098
|
-
});
|
|
1099
|
-
server.get("/api/cdd/tree", async ()=>{
|
|
1100
|
-
return getCddTree();
|
|
1101
|
-
});
|
|
1102
|
-
server.post("/api/cdd/readContent", async (request)=>{
|
|
1103
|
-
const { filePath } = request.body;
|
|
1104
|
-
return readContent(filePath);
|
|
1105
|
-
});
|
|
1106
|
-
server.post("/api/cdd/editContent", async (request)=>{
|
|
1107
|
-
const { filePath } = request.body;
|
|
1108
|
-
return editContent(filePath);
|
|
1109
|
-
});
|
|
1110
|
-
server.post("/api/cdd/openSource", async (request)=>{
|
|
1111
|
-
const { filePath } = request.body;
|
|
1112
|
-
openSourceFile(filePath);
|
|
1113
|
-
return {
|
|
1114
|
-
success: true
|
|
1115
|
-
};
|
|
1116
|
-
});
|
|
1117
|
-
// CDD Schema API
|
|
1118
|
-
server.get("/api/cdd/schemas", async ()=>{
|
|
1119
|
-
return listSchemas();
|
|
1120
|
-
});
|
|
1121
|
-
server.post("/api/cdd/readSchema", async (request)=>{
|
|
1122
|
-
const { schemaKey } = request.body;
|
|
1123
|
-
return readSchema(schemaKey);
|
|
1124
|
-
});
|
|
1125
|
-
server.post("/api/cdd/editSchema", async (request)=>{
|
|
1126
|
-
const { schemaKey } = request.body;
|
|
1127
|
-
return editSchema(schemaKey);
|
|
1128
|
-
});
|
|
1129
|
-
// ui-web 빌드 파일 서빙
|
|
1130
|
-
const uiDistPath = path.resolve(import.meta.dirname, "../ui-web");
|
|
1131
|
-
// 정적 파일 서빙: 루트 폴더 전체 (assets, setting.svg 등)
|
|
1132
|
-
server.register(await import("@fastify/static"), {
|
|
1133
|
-
root: uiDistPath,
|
|
1134
|
-
prefix: "/",
|
|
1135
|
-
decorateReply: false,
|
|
1136
|
-
wildcard: false
|
|
1137
|
-
});
|
|
1138
|
-
// SPA fallback - 정적 파일이 없는 모든 경로는 index.html로
|
|
1139
|
-
server.get("*", async (_request, reply)=>{
|
|
1140
|
-
reply.headers({
|
|
1141
|
-
"Content-type": "text/html"
|
|
1142
|
-
}).send(fs.readFileSync(path.resolve(uiDistPath, "index.html")).toString().replace("{{projectName}}", Sonamu.config.projectName ?? "UnknownSonamuProject"));
|
|
1143
|
-
});
|
|
1144
|
-
}, {
|
|
1145
|
-
prefix: "/sonamu-ui"
|
|
1146
|
-
});
|
|
21
|
+
import path from "path";
|
|
22
|
+
import fs from "fs";
|
|
23
|
+
import { execSync } from "child_process";
|
|
24
|
+
|
|
25
|
+
//#region src/ui/api.ts
|
|
26
|
+
async function sonamuUIApiPlugin(fastify) {
|
|
27
|
+
fastify.register(async (server) => {
|
|
28
|
+
const migrator = new Migrator();
|
|
29
|
+
async function waitForHMRCompleted(fn) {
|
|
30
|
+
const waitPromise = new Promise((resolve) => {
|
|
31
|
+
const handler = () => {
|
|
32
|
+
clearTimeout(timeout);
|
|
33
|
+
resolve();
|
|
34
|
+
};
|
|
35
|
+
const timeout = setTimeout(() => {
|
|
36
|
+
Sonamu.syncer.eventEmitter.off("onHMRCompleted", handler);
|
|
37
|
+
resolve();
|
|
38
|
+
}, 1500);
|
|
39
|
+
Sonamu.syncer.eventEmitter.once("onHMRCompleted", handler);
|
|
40
|
+
});
|
|
41
|
+
const result = await fn();
|
|
42
|
+
await waitPromise;
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
await setAiApi(server);
|
|
46
|
+
server.get("/api/sonamu/config", async () => {
|
|
47
|
+
return Sonamu.config;
|
|
48
|
+
});
|
|
49
|
+
server.get("/api/tools/openVscode", async (request) => {
|
|
50
|
+
const { entityId, preset, absPath } = request.query;
|
|
51
|
+
const targetPath = (() => {
|
|
52
|
+
if (entityId && preset) {
|
|
53
|
+
const entity = EntityManager.get(entityId);
|
|
54
|
+
const { names } = entity;
|
|
55
|
+
const { apiRootPath } = Sonamu;
|
|
56
|
+
const filename = (() => {
|
|
57
|
+
switch (preset) {
|
|
58
|
+
case "types": return `${names.fs}.types.ts`;
|
|
59
|
+
case "entity.json": return `${names.fs}.entity.json`;
|
|
60
|
+
case "generated": return `${names.fs}.generated.ts`;
|
|
61
|
+
}
|
|
62
|
+
})();
|
|
63
|
+
return `${apiRootPath}/src/application/${entity.names.parentFs}/${filename}`;
|
|
64
|
+
} else {
|
|
65
|
+
if (!absPath) {
|
|
66
|
+
throw new BadRequestException(SD("sonamu.error.presetOrAbsPathRequired"));
|
|
67
|
+
}
|
|
68
|
+
return absPath;
|
|
69
|
+
}
|
|
70
|
+
})();
|
|
71
|
+
execSync(`code ${targetPath}`);
|
|
72
|
+
});
|
|
73
|
+
server.get("/api/tools/getSuggestion", async (request) => {
|
|
74
|
+
const { origin, entityId } = request.query;
|
|
75
|
+
const glossary = new Map([
|
|
76
|
+
["status", "상태"],
|
|
77
|
+
["type", "타입"],
|
|
78
|
+
["image", "이미지"],
|
|
79
|
+
["images", "이미지리스트"],
|
|
80
|
+
["url", "URL"],
|
|
81
|
+
["id", "ID"],
|
|
82
|
+
["name", `{EntityID}명`],
|
|
83
|
+
["title", "{EntityID}명"],
|
|
84
|
+
["parent", "상위{EntityID}"],
|
|
85
|
+
["desc", "설명"],
|
|
86
|
+
["at", "일시"],
|
|
87
|
+
["created", "등록"],
|
|
88
|
+
["updated", "수정"],
|
|
89
|
+
["deleted", "삭제"],
|
|
90
|
+
["by", "유저"],
|
|
91
|
+
["date", "일자"],
|
|
92
|
+
["time", "시간"],
|
|
93
|
+
["ko", "(한글)"],
|
|
94
|
+
["en", "(영문)"],
|
|
95
|
+
["krw", "(원)"],
|
|
96
|
+
["usd", "(USD)"],
|
|
97
|
+
["color", "컬러"],
|
|
98
|
+
["code", "코드"],
|
|
99
|
+
["x", "X좌표"],
|
|
100
|
+
["y", "Y좌표"],
|
|
101
|
+
["current", "현재"],
|
|
102
|
+
["stock", "재고"],
|
|
103
|
+
["total", "총"],
|
|
104
|
+
["admin", "관리자"],
|
|
105
|
+
["group", "그룹"],
|
|
106
|
+
["item", "아이템"],
|
|
107
|
+
["cnt", "수량"],
|
|
108
|
+
["price", "가격"],
|
|
109
|
+
["preset", "프리셋"],
|
|
110
|
+
["acct", "계좌"],
|
|
111
|
+
["tel", "전화번호"],
|
|
112
|
+
["no", "번호"],
|
|
113
|
+
["body", "내용"],
|
|
114
|
+
["content", "내용"],
|
|
115
|
+
["orderno", "정렬순서"],
|
|
116
|
+
["priority", "우선순위"],
|
|
117
|
+
["text", "텍스트"],
|
|
118
|
+
["key", "키"],
|
|
119
|
+
["sum", "합산"],
|
|
120
|
+
["expected", "예상"],
|
|
121
|
+
["actual", "실제"]
|
|
122
|
+
]);
|
|
123
|
+
for (const entityId$1 of EntityManager.getAllIds()) {
|
|
124
|
+
const entity = EntityManager.get(entityId$1);
|
|
125
|
+
if ((entity.title ?? "") !== "") {
|
|
126
|
+
glossary.set(inflection.underscore(entity.id), entity.title);
|
|
127
|
+
glossary.set(inflection.underscore(inflection.pluralize(entity.id)), `${entity.title}리스트`);
|
|
128
|
+
}
|
|
129
|
+
entity.props.forEach((prop) => {
|
|
130
|
+
if (glossary.has(prop.name)) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (prop.desc) {
|
|
134
|
+
glossary.set(prop.name, prop.desc.replace(entity.title ?? "", "{EntityID}"));
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
const suggested = (() => {
|
|
139
|
+
const words = origin.split("_");
|
|
140
|
+
const combinations = [...range(words.length, 0, -1)].flatMap((len) => {
|
|
141
|
+
return [...range(0, words.length - len + 1, (idx) => {
|
|
142
|
+
return {
|
|
143
|
+
len,
|
|
144
|
+
w: words.slice(idx, idx + len).join("_")
|
|
145
|
+
};
|
|
146
|
+
})];
|
|
147
|
+
});
|
|
148
|
+
const REPLACED_PREFIX = "#REPLACED//";
|
|
149
|
+
let remainArr = [...words];
|
|
150
|
+
for (const comb of combinations) {
|
|
151
|
+
const remainStr = remainArr.join("_");
|
|
152
|
+
if (remainStr.includes(comb.w) && glossary.has(comb.w)) {
|
|
153
|
+
remainArr = remainStr.replace(comb.w, REPLACED_PREFIX + glossary.get(comb.w)).split("_");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return remainArr.map((r) => {
|
|
157
|
+
if (r.startsWith(REPLACED_PREFIX)) {
|
|
158
|
+
return r.replace(REPLACED_PREFIX, "");
|
|
159
|
+
} else {
|
|
160
|
+
return r.toUpperCase();
|
|
161
|
+
}
|
|
162
|
+
}).join("").replace(/{EntityID}/g, entityId ? EntityManager.get(entityId).title : "");
|
|
163
|
+
})();
|
|
164
|
+
return { suggested };
|
|
165
|
+
});
|
|
166
|
+
server.get("/api/entity/findMany", async () => {
|
|
167
|
+
const entityIds = EntityManager.getAllIds();
|
|
168
|
+
function flattenSubsetRows(subsetRows) {
|
|
169
|
+
return subsetRows.flatMap((subsetRow) => {
|
|
170
|
+
const { children, ...sRow } = subsetRow;
|
|
171
|
+
return [sRow, ...flattenSubsetRows(children)];
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const entities = await Promise.all(entityIds.map((entityId) => {
|
|
175
|
+
const entity = EntityManager.get(entityId);
|
|
176
|
+
const subsetRows = entity.getSubsetRows();
|
|
177
|
+
return {
|
|
178
|
+
...entity,
|
|
179
|
+
flattenSubsetRows: flattenSubsetRows(subsetRows)
|
|
180
|
+
};
|
|
181
|
+
}));
|
|
182
|
+
entities.sort((a, b) => {
|
|
183
|
+
const aId = a.parentId ?? a.id;
|
|
184
|
+
const bId = b.parentId ?? b.id;
|
|
185
|
+
if (aId < bId) return -1;
|
|
186
|
+
if (aId > bId) return 1;
|
|
187
|
+
if (aId === bId) {
|
|
188
|
+
if (a.parentId === undefined) return -1;
|
|
189
|
+
if (b.parentId === undefined) return 1;
|
|
190
|
+
return 0;
|
|
191
|
+
}
|
|
192
|
+
return 0;
|
|
193
|
+
});
|
|
194
|
+
return { entities };
|
|
195
|
+
});
|
|
196
|
+
server.get("/api/entity/typeIds", async (request) => {
|
|
197
|
+
const { filter, reload } = request.query;
|
|
198
|
+
if (reload === "1") {
|
|
199
|
+
await Sonamu.syncer.autoloadTypes();
|
|
200
|
+
}
|
|
201
|
+
const typeIds = (() => {
|
|
202
|
+
const projectTypeIds = Object.entries(Sonamu.syncer.types).filter(([_typeId, zodType]) => zodType._zod.def.type !== "enum").map(([typeId, _zodType]) => typeId);
|
|
203
|
+
const builtInTypeIds = [...BUILT_IN_TYPE_IDS];
|
|
204
|
+
const allTypeIds = [...builtInTypeIds, ...projectTypeIds];
|
|
205
|
+
if (filter === "types") {
|
|
206
|
+
return allTypeIds;
|
|
207
|
+
}
|
|
208
|
+
const enumIds = EntityManager.getAllIds().flatMap((entityId) => {
|
|
209
|
+
const entity = EntityManager.get(entityId);
|
|
210
|
+
return Object.keys(entity.enumLabels);
|
|
211
|
+
});
|
|
212
|
+
if (filter === "enums") {
|
|
213
|
+
return enumIds;
|
|
214
|
+
} else {
|
|
215
|
+
return [...allTypeIds, ...enumIds];
|
|
216
|
+
}
|
|
217
|
+
})();
|
|
218
|
+
return { typeIds };
|
|
219
|
+
});
|
|
220
|
+
server.post("/api/entity/create", async (request) => {
|
|
221
|
+
return await waitForHMRCompleted(async () => {
|
|
222
|
+
const { form } = request.body;
|
|
223
|
+
await Sonamu.syncer.createEntity({
|
|
224
|
+
...form,
|
|
225
|
+
entityId: form.id
|
|
226
|
+
});
|
|
227
|
+
return 1;
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
server.post("/api/entity/del", async (request) => {
|
|
231
|
+
return await waitForHMRCompleted(async () => {
|
|
232
|
+
const { entityId } = request.body;
|
|
233
|
+
return await Sonamu.syncer.delEntity(entityId);
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
server.post("/api/entity/modifyEntityBase", async (request) => {
|
|
237
|
+
return await waitForHMRCompleted(async () => {
|
|
238
|
+
const { entityId, newValues } = request.body;
|
|
239
|
+
const entity = EntityManager.get(entityId);
|
|
240
|
+
entity.title = newValues.title;
|
|
241
|
+
entity.table = newValues.table;
|
|
242
|
+
entity.parentId = newValues.parentId;
|
|
243
|
+
await entity.save();
|
|
244
|
+
return 1;
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
server.post("/api/entity/modifySubset", async (request) => {
|
|
248
|
+
return await waitForHMRCompleted(async () => {
|
|
249
|
+
const { entityId, subsetKey, fields, fieldsInternal } = request.body;
|
|
250
|
+
const entity = EntityManager.get(entityId);
|
|
251
|
+
entity.subsets[subsetKey] = fields;
|
|
252
|
+
if (fieldsInternal !== undefined) {
|
|
253
|
+
if (fieldsInternal.length > 0) {
|
|
254
|
+
entity.subsetsInternal[subsetKey] = fieldsInternal;
|
|
255
|
+
} else {
|
|
256
|
+
delete entity.subsetsInternal[subsetKey];
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
await entity.save();
|
|
260
|
+
return {
|
|
261
|
+
updated: fields,
|
|
262
|
+
updatedInternal: fieldsInternal
|
|
263
|
+
};
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
server.post("/api/entity/delSubset", async (request) => {
|
|
267
|
+
return await waitForHMRCompleted(async () => {
|
|
268
|
+
const { entityId, subsetKey } = request.body;
|
|
269
|
+
const entity = EntityManager.get(entityId);
|
|
270
|
+
delete entity.subsets[subsetKey];
|
|
271
|
+
delete entity.subsetsInternal[subsetKey];
|
|
272
|
+
await entity.save();
|
|
273
|
+
return 1;
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
server.post("/api/entity/createProp", async (request) => {
|
|
277
|
+
return await waitForHMRCompleted(async () => {
|
|
278
|
+
const { entityId, at, newProp } = request.body;
|
|
279
|
+
const entity = EntityManager.get(entityId);
|
|
280
|
+
await entity.createProp(newProp, at);
|
|
281
|
+
return true;
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
server.post("/api/entity/modifyProp", async (request) => {
|
|
285
|
+
return await waitForHMRCompleted(async () => {
|
|
286
|
+
const { entityId, at, newProp } = request.body;
|
|
287
|
+
const entity = EntityManager.get(entityId);
|
|
288
|
+
entity.modifyProp(newProp, at);
|
|
289
|
+
return true;
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
server.post("/api/entity/delProp", async (request) => {
|
|
293
|
+
return await waitForHMRCompleted(async () => {
|
|
294
|
+
const { entityId, at } = request.body;
|
|
295
|
+
const entity = EntityManager.get(entityId);
|
|
296
|
+
entity.delProp(at);
|
|
297
|
+
return true;
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
server.post("/api/entity/moveProp", async (request) => {
|
|
301
|
+
return await waitForHMRCompleted(async () => {
|
|
302
|
+
const { entityId, at, to } = request.body;
|
|
303
|
+
const entity = EntityManager.get(entityId);
|
|
304
|
+
entity.moveProp(at, to);
|
|
305
|
+
return true;
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
server.post("/api/entity/modifyIndexes", async (request) => {
|
|
309
|
+
return await waitForHMRCompleted(async () => {
|
|
310
|
+
const { entityId, indexes } = request.body;
|
|
311
|
+
const entity = EntityManager.get(entityId);
|
|
312
|
+
entity.indexes = indexes;
|
|
313
|
+
await entity.save();
|
|
314
|
+
return { updated: indexes };
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
server.post("/api/entity/modifyEnumLabels", async (request) => {
|
|
318
|
+
return await waitForHMRCompleted(async () => {
|
|
319
|
+
const { entityId, enumLabels } = request.body;
|
|
320
|
+
const entity = EntityManager.get(entityId);
|
|
321
|
+
entity.enumLabels = enumLabels;
|
|
322
|
+
await entity.save();
|
|
323
|
+
return { updated: enumLabels };
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
server.post("/api/entity/createEnumId", async (request) => {
|
|
327
|
+
return await waitForHMRCompleted(async () => {
|
|
328
|
+
const { entityId, newEnumId } = request.body;
|
|
329
|
+
const entity = EntityManager.get(entityId);
|
|
330
|
+
if (entity.enumLabels[newEnumId]) {
|
|
331
|
+
throw new Error(`이미 존재하는 enumId입니다: ${newEnumId}`);
|
|
332
|
+
}
|
|
333
|
+
entity.enumLabels[newEnumId] = newEnumId.endsWith("Status") ? {
|
|
334
|
+
active: "노출",
|
|
335
|
+
hidden: "숨김"
|
|
336
|
+
} : { "": "" };
|
|
337
|
+
await entity.save();
|
|
338
|
+
return 1;
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
server.post("/api/entity/modifyEnumId", async (request) => {
|
|
342
|
+
return await waitForHMRCompleted(async () => {
|
|
343
|
+
const { entityId, enumId } = request.body;
|
|
344
|
+
const entityIds = EntityManager.getAllIds();
|
|
345
|
+
const isExists = entityIds.some((entityId$1) => {
|
|
346
|
+
const entity$1 = EntityManager.get(entityId$1);
|
|
347
|
+
return Object.keys(entity$1.enumLabels).includes(enumId.after);
|
|
348
|
+
});
|
|
349
|
+
if (isExists) {
|
|
350
|
+
throw new Error(`이미 존재하는 EnumId입니다: ${enumId.after}`);
|
|
351
|
+
}
|
|
352
|
+
const entity = EntityManager.get(entityId);
|
|
353
|
+
entity.enumLabels[enumId.after] = entity.enumLabels[enumId.before];
|
|
354
|
+
delete entity.enumLabels[enumId.before];
|
|
355
|
+
await entity.save();
|
|
356
|
+
for (const entityId$1 of entityIds) {
|
|
357
|
+
const entity$1 = EntityManager.get(entityId$1);
|
|
358
|
+
for (const prop of entity$1.props) {
|
|
359
|
+
if (prop.type === "enum" && prop.id === enumId.before) {
|
|
360
|
+
prop.id = enumId.after;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
await entity$1.save();
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
});
|
|
367
|
+
server.post("/api/entity/deleteEnumId", async (request) => {
|
|
368
|
+
return await waitForHMRCompleted(async () => {
|
|
369
|
+
const { entityId, enumId } = request.body;
|
|
370
|
+
const entityIds = EntityManager.getAllIds();
|
|
371
|
+
const isReferenced = entityIds.flatMap((entityId$1) => EntityManager.get(entityId$1).props).some((prop) => prop.type === "enum" && prop.id === enumId);
|
|
372
|
+
if (isReferenced) {
|
|
373
|
+
throw new Error(`${enumId}를 참조하는 프로퍼티가 존재합니다.`);
|
|
374
|
+
}
|
|
375
|
+
const entity = EntityManager.get(entityId);
|
|
376
|
+
delete entity.enumLabels[enumId];
|
|
377
|
+
await entity.save();
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
server.post("/api/entity/updateCone", async (request) => {
|
|
381
|
+
return await waitForHMRCompleted(async () => {
|
|
382
|
+
const { entityId, target, propName, enumId, subsetKey, cone } = request.body;
|
|
383
|
+
const entity = EntityManager.get(entityId);
|
|
384
|
+
if (target === "entity") {
|
|
385
|
+
entity.cone = cone;
|
|
386
|
+
} else if (target === "prop" && propName) {
|
|
387
|
+
const prop = entity.props.find((p) => p.name === propName);
|
|
388
|
+
if (prop) {
|
|
389
|
+
prop.cone = cone;
|
|
390
|
+
}
|
|
391
|
+
} else if (target === "enum" && enumId) {
|
|
392
|
+
entity.enumCones[enumId] = cone;
|
|
393
|
+
} else if (target === "subset" && subsetKey) {
|
|
394
|
+
entity.subsetCones[subsetKey] = cone;
|
|
395
|
+
}
|
|
396
|
+
await entity.save();
|
|
397
|
+
return true;
|
|
398
|
+
});
|
|
399
|
+
});
|
|
400
|
+
server.post("/api/entity/generateCones", async (request, reply) => {
|
|
401
|
+
return await waitForHMRCompleted(async () => {
|
|
402
|
+
const { entityId, preserveExisting, onlyEmpty, locale } = request.body;
|
|
403
|
+
try {
|
|
404
|
+
const entity = EntityManager.get(entityId);
|
|
405
|
+
const effectiveLocale = locale ?? Sonamu.config.i18n.defaultLocale;
|
|
406
|
+
const result = await entity.generateCones({
|
|
407
|
+
preserveExisting: preserveExisting ?? true,
|
|
408
|
+
onlyEmpty: onlyEmpty ?? false,
|
|
409
|
+
locale: effectiveLocale
|
|
410
|
+
});
|
|
411
|
+
return result;
|
|
412
|
+
} catch (error) {
|
|
413
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
414
|
+
if (message.includes("존재하지 않는 Entity")) {
|
|
415
|
+
reply.status(404);
|
|
416
|
+
return {
|
|
417
|
+
success: false,
|
|
418
|
+
error: `Entity not found: ${entityId}`
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
if (message.includes("ANTHROPIC_API_KEY not found")) {
|
|
422
|
+
reply.status(500);
|
|
423
|
+
return {
|
|
424
|
+
success: false,
|
|
425
|
+
error: "API key not configured"
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
if (message.includes("Rate limit exceeded")) {
|
|
429
|
+
reply.status(429);
|
|
430
|
+
return {
|
|
431
|
+
success: false,
|
|
432
|
+
error: "Rate limit exceeded. Please try again later."
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
reply.status(500);
|
|
436
|
+
return {
|
|
437
|
+
success: false,
|
|
438
|
+
error: `Cone generation failed: ${message}`
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
});
|
|
443
|
+
server.get("/api/entity/getTableColumns", async (request) => {
|
|
444
|
+
const { entityId } = request.query;
|
|
445
|
+
const entity = EntityManager.get(entityId);
|
|
446
|
+
const columns = entity.getTableColumns();
|
|
447
|
+
return { columns };
|
|
448
|
+
});
|
|
449
|
+
server.get("/api/migrations/status", async () => {
|
|
450
|
+
const status = await migrator.getStatus();
|
|
451
|
+
return { status };
|
|
452
|
+
});
|
|
453
|
+
server.post("/api/migrations/runAction", async (request) => {
|
|
454
|
+
const { action, targets, force, forceReason, requestor } = request.body;
|
|
455
|
+
if (action === "shadow") {
|
|
456
|
+
return migrator.runShadowTest();
|
|
457
|
+
}
|
|
458
|
+
if (action === "apply") {
|
|
459
|
+
const slackConfirm = new SlackConfirm();
|
|
460
|
+
const requiresApproval = targets.some((t) => slackConfirm.isTargetRequiresApproval(t));
|
|
461
|
+
const localHosts = [
|
|
462
|
+
"localhost",
|
|
463
|
+
"127.0.0.1",
|
|
464
|
+
"0.0.0.0",
|
|
465
|
+
"::1"
|
|
466
|
+
];
|
|
467
|
+
const isLocalTarget = targets.every((target) => {
|
|
468
|
+
const targetConfig = Sonamu.dbConfig[target];
|
|
469
|
+
const host = (targetConfig?.connection)?.host ?? "localhost";
|
|
470
|
+
return localHosts.includes(host.toLowerCase());
|
|
471
|
+
});
|
|
472
|
+
if (requiresApproval && slackConfirm.isConfigured() && !isLocalTarget) {
|
|
473
|
+
const { conns } = await migrator.getStatus();
|
|
474
|
+
const pendingMigrations = [...new Set(conns.filter((conn) => targets.includes(conn.connKey)).flatMap((conn) => conn.pending))];
|
|
475
|
+
if (pendingMigrations.length > 0) {
|
|
476
|
+
const existing = await slackConfirm.getExistingRequest(pendingMigrations);
|
|
477
|
+
if (existing) {
|
|
478
|
+
const { approved, rejected } = await slackConfirm.checkApproval(existing.channel, existing.ts);
|
|
479
|
+
if (approved) {
|
|
480
|
+
const result = await migrator.runAction(action, targets);
|
|
481
|
+
if (result.length > 0) {
|
|
482
|
+
await slackConfirm.logExecution(existing.channel, existing.ts, result, requestor);
|
|
483
|
+
}
|
|
484
|
+
return result;
|
|
485
|
+
} else if (rejected) {
|
|
486
|
+
throw new BadRequestException(SD("sonamu.error.migrationRejected"));
|
|
487
|
+
} else if (force) {
|
|
488
|
+
await slackConfirm.forceApproval(existing.channel, existing.ts, forceReason ?? "사유 없음", requestor);
|
|
489
|
+
const result = await migrator.runAction(action, targets);
|
|
490
|
+
if (result.length > 0) {
|
|
491
|
+
await slackConfirm.logExecution(existing.channel, existing.ts, result, requestor);
|
|
492
|
+
}
|
|
493
|
+
return result;
|
|
494
|
+
} else {
|
|
495
|
+
return {
|
|
496
|
+
type: "pending",
|
|
497
|
+
channel: existing.channel,
|
|
498
|
+
ts: existing.ts
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
} else {
|
|
502
|
+
const { channel, ts } = await slackConfirm.postApprovalRequest(pendingMigrations, targets, requestor);
|
|
503
|
+
await slackConfirm.saveRequest(pendingMigrations, channel, ts);
|
|
504
|
+
return {
|
|
505
|
+
type: "pending",
|
|
506
|
+
channel,
|
|
507
|
+
ts
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
return migrator.runAction(action, targets);
|
|
514
|
+
});
|
|
515
|
+
server.post("/api/migrations/checkApproval", async (request) => {
|
|
516
|
+
const { channel, ts } = request.body;
|
|
517
|
+
const slackConfirm = new SlackConfirm();
|
|
518
|
+
if (!slackConfirm.isConfigured()) {
|
|
519
|
+
return {
|
|
520
|
+
approved: true,
|
|
521
|
+
rejected: false
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
return slackConfirm.checkApproval(channel, ts);
|
|
525
|
+
});
|
|
526
|
+
server.post("/api/migrations/forceApproval", async (request) => {
|
|
527
|
+
const { channel, ts, reason, requestor } = request.body;
|
|
528
|
+
const slackConfirm = new SlackConfirm();
|
|
529
|
+
if (!slackConfirm.isConfigured()) {
|
|
530
|
+
throw new BadRequestException(SD("sonamu.error.slackConfirmNotConfigured"));
|
|
531
|
+
}
|
|
532
|
+
await slackConfirm.forceApproval(channel, ts, reason, requestor);
|
|
533
|
+
return { success: true };
|
|
534
|
+
});
|
|
535
|
+
server.post("/api/migrations/delCodes", async (request) => {
|
|
536
|
+
const { codeNames } = request.body;
|
|
537
|
+
return await migrator.delCodes(codeNames);
|
|
538
|
+
});
|
|
539
|
+
server.post("/api/migrations/generatePreparedCodes", async (_requestt) => {
|
|
540
|
+
return await migrator.generatePreparedCodes();
|
|
541
|
+
});
|
|
542
|
+
server.post("/api/scaffolding/getStatus", async (request) => {
|
|
543
|
+
const { entityIds, templateKeys: _templateKeys } = request.body;
|
|
544
|
+
if ((entityIds ?? []).length === 0) {
|
|
545
|
+
throw new BadRequestException(SD("sonamu.error.entityIdsRequired"));
|
|
546
|
+
} else if ((_templateKeys ?? []).length === 0) {
|
|
547
|
+
throw new BadRequestException(SD("sonamu.error.templateKeysRequired"));
|
|
548
|
+
}
|
|
549
|
+
entityIds.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
|
|
550
|
+
const templateKeys = TemplateKey.options.filter((tk) => _templateKeys.includes(tk));
|
|
551
|
+
const combinations = entityIds.flatMap((entityId) => {
|
|
552
|
+
return templateKeys.map((templateKey) => [entityId, templateKey]);
|
|
553
|
+
});
|
|
554
|
+
const statuses = await Promise.all(combinations.map(async ([entityId, templateKey]) => {
|
|
555
|
+
const { subPath, fullPath, isExists } = await Sonamu.syncer.checkExistsGenCode(entityId, templateKey);
|
|
556
|
+
return {
|
|
557
|
+
entityId,
|
|
558
|
+
templateKey,
|
|
559
|
+
subPath,
|
|
560
|
+
fullPath,
|
|
561
|
+
isExists
|
|
562
|
+
};
|
|
563
|
+
}));
|
|
564
|
+
return { statuses };
|
|
565
|
+
});
|
|
566
|
+
server.post("/api/scaffolding/generate", async (request) => {
|
|
567
|
+
const { options } = request.body;
|
|
568
|
+
if (options.length === 0) {
|
|
569
|
+
throw new BadRequestException(SD("sonamu.error.optionsRequired"));
|
|
570
|
+
}
|
|
571
|
+
const keys = options.flatMap(({ templateKey }) => {
|
|
572
|
+
const template = TemplateManager.get(templateKey);
|
|
573
|
+
return template.getRequiredDictKeys() ?? [];
|
|
574
|
+
});
|
|
575
|
+
await sonamuDictionary.ensureDictKeys([...new Set(keys)]);
|
|
576
|
+
const result = await Promise.all(options.map(async ({ entityId, templateKey, enumId, overwrite }) => {
|
|
577
|
+
try {
|
|
578
|
+
return await Sonamu.syncer.generateTemplate(templateKey, {
|
|
579
|
+
entityId,
|
|
580
|
+
enumId
|
|
581
|
+
}, { overwrite });
|
|
582
|
+
} catch (e) {
|
|
583
|
+
if (isSoException(e) && e.statusCode === 541) {
|
|
584
|
+
return null;
|
|
585
|
+
} else {
|
|
586
|
+
console.error(e);
|
|
587
|
+
throw e;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}));
|
|
591
|
+
if (result.filter(nonNullable).length === 0) {
|
|
592
|
+
throw new ServiceUnavailableException(SD("sonamu.error.allFilesGenerated"));
|
|
593
|
+
}
|
|
594
|
+
return result;
|
|
595
|
+
});
|
|
596
|
+
server.post("/api/scaffolding/preview", async (request) => {
|
|
597
|
+
const { option } = request.body;
|
|
598
|
+
try {
|
|
599
|
+
const { templateKey, ...templateOptions } = option;
|
|
600
|
+
const pathAndCodes = await Sonamu.syncer.renderTemplate(templateKey, templateOptions);
|
|
601
|
+
return { pathAndCodes };
|
|
602
|
+
} catch (e) {
|
|
603
|
+
console.error(e);
|
|
604
|
+
throw e;
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
server.post("/api/fixture", async (request) => {
|
|
608
|
+
const { sourceDB, targetDB, search, duplicateCheck } = request.body;
|
|
609
|
+
return FixtureManager.getFixtures(sourceDB, targetDB, search, duplicateCheck);
|
|
610
|
+
});
|
|
611
|
+
server.post("/api/fixture/import", async (request) => {
|
|
612
|
+
const { db, fixtures } = request.body;
|
|
613
|
+
return FixtureManager.insertFixtures(db, fixtures);
|
|
614
|
+
});
|
|
615
|
+
server.post("/api/fixture/addFixtureLoader", async (request) => {
|
|
616
|
+
const { code } = request.body;
|
|
617
|
+
return FixtureManager.addFixtureLoader(code);
|
|
618
|
+
});
|
|
619
|
+
server.get("/api/i18n/dictionary", async () => {
|
|
620
|
+
return sonamuDictionary.getDictionary();
|
|
621
|
+
});
|
|
622
|
+
server.get("/api/i18n/export", async (_request, reply) => {
|
|
623
|
+
const { filename, buffer } = await sonamuDictionary.exportToExcel();
|
|
624
|
+
reply.header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet").header("Content-Disposition", `attachment; filename="${filename}"`).send(buffer);
|
|
625
|
+
});
|
|
626
|
+
server.post("/api/i18n/import", async (request) => {
|
|
627
|
+
const data = await request.file();
|
|
628
|
+
if (!data) {
|
|
629
|
+
throw new BadRequestException(SD("sonamu.error.fileNotUploaded"));
|
|
630
|
+
}
|
|
631
|
+
const buffer = await data.toBuffer();
|
|
632
|
+
return sonamuDictionary.importFromExcel(buffer);
|
|
633
|
+
});
|
|
634
|
+
server.post("/api/i18n/update", async (request) => {
|
|
635
|
+
await sonamuDictionary.updateEntry(request.body);
|
|
636
|
+
return { success: true };
|
|
637
|
+
});
|
|
638
|
+
server.post("/api/i18n/create", async (request) => {
|
|
639
|
+
await sonamuDictionary.createEntry(request.body);
|
|
640
|
+
return { success: true };
|
|
641
|
+
});
|
|
642
|
+
server.post("/api/i18n/delete", async (request) => {
|
|
643
|
+
await sonamuDictionary.deleteEntry(request.body.key);
|
|
644
|
+
return { success: true };
|
|
645
|
+
});
|
|
646
|
+
server.post("/api/i18n/checkUsage", async (request) => {
|
|
647
|
+
return sonamuDictionary.checkUsage(request.body.keys);
|
|
648
|
+
});
|
|
649
|
+
server.get("/api/tasks/status", async () => {
|
|
650
|
+
try {
|
|
651
|
+
Sonamu.workflows;
|
|
652
|
+
return { active: true };
|
|
653
|
+
} catch {
|
|
654
|
+
return { active: false };
|
|
655
|
+
}
|
|
656
|
+
});
|
|
657
|
+
server.get("/api/tasks/workflowDefinitions", async () => {
|
|
658
|
+
const definitions = Sonamu.workflows.workflowDefinitions;
|
|
659
|
+
return { definitions };
|
|
660
|
+
});
|
|
661
|
+
server.get("/api/tasks/workflowRuns", async (request) => {
|
|
662
|
+
const backend = Sonamu.workflows.backend;
|
|
663
|
+
const { limit, after, before, order, status, workflowName, createdAfter, createdBefore } = request.query;
|
|
664
|
+
return backend.listWorkflowRuns({
|
|
665
|
+
limit: limit ? Number.parseInt(limit, 10) : undefined,
|
|
666
|
+
after,
|
|
667
|
+
before,
|
|
668
|
+
order,
|
|
669
|
+
status: status ? status.split(",") : undefined,
|
|
670
|
+
workflowName: workflowName || undefined,
|
|
671
|
+
createdAfter: createdAfter ? new Date(createdAfter) : undefined,
|
|
672
|
+
createdBefore: createdBefore ? new Date(createdBefore) : undefined
|
|
673
|
+
});
|
|
674
|
+
});
|
|
675
|
+
server.get("/api/tasks/workflowRuns/:id", async (request) => {
|
|
676
|
+
const backend = Sonamu.workflows.backend;
|
|
677
|
+
const workflowRun = await backend.getWorkflowRun({ workflowRunId: request.params.id });
|
|
678
|
+
if (!workflowRun) {
|
|
679
|
+
throw new Error(`Workflow run not found: ${request.params.id}`);
|
|
680
|
+
}
|
|
681
|
+
return workflowRun;
|
|
682
|
+
});
|
|
683
|
+
server.post("/api/tasks/workflowRuns/:id/cancel", async (request) => {
|
|
684
|
+
const backend = Sonamu.workflows.backend;
|
|
685
|
+
return backend.cancelWorkflowRun({ workflowRunId: request.params.id });
|
|
686
|
+
});
|
|
687
|
+
server.post("/api/tasks/workflowRuns/:id/pause", async (request) => {
|
|
688
|
+
const backend = Sonamu.workflows.backend;
|
|
689
|
+
return backend.pauseWorkflowRun({ workflowRunId: request.params.id });
|
|
690
|
+
});
|
|
691
|
+
server.post("/api/tasks/workflowRuns/:id/resume", async (request) => {
|
|
692
|
+
const backend = Sonamu.workflows.backend;
|
|
693
|
+
return backend.resumeWorkflowRun({ workflowRunId: request.params.id });
|
|
694
|
+
});
|
|
695
|
+
server.get("/api/tasks/workflowRuns/:id/steps", async (request) => {
|
|
696
|
+
const backend = Sonamu.workflows.backend;
|
|
697
|
+
const { limit, after, before } = request.query;
|
|
698
|
+
return backend.listStepAttempts({
|
|
699
|
+
workflowRunId: request.params.id,
|
|
700
|
+
limit: limit ? Number.parseInt(limit, 10) : undefined,
|
|
701
|
+
after,
|
|
702
|
+
before
|
|
703
|
+
});
|
|
704
|
+
});
|
|
705
|
+
/**
|
|
706
|
+
* Health Check API
|
|
707
|
+
* MCP 도구가 Sonamu 서버를 자동 감지하기 위한 엔드포인트
|
|
708
|
+
*/
|
|
709
|
+
server.get("/api/sonamu/health", async (request) => {
|
|
710
|
+
const address = request.server.server.address();
|
|
711
|
+
const port = address && typeof address === "object" ? address.port : 0;
|
|
712
|
+
return {
|
|
713
|
+
ok: true,
|
|
714
|
+
project: process.cwd().split("/").pop() || "unknown",
|
|
715
|
+
port,
|
|
716
|
+
timestamp: new Date().toISOString()
|
|
717
|
+
};
|
|
718
|
+
});
|
|
719
|
+
/**
|
|
720
|
+
* Fixture 생성 API
|
|
721
|
+
*/
|
|
722
|
+
server.post("/api/sonamu/fixture/generate", async (request, reply) => {
|
|
723
|
+
const { entity, count = 1, overrides, targetDb = "fixture" } = request.body;
|
|
724
|
+
const dbConfig = targetDb === "fixture" ? Sonamu.dbConfig.fixture : Sonamu.dbConfig.test;
|
|
725
|
+
const db = createKnexInstance(dbConfig);
|
|
726
|
+
try {
|
|
727
|
+
const generator = new FixtureGenerator(db, db, targetDb, EntityManager);
|
|
728
|
+
const fixtures = await generator.generateBatch([{
|
|
729
|
+
entity,
|
|
730
|
+
count,
|
|
731
|
+
overrides: overrides ?? {}
|
|
732
|
+
}]);
|
|
733
|
+
return {
|
|
734
|
+
success: true,
|
|
735
|
+
entity,
|
|
736
|
+
count: fixtures.length,
|
|
737
|
+
fixtures,
|
|
738
|
+
targetDb
|
|
739
|
+
};
|
|
740
|
+
} catch (error) {
|
|
741
|
+
reply.status(400);
|
|
742
|
+
return {
|
|
743
|
+
success: false,
|
|
744
|
+
error: error instanceof Error ? error.message : String(error)
|
|
745
|
+
};
|
|
746
|
+
} finally {
|
|
747
|
+
await db.destroy();
|
|
748
|
+
}
|
|
749
|
+
});
|
|
750
|
+
/**
|
|
751
|
+
* Fixture 데이터 탐색 API
|
|
752
|
+
*/
|
|
753
|
+
server.post("/api/sonamu/fixture/explore", async (request, reply) => {
|
|
754
|
+
const { entity, strategy, limit = 10, where } = request.body;
|
|
755
|
+
const fixtureDbConfig = Sonamu.dbConfig.fixture;
|
|
756
|
+
const fixtureDb = createKnexInstance(fixtureDbConfig);
|
|
757
|
+
try {
|
|
758
|
+
const explorer = new DataExplorer(fixtureDb, EntityManager);
|
|
759
|
+
const data = await explorer.explore(entity, {
|
|
760
|
+
strategy,
|
|
761
|
+
limit,
|
|
762
|
+
where
|
|
763
|
+
});
|
|
764
|
+
return {
|
|
765
|
+
success: true,
|
|
766
|
+
entity,
|
|
767
|
+
strategy,
|
|
768
|
+
count: data.length,
|
|
769
|
+
data
|
|
770
|
+
};
|
|
771
|
+
} catch (error) {
|
|
772
|
+
reply.status(400);
|
|
773
|
+
return {
|
|
774
|
+
success: false,
|
|
775
|
+
error: error instanceof Error ? error.message : String(error)
|
|
776
|
+
};
|
|
777
|
+
} finally {
|
|
778
|
+
await fixtureDb.destroy();
|
|
779
|
+
}
|
|
780
|
+
});
|
|
781
|
+
/**
|
|
782
|
+
* Fixture 데이터 가져오기 (fetch) API
|
|
783
|
+
* production/development DB에서 실제 데이터를 fixture DB로 import
|
|
784
|
+
*/
|
|
785
|
+
server.post("/api/sonamu/fixture/fetch", async (request, reply) => {
|
|
786
|
+
const { entity, strategy = "recent", limit = 10, includeRelations = true, maxDepth = 2 } = request.body;
|
|
787
|
+
const sourceDb = DB.getDB("r");
|
|
788
|
+
const fixtureDb = createKnexInstance(Sonamu.dbConfig.fixture);
|
|
789
|
+
try {
|
|
790
|
+
const generator = new FixtureGenerator(sourceDb, fixtureDb, "fixture", EntityManager);
|
|
791
|
+
const results = await generator.importFromSource(entity, {
|
|
792
|
+
strategy,
|
|
793
|
+
limit,
|
|
794
|
+
includeRelations,
|
|
795
|
+
maxDepth
|
|
796
|
+
});
|
|
797
|
+
return {
|
|
798
|
+
success: true,
|
|
799
|
+
entity,
|
|
800
|
+
strategy,
|
|
801
|
+
count: results.length,
|
|
802
|
+
imported: results
|
|
803
|
+
};
|
|
804
|
+
} catch (error) {
|
|
805
|
+
reply.status(400);
|
|
806
|
+
return {
|
|
807
|
+
success: false,
|
|
808
|
+
error: error instanceof Error ? error.message : String(error)
|
|
809
|
+
};
|
|
810
|
+
} finally {
|
|
811
|
+
await fixtureDb.destroy();
|
|
812
|
+
}
|
|
813
|
+
});
|
|
814
|
+
/**
|
|
815
|
+
* Fixture 데이터 삭제 (clean) API
|
|
816
|
+
* FK 순서를 고려하여 안전하게 삭제
|
|
817
|
+
*/
|
|
818
|
+
server.post("/api/sonamu/fixture/clean", async (request, reply) => {
|
|
819
|
+
const { entities } = request.body;
|
|
820
|
+
const fixtureDb = createKnexInstance(Sonamu.dbConfig.fixture);
|
|
821
|
+
try {
|
|
822
|
+
const targetEntities = entities && entities.length > 0 ? entities : EntityManager.getAllIds();
|
|
823
|
+
const tableNames = targetEntities.map((entityId) => {
|
|
824
|
+
const entity = EntityManager.get(entityId);
|
|
825
|
+
return entity.table;
|
|
826
|
+
});
|
|
827
|
+
await fixtureDb.raw(`TRUNCATE TABLE ${tableNames.map((t) => `"${t}"`).join(", ")} RESTART IDENTITY CASCADE`);
|
|
828
|
+
return {
|
|
829
|
+
success: true,
|
|
830
|
+
cleaned: tableNames,
|
|
831
|
+
count: tableNames.length
|
|
832
|
+
};
|
|
833
|
+
} catch (error) {
|
|
834
|
+
reply.status(400);
|
|
835
|
+
return {
|
|
836
|
+
success: false,
|
|
837
|
+
error: error instanceof Error ? error.message : String(error)
|
|
838
|
+
};
|
|
839
|
+
} finally {
|
|
840
|
+
await fixtureDb.destroy();
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
server.get("/api/cdd/tree", async () => {
|
|
844
|
+
return getCddTree();
|
|
845
|
+
});
|
|
846
|
+
server.post("/api/cdd/readContent", async (request) => {
|
|
847
|
+
const { filePath } = request.body;
|
|
848
|
+
return readContent(filePath);
|
|
849
|
+
});
|
|
850
|
+
server.post("/api/cdd/editContent", async (request) => {
|
|
851
|
+
const { filePath } = request.body;
|
|
852
|
+
return editContent(filePath);
|
|
853
|
+
});
|
|
854
|
+
server.post("/api/cdd/openSource", async (request) => {
|
|
855
|
+
const { filePath } = request.body;
|
|
856
|
+
openSourceFile(filePath);
|
|
857
|
+
return { success: true };
|
|
858
|
+
});
|
|
859
|
+
server.get("/api/cdd/rules", async () => {
|
|
860
|
+
return listRules();
|
|
861
|
+
});
|
|
862
|
+
server.post("/api/cdd/readRule", async (request) => {
|
|
863
|
+
const { ruleKey } = request.body;
|
|
864
|
+
return readRule(ruleKey);
|
|
865
|
+
});
|
|
866
|
+
server.post("/api/cdd/addRule", async (request) => {
|
|
867
|
+
return addRule(request.body);
|
|
868
|
+
});
|
|
869
|
+
server.get("/api/cdd/ac", async () => {
|
|
870
|
+
return getAcList();
|
|
871
|
+
});
|
|
872
|
+
const uiDistPath = path.resolve(import.meta.dirname, "../ui-web");
|
|
873
|
+
server.register(await import("@fastify/static"), {
|
|
874
|
+
root: uiDistPath,
|
|
875
|
+
prefix: "/",
|
|
876
|
+
decorateReply: false,
|
|
877
|
+
wildcard: false
|
|
878
|
+
});
|
|
879
|
+
server.get("*", async (_request, reply) => {
|
|
880
|
+
reply.headers({ "Content-type": "text/html" }).send(fs.readFileSync(path.resolve(uiDistPath, "index.html")).toString().replace("{{projectName}}", Sonamu.config.projectName ?? "UnknownSonamuProject"));
|
|
881
|
+
});
|
|
882
|
+
}, { prefix: "/sonamu-ui" });
|
|
1147
883
|
}
|
|
884
|
+
var init_api = __esmMin((() => {
|
|
885
|
+
init_sonamu();
|
|
886
|
+
init_db();
|
|
887
|
+
init_knex();
|
|
888
|
+
init_sd();
|
|
889
|
+
init_sonamu_dictionary();
|
|
890
|
+
init_entity_manager();
|
|
891
|
+
init_so_exceptions();
|
|
892
|
+
init_migrator();
|
|
893
|
+
init_slack_confirm();
|
|
894
|
+
init_template_manager();
|
|
895
|
+
init_data_explorer();
|
|
896
|
+
init_fixture_generator();
|
|
897
|
+
init_fixture_manager();
|
|
898
|
+
init_types();
|
|
899
|
+
init_utils();
|
|
900
|
+
init_ai_api();
|
|
901
|
+
init_cdd_service();
|
|
902
|
+
}));
|
|
1148
903
|
|
|
1149
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91aS9hcGkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHR5cGUgeyBGYXN0aWZ5SW5zdGFuY2UgfSBmcm9tIFwiZmFzdGlmeVwiO1xuaW1wb3J0IGZzIGZyb20gXCJmc1wiO1xuaW1wb3J0IGluZmxlY3Rpb24gZnJvbSBcImluZmxlY3Rpb25cIjtcbmltcG9ydCB0eXBlIHsgQWRkcmVzc0luZm8gfSBmcm9tIFwibmV0XCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgcmFuZ2UgfSBmcm9tIFwicmFkYXNoaVwiO1xuaW1wb3J0IHsgU29uYW11IH0gZnJvbSBcIi4uL2FwaS9zb25hbXVcIjtcbmltcG9ydCB7IERCLCB0eXBlIFNvbmFtdURCQ29uZmlnIH0gZnJvbSBcIi4uL2RhdGFiYXNlL2RiXCI7XG5pbXBvcnQgeyBjcmVhdGVLbmV4SW5zdGFuY2UgfSBmcm9tIFwiLi4vZGF0YWJhc2Uva25leFwiO1xuaW1wb3J0IHsgU0QgfSBmcm9tIFwiLi4vZGljdC9zZFwiO1xuaW1wb3J0IHsgc29uYW11RGljdGlvbmFyeSB9IGZyb20gXCIuLi9kaWN0L3NvbmFtdS1kaWN0aW9uYXJ5XCI7XG5pbXBvcnQgdHlwZSB7IEVudGl0eSB9IGZyb20gXCIuLi9lbnRpdHkvZW50aXR5XCI7XG5pbXBvcnQgeyBFbnRpdHlNYW5hZ2VyIH0gZnJvbSBcIi4uL2VudGl0eS9lbnRpdHktbWFuYWdlclwiO1xuaW1wb3J0IHtcbiAgQmFkUmVxdWVzdEV4Y2VwdGlvbixcbiAgaXNTb0V4Y2VwdGlvbixcbiAgU2VydmljZVVuYXZhaWxhYmxlRXhjZXB0aW9uLFxufSBmcm9tIFwiLi4vZXhjZXB0aW9ucy9zby1leGNlcHRpb25zXCI7XG5pbXBvcnQgeyB0eXBlIE1pZ3JhdGlvblJlc3VsdCwgTWlncmF0b3IgfSBmcm9tIFwiLi4vbWlncmF0aW9uL21pZ3JhdG9yXCI7XG5pbXBvcnQgeyBTbGFja0NvbmZpcm0sIHR5cGUgU2xhY2tDb25maXJtUGVuZGluZ1Jlc3VsdCB9IGZyb20gXCIuLi9taWdyYXRpb24vc2xhY2stY29uZmlybVwiO1xuaW1wb3J0IHsgVGVtcGxhdGVNYW5hZ2VyIH0gZnJvbSBcIi4uL3RlbXBsYXRlL3RlbXBsYXRlLW1hbmFnZXJcIjtcbmltcG9ydCB7IERhdGFFeHBsb3JlciB9IGZyb20gXCIuLi90ZXN0aW5nL2RhdGEtZXhwbG9yZXJcIjtcbmltcG9ydCB7IEZpeHR1cmVHZW5lcmF0b3IgfSBmcm9tIFwiLi4vdGVzdGluZy9maXh0dXJlLWdlbmVyYXRvclwiO1xuaW1wb3J0IHsgdHlwZSBEdXBsaWNhdGVDaGVja09wdGlvbnMsIEZpeHR1cmVNYW5hZ2VyIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZml4dHVyZS1tYW5hZ2VyXCI7XG5pbXBvcnQge1xuICBCVUlMVF9JTl9UWVBFX0lEUyxcbiAgdHlwZSBDb25lLFxuICB0eXBlIEVudGl0eUluZGV4LFxuICB0eXBlIEVudGl0eVByb3AsXG4gIHR5cGUgRW50aXR5U3Vic2V0Um93LFxuICB0eXBlIEZpeHR1cmVSZWNvcmQsXG4gIHR5cGUgRml4dHVyZVNlYXJjaE9wdGlvbnMsXG4gIHR5cGUgRmxhdHRlblN1YnNldFJvdyxcbiAgdHlwZSBQYXRoQW5kQ29kZSxcbiAgVGVtcGxhdGVLZXksXG59IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgbm9uTnVsbGFibGUgfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcbmltcG9ydCB7IHNldEFpQXBpIH0gZnJvbSBcIi4vYWktYXBpXCI7XG5pbXBvcnQge1xuICBlZGl0Q29udGVudCxcbiAgZWRpdFNjaGVtYSxcbiAgZ2V0Q2RkVHJlZSxcbiAgZ2V0RGFzaGJvYXJkLFxuICBsaXN0U2NoZW1hcyxcbiAgb3BlblNvdXJjZUZpbGUsXG4gIHJlYWRDb250ZW50LFxuICByZWFkU2NoZW1hLFxufSBmcm9tIFwiLi9jZGQtc2VydmljZVwiO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc29uYW11VUlBcGlQbHVnaW4oZmFzdGlmeTogRmFzdGlmeUluc3RhbmNlKSB7XG4gIGZhc3RpZnkucmVnaXN0ZXIoXG4gICAgYXN5bmMgKHNlcnZlcikgPT4ge1xuICAgICAgLy8gbWlncmF0b3JcbiAgICAgIGNvbnN0IG1pZ3JhdG9yID0gbmV3IE1pZ3JhdG9yKCk7XG5cbiAgICAgIC8vIHdhaXRGb3JITVJDb21wbGV0ZWRcbiAgICAgIGFzeW5jIGZ1bmN0aW9uIHdhaXRGb3JITVJDb21wbGV0ZWQ8VD4oZm46ICgpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICAgICAgY29uc3Qgd2FpdFByb21pc2UgPSBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGhhbmRsZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIFNvbmFtdS5zeW5jZXIuZXZlbnRFbWl0dGVyLm9mZihcIm9uSE1SQ29tcGxldGVkXCIsIGhhbmRsZXIpO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0sIDE1MDApO1xuXG4gICAgICAgICAgU29uYW11LnN5bmNlci5ldmVudEVtaXR0ZXIub25jZShcIm9uSE1SQ29tcGxldGVkXCIsIGhhbmRsZXIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmbigpO1xuICAgICAgICBhd2FpdCB3YWl0UHJvbWlzZTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgc2V0QWlBcGkoc2VydmVyKTtcblxuICAgICAgc2VydmVyLmdldChcIi9hcGkvc29uYW11L2NvbmZpZ1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHJldHVybiBTb25hbXUuY29uZmlnO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBRdWVyeXN0cmluZzoge1xuICAgICAgICAgIGVudGl0eUlkPzogc3RyaW5nO1xuICAgICAgICAgIHByZXNldD86IFwidHlwZXNcIiB8IFwiZW50aXR5Lmpzb25cIiB8IFwiZ2VuZXJhdGVkXCI7XG4gICAgICAgICAgYWJzUGF0aD86IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS90b29scy9vcGVuVnNjb2RlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIHByZXNldCwgYWJzUGF0aCB9ID0gcmVxdWVzdC5xdWVyeTtcblxuICAgICAgICBjb25zdCB0YXJnZXRQYXRoID0gKCgpID0+IHtcbiAgICAgICAgICBpZiAoZW50aXR5SWQgJiYgcHJlc2V0KSB7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICBjb25zdCB7IG5hbWVzIH0gPSBlbnRpdHk7XG5cbiAgICAgICAgICAgIGNvbnN0IHsgYXBpUm9vdFBhdGggfSA9IFNvbmFtdTtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVuYW1lID0gKCgpID0+IHtcbiAgICAgICAgICAgICAgc3dpdGNoIChwcmVzZXQpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwidHlwZXNcIjpcbiAgICAgICAgICAgICAgICAgIHJldHVybiBgJHtuYW1lcy5mc30udHlwZXMudHNgO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJlbnRpdHkuanNvblwiOlxuICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke25hbWVzLmZzfS5lbnRpdHkuanNvbmA7XG4gICAgICAgICAgICAgICAgY2FzZSBcImdlbmVyYXRlZFwiOlxuICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke25hbWVzLmZzfS5nZW5lcmF0ZWQudHNgO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICAgICAgcmV0dXJuIGAke2FwaVJvb3RQYXRofS9zcmMvYXBwbGljYXRpb24vJHtlbnRpdHkubmFtZXMucGFyZW50RnN9LyR7ZmlsZW5hbWV9YDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFhYnNQYXRoKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLnByZXNldE9yQWJzUGF0aFJlcXVpcmVkXCIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhYnNQYXRoO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKTtcbiAgICAgICAgZXhlY1N5bmMoYGNvZGUgJHt0YXJnZXRQYXRofWApO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBRdWVyeXN0cmluZzoge1xuICAgICAgICAgIG9yaWdpbjogc3RyaW5nO1xuICAgICAgICAgIGVudGl0eUlkPzogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3Rvb2xzL2dldFN1Z2dlc3Rpb25cIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBvcmlnaW4sIGVudGl0eUlkIH0gPSByZXF1ZXN0LnF1ZXJ5O1xuXG4gICAgICAgIC8vIOy5mO2ZmCDsmqnslrTsp5FcbiAgICAgICAgY29uc3QgZ2xvc3NhcnkgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPihbXG4gICAgICAgICAgW1wic3RhdHVzXCIsIFwi7IOB7YOcXCJdLFxuICAgICAgICAgIFtcInR5cGVcIiwgXCLtg4DsnoVcIl0sXG4gICAgICAgICAgW1wiaW1hZ2VcIiwgXCLsnbTrr7jsp4BcIl0sXG4gICAgICAgICAgW1wiaW1hZ2VzXCIsIFwi7J2066+47KeA66as7Iqk7Yq4XCJdLFxuICAgICAgICAgIFtcInVybFwiLCBcIlVSTFwiXSxcbiAgICAgICAgICBbXCJpZFwiLCBcIklEXCJdLFxuICAgICAgICAgIFtcIm5hbWVcIiwgYHtFbnRpdHlJRH3rqoVgXSxcbiAgICAgICAgICBbXCJ0aXRsZVwiLCBcIntFbnRpdHlJRH3rqoVcIl0sXG4gICAgICAgICAgW1wicGFyZW50XCIsIFwi7IOB7JyEe0VudGl0eUlEfVwiXSxcbiAgICAgICAgICBbXCJkZXNjXCIsIFwi7ISk66qFXCJdLFxuICAgICAgICAgIFtcImF0XCIsIFwi7J287IucXCJdLFxuICAgICAgICAgIFtcImNyZWF0ZWRcIiwgXCLrk7HroZ1cIl0sXG4gICAgICAgICAgW1widXBkYXRlZFwiLCBcIuyImOyglVwiXSxcbiAgICAgICAgICBbXCJkZWxldGVkXCIsIFwi7IKt7KCcXCJdLFxuICAgICAgICAgIFtcImJ5XCIsIFwi7Jyg7KCAXCJdLFxuICAgICAgICAgIFtcImRhdGVcIiwgXCLsnbzsnpBcIl0sXG4gICAgICAgICAgW1widGltZVwiLCBcIuyLnOqwhFwiXSxcbiAgICAgICAgICBbXCJrb1wiLCBcIijtlZzquIApXCJdLFxuICAgICAgICAgIFtcImVuXCIsIFwiKOyYgeusuClcIl0sXG4gICAgICAgICAgW1wia3J3XCIsIFwiKOybkClcIl0sXG4gICAgICAgICAgW1widXNkXCIsIFwiKFVTRClcIl0sXG4gICAgICAgICAgW1wiY29sb3JcIiwgXCLsu6zrn6xcIl0sXG4gICAgICAgICAgW1wiY29kZVwiLCBcIuy9lOuTnFwiXSxcbiAgICAgICAgICBbXCJ4XCIsIFwiWOyijO2RnFwiXSxcbiAgICAgICAgICBbXCJ5XCIsIFwiWeyijO2RnFwiXSxcbiAgICAgICAgICBbXCJjdXJyZW50XCIsIFwi7ZiE7J6sXCJdLFxuICAgICAgICAgIFtcInN0b2NrXCIsIFwi7J6s6rOgXCJdLFxuICAgICAgICAgIFtcInRvdGFsXCIsIFwi7LSdXCJdLFxuICAgICAgICAgIFtcImFkbWluXCIsIFwi6rSA66as7J6QXCJdLFxuICAgICAgICAgIFtcImdyb3VwXCIsIFwi6re466O5XCJdLFxuICAgICAgICAgIFtcIml0ZW1cIiwgXCLslYTsnbTthZxcIl0sXG4gICAgICAgICAgW1wiY250XCIsIFwi7IiY65+JXCJdLFxuICAgICAgICAgIFtcInByaWNlXCIsIFwi6rCA6rKpXCJdLFxuICAgICAgICAgIFtcInByZXNldFwiLCBcIu2UhOumrOyFi1wiXSxcbiAgICAgICAgICBbXCJhY2N0XCIsIFwi6rOE7KKMXCJdLFxuICAgICAgICAgIFtcInRlbFwiLCBcIuyghO2ZlOuyiO2YuFwiXSxcbiAgICAgICAgICBbXCJub1wiLCBcIuuyiO2YuFwiXSxcbiAgICAgICAgICBbXCJib2R5XCIsIFwi64K07JqpXCJdLFxuICAgICAgICAgIFtcImNvbnRlbnRcIiwgXCLrgrTsmqlcIl0sXG4gICAgICAgICAgW1wib3JkZXJub1wiLCBcIuygleugrOyInOyEnFwiXSxcbiAgICAgICAgICBbXCJwcmlvcml0eVwiLCBcIuyasOyEoOyInOychFwiXSxcbiAgICAgICAgICBbXCJ0ZXh0XCIsIFwi7YWN7Iqk7Yq4XCJdLFxuICAgICAgICAgIFtcImtleVwiLCBcIu2CpFwiXSxcbiAgICAgICAgICBbXCJzdW1cIiwgXCLtlansgrBcIl0sXG4gICAgICAgICAgW1wiZXhwZWN0ZWRcIiwgXCLsmIjsg4FcIl0sXG4gICAgICAgICAgW1wiYWN0dWFsXCIsIFwi7Iuk7KCcXCJdLFxuICAgICAgICBdKTtcbiAgICAgICAgLy8g7KCE7LK0IOyXlO2LsO2LsCDsiJztmoztlZjrqbAsIOyXlO2LsO2LsCDtg4DsnbTti4Dqs7wg7ZSE66GtIOyEpOuqheydhCDsuZjtmZgg7Jqp7Ja07KeR7JeQIOy2lOqwgFxuICAgICAgICBmb3IgKGNvbnN0IGVudGl0eUlkIG9mIEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCkpIHtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgaWYgKChlbnRpdHkudGl0bGUgPz8gXCJcIikgIT09IFwiXCIpIHtcbiAgICAgICAgICAgIGdsb3NzYXJ5LnNldChpbmZsZWN0aW9uLnVuZGVyc2NvcmUoZW50aXR5LmlkKSwgZW50aXR5LnRpdGxlKTtcbiAgICAgICAgICAgIGdsb3NzYXJ5LnNldChcbiAgICAgICAgICAgICAgaW5mbGVjdGlvbi51bmRlcnNjb3JlKGluZmxlY3Rpb24ucGx1cmFsaXplKGVudGl0eS5pZCkpLFxuICAgICAgICAgICAgICBgJHtlbnRpdHkudGl0bGV966as7Iqk7Yq4YCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZW50aXR5LnByb3BzLmZvckVhY2goKHByb3ApID0+IHtcbiAgICAgICAgICAgIGlmIChnbG9zc2FyeS5oYXMocHJvcC5uYW1lKSkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocHJvcC5kZXNjKSB7XG4gICAgICAgICAgICAgIGdsb3NzYXJ5LnNldChwcm9wLm5hbWUsIHByb3AuZGVzYy5yZXBsYWNlKGVudGl0eS50aXRsZSA/PyBcIlwiLCBcIntFbnRpdHlJRH1cIikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc3VnZ2VzdGVkID0gKCgpID0+IHtcbiAgICAgICAgICAvLyDri6jslrQg67aE66asLCDqsIDriqXtlZwg7KGw7ZWpIOyDneyEsVxuICAgICAgICAgIGNvbnN0IHdvcmRzID0gb3JpZ2luLnNwbGl0KFwiX1wiKTtcbiAgICAgICAgICBjb25zdCBjb21iaW5hdGlvbnMgPSBbLi4ucmFuZ2Uod29yZHMubGVuZ3RoLCAwLCAtMSldLmZsYXRNYXAoKGxlbikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgLi4ucmFuZ2UoMCwgd29yZHMubGVuZ3RoIC0gbGVuICsgMSwgKGlkeCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICBsZW4sXG4gICAgICAgICAgICAgICAgICB3OiB3b3Jkcy5zbGljZShpZHgsIGlkeCArIGxlbikuam9pbihcIl9cIiksXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBdO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8g7KGw7ZWp7J2EIOyInO2ajO2VmOupsCwg7LmY7ZmYIOyaqeyWtOynkeyXkCDsnojripQg64uo7Ja06rCAIO2PrO2VqOuQnCDqsr3smrAsIOy5mO2ZmCDsmqnslrTroZwg7LmY7ZmYXG4gICAgICAgICAgY29uc3QgUkVQTEFDRURfUFJFRklYID0gXCIjUkVQTEFDRUQvL1wiOyAvLyDsuZjtmZjrkJwg64uo7Ja066W8IGpvaW4g7J207ZuE7JeQ64+EIOyLneuzhO2VmOq4sCDsnITtlbQgcHJlZml4IOy2lOqwgFxuICAgICAgICAgIGxldCByZW1haW5BcnI6IHN0cmluZ1tdID0gWy4uLndvcmRzXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGNvbWIgb2YgY29tYmluYXRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCByZW1haW5TdHIgPSByZW1haW5BcnIuam9pbihcIl9cIik7XG4gICAgICAgICAgICBpZiAocmVtYWluU3RyLmluY2x1ZGVzKGNvbWIudykgJiYgZ2xvc3NhcnkuaGFzKGNvbWIudykpIHtcbiAgICAgICAgICAgICAgcmVtYWluQXJyID0gcmVtYWluU3RyXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoY29tYi53LCBSRVBMQUNFRF9QUkVGSVggKyBnbG9zc2FyeS5nZXQoY29tYi53KSlcbiAgICAgICAgICAgICAgICAuc3BsaXQoXCJfXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiByZW1haW5BcnJcbiAgICAgICAgICAgIC5tYXAoKHIpID0+IHtcbiAgICAgICAgICAgICAgaWYgKHIuc3RhcnRzV2l0aChSRVBMQUNFRF9QUkVGSVgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHIucmVwbGFjZShSRVBMQUNFRF9QUkVGSVgsIFwiXCIpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiByLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuam9pbihcIlwiKVxuICAgICAgICAgICAgLnJlcGxhY2UoL3tFbnRpdHlJRH0vZywgZW50aXR5SWQgPyBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCkudGl0bGUgOiBcIlwiKTtcbiAgICAgICAgfSkoKTtcblxuICAgICAgICByZXR1cm4geyBzdWdnZXN0ZWQgfTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS9lbnRpdHkvZmluZE1hbnlcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBlbnRpdHlJZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuXG4gICAgICAgIGZ1bmN0aW9uIGZsYXR0ZW5TdWJzZXRSb3dzKHN1YnNldFJvd3M6IEVudGl0eVN1YnNldFJvd1tdKTogRmxhdHRlblN1YnNldFJvd1tdIHtcbiAgICAgICAgICByZXR1cm4gc3Vic2V0Um93cy5mbGF0TWFwKChzdWJzZXRSb3cpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgY2hpbGRyZW4sIC4uLnNSb3cgfSA9IHN1YnNldFJvdztcbiAgICAgICAgICAgIHJldHVybiBbc1JvdywgLi4uZmxhdHRlblN1YnNldFJvd3MoY2hpbGRyZW4pXTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVudGl0aWVzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgZW50aXR5SWRzLm1hcCgoZW50aXR5SWQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGNvbnN0IHN1YnNldFJvd3MgPSBlbnRpdHkuZ2V0U3Vic2V0Um93cygpO1xuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAuLi5lbnRpdHksXG4gICAgICAgICAgICAgIGZsYXR0ZW5TdWJzZXRSb3dzOiBmbGF0dGVuU3Vic2V0Um93cyhzdWJzZXRSb3dzKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgZW50aXRpZXMuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgIGNvbnN0IGFJZCA9IGEucGFyZW50SWQgPz8gYS5pZDtcbiAgICAgICAgICBjb25zdCBiSWQgPSBiLnBhcmVudElkID8/IGIuaWQ7XG4gICAgICAgICAgaWYgKGFJZCA8IGJJZCkgcmV0dXJuIC0xO1xuICAgICAgICAgIGlmIChhSWQgPiBiSWQpIHJldHVybiAxO1xuICAgICAgICAgIGlmIChhSWQgPT09IGJJZCkge1xuICAgICAgICAgICAgaWYgKGEucGFyZW50SWQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIC0xO1xuICAgICAgICAgICAgaWYgKGIucGFyZW50SWQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIDE7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4geyBlbnRpdGllcyB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBRdWVyeXN0cmluZzoge1xuICAgICAgICAgIGZpbHRlcj86IFwiZW51bXNcIiB8IFwidHlwZXNcIjtcbiAgICAgICAgICByZWxvYWQ/OiBcIjFcIjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvdHlwZUlkc1wiLCBhc3luYyAocmVxdWVzdCk6IFByb21pc2U8eyB0eXBlSWRzOiBzdHJpbmdbXSB9PiA9PiB7XG4gICAgICAgIGNvbnN0IHsgZmlsdGVyLCByZWxvYWQgfSA9IHJlcXVlc3QucXVlcnk7XG5cbiAgICAgICAgaWYgKHJlbG9hZCA9PT0gXCIxXCIpIHtcbiAgICAgICAgICBhd2FpdCBTb25hbXUuc3luY2VyLmF1dG9sb2FkVHlwZXMoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHR5cGVJZHMgPSAoKCkgPT4ge1xuICAgICAgICAgIC8vIO2UhOuhnOygne2KuOyXkOyEnCDsoJXsnZjtlZwg7YOA7J6F65OkXG4gICAgICAgICAgY29uc3QgcHJvamVjdFR5cGVJZHMgPSBPYmplY3QuZW50cmllcyhTb25hbXUuc3luY2VyLnR5cGVzKVxuICAgICAgICAgICAgLmZpbHRlcigoW190eXBlSWQsIHpvZFR5cGVdKSA9PiAoem9kVHlwZS5fem9kLmRlZi50eXBlIGFzIHN0cmluZykgIT09IFwiZW51bVwiKVxuICAgICAgICAgICAgLm1hcCgoW3R5cGVJZCwgX3pvZFR5cGVdKSA9PiB0eXBlSWQpO1xuXG4gICAgICAgICAgLy8g64K07J6lIO2DgOyeheuTpCAoc29uYW11IOy9lOyWtOyXkOyEnCDsoJzqs7UpXG4gICAgICAgICAgY29uc3QgYnVpbHRJblR5cGVJZHMgPSBbLi4uQlVJTFRfSU5fVFlQRV9JRFNdO1xuXG4gICAgICAgICAgLy8g66qo65OgIO2DgOyehSDrs5HtlalcbiAgICAgICAgICBjb25zdCBhbGxUeXBlSWRzID0gWy4uLmJ1aWx0SW5UeXBlSWRzLCAuLi5wcm9qZWN0VHlwZUlkc107XG5cbiAgICAgICAgICBpZiAoZmlsdGVyID09PSBcInR5cGVzXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBhbGxUeXBlSWRzO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGVudW1JZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpLmZsYXRNYXAoKGVudGl0eUlkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMoZW50aXR5LmVudW1MYWJlbHMpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKGZpbHRlciA9PT0gXCJlbnVtc1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gZW51bUlkcztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFsuLi5hbGxUeXBlSWRzLCAuLi5lbnVtSWRzXTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pKCk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0eXBlSWRzLFxuICAgICAgICB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGZvcm06IHtcbiAgICAgICAgICAgIGlkOiBzdHJpbmc7XG4gICAgICAgICAgICB0aXRsZTogc3RyaW5nO1xuICAgICAgICAgICAgdGFibGU6IHN0cmluZztcbiAgICAgICAgICAgIHBhcmVudElkPzogc3RyaW5nO1xuICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2NyZWF0ZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBmb3JtIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgYXdhaXQgU29uYW11LnN5bmNlci5jcmVhdGVFbnRpdHkoeyAuLi5mb3JtLCBlbnRpdHlJZDogZm9ybS5pZCB9KTtcblxuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9kZWxcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgU29uYW11LnN5bmNlci5kZWxFbnRpdHkoZW50aXR5SWQpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIG5ld1ZhbHVlczoge1xuICAgICAgICAgICAgdGl0bGU6IHN0cmluZztcbiAgICAgICAgICAgIHRhYmxlOiBzdHJpbmc7XG4gICAgICAgICAgICBwYXJlbnRJZD86IHN0cmluZztcbiAgICAgICAgICB9O1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb2RpZnlFbnRpdHlCYXNlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBuZXdWYWx1ZXMgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZW50aXR5LnRpdGxlID0gbmV3VmFsdWVzLnRpdGxlO1xuICAgICAgICAgIGVudGl0eS50YWJsZSA9IG5ld1ZhbHVlcy50YWJsZTtcbiAgICAgICAgICBlbnRpdHkucGFyZW50SWQgPSBuZXdWYWx1ZXMucGFyZW50SWQ7XG4gICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcblxuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIHN1YnNldEtleTogc3RyaW5nO1xuICAgICAgICAgIGZpZWxkczogc3RyaW5nW107XG4gICAgICAgICAgZmllbGRzSW50ZXJuYWw/OiBzdHJpbmdbXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvbW9kaWZ5U3Vic2V0XCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBzdWJzZXRLZXksIGZpZWxkcywgZmllbGRzSW50ZXJuYWwgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZW50aXR5LnN1YnNldHNbc3Vic2V0S2V5XSA9IGZpZWxkcztcbiAgICAgICAgICBpZiAoZmllbGRzSW50ZXJuYWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWYgKGZpZWxkc0ludGVybmFsLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgZW50aXR5LnN1YnNldHNJbnRlcm5hbFtzdWJzZXRLZXldID0gZmllbGRzSW50ZXJuYWw7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBkZWxldGUgZW50aXR5LnN1YnNldHNJbnRlcm5hbFtzdWJzZXRLZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgcmV0dXJuIHsgdXBkYXRlZDogZmllbGRzLCB1cGRhdGVkSW50ZXJuYWw6IGZpZWxkc0ludGVybmFsIH07XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgc3Vic2V0S2V5OiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2RlbFN1YnNldFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgc3Vic2V0S2V5IH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgIGRlbGV0ZSBlbnRpdHkuc3Vic2V0c1tzdWJzZXRLZXldO1xuICAgICAgICAgIGRlbGV0ZSBlbnRpdHkuc3Vic2V0c0ludGVybmFsW3N1YnNldEtleV07XG4gICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcblxuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIG5ld1Byb3A6IEVudGl0eVByb3A7XG4gICAgICAgICAgYXQ/OiBudW1iZXI7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2NyZWF0ZVByb3BcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGF0LCBuZXdQcm9wIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgIGF3YWl0IGVudGl0eS5jcmVhdGVQcm9wKG5ld1Byb3AsIGF0KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBuZXdQcm9wOiBFbnRpdHlQcm9wO1xuICAgICAgICAgIGF0OiBudW1iZXI7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L21vZGlmeVByb3BcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGF0LCBuZXdQcm9wIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZW50aXR5Lm1vZGlmeVByb3AobmV3UHJvcCwgYXQpO1xuXG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgYXQ6IG51bWJlcjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvZGVsUHJvcFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgYXQgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBlbnRpdHkuZGVsUHJvcChhdCk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgYXQ6IG51bWJlcjtcbiAgICAgICAgICB0bzogbnVtYmVyO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb3ZlUHJvcFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgYXQsIHRvIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZW50aXR5Lm1vdmVQcm9wKGF0LCB0byk7XG5cbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBpbmRleGVzOiBFbnRpdHlJbmRleFtdO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb2RpZnlJbmRleGVzXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBpbmRleGVzIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgIGVudGl0eS5pbmRleGVzID0gaW5kZXhlcztcbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgcmV0dXJuIHsgdXBkYXRlZDogaW5kZXhlcyB9O1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIGVudW1MYWJlbHM6IEVudGl0eVtcImVudW1MYWJlbHNcIl07XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L21vZGlmeUVudW1MYWJlbHNcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGVudW1MYWJlbHMgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZW50aXR5LmVudW1MYWJlbHMgPSBlbnVtTGFiZWxzO1xuICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICByZXR1cm4geyB1cGRhdGVkOiBlbnVtTGFiZWxzIH07XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgbmV3RW51bUlkOiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2NyZWF0ZUVudW1JZFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgbmV3RW51bUlkIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuXG4gICAgICAgICAgaWYgKGVudGl0eS5lbnVtTGFiZWxzW25ld0VudW1JZF0pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg7J2066+4IOyhtOyerO2VmOuKlCBlbnVtSWTsnoXri4jri6Q6ICR7bmV3RW51bUlkfWApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGVudGl0eS5lbnVtTGFiZWxzW25ld0VudW1JZF0gPSB7XG4gICAgICAgICAgICAuLi4obmV3RW51bUlkLmVuZHNXaXRoKFwiU3RhdHVzXCIpXG4gICAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgICAgYWN0aXZlOiBcIuuFuOy2nFwiLFxuICAgICAgICAgICAgICAgICAgaGlkZGVuOiBcIuyIqOq5gFwiLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgOiB7XG4gICAgICAgICAgICAgICAgICBcIlwiOiBcIlwiLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgIH07XG4gICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcblxuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIGVudW1JZDoge1xuICAgICAgICAgICAgYmVmb3JlOiBzdHJpbmc7XG4gICAgICAgICAgICBhZnRlcjogc3RyaW5nO1xuICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L21vZGlmeUVudW1JZFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgZW51bUlkIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgY29uc3QgZW50aXR5SWRzID0gRW50aXR5TWFuYWdlci5nZXRBbGxJZHMoKTtcbiAgICAgICAgICBjb25zdCBpc0V4aXN0cyA9IGVudGl0eUlkcy5zb21lKChlbnRpdHlJZCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGVudGl0eS5lbnVtTGFiZWxzKS5pbmNsdWRlcyhlbnVtSWQuYWZ0ZXIpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChpc0V4aXN0cykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDsnbTrr7gg7KG07J6s7ZWY64qUIEVudW1JZOyeheuLiOuLpDogJHtlbnVtSWQuYWZ0ZXJ9YCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgIGVudGl0eS5lbnVtTGFiZWxzW2VudW1JZC5hZnRlcl0gPSBlbnRpdHkuZW51bUxhYmVsc1tlbnVtSWQuYmVmb3JlXTtcbiAgICAgICAgICBkZWxldGUgZW50aXR5LmVudW1MYWJlbHNbZW51bUlkLmJlZm9yZV07XG5cbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBlbnRpdHlJZCBvZiBlbnRpdHlJZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcHJvcCBvZiBlbnRpdHkucHJvcHMpIHtcbiAgICAgICAgICAgICAgaWYgKHByb3AudHlwZSA9PT0gXCJlbnVtXCIgJiYgcHJvcC5pZCA9PT0gZW51bUlkLmJlZm9yZSkge1xuICAgICAgICAgICAgICAgIHByb3AuaWQgPSBlbnVtSWQuYWZ0ZXI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIGVudW1JZDogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9kZWxldGVFbnVtSWRcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGVudW1JZCB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgICAgY29uc3QgZW50aXR5SWRzID0gRW50aXR5TWFuYWdlci5nZXRBbGxJZHMoKTtcbiAgICAgICAgICBjb25zdCBpc1JlZmVyZW5jZWQgPSBlbnRpdHlJZHNcbiAgICAgICAgICAgIC5mbGF0TWFwKChlbnRpdHlJZCkgPT4gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpLnByb3BzKVxuICAgICAgICAgICAgLnNvbWUoKHByb3ApID0+IHByb3AudHlwZSA9PT0gXCJlbnVtXCIgJiYgcHJvcC5pZCA9PT0gZW51bUlkKTtcbiAgICAgICAgICBpZiAoaXNSZWZlcmVuY2VkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZW51bUlkfeulvCDssLjsobDtlZjripQg7ZSE66Gc7Y287Yuw6rCAIOyhtOyerO2VqeuLiOuLpC5gKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZGVsZXRlIGVudGl0eS5lbnVtTGFiZWxzW2VudW1JZF07XG4gICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICB0YXJnZXQ6IFwiZW50aXR5XCIgfCBcInByb3BcIiB8IFwiZW51bVwiIHwgXCJzdWJzZXRcIjtcbiAgICAgICAgICBwcm9wTmFtZT86IHN0cmluZztcbiAgICAgICAgICBlbnVtSWQ/OiBzdHJpbmc7XG4gICAgICAgICAgc3Vic2V0S2V5Pzogc3RyaW5nO1xuICAgICAgICAgIGNvbmU6IENvbmU7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L3VwZGF0ZUNvbmVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIHRhcmdldCwgcHJvcE5hbWUsIGVudW1JZCwgc3Vic2V0S2V5LCBjb25lIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuXG4gICAgICAgICAgaWYgKHRhcmdldCA9PT0gXCJlbnRpdHlcIikge1xuICAgICAgICAgICAgZW50aXR5LmNvbmUgPSBjb25lO1xuICAgICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0ID09PSBcInByb3BcIiAmJiBwcm9wTmFtZSkge1xuICAgICAgICAgICAgY29uc3QgcHJvcCA9IGVudGl0eS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IHByb3BOYW1lKTtcbiAgICAgICAgICAgIGlmIChwcm9wKSB7XG4gICAgICAgICAgICAgIChwcm9wIGFzIHsgY29uZT86IENvbmUgfSkuY29uZSA9IGNvbmU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXQgPT09IFwiZW51bVwiICYmIGVudW1JZCkge1xuICAgICAgICAgICAgZW50aXR5LmVudW1Db25lc1tlbnVtSWRdID0gY29uZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldCA9PT0gXCJzdWJzZXRcIiAmJiBzdWJzZXRLZXkpIHtcbiAgICAgICAgICAgIGVudGl0eS5zdWJzZXRDb25lc1tzdWJzZXRLZXldID0gY29uZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIHByZXNlcnZlRXhpc3Rpbmc/OiBib29sZWFuO1xuICAgICAgICAgIG9ubHlFbXB0eT86IGJvb2xlYW47XG4gICAgICAgICAgbG9jYWxlPzogXCJrb1wiIHwgXCJlblwiIHwgXCJqYVwiO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9nZW5lcmF0ZUNvbmVzXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgcHJlc2VydmVFeGlzdGluZywgb25seUVtcHR5LCBsb2NhbGUgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBFbnRpdHkg7KG07J6sIOyXrOu2gCDtmZXsnbhcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcblxuICAgICAgICAgICAgLy8gbG9jYWxlIOq4sOuzuOqwkjogU29uYW11LmNvbmZpZy5pMThuLmRlZmF1bHRMb2NhbGUg7IKs7JqpXG4gICAgICAgICAgICBjb25zdCBlZmZlY3RpdmVMb2NhbGUgPVxuICAgICAgICAgICAgICBsb2NhbGUgPz8gKFNvbmFtdS5jb25maWcuaTE4bi5kZWZhdWx0TG9jYWxlIGFzIFwia29cIiB8IFwiZW5cIiB8IFwiamFcIik7XG5cbiAgICAgICAgICAgIC8vIENvbmUg7IOd7ISxXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlbnRpdHkuZ2VuZXJhdGVDb25lcyh7XG4gICAgICAgICAgICAgIHByZXNlcnZlRXhpc3Rpbmc6IHByZXNlcnZlRXhpc3RpbmcgPz8gdHJ1ZSxcbiAgICAgICAgICAgICAgb25seUVtcHR5OiBvbmx5RW1wdHkgPz8gZmFsc2UsXG4gICAgICAgICAgICAgIGxvY2FsZTogZWZmZWN0aXZlTG9jYWxlLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG5cbiAgICAgICAgICAgIC8vIEVudGl0eSBub3QgZm91bmRcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKFwi7KG07J6s7ZWY7KeAIOyViuuKlCBFbnRpdHlcIikpIHtcbiAgICAgICAgICAgICAgcmVwbHkuc3RhdHVzKDQwNCk7XG4gICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGBFbnRpdHkgbm90IGZvdW5kOiAke2VudGl0eUlkfWAsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFQSSDtgqQg7JeG7J2MXG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbmNsdWRlcyhcIkFOVEhST1BJQ19BUElfS0VZIG5vdCBmb3VuZFwiKSkge1xuICAgICAgICAgICAgICByZXBseS5zdGF0dXMoNTAwKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBlcnJvcjogXCJBUEkga2V5IG5vdCBjb25maWd1cmVkXCIsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJhdGUgbGltaXRcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKFwiUmF0ZSBsaW1pdCBleGNlZWRlZFwiKSkge1xuICAgICAgICAgICAgICByZXBseS5zdGF0dXMoNDI5KTtcbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBlcnJvcjogXCJSYXRlIGxpbWl0IGV4Y2VlZGVkLiBQbGVhc2UgdHJ5IGFnYWluIGxhdGVyLlwiLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyDquLDtg4Ag7JeQ65+sXG4gICAgICAgICAgICByZXBseS5zdGF0dXMoNTAwKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICBlcnJvcjogYENvbmUgZ2VuZXJhdGlvbiBmYWlsZWQ6ICR7bWVzc2FnZX1gLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBRdWVyeXN0cmluZzoge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2dldFRhYmxlQ29sdW1uc1wiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IGVudGl0eUlkIH0gPSByZXF1ZXN0LnF1ZXJ5O1xuICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgIGNvbnN0IGNvbHVtbnMgPSBlbnRpdHkuZ2V0VGFibGVDb2x1bW5zKCk7XG4gICAgICAgIHJldHVybiB7IGNvbHVtbnMgfTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS9taWdyYXRpb25zL3N0YXR1c1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IGF3YWl0IG1pZ3JhdG9yLmdldFN0YXR1cygpO1xuXG4gICAgICAgIHJldHVybiB7IHN0YXR1cyB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGFjdGlvbjogXCJhcHBseVwiIHwgXCJyb2xsYmFja1wiIHwgXCJzaGFkb3dcIjtcbiAgICAgICAgICB0YXJnZXRzOiAoa2V5b2YgU29uYW11REJDb25maWcpW107XG4gICAgICAgICAgZm9yY2U/OiBib29sZWFuO1xuICAgICAgICAgIGZvcmNlUmVhc29uPzogc3RyaW5nO1xuICAgICAgICAgIHJlcXVlc3Rvcj86IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFxuICAgICAgICBcIi9hcGkvbWlncmF0aW9ucy9ydW5BY3Rpb25cIixcbiAgICAgICAgYXN5bmMgKHJlcXVlc3QpOiBQcm9taXNlPE1pZ3JhdGlvblJlc3VsdCB8IFNsYWNrQ29uZmlybVBlbmRpbmdSZXN1bHQ+ID0+IHtcbiAgICAgICAgICBjb25zdCB7IGFjdGlvbiwgdGFyZ2V0cywgZm9yY2UsIGZvcmNlUmVhc29uLCByZXF1ZXN0b3IgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgIGlmIChhY3Rpb24gPT09IFwic2hhZG93XCIpIHtcbiAgICAgICAgICAgIHJldHVybiBtaWdyYXRvci5ydW5TaGFkb3dUZXN0KCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gU2xhY2sg7Iq57J24IOyytO2BrCAoYXBwbHkg7Iuc7JeQ66eMKVxuICAgICAgICAgIGlmIChhY3Rpb24gPT09IFwiYXBwbHlcIikge1xuICAgICAgICAgICAgY29uc3Qgc2xhY2tDb25maXJtID0gbmV3IFNsYWNrQ29uZmlybSgpO1xuICAgICAgICAgICAgY29uc3QgcmVxdWlyZXNBcHByb3ZhbCA9IHRhcmdldHMuc29tZSgodCkgPT4gc2xhY2tDb25maXJtLmlzVGFyZ2V0UmVxdWlyZXNBcHByb3ZhbCh0KSk7XG5cbiAgICAgICAgICAgIC8vIOuhnOy7rCBEQuyduCDqsr3smrAg7Iq57J24IOyKpO2CtVxuICAgICAgICAgICAgY29uc3QgbG9jYWxIb3N0cyA9IFtcImxvY2FsaG9zdFwiLCBcIjEyNy4wLjAuMVwiLCBcIjAuMC4wLjBcIiwgXCI6OjFcIl07XG4gICAgICAgICAgICBjb25zdCBpc0xvY2FsVGFyZ2V0ID0gdGFyZ2V0cy5ldmVyeSgodGFyZ2V0KSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHRhcmdldENvbmZpZyA9IFNvbmFtdS5kYkNvbmZpZ1t0YXJnZXRdO1xuICAgICAgICAgICAgICBjb25zdCBob3N0ID0gKHRhcmdldENvbmZpZz8uY29ubmVjdGlvbiBhcyB7IGhvc3Q/OiBzdHJpbmcgfSk/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcbiAgICAgICAgICAgICAgcmV0dXJuIGxvY2FsSG9zdHMuaW5jbHVkZXMoaG9zdC50b0xvd2VyQ2FzZSgpKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAocmVxdWlyZXNBcHByb3ZhbCAmJiBzbGFja0NvbmZpcm0uaXNDb25maWd1cmVkKCkgJiYgIWlzTG9jYWxUYXJnZXQpIHtcbiAgICAgICAgICAgICAgY29uc3QgeyBjb25ucyB9ID0gYXdhaXQgbWlncmF0b3IuZ2V0U3RhdHVzKCk7XG5cbiAgICAgICAgICAgICAgLy8g66qo65OgIO2DgOqynyBEQuyXkOyEnCBwZW5kaW5n7J24IOuniOydtOq3uOugiOydtOyFmOydmCDtlansp5HtlansnYQg6rWs7ZWp64uI64ukLlxuICAgICAgICAgICAgICBjb25zdCBwZW5kaW5nTWlncmF0aW9ucyA9IFtcbiAgICAgICAgICAgICAgICAuLi5uZXcgU2V0KFxuICAgICAgICAgICAgICAgICAgY29ubnNcbiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcigoY29ubikgPT4gdGFyZ2V0cy5pbmNsdWRlcyhjb25uLmNvbm5LZXkgYXMga2V5b2YgU29uYW11REJDb25maWcpKVxuICAgICAgICAgICAgICAgICAgICAuZmxhdE1hcCgoY29ubikgPT4gY29ubi5wZW5kaW5nKSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICBdO1xuXG4gICAgICAgICAgICAgIGlmIChwZW5kaW5nTWlncmF0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgLy8g6riw7KG0IOyKueyduCDsmpTssq0g7ZmV7J24XG4gICAgICAgICAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBzbGFja0NvbmZpcm0uZ2V0RXhpc3RpbmdSZXF1ZXN0KHBlbmRpbmdNaWdyYXRpb25zKTtcblxuICAgICAgICAgICAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICAgICAgICAgICAgLy8g6riw7KG0IOyalOyyreydtCDsnojsnLzrqbQg7Iq57J24IOyDge2DnCDtmZXsnbhcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHsgYXBwcm92ZWQsIHJlamVjdGVkIH0gPSBhd2FpdCBzbGFja0NvbmZpcm0uY2hlY2tBcHByb3ZhbChcbiAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcuY2hhbm5lbCxcbiAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcudHMsXG4gICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICBpZiAoYXBwcm92ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g7Iq57J2465CoIOKGkiDsi6TtlolcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbWlncmF0b3IucnVuQWN0aW9uKGFjdGlvbiwgdGFyZ2V0cyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHNsYWNrQ29uZmlybS5sb2dFeGVjdXRpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZy5jaGFubmVsLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcudHMsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0b3IsXG4gICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZWplY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5taWdyYXRpb25SZWplY3RlZFwiKSk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGZvcmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEZvcmNlIOynhO2WiVxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBzbGFja0NvbmZpcm0uZm9yY2VBcHByb3ZhbChcbiAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZy5jaGFubmVsLFxuICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nLnRzLFxuICAgICAgICAgICAgICAgICAgICAgIGZvcmNlUmVhc29uID8/IFwi7IKs7JygIOyXhuydjFwiLFxuICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RvcixcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbWlncmF0b3IucnVuQWN0aW9uKGFjdGlvbiwgdGFyZ2V0cyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHNsYWNrQ29uZmlybS5sb2dFeGVjdXRpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZy5jaGFubmVsLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcudHMsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0b3IsXG4gICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g64yA6riw7KSRXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJwZW5kaW5nXCIsXG4gICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbDogZXhpc3RpbmcuY2hhbm5lbCxcbiAgICAgICAgICAgICAgICAgICAgICB0czogZXhpc3RpbmcudHMsXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIC8vIOyDiCDsirnsnbgg7JqU7LKtIOuwnOyGoVxuICAgICAgICAgICAgICAgICAgY29uc3QgeyBjaGFubmVsLCB0cyB9ID0gYXdhaXQgc2xhY2tDb25maXJtLnBvc3RBcHByb3ZhbFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgIHBlbmRpbmdNaWdyYXRpb25zLFxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRzLFxuICAgICAgICAgICAgICAgICAgICByZXF1ZXN0b3IsXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgYXdhaXQgc2xhY2tDb25maXJtLnNhdmVSZXF1ZXN0KHBlbmRpbmdNaWdyYXRpb25zLCBjaGFubmVsLCB0cyk7XG5cbiAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFwicGVuZGluZ1wiLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsLFxuICAgICAgICAgICAgICAgICAgICB0cyxcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIG1pZ3JhdG9yLnJ1bkFjdGlvbihhY3Rpb24sIHRhcmdldHMpO1xuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgY2hhbm5lbDogc3RyaW5nO1xuICAgICAgICAgIHRzOiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvbWlncmF0aW9ucy9jaGVja0FwcHJvdmFsXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgY2hhbm5lbCwgdHMgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgY29uc3Qgc2xhY2tDb25maXJtID0gbmV3IFNsYWNrQ29uZmlybSgpO1xuXG4gICAgICAgIGlmICghc2xhY2tDb25maXJtLmlzQ29uZmlndXJlZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIHsgYXBwcm92ZWQ6IHRydWUsIHJlamVjdGVkOiBmYWxzZSB9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNsYWNrQ29uZmlybS5jaGVja0FwcHJvdmFsKGNoYW5uZWwsIHRzKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBjaGFubmVsOiBzdHJpbmc7XG4gICAgICAgICAgdHM6IHN0cmluZztcbiAgICAgICAgICByZWFzb246IHN0cmluZztcbiAgICAgICAgICByZXF1ZXN0b3I/OiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvbWlncmF0aW9ucy9mb3JjZUFwcHJvdmFsXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgY2hhbm5lbCwgdHMsIHJlYXNvbiwgcmVxdWVzdG9yIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgIGNvbnN0IHNsYWNrQ29uZmlybSA9IG5ldyBTbGFja0NvbmZpcm0oKTtcblxuICAgICAgICBpZiAoIXNsYWNrQ29uZmlybS5pc0NvbmZpZ3VyZWQoKSkge1xuICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLnNsYWNrQ29uZmlybU5vdENvbmZpZ3VyZWRcIikpO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgc2xhY2tDb25maXJtLmZvcmNlQXBwcm92YWwoY2hhbm5lbCwgdHMsIHJlYXNvbiwgcmVxdWVzdG9yKTtcbiAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGNvZGVOYW1lczogc3RyaW5nW107XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvbWlncmF0aW9ucy9kZWxDb2Rlc1wiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IGNvZGVOYW1lcyB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICByZXR1cm4gYXdhaXQgbWlncmF0b3IuZGVsQ29kZXMoY29kZU5hbWVzKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdChcIi9hcGkvbWlncmF0aW9ucy9nZW5lcmF0ZVByZXBhcmVkQ29kZXNcIiwgYXN5bmMgKF9yZXF1ZXN0dCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgbWlncmF0b3IuZ2VuZXJhdGVQcmVwYXJlZENvZGVzKCk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWRzOiBzdHJpbmdbXTtcbiAgICAgICAgICB0ZW1wbGF0ZUtleXM6IHN0cmluZ1tdO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3NjYWZmb2xkaW5nL2dldFN0YXR1c1wiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IGVudGl0eUlkcywgdGVtcGxhdGVLZXlzOiBfdGVtcGxhdGVLZXlzIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgIGlmICgoZW50aXR5SWRzID8/IFtdKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5lbnRpdHlJZHNSZXF1aXJlZFwiKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoKF90ZW1wbGF0ZUtleXMgPz8gW10pLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLnRlbXBsYXRlS2V5c1JlcXVpcmVkXCIpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHNvcnRpbmdcbiAgICAgICAgZW50aXR5SWRzLnNvcnQoKGEsIGIpID0+IChhIDwgYiA/IC0xIDogYSA+IGIgPyAxIDogMCkpO1xuICAgICAgICBjb25zdCB0ZW1wbGF0ZUtleXMgPSBUZW1wbGF0ZUtleS5vcHRpb25zLmZpbHRlcigodGspID0+IF90ZW1wbGF0ZUtleXMuaW5jbHVkZXModGspKTtcblxuICAgICAgICBjb25zdCBjb21iaW5hdGlvbnMgPSBlbnRpdHlJZHMuZmxhdE1hcCgoZW50aXR5SWQpID0+IHtcbiAgICAgICAgICByZXR1cm4gdGVtcGxhdGVLZXlzLm1hcCgodGVtcGxhdGVLZXkpID0+IFtlbnRpdHlJZCwgdGVtcGxhdGVLZXldKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgc3RhdHVzZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICBjb21iaW5hdGlvbnMubWFwKGFzeW5jIChbZW50aXR5SWQsIHRlbXBsYXRlS2V5XSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBzdWJQYXRoLCBmdWxsUGF0aCwgaXNFeGlzdHMgfSA9IGF3YWl0IFNvbmFtdS5zeW5jZXIuY2hlY2tFeGlzdHNHZW5Db2RlKFxuICAgICAgICAgICAgICBlbnRpdHlJZCxcbiAgICAgICAgICAgICAgdGVtcGxhdGVLZXkgYXMgVGVtcGxhdGVLZXksXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgZW50aXR5SWQsXG4gICAgICAgICAgICAgIHRlbXBsYXRlS2V5LFxuICAgICAgICAgICAgICBzdWJQYXRoLFxuICAgICAgICAgICAgICBmdWxsUGF0aCxcbiAgICAgICAgICAgICAgaXNFeGlzdHMsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4geyBzdGF0dXNlcyB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgICB0ZW1wbGF0ZUtleTogc3RyaW5nO1xuICAgICAgICAgICAgZW51bUlkPzogc3RyaW5nO1xuICAgICAgICAgICAgb3ZlcndyaXRlPzogYm9vbGVhbjtcbiAgICAgICAgICB9W107XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvc2NhZmZvbGRpbmcvZ2VuZXJhdGVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBvcHRpb25zIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgIGlmIChvcHRpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLm9wdGlvbnNSZXF1aXJlZFwiKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyAxLiDrqqjrk6Ag7YWc7ZSM66a/7JeQ7IScIO2VhOyalO2VnCBkaWN0IO2CpOulvCDsiJjsp5FcbiAgICAgICAgY29uc3Qga2V5cyA9IG9wdGlvbnMuZmxhdE1hcCgoeyB0ZW1wbGF0ZUtleSB9KSA9PiB7XG4gICAgICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZU1hbmFnZXIuZ2V0KHRlbXBsYXRlS2V5KTtcbiAgICAgICAgICByZXR1cm4gdGVtcGxhdGUuZ2V0UmVxdWlyZWREaWN0S2V5cygpID8/IFtdO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyAyLiB0YXJnZXTrs4TroZwgZW5zdXJlRGljdEtleXMg7Zi47LacICjsiJzssKgg7LKY66asKVxuICAgICAgICBhd2FpdCBzb25hbXVEaWN0aW9uYXJ5LmVuc3VyZURpY3RLZXlzKFsuLi5uZXcgU2V0KGtleXMpXSk7XG5cbiAgICAgICAgLy8gMy4g7YWc7ZSM66a/IOyDneyEsSAo67OR66CsIOyymOumrClcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgb3B0aW9ucy5tYXAoYXN5bmMgKHsgZW50aXR5SWQsIHRlbXBsYXRlS2V5LCBlbnVtSWQsIG92ZXJ3cml0ZSB9KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgU29uYW11LnN5bmNlci5nZW5lcmF0ZVRlbXBsYXRlKFxuICAgICAgICAgICAgICAgIHRlbXBsYXRlS2V5IGFzIFRlbXBsYXRlS2V5LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGVudGl0eUlkLFxuICAgICAgICAgICAgICAgICAgZW51bUlkLFxuICAgICAgICAgICAgICAgIH0gYXMge1xuICAgICAgICAgICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICAgICAgICAgIGVudW1JZD86IHN0cmluZztcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIG92ZXJ3cml0ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICBpZiAoaXNTb0V4Y2VwdGlvbihlKSAmJiBlLnN0YXR1c0NvZGUgPT09IDU0MSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChyZXN1bHQuZmlsdGVyKG5vbk51bGxhYmxlKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgU2VydmljZVVuYXZhaWxhYmxlRXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLmFsbEZpbGVzR2VuZXJhdGVkXCIpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIG9wdGlvbjoge1xuICAgICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICAgIHRlbXBsYXRlS2V5OiBzdHJpbmc7XG4gICAgICAgICAgICBlbnVtSWQ/OiBzdHJpbmc7XG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zY2FmZm9sZGluZy9wcmV2aWV3XCIsIGFzeW5jIChyZXF1ZXN0KTogUHJvbWlzZTx7IHBhdGhBbmRDb2RlczogUGF0aEFuZENvZGVbXSB9PiA9PiB7XG4gICAgICAgIGNvbnN0IHsgb3B0aW9uIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB7IHRlbXBsYXRlS2V5LCAuLi50ZW1wbGF0ZU9wdGlvbnMgfSA9IG9wdGlvbjtcbiAgICAgICAgICBjb25zdCBwYXRoQW5kQ29kZXMgPSBhd2FpdCBTb25hbXUuc3luY2VyLnJlbmRlclRlbXBsYXRlKFxuICAgICAgICAgICAgdGVtcGxhdGVLZXkgYXMgVGVtcGxhdGVLZXksXG4gICAgICAgICAgICB0ZW1wbGF0ZU9wdGlvbnMsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHJldHVybiB7IHBhdGhBbmRDb2RlcyB9O1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3QoXCIvYXBpL2ZpeHR1cmVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBzb3VyY2VEQiwgdGFyZ2V0REIsIHNlYXJjaCwgZHVwbGljYXRlQ2hlY2sgfSA9IHJlcXVlc3QuYm9keSBhcyB7XG4gICAgICAgICAgc291cmNlREI6IGtleW9mIFNvbmFtdURCQ29uZmlnO1xuICAgICAgICAgIHRhcmdldERCOiBrZXlvZiBTb25hbXVEQkNvbmZpZztcbiAgICAgICAgICBzZWFyY2g6IEZpeHR1cmVTZWFyY2hPcHRpb25zO1xuICAgICAgICAgIGR1cGxpY2F0ZUNoZWNrPzogRHVwbGljYXRlQ2hlY2tPcHRpb25zO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBGaXh0dXJlTWFuYWdlci5nZXRGaXh0dXJlcyhzb3VyY2VEQiwgdGFyZ2V0REIsIHNlYXJjaCwgZHVwbGljYXRlQ2hlY2spO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0KFwiL2FwaS9maXh0dXJlL2ltcG9ydFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IGRiLCBmaXh0dXJlcyB9ID0gcmVxdWVzdC5ib2R5IGFzIHtcbiAgICAgICAgICBkYjoga2V5b2YgU29uYW11REJDb25maWc7XG4gICAgICAgICAgZml4dHVyZXM6IEZpeHR1cmVSZWNvcmRbXTtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gRml4dHVyZU1hbmFnZXIuaW5zZXJ0Rml4dHVyZXMoZGIsIGZpeHR1cmVzKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdChcIi9hcGkvZml4dHVyZS9hZGRGaXh0dXJlTG9hZGVyXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgY29kZSB9ID0gcmVxdWVzdC5ib2R5IGFzIHsgY29kZTogc3RyaW5nIH07XG5cbiAgICAgICAgcmV0dXJuIEZpeHR1cmVNYW5hZ2VyLmFkZEZpeHR1cmVMb2FkZXIoY29kZSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldChcIi9hcGkvaTE4bi9kaWN0aW9uYXJ5XCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHNvbmFtdURpY3Rpb25hcnkuZ2V0RGljdGlvbmFyeSgpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2kxOG4vZXhwb3J0XCIsIGFzeW5jIChfcmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBmaWxlbmFtZSwgYnVmZmVyIH0gPSBhd2FpdCBzb25hbXVEaWN0aW9uYXJ5LmV4cG9ydFRvRXhjZWwoKTtcbiAgICAgICAgcmVwbHlcbiAgICAgICAgICAuaGVhZGVyKFxuICAgICAgICAgICAgXCJDb250ZW50LVR5cGVcIixcbiAgICAgICAgICAgIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuc2hlZXRcIixcbiAgICAgICAgICApXG4gICAgICAgICAgLmhlYWRlcihcIkNvbnRlbnQtRGlzcG9zaXRpb25cIiwgYGF0dGFjaG1lbnQ7IGZpbGVuYW1lPVwiJHtmaWxlbmFtZX1cImApXG4gICAgICAgICAgLnNlbmQoYnVmZmVyKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdChcIi9hcGkvaTE4bi9pbXBvcnRcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcXVlc3QuZmlsZSgpO1xuICAgICAgICBpZiAoIWRhdGEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5maWxlTm90VXBsb2FkZWRcIikpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IGF3YWl0IGRhdGEudG9CdWZmZXIoKTtcbiAgICAgICAgcmV0dXJuIHNvbmFtdURpY3Rpb25hcnkuaW1wb3J0RnJvbUV4Y2VsKGJ1ZmZlcik7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgb2xkS2V5OiBzdHJpbmc7XG4gICAgICAgICAgbmV3S2V5OiBzdHJpbmc7XG4gICAgICAgICAgc291cmNlOiBcImVudGl0eVwiIHwgXCJwcm9qZWN0XCIgfCBcInNvbmFtdVwiO1xuICAgICAgICAgIHZhbHVlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9pMThuL3VwZGF0ZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBhd2FpdCBzb25hbXVEaWN0aW9uYXJ5LnVwZGF0ZUVudHJ5KHJlcXVlc3QuYm9keSk7XG4gICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBrZXk6IHN0cmluZztcbiAgICAgICAgICB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvaTE4bi9jcmVhdGVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgYXdhaXQgc29uYW11RGljdGlvbmFyeS5jcmVhdGVFbnRyeShyZXF1ZXN0LmJvZHkpO1xuICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAga2V5OiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvaTE4bi9kZWxldGVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgYXdhaXQgc29uYW11RGljdGlvbmFyeS5kZWxldGVFbnRyeShyZXF1ZXN0LmJvZHkua2V5KTtcbiAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHsgQm9keTogeyBrZXlzOiBzdHJpbmdbXSB9IH0+KFwiL2FwaS9pMThuL2NoZWNrVXNhZ2VcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIHNvbmFtdURpY3Rpb25hcnkuY2hlY2tVc2FnZShyZXF1ZXN0LmJvZHkua2V5cyk7XG4gICAgICB9KTtcblxuICAgICAgLy8gVGFza3MgQVBJXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS90YXNrcy9zdGF0dXNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIFNvbmFtdS53b3JrZmxvd3M7XG4gICAgICAgICAgcmV0dXJuIHsgYWN0aXZlOiB0cnVlIH07XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIHJldHVybiB7IGFjdGl2ZTogZmFsc2UgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL3Rhc2tzL3dvcmtmbG93RGVmaW5pdGlvbnNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBkZWZpbml0aW9ucyA9IFNvbmFtdS53b3JrZmxvd3Mud29ya2Zsb3dEZWZpbml0aW9ucztcbiAgICAgICAgcmV0dXJuIHsgZGVmaW5pdGlvbnMgfTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0PHtcbiAgICAgICAgUXVlcnlzdHJpbmc6IHtcbiAgICAgICAgICBsaW1pdD86IHN0cmluZztcbiAgICAgICAgICBhZnRlcj86IHN0cmluZztcbiAgICAgICAgICBiZWZvcmU/OiBzdHJpbmc7XG4gICAgICAgICAgb3JkZXI/OiBcImFzY1wiIHwgXCJkZXNjXCI7XG4gICAgICAgICAgc3RhdHVzPzogc3RyaW5nO1xuICAgICAgICAgIHdvcmtmbG93TmFtZT86IHN0cmluZztcbiAgICAgICAgICBjcmVhdGVkQWZ0ZXI/OiBzdHJpbmc7XG4gICAgICAgICAgY3JlYXRlZEJlZm9yZT86IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS90YXNrcy93b3JrZmxvd1J1bnNcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgYmFja2VuZCA9IFNvbmFtdS53b3JrZmxvd3MuYmFja2VuZDtcbiAgICAgICAgY29uc3QgeyBsaW1pdCwgYWZ0ZXIsIGJlZm9yZSwgb3JkZXIsIHN0YXR1cywgd29ya2Zsb3dOYW1lLCBjcmVhdGVkQWZ0ZXIsIGNyZWF0ZWRCZWZvcmUgfSA9XG4gICAgICAgICAgcmVxdWVzdC5xdWVyeTtcbiAgICAgICAgcmV0dXJuIGJhY2tlbmQubGlzdFdvcmtmbG93UnVucyh7XG4gICAgICAgICAgbGltaXQ6IGxpbWl0ID8gTnVtYmVyLnBhcnNlSW50KGxpbWl0LCAxMCkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgYWZ0ZXIsXG4gICAgICAgICAgYmVmb3JlLFxuICAgICAgICAgIG9yZGVyLFxuICAgICAgICAgIHN0YXR1czogc3RhdHVzID8gc3RhdHVzLnNwbGl0KFwiLFwiKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICB3b3JrZmxvd05hbWU6IHdvcmtmbG93TmFtZSB8fCB1bmRlZmluZWQsXG4gICAgICAgICAgY3JlYXRlZEFmdGVyOiBjcmVhdGVkQWZ0ZXIgPyBuZXcgRGF0ZShjcmVhdGVkQWZ0ZXIpIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGNyZWF0ZWRCZWZvcmU6IGNyZWF0ZWRCZWZvcmUgPyBuZXcgRGF0ZShjcmVhdGVkQmVmb3JlKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFBhcmFtczogeyBpZDogc3RyaW5nIH07XG4gICAgICB9PihcIi9hcGkvdGFza3Mvd29ya2Zsb3dSdW5zLzppZFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCBiYWNrZW5kID0gU29uYW11LndvcmtmbG93cy5iYWNrZW5kO1xuICAgICAgICBjb25zdCB3b3JrZmxvd1J1biA9IGF3YWl0IGJhY2tlbmQuZ2V0V29ya2Zsb3dSdW4oe1xuICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJlcXVlc3QucGFyYW1zLmlkLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCF3b3JrZmxvd1J1bikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgV29ya2Zsb3cgcnVuIG5vdCBmb3VuZDogJHtyZXF1ZXN0LnBhcmFtcy5pZH1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gd29ya2Zsb3dSdW47XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgfT4oXCIvYXBpL3Rhc2tzL3dvcmtmbG93UnVucy86aWQvY2FuY2VsXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IGJhY2tlbmQgPSBTb25hbXUud29ya2Zsb3dzLmJhY2tlbmQ7XG4gICAgICAgIHJldHVybiBiYWNrZW5kLmNhbmNlbFdvcmtmbG93UnVuKHtcbiAgICAgICAgICB3b3JrZmxvd1J1bklkOiByZXF1ZXN0LnBhcmFtcy5pZCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgfT4oXCIvYXBpL3Rhc2tzL3dvcmtmbG93UnVucy86aWQvcGF1c2VcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgYmFja2VuZCA9IFNvbmFtdS53b3JrZmxvd3MuYmFja2VuZDtcbiAgICAgICAgcmV0dXJuIGJhY2tlbmQucGF1c2VXb3JrZmxvd1J1bih7XG4gICAgICAgICAgd29ya2Zsb3dSdW5JZDogcmVxdWVzdC5wYXJhbXMuaWQsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgUGFyYW1zOiB7IGlkOiBzdHJpbmcgfTtcbiAgICAgIH0+KFwiL2FwaS90YXNrcy93b3JrZmxvd1J1bnMvOmlkL3Jlc3VtZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCBiYWNrZW5kID0gU29uYW11LndvcmtmbG93cy5iYWNrZW5kO1xuICAgICAgICByZXR1cm4gYmFja2VuZC5yZXN1bWVXb3JrZmxvd1J1bih7XG4gICAgICAgICAgd29ya2Zsb3dSdW5JZDogcmVxdWVzdC5wYXJhbXMuaWQsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgICBRdWVyeXN0cmluZzoge1xuICAgICAgICAgIGxpbWl0Pzogc3RyaW5nO1xuICAgICAgICAgIGFmdGVyPzogc3RyaW5nO1xuICAgICAgICAgIGJlZm9yZT86IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS90YXNrcy93b3JrZmxvd1J1bnMvOmlkL3N0ZXBzXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IGJhY2tlbmQgPSBTb25hbXUud29ya2Zsb3dzLmJhY2tlbmQ7XG4gICAgICAgIGNvbnN0IHsgbGltaXQsIGFmdGVyLCBiZWZvcmUgfSA9IHJlcXVlc3QucXVlcnk7XG4gICAgICAgIHJldHVybiBiYWNrZW5kLmxpc3RTdGVwQXR0ZW1wdHMoe1xuICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJlcXVlc3QucGFyYW1zLmlkLFxuICAgICAgICAgIGxpbWl0OiBsaW1pdCA/IE51bWJlci5wYXJzZUludChsaW1pdCwgMTApIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGFmdGVyLFxuICAgICAgICAgIGJlZm9yZSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgLyoqXG4gICAgICAgKiBIZWFsdGggQ2hlY2sgQVBJXG4gICAgICAgKiBNQ1Ag64+E6rWs6rCAIFNvbmFtdSDshJzrsoTrpbwg7J6Q64+ZIOqwkOyngO2VmOq4sCDsnITtlZwg7JeU65Oc7Y+s7J247Yq4XG4gICAgICAgKi9cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL3NvbmFtdS9oZWFsdGhcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgYWRkcmVzcyA9IHJlcXVlc3Quc2VydmVyLnNlcnZlci5hZGRyZXNzKCk7XG4gICAgICAgIGNvbnN0IHBvcnQgPSBhZGRyZXNzICYmIHR5cGVvZiBhZGRyZXNzID09PSBcIm9iamVjdFwiID8gKGFkZHJlc3MgYXMgQWRkcmVzc0luZm8pLnBvcnQgOiAwO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgb2s6IHRydWUsXG4gICAgICAgICAgcHJvamVjdDogcHJvY2Vzcy5jd2QoKS5zcGxpdChcIi9cIikucG9wKCkgfHwgXCJ1bmtub3duXCIsXG4gICAgICAgICAgcG9ydCxcbiAgICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuXG4gICAgICAvKipcbiAgICAgICAqIEZpeHR1cmUg7IOd7ISxIEFQSVxuICAgICAgICovXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHk6IHN0cmluZztcbiAgICAgICAgICBjb3VudD86IG51bWJlcjtcbiAgICAgICAgICBvdmVycmlkZXM/OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICAgICAgICB0YXJnZXREYj86IFwiZml4dHVyZVwiIHwgXCJ0ZXN0XCI7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvc29uYW11L2ZpeHR1cmUvZ2VuZXJhdGVcIiwgYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5LCBjb3VudCA9IDEsIG92ZXJyaWRlcywgdGFyZ2V0RGIgPSBcImZpeHR1cmVcIiB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgIC8vIO2DgOqynyBEQiDshKTsoJUg6rCA7KC47Jik6riwXG4gICAgICAgIGNvbnN0IGRiQ29uZmlnID0gdGFyZ2V0RGIgPT09IFwiZml4dHVyZVwiID8gU29uYW11LmRiQ29uZmlnLmZpeHR1cmUgOiBTb25hbXUuZGJDb25maWcudGVzdDtcblxuICAgICAgICAvLyBLbmV4IOyduOyKpO2EtOyKpCDsg53shLFcbiAgICAgICAgY29uc3QgZGIgPSBjcmVhdGVLbmV4SW5zdGFuY2UoZGJDb25maWcpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gRml4dHVyZUdlbmVyYXRvciDsg53shLFcbiAgICAgICAgICBjb25zdCBnZW5lcmF0b3IgPSBuZXcgRml4dHVyZUdlbmVyYXRvcihkYiwgZGIsIHRhcmdldERiLCBFbnRpdHlNYW5hZ2VyKTtcblxuICAgICAgICAgIC8vIOuLqOydvCBFbnRpdHkg67Cw7LmYIOyDneyEsVxuICAgICAgICAgIGNvbnN0IGZpeHR1cmVzID0gYXdhaXQgZ2VuZXJhdG9yLmdlbmVyYXRlQmF0Y2goW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBlbnRpdHksXG4gICAgICAgICAgICAgIGNvdW50LFxuICAgICAgICAgICAgICBvdmVycmlkZXM6IG92ZXJyaWRlcyA/PyB7fSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgIGVudGl0eSxcbiAgICAgICAgICAgIGNvdW50OiBmaXh0dXJlcy5sZW5ndGgsXG4gICAgICAgICAgICBmaXh0dXJlcyxcbiAgICAgICAgICAgIHRhcmdldERiLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgcmVwbHkuc3RhdHVzKDQwMCk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IGRiLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8qKlxuICAgICAgICogRml4dHVyZSDrjbDsnbTthLAg7YOQ7IOJIEFQSVxuICAgICAgICovXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHk6IHN0cmluZztcbiAgICAgICAgICBzdHJhdGVneTogXCJzYW1wbGVcIiB8IFwicmVjZW50XCIgfCBcInJhbmRvbVwiIHwgXCJxdWVyeVwiO1xuICAgICAgICAgIGxpbWl0PzogbnVtYmVyO1xuICAgICAgICAgIHdoZXJlPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvc29uYW11L2ZpeHR1cmUvZXhwbG9yZVwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBlbnRpdHksIHN0cmF0ZWd5LCBsaW1pdCA9IDEwLCB3aGVyZSB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgIC8vIEZpeHR1cmUgREIg7ISk7KCVIOqwgOyguOyYpOq4sFxuICAgICAgICBjb25zdCBmaXh0dXJlRGJDb25maWcgPSBTb25hbXUuZGJDb25maWcuZml4dHVyZTtcblxuICAgICAgICAvLyBLbmV4IOyduOyKpO2EtOyKpCDsg53shLFcbiAgICAgICAgY29uc3QgZml4dHVyZURiID0gY3JlYXRlS25leEluc3RhbmNlKGZpeHR1cmVEYkNvbmZpZyk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBEYXRhRXhwbG9yZXIg7IOd7ISxXG4gICAgICAgICAgY29uc3QgZXhwbG9yZXIgPSBuZXcgRGF0YUV4cGxvcmVyKGZpeHR1cmVEYiwgRW50aXR5TWFuYWdlcik7XG5cbiAgICAgICAgICBjb25zdCBkYXRhID0gYXdhaXQgZXhwbG9yZXIuZXhwbG9yZShlbnRpdHksIHtcbiAgICAgICAgICAgIHN0cmF0ZWd5LFxuICAgICAgICAgICAgbGltaXQsXG4gICAgICAgICAgICB3aGVyZSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBjb3VudDogZGF0YS5sZW5ndGgsXG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgcmVwbHkuc3RhdHVzKDQwMCk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgZXJyb3I6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogU3RyaW5nKGVycm9yKSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IGZpeHR1cmVEYi5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvKipcbiAgICAgICAqIEZpeHR1cmUg642w7J207YSwIOqwgOyguOyYpOq4sCAoZmV0Y2gpIEFQSVxuICAgICAgICogcHJvZHVjdGlvbi9kZXZlbG9wbWVudCBEQuyXkOyEnCDsi6TsoJwg642w7J207YSw66W8IGZpeHR1cmUgRELroZwgaW1wb3J0XG4gICAgICAgKi9cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eTogc3RyaW5nO1xuICAgICAgICAgIHN0cmF0ZWd5PzogXCJzYW1wbGVcIiB8IFwicmVjZW50XCIgfCBcInJhbmRvbVwiIHwgXCJxdWVyeVwiO1xuICAgICAgICAgIGxpbWl0PzogbnVtYmVyO1xuICAgICAgICAgIGluY2x1ZGVSZWxhdGlvbnM/OiBib29sZWFuO1xuICAgICAgICAgIG1heERlcHRoPzogbnVtYmVyO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3NvbmFtdS9maXh0dXJlL2ZldGNoXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgZW50aXR5LFxuICAgICAgICAgIHN0cmF0ZWd5ID0gXCJyZWNlbnRcIixcbiAgICAgICAgICBsaW1pdCA9IDEwLFxuICAgICAgICAgIGluY2x1ZGVSZWxhdGlvbnMgPSB0cnVlLFxuICAgICAgICAgIG1heERlcHRoID0gMixcbiAgICAgICAgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAvLyBTb3VyY2UgREIgKHByb2R1Y3Rpb24vZGV2ZWxvcG1lbnQpIC0g7J296riwIOyghOyaqVxuICAgICAgICBjb25zdCBzb3VyY2VEYiA9IERCLmdldERCKFwiclwiKTtcblxuICAgICAgICAvLyBUYXJnZXQgREIgKGZpeHR1cmUpXG4gICAgICAgIGNvbnN0IGZpeHR1cmVEYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWcuZml4dHVyZSk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyBGaXh0dXJlR2VuZXJhdG9yIOyDneyEsVxuICAgICAgICAgIGNvbnN0IGdlbmVyYXRvciA9IG5ldyBGaXh0dXJlR2VuZXJhdG9yKHNvdXJjZURiLCBmaXh0dXJlRGIsIFwiZml4dHVyZVwiLCBFbnRpdHlNYW5hZ2VyKTtcblxuICAgICAgICAgIC8vIHByb2R1Y3Rpb24g642w7J207YSw66W8IGZpeHR1cmUgRELroZwgaW1wb3J0XG4gICAgICAgICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IGdlbmVyYXRvci5pbXBvcnRGcm9tU291cmNlKGVudGl0eSwge1xuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBsaW1pdCxcbiAgICAgICAgICAgIGluY2x1ZGVSZWxhdGlvbnMsXG4gICAgICAgICAgICBtYXhEZXB0aCxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgc3RyYXRlZ3ksXG4gICAgICAgICAgICBjb3VudDogcmVzdWx0cy5sZW5ndGgsXG4gICAgICAgICAgICBpbXBvcnRlZDogcmVzdWx0cyxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDApO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICAvLyBzb3VyY2VEYuuKlCBTb25hbXXqsIAg6rSA66as7ZWY66+A66GcIGRlc3Ryb3ntlZjsp4Ag7JWK7J2MXG4gICAgICAgICAgYXdhaXQgZml4dHVyZURiLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8qKlxuICAgICAgICogRml4dHVyZSDrjbDsnbTthLAg7IKt7KCcIChjbGVhbikgQVBJXG4gICAgICAgKiBGSyDsiJzshJzrpbwg6rOg66Ck7ZWY7JesIOyViOyghO2VmOqyjCDsgq3soJxcbiAgICAgICAqL1xuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXRpZXM/OiBzdHJpbmdbXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zb25hbXUvZml4dHVyZS9jbGVhblwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBlbnRpdGllcyB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgIC8vIEZpeHR1cmUgREIg7Jew6rKwXG4gICAgICAgIGNvbnN0IGZpeHR1cmVEYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShTb25hbXUuZGJDb25maWcuZml4dHVyZSk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAvLyDsgq3soJztlaAgRW50aXR5IOuqqeuhnSDqsrDsoJVcbiAgICAgICAgICBjb25zdCB0YXJnZXRFbnRpdGllcyA9XG4gICAgICAgICAgICBlbnRpdGllcyAmJiBlbnRpdGllcy5sZW5ndGggPiAwID8gZW50aXRpZXMgOiBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuXG4gICAgICAgICAgLy8gRW50aXR5IElE66W8IO2FjOydtOu4lOuqheycvOuhnCDrs4DtmZggKHNuYWtlX2Nhc2Ug67O17IiY7ZiVKVxuICAgICAgICAgIGNvbnN0IHRhYmxlTmFtZXMgPSB0YXJnZXRFbnRpdGllcy5tYXAoKGVudGl0eUlkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICByZXR1cm4gZW50aXR5LnRhYmxlO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gUG9zdGdyZVNRTDogVFJVTkNBVEUgQ0FTQ0FEReuhnCBGSyDsiJzshJwg66y06rSA7ZWY6rKMIOyViOyghO2VmOqyjCDsgq3soJxcbiAgICAgICAgICAvLyBDQVNDQURFIOyYteyFmOycvOuhnCDsnZjsobTshLEg7J6I64qUIOuNsOydtO2EsOuPhCDtlajqu5gg7IKt7KCcXG4gICAgICAgICAgYXdhaXQgZml4dHVyZURiLnJhdyhcbiAgICAgICAgICAgIGBUUlVOQ0FURSBUQUJMRSAke3RhYmxlTmFtZXMubWFwKCh0KSA9PiBgXCIke3R9XCJgKS5qb2luKFwiLCBcIil9IFJFU1RBUlQgSURFTlRJVFkgQ0FTQ0FERWAsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgICAgY2xlYW5lZDogdGFibGVOYW1lcyxcbiAgICAgICAgICAgIGNvdW50OiB0YWJsZU5hbWVzLmxlbmd0aCxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDApO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBhd2FpdCBmaXh0dXJlRGIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gQ0REIEFQSVxuICAgICAgc2VydmVyLmdldChcIi9hcGkvY2RkL2Rhc2hib2FyZFwiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHJldHVybiBnZXREYXNoYm9hcmQoKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS9jZGQvdHJlZVwiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHJldHVybiBnZXRDZGRUcmVlKCk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8eyBCb2R5OiB7IGZpbGVQYXRoOiBzdHJpbmcgfSB9PihcIi9hcGkvY2RkL3JlYWRDb250ZW50XCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZmlsZVBhdGggfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgcmV0dXJuIHJlYWRDb250ZW50KGZpbGVQYXRoKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7IEJvZHk6IHsgZmlsZVBhdGg6IHN0cmluZyB9IH0+KFwiL2FwaS9jZGQvZWRpdENvbnRlbnRcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBmaWxlUGF0aCB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICByZXR1cm4gZWRpdENvbnRlbnQoZmlsZVBhdGgpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHsgQm9keTogeyBmaWxlUGF0aDogc3RyaW5nIH0gfT4oXCIvYXBpL2NkZC9vcGVuU291cmNlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZmlsZVBhdGggfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgb3BlblNvdXJjZUZpbGUoZmlsZVBhdGgpO1xuICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG4gICAgICB9KTtcblxuICAgICAgLy8gQ0REIFNjaGVtYSBBUElcbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2NkZC9zY2hlbWFzXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcmV0dXJuIGxpc3RTY2hlbWFzKCk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8eyBCb2R5OiB7IHNjaGVtYUtleTogc3RyaW5nIH0gfT4oXCIvYXBpL2NkZC9yZWFkU2NoZW1hXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgc2NoZW1hS2V5IH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgIHJldHVybiByZWFkU2NoZW1hKHNjaGVtYUtleSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8eyBCb2R5OiB7IHNjaGVtYUtleTogc3RyaW5nIH0gfT4oXCIvYXBpL2NkZC9lZGl0U2NoZW1hXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgc2NoZW1hS2V5IH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgIHJldHVybiBlZGl0U2NoZW1hKHNjaGVtYUtleSk7XG4gICAgICB9KTtcblxuICAgICAgLy8gdWktd2ViIOu5jOuTnCDtjIzsnbwg7ISc67mZXG4gICAgICBjb25zdCB1aURpc3RQYXRoID0gcGF0aC5yZXNvbHZlKGltcG9ydC5tZXRhLmRpcm5hbWUsIFwiLi4vdWktd2ViXCIpO1xuXG4gICAgICAvLyDsoJXsoIEg7YyM7J28IOyEnOu5mTog66Oo7Yq4IO2PtOuNlCDsoITssrQgKGFzc2V0cywgc2V0dGluZy5zdmcg65OxKVxuICAgICAgc2VydmVyLnJlZ2lzdGVyKGF3YWl0IGltcG9ydChcIkBmYXN0aWZ5L3N0YXRpY1wiKSwge1xuICAgICAgICByb290OiB1aURpc3RQYXRoLFxuICAgICAgICBwcmVmaXg6IFwiL1wiLFxuICAgICAgICBkZWNvcmF0ZVJlcGx5OiBmYWxzZSxcbiAgICAgICAgd2lsZGNhcmQ6IGZhbHNlLFxuICAgICAgfSk7XG5cbiAgICAgIC8vIFNQQSBmYWxsYmFjayAtIOygleyggSDtjIzsnbzsnbQg7JeG64qUIOuqqOuToCDqsr3roZzripQgaW5kZXguaHRtbOuhnFxuICAgICAgc2VydmVyLmdldChcIipcIiwgYXN5bmMgKF9yZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICByZXBseS5oZWFkZXJzKHsgXCJDb250ZW50LXR5cGVcIjogXCJ0ZXh0L2h0bWxcIiB9KS5zZW5kKFxuICAgICAgICAgIGZzXG4gICAgICAgICAgICAucmVhZEZpbGVTeW5jKHBhdGgucmVzb2x2ZSh1aURpc3RQYXRoLCBcImluZGV4Lmh0bWxcIikpXG4gICAgICAgICAgICAudG9TdHJpbmcoKVxuICAgICAgICAgICAgLnJlcGxhY2UoXCJ7e3Byb2plY3ROYW1lfX1cIiwgU29uYW11LmNvbmZpZy5wcm9qZWN0TmFtZSA/PyBcIlVua25vd25Tb25hbXVQcm9qZWN0XCIpLFxuICAgICAgICApO1xuICAgICAgfSk7XG4gICAgfSxcbiAgICB7IHByZWZpeDogXCIvc29uYW11LXVpXCIgfSxcbiAgKTtcbn1cbiJdLCJuYW1lcyI6WyJleGVjU3luYyIsImZzIiwiaW5mbGVjdGlvbiIsInBhdGgiLCJyYW5nZSIsIlNvbmFtdSIsIkRCIiwiY3JlYXRlS25leEluc3RhbmNlIiwiU0QiLCJzb25hbXVEaWN0aW9uYXJ5IiwiRW50aXR5TWFuYWdlciIsIkJhZFJlcXVlc3RFeGNlcHRpb24iLCJpc1NvRXhjZXB0aW9uIiwiU2VydmljZVVuYXZhaWxhYmxlRXhjZXB0aW9uIiwiTWlncmF0b3IiLCJTbGFja0NvbmZpcm0iLCJUZW1wbGF0ZU1hbmFnZXIiLCJEYXRhRXhwbG9yZXIiLCJGaXh0dXJlR2VuZXJhdG9yIiwiRml4dHVyZU1hbmFnZXIiLCJCVUlMVF9JTl9UWVBFX0lEUyIsIlRlbXBsYXRlS2V5Iiwibm9uTnVsbGFibGUiLCJzZXRBaUFwaSIsImVkaXRDb250ZW50IiwiZWRpdFNjaGVtYSIsImdldENkZFRyZWUiLCJnZXREYXNoYm9hcmQiLCJsaXN0U2NoZW1hcyIsIm9wZW5Tb3VyY2VGaWxlIiwicmVhZENvbnRlbnQiLCJyZWFkU2NoZW1hIiwic29uYW11VUlBcGlQbHVnaW4iLCJmYXN0aWZ5IiwicmVnaXN0ZXIiLCJzZXJ2ZXIiLCJtaWdyYXRvciIsIndhaXRGb3JITVJDb21wbGV0ZWQiLCJmbiIsIndhaXRQcm9taXNlIiwiUHJvbWlzZSIsInJlc29sdmUiLCJoYW5kbGVyIiwiY2xlYXJUaW1lb3V0IiwidGltZW91dCIsInNldFRpbWVvdXQiLCJzeW5jZXIiLCJldmVudEVtaXR0ZXIiLCJvZmYiLCJvbmNlIiwicmVzdWx0IiwiZ2V0IiwiY29uZmlnIiwicmVxdWVzdCIsImVudGl0eUlkIiwicHJlc2V0IiwiYWJzUGF0aCIsInF1ZXJ5IiwidGFyZ2V0UGF0aCIsImVudGl0eSIsIm5hbWVzIiwiYXBpUm9vdFBhdGgiLCJmaWxlbmFtZSIsInBhcmVudEZzIiwib3JpZ2luIiwiZ2xvc3NhcnkiLCJNYXAiLCJnZXRBbGxJZHMiLCJ0aXRsZSIsInNldCIsInVuZGVyc2NvcmUiLCJpZCIsInBsdXJhbGl6ZSIsInByb3BzIiwiZm9yRWFjaCIsInByb3AiLCJoYXMiLCJuYW1lIiwiZGVzYyIsInJlcGxhY2UiLCJzdWdnZXN0ZWQiLCJ3b3JkcyIsInNwbGl0IiwiY29tYmluYXRpb25zIiwibGVuZ3RoIiwiZmxhdE1hcCIsImxlbiIsImlkeCIsInciLCJzbGljZSIsImpvaW4iLCJSRVBMQUNFRF9QUkVGSVgiLCJyZW1haW5BcnIiLCJjb21iIiwicmVtYWluU3RyIiwiaW5jbHVkZXMiLCJtYXAiLCJyIiwic3RhcnRzV2l0aCIsInRvVXBwZXJDYXNlIiwiZW50aXR5SWRzIiwiZmxhdHRlblN1YnNldFJvd3MiLCJzdWJzZXRSb3dzIiwic3Vic2V0Um93IiwiY2hpbGRyZW4iLCJzUm93IiwiZW50aXRpZXMiLCJhbGwiLCJnZXRTdWJzZXRSb3dzIiwic29ydCIsImEiLCJiIiwiYUlkIiwicGFyZW50SWQiLCJiSWQiLCJ1bmRlZmluZWQiLCJmaWx0ZXIiLCJyZWxvYWQiLCJhdXRvbG9hZFR5cGVzIiwidHlwZUlkcyIsInByb2plY3RUeXBlSWRzIiwiT2JqZWN0IiwiZW50cmllcyIsInR5cGVzIiwiX3R5cGVJZCIsInpvZFR5cGUiLCJfem9kIiwiZGVmIiwidHlwZSIsInR5cGVJZCIsIl96b2RUeXBlIiwiYnVpbHRJblR5cGVJZHMiLCJhbGxUeXBlSWRzIiwiZW51bUlkcyIsImtleXMiLCJlbnVtTGFiZWxzIiwicG9zdCIsImZvcm0iLCJib2R5IiwiY3JlYXRlRW50aXR5IiwiZGVsRW50aXR5IiwibmV3VmFsdWVzIiwidGFibGUiLCJzYXZlIiwic3Vic2V0S2V5IiwiZmllbGRzIiwiZmllbGRzSW50ZXJuYWwiLCJzdWJzZXRzIiwic3Vic2V0c0ludGVybmFsIiwidXBkYXRlZCIsInVwZGF0ZWRJbnRlcm5hbCIsImF0IiwibmV3UHJvcCIsImNyZWF0ZVByb3AiLCJtb2RpZnlQcm9wIiwiZGVsUHJvcCIsInRvIiwibW92ZVByb3AiLCJpbmRleGVzIiwibmV3RW51bUlkIiwiRXJyb3IiLCJlbmRzV2l0aCIsImFjdGl2ZSIsImhpZGRlbiIsImVudW1JZCIsImlzRXhpc3RzIiwic29tZSIsImFmdGVyIiwiYmVmb3JlIiwiaXNSZWZlcmVuY2VkIiwidGFyZ2V0IiwicHJvcE5hbWUiLCJjb25lIiwiZmluZCIsInAiLCJlbnVtQ29uZXMiLCJzdWJzZXRDb25lcyIsInJlcGx5IiwicHJlc2VydmVFeGlzdGluZyIsIm9ubHlFbXB0eSIsImxvY2FsZSIsImVmZmVjdGl2ZUxvY2FsZSIsImkxOG4iLCJkZWZhdWx0TG9jYWxlIiwiZ2VuZXJhdGVDb25lcyIsImVycm9yIiwibWVzc2FnZSIsIlN0cmluZyIsInN0YXR1cyIsInN1Y2Nlc3MiLCJjb2x1bW5zIiwiZ2V0VGFibGVDb2x1bW5zIiwiZ2V0U3RhdHVzIiwiYWN0aW9uIiwidGFyZ2V0cyIsImZvcmNlIiwiZm9yY2VSZWFzb24iLCJyZXF1ZXN0b3IiLCJydW5TaGFkb3dUZXN0Iiwic2xhY2tDb25maXJtIiwicmVxdWlyZXNBcHByb3ZhbCIsInQiLCJpc1RhcmdldFJlcXVpcmVzQXBwcm92YWwiLCJsb2NhbEhvc3RzIiwiaXNMb2NhbFRhcmdldCIsImV2ZXJ5IiwidGFyZ2V0Q29uZmlnIiwiZGJDb25maWciLCJob3N0IiwiY29ubmVjdGlvbiIsInRvTG93ZXJDYXNlIiwiaXNDb25maWd1cmVkIiwiY29ubnMiLCJwZW5kaW5nTWlncmF0aW9ucyIsIlNldCIsImNvbm4iLCJjb25uS2V5IiwicGVuZGluZyIsImV4aXN0aW5nIiwiZ2V0RXhpc3RpbmdSZXF1ZXN0IiwiYXBwcm92ZWQiLCJyZWplY3RlZCIsImNoZWNrQXBwcm92YWwiLCJjaGFubmVsIiwidHMiLCJydW5BY3Rpb24iLCJsb2dFeGVjdXRpb24iLCJmb3JjZUFwcHJvdmFsIiwicG9zdEFwcHJvdmFsUmVxdWVzdCIsInNhdmVSZXF1ZXN0IiwicmVhc29uIiwiY29kZU5hbWVzIiwiZGVsQ29kZXMiLCJfcmVxdWVzdHQiLCJnZW5lcmF0ZVByZXBhcmVkQ29kZXMiLCJ0ZW1wbGF0ZUtleXMiLCJfdGVtcGxhdGVLZXlzIiwib3B0aW9ucyIsInRrIiwidGVtcGxhdGVLZXkiLCJzdGF0dXNlcyIsInN1YlBhdGgiLCJmdWxsUGF0aCIsImNoZWNrRXhpc3RzR2VuQ29kZSIsInRlbXBsYXRlIiwiZ2V0UmVxdWlyZWREaWN0S2V5cyIsImVuc3VyZURpY3RLZXlzIiwib3ZlcndyaXRlIiwiZ2VuZXJhdGVUZW1wbGF0ZSIsImUiLCJzdGF0dXNDb2RlIiwiY29uc29sZSIsIm9wdGlvbiIsInRlbXBsYXRlT3B0aW9ucyIsInBhdGhBbmRDb2RlcyIsInJlbmRlclRlbXBsYXRlIiwic291cmNlREIiLCJ0YXJnZXREQiIsInNlYXJjaCIsImR1cGxpY2F0ZUNoZWNrIiwiZ2V0Rml4dHVyZXMiLCJkYiIsImZpeHR1cmVzIiwiaW5zZXJ0Rml4dHVyZXMiLCJjb2RlIiwiYWRkRml4dHVyZUxvYWRlciIsImdldERpY3Rpb25hcnkiLCJfcmVxdWVzdCIsImJ1ZmZlciIsImV4cG9ydFRvRXhjZWwiLCJoZWFkZXIiLCJzZW5kIiwiZGF0YSIsImZpbGUiLCJ0b0J1ZmZlciIsImltcG9ydEZyb21FeGNlbCIsInVwZGF0ZUVudHJ5IiwiY3JlYXRlRW50cnkiLCJkZWxldGVFbnRyeSIsImtleSIsImNoZWNrVXNhZ2UiLCJ3b3JrZmxvd3MiLCJkZWZpbml0aW9ucyIsIndvcmtmbG93RGVmaW5pdGlvbnMiLCJiYWNrZW5kIiwibGltaXQiLCJvcmRlciIsIndvcmtmbG93TmFtZSIsImNyZWF0ZWRBZnRlciIsImNyZWF0ZWRCZWZvcmUiLCJsaXN0V29ya2Zsb3dSdW5zIiwiTnVtYmVyIiwicGFyc2VJbnQiLCJEYXRlIiwid29ya2Zsb3dSdW4iLCJnZXRXb3JrZmxvd1J1biIsIndvcmtmbG93UnVuSWQiLCJwYXJhbXMiLCJjYW5jZWxXb3JrZmxvd1J1biIsInBhdXNlV29ya2Zsb3dSdW4iLCJyZXN1bWVXb3JrZmxvd1J1biIsImxpc3RTdGVwQXR0ZW1wdHMiLCJhZGRyZXNzIiwicG9ydCIsIm9rIiwicHJvamVjdCIsInByb2Nlc3MiLCJjd2QiLCJwb3AiLCJ0aW1lc3RhbXAiLCJ0b0lTT1N0cmluZyIsImNvdW50Iiwib3ZlcnJpZGVzIiwidGFyZ2V0RGIiLCJmaXh0dXJlIiwidGVzdCIsImdlbmVyYXRvciIsImdlbmVyYXRlQmF0Y2giLCJkZXN0cm95Iiwic3RyYXRlZ3kiLCJ3aGVyZSIsImZpeHR1cmVEYkNvbmZpZyIsImZpeHR1cmVEYiIsImV4cGxvcmVyIiwiZXhwbG9yZSIsImluY2x1ZGVSZWxhdGlvbnMiLCJtYXhEZXB0aCIsInNvdXJjZURiIiwiZ2V0REIiLCJyZXN1bHRzIiwiaW1wb3J0RnJvbVNvdXJjZSIsImltcG9ydGVkIiwidGFyZ2V0RW50aXRpZXMiLCJ0YWJsZU5hbWVzIiwicmF3IiwiY2xlYW5lZCIsImZpbGVQYXRoIiwic2NoZW1hS2V5IiwidWlEaXN0UGF0aCIsImRpcm5hbWUiLCJyb290IiwicHJlZml4IiwiZGVjb3JhdGVSZXBseSIsIndpbGRjYXJkIiwiaGVhZGVycyIsInJlYWRGaWxlU3luYyIsInRvU3RyaW5nIiwicHJvamVjdE5hbWUiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLFFBQVEsUUFBUSxnQkFBZ0I7QUFFekMsT0FBT0MsUUFBUSxLQUFLO0FBQ3BCLE9BQU9DLGdCQUFnQixhQUFhO0FBRXBDLE9BQU9DLFVBQVUsT0FBTztBQUN4QixTQUFTQyxLQUFLLFFBQVEsVUFBVTtBQUNoQyxTQUFTQyxNQUFNLFFBQVEsbUJBQWdCO0FBQ3ZDLFNBQVNDLEVBQUUsUUFBNkIsb0JBQWlCO0FBQ3pELFNBQVNDLGtCQUFrQixRQUFRLHNCQUFtQjtBQUN0RCxTQUFTQyxFQUFFLFFBQVEsZ0JBQWE7QUFDaEMsU0FBU0MsZ0JBQWdCLFFBQVEsK0JBQTRCO0FBRTdELFNBQVNDLGFBQWEsUUFBUSw4QkFBMkI7QUFDekQsU0FDRUMsbUJBQW1CLEVBQ25CQyxhQUFhLEVBQ2JDLDJCQUEyQixRQUN0QixpQ0FBOEI7QUFDckMsU0FBK0JDLFFBQVEsUUFBUSwyQkFBd0I7QUFDdkUsU0FBU0MsWUFBWSxRQUF3QyxnQ0FBNkI7QUFDMUYsU0FBU0MsZUFBZSxRQUFRLGtDQUErQjtBQUMvRCxTQUFTQyxZQUFZLFFBQVEsOEJBQTJCO0FBQ3hELFNBQVNDLGdCQUFnQixRQUFRLGtDQUErQjtBQUNoRSxTQUFxQ0MsY0FBYyxRQUFRLGdDQUE2QjtBQUN4RixTQUNFQyxpQkFBaUIsRUFTakJDLFdBQVcsUUFDTixvQkFBaUI7QUFDeEIsU0FBU0MsV0FBVyxRQUFRLG9CQUFpQjtBQUM3QyxTQUFTQyxRQUFRLFFBQVEsY0FBVztBQUNwQyxTQUNFQyxXQUFXLEVBQ1hDLFVBQVUsRUFDVkMsVUFBVSxFQUNWQyxZQUFZLEVBQ1pDLFdBQVcsRUFDWEMsY0FBYyxFQUNkQyxXQUFXLEVBQ1hDLFVBQVUsUUFDTCxtQkFBZ0I7QUFFdkIsT0FBTyxlQUFlQyxrQkFBa0JDLE9BQXdCO0lBQzlEQSxRQUFRQyxRQUFRLENBQ2QsT0FBT0M7UUFDTCxXQUFXO1FBQ1gsTUFBTUMsV0FBVyxJQUFJdEI7UUFFckIsc0JBQXNCO1FBQ3RCLGVBQWV1QixvQkFBdUJDLEVBQW9CO1lBQ3hELE1BQU1DLGNBQWMsSUFBSUMsUUFBYyxDQUFDQztnQkFDckMsTUFBTUMsVUFBVTtvQkFDZEMsYUFBYUM7b0JBQ2JIO2dCQUNGO2dCQUVBLE1BQU1HLFVBQVVDLFdBQVc7b0JBQ3pCeEMsT0FBT3lDLE1BQU0sQ0FBQ0MsWUFBWSxDQUFDQyxHQUFHLENBQUMsa0JBQWtCTjtvQkFDakREO2dCQUNGLEdBQUc7Z0JBRUhwQyxPQUFPeUMsTUFBTSxDQUFDQyxZQUFZLENBQUNFLElBQUksQ0FBQyxrQkFBa0JQO1lBQ3BEO1lBRUEsTUFBTVEsU0FBUyxNQUFNWjtZQUNyQixNQUFNQztZQUNOLE9BQU9XO1FBQ1Q7UUFFQSxNQUFNM0IsU0FBU1k7UUFFZkEsT0FBT2dCLEdBQUcsQ0FBQyxzQkFBc0I7WUFDL0IsT0FBTzlDLE9BQU8rQyxNQUFNO1FBQ3RCO1FBRUFqQixPQUFPZ0IsR0FBRyxDQU1QLHlCQUF5QixPQUFPRTtZQUNqQyxNQUFNLEVBQUVDLFFBQVEsRUFBRUMsTUFBTSxFQUFFQyxPQUFPLEVBQUUsR0FBR0gsUUFBUUksS0FBSztZQUVuRCxNQUFNQyxhQUFhLEFBQUMsQ0FBQTtnQkFDbEIsSUFBSUosWUFBWUMsUUFBUTtvQkFDdEIsTUFBTUksU0FBU2pELGNBQWN5QyxHQUFHLENBQUNHO29CQUNqQyxNQUFNLEVBQUVNLEtBQUssRUFBRSxHQUFHRDtvQkFFbEIsTUFBTSxFQUFFRSxXQUFXLEVBQUUsR0FBR3hEO29CQUN4QixNQUFNeUQsV0FBVyxBQUFDLENBQUE7d0JBQ2hCLE9BQVFQOzRCQUNOLEtBQUs7Z0NBQ0gsT0FBTyxHQUFHSyxNQUFNM0QsRUFBRSxDQUFDLFNBQVMsQ0FBQzs0QkFDL0IsS0FBSztnQ0FDSCxPQUFPLEdBQUcyRCxNQUFNM0QsRUFBRSxDQUFDLFlBQVksQ0FBQzs0QkFDbEMsS0FBSztnQ0FDSCxPQUFPLEdBQUcyRCxNQUFNM0QsRUFBRSxDQUFDLGFBQWEsQ0FBQzt3QkFDckM7b0JBQ0YsQ0FBQTtvQkFDQSxPQUFPLEdBQUc0RCxZQUFZLGlCQUFpQixFQUFFRixPQUFPQyxLQUFLLENBQUNHLFFBQVEsQ0FBQyxDQUFDLEVBQUVELFVBQVU7Z0JBQzlFLE9BQU87b0JBQ0wsSUFBSSxDQUFDTixTQUFTO3dCQUNaLE1BQU0sSUFBSTdDLG9CQUFvQkgsR0FBRztvQkFDbkM7b0JBQ0EsT0FBT2dEO2dCQUNUO1lBQ0YsQ0FBQTtZQUNBeEQsU0FBUyxDQUFDLEtBQUssRUFBRTBELFlBQVk7UUFDL0I7UUFFQXZCLE9BQU9nQixHQUFHLENBS1AsNEJBQTRCLE9BQU9FO1lBQ3BDLE1BQU0sRUFBRVcsTUFBTSxFQUFFVixRQUFRLEVBQUUsR0FBR0QsUUFBUUksS0FBSztZQUUxQyxTQUFTO1lBQ1QsTUFBTVEsV0FBVyxJQUFJQyxJQUFvQjtnQkFDdkM7b0JBQUM7b0JBQVU7aUJBQUs7Z0JBQ2hCO29CQUFDO29CQUFRO2lCQUFLO2dCQUNkO29CQUFDO29CQUFTO2lCQUFNO2dCQUNoQjtvQkFBQztvQkFBVTtpQkFBUztnQkFDcEI7b0JBQUM7b0JBQU87aUJBQU07Z0JBQ2Q7b0JBQUM7b0JBQU07aUJBQUs7Z0JBQ1o7b0JBQUM7b0JBQVEsQ0FBQyxXQUFXLENBQUM7aUJBQUM7Z0JBQ3ZCO29CQUFDO29CQUFTO2lCQUFjO2dCQUN4QjtvQkFBQztvQkFBVTtpQkFBZTtnQkFDMUI7b0JBQUM7b0JBQVE7aUJBQUs7Z0JBQ2Q7b0JBQUM7b0JBQU07aUJBQUs7Z0JBQ1o7b0JBQUM7b0JBQVc7aUJBQUs7Z0JBQ2pCO29CQUFDO29CQUFXO2lCQUFLO2dCQUNqQjtvQkFBQztvQkFBVztpQkFBSztnQkFDakI7b0JBQUM7b0JBQU07aUJBQUs7Z0JBQ1o7b0JBQUM7b0JBQVE7aUJBQUs7Z0JBQ2Q7b0JBQUM7b0JBQVE7aUJBQUs7Z0JBQ2Q7b0JBQUM7b0JBQU07aUJBQU87Z0JBQ2Q7b0JBQUM7b0JBQU07aUJBQU87Z0JBQ2Q7b0JBQUM7b0JBQU87aUJBQU07Z0JBQ2Q7b0JBQUM7b0JBQU87aUJBQVE7Z0JBQ2hCO29CQUFDO29CQUFTO2lCQUFLO2dCQUNmO29CQUFDO29CQUFRO2lCQUFLO2dCQUNkO29CQUFDO29CQUFLO2lCQUFNO2dCQUNaO29CQUFDO29CQUFLO2lCQUFNO2dCQUNaO29CQUFDO29CQUFXO2lCQUFLO2dCQUNqQjtvQkFBQztvQkFBUztpQkFBSztnQkFDZjtvQkFBQztvQkFBUztpQkFBSTtnQkFDZDtvQkFBQztvQkFBUztpQkFBTTtnQkFDaEI7b0JBQUM7b0JBQVM7aUJBQUs7Z0JBQ2Y7b0JBQUM7b0JBQVE7aUJBQU07Z0JBQ2Y7b0JBQUM7b0JBQU87aUJBQUs7Z0JBQ2I7b0JBQUM7b0JBQVM7aUJBQUs7Z0JBQ2Y7b0JBQUM7b0JBQVU7aUJBQU07Z0JBQ2pCO29CQUFDO29CQUFRO2lCQUFLO2dCQUNkO29CQUFDO29CQUFPO2lCQUFPO2dCQUNmO29CQUFDO29CQUFNO2lCQUFLO2dCQUNaO29CQUFDO29CQUFRO2lCQUFLO2dCQUNkO29CQUFDO29CQUFXO2lCQUFLO2dCQUNqQjtvQkFBQztvQkFBVztpQkFBTztnQkFDbkI7b0JBQUM7b0JBQVk7aUJBQU87Z0JBQ3BCO29CQUFDO29CQUFRO2lCQUFNO2dCQUNmO29CQUFDO29CQUFPO2lCQUFJO2dCQUNaO29CQUFDO29CQUFPO2lCQUFLO2dCQUNiO29CQUFDO29CQUFZO2lCQUFLO2dCQUNsQjtvQkFBQztvQkFBVTtpQkFBSzthQUNqQjtZQUNELDBDQUEwQztZQUMxQyxLQUFLLE1BQU1aLFlBQVk1QyxjQUFjeUQsU0FBUyxHQUFJO2dCQUNoRCxNQUFNUixTQUFTakQsY0FBY3lDLEdBQUcsQ0FBQ0c7Z0JBQ2pDLElBQUksQUFBQ0ssQ0FBQUEsT0FBT1MsS0FBSyxJQUFJLEVBQUMsTUFBTyxJQUFJO29CQUMvQkgsU0FBU0ksR0FBRyxDQUFDbkUsV0FBV29FLFVBQVUsQ0FBQ1gsT0FBT1ksRUFBRSxHQUFHWixPQUFPUyxLQUFLO29CQUMzREgsU0FBU0ksR0FBRyxDQUNWbkUsV0FBV29FLFVBQVUsQ0FBQ3BFLFdBQVdzRSxTQUFTLENBQUNiLE9BQU9ZLEVBQUUsSUFDcEQsR0FBR1osT0FBT1MsS0FBSyxDQUFDLEdBQUcsQ0FBQztnQkFFeEI7Z0JBRUFULE9BQU9jLEtBQUssQ0FBQ0MsT0FBTyxDQUFDLENBQUNDO29CQUNwQixJQUFJVixTQUFTVyxHQUFHLENBQUNELEtBQUtFLElBQUksR0FBRzt3QkFDM0I7b0JBQ0Y7b0JBQ0EsSUFBSUYsS0FBS0csSUFBSSxFQUFFO3dCQUNiYixTQUFTSSxHQUFHLENBQUNNLEtBQUtFLElBQUksRUFBRUYsS0FBS0csSUFBSSxDQUFDQyxPQUFPLENBQUNwQixPQUFPUyxLQUFLLElBQUksSUFBSTtvQkFDaEU7Z0JBQ0Y7WUFDRjtZQUVBLE1BQU1ZLFlBQVksQUFBQyxDQUFBO2dCQUNqQixtQkFBbUI7Z0JBQ25CLE1BQU1DLFFBQVFqQixPQUFPa0IsS0FBSyxDQUFDO2dCQUMzQixNQUFNQyxlQUFlO3VCQUFJL0UsTUFBTTZFLE1BQU1HLE1BQU0sRUFBRSxHQUFHLENBQUM7aUJBQUcsQ0FBQ0MsT0FBTyxDQUFDLENBQUNDO29CQUM1RCxPQUFPOzJCQUNGbEYsTUFBTSxHQUFHNkUsTUFBTUcsTUFBTSxHQUFHRSxNQUFNLEdBQUcsQ0FBQ0M7NEJBQ25DLE9BQU87Z0NBQ0xEO2dDQUNBRSxHQUFHUCxNQUFNUSxLQUFLLENBQUNGLEtBQUtBLE1BQU1ELEtBQUtJLElBQUksQ0FBQzs0QkFDdEM7d0JBQ0Y7cUJBQ0Q7Z0JBQ0g7Z0JBRUEsNkNBQTZDO2dCQUM3QyxNQUFNQyxrQkFBa0IsZUFBZSxzQ0FBc0M7Z0JBQzdFLElBQUlDLFlBQXNCO3VCQUFJWDtpQkFBTTtnQkFDcEMsS0FBSyxNQUFNWSxRQUFRVixhQUFjO29CQUMvQixNQUFNVyxZQUFZRixVQUFVRixJQUFJLENBQUM7b0JBQ2pDLElBQUlJLFVBQVVDLFFBQVEsQ0FBQ0YsS0FBS0wsQ0FBQyxLQUFLdkIsU0FBU1csR0FBRyxDQUFDaUIsS0FBS0wsQ0FBQyxHQUFHO3dCQUN0REksWUFBWUUsVUFDVGYsT0FBTyxDQUFDYyxLQUFLTCxDQUFDLEVBQUVHLGtCQUFrQjFCLFNBQVNkLEdBQUcsQ0FBQzBDLEtBQUtMLENBQUMsR0FDckROLEtBQUssQ0FBQztvQkFDWDtnQkFDRjtnQkFFQSxPQUFPVSxVQUNKSSxHQUFHLENBQUMsQ0FBQ0M7b0JBQ0osSUFBSUEsRUFBRUMsVUFBVSxDQUFDUCxrQkFBa0I7d0JBQ2pDLE9BQU9NLEVBQUVsQixPQUFPLENBQUNZLGlCQUFpQjtvQkFDcEMsT0FBTzt3QkFDTCxPQUFPTSxFQUFFRSxXQUFXO29CQUN0QjtnQkFDRixHQUNDVCxJQUFJLENBQUMsSUFDTFgsT0FBTyxDQUFDLGVBQWV6QixXQUFXNUMsY0FBY3lDLEdBQUcsQ0FBQ0csVUFBVWMsS0FBSyxHQUFHO1lBQzNFLENBQUE7WUFFQSxPQUFPO2dCQUFFWTtZQUFVO1FBQ3JCO1FBRUE3QyxPQUFPZ0IsR0FBRyxDQUFDLHdCQUF3QjtZQUNqQyxNQUFNaUQsWUFBWTFGLGNBQWN5RCxTQUFTO1lBRXpDLFNBQVNrQyxrQkFBa0JDLFVBQTZCO2dCQUN0RCxPQUFPQSxXQUFXakIsT0FBTyxDQUFDLENBQUNrQjtvQkFDekIsTUFBTSxFQUFFQyxRQUFRLEVBQUUsR0FBR0MsTUFBTSxHQUFHRjtvQkFDOUIsT0FBTzt3QkFBQ0U7MkJBQVNKLGtCQUFrQkc7cUJBQVU7Z0JBQy9DO1lBQ0Y7WUFFQSxNQUFNRSxXQUFXLE1BQU1sRSxRQUFRbUUsR0FBRyxDQUNoQ1AsVUFBVUosR0FBRyxDQUFDLENBQUMxQztnQkFDYixNQUFNSyxTQUFTakQsY0FBY3lDLEdBQUcsQ0FBQ0c7Z0JBQ2pDLE1BQU1nRCxhQUFhM0MsT0FBT2lELGFBQWE7Z0JBRXZDLE9BQU87b0JBQ0wsR0FBR2pELE1BQU07b0JBQ1QwQyxtQkFBbUJBLGtCQUFrQkM7Z0JBQ3ZDO1lBQ0Y7WUFHRkksU0FBU0csSUFBSSxDQUFDLENBQUNDLEdBQUdDO2dCQUNoQixNQUFNQyxNQUFNRixFQUFFRyxRQUFRLElBQUlILEVBQUV2QyxFQUFFO2dCQUM5QixNQUFNMkMsTUFBTUgsRUFBRUUsUUFBUSxJQUFJRixFQUFFeEMsRUFBRTtnQkFDOUIsSUFBSXlDLE1BQU1FLEtBQUssT0FBTyxDQUFDO2dCQUN2QixJQUFJRixNQUFNRSxLQUFLLE9BQU87Z0JBQ3RCLElBQUlGLFFBQVFFLEtBQUs7b0JBQ2YsSUFBSUosRUFBRUcsUUFBUSxLQUFLRSxXQUFXLE9BQU8sQ0FBQztvQkFDdEMsSUFBSUosRUFBRUUsUUFBUSxLQUFLRSxXQUFXLE9BQU87b0JBQ3JDLE9BQU87Z0JBQ1Q7Z0JBQ0EsT0FBTztZQUNUO1lBQ0EsT0FBTztnQkFBRVQ7WUFBUztRQUNwQjtRQUVBdkUsT0FBT2dCLEdBQUcsQ0FLUCx1QkFBdUIsT0FBT0U7WUFDL0IsTUFBTSxFQUFFK0QsTUFBTSxFQUFFQyxNQUFNLEVBQUUsR0FBR2hFLFFBQVFJLEtBQUs7WUFFeEMsSUFBSTRELFdBQVcsS0FBSztnQkFDbEIsTUFBTWhILE9BQU95QyxNQUFNLENBQUN3RSxhQUFhO1lBQ25DO1lBRUEsTUFBTUMsVUFBVSxBQUFDLENBQUE7Z0JBQ2YsaUJBQWlCO2dCQUNqQixNQUFNQyxpQkFBaUJDLE9BQU9DLE9BQU8sQ0FBQ3JILE9BQU95QyxNQUFNLENBQUM2RSxLQUFLLEVBQ3REUCxNQUFNLENBQUMsQ0FBQyxDQUFDUSxTQUFTQyxRQUFRLEdBQUssQUFBQ0EsUUFBUUMsSUFBSSxDQUFDQyxHQUFHLENBQUNDLElBQUksS0FBZ0IsUUFDckVoQyxHQUFHLENBQUMsQ0FBQyxDQUFDaUMsUUFBUUMsU0FBUyxHQUFLRDtnQkFFL0IsMEJBQTBCO2dCQUMxQixNQUFNRSxpQkFBaUI7dUJBQUkvRztpQkFBa0I7Z0JBRTdDLFdBQVc7Z0JBQ1gsTUFBTWdILGFBQWE7dUJBQUlEO3VCQUFtQlg7aUJBQWU7Z0JBRXpELElBQUlKLFdBQVcsU0FBUztvQkFDdEIsT0FBT2dCO2dCQUNUO2dCQUVBLE1BQU1DLFVBQVUzSCxjQUFjeUQsU0FBUyxHQUFHa0IsT0FBTyxDQUFDLENBQUMvQjtvQkFDakQsTUFBTUssU0FBU2pELGNBQWN5QyxHQUFHLENBQUNHO29CQUNqQyxPQUFPbUUsT0FBT2EsSUFBSSxDQUFDM0UsT0FBTzRFLFVBQVU7Z0JBQ3RDO2dCQUVBLElBQUluQixXQUFXLFNBQVM7b0JBQ3RCLE9BQU9pQjtnQkFDVCxPQUFPO29CQUNMLE9BQU87MkJBQUlEOzJCQUFlQztxQkFBUTtnQkFDcEM7WUFDRixDQUFBO1lBRUEsT0FBTztnQkFDTGQ7WUFDRjtRQUNGO1FBRUFwRixPQUFPcUcsSUFBSSxDQVNSLHNCQUFzQixPQUFPbkY7WUFDOUIsT0FBTyxNQUFNaEIsb0JBQW9CO2dCQUMvQixNQUFNLEVBQUVvRyxJQUFJLEVBQUUsR0FBR3BGLFFBQVFxRixJQUFJO2dCQUM3QixNQUFNckksT0FBT3lDLE1BQU0sQ0FBQzZGLFlBQVksQ0FBQztvQkFBRSxHQUFHRixJQUFJO29CQUFFbkYsVUFBVW1GLEtBQUtsRSxFQUFFO2dCQUFDO2dCQUU5RCxPQUFPO1lBQ1Q7UUFDRjtRQUVBcEMsT0FBT3FHLElBQUksQ0FJUixtQkFBbUIsT0FBT25GO1lBQzNCLE9BQU8sTUFBTWhCLG9CQUFvQjtnQkFDL0IsTUFBTSxFQUFFaUIsUUFBUSxFQUFFLEdBQUdELFFBQVFxRixJQUFJO2dCQUNqQyxPQUFPLE1BQU1ySSxPQUFPeUMsTUFBTSxDQUFDOEYsU0FBUyxDQUFDdEY7WUFDdkM7UUFDRjtRQUVBbkIsT0FBT3FHLElBQUksQ0FTUixnQ0FBZ0MsT0FBT25GO1lBQ3hDLE9BQU8sTUFBTWhCLG9CQUFvQjtnQkFDL0IsTUFBTSxFQUFFaUIsUUFBUSxFQUFFdUYsU0FBUyxFQUFFLEdBQUd4RixRQUFRcUYsSUFBSTtnQkFDNUMsTUFBTS9FLFNBQVNqRCxjQUFjeUMsR0FBRyxDQUFDRztnQkFDakNLLE9BQU9TLEtBQUssR0FBR3lFLFVBQVV6RSxLQUFLO2dCQUM5QlQsT0FBT21GLEtBQUssR0FBR0QsVUFBVUMsS0FBSztnQkFDOUJuRixPQUFPc0QsUUFBUSxHQUFHNEIsVUFBVTVCLFFBQVE7Z0JBQ3BDLE1BQU10RCxPQUFPb0YsSUFBSTtnQkFFakIsT0FBTztZQUNUO1FBQ0Y7UUFFQTVHLE9BQU9xRyxJQUFJLENBT1IsNEJBQTRCLE9BQU9uRjtZQUNwQyxPQUFPLE1BQU1oQixvQkFBb0I7Z0JBQy9CLE1BQU0sRUFBRWlCLFFBQVEsRUFBRTBGLFNBQVMsRUFBRUMsTUFBTSxFQUFFQyxjQUFjLEVBQUUsR0FBRzdGLFFBQVFxRixJQUFJO2dCQUNwRSxNQUFNL0UsU0FBU2pELGNBQWN5QyxHQUFHLENBQUNHO2dCQUNqQ0ssT0FBT3dGLE9BQU8sQ0FBQ0gsVUFBVSxHQUFHQztnQkFDNUIsSUFBSUMsbUJBQW1CL0IsV0FBVztvQkFDaEMsSUFBSStCLGVBQWU5RCxNQUFNLEdBQUcsR0FBRzt3QkFDN0J6QixPQUFPeUYsZUFBZSxDQUFDSixVQUFVLEdBQUdFO29CQUN0QyxPQUFPO3dCQUNMLE9BQU92RixPQUFPeUYsZUFBZSxDQUFDSixVQUFVO29CQUMxQztnQkFDRjtnQkFDQSxNQUFNckYsT0FBT29GLElBQUk7Z0JBRWpCLE9BQU87b0JBQUVNLFNBQVNKO29CQUFRSyxpQkFBaUJKO2dCQUFlO1lBQzVEO1FBQ0Y7UUFFQS9HLE9BQU9xRyxJQUFJLENBS1IseUJBQXlCLE9BQU9uRjtZQUNqQyxPQUFPLE1BQU1oQixvQkFBb0I7Z0JBQy9CLE1BQU0sRUFBRWlCLFFBQVEsRUFBRTBGLFNBQVMsRUFBRSxHQUFHM0YsUUFBUXFGLElBQUk7Z0JBQzVDLE1BQU0vRSxTQUFTakQsY0FBY3lDLEdBQUcsQ0FBQ0c7Z0JBQ2pDLE9BQU9LLE9BQU93RixPQUFPLENBQUNILFVBQVU7Z0JBQ2hDLE9BQU9yRixPQUFPeUYsZUFBZSxDQUFDSixVQUFVO2dCQUN4QyxNQUFNckYsT0FBT29GLElBQUk7Z0JBRWpCLE9BQU87WUFDVDtRQUNGO1FBRUE1RyxPQUFPcUcsSUFBSSxDQU1SLDBCQUEwQixPQUFPbkY7WUFDbEMsT0FBTyxNQUFNaEIsb0JBQW9CO2dCQUMvQixNQUFNLEVBQUVpQixRQUFRLEVBQUVpRyxFQUFFLEVBQUVDLE9BQU8sRUFBRSxHQUFHbkcsUUFBUXFGLElBQUk7Z0JBQzlDLE1BQU0vRSxTQUFTakQsY0FBY3lDLEdBQUcsQ0FBQ0c7Z0JBQ2pDLE1BQU1LLE9BQU84RixVQUFVLENBQUNELFNBQVNEO2dCQUNqQyxPQUFPO1lBQ1Q7UUFDRjtRQUVBcEgsT0FBT3FHLElBQUksQ0FNUiwwQkFBMEIsT0FBT25GO1lBQ2xDLE9BQU8sTUFBTWhCLG9CQUFvQjtnQkFDL0IsTUFBTSxFQUFFaUIsUUFBUSxFQUFFaUcsRUFBRSxFQUFFQyxPQUFPLEVBQUUsR0FBR25HLFFBQVFxRixJQUFJO2dCQUU5QyxNQUFNL0UsU0FBU2pELGNBQWN5QyxHQUFHLENBQUNHO2dCQUNqQ0ssT0FBTytGLFVBQVUsQ0FBQ0YsU0FBU0Q7Z0JBRTNCLE9BQU87WUFDVDtRQUNGO1FBRUFwSCxPQUFPcUcsSUFBSSxDQUtSLHVCQUF1QixPQUFPbkY7WUFDL0IsT0FBTyxNQUFNaEIsb0JBQW9CO2dCQUMvQixNQUFNLEVBQUVpQixRQUFRLEVBQUVpRyxFQUFFLEVBQUUsR0FBR2xHLFFBQVFxRixJQUFJO2dCQUVyQyxNQUFNL0UsU0FBU2pELGNBQWN5QyxHQUFHLENBQUNHO2dCQUNqQ0ssT0FBT2dHLE9BQU8sQ0FBQ0o7Z0JBQ2YsT0FBTztZQUNUO1FBQ0Y7UUFFQXBILE9BQU9xRyxJQUFJLENBTVIsd0JBQXdCLE9BQU9uRjtZQUNoQyxPQUFPLE1BQU1oQixvQkFBb0I7Z0JBQy9CLE1BQU0sRUFBRWlCLFFBQVEsRUFBRWlHLEVBQUUsRUFBRUssRUFBRSxFQUFFLEdBQUd2RyxRQUFRcUYsSUFBSTtnQkFFekMsTUFBTS9FLFNBQVNqRCxjQUFjeUMsR0FBRyxDQUFDRztnQkFDakNLLE9BQU9rRyxRQUFRLENBQUNOLElBQUlLO2dCQUVwQixPQUFPO1lBQ1Q7UUFDRjtRQUVBekgsT0FBT3FHLElBQUksQ0FLUiw2QkFBNkIsT0FBT25GO1lBQ3JDLE9BQU8sTUFBTWhCLG9CQUFvQjtnQkFDL0IsTUFBTSxFQUFFaUIsUUFBUSxFQUFFd0csT0FBTyxFQUFFLEdBQUd6RyxRQUFRcUYsSUFBSTtnQkFDMUMsTUFBTS9FLFNBQVNqRCxjQUFjeUMsR0FBRyxDQUFDRztnQkFDakNLLE9BQU9tRyxPQUFPLEdBQUdBO2dCQUNqQixNQUFNbkcsT0FBT29GLElBQUk7Z0JBRWpCLE9BQU87b0JBQUVNLFNBQVNTO2dCQUFRO1lBQzVCO1FBQ0Y7UUFFQTNILE9BQU9xRyxJQUFJLENBS1IsZ0NBQWdDLE9BQU9uRjtZQUN4QyxPQUFPLE1BQU1oQixvQkFBb0I7Z0JBQy9CLE1BQU0sRUFBRWlCLFFBQVEsRUFBRWlGLFVBQVUsRUFBRSxHQUFHbEYsUUFBUXFGLElBQUk7Z0JBQzdDLE1BQU0vRSxTQUFTakQsY0FBY3lDLEdBQUcsQ0FBQ0c7Z0JBQ2pDSyxPQUFPNEUsVUFBVSxHQUFHQTtnQkFDcEIsTUFBTTVFLE9BQU9vRixJQUFJO2dCQUVqQixPQUFPO29CQUFFTSxTQUFTZDtnQkFBVztZQUMvQjtRQUNGO1FBRUFwRyxPQUFPcUcsSUFBSSxDQUtSLDRCQUE0QixPQUFPbkY7WUFDcEMsT0FBTyxNQUFNaEIsb0JBQW9CO2dCQUMvQixNQUFNLEVBQUVpQixRQUFRLEVBQUV5RyxTQUFTLEVBQUUsR0FBRzFHLFFBQVFxRixJQUFJO2dCQUM1QyxNQUFNL0UsU0FBU2pELGNBQWN5QyxHQUFHLENBQUNHO2dCQUVqQyxJQUFJSyxPQUFPNEUsVUFBVSxDQUFDd0IsVUFBVSxFQUFFO29CQUNoQyxNQUFNLElBQUlDLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRUQsV0FBVztnQkFDbkQ7Z0JBRUFwRyxPQUFPNEUsVUFBVSxDQUFDd0IsVUFBVSxHQUFHO29CQUM3QixHQUFJQSxVQUFVRSxRQUFRLENBQUMsWUFDbkI7d0JBQ0VDLFFBQVE7d0JBQ1JDLFFBQVE7b0JBQ1YsSUFDQTt3QkFDRSxJQUFJO29CQUNOLENBQUM7Z0JBQ1A7Z0JBQ0EsTUFBTXhHLE9BQU9vRixJQUFJO2dCQUVqQixPQUFPO1lBQ1Q7UUFDRjtRQUVBNUcsT0FBT3FHLElBQUksQ0FRUiw0QkFBNEIsT0FBT25GO1lBQ3BDLE9BQU8sTUFBTWhCLG9CQUFvQjtnQkFDL0IsTUFBTSxFQUFFaUIsUUFBUSxFQUFFOEcsTUFBTSxFQUFFLEdBQUcvRyxRQUFRcUYsSUFBSTtnQkFDekMsTUFBTXRDLFlBQVkxRixjQUFjeUQsU0FBUztnQkFDekMsTUFBTWtHLFdBQVdqRSxVQUFVa0UsSUFBSSxDQUFDLENBQUNoSDtvQkFDL0IsTUFBTUssU0FBU2pELGNBQWN5QyxHQUFHLENBQUNHO29CQUNqQyxPQUFPbUUsT0FBT2EsSUFBSSxDQUFDM0UsT0FBTzRFLFVBQVUsRUFBRXhDLFFBQVEsQ0FBQ3FFLE9BQU9HLEtBQUs7Z0JBQzdEO2dCQUNBLElBQUlGLFVBQVU7b0JBQ1osTUFBTSxJQUFJTCxNQUFNLENBQUMsbUJBQW1CLEVBQUVJLE9BQU9HLEtBQUssRUFBRTtnQkFDdEQ7Z0JBRUEsTUFBTTVHLFNBQVNqRCxjQUFjeUMsR0FBRyxDQUFDRztnQkFDakNLLE9BQU80RSxVQUFVLENBQUM2QixPQUFPRyxLQUFLLENBQUMsR0FBRzVHLE9BQU80RSxVQUFVLENBQUM2QixPQUFPSSxNQUFNLENBQUM7Z0JBQ2xFLE9BQU83RyxPQUFPNEUsVUFBVSxDQUFDNkIsT0FBT0ksTUFBTSxDQUFDO2dCQUV2QyxNQUFNN0csT0FBT29GLElBQUk7Z0JBRWpCLEtBQUssTUFBTXpGLFlBQVk4QyxVQUFXO29CQUNoQyxNQUFNekMsU0FBU2pELGNBQWN5QyxHQUFHLENBQUNHO29CQUNqQyxLQUFLLE1BQU1xQixRQUFRaEIsT0FBT2MsS0FBSyxDQUFFO3dCQUMvQixJQUFJRSxLQUFLcUQsSUFBSSxLQUFLLFVBQVVyRCxLQUFLSixFQUFFLEtBQUs2RixPQUFPSSxNQUFNLEVBQUU7NEJBQ3JEN0YsS0FBS0osRUFBRSxHQUFHNkYsT0FBT0csS0FBSzt3QkFDeEI7b0JBQ0Y7b0JBQ0EsTUFBTTVHLE9BQU9vRixJQUFJO2dCQUNuQjtZQUNGO1FBQ0Y7UUFFQTVHLE9BQU9xRyxJQUFJLENBS1IsNEJBQTRCLE9BQU9uRjtZQUNwQyxPQUFPLE1BQU1oQixvQkFBb0I7Z0JBQy9CLE1BQU0sRUFBRWlCLFFBQVEsRUFBRThHLE1BQU0sRUFBRSxHQUFHL0csUUFBUXFGLElBQUk7Z0JBRXpDLE1BQU10QyxZQUFZMUYsY0FBY3lELFNBQVM7Z0JBQ3pDLE1BQU1zRyxlQUFlckUsVUFDbEJmLE9BQU8sQ0FBQyxDQUFDL0IsV0FBYTVDLGNBQWN5QyxHQUFHLENBQUNHLFVBQVVtQixLQUFLLEVBQ3ZENkYsSUFBSSxDQUFDLENBQUMzRixPQUFTQSxLQUFLcUQsSUFBSSxLQUFLLFVBQVVyRCxLQUFLSixFQUFFLEtBQUs2RjtnQkFDdEQsSUFBSUssY0FBYztvQkFDaEIsTUFBTSxJQUFJVCxNQUFNLEdBQUdJLE9BQU8sbUJBQW1CLENBQUM7Z0JBQ2hEO2dCQUVBLE1BQU16RyxTQUFTakQsY0FBY3lDLEdBQUcsQ0FBQ0c7Z0JBQ2pDLE9BQU9LLE9BQU80RSxVQUFVLENBQUM2QixPQUFPO2dCQUNoQyxNQUFNekcsT0FBT29GLElBQUk7WUFDbkI7UUFDRjtRQUVBNUcsT0FBT3FHLElBQUksQ0FTUiwwQkFBMEIsT0FBT25GO1lBQ2xDLE9BQU8sTUFBTWhCLG9CQUFvQjtnQkFDL0IsTUFBTSxFQUFFaUIsUUFBUSxFQUFFb0gsTUFBTSxFQUFFQyxRQUFRLEVBQUVQLE1BQU0sRUFBRXBCLFNBQVMsRUFBRTRCLElBQUksRUFBRSxHQUFHdkgsUUFBUXFGLElBQUk7Z0JBQzVFLE1BQU0vRSxTQUFTakQsY0FBY3lDLEdBQUcsQ0FBQ0c7Z0JBRWpDLElBQUlvSCxXQUFXLFVBQVU7b0JBQ3ZCL0csT0FBT2lILElBQUksR0FBR0E7Z0JBQ2hCLE9BQU8sSUFBSUYsV0FBVyxVQUFVQyxVQUFVO29CQUN4QyxNQUFNaEcsT0FBT2hCLE9BQU9jLEtBQUssQ0FBQ29HLElBQUksQ0FBQyxDQUFDQyxJQUFNQSxFQUFFakcsSUFBSSxLQUFLOEY7b0JBQ2pELElBQUloRyxNQUFNO3dCQUNQQSxLQUF5QmlHLElBQUksR0FBR0E7b0JBQ25DO2dCQUNGLE9BQU8sSUFBSUYsV0FBVyxVQUFVTixRQUFRO29CQUN0Q3pHLE9BQU9vSCxTQUFTLENBQUNYLE9BQU8sR0FBR1E7Z0JBQzdCLE9BQU8sSUFBSUYsV0FBVyxZQUFZMUIsV0FBVztvQkFDM0NyRixPQUFPcUgsV0FBVyxDQUFDaEMsVUFBVSxHQUFHNEI7Z0JBQ2xDO2dCQUVBLE1BQU1qSCxPQUFPb0YsSUFBSTtnQkFDakIsT0FBTztZQUNUO1FBQ0Y7UUFFQTVHLE9BQU9xRyxJQUFJLENBT1IsNkJBQTZCLE9BQU9uRixTQUFTNEg7WUFDOUMsT0FBTyxNQUFNNUksb0JBQW9CO2dCQUMvQixNQUFNLEVBQUVpQixRQUFRLEVBQUU0SCxnQkFBZ0IsRUFBRUMsU0FBUyxFQUFFQyxNQUFNLEVBQUUsR0FBRy9ILFFBQVFxRixJQUFJO2dCQUV0RSxJQUFJO29CQUNGLGtCQUFrQjtvQkFDbEIsTUFBTS9FLFNBQVNqRCxjQUFjeUMsR0FBRyxDQUFDRztvQkFFakMsa0RBQWtEO29CQUNsRCxNQUFNK0gsa0JBQ0pELFVBQVcvSyxPQUFPK0MsTUFBTSxDQUFDa0ksSUFBSSxDQUFDQyxhQUFhO29CQUU3QyxVQUFVO29CQUNWLE1BQU1ySSxTQUFTLE1BQU1TLE9BQU82SCxhQUFhLENBQUM7d0JBQ3hDTixrQkFBa0JBLG9CQUFvQjt3QkFDdENDLFdBQVdBLGFBQWE7d0JBQ3hCQyxRQUFRQztvQkFDVjtvQkFFQSxPQUFPbkk7Z0JBQ1QsRUFBRSxPQUFPdUksT0FBZ0I7b0JBQ3ZCLE1BQU1DLFVBQVVELGlCQUFpQnpCLFFBQVF5QixNQUFNQyxPQUFPLEdBQUdDLE9BQU9GO29CQUVoRSxtQkFBbUI7b0JBQ25CLElBQUlDLFFBQVEzRixRQUFRLENBQUMsbUJBQW1CO3dCQUN0Q2tGLE1BQU1XLE1BQU0sQ0FBQzt3QkFDYixPQUFPOzRCQUNMQyxTQUFTOzRCQUNUSixPQUFPLENBQUMsa0JBQWtCLEVBQUVuSSxVQUFVO3dCQUN4QztvQkFDRjtvQkFFQSxXQUFXO29CQUNYLElBQUlvSSxRQUFRM0YsUUFBUSxDQUFDLGdDQUFnQzt3QkFDbkRrRixNQUFNVyxNQUFNLENBQUM7d0JBQ2IsT0FBTzs0QkFDTEMsU0FBUzs0QkFDVEosT0FBTzt3QkFDVDtvQkFDRjtvQkFFQSxhQUFhO29CQUNiLElBQUlDLFFBQVEzRixRQUFRLENBQUMsd0JBQXdCO3dCQUMzQ2tGLE1BQU1XLE1BQU0sQ0FBQzt3QkFDYixPQUFPOzRCQUNMQyxTQUFTOzRCQUNUSixPQUFPO3dCQUNUO29CQUNGO29CQUVBLFFBQVE7b0JBQ1JSLE1BQU1XLE1BQU0sQ0FBQztvQkFDYixPQUFPO3dCQUNMQyxTQUFTO3dCQUNUSixPQUFPLENBQUMsd0JBQXdCLEVBQUVDLFNBQVM7b0JBQzdDO2dCQUNGO1lBQ0Y7UUFDRjtRQUVBdkosT0FBT2dCLEdBQUcsQ0FJUCwrQkFBK0IsT0FBT0U7WUFDdkMsTUFBTSxFQUFFQyxRQUFRLEVBQUUsR0FBR0QsUUFBUUksS0FBSztZQUNsQyxNQUFNRSxTQUFTakQsY0FBY3lDLEdBQUcsQ0FBQ0c7WUFDakMsTUFBTXdJLFVBQVVuSSxPQUFPb0ksZUFBZTtZQUN0QyxPQUFPO2dCQUFFRDtZQUFRO1FBQ25CO1FBRUEzSixPQUFPZ0IsR0FBRyxDQUFDLDBCQUEwQjtZQUNuQyxNQUFNeUksU0FBUyxNQUFNeEosU0FBUzRKLFNBQVM7WUFFdkMsT0FBTztnQkFBRUo7WUFBTztRQUNsQjtRQUVBekosT0FBT3FHLElBQUksQ0FTVCw2QkFDQSxPQUFPbkY7WUFDTCxNQUFNLEVBQUU0SSxNQUFNLEVBQUVDLE9BQU8sRUFBRUMsS0FBSyxFQUFFQyxXQUFXLEVBQUVDLFNBQVMsRUFBRSxHQUFHaEosUUFBUXFGLElBQUk7WUFFdkUsSUFBSXVELFdBQVcsVUFBVTtnQkFDdkIsT0FBTzdKLFNBQVNrSyxhQUFhO1lBQy9CO1lBRUEsMEJBQTBCO1lBQzFCLElBQUlMLFdBQVcsU0FBUztnQkFDdEIsTUFBTU0sZUFBZSxJQUFJeEw7Z0JBQ3pCLE1BQU15TCxtQkFBbUJOLFFBQVE1QixJQUFJLENBQUMsQ0FBQ21DLElBQU1GLGFBQWFHLHdCQUF3QixDQUFDRDtnQkFFbkYsa0JBQWtCO2dCQUNsQixNQUFNRSxhQUFhO29CQUFDO29CQUFhO29CQUFhO29CQUFXO2lCQUFNO2dCQUMvRCxNQUFNQyxnQkFBZ0JWLFFBQVFXLEtBQUssQ0FBQyxDQUFDbkM7b0JBQ25DLE1BQU1vQyxlQUFlek0sT0FBTzBNLFFBQVEsQ0FBQ3JDLE9BQU87b0JBQzVDLE1BQU1zQyxPQUFPLEFBQUNGLGNBQWNHLFlBQWtDRCxRQUFRO29CQUN0RSxPQUFPTCxXQUFXNUcsUUFBUSxDQUFDaUgsS0FBS0UsV0FBVztnQkFDN0M7Z0JBRUEsSUFBSVYsb0JBQW9CRCxhQUFhWSxZQUFZLE1BQU0sQ0FBQ1AsZUFBZTtvQkFDckUsTUFBTSxFQUFFUSxLQUFLLEVBQUUsR0FBRyxNQUFNaEwsU0FBUzRKLFNBQVM7b0JBRTFDLHlDQUF5QztvQkFDekMsTUFBTXFCLG9CQUFvQjsyQkFDckIsSUFBSUMsSUFDTEYsTUFDR2hHLE1BQU0sQ0FBQyxDQUFDbUcsT0FBU3JCLFFBQVFuRyxRQUFRLENBQUN3SCxLQUFLQyxPQUFPLEdBQzlDbkksT0FBTyxDQUFDLENBQUNrSSxPQUFTQSxLQUFLRSxPQUFPO3FCQUVwQztvQkFFRCxJQUFJSixrQkFBa0JqSSxNQUFNLEdBQUcsR0FBRzt3QkFDaEMsY0FBYzt3QkFDZCxNQUFNc0ksV0FBVyxNQUFNbkIsYUFBYW9CLGtCQUFrQixDQUFDTjt3QkFFdkQsSUFBSUssVUFBVTs0QkFDWixzQkFBc0I7NEJBQ3RCLE1BQU0sRUFBRUUsUUFBUSxFQUFFQyxRQUFRLEVBQUUsR0FBRyxNQUFNdEIsYUFBYXVCLGFBQWEsQ0FDN0RKLFNBQVNLLE9BQU8sRUFDaEJMLFNBQVNNLEVBQUU7NEJBR2IsSUFBSUosVUFBVTtnQ0FDWixXQUFXO2dDQUNYLE1BQU0xSyxTQUFTLE1BQU1kLFNBQVM2TCxTQUFTLENBQUNoQyxRQUFRQztnQ0FDaEQsSUFBSWhKLE9BQU9rQyxNQUFNLEdBQUcsR0FBRztvQ0FDckIsTUFBTW1ILGFBQWEyQixZQUFZLENBQzdCUixTQUFTSyxPQUFPLEVBQ2hCTCxTQUFTTSxFQUFFLEVBQ1g5SyxRQUNBbUo7Z0NBRUo7Z0NBQ0EsT0FBT25KOzRCQUNULE9BQU8sSUFBSTJLLFVBQVU7Z0NBQ25CLE1BQU0sSUFBSWxOLG9CQUFvQkgsR0FBRzs0QkFDbkMsT0FBTyxJQUFJMkwsT0FBTztnQ0FDaEIsV0FBVztnQ0FDWCxNQUFNSSxhQUFhNEIsYUFBYSxDQUM5QlQsU0FBU0ssT0FBTyxFQUNoQkwsU0FBU00sRUFBRSxFQUNYNUIsZUFBZSxTQUNmQztnQ0FFRixNQUFNbkosU0FBUyxNQUFNZCxTQUFTNkwsU0FBUyxDQUFDaEMsUUFBUUM7Z0NBQ2hELElBQUloSixPQUFPa0MsTUFBTSxHQUFHLEdBQUc7b0NBQ3JCLE1BQU1tSCxhQUFhMkIsWUFBWSxDQUM3QlIsU0FBU0ssT0FBTyxFQUNoQkwsU0FBU00sRUFBRSxFQUNYOUssUUFDQW1KO2dDQUVKO2dDQUNBLE9BQU9uSjs0QkFDVCxPQUFPO2dDQUNMLE1BQU07Z0NBQ04sT0FBTztvQ0FDTDhFLE1BQU07b0NBQ04rRixTQUFTTCxTQUFTSyxPQUFPO29DQUN6QkMsSUFBSU4sU0FBU00sRUFBRTtnQ0FDakI7NEJBQ0Y7d0JBQ0YsT0FBTzs0QkFDTCxhQUFhOzRCQUNiLE1BQU0sRUFBRUQsT0FBTyxFQUFFQyxFQUFFLEVBQUUsR0FBRyxNQUFNekIsYUFBYTZCLG1CQUFtQixDQUM1RGYsbUJBQ0FuQixTQUNBRzs0QkFFRixNQUFNRSxhQUFhOEIsV0FBVyxDQUFDaEIsbUJBQW1CVSxTQUFTQzs0QkFFM0QsT0FBTztnQ0FDTGhHLE1BQU07Z0NBQ04rRjtnQ0FDQUM7NEJBQ0Y7d0JBQ0Y7b0JBQ0Y7Z0JBQ0Y7WUFDRjtZQUVBLE9BQU81TCxTQUFTNkwsU0FBUyxDQUFDaEMsUUFBUUM7UUFDcEM7UUFHRi9KLE9BQU9xRyxJQUFJLENBS1IsaUNBQWlDLE9BQU9uRjtZQUN6QyxNQUFNLEVBQUUwSyxPQUFPLEVBQUVDLEVBQUUsRUFBRSxHQUFHM0ssUUFBUXFGLElBQUk7WUFDcEMsTUFBTTZELGVBQWUsSUFBSXhMO1lBRXpCLElBQUksQ0FBQ3dMLGFBQWFZLFlBQVksSUFBSTtnQkFDaEMsT0FBTztvQkFBRVMsVUFBVTtvQkFBTUMsVUFBVTtnQkFBTTtZQUMzQztZQUVBLE9BQU90QixhQUFhdUIsYUFBYSxDQUFDQyxTQUFTQztRQUM3QztRQUVBN0wsT0FBT3FHLElBQUksQ0FPUixpQ0FBaUMsT0FBT25GO1lBQ3pDLE1BQU0sRUFBRTBLLE9BQU8sRUFBRUMsRUFBRSxFQUFFTSxNQUFNLEVBQUVqQyxTQUFTLEVBQUUsR0FBR2hKLFFBQVFxRixJQUFJO1lBQ3ZELE1BQU02RCxlQUFlLElBQUl4TDtZQUV6QixJQUFJLENBQUN3TCxhQUFhWSxZQUFZLElBQUk7Z0JBQ2hDLE1BQU0sSUFBSXhNLG9CQUFvQkgsR0FBRztZQUNuQztZQUVBLE1BQU0rTCxhQUFhNEIsYUFBYSxDQUFDSixTQUFTQyxJQUFJTSxRQUFRakM7WUFDdEQsT0FBTztnQkFBRVIsU0FBUztZQUFLO1FBQ3pCO1FBRUExSixPQUFPcUcsSUFBSSxDQUlSLDRCQUE0QixPQUFPbkY7WUFDcEMsTUFBTSxFQUFFa0wsU0FBUyxFQUFFLEdBQUdsTCxRQUFRcUYsSUFBSTtZQUNsQyxPQUFPLE1BQU10RyxTQUFTb00sUUFBUSxDQUFDRDtRQUNqQztRQUVBcE0sT0FBT3FHLElBQUksQ0FBQyx5Q0FBeUMsT0FBT2lHO1lBQzFELE9BQU8sTUFBTXJNLFNBQVNzTSxxQkFBcUI7UUFDN0M7UUFFQXZNLE9BQU9xRyxJQUFJLENBS1IsOEJBQThCLE9BQU9uRjtZQUN0QyxNQUFNLEVBQUUrQyxTQUFTLEVBQUV1SSxjQUFjQyxhQUFhLEVBQUUsR0FBR3ZMLFFBQVFxRixJQUFJO1lBQy9ELElBQUksQUFBQ3RDLENBQUFBLGFBQWEsRUFBRSxBQUFELEVBQUdoQixNQUFNLEtBQUssR0FBRztnQkFDbEMsTUFBTSxJQUFJekUsb0JBQW9CSCxHQUFHO1lBQ25DLE9BQU8sSUFBSSxBQUFDb08sQ0FBQUEsaUJBQWlCLEVBQUUsQUFBRCxFQUFHeEosTUFBTSxLQUFLLEdBQUc7Z0JBQzdDLE1BQU0sSUFBSXpFLG9CQUFvQkgsR0FBRztZQUNuQztZQUVBLFVBQVU7WUFDVjRGLFVBQVVTLElBQUksQ0FBQyxDQUFDQyxHQUFHQyxJQUFPRCxJQUFJQyxJQUFJLENBQUMsSUFBSUQsSUFBSUMsSUFBSSxJQUFJO1lBQ25ELE1BQU00SCxlQUFldE4sWUFBWXdOLE9BQU8sQ0FBQ3pILE1BQU0sQ0FBQyxDQUFDMEgsS0FBT0YsY0FBYzdJLFFBQVEsQ0FBQytJO1lBRS9FLE1BQU0zSixlQUFlaUIsVUFBVWYsT0FBTyxDQUFDLENBQUMvQjtnQkFDdEMsT0FBT3FMLGFBQWEzSSxHQUFHLENBQUMsQ0FBQytJLGNBQWdCO3dCQUFDekw7d0JBQVV5TDtxQkFBWTtZQUNsRTtZQUVBLE1BQU1DLFdBQVcsTUFBTXhNLFFBQVFtRSxHQUFHLENBQ2hDeEIsYUFBYWEsR0FBRyxDQUFDLE9BQU8sQ0FBQzFDLFVBQVV5TCxZQUFZO2dCQUM3QyxNQUFNLEVBQUVFLE9BQU8sRUFBRUMsUUFBUSxFQUFFN0UsUUFBUSxFQUFFLEdBQUcsTUFBTWhLLE9BQU95QyxNQUFNLENBQUNxTSxrQkFBa0IsQ0FDNUU3TCxVQUNBeUw7Z0JBRUYsT0FBTztvQkFDTHpMO29CQUNBeUw7b0JBQ0FFO29CQUNBQztvQkFDQTdFO2dCQUNGO1lBQ0Y7WUFFRixPQUFPO2dCQUFFMkU7WUFBUztRQUNwQjtRQUVBN00sT0FBT3FHLElBQUksQ0FTUiw2QkFBNkIsT0FBT25GO1lBQ3JDLE1BQU0sRUFBRXdMLE9BQU8sRUFBRSxHQUFHeEwsUUFBUXFGLElBQUk7WUFDaEMsSUFBSW1HLFFBQVF6SixNQUFNLEtBQUssR0FBRztnQkFDeEIsTUFBTSxJQUFJekUsb0JBQW9CSCxHQUFHO1lBQ25DO1lBRUEsNkJBQTZCO1lBQzdCLE1BQU04SCxPQUFPdUcsUUFBUXhKLE9BQU8sQ0FBQyxDQUFDLEVBQUUwSixXQUFXLEVBQUU7Z0JBQzNDLE1BQU1LLFdBQVdwTyxnQkFBZ0JtQyxHQUFHLENBQUM0TDtnQkFDckMsT0FBT0ssU0FBU0MsbUJBQW1CLE1BQU0sRUFBRTtZQUM3QztZQUVBLHdDQUF3QztZQUN4QyxNQUFNNU8saUJBQWlCNk8sY0FBYyxDQUFDO21CQUFJLElBQUloQyxJQUFJaEY7YUFBTTtZQUV4RCxvQkFBb0I7WUFDcEIsTUFBTXBGLFNBQVMsTUFBTVYsUUFBUW1FLEdBQUcsQ0FDOUJrSSxRQUFRN0ksR0FBRyxDQUFDLE9BQU8sRUFBRTFDLFFBQVEsRUFBRXlMLFdBQVcsRUFBRTNFLE1BQU0sRUFBRW1GLFNBQVMsRUFBRTtnQkFDN0QsSUFBSTtvQkFDRixPQUFPLE1BQU1sUCxPQUFPeUMsTUFBTSxDQUFDME0sZ0JBQWdCLENBQ3pDVCxhQUNBO3dCQUNFekw7d0JBQ0E4RztvQkFDRixHQUlBO3dCQUNFbUY7b0JBQ0Y7Z0JBRUosRUFBRSxPQUFPRSxHQUFHO29CQUNWLElBQUk3TyxjQUFjNk8sTUFBTUEsRUFBRUMsVUFBVSxLQUFLLEtBQUs7d0JBQzVDLE9BQU87b0JBQ1QsT0FBTzt3QkFDTEMsUUFBUWxFLEtBQUssQ0FBQ2dFO3dCQUNkLE1BQU1BO29CQUNSO2dCQUNGO1lBQ0Y7WUFHRixJQUFJdk0sT0FBT2tFLE1BQU0sQ0FBQzlGLGFBQWE4RCxNQUFNLEtBQUssR0FBRztnQkFDM0MsTUFBTSxJQUFJdkUsNEJBQTRCTCxHQUFHO1lBQzNDO1lBQ0EsT0FBTzBDO1FBQ1Q7UUFFQWYsT0FBT3FHLElBQUksQ0FRUiw0QkFBNEIsT0FBT25GO1lBQ3BDLE1BQU0sRUFBRXVNLE1BQU0sRUFBRSxHQUFHdk0sUUFBUXFGLElBQUk7WUFFL0IsSUFBSTtnQkFDRixNQUFNLEVBQUVxRyxXQUFXLEVBQUUsR0FBR2MsaUJBQWlCLEdBQUdEO2dCQUM1QyxNQUFNRSxlQUFlLE1BQU16UCxPQUFPeUMsTUFBTSxDQUFDaU4sY0FBYyxDQUNyRGhCLGFBQ0FjO2dCQUdGLE9BQU87b0JBQUVDO2dCQUFhO1lBQ3hCLEVBQUUsT0FBT0wsR0FBRztnQkFDVkUsUUFBUWxFLEtBQUssQ0FBQ2dFO2dCQUNkLE1BQU1BO1lBQ1I7UUFDRjtRQUVBdE4sT0FBT3FHLElBQUksQ0FBQyxnQkFBZ0IsT0FBT25GO1lBQ2pDLE1BQU0sRUFBRTJNLFFBQVEsRUFBRUMsUUFBUSxFQUFFQyxNQUFNLEVBQUVDLGNBQWMsRUFBRSxHQUFHOU0sUUFBUXFGLElBQUk7WUFPbkUsT0FBT3ZILGVBQWVpUCxXQUFXLENBQUNKLFVBQVVDLFVBQVVDLFFBQVFDO1FBQ2hFO1FBRUFoTyxPQUFPcUcsSUFBSSxDQUFDLHVCQUF1QixPQUFPbkY7WUFDeEMsTUFBTSxFQUFFZ04sRUFBRSxFQUFFQyxRQUFRLEVBQUUsR0FBR2pOLFFBQVFxRixJQUFJO1lBS3JDLE9BQU92SCxlQUFlb1AsY0FBYyxDQUFDRixJQUFJQztRQUMzQztRQUVBbk8sT0FBT3FHLElBQUksQ0FBQyxpQ0FBaUMsT0FBT25GO1lBQ2xELE1BQU0sRUFBRW1OLElBQUksRUFBRSxHQUFHbk4sUUFBUXFGLElBQUk7WUFFN0IsT0FBT3ZILGVBQWVzUCxnQkFBZ0IsQ0FBQ0Q7UUFDekM7UUFFQXJPLE9BQU9nQixHQUFHLENBQUMsd0JBQXdCO1lBQ2pDLE9BQU8xQyxpQkFBaUJpUSxhQUFhO1FBQ3ZDO1FBRUF2TyxPQUFPZ0IsR0FBRyxDQUFDLG9CQUFvQixPQUFPd04sVUFBVTFGO1lBQzlDLE1BQU0sRUFBRW5ILFFBQVEsRUFBRThNLE1BQU0sRUFBRSxHQUFHLE1BQU1uUSxpQkFBaUJvUSxhQUFhO1lBQ2pFNUYsTUFDRzZGLE1BQU0sQ0FDTCxnQkFDQSxxRUFFREEsTUFBTSxDQUFDLHVCQUF1QixDQUFDLHNCQUFzQixFQUFFaE4sU0FBUyxDQUFDLENBQUMsRUFDbEVpTixJQUFJLENBQUNIO1FBQ1Y7UUFFQXpPLE9BQU9xRyxJQUFJLENBQUMsb0JBQW9CLE9BQU9uRjtZQUNyQyxNQUFNMk4sT0FBTyxNQUFNM04sUUFBUTROLElBQUk7WUFDL0IsSUFBSSxDQUFDRCxNQUFNO2dCQUNULE1BQU0sSUFBSXJRLG9CQUFvQkgsR0FBRztZQUNuQztZQUNBLE1BQU1vUSxTQUFTLE1BQU1JLEtBQUtFLFFBQVE7WUFDbEMsT0FBT3pRLGlCQUFpQjBRLGVBQWUsQ0FBQ1A7UUFDMUM7UUFFQXpPLE9BQU9xRyxJQUFJLENBT1Isb0JBQW9CLE9BQU9uRjtZQUM1QixNQUFNNUMsaUJBQWlCMlEsV0FBVyxDQUFDL04sUUFBUXFGLElBQUk7WUFDL0MsT0FBTztnQkFBRW1ELFNBQVM7WUFBSztRQUN6QjtRQUVBMUosT0FBT3FHLElBQUksQ0FLUixvQkFBb0IsT0FBT25GO1lBQzVCLE1BQU01QyxpQkFBaUI0USxXQUFXLENBQUNoTyxRQUFRcUYsSUFBSTtZQUMvQyxPQUFPO2dCQUFFbUQsU0FBUztZQUFLO1FBQ3pCO1FBRUExSixPQUFPcUcsSUFBSSxDQUlSLG9CQUFvQixPQUFPbkY7WUFDNUIsTUFBTTVDLGlCQUFpQjZRLFdBQVcsQ0FBQ2pPLFFBQVFxRixJQUFJLENBQUM2SSxHQUFHO1lBQ25ELE9BQU87Z0JBQUUxRixTQUFTO1lBQUs7UUFDekI7UUFFQTFKLE9BQU9xRyxJQUFJLENBQStCLHdCQUF3QixPQUFPbkY7WUFDdkUsT0FBTzVDLGlCQUFpQitRLFVBQVUsQ0FBQ25PLFFBQVFxRixJQUFJLENBQUNKLElBQUk7UUFDdEQ7UUFFQSxZQUFZO1FBQ1puRyxPQUFPZ0IsR0FBRyxDQUFDLHFCQUFxQjtZQUM5QixJQUFJO2dCQUNGOUMsT0FBT29SLFNBQVM7Z0JBQ2hCLE9BQU87b0JBQUV2SCxRQUFRO2dCQUFLO1lBQ3hCLEVBQUUsT0FBTTtnQkFDTixPQUFPO29CQUFFQSxRQUFRO2dCQUFNO1lBQ3pCO1FBQ0Y7UUFFQS9ILE9BQU9nQixHQUFHLENBQUMsa0NBQWtDO1lBQzNDLE1BQU11TyxjQUFjclIsT0FBT29SLFNBQVMsQ0FBQ0UsbUJBQW1CO1lBQ3hELE9BQU87Z0JBQUVEO1lBQVk7UUFDdkI7UUFFQXZQLE9BQU9nQixHQUFHLENBV1AsMkJBQTJCLE9BQU9FO1lBQ25DLE1BQU11TyxVQUFVdlIsT0FBT29SLFNBQVMsQ0FBQ0csT0FBTztZQUN4QyxNQUFNLEVBQUVDLEtBQUssRUFBRXRILEtBQUssRUFBRUMsTUFBTSxFQUFFc0gsS0FBSyxFQUFFbEcsTUFBTSxFQUFFbUcsWUFBWSxFQUFFQyxZQUFZLEVBQUVDLGFBQWEsRUFBRSxHQUN0RjVPLFFBQVFJLEtBQUs7WUFDZixPQUFPbU8sUUFBUU0sZ0JBQWdCLENBQUM7Z0JBQzlCTCxPQUFPQSxRQUFRTSxPQUFPQyxRQUFRLENBQUNQLE9BQU8sTUFBTTFLO2dCQUM1Q29EO2dCQUNBQztnQkFDQXNIO2dCQUNBbEcsUUFBUUEsU0FBU0EsT0FBTzFHLEtBQUssQ0FBQyxPQUFPaUM7Z0JBQ3JDNEssY0FBY0EsZ0JBQWdCNUs7Z0JBQzlCNkssY0FBY0EsZUFBZSxJQUFJSyxLQUFLTCxnQkFBZ0I3SztnQkFDdEQ4SyxlQUFlQSxnQkFBZ0IsSUFBSUksS0FBS0osaUJBQWlCOUs7WUFDM0Q7UUFDRjtRQUVBaEYsT0FBT2dCLEdBQUcsQ0FFUCwrQkFBK0IsT0FBT0U7WUFDdkMsTUFBTXVPLFVBQVV2UixPQUFPb1IsU0FBUyxDQUFDRyxPQUFPO1lBQ3hDLE1BQU1VLGNBQWMsTUFBTVYsUUFBUVcsY0FBYyxDQUFDO2dCQUMvQ0MsZUFBZW5QLFFBQVFvUCxNQUFNLENBQUNsTyxFQUFFO1lBQ2xDO1lBQ0EsSUFBSSxDQUFDK04sYUFBYTtnQkFDaEIsTUFBTSxJQUFJdEksTUFBTSxDQUFDLHdCQUF3QixFQUFFM0csUUFBUW9QLE1BQU0sQ0FBQ2xPLEVBQUUsRUFBRTtZQUNoRTtZQUNBLE9BQU8rTjtRQUNUO1FBRUFuUSxPQUFPcUcsSUFBSSxDQUVSLHNDQUFzQyxPQUFPbkY7WUFDOUMsTUFBTXVPLFVBQVV2UixPQUFPb1IsU0FBUyxDQUFDRyxPQUFPO1lBQ3hDLE9BQU9BLFFBQVFjLGlCQUFpQixDQUFDO2dCQUMvQkYsZUFBZW5QLFFBQVFvUCxNQUFNLENBQUNsTyxFQUFFO1lBQ2xDO1FBQ0Y7UUFFQXBDLE9BQU9xRyxJQUFJLENBRVIscUNBQXFDLE9BQU9uRjtZQUM3QyxNQUFNdU8sVUFBVXZSLE9BQU9vUixTQUFTLENBQUNHLE9BQU87WUFDeEMsT0FBT0EsUUFBUWUsZ0JBQWdCLENBQUM7Z0JBQzlCSCxlQUFlblAsUUFBUW9QLE1BQU0sQ0FBQ2xPLEVBQUU7WUFDbEM7UUFDRjtRQUVBcEMsT0FBT3FHLElBQUksQ0FFUixzQ0FBc0MsT0FBT25GO1lBQzlDLE1BQU11TyxVQUFVdlIsT0FBT29SLFNBQVMsQ0FBQ0csT0FBTztZQUN4QyxPQUFPQSxRQUFRZ0IsaUJBQWlCLENBQUM7Z0JBQy9CSixlQUFlblAsUUFBUW9QLE1BQU0sQ0FBQ2xPLEVBQUU7WUFDbEM7UUFDRjtRQUVBcEMsT0FBT2dCLEdBQUcsQ0FPUCxxQ0FBcUMsT0FBT0U7WUFDN0MsTUFBTXVPLFVBQVV2UixPQUFPb1IsU0FBUyxDQUFDRyxPQUFPO1lBQ3hDLE1BQU0sRUFBRUMsS0FBSyxFQUFFdEgsS0FBSyxFQUFFQyxNQUFNLEVBQUUsR0FBR25ILFFBQVFJLEtBQUs7WUFDOUMsT0FBT21PLFFBQVFpQixnQkFBZ0IsQ0FBQztnQkFDOUJMLGVBQWVuUCxRQUFRb1AsTUFBTSxDQUFDbE8sRUFBRTtnQkFDaENzTixPQUFPQSxRQUFRTSxPQUFPQyxRQUFRLENBQUNQLE9BQU8sTUFBTTFLO2dCQUM1Q29EO2dCQUNBQztZQUNGO1FBQ0Y7UUFFQTs7O09BR0MsR0FDRHJJLE9BQU9nQixHQUFHLENBQUMsc0JBQXNCLE9BQU9FO1lBQ3RDLE1BQU15UCxVQUFVelAsUUFBUWxCLE1BQU0sQ0FBQ0EsTUFBTSxDQUFDMlEsT0FBTztZQUM3QyxNQUFNQyxPQUFPRCxXQUFXLE9BQU9BLFlBQVksV0FBVyxBQUFDQSxRQUF3QkMsSUFBSSxHQUFHO1lBRXRGLE9BQU87Z0JBQ0xDLElBQUk7Z0JBQ0pDLFNBQVNDLFFBQVFDLEdBQUcsR0FBR2pPLEtBQUssQ0FBQyxLQUFLa08sR0FBRyxNQUFNO2dCQUMzQ0w7Z0JBQ0FNLFdBQVcsSUFBSWhCLE9BQU9pQixXQUFXO1lBQ25DO1FBQ0Y7UUFFQTs7T0FFQyxHQUNEblIsT0FBT3FHLElBQUksQ0FPUixnQ0FBZ0MsT0FBT25GLFNBQVM0SDtZQUNqRCxNQUFNLEVBQUV0SCxNQUFNLEVBQUU0UCxRQUFRLENBQUMsRUFBRUMsU0FBUyxFQUFFQyxXQUFXLFNBQVMsRUFBRSxHQUFHcFEsUUFBUXFGLElBQUk7WUFFM0UsZ0JBQWdCO1lBQ2hCLE1BQU1xRSxXQUFXMEcsYUFBYSxZQUFZcFQsT0FBTzBNLFFBQVEsQ0FBQzJHLE9BQU8sR0FBR3JULE9BQU8wTSxRQUFRLENBQUM0RyxJQUFJO1lBRXhGLGVBQWU7WUFDZixNQUFNdEQsS0FBSzlQLG1CQUFtQndNO1lBRTlCLElBQUk7Z0JBQ0Ysc0JBQXNCO2dCQUN0QixNQUFNNkcsWUFBWSxJQUFJMVMsaUJBQWlCbVAsSUFBSUEsSUFBSW9ELFVBQVUvUztnQkFFekQsa0JBQWtCO2dCQUNsQixNQUFNNFAsV0FBVyxNQUFNc0QsVUFBVUMsYUFBYSxDQUFDO29CQUM3Qzt3QkFDRWxRO3dCQUNBNFA7d0JBQ0FDLFdBQVdBLGFBQWEsQ0FBQztvQkFDM0I7aUJBQ0Q7Z0JBRUQsT0FBTztvQkFDTDNILFNBQVM7b0JBQ1RsSTtvQkFDQTRQLE9BQU9qRCxTQUFTbEwsTUFBTTtvQkFDdEJrTDtvQkFDQW1EO2dCQUNGO1lBQ0YsRUFBRSxPQUFPaEksT0FBTztnQkFDZFIsTUFBTVcsTUFBTSxDQUFDO2dCQUNiLE9BQU87b0JBQ0xDLFNBQVM7b0JBQ1RKLE9BQU9BLGlCQUFpQnpCLFFBQVF5QixNQUFNQyxPQUFPLEdBQUdDLE9BQU9GO2dCQUN6RDtZQUNGLFNBQVU7Z0JBQ1IsTUFBTTRFLEdBQUd5RCxPQUFPO1lBQ2xCO1FBQ0Y7UUFFQTs7T0FFQyxHQUNEM1IsT0FBT3FHLElBQUksQ0FPUiwrQkFBK0IsT0FBT25GLFNBQVM0SDtZQUNoRCxNQUFNLEVBQUV0SCxNQUFNLEVBQUVvUSxRQUFRLEVBQUVsQyxRQUFRLEVBQUUsRUFBRW1DLEtBQUssRUFBRSxHQUFHM1EsUUFBUXFGLElBQUk7WUFFNUQscUJBQXFCO1lBQ3JCLE1BQU11TCxrQkFBa0I1VCxPQUFPME0sUUFBUSxDQUFDMkcsT0FBTztZQUUvQyxlQUFlO1lBQ2YsTUFBTVEsWUFBWTNULG1CQUFtQjBUO1lBRXJDLElBQUk7Z0JBQ0Ysa0JBQWtCO2dCQUNsQixNQUFNRSxXQUFXLElBQUlsVCxhQUFhaVQsV0FBV3hUO2dCQUU3QyxNQUFNc1EsT0FBTyxNQUFNbUQsU0FBU0MsT0FBTyxDQUFDelEsUUFBUTtvQkFDMUNvUTtvQkFDQWxDO29CQUNBbUM7Z0JBQ0Y7Z0JBRUEsT0FBTztvQkFDTG5JLFNBQVM7b0JBQ1RsSTtvQkFDQW9RO29CQUNBUixPQUFPdkMsS0FBSzVMLE1BQU07b0JBQ2xCNEw7Z0JBQ0Y7WUFDRixFQUFFLE9BQU92RixPQUFPO2dCQUNkUixNQUFNVyxNQUFNLENBQUM7Z0JBQ2IsT0FBTztvQkFDTEMsU0FBUztvQkFDVEosT0FBT0EsaUJBQWlCekIsUUFBUXlCLE1BQU1DLE9BQU8sR0FBR0MsT0FBT0Y7Z0JBQ3pEO1lBQ0YsU0FBVTtnQkFDUixNQUFNeUksVUFBVUosT0FBTztZQUN6QjtRQUNGO1FBRUE7OztPQUdDLEdBQ0QzUixPQUFPcUcsSUFBSSxDQVFSLDZCQUE2QixPQUFPbkYsU0FBUzRIO1lBQzlDLE1BQU0sRUFDSnRILE1BQU0sRUFDTm9RLFdBQVcsUUFBUSxFQUNuQmxDLFFBQVEsRUFBRSxFQUNWd0MsbUJBQW1CLElBQUksRUFDdkJDLFdBQVcsQ0FBQyxFQUNiLEdBQUdqUixRQUFRcUYsSUFBSTtZQUVoQiw2Q0FBNkM7WUFDN0MsTUFBTTZMLFdBQVdqVSxHQUFHa1UsS0FBSyxDQUFDO1lBRTFCLHNCQUFzQjtZQUN0QixNQUFNTixZQUFZM1QsbUJBQW1CRixPQUFPME0sUUFBUSxDQUFDMkcsT0FBTztZQUU1RCxJQUFJO2dCQUNGLHNCQUFzQjtnQkFDdEIsTUFBTUUsWUFBWSxJQUFJMVMsaUJBQWlCcVQsVUFBVUwsV0FBVyxXQUFXeFQ7Z0JBRXZFLHFDQUFxQztnQkFDckMsTUFBTStULFVBQVUsTUFBTWIsVUFBVWMsZ0JBQWdCLENBQUMvUSxRQUFRO29CQUN2RG9RO29CQUNBbEM7b0JBQ0F3QztvQkFDQUM7Z0JBQ0Y7Z0JBRUEsT0FBTztvQkFDTHpJLFNBQVM7b0JBQ1RsSTtvQkFDQW9RO29CQUNBUixPQUFPa0IsUUFBUXJQLE1BQU07b0JBQ3JCdVAsVUFBVUY7Z0JBQ1o7WUFDRixFQUFFLE9BQU9oSixPQUFPO2dCQUNkUixNQUFNVyxNQUFNLENBQUM7Z0JBQ2IsT0FBTztvQkFDTEMsU0FBUztvQkFDVEosT0FBT0EsaUJBQWlCekIsUUFBUXlCLE1BQU1DLE9BQU8sR0FBR0MsT0FBT0Y7Z0JBQ3pEO1lBQ0YsU0FBVTtnQkFDUix1Q0FBdUM7Z0JBQ3ZDLE1BQU15SSxVQUFVSixPQUFPO1lBQ3pCO1FBQ0Y7UUFFQTs7O09BR0MsR0FDRDNSLE9BQU9xRyxJQUFJLENBSVIsNkJBQTZCLE9BQU9uRixTQUFTNEg7WUFDOUMsTUFBTSxFQUFFdkUsUUFBUSxFQUFFLEdBQUdyRCxRQUFRcUYsSUFBSTtZQUVqQyxnQkFBZ0I7WUFDaEIsTUFBTXdMLFlBQVkzVCxtQkFBbUJGLE9BQU8wTSxRQUFRLENBQUMyRyxPQUFPO1lBRTVELElBQUk7Z0JBQ0YsbUJBQW1CO2dCQUNuQixNQUFNa0IsaUJBQ0psTyxZQUFZQSxTQUFTdEIsTUFBTSxHQUFHLElBQUlzQixXQUFXaEcsY0FBY3lELFNBQVM7Z0JBRXRFLHdDQUF3QztnQkFDeEMsTUFBTTBRLGFBQWFELGVBQWU1TyxHQUFHLENBQUMsQ0FBQzFDO29CQUNyQyxNQUFNSyxTQUFTakQsY0FBY3lDLEdBQUcsQ0FBQ0c7b0JBQ2pDLE9BQU9LLE9BQU9tRixLQUFLO2dCQUNyQjtnQkFFQSxtREFBbUQ7Z0JBQ25ELGlDQUFpQztnQkFDakMsTUFBTW9MLFVBQVVZLEdBQUcsQ0FDakIsQ0FBQyxlQUFlLEVBQUVELFdBQVc3TyxHQUFHLENBQUMsQ0FBQ3lHLElBQU0sQ0FBQyxDQUFDLEVBQUVBLEVBQUUsQ0FBQyxDQUFDLEVBQUUvRyxJQUFJLENBQUMsTUFBTSx5QkFBeUIsQ0FBQztnQkFHekYsT0FBTztvQkFDTG1HLFNBQVM7b0JBQ1RrSixTQUFTRjtvQkFDVHRCLE9BQU9zQixXQUFXelAsTUFBTTtnQkFDMUI7WUFDRixFQUFFLE9BQU9xRyxPQUFPO2dCQUNkUixNQUFNVyxNQUFNLENBQUM7Z0JBQ2IsT0FBTztvQkFDTEMsU0FBUztvQkFDVEosT0FBT0EsaUJBQWlCekIsUUFBUXlCLE1BQU1DLE9BQU8sR0FBR0MsT0FBT0Y7Z0JBQ3pEO1lBQ0YsU0FBVTtnQkFDUixNQUFNeUksVUFBVUosT0FBTztZQUN6QjtRQUNGO1FBRUEsVUFBVTtRQUNWM1IsT0FBT2dCLEdBQUcsQ0FBQyxzQkFBc0I7WUFDL0IsT0FBT3hCO1FBQ1Q7UUFFQVEsT0FBT2dCLEdBQUcsQ0FBQyxpQkFBaUI7WUFDMUIsT0FBT3pCO1FBQ1Q7UUFFQVMsT0FBT3FHLElBQUksQ0FBaUMsd0JBQXdCLE9BQU9uRjtZQUN6RSxNQUFNLEVBQUUyUixRQUFRLEVBQUUsR0FBRzNSLFFBQVFxRixJQUFJO1lBQ2pDLE9BQU81RyxZQUFZa1Q7UUFDckI7UUFFQTdTLE9BQU9xRyxJQUFJLENBQWlDLHdCQUF3QixPQUFPbkY7WUFDekUsTUFBTSxFQUFFMlIsUUFBUSxFQUFFLEdBQUczUixRQUFRcUYsSUFBSTtZQUNqQyxPQUFPbEgsWUFBWXdUO1FBQ3JCO1FBRUE3UyxPQUFPcUcsSUFBSSxDQUFpQyx1QkFBdUIsT0FBT25GO1lBQ3hFLE1BQU0sRUFBRTJSLFFBQVEsRUFBRSxHQUFHM1IsUUFBUXFGLElBQUk7WUFDakM3RyxlQUFlbVQ7WUFDZixPQUFPO2dCQUFFbkosU0FBUztZQUFLO1FBQ3pCO1FBRUEsaUJBQWlCO1FBQ2pCMUosT0FBT2dCLEdBQUcsQ0FBQyxvQkFBb0I7WUFDN0IsT0FBT3ZCO1FBQ1Q7UUFFQU8sT0FBT3FHLElBQUksQ0FBa0MsdUJBQXVCLE9BQU9uRjtZQUN6RSxNQUFNLEVBQUU0UixTQUFTLEVBQUUsR0FBRzVSLFFBQVFxRixJQUFJO1lBQ2xDLE9BQU8zRyxXQUFXa1Q7UUFDcEI7UUFFQTlTLE9BQU9xRyxJQUFJLENBQWtDLHVCQUF1QixPQUFPbkY7WUFDekUsTUFBTSxFQUFFNFIsU0FBUyxFQUFFLEdBQUc1UixRQUFRcUYsSUFBSTtZQUNsQyxPQUFPakgsV0FBV3dUO1FBQ3BCO1FBRUEsa0JBQWtCO1FBQ2xCLE1BQU1DLGFBQWEvVSxLQUFLc0MsT0FBTyxDQUFDLFlBQVkwUyxPQUFPLEVBQUU7UUFFckQsNkNBQTZDO1FBQzdDaFQsT0FBT0QsUUFBUSxDQUFDLE1BQU0sTUFBTSxDQUFDLG9CQUFvQjtZQUMvQ2tULE1BQU1GO1lBQ05HLFFBQVE7WUFDUkMsZUFBZTtZQUNmQyxVQUFVO1FBQ1o7UUFFQSw4Q0FBOEM7UUFDOUNwVCxPQUFPZ0IsR0FBRyxDQUFDLEtBQUssT0FBT3dOLFVBQVUxRjtZQUMvQkEsTUFBTXVLLE9BQU8sQ0FBQztnQkFBRSxnQkFBZ0I7WUFBWSxHQUFHekUsSUFBSSxDQUNqRDlRLEdBQ0d3VixZQUFZLENBQUN0VixLQUFLc0MsT0FBTyxDQUFDeVMsWUFBWSxlQUN0Q1EsUUFBUSxHQUNSM1EsT0FBTyxDQUFDLG1CQUFtQjFFLE9BQU8rQyxNQUFNLENBQUN1UyxXQUFXLElBQUk7UUFFL0Q7SUFDRixHQUNBO1FBQUVOLFFBQVE7SUFBYTtBQUUzQiJ9
|
|
904
|
+
//#endregion
|
|
905
|
+
init_api();
|
|
906
|
+
export { sonamuUIApiPlugin };
|
|
907
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwibmFtZXMiOlsiZW50aXR5SWQiLCJyZW1haW5BcnI6IHN0cmluZ1tdIiwiZW50aXR5IiwiZXJyb3I6IHVua25vd24iXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdWkvYXBpLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGV4ZWNTeW5jIH0gZnJvbSBcImNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmltcG9ydCB7IHR5cGUgRmFzdGlmeUluc3RhbmNlIH0gZnJvbSBcImZhc3RpZnlcIjtcbmltcG9ydCBpbmZsZWN0aW9uIGZyb20gXCJpbmZsZWN0aW9uXCI7XG5pbXBvcnQgeyByYW5nZSB9IGZyb20gXCJyYWRhc2hpXCI7XG5cbmltcG9ydCB7IFNvbmFtdSB9IGZyb20gXCIuLi9hcGkvc29uYW11XCI7XG5pbXBvcnQgeyBEQiB9IGZyb20gXCIuLi9kYXRhYmFzZS9kYlwiO1xuaW1wb3J0IHsgdHlwZSBTb25hbXVEQkNvbmZpZyB9IGZyb20gXCIuLi9kYXRhYmFzZS9kYlwiO1xuaW1wb3J0IHsgY3JlYXRlS25leEluc3RhbmNlIH0gZnJvbSBcIi4uL2RhdGFiYXNlL2tuZXhcIjtcbmltcG9ydCB7IFNEIH0gZnJvbSBcIi4uL2RpY3Qvc2RcIjtcbmltcG9ydCB7IHNvbmFtdURpY3Rpb25hcnkgfSBmcm9tIFwiLi4vZGljdC9zb25hbXUtZGljdGlvbmFyeVwiO1xuaW1wb3J0IHsgdHlwZSBFbnRpdHkgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eVwiO1xuaW1wb3J0IHsgRW50aXR5TWFuYWdlciB9IGZyb20gXCIuLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIjtcbmltcG9ydCB7XG4gIEJhZFJlcXVlc3RFeGNlcHRpb24sXG4gIGlzU29FeGNlcHRpb24sXG4gIFNlcnZpY2VVbmF2YWlsYWJsZUV4Y2VwdGlvbixcbn0gZnJvbSBcIi4uL2V4Y2VwdGlvbnMvc28tZXhjZXB0aW9uc1wiO1xuaW1wb3J0IHsgTWlncmF0b3IgfSBmcm9tIFwiLi4vbWlncmF0aW9uL21pZ3JhdG9yXCI7XG5pbXBvcnQgeyB0eXBlIE1pZ3JhdGlvblJlc3VsdCB9IGZyb20gXCIuLi9taWdyYXRpb24vbWlncmF0b3JcIjtcbmltcG9ydCB7IFNsYWNrQ29uZmlybSB9IGZyb20gXCIuLi9taWdyYXRpb24vc2xhY2stY29uZmlybVwiO1xuaW1wb3J0IHsgdHlwZSBTbGFja0NvbmZpcm1QZW5kaW5nUmVzdWx0IH0gZnJvbSBcIi4uL21pZ3JhdGlvbi9zbGFjay1jb25maXJtXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZU1hbmFnZXIgfSBmcm9tIFwiLi4vdGVtcGxhdGUvdGVtcGxhdGUtbWFuYWdlclwiO1xuaW1wb3J0IHsgRGF0YUV4cGxvcmVyIH0gZnJvbSBcIi4uL3Rlc3RpbmcvZGF0YS1leHBsb3JlclwiO1xuaW1wb3J0IHsgRml4dHVyZUdlbmVyYXRvciB9IGZyb20gXCIuLi90ZXN0aW5nL2ZpeHR1cmUtZ2VuZXJhdG9yXCI7XG5pbXBvcnQgeyBGaXh0dXJlTWFuYWdlciB9IGZyb20gXCIuLi90ZXN0aW5nL2ZpeHR1cmUtbWFuYWdlclwiO1xuaW1wb3J0IHsgdHlwZSBEdXBsaWNhdGVDaGVja09wdGlvbnMgfSBmcm9tIFwiLi4vdGVzdGluZy9maXh0dXJlLW1hbmFnZXJcIjtcbmltcG9ydCB7IEJVSUxUX0lOX1RZUEVfSURTLCBUZW1wbGF0ZUtleSB9IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHtcbiAgdHlwZSBDb25lLFxuICB0eXBlIEVudGl0eUluZGV4LFxuICB0eXBlIEVudGl0eVByb3AsXG4gIHR5cGUgRW50aXR5U3Vic2V0Um93LFxuICB0eXBlIEZpeHR1cmVSZWNvcmQsXG4gIHR5cGUgRml4dHVyZVNlYXJjaE9wdGlvbnMsXG4gIHR5cGUgRmxhdHRlblN1YnNldFJvdyxcbiAgdHlwZSBQYXRoQW5kQ29kZSxcbn0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgeyBub25OdWxsYWJsZSB9IGZyb20gXCIuLi91dGlscy91dGlsc1wiO1xuaW1wb3J0IHsgc2V0QWlBcGkgfSBmcm9tIFwiLi9haS1hcGlcIjtcbmltcG9ydCB7IHR5cGUgQ2RkQWRkUnVsZVJlcXVlc3QgfSBmcm9tIFwiLi9jZGQtc2VydmljZVwiO1xuaW1wb3J0IHtcbiAgYWRkUnVsZSxcbiAgZWRpdENvbnRlbnQsXG4gIGdldEFjTGlzdCxcbiAgZ2V0Q2RkVHJlZSxcbiAgbGlzdFJ1bGVzLFxuICBvcGVuU291cmNlRmlsZSxcbiAgcmVhZENvbnRlbnQsXG4gIHJlYWRSdWxlLFxufSBmcm9tIFwiLi9jZGQtc2VydmljZVwiO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc29uYW11VUlBcGlQbHVnaW4oZmFzdGlmeTogRmFzdGlmeUluc3RhbmNlKSB7XG4gIGZhc3RpZnkucmVnaXN0ZXIoXG4gICAgYXN5bmMgKHNlcnZlcikgPT4ge1xuICAgICAgLy8gbWlncmF0b3JcbiAgICAgIGNvbnN0IG1pZ3JhdG9yID0gbmV3IE1pZ3JhdG9yKCk7XG5cbiAgICAgIC8vIHdhaXRGb3JITVJDb21wbGV0ZWRcbiAgICAgIGFzeW5jIGZ1bmN0aW9uIHdhaXRGb3JITVJDb21wbGV0ZWQ8VD4oZm46ICgpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICAgICAgY29uc3Qgd2FpdFByb21pc2UgPSBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGhhbmRsZXIgPSAoKSA9PiB7XG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgICAgICByZXNvbHZlKCk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGNvbnN0IHRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgIFNvbmFtdS5zeW5jZXIuZXZlbnRFbWl0dGVyLm9mZihcIm9uSE1SQ29tcGxldGVkXCIsIGhhbmRsZXIpO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgIH0sIDE1MDApO1xuXG4gICAgICAgICAgU29uYW11LnN5bmNlci5ldmVudEVtaXR0ZXIub25jZShcIm9uSE1SQ29tcGxldGVkXCIsIGhhbmRsZXIpO1xuICAgICAgICB9KTtcblxuICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBmbigpO1xuICAgICAgICBhd2FpdCB3YWl0UHJvbWlzZTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgc2V0QWlBcGkoc2VydmVyKTtcblxuICAgICAgc2VydmVyLmdldChcIi9hcGkvc29uYW11L2NvbmZpZ1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHJldHVybiBTb25hbXUuY29uZmlnO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBRdWVyeXN0cmluZzoge1xuICAgICAgICAgIGVudGl0eUlkPzogc3RyaW5nO1xuICAgICAgICAgIHByZXNldD86IFwidHlwZXNcIiB8IFwiZW50aXR5Lmpzb25cIiB8IFwiZ2VuZXJhdGVkXCI7XG4gICAgICAgICAgYWJzUGF0aD86IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS90b29scy9vcGVuVnNjb2RlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIHByZXNldCwgYWJzUGF0aCB9ID0gcmVxdWVzdC5xdWVyeTtcblxuICAgICAgICBjb25zdCB0YXJnZXRQYXRoID0gKCgpID0+IHtcbiAgICAgICAgICBpZiAoZW50aXR5SWQgJiYgcHJlc2V0KSB7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICBjb25zdCB7IG5hbWVzIH0gPSBlbnRpdHk7XG5cbiAgICAgICAgICAgIGNvbnN0IHsgYXBpUm9vdFBhdGggfSA9IFNvbmFtdTtcbiAgICAgICAgICAgIGNvbnN0IGZpbGVuYW1lID0gKCgpID0+IHtcbiAgICAgICAgICAgICAgc3dpdGNoIChwcmVzZXQpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFwidHlwZXNcIjpcbiAgICAgICAgICAgICAgICAgIHJldHVybiBgJHtuYW1lcy5mc30udHlwZXMudHNgO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJlbnRpdHkuanNvblwiOlxuICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke25hbWVzLmZzfS5lbnRpdHkuanNvbmA7XG4gICAgICAgICAgICAgICAgY2FzZSBcImdlbmVyYXRlZFwiOlxuICAgICAgICAgICAgICAgICAgcmV0dXJuIGAke25hbWVzLmZzfS5nZW5lcmF0ZWQudHNgO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KSgpO1xuICAgICAgICAgICAgcmV0dXJuIGAke2FwaVJvb3RQYXRofS9zcmMvYXBwbGljYXRpb24vJHtlbnRpdHkubmFtZXMucGFyZW50RnN9LyR7ZmlsZW5hbWV9YDtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCFhYnNQYXRoKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLnByZXNldE9yQWJzUGF0aFJlcXVpcmVkXCIpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhYnNQYXRoO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkoKTtcbiAgICAgICAgZXhlY1N5bmMoYGNvZGUgJHt0YXJnZXRQYXRofWApO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBRdWVyeXN0cmluZzoge1xuICAgICAgICAgIG9yaWdpbjogc3RyaW5nO1xuICAgICAgICAgIGVudGl0eUlkPzogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3Rvb2xzL2dldFN1Z2dlc3Rpb25cIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBvcmlnaW4sIGVudGl0eUlkIH0gPSByZXF1ZXN0LnF1ZXJ5O1xuXG4gICAgICAgIC8vIOy5mO2ZmCDsmqnslrTsp5FcbiAgICAgICAgY29uc3QgZ2xvc3NhcnkgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPihbXG4gICAgICAgICAgW1wic3RhdHVzXCIsIFwi7IOB7YOcXCJdLFxuICAgICAgICAgIFtcInR5cGVcIiwgXCLtg4DsnoVcIl0sXG4gICAgICAgICAgW1wiaW1hZ2VcIiwgXCLsnbTrr7jsp4BcIl0sXG4gICAgICAgICAgW1wiaW1hZ2VzXCIsIFwi7J2066+47KeA66as7Iqk7Yq4XCJdLFxuICAgICAgICAgIFtcInVybFwiLCBcIlVSTFwiXSxcbiAgICAgICAgICBbXCJpZFwiLCBcIklEXCJdLFxuICAgICAgICAgIFtcIm5hbWVcIiwgYHtFbnRpdHlJRH3rqoVgXSxcbiAgICAgICAgICBbXCJ0aXRsZVwiLCBcIntFbnRpdHlJRH3rqoVcIl0sXG4gICAgICAgICAgW1wicGFyZW50XCIsIFwi7IOB7JyEe0VudGl0eUlEfVwiXSxcbiAgICAgICAgICBbXCJkZXNjXCIsIFwi7ISk66qFXCJdLFxuICAgICAgICAgIFtcImF0XCIsIFwi7J287IucXCJdLFxuICAgICAgICAgIFtcImNyZWF0ZWRcIiwgXCLrk7HroZ1cIl0sXG4gICAgICAgICAgW1widXBkYXRlZFwiLCBcIuyImOyglVwiXSxcbiAgICAgICAgICBbXCJkZWxldGVkXCIsIFwi7IKt7KCcXCJdLFxuICAgICAgICAgIFtcImJ5XCIsIFwi7Jyg7KCAXCJdLFxuICAgICAgICAgIFtcImRhdGVcIiwgXCLsnbzsnpBcIl0sXG4gICAgICAgICAgW1widGltZVwiLCBcIuyLnOqwhFwiXSxcbiAgICAgICAgICBbXCJrb1wiLCBcIijtlZzquIApXCJdLFxuICAgICAgICAgIFtcImVuXCIsIFwiKOyYgeusuClcIl0sXG4gICAgICAgICAgW1wia3J3XCIsIFwiKOybkClcIl0sXG4gICAgICAgICAgW1widXNkXCIsIFwiKFVTRClcIl0sXG4gICAgICAgICAgW1wiY29sb3JcIiwgXCLsu6zrn6xcIl0sXG4gICAgICAgICAgW1wiY29kZVwiLCBcIuy9lOuTnFwiXSxcbiAgICAgICAgICBbXCJ4XCIsIFwiWOyijO2RnFwiXSxcbiAgICAgICAgICBbXCJ5XCIsIFwiWeyijO2RnFwiXSxcbiAgICAgICAgICBbXCJjdXJyZW50XCIsIFwi7ZiE7J6sXCJdLFxuICAgICAgICAgIFtcInN0b2NrXCIsIFwi7J6s6rOgXCJdLFxuICAgICAgICAgIFtcInRvdGFsXCIsIFwi7LSdXCJdLFxuICAgICAgICAgIFtcImFkbWluXCIsIFwi6rSA66as7J6QXCJdLFxuICAgICAgICAgIFtcImdyb3VwXCIsIFwi6re466O5XCJdLFxuICAgICAgICAgIFtcIml0ZW1cIiwgXCLslYTsnbTthZxcIl0sXG4gICAgICAgICAgW1wiY250XCIsIFwi7IiY65+JXCJdLFxuICAgICAgICAgIFtcInByaWNlXCIsIFwi6rCA6rKpXCJdLFxuICAgICAgICAgIFtcInByZXNldFwiLCBcIu2UhOumrOyFi1wiXSxcbiAgICAgICAgICBbXCJhY2N0XCIsIFwi6rOE7KKMXCJdLFxuICAgICAgICAgIFtcInRlbFwiLCBcIuyghO2ZlOuyiO2YuFwiXSxcbiAgICAgICAgICBbXCJub1wiLCBcIuuyiO2YuFwiXSxcbiAgICAgICAgICBbXCJib2R5XCIsIFwi64K07JqpXCJdLFxuICAgICAgICAgIFtcImNvbnRlbnRcIiwgXCLrgrTsmqlcIl0sXG4gICAgICAgICAgW1wib3JkZXJub1wiLCBcIuygleugrOyInOyEnFwiXSxcbiAgICAgICAgICBbXCJwcmlvcml0eVwiLCBcIuyasOyEoOyInOychFwiXSxcbiAgICAgICAgICBbXCJ0ZXh0XCIsIFwi7YWN7Iqk7Yq4XCJdLFxuICAgICAgICAgIFtcImtleVwiLCBcIu2CpFwiXSxcbiAgICAgICAgICBbXCJzdW1cIiwgXCLtlansgrBcIl0sXG4gICAgICAgICAgW1wiZXhwZWN0ZWRcIiwgXCLsmIjsg4FcIl0sXG4gICAgICAgICAgW1wiYWN0dWFsXCIsIFwi7Iuk7KCcXCJdLFxuICAgICAgICBdKTtcbiAgICAgICAgLy8g7KCE7LK0IOyXlO2LsO2LsCDsiJztmoztlZjrqbAsIOyXlO2LsO2LsCDtg4DsnbTti4Dqs7wg7ZSE66GtIOyEpOuqheydhCDsuZjtmZgg7Jqp7Ja07KeR7JeQIOy2lOqwgFxuICAgICAgICBmb3IgKGNvbnN0IGVudGl0eUlkIG9mIEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCkpIHtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgaWYgKChlbnRpdHkudGl0bGUgPz8gXCJcIikgIT09IFwiXCIpIHtcbiAgICAgICAgICAgIGdsb3NzYXJ5LnNldChpbmZsZWN0aW9uLnVuZGVyc2NvcmUoZW50aXR5LmlkKSwgZW50aXR5LnRpdGxlKTtcbiAgICAgICAgICAgIGdsb3NzYXJ5LnNldChcbiAgICAgICAgICAgICAgaW5mbGVjdGlvbi51bmRlcnNjb3JlKGluZmxlY3Rpb24ucGx1cmFsaXplKGVudGl0eS5pZCkpLFxuICAgICAgICAgICAgICBgJHtlbnRpdHkudGl0bGV966as7Iqk7Yq4YCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZW50aXR5LnByb3BzLmZvckVhY2goKHByb3ApID0+IHtcbiAgICAgICAgICAgIGlmIChnbG9zc2FyeS5oYXMocHJvcC5uYW1lKSkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocHJvcC5kZXNjKSB7XG4gICAgICAgICAgICAgIGdsb3NzYXJ5LnNldChwcm9wLm5hbWUsIHByb3AuZGVzYy5yZXBsYWNlKGVudGl0eS50aXRsZSA/PyBcIlwiLCBcIntFbnRpdHlJRH1cIikpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qgc3VnZ2VzdGVkID0gKCgpID0+IHtcbiAgICAgICAgICAvLyDri6jslrQg67aE66asLCDqsIDriqXtlZwg7KGw7ZWpIOyDneyEsVxuICAgICAgICAgIGNvbnN0IHdvcmRzID0gb3JpZ2luLnNwbGl0KFwiX1wiKTtcbiAgICAgICAgICBjb25zdCBjb21iaW5hdGlvbnMgPSBbLi4ucmFuZ2Uod29yZHMubGVuZ3RoLCAwLCAtMSldLmZsYXRNYXAoKGxlbikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAgICAgLi4ucmFuZ2UoMCwgd29yZHMubGVuZ3RoIC0gbGVuICsgMSwgKGlkeCkgPT4ge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICBsZW4sXG4gICAgICAgICAgICAgICAgICB3OiB3b3Jkcy5zbGljZShpZHgsIGlkeCArIGxlbikuam9pbihcIl9cIiksXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBdO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8g7KGw7ZWp7J2EIOyInO2ajO2VmOupsCwg7LmY7ZmYIOyaqeyWtOynkeyXkCDsnojripQg64uo7Ja06rCAIO2PrO2VqOuQnCDqsr3smrAsIOy5mO2ZmCDsmqnslrTroZwg7LmY7ZmYXG4gICAgICAgICAgY29uc3QgUkVQTEFDRURfUFJFRklYID0gXCIjUkVQTEFDRUQvL1wiOyAvLyDsuZjtmZjrkJwg64uo7Ja066W8IGpvaW4g7J207ZuE7JeQ64+EIOyLneuzhO2VmOq4sCDsnITtlbQgcHJlZml4IOy2lOqwgFxuICAgICAgICAgIGxldCByZW1haW5BcnI6IHN0cmluZ1tdID0gWy4uLndvcmRzXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGNvbWIgb2YgY29tYmluYXRpb25zKSB7XG4gICAgICAgICAgICBjb25zdCByZW1haW5TdHIgPSByZW1haW5BcnIuam9pbihcIl9cIik7XG4gICAgICAgICAgICBpZiAocmVtYWluU3RyLmluY2x1ZGVzKGNvbWIudykgJiYgZ2xvc3NhcnkuaGFzKGNvbWIudykpIHtcbiAgICAgICAgICAgICAgcmVtYWluQXJyID0gcmVtYWluU3RyXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoY29tYi53LCBSRVBMQUNFRF9QUkVGSVggKyBnbG9zc2FyeS5nZXQoY29tYi53KSlcbiAgICAgICAgICAgICAgICAuc3BsaXQoXCJfXCIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiByZW1haW5BcnJcbiAgICAgICAgICAgIC5tYXAoKHIpID0+IHtcbiAgICAgICAgICAgICAgaWYgKHIuc3RhcnRzV2l0aChSRVBMQUNFRF9QUkVGSVgpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHIucmVwbGFjZShSRVBMQUNFRF9QUkVGSVgsIFwiXCIpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiByLnRvVXBwZXJDYXNlKCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuam9pbihcIlwiKVxuICAgICAgICAgICAgLnJlcGxhY2UoL3tFbnRpdHlJRH0vZywgZW50aXR5SWQgPyBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCkudGl0bGUgOiBcIlwiKTtcbiAgICAgICAgfSkoKTtcblxuICAgICAgICByZXR1cm4geyBzdWdnZXN0ZWQgfTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS9lbnRpdHkvZmluZE1hbnlcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBlbnRpdHlJZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuXG4gICAgICAgIGZ1bmN0aW9uIGZsYXR0ZW5TdWJzZXRSb3dzKHN1YnNldFJvd3M6IEVudGl0eVN1YnNldFJvd1tdKTogRmxhdHRlblN1YnNldFJvd1tdIHtcbiAgICAgICAgICByZXR1cm4gc3Vic2V0Um93cy5mbGF0TWFwKChzdWJzZXRSb3cpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHsgY2hpbGRyZW4sIC4uLnNSb3cgfSA9IHN1YnNldFJvdztcbiAgICAgICAgICAgIHJldHVybiBbc1JvdywgLi4uZmxhdHRlblN1YnNldFJvd3MoY2hpbGRyZW4pXTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGVudGl0aWVzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgZW50aXR5SWRzLm1hcCgoZW50aXR5SWQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGNvbnN0IHN1YnNldFJvd3MgPSBlbnRpdHkuZ2V0U3Vic2V0Um93cygpO1xuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAuLi5lbnRpdHksXG4gICAgICAgICAgICAgIGZsYXR0ZW5TdWJzZXRSb3dzOiBmbGF0dGVuU3Vic2V0Um93cyhzdWJzZXRSb3dzKSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG5cbiAgICAgICAgZW50aXRpZXMuc29ydCgoYSwgYikgPT4ge1xuICAgICAgICAgIGNvbnN0IGFJZCA9IGEucGFyZW50SWQgPz8gYS5pZDtcbiAgICAgICAgICBjb25zdCBiSWQgPSBiLnBhcmVudElkID8/IGIuaWQ7XG4gICAgICAgICAgaWYgKGFJZCA8IGJJZCkgcmV0dXJuIC0xO1xuICAgICAgICAgIGlmIChhSWQgPiBiSWQpIHJldHVybiAxO1xuICAgICAgICAgIGlmIChhSWQgPT09IGJJZCkge1xuICAgICAgICAgICAgaWYgKGEucGFyZW50SWQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIC0xO1xuICAgICAgICAgICAgaWYgKGIucGFyZW50SWQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIDE7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4geyBlbnRpdGllcyB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBRdWVyeXN0cmluZzoge1xuICAgICAgICAgIGZpbHRlcj86IFwiZW51bXNcIiB8IFwidHlwZXNcIjtcbiAgICAgICAgICByZWxvYWQ/OiBcIjFcIjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvdHlwZUlkc1wiLCBhc3luYyAocmVxdWVzdCk6IFByb21pc2U8eyB0eXBlSWRzOiBzdHJpbmdbXSB9PiA9PiB7XG4gICAgICAgIGNvbnN0IHsgZmlsdGVyLCByZWxvYWQgfSA9IHJlcXVlc3QucXVlcnk7XG5cbiAgICAgICAgaWYgKHJlbG9hZCA9PT0gXCIxXCIpIHtcbiAgICAgICAgICBhd2FpdCBTb25hbXUuc3luY2VyLmF1dG9sb2FkVHlwZXMoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHR5cGVJZHMgPSAoKCkgPT4ge1xuICAgICAgICAgIC8vIO2UhOuhnOygne2KuOyXkOyEnCDsoJXsnZjtlZwg7YOA7J6F65OkXG4gICAgICAgICAgY29uc3QgcHJvamVjdFR5cGVJZHMgPSBPYmplY3QuZW50cmllcyhTb25hbXUuc3luY2VyLnR5cGVzKVxuICAgICAgICAgICAgLmZpbHRlcigoW190eXBlSWQsIHpvZFR5cGVdKSA9PiAoem9kVHlwZS5fem9kLmRlZi50eXBlIGFzIHN0cmluZykgIT09IFwiZW51bVwiKVxuICAgICAgICAgICAgLm1hcCgoW3R5cGVJZCwgX3pvZFR5cGVdKSA9PiB0eXBlSWQpO1xuXG4gICAgICAgICAgLy8g64K07J6lIO2DgOyeheuTpCAoc29uYW11IOy9lOyWtOyXkOyEnCDsoJzqs7UpXG4gICAgICAgICAgY29uc3QgYnVpbHRJblR5cGVJZHMgPSBbLi4uQlVJTFRfSU5fVFlQRV9JRFNdO1xuXG4gICAgICAgICAgLy8g66qo65OgIO2DgOyehSDrs5HtlalcbiAgICAgICAgICBjb25zdCBhbGxUeXBlSWRzID0gWy4uLmJ1aWx0SW5UeXBlSWRzLCAuLi5wcm9qZWN0VHlwZUlkc107XG5cbiAgICAgICAgICBpZiAoZmlsdGVyID09PSBcInR5cGVzXCIpIHtcbiAgICAgICAgICAgIHJldHVybiBhbGxUeXBlSWRzO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IGVudW1JZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpLmZsYXRNYXAoKGVudGl0eUlkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMoZW50aXR5LmVudW1MYWJlbHMpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKGZpbHRlciA9PT0gXCJlbnVtc1wiKSB7XG4gICAgICAgICAgICByZXR1cm4gZW51bUlkcztcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIFsuLi5hbGxUeXBlSWRzLCAuLi5lbnVtSWRzXTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pKCk7XG5cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0eXBlSWRzLFxuICAgICAgICB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGZvcm06IHtcbiAgICAgICAgICAgIGlkOiBzdHJpbmc7XG4gICAgICAgICAgICB0aXRsZTogc3RyaW5nO1xuICAgICAgICAgICAgdGFibGU6IHN0cmluZztcbiAgICAgICAgICAgIHBhcmVudElkPzogc3RyaW5nO1xuICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2NyZWF0ZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBmb3JtIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgYXdhaXQgU29uYW11LnN5bmNlci5jcmVhdGVFbnRpdHkoeyAuLi5mb3JtLCBlbnRpdHlJZDogZm9ybS5pZCB9KTtcblxuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9kZWxcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgU29uYW11LnN5bmNlci5kZWxFbnRpdHkoZW50aXR5SWQpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIG5ld1ZhbHVlczoge1xuICAgICAgICAgICAgdGl0bGU6IHN0cmluZztcbiAgICAgICAgICAgIHRhYmxlOiBzdHJpbmc7XG4gICAgICAgICAgICBwYXJlbnRJZD86IHN0cmluZztcbiAgICAgICAgICB9O1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb2RpZnlFbnRpdHlCYXNlXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBuZXdWYWx1ZXMgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZW50aXR5LnRpdGxlID0gbmV3VmFsdWVzLnRpdGxlO1xuICAgICAgICAgIGVudGl0eS50YWJsZSA9IG5ld1ZhbHVlcy50YWJsZTtcbiAgICAgICAgICBlbnRpdHkucGFyZW50SWQgPSBuZXdWYWx1ZXMucGFyZW50SWQ7XG4gICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcblxuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIHN1YnNldEtleTogc3RyaW5nO1xuICAgICAgICAgIGZpZWxkczogc3RyaW5nW107XG4gICAgICAgICAgZmllbGRzSW50ZXJuYWw/OiBzdHJpbmdbXTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvbW9kaWZ5U3Vic2V0XCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBzdWJzZXRLZXksIGZpZWxkcywgZmllbGRzSW50ZXJuYWwgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZW50aXR5LnN1YnNldHNbc3Vic2V0S2V5XSA9IGZpZWxkcztcbiAgICAgICAgICBpZiAoZmllbGRzSW50ZXJuYWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgaWYgKGZpZWxkc0ludGVybmFsLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgZW50aXR5LnN1YnNldHNJbnRlcm5hbFtzdWJzZXRLZXldID0gZmllbGRzSW50ZXJuYWw7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBkZWxldGUgZW50aXR5LnN1YnNldHNJbnRlcm5hbFtzdWJzZXRLZXldO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgcmV0dXJuIHsgdXBkYXRlZDogZmllbGRzLCB1cGRhdGVkSW50ZXJuYWw6IGZpZWxkc0ludGVybmFsIH07XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgc3Vic2V0S2V5OiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2RlbFN1YnNldFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgc3Vic2V0S2V5IH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgIGRlbGV0ZSBlbnRpdHkuc3Vic2V0c1tzdWJzZXRLZXldO1xuICAgICAgICAgIGRlbGV0ZSBlbnRpdHkuc3Vic2V0c0ludGVybmFsW3N1YnNldEtleV07XG4gICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcblxuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIG5ld1Byb3A6IEVudGl0eVByb3A7XG4gICAgICAgICAgYXQ/OiBudW1iZXI7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2NyZWF0ZVByb3BcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGF0LCBuZXdQcm9wIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgIGF3YWl0IGVudGl0eS5jcmVhdGVQcm9wKG5ld1Byb3AsIGF0KTtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBuZXdQcm9wOiBFbnRpdHlQcm9wO1xuICAgICAgICAgIGF0OiBudW1iZXI7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L21vZGlmeVByb3BcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGF0LCBuZXdQcm9wIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZW50aXR5Lm1vZGlmeVByb3AobmV3UHJvcCwgYXQpO1xuXG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgYXQ6IG51bWJlcjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9lbnRpdHkvZGVsUHJvcFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgYXQgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICBlbnRpdHkuZGVsUHJvcChhdCk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgYXQ6IG51bWJlcjtcbiAgICAgICAgICB0bzogbnVtYmVyO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb3ZlUHJvcFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgYXQsIHRvIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZW50aXR5Lm1vdmVQcm9wKGF0LCB0byk7XG5cbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICBpbmRleGVzOiBFbnRpdHlJbmRleFtdO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9tb2RpZnlJbmRleGVzXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIHJldHVybiBhd2FpdCB3YWl0Rm9ySE1SQ29tcGxldGVkKGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCB7IGVudGl0eUlkLCBpbmRleGVzIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgIGVudGl0eS5pbmRleGVzID0gaW5kZXhlcztcbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgcmV0dXJuIHsgdXBkYXRlZDogaW5kZXhlcyB9O1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIGVudW1MYWJlbHM6IEVudGl0eVtcImVudW1MYWJlbHNcIl07XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L21vZGlmeUVudW1MYWJlbHNcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGVudW1MYWJlbHMgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZW50aXR5LmVudW1MYWJlbHMgPSBlbnVtTGFiZWxzO1xuICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG5cbiAgICAgICAgICByZXR1cm4geyB1cGRhdGVkOiBlbnVtTGFiZWxzIH07XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgbmV3RW51bUlkOiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2NyZWF0ZUVudW1JZFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgbmV3RW51bUlkIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuXG4gICAgICAgICAgaWYgKGVudGl0eS5lbnVtTGFiZWxzW25ld0VudW1JZF0pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg7J2066+4IOyhtOyerO2VmOuKlCBlbnVtSWTsnoXri4jri6Q6ICR7bmV3RW51bUlkfWApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGVudGl0eS5lbnVtTGFiZWxzW25ld0VudW1JZF0gPSBuZXdFbnVtSWQuZW5kc1dpdGgoXCJTdGF0dXNcIilcbiAgICAgICAgICAgID8ge1xuICAgICAgICAgICAgICAgIGFjdGl2ZTogXCLrhbjstpxcIixcbiAgICAgICAgICAgICAgICBoaWRkZW46IFwi7Iio6rmAXCIsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgIFwiXCI6IFwiXCIsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcblxuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIGVudW1JZDoge1xuICAgICAgICAgICAgYmVmb3JlOiBzdHJpbmc7XG4gICAgICAgICAgICBhZnRlcjogc3RyaW5nO1xuICAgICAgICAgIH07XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L21vZGlmeUVudW1JZFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgZW51bUlkIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgY29uc3QgZW50aXR5SWRzID0gRW50aXR5TWFuYWdlci5nZXRBbGxJZHMoKTtcbiAgICAgICAgICBjb25zdCBpc0V4aXN0cyA9IGVudGl0eUlkcy5zb21lKChlbnRpdHlJZCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGVudGl0eS5lbnVtTGFiZWxzKS5pbmNsdWRlcyhlbnVtSWQuYWZ0ZXIpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChpc0V4aXN0cykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDsnbTrr7gg7KG07J6s7ZWY64qUIEVudW1JZOyeheuLiOuLpDogJHtlbnVtSWQuYWZ0ZXJ9YCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgIGVudGl0eS5lbnVtTGFiZWxzW2VudW1JZC5hZnRlcl0gPSBlbnRpdHkuZW51bUxhYmVsc1tlbnVtSWQuYmVmb3JlXTtcbiAgICAgICAgICBkZWxldGUgZW50aXR5LmVudW1MYWJlbHNbZW51bUlkLmJlZm9yZV07XG5cbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuXG4gICAgICAgICAgZm9yIChjb25zdCBlbnRpdHlJZCBvZiBlbnRpdHlJZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgcHJvcCBvZiBlbnRpdHkucHJvcHMpIHtcbiAgICAgICAgICAgICAgaWYgKHByb3AudHlwZSA9PT0gXCJlbnVtXCIgJiYgcHJvcC5pZCA9PT0gZW51bUlkLmJlZm9yZSkge1xuICAgICAgICAgICAgICAgIHByb3AuaWQgPSBlbnVtSWQuYWZ0ZXI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IGVudGl0eS5zYXZlKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIGVudW1JZDogc3RyaW5nO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9kZWxldGVFbnVtSWRcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIGVudW1JZCB9ID0gcmVxdWVzdC5ib2R5O1xuXG4gICAgICAgICAgY29uc3QgZW50aXR5SWRzID0gRW50aXR5TWFuYWdlci5nZXRBbGxJZHMoKTtcbiAgICAgICAgICBjb25zdCBpc1JlZmVyZW5jZWQgPSBlbnRpdHlJZHNcbiAgICAgICAgICAgIC5mbGF0TWFwKChlbnRpdHlJZCkgPT4gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpLnByb3BzKVxuICAgICAgICAgICAgLnNvbWUoKHByb3ApID0+IHByb3AudHlwZSA9PT0gXCJlbnVtXCIgJiYgcHJvcC5pZCA9PT0gZW51bUlkKTtcbiAgICAgICAgICBpZiAoaXNSZWZlcmVuY2VkKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZW51bUlkfeulvCDssLjsobDtlZjripQg7ZSE66Gc7Y287Yuw6rCAIOyhtOyerO2VqeuLiOuLpC5gKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgICAgZGVsZXRlIGVudGl0eS5lbnVtTGFiZWxzW2VudW1JZF07XG4gICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICB0YXJnZXQ6IFwiZW50aXR5XCIgfCBcInByb3BcIiB8IFwiZW51bVwiIHwgXCJzdWJzZXRcIjtcbiAgICAgICAgICBwcm9wTmFtZT86IHN0cmluZztcbiAgICAgICAgICBlbnVtSWQ/OiBzdHJpbmc7XG4gICAgICAgICAgc3Vic2V0S2V5Pzogc3RyaW5nO1xuICAgICAgICAgIGNvbmU6IENvbmU7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L3VwZGF0ZUNvbmVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IHdhaXRGb3JITVJDb21wbGV0ZWQoYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHsgZW50aXR5SWQsIHRhcmdldCwgcHJvcE5hbWUsIGVudW1JZCwgc3Vic2V0S2V5LCBjb25lIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuXG4gICAgICAgICAgaWYgKHRhcmdldCA9PT0gXCJlbnRpdHlcIikge1xuICAgICAgICAgICAgZW50aXR5LmNvbmUgPSBjb25lO1xuICAgICAgICAgIH0gZWxzZSBpZiAodGFyZ2V0ID09PSBcInByb3BcIiAmJiBwcm9wTmFtZSkge1xuICAgICAgICAgICAgY29uc3QgcHJvcCA9IGVudGl0eS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IHByb3BOYW1lKTtcbiAgICAgICAgICAgIGlmIChwcm9wKSB7XG4gICAgICAgICAgICAgIChwcm9wIGFzIHsgY29uZT86IENvbmUgfSkuY29uZSA9IGNvbmU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmICh0YXJnZXQgPT09IFwiZW51bVwiICYmIGVudW1JZCkge1xuICAgICAgICAgICAgZW50aXR5LmVudW1Db25lc1tlbnVtSWRdID0gY29uZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHRhcmdldCA9PT0gXCJzdWJzZXRcIiAmJiBzdWJzZXRLZXkpIHtcbiAgICAgICAgICAgIGVudGl0eS5zdWJzZXRDb25lc1tzdWJzZXRLZXldID0gY29uZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBhd2FpdCBlbnRpdHkuc2F2ZSgpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgIHByZXNlcnZlRXhpc3Rpbmc/OiBib29sZWFuO1xuICAgICAgICAgIG9ubHlFbXB0eT86IGJvb2xlYW47XG4gICAgICAgICAgbG9jYWxlPzogXCJrb1wiIHwgXCJlblwiIHwgXCJqYVwiO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL2VudGl0eS9nZW5lcmF0ZUNvbmVzXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgd2FpdEZvckhNUkNvbXBsZXRlZChhc3luYyAoKSA9PiB7XG4gICAgICAgICAgY29uc3QgeyBlbnRpdHlJZCwgcHJlc2VydmVFeGlzdGluZywgb25seUVtcHR5LCBsb2NhbGUgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBFbnRpdHkg7KG07J6sIOyXrOu2gCDtmZXsnbhcbiAgICAgICAgICAgIGNvbnN0IGVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKTtcblxuICAgICAgICAgICAgLy8gbG9jYWxlIOq4sOuzuOqwkjogU29uYW11LmNvbmZpZy5pMThuLmRlZmF1bHRMb2NhbGUg7IKs7JqpXG4gICAgICAgICAgICBjb25zdCBlZmZlY3RpdmVMb2NhbGUgPVxuICAgICAgICAgICAgICBsb2NhbGUgPz8gKFNvbmFtdS5jb25maWcuaTE4bi5kZWZhdWx0TG9jYWxlIGFzIFwia29cIiB8IFwiZW5cIiB8IFwiamFcIik7XG5cbiAgICAgICAgICAgIC8vIENvbmUg7IOd7ISxXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlbnRpdHkuZ2VuZXJhdGVDb25lcyh7XG4gICAgICAgICAgICAgIHByZXNlcnZlRXhpc3Rpbmc6IHByZXNlcnZlRXhpc3RpbmcgPz8gdHJ1ZSxcbiAgICAgICAgICAgICAgb25seUVtcHR5OiBvbmx5RW1wdHkgPz8gZmFsc2UsXG4gICAgICAgICAgICAgIGxvY2FsZTogZWZmZWN0aXZlTG9jYWxlLFxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgICAgICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvcik7XG5cbiAgICAgICAgICAgIC8vIEVudGl0eSBub3QgZm91bmRcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKFwi7KG07J6s7ZWY7KeAIOyViuuKlCBFbnRpdHlcIikpIHtcbiAgICAgICAgICAgICAgcmVwbHkuc3RhdHVzKDQwNCk7XG4gICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICAgICAgZXJyb3I6IGBFbnRpdHkgbm90IGZvdW5kOiAke2VudGl0eUlkfWAsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEFQSSDtgqQg7JeG7J2MXG4gICAgICAgICAgICBpZiAobWVzc2FnZS5pbmNsdWRlcyhcIkFOVEhST1BJQ19BUElfS0VZIG5vdCBmb3VuZFwiKSkge1xuICAgICAgICAgICAgICByZXBseS5zdGF0dXMoNTAwKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBlcnJvcjogXCJBUEkga2V5IG5vdCBjb25maWd1cmVkXCIsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJhdGUgbGltaXRcbiAgICAgICAgICAgIGlmIChtZXNzYWdlLmluY2x1ZGVzKFwiUmF0ZSBsaW1pdCBleGNlZWRlZFwiKSkge1xuICAgICAgICAgICAgICByZXBseS5zdGF0dXMoNDI5KTtcbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICBlcnJvcjogXCJSYXRlIGxpbWl0IGV4Y2VlZGVkLiBQbGVhc2UgdHJ5IGFnYWluIGxhdGVyLlwiLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyDquLDtg4Ag7JeQ65+sXG4gICAgICAgICAgICByZXBseS5zdGF0dXMoNTAwKTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHN1Y2Nlc3M6IGZhbHNlLFxuICAgICAgICAgICAgICBlcnJvcjogYENvbmUgZ2VuZXJhdGlvbiBmYWlsZWQ6ICR7bWVzc2FnZX1gLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBRdWVyeXN0cmluZzoge1xuICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvZW50aXR5L2dldFRhYmxlQ29sdW1uc1wiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IGVudGl0eUlkIH0gPSByZXF1ZXN0LnF1ZXJ5O1xuICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG4gICAgICAgIGNvbnN0IGNvbHVtbnMgPSBlbnRpdHkuZ2V0VGFibGVDb2x1bW5zKCk7XG4gICAgICAgIHJldHVybiB7IGNvbHVtbnMgfTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS9taWdyYXRpb25zL3N0YXR1c1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IGF3YWl0IG1pZ3JhdG9yLmdldFN0YXR1cygpO1xuXG4gICAgICAgIHJldHVybiB7IHN0YXR1cyB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGFjdGlvbjogXCJhcHBseVwiIHwgXCJyb2xsYmFja1wiIHwgXCJzaGFkb3dcIjtcbiAgICAgICAgICB0YXJnZXRzOiAoa2V5b2YgU29uYW11REJDb25maWcpW107XG4gICAgICAgICAgZm9yY2U/OiBib29sZWFuO1xuICAgICAgICAgIGZvcmNlUmVhc29uPzogc3RyaW5nO1xuICAgICAgICAgIHJlcXVlc3Rvcj86IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFxuICAgICAgICBcIi9hcGkvbWlncmF0aW9ucy9ydW5BY3Rpb25cIixcbiAgICAgICAgYXN5bmMgKHJlcXVlc3QpOiBQcm9taXNlPE1pZ3JhdGlvblJlc3VsdCB8IFNsYWNrQ29uZmlybVBlbmRpbmdSZXN1bHQ+ID0+IHtcbiAgICAgICAgICBjb25zdCB7IGFjdGlvbiwgdGFyZ2V0cywgZm9yY2UsIGZvcmNlUmVhc29uLCByZXF1ZXN0b3IgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAgIGlmIChhY3Rpb24gPT09IFwic2hhZG93XCIpIHtcbiAgICAgICAgICAgIHJldHVybiBtaWdyYXRvci5ydW5TaGFkb3dUZXN0KCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gU2xhY2sg7Iq57J24IOyytO2BrCAoYXBwbHkg7Iuc7JeQ66eMKVxuICAgICAgICAgIGlmIChhY3Rpb24gPT09IFwiYXBwbHlcIikge1xuICAgICAgICAgICAgY29uc3Qgc2xhY2tDb25maXJtID0gbmV3IFNsYWNrQ29uZmlybSgpO1xuICAgICAgICAgICAgY29uc3QgcmVxdWlyZXNBcHByb3ZhbCA9IHRhcmdldHMuc29tZSgodCkgPT4gc2xhY2tDb25maXJtLmlzVGFyZ2V0UmVxdWlyZXNBcHByb3ZhbCh0KSk7XG5cbiAgICAgICAgICAgIC8vIOuhnOy7rCBEQuyduCDqsr3smrAg7Iq57J24IOyKpO2CtVxuICAgICAgICAgICAgY29uc3QgbG9jYWxIb3N0cyA9IFtcImxvY2FsaG9zdFwiLCBcIjEyNy4wLjAuMVwiLCBcIjAuMC4wLjBcIiwgXCI6OjFcIl07XG4gICAgICAgICAgICBjb25zdCBpc0xvY2FsVGFyZ2V0ID0gdGFyZ2V0cy5ldmVyeSgodGFyZ2V0KSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IHRhcmdldENvbmZpZyA9IFNvbmFtdS5kYkNvbmZpZ1t0YXJnZXRdO1xuICAgICAgICAgICAgICBjb25zdCBob3N0ID0gKHRhcmdldENvbmZpZz8uY29ubmVjdGlvbiBhcyB7IGhvc3Q/OiBzdHJpbmcgfSk/Lmhvc3QgPz8gXCJsb2NhbGhvc3RcIjtcbiAgICAgICAgICAgICAgcmV0dXJuIGxvY2FsSG9zdHMuaW5jbHVkZXMoaG9zdC50b0xvd2VyQ2FzZSgpKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAocmVxdWlyZXNBcHByb3ZhbCAmJiBzbGFja0NvbmZpcm0uaXNDb25maWd1cmVkKCkgJiYgIWlzTG9jYWxUYXJnZXQpIHtcbiAgICAgICAgICAgICAgY29uc3QgeyBjb25ucyB9ID0gYXdhaXQgbWlncmF0b3IuZ2V0U3RhdHVzKCk7XG5cbiAgICAgICAgICAgICAgLy8g66qo65OgIO2DgOqynyBEQuyXkOyEnCBwZW5kaW5n7J24IOuniOydtOq3uOugiOydtOyFmOydmCDtlansp5HtlansnYQg6rWs7ZWp64uI64ukLlxuICAgICAgICAgICAgICBjb25zdCBwZW5kaW5nTWlncmF0aW9ucyA9IFtcbiAgICAgICAgICAgICAgICAuLi5uZXcgU2V0KFxuICAgICAgICAgICAgICAgICAgY29ubnNcbiAgICAgICAgICAgICAgICAgICAgLmZpbHRlcigoY29ubikgPT4gdGFyZ2V0cy5pbmNsdWRlcyhjb25uLmNvbm5LZXkpKVxuICAgICAgICAgICAgICAgICAgICAuZmxhdE1hcCgoY29ubikgPT4gY29ubi5wZW5kaW5nKSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICBdO1xuXG4gICAgICAgICAgICAgIGlmIChwZW5kaW5nTWlncmF0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgLy8g6riw7KG0IOyKueyduCDsmpTssq0g7ZmV7J24XG4gICAgICAgICAgICAgICAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBzbGFja0NvbmZpcm0uZ2V0RXhpc3RpbmdSZXF1ZXN0KHBlbmRpbmdNaWdyYXRpb25zKTtcblxuICAgICAgICAgICAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICAgICAgICAgICAgLy8g6riw7KG0IOyalOyyreydtCDsnojsnLzrqbQg7Iq57J24IOyDge2DnCDtmZXsnbhcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHsgYXBwcm92ZWQsIHJlamVjdGVkIH0gPSBhd2FpdCBzbGFja0NvbmZpcm0uY2hlY2tBcHByb3ZhbChcbiAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcuY2hhbm5lbCxcbiAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcudHMsXG4gICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICBpZiAoYXBwcm92ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g7Iq57J2465CoIOKGkiDsi6TtlolcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbWlncmF0b3IucnVuQWN0aW9uKGFjdGlvbiwgdGFyZ2V0cyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHNsYWNrQ29uZmlybS5sb2dFeGVjdXRpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZy5jaGFubmVsLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcudHMsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0b3IsXG4gICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZWplY3RlZCkge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5taWdyYXRpb25SZWplY3RlZFwiKSk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGZvcmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEZvcmNlIOynhO2WiVxuICAgICAgICAgICAgICAgICAgICBhd2FpdCBzbGFja0NvbmZpcm0uZm9yY2VBcHByb3ZhbChcbiAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZy5jaGFubmVsLFxuICAgICAgICAgICAgICAgICAgICAgIGV4aXN0aW5nLnRzLFxuICAgICAgICAgICAgICAgICAgICAgIGZvcmNlUmVhc29uID8/IFwi7IKs7JygIOyXhuydjFwiLFxuICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RvcixcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbWlncmF0b3IucnVuQWN0aW9uKGFjdGlvbiwgdGFyZ2V0cyk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHNsYWNrQ29uZmlybS5sb2dFeGVjdXRpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICBleGlzdGluZy5jaGFubmVsLFxuICAgICAgICAgICAgICAgICAgICAgICAgZXhpc3RpbmcudHMsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQsXG4gICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0b3IsXG4gICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g64yA6riw7KSRXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJwZW5kaW5nXCIsXG4gICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbDogZXhpc3RpbmcuY2hhbm5lbCxcbiAgICAgICAgICAgICAgICAgICAgICB0czogZXhpc3RpbmcudHMsXG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIC8vIOyDiCDsirnsnbgg7JqU7LKtIOuwnOyGoVxuICAgICAgICAgICAgICAgICAgY29uc3QgeyBjaGFubmVsLCB0cyB9ID0gYXdhaXQgc2xhY2tDb25maXJtLnBvc3RBcHByb3ZhbFJlcXVlc3QoXG4gICAgICAgICAgICAgICAgICAgIHBlbmRpbmdNaWdyYXRpb25zLFxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRzLFxuICAgICAgICAgICAgICAgICAgICByZXF1ZXN0b3IsXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgYXdhaXQgc2xhY2tDb25maXJtLnNhdmVSZXF1ZXN0KHBlbmRpbmdNaWdyYXRpb25zLCBjaGFubmVsLCB0cyk7XG5cbiAgICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICAgIHR5cGU6IFwicGVuZGluZ1wiLFxuICAgICAgICAgICAgICAgICAgICBjaGFubmVsLFxuICAgICAgICAgICAgICAgICAgICB0cyxcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIG1pZ3JhdG9yLnJ1bkFjdGlvbihhY3Rpb24sIHRhcmdldHMpO1xuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgY2hhbm5lbDogc3RyaW5nO1xuICAgICAgICAgIHRzOiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvbWlncmF0aW9ucy9jaGVja0FwcHJvdmFsXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgY2hhbm5lbCwgdHMgfSA9IHJlcXVlc3QuYm9keTtcbiAgICAgICAgY29uc3Qgc2xhY2tDb25maXJtID0gbmV3IFNsYWNrQ29uZmlybSgpO1xuXG4gICAgICAgIGlmICghc2xhY2tDb25maXJtLmlzQ29uZmlndXJlZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIHsgYXBwcm92ZWQ6IHRydWUsIHJlamVjdGVkOiBmYWxzZSB9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNsYWNrQ29uZmlybS5jaGVja0FwcHJvdmFsKGNoYW5uZWwsIHRzKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBjaGFubmVsOiBzdHJpbmc7XG4gICAgICAgICAgdHM6IHN0cmluZztcbiAgICAgICAgICByZWFzb246IHN0cmluZztcbiAgICAgICAgICByZXF1ZXN0b3I/OiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvbWlncmF0aW9ucy9mb3JjZUFwcHJvdmFsXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgY2hhbm5lbCwgdHMsIHJlYXNvbiwgcmVxdWVzdG9yIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgIGNvbnN0IHNsYWNrQ29uZmlybSA9IG5ldyBTbGFja0NvbmZpcm0oKTtcblxuICAgICAgICBpZiAoIXNsYWNrQ29uZmlybS5pc0NvbmZpZ3VyZWQoKSkge1xuICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLnNsYWNrQ29uZmlybU5vdENvbmZpZ3VyZWRcIikpO1xuICAgICAgICB9XG5cbiAgICAgICAgYXdhaXQgc2xhY2tDb25maXJtLmZvcmNlQXBwcm92YWwoY2hhbm5lbCwgdHMsIHJlYXNvbiwgcmVxdWVzdG9yKTtcbiAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGNvZGVOYW1lczogc3RyaW5nW107XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvbWlncmF0aW9ucy9kZWxDb2Rlc1wiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IGNvZGVOYW1lcyB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICByZXR1cm4gYXdhaXQgbWlncmF0b3IuZGVsQ29kZXMoY29kZU5hbWVzKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdChcIi9hcGkvbWlncmF0aW9ucy9nZW5lcmF0ZVByZXBhcmVkQ29kZXNcIiwgYXN5bmMgKF9yZXF1ZXN0dCkgPT4ge1xuICAgICAgICByZXR1cm4gYXdhaXQgbWlncmF0b3IuZ2VuZXJhdGVQcmVwYXJlZENvZGVzKCk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5SWRzOiBzdHJpbmdbXTtcbiAgICAgICAgICB0ZW1wbGF0ZUtleXM6IHN0cmluZ1tdO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3NjYWZmb2xkaW5nL2dldFN0YXR1c1wiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IGVudGl0eUlkcywgdGVtcGxhdGVLZXlzOiBfdGVtcGxhdGVLZXlzIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgIGlmICgoZW50aXR5SWRzID8/IFtdKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5lbnRpdHlJZHNSZXF1aXJlZFwiKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoKF90ZW1wbGF0ZUtleXMgPz8gW10pLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLnRlbXBsYXRlS2V5c1JlcXVpcmVkXCIpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHNvcnRpbmdcbiAgICAgICAgZW50aXR5SWRzLnNvcnQoKGEsIGIpID0+IChhIDwgYiA/IC0xIDogYSA+IGIgPyAxIDogMCkpO1xuICAgICAgICBjb25zdCB0ZW1wbGF0ZUtleXMgPSBUZW1wbGF0ZUtleS5vcHRpb25zLmZpbHRlcigodGspID0+IF90ZW1wbGF0ZUtleXMuaW5jbHVkZXModGspKTtcblxuICAgICAgICBjb25zdCBjb21iaW5hdGlvbnMgPSBlbnRpdHlJZHMuZmxhdE1hcCgoZW50aXR5SWQpID0+IHtcbiAgICAgICAgICByZXR1cm4gdGVtcGxhdGVLZXlzLm1hcCgodGVtcGxhdGVLZXkpID0+IFtlbnRpdHlJZCwgdGVtcGxhdGVLZXldKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3Qgc3RhdHVzZXMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgICAgICBjb21iaW5hdGlvbnMubWFwKGFzeW5jIChbZW50aXR5SWQsIHRlbXBsYXRlS2V5XSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgeyBzdWJQYXRoLCBmdWxsUGF0aCwgaXNFeGlzdHMgfSA9IGF3YWl0IFNvbmFtdS5zeW5jZXIuY2hlY2tFeGlzdHNHZW5Db2RlKFxuICAgICAgICAgICAgICBlbnRpdHlJZCxcbiAgICAgICAgICAgICAgdGVtcGxhdGVLZXkgYXMgVGVtcGxhdGVLZXksXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgZW50aXR5SWQsXG4gICAgICAgICAgICAgIHRlbXBsYXRlS2V5LFxuICAgICAgICAgICAgICBzdWJQYXRoLFxuICAgICAgICAgICAgICBmdWxsUGF0aCxcbiAgICAgICAgICAgICAgaXNFeGlzdHMsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm4geyBzdGF0dXNlcyB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgICB0ZW1wbGF0ZUtleTogc3RyaW5nO1xuICAgICAgICAgICAgZW51bUlkPzogc3RyaW5nO1xuICAgICAgICAgICAgb3ZlcndyaXRlPzogYm9vbGVhbjtcbiAgICAgICAgICB9W107XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvc2NhZmZvbGRpbmcvZ2VuZXJhdGVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBvcHRpb25zIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgIGlmIChvcHRpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBCYWRSZXF1ZXN0RXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLm9wdGlvbnNSZXF1aXJlZFwiKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyAxLiDrqqjrk6Ag7YWc7ZSM66a/7JeQ7IScIO2VhOyalO2VnCBkaWN0IO2CpOulvCDsiJjsp5FcbiAgICAgICAgY29uc3Qga2V5cyA9IG9wdGlvbnMuZmxhdE1hcCgoeyB0ZW1wbGF0ZUtleSB9KSA9PiB7XG4gICAgICAgICAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZU1hbmFnZXIuZ2V0KHRlbXBsYXRlS2V5KTtcbiAgICAgICAgICByZXR1cm4gdGVtcGxhdGUuZ2V0UmVxdWlyZWREaWN0S2V5cygpID8/IFtdO1xuICAgICAgICB9KTtcblxuICAgICAgICAvLyAyLiB0YXJnZXTrs4TroZwgZW5zdXJlRGljdEtleXMg7Zi47LacICjsiJzssKgg7LKY66asKVxuICAgICAgICBhd2FpdCBzb25hbXVEaWN0aW9uYXJ5LmVuc3VyZURpY3RLZXlzKFsuLi5uZXcgU2V0KGtleXMpXSk7XG5cbiAgICAgICAgLy8gMy4g7YWc7ZSM66a/IOyDneyEsSAo67OR66CsIOyymOumrClcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgb3B0aW9ucy5tYXAoYXN5bmMgKHsgZW50aXR5SWQsIHRlbXBsYXRlS2V5LCBlbnVtSWQsIG92ZXJ3cml0ZSB9KSA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgU29uYW11LnN5bmNlci5nZW5lcmF0ZVRlbXBsYXRlKFxuICAgICAgICAgICAgICAgIHRlbXBsYXRlS2V5IGFzIFRlbXBsYXRlS2V5LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGVudGl0eUlkLFxuICAgICAgICAgICAgICAgICAgZW51bUlkLFxuICAgICAgICAgICAgICAgIH0gYXMge1xuICAgICAgICAgICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICAgICAgICAgIGVudW1JZD86IHN0cmluZztcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIG92ZXJ3cml0ZSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICBpZiAoaXNTb0V4Y2VwdGlvbihlKSAmJiBlLnN0YXR1c0NvZGUgPT09IDU0MSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChyZXN1bHQuZmlsdGVyKG5vbk51bGxhYmxlKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgU2VydmljZVVuYXZhaWxhYmxlRXhjZXB0aW9uKFNEKFwic29uYW11LmVycm9yLmFsbEZpbGVzR2VuZXJhdGVkXCIpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIG9wdGlvbjoge1xuICAgICAgICAgICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICAgICAgICAgIHRlbXBsYXRlS2V5OiBzdHJpbmc7XG4gICAgICAgICAgICBlbnVtSWQ/OiBzdHJpbmc7XG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zY2FmZm9sZGluZy9wcmV2aWV3XCIsIGFzeW5jIChyZXF1ZXN0KTogUHJvbWlzZTx7IHBhdGhBbmRDb2RlczogUGF0aEFuZENvZGVbXSB9PiA9PiB7XG4gICAgICAgIGNvbnN0IHsgb3B0aW9uIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB7IHRlbXBsYXRlS2V5LCAuLi50ZW1wbGF0ZU9wdGlvbnMgfSA9IG9wdGlvbjtcbiAgICAgICAgICBjb25zdCBwYXRoQW5kQ29kZXMgPSBhd2FpdCBTb25hbXUuc3luY2VyLnJlbmRlclRlbXBsYXRlKFxuICAgICAgICAgICAgdGVtcGxhdGVLZXkgYXMgVGVtcGxhdGVLZXksXG4gICAgICAgICAgICB0ZW1wbGF0ZU9wdGlvbnMsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIHJldHVybiB7IHBhdGhBbmRDb2RlcyB9O1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3QoXCIvYXBpL2ZpeHR1cmVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBzb3VyY2VEQiwgdGFyZ2V0REIsIHNlYXJjaCwgZHVwbGljYXRlQ2hlY2sgfSA9IHJlcXVlc3QuYm9keSBhcyB7XG4gICAgICAgICAgc291cmNlREI6IGtleW9mIFNvbmFtdURCQ29uZmlnO1xuICAgICAgICAgIHRhcmdldERCOiBrZXlvZiBTb25hbXVEQkNvbmZpZztcbiAgICAgICAgICBzZWFyY2g6IEZpeHR1cmVTZWFyY2hPcHRpb25zO1xuICAgICAgICAgIGR1cGxpY2F0ZUNoZWNrPzogRHVwbGljYXRlQ2hlY2tPcHRpb25zO1xuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiBGaXh0dXJlTWFuYWdlci5nZXRGaXh0dXJlcyhzb3VyY2VEQiwgdGFyZ2V0REIsIHNlYXJjaCwgZHVwbGljYXRlQ2hlY2spO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0KFwiL2FwaS9maXh0dXJlL2ltcG9ydFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IGRiLCBmaXh0dXJlcyB9ID0gcmVxdWVzdC5ib2R5IGFzIHtcbiAgICAgICAgICBkYjoga2V5b2YgU29uYW11REJDb25maWc7XG4gICAgICAgICAgZml4dHVyZXM6IEZpeHR1cmVSZWNvcmRbXTtcbiAgICAgICAgfTtcblxuICAgICAgICByZXR1cm4gRml4dHVyZU1hbmFnZXIuaW5zZXJ0Rml4dHVyZXMoZGIsIGZpeHR1cmVzKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdChcIi9hcGkvZml4dHVyZS9hZGRGaXh0dXJlTG9hZGVyXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgY29kZSB9ID0gcmVxdWVzdC5ib2R5IGFzIHsgY29kZTogc3RyaW5nIH07XG5cbiAgICAgICAgcmV0dXJuIEZpeHR1cmVNYW5hZ2VyLmFkZEZpeHR1cmVMb2FkZXIoY29kZSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldChcIi9hcGkvaTE4bi9kaWN0aW9uYXJ5XCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcmV0dXJuIHNvbmFtdURpY3Rpb25hcnkuZ2V0RGljdGlvbmFyeSgpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2kxOG4vZXhwb3J0XCIsIGFzeW5jIChfcmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3QgeyBmaWxlbmFtZSwgYnVmZmVyIH0gPSBhd2FpdCBzb25hbXVEaWN0aW9uYXJ5LmV4cG9ydFRvRXhjZWwoKTtcbiAgICAgICAgcmVwbHlcbiAgICAgICAgICAuaGVhZGVyKFxuICAgICAgICAgICAgXCJDb250ZW50LVR5cGVcIixcbiAgICAgICAgICAgIFwiYXBwbGljYXRpb24vdm5kLm9wZW54bWxmb3JtYXRzLW9mZmljZWRvY3VtZW50LnNwcmVhZHNoZWV0bWwuc2hlZXRcIixcbiAgICAgICAgICApXG4gICAgICAgICAgLmhlYWRlcihcIkNvbnRlbnQtRGlzcG9zaXRpb25cIiwgYGF0dGFjaG1lbnQ7IGZpbGVuYW1lPVwiJHtmaWxlbmFtZX1cImApXG4gICAgICAgICAgLnNlbmQoYnVmZmVyKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdChcIi9hcGkvaTE4bi9pbXBvcnRcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlcXVlc3QuZmlsZSgpO1xuICAgICAgICBpZiAoIWRhdGEpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgQmFkUmVxdWVzdEV4Y2VwdGlvbihTRChcInNvbmFtdS5lcnJvci5maWxlTm90VXBsb2FkZWRcIikpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGJ1ZmZlciA9IGF3YWl0IGRhdGEudG9CdWZmZXIoKTtcbiAgICAgICAgcmV0dXJuIHNvbmFtdURpY3Rpb25hcnkuaW1wb3J0RnJvbUV4Y2VsKGJ1ZmZlcik7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgb2xkS2V5OiBzdHJpbmc7XG4gICAgICAgICAgbmV3S2V5OiBzdHJpbmc7XG4gICAgICAgICAgc291cmNlOiBcImVudGl0eVwiIHwgXCJwcm9qZWN0XCIgfCBcInNvbmFtdVwiO1xuICAgICAgICAgIHZhbHVlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9pMThuL3VwZGF0ZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBhd2FpdCBzb25hbXVEaWN0aW9uYXJ5LnVwZGF0ZUVudHJ5KHJlcXVlc3QuYm9keSk7XG4gICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBrZXk6IHN0cmluZztcbiAgICAgICAgICB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvaTE4bi9jcmVhdGVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgYXdhaXQgc29uYW11RGljdGlvbmFyeS5jcmVhdGVFbnRyeShyZXF1ZXN0LmJvZHkpO1xuICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlIH07XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAga2V5OiBzdHJpbmc7XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvaTE4bi9kZWxldGVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgYXdhaXQgc29uYW11RGljdGlvbmFyeS5kZWxldGVFbnRyeShyZXF1ZXN0LmJvZHkua2V5KTtcbiAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSB9O1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHsgQm9keTogeyBrZXlzOiBzdHJpbmdbXSB9IH0+KFwiL2FwaS9pMThuL2NoZWNrVXNhZ2VcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgcmV0dXJuIHNvbmFtdURpY3Rpb25hcnkuY2hlY2tVc2FnZShyZXF1ZXN0LmJvZHkua2V5cyk7XG4gICAgICB9KTtcblxuICAgICAgLy8gVGFza3MgQVBJXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS90YXNrcy9zdGF0dXNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIFNvbmFtdS53b3JrZmxvd3M7XG4gICAgICAgICAgcmV0dXJuIHsgYWN0aXZlOiB0cnVlIH07XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIHJldHVybiB7IGFjdGl2ZTogZmFsc2UgfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL3Rhc2tzL3dvcmtmbG93RGVmaW5pdGlvbnNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBkZWZpbml0aW9ucyA9IFNvbmFtdS53b3JrZmxvd3Mud29ya2Zsb3dEZWZpbml0aW9ucztcbiAgICAgICAgcmV0dXJuIHsgZGVmaW5pdGlvbnMgfTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIuZ2V0PHtcbiAgICAgICAgUXVlcnlzdHJpbmc6IHtcbiAgICAgICAgICBsaW1pdD86IHN0cmluZztcbiAgICAgICAgICBhZnRlcj86IHN0cmluZztcbiAgICAgICAgICBiZWZvcmU/OiBzdHJpbmc7XG4gICAgICAgICAgb3JkZXI/OiBcImFzY1wiIHwgXCJkZXNjXCI7XG4gICAgICAgICAgc3RhdHVzPzogc3RyaW5nO1xuICAgICAgICAgIHdvcmtmbG93TmFtZT86IHN0cmluZztcbiAgICAgICAgICBjcmVhdGVkQWZ0ZXI/OiBzdHJpbmc7XG4gICAgICAgICAgY3JlYXRlZEJlZm9yZT86IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS90YXNrcy93b3JrZmxvd1J1bnNcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgYmFja2VuZCA9IFNvbmFtdS53b3JrZmxvd3MuYmFja2VuZDtcbiAgICAgICAgY29uc3QgeyBsaW1pdCwgYWZ0ZXIsIGJlZm9yZSwgb3JkZXIsIHN0YXR1cywgd29ya2Zsb3dOYW1lLCBjcmVhdGVkQWZ0ZXIsIGNyZWF0ZWRCZWZvcmUgfSA9XG4gICAgICAgICAgcmVxdWVzdC5xdWVyeTtcbiAgICAgICAgcmV0dXJuIGJhY2tlbmQubGlzdFdvcmtmbG93UnVucyh7XG4gICAgICAgICAgbGltaXQ6IGxpbWl0ID8gTnVtYmVyLnBhcnNlSW50KGxpbWl0LCAxMCkgOiB1bmRlZmluZWQsXG4gICAgICAgICAgYWZ0ZXIsXG4gICAgICAgICAgYmVmb3JlLFxuICAgICAgICAgIG9yZGVyLFxuICAgICAgICAgIHN0YXR1czogc3RhdHVzID8gc3RhdHVzLnNwbGl0KFwiLFwiKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICB3b3JrZmxvd05hbWU6IHdvcmtmbG93TmFtZSB8fCB1bmRlZmluZWQsXG4gICAgICAgICAgY3JlYXRlZEFmdGVyOiBjcmVhdGVkQWZ0ZXIgPyBuZXcgRGF0ZShjcmVhdGVkQWZ0ZXIpIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGNyZWF0ZWRCZWZvcmU6IGNyZWF0ZWRCZWZvcmUgPyBuZXcgRGF0ZShjcmVhdGVkQmVmb3JlKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLmdldDx7XG4gICAgICAgIFBhcmFtczogeyBpZDogc3RyaW5nIH07XG4gICAgICB9PihcIi9hcGkvdGFza3Mvd29ya2Zsb3dSdW5zLzppZFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCBiYWNrZW5kID0gU29uYW11LndvcmtmbG93cy5iYWNrZW5kO1xuICAgICAgICBjb25zdCB3b3JrZmxvd1J1biA9IGF3YWl0IGJhY2tlbmQuZ2V0V29ya2Zsb3dSdW4oe1xuICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJlcXVlc3QucGFyYW1zLmlkLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCF3b3JrZmxvd1J1bikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgV29ya2Zsb3cgcnVuIG5vdCBmb3VuZDogJHtyZXF1ZXN0LnBhcmFtcy5pZH1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gd29ya2Zsb3dSdW47XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgfT4oXCIvYXBpL3Rhc2tzL3dvcmtmbG93UnVucy86aWQvY2FuY2VsXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IGJhY2tlbmQgPSBTb25hbXUud29ya2Zsb3dzLmJhY2tlbmQ7XG4gICAgICAgIHJldHVybiBiYWNrZW5kLmNhbmNlbFdvcmtmbG93UnVuKHtcbiAgICAgICAgICB3b3JrZmxvd1J1bklkOiByZXF1ZXN0LnBhcmFtcy5pZCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgfT4oXCIvYXBpL3Rhc2tzL3dvcmtmbG93UnVucy86aWQvcGF1c2VcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgYmFja2VuZCA9IFNvbmFtdS53b3JrZmxvd3MuYmFja2VuZDtcbiAgICAgICAgcmV0dXJuIGJhY2tlbmQucGF1c2VXb3JrZmxvd1J1bih7XG4gICAgICAgICAgd29ya2Zsb3dSdW5JZDogcmVxdWVzdC5wYXJhbXMuaWQsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgUGFyYW1zOiB7IGlkOiBzdHJpbmcgfTtcbiAgICAgIH0+KFwiL2FwaS90YXNrcy93b3JrZmxvd1J1bnMvOmlkL3Jlc3VtZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCBiYWNrZW5kID0gU29uYW11LndvcmtmbG93cy5iYWNrZW5kO1xuICAgICAgICByZXR1cm4gYmFja2VuZC5yZXN1bWVXb3JrZmxvd1J1bih7XG4gICAgICAgICAgd29ya2Zsb3dSdW5JZDogcmVxdWVzdC5wYXJhbXMuaWQsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5nZXQ8e1xuICAgICAgICBQYXJhbXM6IHsgaWQ6IHN0cmluZyB9O1xuICAgICAgICBRdWVyeXN0cmluZzoge1xuICAgICAgICAgIGxpbWl0Pzogc3RyaW5nO1xuICAgICAgICAgIGFmdGVyPzogc3RyaW5nO1xuICAgICAgICAgIGJlZm9yZT86IHN0cmluZztcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS90YXNrcy93b3JrZmxvd1J1bnMvOmlkL3N0ZXBzXCIsIGFzeW5jIChyZXF1ZXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IGJhY2tlbmQgPSBTb25hbXUud29ya2Zsb3dzLmJhY2tlbmQ7XG4gICAgICAgIGNvbnN0IHsgbGltaXQsIGFmdGVyLCBiZWZvcmUgfSA9IHJlcXVlc3QucXVlcnk7XG4gICAgICAgIHJldHVybiBiYWNrZW5kLmxpc3RTdGVwQXR0ZW1wdHMoe1xuICAgICAgICAgIHdvcmtmbG93UnVuSWQ6IHJlcXVlc3QucGFyYW1zLmlkLFxuICAgICAgICAgIGxpbWl0OiBsaW1pdCA/IE51bWJlci5wYXJzZUludChsaW1pdCwgMTApIDogdW5kZWZpbmVkLFxuICAgICAgICAgIGFmdGVyLFxuICAgICAgICAgIGJlZm9yZSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcblxuICAgICAgLyoqXG4gICAgICAgKiBIZWFsdGggQ2hlY2sgQVBJXG4gICAgICAgKiBNQ1Ag64+E6rWs6rCAIFNvbmFtdSDshJzrsoTrpbwg7J6Q64+ZIOqwkOyngO2VmOq4sCDsnITtlZwg7JeU65Oc7Y+s7J247Yq4XG4gICAgICAgKi9cbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL3NvbmFtdS9oZWFsdGhcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgYWRkcmVzcyA9IHJlcXVlc3Quc2VydmVyLnNlcnZlci5hZGRyZXNzKCk7XG4gICAgICAgIGNvbnN0IHBvcnQgPSBhZGRyZXNzICYmIHR5cGVvZiBhZGRyZXNzID09PSBcIm9iamVjdFwiID8gYWRkcmVzcy5wb3J0IDogMDtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIG9rOiB0cnVlLFxuICAgICAgICAgIHByb2plY3Q6IHByb2Nlc3MuY3dkKCkuc3BsaXQoXCIvXCIpLnBvcCgpIHx8IFwidW5rbm93blwiLFxuICAgICAgICAgIHBvcnQsXG4gICAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgICAgLyoqXG4gICAgICAgKiBGaXh0dXJlIOyDneyEsSBBUElcbiAgICAgICAqL1xuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5OiBzdHJpbmc7XG4gICAgICAgICAgY291bnQ/OiBudW1iZXI7XG4gICAgICAgICAgb3ZlcnJpZGVzPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgICAgdGFyZ2V0RGI/OiBcImZpeHR1cmVcIiB8IFwidGVzdFwiO1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3NvbmFtdS9maXh0dXJlL2dlbmVyYXRlXCIsIGFzeW5jIChyZXF1ZXN0LCByZXBseSkgPT4ge1xuICAgICAgICBjb25zdCB7IGVudGl0eSwgY291bnQgPSAxLCBvdmVycmlkZXMsIHRhcmdldERiID0gXCJmaXh0dXJlXCIgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAvLyDtg4Dqsp8gREIg7ISk7KCVIOqwgOyguOyYpOq4sFxuICAgICAgICBjb25zdCBkYkNvbmZpZyA9IHRhcmdldERiID09PSBcImZpeHR1cmVcIiA/IFNvbmFtdS5kYkNvbmZpZy5maXh0dXJlIDogU29uYW11LmRiQ29uZmlnLnRlc3Q7XG5cbiAgICAgICAgLy8gS25leCDsnbjsiqTthLTsiqQg7IOd7ISxXG4gICAgICAgIGNvbnN0IGRiID0gY3JlYXRlS25leEluc3RhbmNlKGRiQ29uZmlnKTtcblxuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIEZpeHR1cmVHZW5lcmF0b3Ig7IOd7ISxXG4gICAgICAgICAgY29uc3QgZ2VuZXJhdG9yID0gbmV3IEZpeHR1cmVHZW5lcmF0b3IoZGIsIGRiLCB0YXJnZXREYiwgRW50aXR5TWFuYWdlcik7XG5cbiAgICAgICAgICAvLyDri6jsnbwgRW50aXR5IOuwsOy5mCDsg53shLFcbiAgICAgICAgICBjb25zdCBmaXh0dXJlcyA9IGF3YWl0IGdlbmVyYXRvci5nZW5lcmF0ZUJhdGNoKFtcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZW50aXR5LFxuICAgICAgICAgICAgICBjb3VudCxcbiAgICAgICAgICAgICAgb3ZlcnJpZGVzOiBvdmVycmlkZXMgPz8ge30sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0pO1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IHRydWUsXG4gICAgICAgICAgICBlbnRpdHksXG4gICAgICAgICAgICBjb3VudDogZml4dHVyZXMubGVuZ3RoLFxuICAgICAgICAgICAgZml4dHVyZXMsXG4gICAgICAgICAgICB0YXJnZXREYixcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDApO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBhd2FpdCBkYi5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvKipcbiAgICAgICAqIEZpeHR1cmUg642w7J207YSwIO2DkOyDiSBBUElcbiAgICAgICAqL1xuICAgICAgc2VydmVyLnBvc3Q8e1xuICAgICAgICBCb2R5OiB7XG4gICAgICAgICAgZW50aXR5OiBzdHJpbmc7XG4gICAgICAgICAgc3RyYXRlZ3k6IFwic2FtcGxlXCIgfCBcInJlY2VudFwiIHwgXCJyYW5kb21cIiB8IFwicXVlcnlcIjtcbiAgICAgICAgICBsaW1pdD86IG51bWJlcjtcbiAgICAgICAgICB3aGVyZT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgICAgICB9O1xuICAgICAgfT4oXCIvYXBpL3NvbmFtdS9maXh0dXJlL2V4cGxvcmVcIiwgYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZW50aXR5LCBzdHJhdGVneSwgbGltaXQgPSAxMCwgd2hlcmUgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAvLyBGaXh0dXJlIERCIOyEpOyglSDqsIDsoLjsmKTquLBcbiAgICAgICAgY29uc3QgZml4dHVyZURiQ29uZmlnID0gU29uYW11LmRiQ29uZmlnLmZpeHR1cmU7XG5cbiAgICAgICAgLy8gS25leCDsnbjsiqTthLTsiqQg7IOd7ISxXG4gICAgICAgIGNvbnN0IGZpeHR1cmVEYiA9IGNyZWF0ZUtuZXhJbnN0YW5jZShmaXh0dXJlRGJDb25maWcpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gRGF0YUV4cGxvcmVyIOyDneyEsVxuICAgICAgICAgIGNvbnN0IGV4cGxvcmVyID0gbmV3IERhdGFFeHBsb3JlcihmaXh0dXJlRGIsIEVudGl0eU1hbmFnZXIpO1xuXG4gICAgICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IGV4cGxvcmVyLmV4cGxvcmUoZW50aXR5LCB7XG4gICAgICAgICAgICBzdHJhdGVneSxcbiAgICAgICAgICAgIGxpbWl0LFxuICAgICAgICAgICAgd2hlcmUsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgIGVudGl0eSxcbiAgICAgICAgICAgIHN0cmF0ZWd5LFxuICAgICAgICAgICAgY291bnQ6IGRhdGEubGVuZ3RoLFxuICAgICAgICAgICAgZGF0YSxcbiAgICAgICAgICB9O1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHJlcGx5LnN0YXR1cyg0MDApO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgIGVycm9yOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFN0cmluZyhlcnJvciksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgICBhd2FpdCBmaXh0dXJlRGIuZGVzdHJveSgpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLyoqXG4gICAgICAgKiBGaXh0dXJlIOuNsOydtO2EsCDqsIDsoLjsmKTquLAgKGZldGNoKSBBUElcbiAgICAgICAqIHByb2R1Y3Rpb24vZGV2ZWxvcG1lbnQgRELsl5DshJwg7Iuk7KCcIOuNsOydtO2EsOulvCBmaXh0dXJlIERC66GcIGltcG9ydFxuICAgICAgICovXG4gICAgICBzZXJ2ZXIucG9zdDx7XG4gICAgICAgIEJvZHk6IHtcbiAgICAgICAgICBlbnRpdHk6IHN0cmluZztcbiAgICAgICAgICBzdHJhdGVneT86IFwic2FtcGxlXCIgfCBcInJlY2VudFwiIHwgXCJyYW5kb21cIiB8IFwicXVlcnlcIjtcbiAgICAgICAgICBsaW1pdD86IG51bWJlcjtcbiAgICAgICAgICBpbmNsdWRlUmVsYXRpb25zPzogYm9vbGVhbjtcbiAgICAgICAgICBtYXhEZXB0aD86IG51bWJlcjtcbiAgICAgICAgfTtcbiAgICAgIH0+KFwiL2FwaS9zb25hbXUvZml4dHVyZS9mZXRjaFwiLCBhc3luYyAocmVxdWVzdCwgcmVwbHkpID0+IHtcbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgIGVudGl0eSxcbiAgICAgICAgICBzdHJhdGVneSA9IFwicmVjZW50XCIsXG4gICAgICAgICAgbGltaXQgPSAxMCxcbiAgICAgICAgICBpbmNsdWRlUmVsYXRpb25zID0gdHJ1ZSxcbiAgICAgICAgICBtYXhEZXB0aCA9IDIsXG4gICAgICAgIH0gPSByZXF1ZXN0LmJvZHk7XG5cbiAgICAgICAgLy8gU291cmNlIERCIChwcm9kdWN0aW9uL2RldmVsb3BtZW50KSAtIOydveq4sCDsoITsmqlcbiAgICAgICAgY29uc3Qgc291cmNlRGIgPSBEQi5nZXREQihcInJcIik7XG5cbiAgICAgICAgLy8gVGFyZ2V0IERCIChmaXh0dXJlKVxuICAgICAgICBjb25zdCBmaXh0dXJlRGIgPSBjcmVhdGVLbmV4SW5zdGFuY2UoU29uYW11LmRiQ29uZmlnLmZpeHR1cmUpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gRml4dHVyZUdlbmVyYXRvciDsg53shLFcbiAgICAgICAgICBjb25zdCBnZW5lcmF0b3IgPSBuZXcgRml4dHVyZUdlbmVyYXRvcihzb3VyY2VEYiwgZml4dHVyZURiLCBcImZpeHR1cmVcIiwgRW50aXR5TWFuYWdlcik7XG5cbiAgICAgICAgICAvLyBwcm9kdWN0aW9uIOuNsOydtO2EsOulvCBmaXh0dXJlIERC66GcIGltcG9ydFxuICAgICAgICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBnZW5lcmF0b3IuaW1wb3J0RnJvbVNvdXJjZShlbnRpdHksIHtcbiAgICAgICAgICAgIHN0cmF0ZWd5LFxuICAgICAgICAgICAgbGltaXQsXG4gICAgICAgICAgICBpbmNsdWRlUmVsYXRpb25zLFxuICAgICAgICAgICAgbWF4RGVwdGgsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgIGVudGl0eSxcbiAgICAgICAgICAgIHN0cmF0ZWd5LFxuICAgICAgICAgICAgY291bnQ6IHJlc3VsdHMubGVuZ3RoLFxuICAgICAgICAgICAgaW1wb3J0ZWQ6IHJlc3VsdHMsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICByZXBseS5zdGF0dXMoNDAwKTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgLy8gc291cmNlRGLripQgU29uYW116rCAIOq0gOumrO2VmOuvgOuhnCBkZXN0cm957ZWY7KeAIOyViuydjFxuICAgICAgICAgIGF3YWl0IGZpeHR1cmVEYi5kZXN0cm95KCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvKipcbiAgICAgICAqIEZpeHR1cmUg642w7J207YSwIOyCreygnCAoY2xlYW4pIEFQSVxuICAgICAgICogRksg7Iic7ISc66W8IOqzoOugpO2VmOyXrCDslYjsoITtlZjqsowg7IKt7KCcXG4gICAgICAgKi9cbiAgICAgIHNlcnZlci5wb3N0PHtcbiAgICAgICAgQm9keToge1xuICAgICAgICAgIGVudGl0aWVzPzogc3RyaW5nW107XG4gICAgICAgIH07XG4gICAgICB9PihcIi9hcGkvc29uYW11L2ZpeHR1cmUvY2xlYW5cIiwgYXN5bmMgKHJlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZW50aXRpZXMgfSA9IHJlcXVlc3QuYm9keTtcblxuICAgICAgICAvLyBGaXh0dXJlIERCIOyXsOqysFxuICAgICAgICBjb25zdCBmaXh0dXJlRGIgPSBjcmVhdGVLbmV4SW5zdGFuY2UoU29uYW11LmRiQ29uZmlnLmZpeHR1cmUpO1xuXG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8g7IKt7KCc7ZWgIEVudGl0eSDrqqnroZ0g6rKw7KCVXG4gICAgICAgICAgY29uc3QgdGFyZ2V0RW50aXRpZXMgPVxuICAgICAgICAgICAgZW50aXRpZXMgJiYgZW50aXRpZXMubGVuZ3RoID4gMCA/IGVudGl0aWVzIDogRW50aXR5TWFuYWdlci5nZXRBbGxJZHMoKTtcblxuICAgICAgICAgIC8vIEVudGl0eSBJROulvCDthYzsnbTruJTrqoXsnLzroZwg67OA7ZmYIChzbmFrZV9jYXNlIOuzteyImO2YlSlcbiAgICAgICAgICBjb25zdCB0YWJsZU5hbWVzID0gdGFyZ2V0RW50aXRpZXMubWFwKChlbnRpdHlJZCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgICAgICAgcmV0dXJuIGVudGl0eS50YWJsZTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIFBvc3RncmVTUUw6IFRSVU5DQVRFIENBU0NBREXroZwgRksg7Iic7IScIOustOq0gO2VmOqyjCDslYjsoITtlZjqsowg7IKt7KCcXG4gICAgICAgICAgLy8gQ0FTQ0FERSDsmLXshZjsnLzroZwg7J2Y7KG07ISxIOyeiOuKlCDrjbDsnbTthLDrj4Qg7ZWo6ruYIOyCreygnFxuICAgICAgICAgIGF3YWl0IGZpeHR1cmVEYi5yYXcoXG4gICAgICAgICAgICBgVFJVTkNBVEUgVEFCTEUgJHt0YWJsZU5hbWVzLm1hcCgodCkgPT4gYFwiJHt0fVwiYCkuam9pbihcIiwgXCIpfSBSRVNUQVJUIElERU5USVRZIENBU0NBREVgLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogdHJ1ZSxcbiAgICAgICAgICAgIGNsZWFuZWQ6IHRhYmxlTmFtZXMsXG4gICAgICAgICAgICBjb3VudDogdGFibGVOYW1lcy5sZW5ndGgsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICByZXBseS5zdGF0dXMoNDAwKTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICAgICAgICBlcnJvcjogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBTdHJpbmcoZXJyb3IpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgYXdhaXQgZml4dHVyZURiLmRlc3Ryb3koKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIENERCBBUElcbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2NkZC90cmVlXCIsIGFzeW5jICgpID0+IHtcbiAgICAgICAgcmV0dXJuIGdldENkZFRyZWUoKTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7IEJvZHk6IHsgZmlsZVBhdGg6IHN0cmluZyB9IH0+KFwiL2FwaS9jZGQvcmVhZENvbnRlbnRcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBmaWxlUGF0aCB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICByZXR1cm4gcmVhZENvbnRlbnQoZmlsZVBhdGgpO1xuICAgICAgfSk7XG5cbiAgICAgIHNlcnZlci5wb3N0PHsgQm9keTogeyBmaWxlUGF0aDogc3RyaW5nIH0gfT4oXCIvYXBpL2NkZC9lZGl0Q29udGVudFwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICBjb25zdCB7IGZpbGVQYXRoIH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgIHJldHVybiBlZGl0Q29udGVudChmaWxlUGF0aCk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8eyBCb2R5OiB7IGZpbGVQYXRoOiBzdHJpbmcgfSB9PihcIi9hcGkvY2RkL29wZW5Tb3VyY2VcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBmaWxlUGF0aCB9ID0gcmVxdWVzdC5ib2R5O1xuICAgICAgICBvcGVuU291cmNlRmlsZShmaWxlUGF0aCk7XG4gICAgICAgIHJldHVybiB7IHN1Y2Nlc3M6IHRydWUgfTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBDREQgUnVsZXMgQVBJXG4gICAgICBzZXJ2ZXIuZ2V0KFwiL2FwaS9jZGQvcnVsZXNcIiwgYXN5bmMgKCkgPT4ge1xuICAgICAgICByZXR1cm4gbGlzdFJ1bGVzKCk7XG4gICAgICB9KTtcblxuICAgICAgc2VydmVyLnBvc3Q8eyBCb2R5OiB7IHJ1bGVLZXk6IHN0cmluZyB9IH0+KFwiL2FwaS9jZGQvcmVhZFJ1bGVcIiwgYXN5bmMgKHJlcXVlc3QpID0+IHtcbiAgICAgICAgY29uc3QgeyBydWxlS2V5IH0gPSByZXF1ZXN0LmJvZHk7XG4gICAgICAgIHJldHVybiByZWFkUnVsZShydWxlS2V5KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZXJ2ZXIucG9zdDx7IEJvZHk6IENkZEFkZFJ1bGVSZXF1ZXN0IH0+KFwiL2FwaS9jZGQvYWRkUnVsZVwiLCBhc3luYyAocmVxdWVzdCkgPT4ge1xuICAgICAgICByZXR1cm4gYWRkUnVsZShyZXF1ZXN0LmJvZHkpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIENERCBBQyBBUElcbiAgICAgIHNlcnZlci5nZXQoXCIvYXBpL2NkZC9hY1wiLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIHJldHVybiBnZXRBY0xpc3QoKTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyB1aS13ZWIg67mM65OcIO2MjOydvCDshJzruZlcbiAgICAgIGNvbnN0IHVpRGlzdFBhdGggPSBwYXRoLnJlc29sdmUoaW1wb3J0Lm1ldGEuZGlybmFtZSwgXCIuLi91aS13ZWJcIik7XG5cbiAgICAgIC8vIOygleyggSDtjIzsnbwg7ISc67mZOiDro6jtirgg7Y+0642UIOyghOyytCAoYXNzZXRzLCBzZXR0aW5nLnN2ZyDrk7EpXG4gICAgICBzZXJ2ZXIucmVnaXN0ZXIoYXdhaXQgaW1wb3J0KFwiQGZhc3RpZnkvc3RhdGljXCIpLCB7XG4gICAgICAgIHJvb3Q6IHVpRGlzdFBhdGgsXG4gICAgICAgIHByZWZpeDogXCIvXCIsXG4gICAgICAgIGRlY29yYXRlUmVwbHk6IGZhbHNlLFxuICAgICAgICB3aWxkY2FyZDogZmFsc2UsXG4gICAgICB9KTtcblxuICAgICAgLy8gU1BBIGZhbGxiYWNrIC0g7KCV7KCBIO2MjOydvOydtCDsl4bripQg66qo65OgIOqyveuhnOuKlCBpbmRleC5odG1s66GcXG4gICAgICBzZXJ2ZXIuZ2V0KFwiKlwiLCBhc3luYyAoX3JlcXVlc3QsIHJlcGx5KSA9PiB7XG4gICAgICAgIHJlcGx5LmhlYWRlcnMoeyBcIkNvbnRlbnQtdHlwZVwiOiBcInRleHQvaHRtbFwiIH0pLnNlbmQoXG4gICAgICAgICAgZnNcbiAgICAgICAgICAgIC5yZWFkRmlsZVN5bmMocGF0aC5yZXNvbHZlKHVpRGlzdFBhdGgsIFwiaW5kZXguaHRtbFwiKSlcbiAgICAgICAgICAgIC50b1N0cmluZygpXG4gICAgICAgICAgICAucmVwbGFjZShcInt7cHJvamVjdE5hbWV9fVwiLCBTb25hbXUuY29uZmlnLnByb2plY3ROYW1lID8/IFwiVW5rbm93blNvbmFtdVByb2plY3RcIiksXG4gICAgICAgICk7XG4gICAgICB9KTtcbiAgICB9LFxuICAgIHsgcHJlZml4OiBcIi9zb25hbXUtdWlcIiB9LFxuICApO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBdURBLGVBQXNCLGtCQUFrQixTQUEwQjtBQUNoRSxTQUFRLFNBQ04sT0FBTyxXQUFXO0VBRWhCLE1BQU0sV0FBVyxJQUFJLFVBQVU7RUFHL0IsZUFBZSxvQkFBdUIsSUFBa0M7R0FDdEUsTUFBTSxjQUFjLElBQUksU0FBZSxZQUFZO0lBQ2pELE1BQU0sZ0JBQWdCO0FBQ3BCLGtCQUFhLFFBQVE7QUFDckIsY0FBUzs7SUFHWCxNQUFNLFVBQVUsaUJBQWlCO0FBQy9CLFlBQU8sT0FBTyxhQUFhLElBQUksa0JBQWtCLFFBQVE7QUFDekQsY0FBUztPQUNSLEtBQUs7QUFFUixXQUFPLE9BQU8sYUFBYSxLQUFLLGtCQUFrQixRQUFRO0tBQzFEO0dBRUYsTUFBTSxTQUFTLE1BQU0sSUFBSTtBQUN6QixTQUFNO0FBQ04sVUFBTzs7QUFHVCxRQUFNLFNBQVMsT0FBTztBQUV0QixTQUFPLElBQUksc0JBQXNCLFlBQVk7QUFDM0MsVUFBTyxPQUFPO0lBQ2Q7QUFFRixTQUFPLElBTUoseUJBQXlCLE9BQU8sWUFBWTtHQUM3QyxNQUFNLEVBQUUsVUFBVSxRQUFRLFlBQVksUUFBUTtHQUU5QyxNQUFNLG9CQUFvQjtBQUN4QixRQUFJLFlBQVksUUFBUTtLQUN0QixNQUFNLFNBQVMsY0FBYyxJQUFJLFNBQVM7S0FDMUMsTUFBTSxFQUFFLFVBQVU7S0FFbEIsTUFBTSxFQUFFLGdCQUFnQjtLQUN4QixNQUFNLGtCQUFrQjtBQUN0QixjQUFRLFFBQVI7T0FDRSxLQUFLLFFBQ0gsUUFBTyxHQUFHLE1BQU0sR0FBRztPQUNyQixLQUFLLGNBQ0gsUUFBTyxHQUFHLE1BQU0sR0FBRztPQUNyQixLQUFLLFlBQ0gsUUFBTyxHQUFHLE1BQU0sR0FBRzs7U0FFckI7QUFDSixZQUFPLEdBQUcsWUFBWSxtQkFBbUIsT0FBTyxNQUFNLFNB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
|