sonamu 0.8.26 → 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 -157
- 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 +6 -7
- 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 +1 -1
- package/dist/ui/cdd-service.d.ts.map +1 -1
- package/dist/ui/cdd-service.js +406 -407
- 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 +31 -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 +6 -5
- 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 +5 -3
- 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 +33 -32
- package/src/database/puri-subset.types.ts +6 -7
- 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 +111 -104
- 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 +11 -17
- 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 +6 -5
- package/src/ui/api.ts +25 -23
- package/src/ui/cdd-service.ts +12 -11
- 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 -89
- 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-CKo0Z2Iu.css +0 -1
- package/dist/ui-web/assets/index-DK-2aacv.js +0 -257
package/dist/entity/entity.js
CHANGED
|
@@ -1,1092 +1,955 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { __esmMin } from "../_virtual/rolldown_runtime.js";
|
|
2
|
+
import { exists, init_fs_utils } from "../utils/fs-utils.js";
|
|
3
|
+
import { assertDefined, init_utils, nonNullable } from "../utils/utils.js";
|
|
4
|
+
import { Sonamu, init_sonamu } from "../api/sonamu.js";
|
|
5
|
+
import { getEnumDefValues, getSubsetFields, init_types, isBelongsToOneRelationProp, isEnumProp, isHasManyRelationProp, isInternalSubsetField, isManyToManyRelationProp, isOneToOneRelationProp, isRelationProp, isVirtualCodeProp, isVirtualProp, normalizeSubsetField } from "../types/types.js";
|
|
6
|
+
import { importMembers, init_esm_utils } from "../utils/esm-utils.js";
|
|
7
|
+
import { init_path_utils, runtimePath } from "../utils/path-utils.js";
|
|
8
|
+
import { EntityManager, init_entity_manager } from "./entity-manager.js";
|
|
9
|
+
import { formatCode, init_formatter } from "../utils/formatter.js";
|
|
3
10
|
import inflection from "inflection";
|
|
4
|
-
import
|
|
11
|
+
import { z as z$1 } from "zod";
|
|
5
12
|
import { group, unique } 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
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
return result;
|
|
945
|
-
}
|
|
946
|
-
async modifyProp(newProp, at) {
|
|
947
|
-
// 이전 프롭 이름 저장
|
|
948
|
-
const oldName = this.props[at].name;
|
|
949
|
-
// 저장할 엔티티
|
|
950
|
-
const entities = [
|
|
951
|
-
this
|
|
952
|
-
];
|
|
953
|
-
// 이름이 바뀐 경우
|
|
954
|
-
if (oldName !== newProp.name) {
|
|
955
|
-
// 전체 엔티티에서 현재 수정된 프롭을 참조하고 있는 모든 서브셋필드 찾아서 수정
|
|
956
|
-
const allEntityIds = EntityManager.getAllIds();
|
|
957
|
-
for (const relEntityId of allEntityIds){
|
|
958
|
-
const relEntity = EntityManager.get(relEntityId);
|
|
959
|
-
const relEntitySubsetKeys = Object.keys(relEntity.subsets);
|
|
960
|
-
for (const subsetKey of relEntitySubsetKeys){
|
|
961
|
-
const subset = relEntity.subsets[subsetKey];
|
|
962
|
-
// 서브셋 필드를 순회하며, 엔티티-프롭 단위로 분석한 후 현재 엔티티-프롭과 일치하는 경우 수정 처리
|
|
963
|
-
const modifiedSubsetFields = subset.map((subsetField)=>{
|
|
964
|
-
const analyzed = relEntity.analyzeSubsetField(subsetField);
|
|
965
|
-
const modified = analyzed.map((a)=>a.propName === oldName && a.entityId === this.id ? {
|
|
966
|
-
...a,
|
|
967
|
-
propName: newProp.name
|
|
968
|
-
} : a);
|
|
969
|
-
// 분석한 필드를 다시 서브셋 필드로 복구
|
|
970
|
-
return modified.map((a)=>a.propName).join(".");
|
|
971
|
-
});
|
|
972
|
-
if (subset.join(",") !== modifiedSubsetFields.join(",")) {
|
|
973
|
-
relEntity.subsets[subsetKey] = modifiedSubsetFields;
|
|
974
|
-
entities.push(relEntity);
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
// 프롭 수정
|
|
980
|
-
this.props[at] = newProp;
|
|
981
|
-
await Promise.all(entities.map(async (entity)=>entity.save()));
|
|
982
|
-
}
|
|
983
|
-
async delProp(at) {
|
|
984
|
-
// 이전 프롭 이름 저장
|
|
985
|
-
const oldName = this.props[at].name;
|
|
986
|
-
// 저장할 엔티티
|
|
987
|
-
const entities = [
|
|
988
|
-
this
|
|
989
|
-
];
|
|
990
|
-
// 전체 엔티티에서 현재 삭제된 프롭을 참조하고 있는 모든 서브셋필드 찾아서 제외
|
|
991
|
-
const allEntityIds = EntityManager.getAllIds();
|
|
992
|
-
for (const relEntityId of allEntityIds){
|
|
993
|
-
const relEntity = EntityManager.get(relEntityId);
|
|
994
|
-
const relEntitySubsetKeys = Object.keys(relEntity.subsets);
|
|
995
|
-
for (const subsetKey of relEntitySubsetKeys){
|
|
996
|
-
const subset = relEntity.subsets[subsetKey];
|
|
997
|
-
// 서브셋 필드를 순회하며, 엔티티-프롭 단위로 분석한 후 현재 엔티티-프롭과 일치하는 경우 이후의 필드를 제외
|
|
998
|
-
const modifiedSubsetFields = subset.map((subsetField)=>{
|
|
999
|
-
const analyzed = relEntity.analyzeSubsetField(subsetField);
|
|
1000
|
-
if (analyzed.find((a)=>a.propName === oldName && a.entityId === this.id)) {
|
|
1001
|
-
return null;
|
|
1002
|
-
} else {
|
|
1003
|
-
return subsetField;
|
|
1004
|
-
}
|
|
1005
|
-
}).filter(nonNullable);
|
|
1006
|
-
if (subset.join(",") !== modifiedSubsetFields.join(",")) {
|
|
1007
|
-
relEntity.subsets[subsetKey] = modifiedSubsetFields;
|
|
1008
|
-
entities.push(relEntity);
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
}
|
|
1012
|
-
// 현재 엔티티의 인덱스에서 제외
|
|
1013
|
-
for (const index of EntityManager.get(this.id).indexes){
|
|
1014
|
-
index.columns = index.columns.filter((col)=>col.name !== oldName);
|
|
1015
|
-
}
|
|
1016
|
-
// 프롭 삭제
|
|
1017
|
-
this.props.splice(at, 1);
|
|
1018
|
-
await Promise.all(entities.map(async (entity)=>entity.save()));
|
|
1019
|
-
}
|
|
1020
|
-
getEntityIdFromSubsetField(subsetField) {
|
|
1021
|
-
if (subsetField.includes(".") === false) {
|
|
1022
|
-
return this.id;
|
|
1023
|
-
}
|
|
1024
|
-
// 서브셋 필드의 마지막은 프롭이므로 제외
|
|
1025
|
-
const arr = subsetField.split(".").slice(0, -1);
|
|
1026
|
-
// 서브셋 필드를 내려가면서 마지막으로 relation된 엔티티를 찾음
|
|
1027
|
-
const lastEntityId = arr.reduce((entityId, field)=>{
|
|
1028
|
-
const relProp = EntityManager.get(entityId).props.find((p)=>p.name === field);
|
|
1029
|
-
if (!relProp || relProp.type !== "relation") {
|
|
1030
|
-
console.debug({
|
|
1031
|
-
arr,
|
|
1032
|
-
thisId: this.id,
|
|
1033
|
-
entityId,
|
|
1034
|
-
field
|
|
1035
|
-
});
|
|
1036
|
-
throw new Error(`잘못된 서브셋키 ${subsetField}`);
|
|
1037
|
-
}
|
|
1038
|
-
return relProp.with;
|
|
1039
|
-
}, this.id);
|
|
1040
|
-
return lastEntityId;
|
|
1041
|
-
}
|
|
1042
|
-
async moveProp(at, to) {
|
|
1043
|
-
const prop = this.props[at];
|
|
1044
|
-
const newProps = [
|
|
1045
|
-
...this.props
|
|
1046
|
-
];
|
|
1047
|
-
newProps.splice(to, 0, prop);
|
|
1048
|
-
newProps.splice(at < to ? at : at + 1, 1);
|
|
1049
|
-
this.props = newProps;
|
|
1050
|
-
await this.save();
|
|
1051
|
-
}
|
|
1052
|
-
/**
|
|
1053
|
-
* 필드명을 "테이블명.필드명" 형식으로 변환
|
|
1054
|
-
*/ getFullFieldName(field) {
|
|
1055
|
-
if (field.includes(".")) {
|
|
1056
|
-
return field;
|
|
1057
|
-
}
|
|
1058
|
-
return `${this.table}.${field}`;
|
|
1059
|
-
}
|
|
1060
|
-
/**
|
|
1061
|
-
* 엔티티의 PK 타입을 반환합니다.
|
|
1062
|
-
* id 필드의 타입을 기준으로 "integer" | "string" | "uuid"를 반환합니다.
|
|
1063
|
-
*/ getPkType() {
|
|
1064
|
-
const idProp = this.propsDict.id;
|
|
1065
|
-
if (!idProp) {
|
|
1066
|
-
throw new Error(`Entity ${this.id}에 id 필드가 없습니다`);
|
|
1067
|
-
}
|
|
1068
|
-
if (idProp.type === "string" || idProp.type === "uuid") {
|
|
1069
|
-
return idProp.type;
|
|
1070
|
-
}
|
|
1071
|
-
return "integer";
|
|
1072
|
-
}
|
|
1073
|
-
/**
|
|
1074
|
-
* 엔티티의 PK prop을 반환합니다.
|
|
1075
|
-
* length 등 세부 정보에 접근할 때 사용합니다.
|
|
1076
|
-
*/ getPkProp() {
|
|
1077
|
-
const idProp = this.propsDict.id;
|
|
1078
|
-
if (!idProp) {
|
|
1079
|
-
throw new Error(`Entity ${this.id}에 id 필드가 없습니다`);
|
|
1080
|
-
}
|
|
1081
|
-
return idProp;
|
|
1082
|
-
}
|
|
1083
|
-
/**
|
|
1084
|
-
* 엔티티의 PK 배열 타입을 반환합니다.
|
|
1085
|
-
* LoaderQuery의 fromIds 타입으로 사용됩니다.
|
|
1086
|
-
*/ getPkArrayType() {
|
|
1087
|
-
const pkType = this.getPkType();
|
|
1088
|
-
return pkType === "integer" ? "number[]" : "string[]";
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
13
|
+
import assert from "assert";
|
|
14
|
+
import { writeFile } from "fs/promises";
|
|
15
|
+
import path from "path";
|
|
16
|
+
|
|
17
|
+
//#region src/entity/entity.ts
|
|
18
|
+
var Entity;
|
|
19
|
+
var init_entity = __esmMin((() => {
|
|
20
|
+
init_sonamu();
|
|
21
|
+
init_types();
|
|
22
|
+
init_esm_utils();
|
|
23
|
+
init_formatter();
|
|
24
|
+
init_fs_utils();
|
|
25
|
+
init_path_utils();
|
|
26
|
+
init_utils();
|
|
27
|
+
init_entity_manager();
|
|
28
|
+
Entity = class {
|
|
29
|
+
id;
|
|
30
|
+
parentId;
|
|
31
|
+
table;
|
|
32
|
+
title;
|
|
33
|
+
cone;
|
|
34
|
+
names;
|
|
35
|
+
props;
|
|
36
|
+
propsDict;
|
|
37
|
+
relations;
|
|
38
|
+
indexes;
|
|
39
|
+
subsets;
|
|
40
|
+
subsetsInternal;
|
|
41
|
+
types = {};
|
|
42
|
+
enums = {};
|
|
43
|
+
enumLabels = {};
|
|
44
|
+
enumCones = {};
|
|
45
|
+
subsetCones = {};
|
|
46
|
+
constructor({ id, parentId, table, title, cone, props, indexes, subsets, enums }) {
|
|
47
|
+
this.id = id;
|
|
48
|
+
this.parentId = parentId;
|
|
49
|
+
this.title = title ?? this.id;
|
|
50
|
+
this.table = table ?? inflection.underscore(inflection.pluralize(id));
|
|
51
|
+
this.cone = cone;
|
|
52
|
+
if (props) {
|
|
53
|
+
this.props = props.map((prop) => {
|
|
54
|
+
if (isEnumProp(prop)) {
|
|
55
|
+
if (prop.id.includes("$Model")) {
|
|
56
|
+
prop.id = prop.id.replace("$Model", id);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return prop;
|
|
60
|
+
});
|
|
61
|
+
this.propsDict = Object.fromEntries(props.map((prop) => {
|
|
62
|
+
return [prop.name, prop];
|
|
63
|
+
}));
|
|
64
|
+
this.relations = Object.fromEntries(props.filter((prop) => isRelationProp(prop)).map((prop) => [prop.name, prop]));
|
|
65
|
+
} else {
|
|
66
|
+
this.props = [];
|
|
67
|
+
this.propsDict = {};
|
|
68
|
+
this.relations = {};
|
|
69
|
+
}
|
|
70
|
+
this.indexes = indexes ?? [];
|
|
71
|
+
this.subsets = {};
|
|
72
|
+
this.subsetsInternal = {};
|
|
73
|
+
for (const [key, subsetDef] of Object.entries(subsets ?? {})) {
|
|
74
|
+
const fields = getSubsetFields(subsetDef);
|
|
75
|
+
this.subsets[key] = fields.filter((f) => !isInternalSubsetField(f)).map(normalizeSubsetField);
|
|
76
|
+
this.subsetsInternal[key] = fields.filter(isInternalSubsetField).map(normalizeSubsetField);
|
|
77
|
+
if (!Array.isArray(subsetDef) && "cone" in subsetDef && subsetDef.cone) {
|
|
78
|
+
this.subsetCones[key] = subsetDef.cone;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
this.enumLabels = Object.fromEntries(Object.entries(enums ?? {}).map(([key, enumDef]) => {
|
|
82
|
+
if ("values" in enumDef && "cone" in enumDef && enumDef.cone) {
|
|
83
|
+
this.enumCones[key] = enumDef.cone;
|
|
84
|
+
}
|
|
85
|
+
return [key, getEnumDefValues(enumDef)];
|
|
86
|
+
}));
|
|
87
|
+
this.enums = Object.fromEntries(Object.entries(this.enumLabels).map(([key, enumLabel]) => {
|
|
88
|
+
return [key, z$1.enum(Object.keys(enumLabel))];
|
|
89
|
+
}));
|
|
90
|
+
this.names = {
|
|
91
|
+
parentFs: inflection.dasherize(inflection.underscore(parentId ?? id)).toLowerCase(),
|
|
92
|
+
fs: inflection.dasherize(inflection.underscore(id)).toLowerCase(),
|
|
93
|
+
module: id
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* 쿼리용 서브셋 필드를 반환합니다 (subsets + subsetsInternal 합침)
|
|
98
|
+
*/
|
|
99
|
+
getSubsetFieldsForQuery(subsetKey) {
|
|
100
|
+
return [...this.subsets[subsetKey] ?? [], ...this.subsetsInternal[subsetKey] ?? []];
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* 주어진 이름(subsetKey)의 subset을 실제로 가져오는 Puri 코드 구현체 string을 반환합니다.
|
|
104
|
+
*/
|
|
105
|
+
getPuriSubsetQuery(subsetKey) {
|
|
106
|
+
const subset = this.getSubsetFieldsForQuery(subsetKey);
|
|
107
|
+
const subsetQuery = this.resolveSubsetQuery("", subset);
|
|
108
|
+
const lines = [];
|
|
109
|
+
lines.push(`return qbWrapper`);
|
|
110
|
+
lines.push(`.from("${this.table}")`);
|
|
111
|
+
for (const join$1 of subsetQuery.joins) {
|
|
112
|
+
const joinMethod = join$1.join === "inner" ? "join" : "leftJoin";
|
|
113
|
+
if ("custom" in join$1) {
|
|
114
|
+
lines.push(`.${joinMethod}({ ${join$1.as}: "${join$1.table}" }, qbWrapper.knex.raw(\`${join$1.custom}\`))`);
|
|
115
|
+
} else {
|
|
116
|
+
lines.push(`.${joinMethod}({ ${join$1.as}: "${join$1.table}" }, "${join$1.from}", "${join$1.to}")`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
const selectObj = this.buildNestedSelectObject(subsetQuery.select);
|
|
120
|
+
lines.push(`.select(${this.stringifyNestedSelectObject(selectObj)});`);
|
|
121
|
+
return lines.join("\n");
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* *.entity.json의 subset에 들어있는 필드 배열을 받아서,
|
|
125
|
+
* Puri의 SelectObject 타입으로 변환합니다.
|
|
126
|
+
*
|
|
127
|
+
* 예: ["users.id", "parent.id", "parent.name"]
|
|
128
|
+
* → { id: "users.id", parent: { id: "parent.id", name: "parent.name" } }
|
|
129
|
+
*
|
|
130
|
+
* 언더바가 아닌 중첩 객체로 변환함에 유의하세요.
|
|
131
|
+
* 이렇게 중첩 객체로 변환하여 select에 넘겨주면 ParseSelectObject 타입이 join된 객체의 타입을 잘 잡아줄 수 있습니다.
|
|
132
|
+
* 즉, enhancer에서 row를 받았을 때 hydrate된 객체 자체의 nullity와 그 안쪽 필드의 nullity가 fk nullable 여부에 따라 잘 추론됩니다.
|
|
133
|
+
*/
|
|
134
|
+
buildNestedSelectObject(selectItems) {
|
|
135
|
+
const result = {};
|
|
136
|
+
for (const selectItem of selectItems) {
|
|
137
|
+
const match = selectItem.match(/^(.+?)(?: as (.+))?$/);
|
|
138
|
+
if (!match) continue;
|
|
139
|
+
const [, column, alias] = match;
|
|
140
|
+
const columnValue = `"${column.trim()}"`;
|
|
141
|
+
if (!alias || !alias.includes("__")) {
|
|
142
|
+
const key = alias ?? assertDefined(column.split(".").pop());
|
|
143
|
+
result[key] = columnValue;
|
|
144
|
+
} else {
|
|
145
|
+
const parts = alias.split("__");
|
|
146
|
+
let current = result;
|
|
147
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
148
|
+
const part = parts[i];
|
|
149
|
+
if (part in current) {
|
|
150
|
+
if (typeof current[part] === "string") {
|
|
151
|
+
throw new Error(`Conflict detected in select items: parent path "${parts.slice(0, i + 1).join("__")}" is already set as a field, cannot nest "${alias}" under it.`);
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
current[part] = {};
|
|
155
|
+
}
|
|
156
|
+
current = current[part];
|
|
157
|
+
}
|
|
158
|
+
const lastPart = parts[parts.length - 1];
|
|
159
|
+
current[lastPart] = columnValue;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* JSON.stringify와 유사한 일을 합니다.
|
|
166
|
+
* 다만 주어진 객체를 JSON이 아닌 TypeScript 객체 리터럴 스트링으로 만들어줍니다.
|
|
167
|
+
* key에 따옴표가 없어요.
|
|
168
|
+
* 출력 예시:
|
|
169
|
+
* ```typescript
|
|
170
|
+
* {
|
|
171
|
+
* id: "users.id",
|
|
172
|
+
* parent: {
|
|
173
|
+
* id: "parent.id",
|
|
174
|
+
* name: "parent.name",
|
|
175
|
+
* },
|
|
176
|
+
* }
|
|
177
|
+
* ```
|
|
178
|
+
* @param obj 변환할 객체
|
|
179
|
+
* @param indent 들여쓰기 레벨
|
|
180
|
+
* @param withBraces true면 중괄호 포함, false면 내용만 반환
|
|
181
|
+
*/
|
|
182
|
+
stringifyNestedSelectObject(obj, indent = 0, withBraces = true) {
|
|
183
|
+
const spaces = " ".repeat(indent);
|
|
184
|
+
const innerSpaces = " ".repeat(indent + 1);
|
|
185
|
+
const entries = Object.entries(obj);
|
|
186
|
+
if (entries.length === 0) return withBraces ? "{}" : "";
|
|
187
|
+
const lines = entries.map(([key, value]) => {
|
|
188
|
+
if (typeof value === "string") {
|
|
189
|
+
return `${innerSpaces}${key}: ${value},`;
|
|
190
|
+
} else {
|
|
191
|
+
return `${innerSpaces}${key}: ${this.stringifyNestedSelectObject(value, indent + 1, true)},`;
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
if (withBraces) {
|
|
195
|
+
return `{\n${lines.join("\n")}\n${spaces}}`;
|
|
196
|
+
} else {
|
|
197
|
+
return lines.join("\n");
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
getPuriLoaderQuery(subsetKey) {
|
|
201
|
+
const subset = this.getSubsetFieldsForQuery(subsetKey);
|
|
202
|
+
const { loaders } = this.resolveSubsetQuery("", subset);
|
|
203
|
+
const lines = [`[`];
|
|
204
|
+
const generateLoaderCode = (loaders$1) => {
|
|
205
|
+
const loaderLines = [];
|
|
206
|
+
for (const loader of loaders$1) {
|
|
207
|
+
const { toTable, toCol, through, fromTable } = loader.manyJoin;
|
|
208
|
+
const fromEntity = EntityManager.getByTable(fromTable);
|
|
209
|
+
const fromIdsType = fromEntity.getPkArrayType();
|
|
210
|
+
loaderLines.push("{", `as: "${loader.as}",`, `refId: "${loader.manyJoin.idField}",`, `qb: (qbWrapper: PuriWrapper<DatabaseSchemaExtend>, fromIds: number[] | string[]) => {`);
|
|
211
|
+
if (through === undefined) {
|
|
212
|
+
loaderLines.push("return qbWrapper", `.from("${toTable}")`);
|
|
213
|
+
loader.oneJoins.forEach((join$1) => {
|
|
214
|
+
const joinMethod = join$1.join === "inner" ? "join" : "leftJoin";
|
|
215
|
+
if ("custom" in join$1) {
|
|
216
|
+
loaderLines.push(`.${joinMethod}({ ${join$1.as}: "${join$1.table}" }, (j) => {`, `j.on(Puri.rawString("${join$1.custom}"));`, "})");
|
|
217
|
+
} else {
|
|
218
|
+
loaderLines.push(`.${joinMethod}({ ${join$1.as}: "${join$1.table}" }, "${join$1.from}", "${join$1.to}")`);
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
const selectObj = this.buildNestedSelectObject(loader.select);
|
|
222
|
+
selectObj.refId = `"${toTable}.${toCol}"`;
|
|
223
|
+
loaderLines.push(`.whereIn("${toTable}.${toCol}", fromIds as ${fromIdsType})`, `.select(${this.stringifyNestedSelectObject(selectObj)});`);
|
|
224
|
+
} else {
|
|
225
|
+
loaderLines.push("return qbWrapper", `.from("${through.table}")`, `.join("${toTable}", "${through.table}.${through.toCol}", "${toTable}.${toCol}")`);
|
|
226
|
+
loader.oneJoins.forEach((join$1) => {
|
|
227
|
+
const joinMethod = join$1.join === "inner" ? "join" : "leftJoin";
|
|
228
|
+
if ("custom" in join$1) {
|
|
229
|
+
loaderLines.push(`.${joinMethod}({ ${join$1.as}: "${join$1.table}" }, (j) => {`, `j.on(Puri.rawString("${join$1.custom}"));`, "})");
|
|
230
|
+
} else {
|
|
231
|
+
loaderLines.push(`.${joinMethod}({ ${join$1.as}: "${join$1.table}" }, "${join$1.from}", "${join$1.to}")`);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
const selectObj = this.buildNestedSelectObject(loader.select);
|
|
235
|
+
selectObj.refId = `"${through.table}.${through.fromCol}"`;
|
|
236
|
+
loaderLines.push(`.whereIn("${through.table}.${through.fromCol}", fromIds as ${fromIdsType})`, `.select(${this.stringifyNestedSelectObject(selectObj)});`);
|
|
237
|
+
}
|
|
238
|
+
loaderLines.push(`},`);
|
|
239
|
+
if (loader.loaders && loader.loaders.length > 0) {
|
|
240
|
+
loaderLines.push("loaders: [", ...generateLoaderCode(loader.loaders), "],");
|
|
241
|
+
}
|
|
242
|
+
loaderLines.push("},");
|
|
243
|
+
}
|
|
244
|
+
return loaderLines;
|
|
245
|
+
};
|
|
246
|
+
lines.push(...generateLoaderCode(loaders));
|
|
247
|
+
lines.push(`]`);
|
|
248
|
+
return lines.join("\n");
|
|
249
|
+
}
|
|
250
|
+
getSubsetQuery(subsetKey) {
|
|
251
|
+
const subset = this.getSubsetFieldsForQuery(subsetKey);
|
|
252
|
+
const result = this.resolveSubsetQuery("", subset);
|
|
253
|
+
return result;
|
|
254
|
+
}
|
|
255
|
+
resolveSubsetQuery(prefix, fields, isAlreadyOuterJoined = false) {
|
|
256
|
+
prefix = prefix.replace(/\./g, "__");
|
|
257
|
+
const subsetGroup = group(fields, (field) => {
|
|
258
|
+
if (field.includes(".")) {
|
|
259
|
+
const [rel] = field.split(".");
|
|
260
|
+
return rel;
|
|
261
|
+
} else {
|
|
262
|
+
return "";
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
const result = Object.keys(subsetGroup).reduce((r, groupKey) => {
|
|
266
|
+
const fields$1 = subsetGroup[groupKey];
|
|
267
|
+
assert(fields$1 !== undefined, "fields is undefined");
|
|
268
|
+
if (groupKey === "") {
|
|
269
|
+
const realFields = fields$1.filter((field) => !isVirtualProp(this.propsDict[field]));
|
|
270
|
+
const virtualCodeFields = fields$1.filter((field) => isVirtualCodeProp(this.propsDict[field]));
|
|
271
|
+
if (prefix === "") {
|
|
272
|
+
r.select = r.select.concat(realFields.map((field) => this.getFullFieldName(field)));
|
|
273
|
+
r.virtual = r.virtual.concat(virtualCodeFields);
|
|
274
|
+
} else {
|
|
275
|
+
r.select = r.select.concat(realFields.map((field) => `${prefix}.${field} as ${prefix}__${field}`));
|
|
276
|
+
}
|
|
277
|
+
return r;
|
|
278
|
+
}
|
|
279
|
+
const relation = this.relations[groupKey];
|
|
280
|
+
if (relation === undefined) {
|
|
281
|
+
throw new Error(`존재하지 않는 relation 참조 ${groupKey}`);
|
|
282
|
+
}
|
|
283
|
+
const relEntity = EntityManager.get(relation.with);
|
|
284
|
+
if (isOneToOneRelationProp(relation) || isBelongsToOneRelationProp(relation)) {
|
|
285
|
+
const relFields = fields$1.map((field) => field.split(".").slice(1).join("."));
|
|
286
|
+
if (relFields.length === 1 && relFields[0] === "id") {
|
|
287
|
+
if (prefix === "") {
|
|
288
|
+
r.select = r.select.concat(`${this.table}.${groupKey}_id`);
|
|
289
|
+
} else {
|
|
290
|
+
r.select = r.select.concat(`${prefix}.${groupKey}_id as ${prefix}__${groupKey}_id`);
|
|
291
|
+
}
|
|
292
|
+
return r;
|
|
293
|
+
}
|
|
294
|
+
const innerOrOuter = (() => {
|
|
295
|
+
if (isAlreadyOuterJoined) {
|
|
296
|
+
return "outer";
|
|
297
|
+
}
|
|
298
|
+
if (isOneToOneRelationProp(relation)) {
|
|
299
|
+
if (relation.hasJoinColumn && !(relation.nullable ?? false)) {
|
|
300
|
+
return "inner";
|
|
301
|
+
} else {
|
|
302
|
+
return "outer";
|
|
303
|
+
}
|
|
304
|
+
} else {
|
|
305
|
+
if (relation.nullable) {
|
|
306
|
+
return "outer";
|
|
307
|
+
} else {
|
|
308
|
+
return "inner";
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
})();
|
|
312
|
+
const relSubsetQuery = relEntity.resolveSubsetQuery(`${prefix !== "" ? `${prefix}.` : ""}${groupKey}`, relFields, innerOrOuter === "outer");
|
|
313
|
+
r.select = r.select.concat(relSubsetQuery.select);
|
|
314
|
+
r.virtual = r.virtual.concat(relSubsetQuery.virtual);
|
|
315
|
+
const joinAs = prefix === "" ? groupKey : `${prefix}__${groupKey}`;
|
|
316
|
+
const fromTable = prefix === "" ? this.table : prefix;
|
|
317
|
+
let joinClause;
|
|
318
|
+
if (relation.customJoinClause) {
|
|
319
|
+
joinClause = { custom: relation.customJoinClause };
|
|
320
|
+
} else {
|
|
321
|
+
let from, to;
|
|
322
|
+
if (isOneToOneRelationProp(relation)) {
|
|
323
|
+
if (relation.hasJoinColumn) {
|
|
324
|
+
from = `${fromTable}.${relation.name}_id`;
|
|
325
|
+
to = `${joinAs}.id`;
|
|
326
|
+
} else {
|
|
327
|
+
from = `${fromTable}.id`;
|
|
328
|
+
to = `${joinAs}.${inflection.underscore(this.names.fs.replace(/-/g, "_"))}_id`;
|
|
329
|
+
}
|
|
330
|
+
} else {
|
|
331
|
+
from = `${fromTable}.${relation.name}_id`;
|
|
332
|
+
to = `${joinAs}.id`;
|
|
333
|
+
}
|
|
334
|
+
joinClause = {
|
|
335
|
+
from,
|
|
336
|
+
to
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
r.joins.push({
|
|
340
|
+
as: joinAs,
|
|
341
|
+
join: innerOrOuter,
|
|
342
|
+
table: relEntity.table,
|
|
343
|
+
...joinClause
|
|
344
|
+
});
|
|
345
|
+
if (relSubsetQuery.loaders.length > 0) {
|
|
346
|
+
const convertedLoaders = relSubsetQuery.loaders.map((loader) => {
|
|
347
|
+
const newAs = [groupKey, loader.as].join("__");
|
|
348
|
+
return {
|
|
349
|
+
as: newAs,
|
|
350
|
+
table: loader.table,
|
|
351
|
+
manyJoin: loader.manyJoin,
|
|
352
|
+
oneJoins: loader.oneJoins,
|
|
353
|
+
select: loader.select,
|
|
354
|
+
loaders: loader.loaders
|
|
355
|
+
};
|
|
356
|
+
});
|
|
357
|
+
r.loaders = [...r.loaders, ...convertedLoaders];
|
|
358
|
+
}
|
|
359
|
+
r.joins = r.joins.concat(relSubsetQuery.joins);
|
|
360
|
+
} else if (isHasManyRelationProp(relation) || isManyToManyRelationProp(relation)) {
|
|
361
|
+
const relFields = fields$1.map((field) => field.split(".").slice(1).join("."));
|
|
362
|
+
const relSubsetQuery = relEntity.resolveSubsetQuery("", relFields);
|
|
363
|
+
let manyJoin;
|
|
364
|
+
if (isHasManyRelationProp(relation)) {
|
|
365
|
+
const fromCol = relation?.fromColumn ?? "id";
|
|
366
|
+
manyJoin = {
|
|
367
|
+
fromTable: this.table,
|
|
368
|
+
fromCol,
|
|
369
|
+
idField: prefix === "" ? `${fromCol}` : `${prefix}__${fromCol}`,
|
|
370
|
+
toTable: relEntity.table,
|
|
371
|
+
toCol: relation.joinColumn
|
|
372
|
+
};
|
|
373
|
+
} else if (isManyToManyRelationProp(relation)) {
|
|
374
|
+
manyJoin = {
|
|
375
|
+
fromTable: this.table,
|
|
376
|
+
fromCol: "id",
|
|
377
|
+
idField: prefix === "" ? `id` : `${prefix}__id`,
|
|
378
|
+
through: {
|
|
379
|
+
table: relation.joinTable,
|
|
380
|
+
fromCol: `${inflection.singularize(this.table)}_id`,
|
|
381
|
+
toCol: `${inflection.singularize(relEntity.table)}_id`
|
|
382
|
+
},
|
|
383
|
+
toTable: relEntity.table,
|
|
384
|
+
toCol: "id"
|
|
385
|
+
};
|
|
386
|
+
} else {
|
|
387
|
+
throw new Error();
|
|
388
|
+
}
|
|
389
|
+
r.loaders.push({
|
|
390
|
+
as: groupKey,
|
|
391
|
+
table: relEntity.table,
|
|
392
|
+
manyJoin,
|
|
393
|
+
oneJoins: relSubsetQuery.joins,
|
|
394
|
+
select: relSubsetQuery.select,
|
|
395
|
+
loaders: relSubsetQuery.loaders
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
return r;
|
|
399
|
+
}, {
|
|
400
|
+
select: [],
|
|
401
|
+
virtual: [],
|
|
402
|
+
joins: [],
|
|
403
|
+
loaders: []
|
|
404
|
+
});
|
|
405
|
+
return result;
|
|
406
|
+
}
|
|
407
|
+
fieldExprsToPropNodes(fieldExprs, entity = this) {
|
|
408
|
+
const groups = fieldExprs.reduce((result, fieldExpr) => {
|
|
409
|
+
let key, value, elseExpr;
|
|
410
|
+
if (fieldExpr.includes(".")) {
|
|
411
|
+
[key, ...elseExpr] = fieldExpr.split(".");
|
|
412
|
+
value = elseExpr.join(".");
|
|
413
|
+
} else {
|
|
414
|
+
key = "";
|
|
415
|
+
value = fieldExpr;
|
|
416
|
+
}
|
|
417
|
+
result[key] = (result[key] ?? []).concat(value);
|
|
418
|
+
return result;
|
|
419
|
+
}, {});
|
|
420
|
+
return Object.keys(groups).flatMap((key) => {
|
|
421
|
+
const group$1 = groups[key];
|
|
422
|
+
if (key === "") {
|
|
423
|
+
return group$1.map((propName) => {
|
|
424
|
+
const prop$1 = entity.props.find((p) => p.name === propName);
|
|
425
|
+
if (prop$1 === undefined) {
|
|
426
|
+
throw new Error(`${entity.id} -- 잘못된 FieldExpr '${propName}' (사용 가능한 props: ${entity.props.map((p) => p.name).join(", ")})`);
|
|
427
|
+
}
|
|
428
|
+
return {
|
|
429
|
+
nodeType: "plain",
|
|
430
|
+
prop: prop$1
|
|
431
|
+
};
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
const prop = entity.propsDict[key];
|
|
435
|
+
if (!isRelationProp(prop)) {
|
|
436
|
+
throw new Error(`잘못된 FieldExpr ${key}.${group$1[0]}`);
|
|
437
|
+
}
|
|
438
|
+
const relEntity = EntityManager.get(prop.with);
|
|
439
|
+
if (isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop)) {
|
|
440
|
+
if (group$1.length === 1 && (group$1[0] === "id" || group$1[0] === "id?")) {
|
|
441
|
+
const idProp = relEntity.propsDict.id;
|
|
442
|
+
return {
|
|
443
|
+
nodeType: "plain",
|
|
444
|
+
prop: {
|
|
445
|
+
...idProp,
|
|
446
|
+
name: `${key}_id`,
|
|
447
|
+
nullable: prop.nullable
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
const children = this.fieldExprsToPropNodes(group$1, relEntity);
|
|
453
|
+
const nodeType = isBelongsToOneRelationProp(prop) || isOneToOneRelationProp(prop) ? "object" : "array";
|
|
454
|
+
return {
|
|
455
|
+
nodeType,
|
|
456
|
+
prop,
|
|
457
|
+
children
|
|
458
|
+
};
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
getFieldExprs(prefix = "", maxDepth = 3, froms = []) {
|
|
462
|
+
return this.props.flatMap((prop) => {
|
|
463
|
+
const propName = [prefix, prop.name].filter((v) => v !== "").join(".");
|
|
464
|
+
if (propName === prefix) {
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
if (isRelationProp(prop)) {
|
|
468
|
+
if (maxDepth < 0) {
|
|
469
|
+
return null;
|
|
470
|
+
}
|
|
471
|
+
if (froms.includes(prop.with)) {
|
|
472
|
+
return null;
|
|
473
|
+
}
|
|
474
|
+
const relMd = EntityManager.get(prop.with);
|
|
475
|
+
return relMd.getFieldExprs(propName, maxDepth - 1, [...froms, this.id]);
|
|
476
|
+
}
|
|
477
|
+
return propName;
|
|
478
|
+
}).filter((f) => f !== null);
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Relation prop이 현재 테이블에 FK 컬럼을 생성하는지 확인
|
|
482
|
+
*(BelongsToOne 또는 OneToOne(hasJoinColumn=true)인 경우 FK 생성)
|
|
483
|
+
*/
|
|
484
|
+
hasForeignKey(prop) {
|
|
485
|
+
return prop.relationType === "BelongsToOne" || prop.relationType === "OneToOne" && prop.hasJoinColumn;
|
|
486
|
+
}
|
|
487
|
+
getTableColumns() {
|
|
488
|
+
return this.props.map((prop) => {
|
|
489
|
+
if (prop.type === "relation") {
|
|
490
|
+
if (this.hasForeignKey(prop)) {
|
|
491
|
+
return {
|
|
492
|
+
name: `${prop.name}_id`,
|
|
493
|
+
type: "int_unsigned"
|
|
494
|
+
};
|
|
495
|
+
} else {
|
|
496
|
+
return null;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return {
|
|
500
|
+
name: prop.name,
|
|
501
|
+
type: prop.type
|
|
502
|
+
};
|
|
503
|
+
}).filter(nonNullable);
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* Entity에 정의된 모든 vector 타입 컬럼 반환
|
|
507
|
+
*/
|
|
508
|
+
getVectorColumns() {
|
|
509
|
+
return this.props.filter((p) => p.type === "vector");
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* 특정 vector 컬럼 반환
|
|
513
|
+
* @param columnName - 컬럼명 (생략 시 첫 번째 vector 컬럼)
|
|
514
|
+
*/
|
|
515
|
+
getVectorColumn(columnName) {
|
|
516
|
+
const vectorProps = this.getVectorColumns();
|
|
517
|
+
if (columnName) {
|
|
518
|
+
return vectorProps.find((p) => p.name === columnName);
|
|
519
|
+
}
|
|
520
|
+
return vectorProps[0];
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* 필터링 가능한 props 반환
|
|
524
|
+
*
|
|
525
|
+
* - 일반 prop
|
|
526
|
+
* - FK를 생성하는 relation (BelongsToOne, OneToOne with hasJoinColumn)
|
|
527
|
+
* → {name}_id 형태의 가상 integer prop으로 변환
|
|
528
|
+
*/
|
|
529
|
+
getFilterableProps() {
|
|
530
|
+
return this.props.flatMap((prop) => {
|
|
531
|
+
if (isVirtualProp(prop)) {
|
|
532
|
+
return [];
|
|
533
|
+
}
|
|
534
|
+
if (isRelationProp(prop)) {
|
|
535
|
+
if (this.hasForeignKey(prop)) {
|
|
536
|
+
return {
|
|
537
|
+
name: `${prop.name}_id`,
|
|
538
|
+
type: "integer",
|
|
539
|
+
nullable: prop.nullable
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
return [];
|
|
543
|
+
}
|
|
544
|
+
return prop;
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
async registerModulePaths() {
|
|
548
|
+
const basePath = `${this.names.parentFs}`;
|
|
549
|
+
EntityManager.setModulePath(`${this.id}BaseSchema`, `sonamu.generated`);
|
|
550
|
+
if (Object.keys(this.subsets).length > 0) {
|
|
551
|
+
EntityManager.setModulePath(`${this.id}SubsetKey`, `sonamu.generated`);
|
|
552
|
+
EntityManager.setModulePath(`${this.id}SubsetMapping`, `sonamu.generated`);
|
|
553
|
+
for (const subsetKey of Object.keys(this.subsets)) {
|
|
554
|
+
EntityManager.setModulePath(`${this.id}Subset${subsetKey.toUpperCase()}`, `sonamu.generated`);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
for (const enumId of Object.keys(this.enumLabels)) {
|
|
558
|
+
EntityManager.setModulePath(enumId, `sonamu.generated`);
|
|
559
|
+
}
|
|
560
|
+
const typesModulePath = `${basePath}/${this.names.parentFs}.types`;
|
|
561
|
+
const typesFilePath = path.join(Sonamu.apiRootPath, runtimePath(`dist/application/${typesModulePath}.js`));
|
|
562
|
+
if (await exists(typesFilePath)) {
|
|
563
|
+
const importedMembers = await importMembers(typesFilePath);
|
|
564
|
+
this.types = Object.fromEntries(importedMembers.map(({ name, value }) => {
|
|
565
|
+
EntityManager.setModulePath(name, typesModulePath);
|
|
566
|
+
return [name, value];
|
|
567
|
+
}));
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
registerTableSpecs() {
|
|
571
|
+
const uniqueIndexes = this.indexes.filter((idx) => idx.type === "unique").filter((idx) => idx.columns.every((col) => !col.name.includes(".")));
|
|
572
|
+
EntityManager.setTableSpec({
|
|
573
|
+
name: this.table,
|
|
574
|
+
uniqueIndexes,
|
|
575
|
+
jsonColumns: this.props.filter((p) => p.type === "json").map((p) => p.name)
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
toJson() {
|
|
579
|
+
const subsets = {};
|
|
580
|
+
for (const key of Object.keys(this.subsets)) {
|
|
581
|
+
const normalFields = this.subsets[key];
|
|
582
|
+
const internalFields = (this.subsetsInternal[key] ?? []).map((field) => ({
|
|
583
|
+
field,
|
|
584
|
+
internal: true
|
|
585
|
+
}));
|
|
586
|
+
const fields = [...normalFields, ...internalFields];
|
|
587
|
+
if (this.subsetCones[key]) {
|
|
588
|
+
subsets[key] = {
|
|
589
|
+
fields,
|
|
590
|
+
cone: this.subsetCones[key]
|
|
591
|
+
};
|
|
592
|
+
} else {
|
|
593
|
+
subsets[key] = fields;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
const enums = {};
|
|
597
|
+
for (const [key, values] of Object.entries(this.enumLabels)) {
|
|
598
|
+
if (this.enumCones[key]) {
|
|
599
|
+
enums[key] = {
|
|
600
|
+
values,
|
|
601
|
+
cone: this.enumCones[key]
|
|
602
|
+
};
|
|
603
|
+
} else {
|
|
604
|
+
enums[key] = values;
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
return {
|
|
608
|
+
id: this.id,
|
|
609
|
+
parentId: this.parentId,
|
|
610
|
+
table: this.table,
|
|
611
|
+
title: this.title,
|
|
612
|
+
cone: this.cone,
|
|
613
|
+
props: this.props,
|
|
614
|
+
indexes: this.indexes,
|
|
615
|
+
subsets,
|
|
616
|
+
enums
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
async save() {
|
|
620
|
+
const subsetRows = this.getSubsetRows();
|
|
621
|
+
this.subsets = Object.fromEntries(Object.entries(this.subsets).map(([subsetKey]) => {
|
|
622
|
+
return [subsetKey, this.subsetRowsToSubsetFields(subsetRows, subsetKey, false)];
|
|
623
|
+
}));
|
|
624
|
+
this.subsetsInternal = Object.fromEntries(Object.entries(this.subsetsInternal).map(([subsetKey]) => {
|
|
625
|
+
return [subsetKey, this.subsetRowsToSubsetFields(subsetRows, subsetKey, true)];
|
|
626
|
+
}));
|
|
627
|
+
const jsonPath = path.join(Sonamu.apiRootPath, `src/application/${this.names.parentFs}/${this.names.fs}.entity.json`);
|
|
628
|
+
const json = this.toJson();
|
|
629
|
+
await writeFile(jsonPath, await formatCode(JSON.stringify(json), "json", jsonPath));
|
|
630
|
+
await EntityManager.register(json);
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* 템플릿 cone 메타데이터를 생성합니다.
|
|
634
|
+
*
|
|
635
|
+
* LLM을 사용하지 않고 faker-mappings.ts를 활용하여 기본 cone을 생성합니다.
|
|
636
|
+
* stub entity 생성 시 자동으로 호출되어 최소한의 cone 메타데이터를 제공합니다.
|
|
637
|
+
*
|
|
638
|
+
* @param locale - 생성 시 사용할 locale (기본값: Sonamu.config.i18n.defaultLocale 또는 "ko")
|
|
639
|
+
*/
|
|
640
|
+
async generateTemplateCones(locale) {
|
|
641
|
+
const { generateTemplateCones } = await import("./entity-template-cone.js");
|
|
642
|
+
const configLocale = Sonamu.config.i18n?.defaultLocale;
|
|
643
|
+
const effectiveLocale = locale || (configLocale === "ko" || configLocale === "en" || configLocale === "ja" ? configLocale : "ko");
|
|
644
|
+
const result = generateTemplateCones(this.toJson(), effectiveLocale);
|
|
645
|
+
if (result.entityCone) {
|
|
646
|
+
this.cone = result.entityCone;
|
|
647
|
+
}
|
|
648
|
+
for (const [propName, cone] of Object.entries(result.propCones)) {
|
|
649
|
+
const prop = this.props.find((p) => p.name === propName);
|
|
650
|
+
if (prop) {
|
|
651
|
+
prop.cone = cone;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
this.enumCones = {
|
|
655
|
+
...this.enumCones,
|
|
656
|
+
...result.enumCones
|
|
657
|
+
};
|
|
658
|
+
this.subsetCones = {
|
|
659
|
+
...this.subsetCones,
|
|
660
|
+
...result.subsetCones
|
|
661
|
+
};
|
|
662
|
+
await this.save();
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* LLM을 사용하여 cone 메타데이터를 생성합니다.
|
|
666
|
+
*
|
|
667
|
+
* @param options.preserveExisting - 기존 cone 보존 여부 (기본값: true)
|
|
668
|
+
* @param options.onlyEmpty - fixtureHint가 없는 cone만 생성 (기본값: false)
|
|
669
|
+
* @param options.locale - 생성 시 사용할 locale (기본값: "ko")
|
|
670
|
+
*/
|
|
671
|
+
async generateCones(options) {
|
|
672
|
+
const { generateCones } = await import("../cone/cone-generator.js");
|
|
673
|
+
const context = {
|
|
674
|
+
entity: this.toJson(),
|
|
675
|
+
locale: options?.locale || "ko",
|
|
676
|
+
existingCones: options?.preserveExisting !== false ? this.collectExistingCones() : undefined,
|
|
677
|
+
onlyEmpty: options?.onlyEmpty ?? false
|
|
678
|
+
};
|
|
679
|
+
const result = await generateCones(context);
|
|
680
|
+
this.applyCones(result);
|
|
681
|
+
await this.save();
|
|
682
|
+
return result;
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* 기존 cone들을 수집합니다 (entity, props, enums, subsets).
|
|
686
|
+
*
|
|
687
|
+
* @returns 키가 "entity:id", "prop:name", "enum:enumId", "subset:key" 형식인 cone 맵
|
|
688
|
+
*/
|
|
689
|
+
collectExistingCones() {
|
|
690
|
+
const cones = {};
|
|
691
|
+
if (this.cone) {
|
|
692
|
+
cones[`entity:${this.id}`] = this.cone;
|
|
693
|
+
}
|
|
694
|
+
for (const prop of this.props) {
|
|
695
|
+
if (prop.cone) {
|
|
696
|
+
cones[`prop:${prop.name}`] = prop.cone;
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
for (const [enumId, cone] of Object.entries(this.enumCones)) {
|
|
700
|
+
cones[`enum:${enumId}`] = cone;
|
|
701
|
+
}
|
|
702
|
+
for (const [subsetKey, cone] of Object.entries(this.subsetCones)) {
|
|
703
|
+
cones[`subset:${subsetKey}`] = cone;
|
|
704
|
+
}
|
|
705
|
+
return cones;
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* 생성된 cone들을 Entity에 적용합니다.
|
|
709
|
+
*
|
|
710
|
+
* @param result - LLM으로 생성된 cone 결과
|
|
711
|
+
*/
|
|
712
|
+
applyCones(result) {
|
|
713
|
+
if (result.entityCone) {
|
|
714
|
+
this.cone = result.entityCone;
|
|
715
|
+
}
|
|
716
|
+
for (const [propName, cone] of Object.entries(result.propCones)) {
|
|
717
|
+
const prop = this.props.find((p) => p.name === propName);
|
|
718
|
+
if (prop) {
|
|
719
|
+
prop.cone = cone;
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
this.enumCones = {
|
|
723
|
+
...this.enumCones,
|
|
724
|
+
...result.enumCones
|
|
725
|
+
};
|
|
726
|
+
this.subsetCones = {
|
|
727
|
+
...this.subsetCones,
|
|
728
|
+
...result.subsetCones
|
|
729
|
+
};
|
|
730
|
+
}
|
|
731
|
+
getSubsetRows(_subsets, _subsetsInternal, prefixes = []) {
|
|
732
|
+
if (prefixes.length > 10) {
|
|
733
|
+
return [];
|
|
734
|
+
}
|
|
735
|
+
const subsets = _subsets ?? this.subsets;
|
|
736
|
+
const subsetsInternal = _subsetsInternal ?? this.subsetsInternal;
|
|
737
|
+
const subsetKeys = Object.keys(subsets);
|
|
738
|
+
const allFields = unique(subsetKeys.flatMap((key) => subsets[key]));
|
|
739
|
+
const allInternalFields = unique(subsetKeys.flatMap((key) => subsetsInternal[key] ?? []));
|
|
740
|
+
const combinedFields = unique([...allFields, ...allInternalFields]);
|
|
741
|
+
return this.props.map((prop) => {
|
|
742
|
+
if (prop.type === "relation" && combinedFields.find((f) => f.startsWith(`${[...prefixes, prop.name].join(".")}.`))) {
|
|
743
|
+
const relEntity = EntityManager.get(prop.with);
|
|
744
|
+
const children = relEntity.getSubsetRows(subsets, subsetsInternal, [...prefixes, `${prop.name}`]);
|
|
745
|
+
return {
|
|
746
|
+
field: prop.name,
|
|
747
|
+
children,
|
|
748
|
+
relationEntity: prop.with,
|
|
749
|
+
prefixes,
|
|
750
|
+
isOpen: children.length > 0,
|
|
751
|
+
has: Object.fromEntries(subsetKeys.map((subsetKey) => {
|
|
752
|
+
return [subsetKey, children.every((child) => child.has[subsetKey])];
|
|
753
|
+
})),
|
|
754
|
+
isInternal: Object.fromEntries(subsetKeys.map((subsetKey) => {
|
|
755
|
+
return [subsetKey, children.every((child) => child.isInternal[subsetKey])];
|
|
756
|
+
}))
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
const field = [...prefixes, prop.name].join(".");
|
|
760
|
+
return {
|
|
761
|
+
field: prop.name,
|
|
762
|
+
children: [],
|
|
763
|
+
relationEntity: prop.type === "relation" ? prop.with : undefined,
|
|
764
|
+
prefixes,
|
|
765
|
+
has: Object.fromEntries(subsetKeys.map((subsetKey) => {
|
|
766
|
+
const subsetFields = subsets[subsetKey];
|
|
767
|
+
const has = subsetFields.some((f) => {
|
|
768
|
+
return f === field || f.startsWith(`${field}.`);
|
|
769
|
+
});
|
|
770
|
+
return [subsetKey, has];
|
|
771
|
+
})),
|
|
772
|
+
isInternal: Object.fromEntries(subsetKeys.map((subsetKey) => {
|
|
773
|
+
const internalFields = subsetsInternal[subsetKey] ?? [];
|
|
774
|
+
const isInternal = internalFields.some((f) => {
|
|
775
|
+
return f === field || f.startsWith(`${field}.`);
|
|
776
|
+
});
|
|
777
|
+
return [subsetKey, isInternal];
|
|
778
|
+
}))
|
|
779
|
+
};
|
|
780
|
+
});
|
|
781
|
+
}
|
|
782
|
+
subsetRowsToSubsetFields(subsetRows, subsetKey, internal = false) {
|
|
783
|
+
const hasKey = internal ? "isInternal" : "has";
|
|
784
|
+
return subsetRows.map((subsetRow) => {
|
|
785
|
+
if (subsetRow.children.length > 0) {
|
|
786
|
+
return this.subsetRowsToSubsetFields(subsetRow.children, subsetKey, internal);
|
|
787
|
+
} else if (subsetRow[hasKey][subsetKey]) {
|
|
788
|
+
return subsetRow.prefixes.concat(subsetRow.field).join(".");
|
|
789
|
+
} else {
|
|
790
|
+
return null;
|
|
791
|
+
}
|
|
792
|
+
}).filter(nonNullable).flat();
|
|
793
|
+
}
|
|
794
|
+
async createProp(prop, at) {
|
|
795
|
+
if (!at) {
|
|
796
|
+
this.props.push(prop);
|
|
797
|
+
} else {
|
|
798
|
+
this.props.splice(at, 0, prop);
|
|
799
|
+
}
|
|
800
|
+
await this.save();
|
|
801
|
+
}
|
|
802
|
+
analyzeSubsetField(subsetField) {
|
|
803
|
+
const arr = subsetField.split(".");
|
|
804
|
+
let entityId = this.id;
|
|
805
|
+
const result = [];
|
|
806
|
+
for (let i = 0; i < arr.length; i++) {
|
|
807
|
+
const propName = arr[i];
|
|
808
|
+
result.push({
|
|
809
|
+
entityId,
|
|
810
|
+
propName
|
|
811
|
+
});
|
|
812
|
+
const prop = EntityManager.get(entityId).props.find((p) => p.name === propName);
|
|
813
|
+
if (!prop) {
|
|
814
|
+
throw new Error(`${entityId}의 잘못된 서브셋키 ${subsetField}`);
|
|
815
|
+
}
|
|
816
|
+
if (isRelationProp(prop)) {
|
|
817
|
+
entityId = prop.with;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
return result;
|
|
821
|
+
}
|
|
822
|
+
async modifyProp(newProp, at) {
|
|
823
|
+
const oldName = this.props[at].name;
|
|
824
|
+
const entities = [this];
|
|
825
|
+
if (oldName !== newProp.name) {
|
|
826
|
+
const allEntityIds = EntityManager.getAllIds();
|
|
827
|
+
for (const relEntityId of allEntityIds) {
|
|
828
|
+
const relEntity = EntityManager.get(relEntityId);
|
|
829
|
+
const relEntitySubsetKeys = Object.keys(relEntity.subsets);
|
|
830
|
+
for (const subsetKey of relEntitySubsetKeys) {
|
|
831
|
+
const subset = relEntity.subsets[subsetKey];
|
|
832
|
+
const modifiedSubsetFields = subset.map((subsetField) => {
|
|
833
|
+
const analyzed = relEntity.analyzeSubsetField(subsetField);
|
|
834
|
+
const modified = analyzed.map((a) => a.propName === oldName && a.entityId === this.id ? {
|
|
835
|
+
...a,
|
|
836
|
+
propName: newProp.name
|
|
837
|
+
} : a);
|
|
838
|
+
return modified.map((a) => a.propName).join(".");
|
|
839
|
+
});
|
|
840
|
+
if (subset.join(",") !== modifiedSubsetFields.join(",")) {
|
|
841
|
+
relEntity.subsets[subsetKey] = modifiedSubsetFields;
|
|
842
|
+
entities.push(relEntity);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
this.props[at] = newProp;
|
|
848
|
+
await Promise.all(entities.map(async (entity) => entity.save()));
|
|
849
|
+
}
|
|
850
|
+
async delProp(at) {
|
|
851
|
+
const oldName = this.props[at].name;
|
|
852
|
+
const entities = [this];
|
|
853
|
+
const allEntityIds = EntityManager.getAllIds();
|
|
854
|
+
for (const relEntityId of allEntityIds) {
|
|
855
|
+
const relEntity = EntityManager.get(relEntityId);
|
|
856
|
+
const relEntitySubsetKeys = Object.keys(relEntity.subsets);
|
|
857
|
+
for (const subsetKey of relEntitySubsetKeys) {
|
|
858
|
+
const subset = relEntity.subsets[subsetKey];
|
|
859
|
+
const modifiedSubsetFields = subset.map((subsetField) => {
|
|
860
|
+
const analyzed = relEntity.analyzeSubsetField(subsetField);
|
|
861
|
+
if (analyzed.find((a) => a.propName === oldName && a.entityId === this.id)) {
|
|
862
|
+
return null;
|
|
863
|
+
} else {
|
|
864
|
+
return subsetField;
|
|
865
|
+
}
|
|
866
|
+
}).filter(nonNullable);
|
|
867
|
+
if (subset.join(",") !== modifiedSubsetFields.join(",")) {
|
|
868
|
+
relEntity.subsets[subsetKey] = modifiedSubsetFields;
|
|
869
|
+
entities.push(relEntity);
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
for (const index of EntityManager.get(this.id).indexes) {
|
|
874
|
+
index.columns = index.columns.filter((col) => col.name !== oldName);
|
|
875
|
+
}
|
|
876
|
+
this.props.splice(at, 1);
|
|
877
|
+
await Promise.all(entities.map(async (entity) => entity.save()));
|
|
878
|
+
}
|
|
879
|
+
getEntityIdFromSubsetField(subsetField) {
|
|
880
|
+
if (!subsetField.includes(".")) {
|
|
881
|
+
return this.id;
|
|
882
|
+
}
|
|
883
|
+
const arr = subsetField.split(".").slice(0, -1);
|
|
884
|
+
const lastEntityId = arr.reduce((entityId, field) => {
|
|
885
|
+
const relProp = EntityManager.get(entityId).props.find((p) => p.name === field);
|
|
886
|
+
if (!relProp || relProp.type !== "relation") {
|
|
887
|
+
console.debug({
|
|
888
|
+
arr,
|
|
889
|
+
thisId: this.id,
|
|
890
|
+
entityId,
|
|
891
|
+
field
|
|
892
|
+
});
|
|
893
|
+
throw new Error(`잘못된 서브셋키 ${subsetField}`);
|
|
894
|
+
}
|
|
895
|
+
return relProp.with;
|
|
896
|
+
}, this.id);
|
|
897
|
+
return lastEntityId;
|
|
898
|
+
}
|
|
899
|
+
async moveProp(at, to) {
|
|
900
|
+
const prop = this.props[at];
|
|
901
|
+
const newProps = [...this.props];
|
|
902
|
+
newProps.splice(to, 0, prop);
|
|
903
|
+
newProps.splice(at < to ? at : at + 1, 1);
|
|
904
|
+
this.props = newProps;
|
|
905
|
+
await this.save();
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* 필드명을 "테이블명.필드명" 형식으로 변환
|
|
909
|
+
*/
|
|
910
|
+
getFullFieldName(field) {
|
|
911
|
+
if (field.includes(".")) {
|
|
912
|
+
return field;
|
|
913
|
+
}
|
|
914
|
+
return `${this.table}.${field}`;
|
|
915
|
+
}
|
|
916
|
+
/**
|
|
917
|
+
* 엔티티의 PK 타입을 반환합니다.
|
|
918
|
+
* id 필드의 타입을 기준으로 "integer" | "string" | "uuid"를 반환합니다.
|
|
919
|
+
*/
|
|
920
|
+
getPkType() {
|
|
921
|
+
const idProp = this.propsDict.id;
|
|
922
|
+
if (!idProp) {
|
|
923
|
+
throw new Error(`Entity ${this.id}에 id 필드가 없습니다`);
|
|
924
|
+
}
|
|
925
|
+
if (idProp.type === "string" || idProp.type === "uuid") {
|
|
926
|
+
return idProp.type;
|
|
927
|
+
}
|
|
928
|
+
return "integer";
|
|
929
|
+
}
|
|
930
|
+
/**
|
|
931
|
+
* 엔티티의 PK prop을 반환합니다.
|
|
932
|
+
* length 등 세부 정보에 접근할 때 사용합니다.
|
|
933
|
+
*/
|
|
934
|
+
getPkProp() {
|
|
935
|
+
const idProp = this.propsDict.id;
|
|
936
|
+
if (!idProp) {
|
|
937
|
+
throw new Error(`Entity ${this.id}에 id 필드가 없습니다`);
|
|
938
|
+
}
|
|
939
|
+
return idProp;
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* 엔티티의 PK 배열 타입을 반환합니다.
|
|
943
|
+
* LoaderQuery의 fromIds 타입으로 사용됩니다.
|
|
944
|
+
*/
|
|
945
|
+
getPkArrayType() {
|
|
946
|
+
const pkType = this.getPkType();
|
|
947
|
+
return pkType === "integer" ? "number[]" : "string[]";
|
|
948
|
+
}
|
|
949
|
+
};
|
|
950
|
+
}));
|
|
1091
951
|
|
|
1092
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lbnRpdHkvZW50aXR5LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSBcImFzc2VydFwiO1xuaW1wb3J0IHsgd3JpdGVGaWxlIH0gZnJvbSBcImZzL3Byb21pc2VzXCI7XG5pbXBvcnQgaW5mbGVjdGlvbiBmcm9tIFwiaW5mbGVjdGlvblwiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCB7IGdyb3VwLCB1bmlxdWUgfSBmcm9tIFwicmFkYXNoaVwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB7IFNvbmFtdSB9IGZyb20gXCIuLi9hcGkvc29uYW11XCI7XG5pbXBvcnQge1xuICB0eXBlIENvbmUsXG4gIHR5cGUgRW50aXR5SW5kZXgsXG4gIHR5cGUgRW50aXR5SnNvbixcbiAgdHlwZSBFbnRpdHlQcm9wLFxuICB0eXBlIEVudGl0eVByb3BOb2RlLFxuICB0eXBlIEVudGl0eVN1YnNldFJvdyxcbiAgZ2V0RW51bURlZlZhbHVlcyxcbiAgZ2V0U3Vic2V0RmllbGRzLFxuICBpc0JlbG9uZ3NUb09uZVJlbGF0aW9uUHJvcCxcbiAgaXNFbnVtUHJvcCxcbiAgaXNIYXNNYW55UmVsYXRpb25Qcm9wLFxuICBpc0ludGVybmFsU3Vic2V0RmllbGQsXG4gIGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcCxcbiAgaXNPbmVUb09uZVJlbGF0aW9uUHJvcCxcbiAgaXNSZWxhdGlvblByb3AsXG4gIGlzVmlydHVhbENvZGVQcm9wLFxuICBpc1ZpcnR1YWxQcm9wLFxuICBub3JtYWxpemVTdWJzZXRGaWVsZCxcbiAgdHlwZSBSZWxhdGlvblByb3AsXG4gIHR5cGUgU3Vic2V0RmllbGQsXG4gIHR5cGUgU3Vic2V0UXVlcnksXG59IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgaW1wb3J0TWVtYmVycyB9IGZyb20gXCIuLi91dGlscy9lc20tdXRpbHNcIjtcbmltcG9ydCB7IGZvcm1hdENvZGUgfSBmcm9tIFwiLi4vdXRpbHMvZm9ybWF0dGVyXCI7XG5pbXBvcnQgeyBleGlzdHMgfSBmcm9tIFwiLi4vdXRpbHMvZnMtdXRpbHNcIjtcbmltcG9ydCB7IHJ1bnRpbWVQYXRoIH0gZnJvbSBcIi4uL3V0aWxzL3BhdGgtdXRpbHNcIjtcbmltcG9ydCB7IGFzc2VydERlZmluZWQsIG5vbk51bGxhYmxlIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5pbXBvcnQgeyBFbnRpdHlNYW5hZ2VyIH0gZnJvbSBcIi4vZW50aXR5LW1hbmFnZXJcIjtcblxuZXhwb3J0IGNsYXNzIEVudGl0eSB7XG4gIGlkOiBzdHJpbmc7XG4gIHBhcmVudElkPzogc3RyaW5nO1xuICB0YWJsZTogc3RyaW5nO1xuICB0aXRsZTogc3RyaW5nO1xuICBjb25lPzogQ29uZTtcbiAgbmFtZXM6IHtcbiAgICBwYXJlbnRGczogc3RyaW5nO1xuICAgIGZzOiBzdHJpbmc7XG4gICAgbW9kdWxlOiBzdHJpbmc7XG4gIH07XG4gIHByb3BzOiBFbnRpdHlQcm9wW107XG4gIHByb3BzRGljdDoge1xuICAgIFtrZXk6IHN0cmluZ106IEVudGl0eVByb3A7XG4gIH07XG4gIHJlbGF0aW9uczoge1xuICAgIFtrZXk6IHN0cmluZ106IFJlbGF0aW9uUHJvcDtcbiAgfTtcbiAgaW5kZXhlczogRW50aXR5SW5kZXhbXTtcbiAgc3Vic2V0czoge1xuICAgIFtrZXk6IHN0cmluZ106IHN0cmluZ1tdO1xuICB9O1xuICBzdWJzZXRzSW50ZXJuYWw6IHtcbiAgICBba2V5OiBzdHJpbmddOiBzdHJpbmdbXTtcbiAgfTtcbiAgdHlwZXM6IHtcbiAgICBbbmFtZTogc3RyaW5nXTogei5ab2RUeXBlQW55O1xuICB9ID0ge307XG4gIGVudW1zOiB7XG4gICAgW2VudW1JZDogc3RyaW5nXTogei5ab2RFbnVtPFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHN0cmluZz4+PjtcbiAgfSA9IHt9O1xuICBlbnVtTGFiZWxzOiB7XG4gICAgW2VudW1JZDogc3RyaW5nXToge1xuICAgICAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xuICAgIH07XG4gIH0gPSB7fTtcbiAgZW51bUNvbmVzOiB7XG4gICAgW2VudW1JZDogc3RyaW5nXTogQ29uZTtcbiAgfSA9IHt9O1xuICBzdWJzZXRDb25lczoge1xuICAgIFtzdWJzZXRLZXk6IHN0cmluZ106IENvbmU7XG4gIH0gPSB7fTtcblxuICBjb25zdHJ1Y3Rvcih7IGlkLCBwYXJlbnRJZCwgdGFibGUsIHRpdGxlLCBjb25lLCBwcm9wcywgaW5kZXhlcywgc3Vic2V0cywgZW51bXMgfTogRW50aXR5SnNvbikge1xuICAgIC8vIGlkXG4gICAgdGhpcy5pZCA9IGlkO1xuICAgIHRoaXMucGFyZW50SWQgPSBwYXJlbnRJZDtcbiAgICB0aGlzLnRpdGxlID0gdGl0bGUgPz8gdGhpcy5pZDtcbiAgICB0aGlzLnRhYmxlID0gdGFibGUgPz8gaW5mbGVjdGlvbi51bmRlcnNjb3JlKGluZmxlY3Rpb24ucGx1cmFsaXplKGlkKSk7XG4gICAgdGhpcy5jb25lID0gY29uZTtcblxuICAgIC8vIHByb3BzXG4gICAgaWYgKHByb3BzKSB7XG4gICAgICB0aGlzLnByb3BzID0gcHJvcHMubWFwKChwcm9wKSA9PiB7XG4gICAgICAgIGlmIChpc0VudW1Qcm9wKHByb3ApKSB7XG4gICAgICAgICAgaWYgKHByb3AuaWQuaW5jbHVkZXMoXCIkTW9kZWxcIikpIHtcbiAgICAgICAgICAgIHByb3AuaWQgPSBwcm9wLmlkLnJlcGxhY2UoXCIkTW9kZWxcIiwgaWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvcDtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5wcm9wc0RpY3QgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgIHByb3BzLm1hcCgocHJvcCkgPT4ge1xuICAgICAgICAgIHJldHVybiBbcHJvcC5uYW1lLCBwcm9wXTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICAvLyByZWxhdGlvbnNcbiAgICAgIHRoaXMucmVsYXRpb25zID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICBwcm9wcy5maWx0ZXIoKHByb3ApID0+IGlzUmVsYXRpb25Qcm9wKHByb3ApKS5tYXAoKHByb3ApID0+IFtwcm9wLm5hbWUsIHByb3BdKSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHJvcHMgPSBbXTtcbiAgICAgIHRoaXMucHJvcHNEaWN0ID0ge307XG4gICAgICB0aGlzLnJlbGF0aW9ucyA9IHt9O1xuICAgIH1cblxuICAgIC8vIGluZGV4ZXNcbiAgICB0aGlzLmluZGV4ZXMgPSBpbmRleGVzID8/IFtdO1xuXG4gICAgLy8gc3Vic2V0czogU3Vic2V0RGVm7JeQ7IScIFN1YnNldEZpZWxkW13rpbwg7LaU7Lac7ZWY7JesIHN1YnNldHMo7J2867CYKeyZgCBzdWJzZXRzSW50ZXJuYWwoaW50ZXJuYWwp66GcIOu2hOumrFxuICAgIHRoaXMuc3Vic2V0cyA9IHt9O1xuICAgIHRoaXMuc3Vic2V0c0ludGVybmFsID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCBzdWJzZXREZWZdIG9mIE9iamVjdC5lbnRyaWVzKHN1YnNldHMgPz8ge30pKSB7XG4gICAgICBjb25zdCBmaWVsZHMgPSBnZXRTdWJzZXRGaWVsZHMoc3Vic2V0RGVmKTtcbiAgICAgIHRoaXMuc3Vic2V0c1trZXldID0gZmllbGRzLmZpbHRlcigoZikgPT4gIWlzSW50ZXJuYWxTdWJzZXRGaWVsZChmKSkubWFwKG5vcm1hbGl6ZVN1YnNldEZpZWxkKTtcbiAgICAgIHRoaXMuc3Vic2V0c0ludGVybmFsW2tleV0gPSBmaWVsZHMuZmlsdGVyKGlzSW50ZXJuYWxTdWJzZXRGaWVsZCkubWFwKG5vcm1hbGl6ZVN1YnNldEZpZWxkKTtcblxuICAgICAgLy8gY29uZSDstpTstpxcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShzdWJzZXREZWYpICYmIFwiY29uZVwiIGluIHN1YnNldERlZiAmJiBzdWJzZXREZWYuY29uZSkge1xuICAgICAgICB0aGlzLnN1YnNldENvbmVzW2tleV0gPSBzdWJzZXREZWYuY29uZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBlbnVtczogRW51bURlZuyXkOyEnCB2YWx1ZXPsmYAgY29uZeulvCDstpTstpztlZjsl6wg7LKY66asXG4gICAgdGhpcy5lbnVtTGFiZWxzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXMoZW51bXMgPz8ge30pLm1hcCgoW2tleSwgZW51bURlZl0pID0+IHtcbiAgICAgICAgLy8gY29uZSDstpTstpxcbiAgICAgICAgaWYgKFwidmFsdWVzXCIgaW4gZW51bURlZiAmJiBcImNvbmVcIiBpbiBlbnVtRGVmICYmIGVudW1EZWYuY29uZSkge1xuICAgICAgICAgIHRoaXMuZW51bUNvbmVzW2tleV0gPSBlbnVtRGVmLmNvbmUgYXMgQ29uZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW2tleSwgZ2V0RW51bURlZlZhbHVlcyhlbnVtRGVmKV07XG4gICAgICB9KSxcbiAgICApO1xuICAgIHRoaXMuZW51bXMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyh0aGlzLmVudW1MYWJlbHMpLm1hcCgoW2tleSwgZW51bUxhYmVsXSkgPT4ge1xuICAgICAgICByZXR1cm4gW2tleSwgei5lbnVtKE9iamVjdC5rZXlzKGVudW1MYWJlbCkgYXMgdW5rbm93biBhcyByZWFkb25seSBbc3RyaW5nLCAuLi5zdHJpbmdbXV0pXTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICAvLyBuYW1lc1xuICAgIHRoaXMubmFtZXMgPSB7XG4gICAgICBwYXJlbnRGczogaW5mbGVjdGlvbi5kYXNoZXJpemUoaW5mbGVjdGlvbi51bmRlcnNjb3JlKHBhcmVudElkID8/IGlkKSkudG9Mb3dlckNhc2UoKSxcbiAgICAgIGZzOiBpbmZsZWN0aW9uLmRhc2hlcml6ZShpbmZsZWN0aW9uLnVuZGVyc2NvcmUoaWQpKS50b0xvd2VyQ2FzZSgpLFxuICAgICAgbW9kdWxlOiBpZCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOy/vOumrOyaqSDshJzruIzshYsg7ZWE65Oc66W8IOuwmO2ZmO2VqeuLiOuLpCAoc3Vic2V0cyArIHN1YnNldHNJbnRlcm5hbCDtlansuagpXG4gICAqL1xuICBnZXRTdWJzZXRGaWVsZHNGb3JRdWVyeShzdWJzZXRLZXk6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gWy4uLih0aGlzLnN1YnNldHNbc3Vic2V0S2V5XSA/PyBbXSksIC4uLih0aGlzLnN1YnNldHNJbnRlcm5hbFtzdWJzZXRLZXldID8/IFtdKV07XG4gIH1cblxuICAvKipcbiAgICog7KO87Ja07KeEIOydtOumhChzdWJzZXRLZXkp7J2YIHN1YnNldOydhCDsi6TsoJzroZwg6rCA7KC47Jik64qUIFB1cmkg7L2U65OcIOq1rO2YhOyytCBzdHJpbmfsnYQg67CY7ZmY7ZWp64uI64ukLlxuICAgKi9cbiAgZ2V0UHVyaVN1YnNldFF1ZXJ5KHN1YnNldEtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdWJzZXQgPSB0aGlzLmdldFN1YnNldEZpZWxkc0ZvclF1ZXJ5KHN1YnNldEtleSk7XG4gICAgY29uc3Qgc3Vic2V0UXVlcnkgPSB0aGlzLnJlc29sdmVTdWJzZXRRdWVyeShcIlwiLCBzdWJzZXQpO1xuXG4gICAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW107XG5cbiAgICAvLyBmcm9tXG4gICAgbGluZXMucHVzaChgcmV0dXJuIHFiV3JhcHBlcmApO1xuICAgIGxpbmVzLnB1c2goYC5mcm9tKFwiJHt0aGlzLnRhYmxlfVwiKWApO1xuXG4gICAgLy8gam9pblxuICAgIGZvciAoY29uc3Qgam9pbiBvZiBzdWJzZXRRdWVyeS5qb2lucykge1xuICAgICAgLy8gam9pbiDrqZTshJzrk5wg6rKw7KCVOiBpbm5lciDihpIgam9pbiwgb3V0ZXIg4oaSIGxlZnRKb2luXG4gICAgICAvLyBGSyBudWxsYWJsZSDsl6zrtoDripQgbGVmdEpvaW4g7YOA7J6FIOyLnOq3uOuLiOyymOyXkOyEnCDsnpDrj5nsnLzroZwg7YyQ64uo65CoXG4gICAgICBjb25zdCBqb2luTWV0aG9kID0gam9pbi5qb2luID09PSBcImlubmVyXCIgPyBcImpvaW5cIiA6IFwibGVmdEpvaW5cIjtcblxuICAgICAgaWYgKFwiY3VzdG9tXCIgaW4gam9pbikge1xuICAgICAgICAvLyBjdXN0b20gam9pbiBjbGF1c2XripQgcmF3IOyCrOyaqVxuICAgICAgICBsaW5lcy5wdXNoKFxuICAgICAgICAgIGAuJHtqb2luTWV0aG9kfSh7ICR7am9pbi5hc306IFwiJHtqb2luLnRhYmxlfVwiIH0sIHFiV3JhcHBlci5rbmV4LnJhdyhcXGAke2pvaW4uY3VzdG9tfVxcYCkpYCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpbmVzLnB1c2goYC4ke2pvaW5NZXRob2R9KHsgJHtqb2luLmFzfTogXCIke2pvaW4udGFibGV9XCIgfSwgXCIke2pvaW4uZnJvbX1cIiwgXCIke2pvaW4udG99XCIpYCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2VsZWN0IC0g7J6F7LK07KCBIOq1rOyhsOuhnCDsg53shLFcbiAgICBjb25zdCBzZWxlY3RPYmogPSB0aGlzLmJ1aWxkTmVzdGVkU2VsZWN0T2JqZWN0KHN1YnNldFF1ZXJ5LnNlbGVjdCk7XG4gICAgbGluZXMucHVzaChgLnNlbGVjdCgke3RoaXMuc3RyaW5naWZ5TmVzdGVkU2VsZWN0T2JqZWN0KHNlbGVjdE9iail9KTtgKTtcblxuICAgIHJldHVybiBsaW5lcy5qb2luKFwiXFxuXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqICouZW50aXR5Lmpzb27snZggc3Vic2V07JeQIOuTpOyWtOyeiOuKlCDtlYTrk5wg67Cw7Je07J2EIOuwm+yVhOyEnCxcbiAgICogUHVyaeydmCBTZWxlY3RPYmplY3Qg7YOA7J6F7Jy866GcIOuzgO2ZmO2VqeuLiOuLpC5cbiAgICpcbiAgICog7JiIOiBbXCJ1c2Vycy5pZFwiLCBcInBhcmVudC5pZFwiLCBcInBhcmVudC5uYW1lXCJdXG4gICAqICAg4oaSIHsgaWQ6IFwidXNlcnMuaWRcIiwgcGFyZW50OiB7IGlkOiBcInBhcmVudC5pZFwiLCBuYW1lOiBcInBhcmVudC5uYW1lXCIgfSB9XG4gICAqXG4gICAqIOyWuOuNlOuwlOqwgCDslYTri4wg7KSR7LKpIOqwneyytOuhnCDrs4DtmZjtlajsl5Ag7Jyg7J2Y7ZWY7IS47JqULlxuICAgKiDsnbTroIfqsowg7KSR7LKpIOqwneyytOuhnCDrs4DtmZjtlZjsl6wgc2VsZWN07JeQIOuEmOqyqOyjvOuptCBQYXJzZVNlbGVjdE9iamVjdCDtg4DsnoXsnbQgam9pbuuQnCDqsJ3ssrTsnZgg7YOA7J6F7J2EIOyemCDsnqHslYTspIQg7IiYIOyeiOyKteuLiOuLpC5cbiAgICog7KaJLCBlbmhhbmNlcuyXkOyEnCByb3frpbwg67Cb7JWY7J2EIOuVjCBoeWRyYXRl65CcIOqwneyytCDsnpDssrTsnZggbnVsbGl0eeyZgCDqt7gg7JWI7Kq9IO2VhOuTnOydmCBudWxsaXR56rCAIGZrIG51bGxhYmxlIOyXrOu2gOyXkCDrlLDrnbwg7J6YIOy2lOuhoOuQqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgYnVpbGROZXN0ZWRTZWxlY3RPYmplY3QoXG4gICAgc2VsZWN0SXRlbXM6IHN0cmluZ1tdLFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTog67CY7ZmYIOyYpOu4jOygne2KuOydmCDqsJLsnYAgc3RyaW5n7J28IOyImOuPhCDsnojqs6Ag65iQ64uk66W4IOyYpOu4jOygne2KuOydvCDsiJjrj4Qg7J6I64qU642wLCDsnbTrpbwg7J6s6reAIO2DgOyeheycvOuhnCDrgpjtg4Drgrwg7IiYIOyXhuyWtCBhbnnroZwg7LKY66as7ZWp64uI64ukLlxuICApOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgICBjb25zdCByZXN1bHQ6IFJldHVyblR5cGU8dHlwZW9mIHRoaXMuYnVpbGROZXN0ZWRTZWxlY3RPYmplY3Q+ID0ge307XG5cbiAgICBmb3IgKGNvbnN0IHNlbGVjdEl0ZW0gb2Ygc2VsZWN0SXRlbXMpIHtcbiAgICAgIC8vIFwidXNlcnMuaWRcIiDrmJDripQgXCJ1c2Vycy5pZCBhcyB1c2VyX19pZFwiIO2Yle2DnCDtjIzsi7FcbiAgICAgIGNvbnN0IG1hdGNoID0gc2VsZWN0SXRlbS5tYXRjaCgvXiguKz8pKD86IGFzICguKykpPyQvKTtcbiAgICAgIGlmICghbWF0Y2gpIGNvbnRpbnVlO1xuXG4gICAgICBjb25zdCBbLCBjb2x1bW4sIGFsaWFzXSA9IG1hdGNoO1xuICAgICAgY29uc3QgY29sdW1uVmFsdWUgPSBgXCIke2NvbHVtbi50cmltKCl9XCJgO1xuXG4gICAgICBpZiAoIWFsaWFzIHx8ICFhbGlhcy5pbmNsdWRlcyhcIl9fXCIpKSB7XG4gICAgICAgIC8vIGFsaWFz6rCAIOyXhuqxsOuCmCBfX+ulvCDtj6ztlajtlZjsp4Ag7JWK7Jy866m0IOy1nOyDgeychCDtlYTrk5xcbiAgICAgICAgY29uc3Qga2V5ID0gYWxpYXMgPz8gYXNzZXJ0RGVmaW5lZChjb2x1bW4uc3BsaXQoXCIuXCIpLnBvcCgpKTtcbiAgICAgICAgcmVzdWx0W2tleV0gPSBjb2x1bW5WYWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGFsaWFz6rCAIF9f66W8IO2PrO2VqO2VmOuptCDsnoXssrQg6rWs7KGw66GcIOq3uOujue2ZlFxuICAgICAgICBjb25zdCBwYXJ0cyA9IGFsaWFzLnNwbGl0KFwiX19cIik7XG4gICAgICAgIGxldCBjdXJyZW50ID0gcmVzdWx0O1xuXG4gICAgICAgIC8vIOuniOyngOuniSDtjIztirgg7KCE6rmM7KeAIOykkeyyqSDqsJ3ssrQg7IOd7ISxXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICAgICAgY29uc3QgcGFydCA9IHBhcnRzW2ldO1xuICAgICAgICAgIGlmIChwYXJ0IGluIGN1cnJlbnQpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY3VycmVudFtwYXJ0XSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAvLyDsnoXroKXsnbQgW1widXNlclwiLCBcInVzZXJfX2lkXCJdIOqwmeydgCDqsr3smrAhXG4gICAgICAgICAgICAgIC8vIOyVoOy0iOyXkCDrp5Drj4Qg7JWIIOuQmOyngOunjCDslYjsoITtlZjqsowg7JiI7Jm466W8IOuNmOynkeuLiOuLpC5cbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICAgIGBDb25mbGljdCBkZXRlY3RlZCBpbiBzZWxlY3QgaXRlbXM6IHBhcmVudCBwYXRoIFwiJHtwYXJ0cy5zbGljZSgwLCBpICsgMSkuam9pbihcIl9fXCIpfVwiIGlzIGFscmVhZHkgc2V0IGFzIGEgZmllbGQsIGNhbm5vdCBuZXN0IFwiJHthbGlhc31cIiB1bmRlciBpdC5gLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjdXJyZW50W3BhcnRdID0ge307XG4gICAgICAgICAgfVxuICAgICAgICAgIGN1cnJlbnQgPSBjdXJyZW50W3BhcnRdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8g66eI7KeA66eJIO2MjO2KuOyXkCDqsJIg7ISk7KCVXG4gICAgICAgIGNvbnN0IGxhc3RQYXJ0ID0gcGFydHNbcGFydHMubGVuZ3RoIC0gMV07XG4gICAgICAgIGN1cnJlbnRbbGFzdFBhcnRdID0gY29sdW1uVmFsdWU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBKU09OLnN0cmluZ2lmeeyZgCDsnKDsgqztlZwg7J287J2EIO2VqeuLiOuLpC5cbiAgICog64uk66eMIOyjvOyWtOynhCDqsJ3ssrTrpbwgSlNPTuydtCDslYTri4wgVHlwZVNjcmlwdCDqsJ3ssrQg66as7YSw65+0IOyKpO2KuOungeycvOuhnCDrp4zrk6TslrTspI3ri4jri6QuXG4gICAqIGtleeyXkCDrlLDsmLTtkZzqsIAg7JeG7Ja07JqULlxuICAgKiDstpzroKUg7JiI7IucOlxuICAgKiBgYGB0eXBlc2NyaXB0XG4gICAqIHtcbiAgICogICBpZDogXCJ1c2Vycy5pZFwiLFxuICAgKiAgIHBhcmVudDoge1xuICAgKiAgICAgaWQ6IFwicGFyZW50LmlkXCIsXG4gICAqICAgICBuYW1lOiBcInBhcmVudC5uYW1lXCIsXG4gICAqICAgfSxcbiAgICogfVxuICAgKiBgYGBcbiAgICogQHBhcmFtIG9iaiDrs4DtmZjtlaAg6rCd7LK0XG4gICAqIEBwYXJhbSBpbmRlbnQg65Ok7Jes7JOw6riwIOugiOuyqFxuICAgKiBAcGFyYW0gd2l0aEJyYWNlcyB0cnVl66m0IOykkeq0hO2YuCDtj6ztlagsIGZhbHNl66m0IOuCtOyaqeunjCDrsJjtmZhcbiAgICovXG4gIHByaXZhdGUgc3RyaW5naWZ5TmVzdGVkU2VsZWN0T2JqZWN0KFxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9FeHBsaWNpdEFueTog7KSR7LKpIOyYpOu4jOygne2KuOydmCDqsJLsnYAgc3RyaW5n7J28IOyImOuPhCDsnojqs6Ag65iQ64uk66W4IOyYpOu4jOygne2KuOydvCDsiJjrj4Qg7J6I64qU642wLCDsnbTrpbwg7J6s6reAIO2DgOyeheycvOuhnCDrgpjtg4Drgrwg7IiYIOyXhuyWtCBhbnnroZwg7LKY66as7ZWp64uI64ukLlxuICAgIG9iajogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICBpbmRlbnQ6IG51bWJlciA9IDAsXG4gICAgd2l0aEJyYWNlczogYm9vbGVhbiA9IHRydWUsXG4gICk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3BhY2VzID0gXCIgIFwiLnJlcGVhdChpbmRlbnQpO1xuICAgIGNvbnN0IGlubmVyU3BhY2VzID0gXCIgIFwiLnJlcGVhdChpbmRlbnQgKyAxKTtcblxuICAgIGNvbnN0IGVudHJpZXMgPSBPYmplY3QuZW50cmllcyhvYmopO1xuICAgIGlmIChlbnRyaWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIHdpdGhCcmFjZXMgPyBcInt9XCIgOiBcIlwiO1xuXG4gICAgY29uc3QgbGluZXMgPSBlbnRyaWVzLm1hcCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBpZiAodHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIC8vIOy7rOufvCDqsr3roZwgKOydtOuvuCDrlLDsmLTtkZwg7Y+s7ZWoKVxuICAgICAgICByZXR1cm4gYCR7aW5uZXJTcGFjZXN9JHtrZXl9OiAke3ZhbHVlfSxgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8g7KSR7LKpIOqwneyytCAo7ZWt7IOBIOykkeq0hO2YuCDtj6ztlagpXG4gICAgICAgIHJldHVybiBgJHtpbm5lclNwYWNlc30ke2tleX06ICR7dGhpcy5zdHJpbmdpZnlOZXN0ZWRTZWxlY3RPYmplY3QodmFsdWUsIGluZGVudCArIDEsIHRydWUpfSxgO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgaWYgKHdpdGhCcmFjZXMpIHtcbiAgICAgIHJldHVybiBge1xcbiR7bGluZXMuam9pbihcIlxcblwiKX1cXG4ke3NwYWNlc319YDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8g7KSR6rSE7Zi4IOyXhuydtCDrgrTsmqnrp4wg67CY7ZmYICjslZ7rkqQg6rCc7ZaJIOygnOyZuClcbiAgICAgIHJldHVybiBsaW5lcy5qb2luKFwiXFxuXCIpO1xuICAgIH1cbiAgfVxuXG4gIGdldFB1cmlMb2FkZXJRdWVyeShzdWJzZXRLZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3Qgc3Vic2V0ID0gdGhpcy5nZXRTdWJzZXRGaWVsZHNGb3JRdWVyeShzdWJzZXRLZXkpO1xuICAgIGNvbnN0IHsgbG9hZGVycyB9ID0gdGhpcy5yZXNvbHZlU3Vic2V0UXVlcnkoXCJcIiwgc3Vic2V0KTtcblxuICAgIGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtgW2BdO1xuXG4gICAgLy8g7J6s6reA7KCB7Jy866GcIGxvYWRlciDsg53shLHtlZjripQg7Zes7Y28IO2VqOyImFxuICAgIGNvbnN0IGdlbmVyYXRlTG9hZGVyQ29kZSA9IChsb2FkZXJzOiBTdWJzZXRRdWVyeVtcImxvYWRlcnNcIl0pOiBzdHJpbmdbXSA9PiB7XG4gICAgICBjb25zdCBsb2FkZXJMaW5lczogc3RyaW5nW10gPSBbXTtcblxuICAgICAgZm9yIChjb25zdCBsb2FkZXIgb2YgbG9hZGVycykge1xuICAgICAgICBjb25zdCB7IHRvVGFibGUsIHRvQ29sLCB0aHJvdWdoLCBmcm9tVGFibGUgfSA9IGxvYWRlci5tYW55Sm9pbjtcblxuICAgICAgICAvLyBmcm9tVGFibGXsnZggRW50aXR566W8IOqwgOyguOyZgOyEnCBQSyDtg4DsnoUg7ZmV7J24XG4gICAgICAgIGNvbnN0IGZyb21FbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldEJ5VGFibGUoZnJvbVRhYmxlKTtcbiAgICAgICAgY29uc3QgZnJvbUlkc1R5cGUgPSBmcm9tRW50aXR5LmdldFBrQXJyYXlUeXBlKCk7XG5cbiAgICAgICAgbG9hZGVyTGluZXMucHVzaChcbiAgICAgICAgICBcIntcIixcbiAgICAgICAgICBgYXM6IFwiJHtsb2FkZXIuYXN9XCIsYCxcbiAgICAgICAgICBgcmVmSWQ6IFwiJHtsb2FkZXIubWFueUpvaW4uaWRGaWVsZH1cIixgLFxuICAgICAgICAgIGBxYjogKHFiV3JhcHBlcjogUHVyaVdyYXBwZXI8RGF0YWJhc2VTY2hlbWFFeHRlbmQ+LCBmcm9tSWRzOiBudW1iZXJbXSB8IHN0cmluZ1tdKSA9PiB7YCxcbiAgICAgICAgKTtcblxuICAgICAgICBpZiAodGhyb3VnaCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgLy8gSGFzTWFueVxuICAgICAgICAgIGxvYWRlckxpbmVzLnB1c2goXG4gICAgICAgICAgICAvL1xuICAgICAgICAgICAgXCJyZXR1cm4gcWJXcmFwcGVyXCIsXG4gICAgICAgICAgICBgLmZyb20oXCIke3RvVGFibGV9XCIpYCxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgbG9hZGVyLm9uZUpvaW5zLmZvckVhY2goKGpvaW46IFN1YnNldFF1ZXJ5W1wiam9pbnNcIl1bbnVtYmVyXSkgPT4ge1xuICAgICAgICAgICAgLy8gRksgbnVsbGFibGUg7Jes67aA64qUIGxlZnRKb2luIO2DgOyehSDsi5zqt7jri4jsspjsl5DshJwg7J6Q64+Z7Jy866GcIO2MkOuLqOuQqFxuICAgICAgICAgICAgY29uc3Qgam9pbk1ldGhvZCA9IGpvaW4uam9pbiA9PT0gXCJpbm5lclwiID8gXCJqb2luXCIgOiBcImxlZnRKb2luXCI7XG4gICAgICAgICAgICBpZiAoXCJjdXN0b21cIiBpbiBqb2luKSB7XG4gICAgICAgICAgICAgIC8vIGN1c3RvbSBqb2luIGNsYXVzZeuKlCBjYWxsYmFjayDtmJXtg5zsnZggb24g66mU7ISc65Oc66GcIOyymOumrO2VqeuLiOuLpC5cbiAgICAgICAgICAgICAgbG9hZGVyTGluZXMucHVzaChcbiAgICAgICAgICAgICAgICBgLiR7am9pbk1ldGhvZH0oeyAke2pvaW4uYXN9OiBcIiR7am9pbi50YWJsZX1cIiB9LCAoaikgPT4ge2AsXG4gICAgICAgICAgICAgICAgYGoub24oUHVyaS5yYXdTdHJpbmcoXCIke2pvaW4uY3VzdG9tfVwiKSk7YCxcbiAgICAgICAgICAgICAgICBcIn0pXCIsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgICAgICAgIGAuJHtqb2luTWV0aG9kfSh7ICR7am9pbi5hc306IFwiJHtqb2luLnRhYmxlfVwiIH0sIFwiJHtqb2luLmZyb219XCIsIFwiJHtqb2luLnRvfVwiKWAsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyDsnoXssrTsoIEgc2VsZWN0IOq1rOyhsCDsg53shLEgKHJlZklkIO2PrO2VqClcbiAgICAgICAgICBjb25zdCBzZWxlY3RPYmogPSB0aGlzLmJ1aWxkTmVzdGVkU2VsZWN0T2JqZWN0KGxvYWRlci5zZWxlY3QpO1xuICAgICAgICAgIHNlbGVjdE9iai5yZWZJZCA9IGBcIiR7dG9UYWJsZX0uJHt0b0NvbH1cImA7XG4gICAgICAgICAgbG9hZGVyTGluZXMucHVzaChcbiAgICAgICAgICAgIGAud2hlcmVJbihcIiR7dG9UYWJsZX0uJHt0b0NvbH1cIiwgZnJvbUlkcyBhcyAke2Zyb21JZHNUeXBlfSlgLFxuICAgICAgICAgICAgYC5zZWxlY3QoJHt0aGlzLnN0cmluZ2lmeU5lc3RlZFNlbGVjdE9iamVjdChzZWxlY3RPYmopfSk7YCxcbiAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE1hbnlUb01hbnlcbiAgICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgICAgXCJyZXR1cm4gcWJXcmFwcGVyXCIsXG4gICAgICAgICAgICBgLmZyb20oXCIke3Rocm91Z2gudGFibGV9XCIpYCxcbiAgICAgICAgICAgIGAuam9pbihcIiR7dG9UYWJsZX1cIiwgXCIke3Rocm91Z2gudGFibGV9LiR7dGhyb3VnaC50b0NvbH1cIiwgXCIke3RvVGFibGV9LiR7dG9Db2x9XCIpYCxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgbG9hZGVyLm9uZUpvaW5zLmZvckVhY2goKGpvaW46IFN1YnNldFF1ZXJ5W1wiam9pbnNcIl1bbnVtYmVyXSkgPT4ge1xuICAgICAgICAgICAgLy8gRksgbnVsbGFibGUg7Jes67aA64qUIGxlZnRKb2luIO2DgOyehSDsi5zqt7jri4jsspjsl5DshJwg7J6Q64+Z7Jy866GcIO2MkOuLqOuQqFxuICAgICAgICAgICAgY29uc3Qgam9pbk1ldGhvZCA9IGpvaW4uam9pbiA9PT0gXCJpbm5lclwiID8gXCJqb2luXCIgOiBcImxlZnRKb2luXCI7XG4gICAgICAgICAgICBpZiAoXCJjdXN0b21cIiBpbiBqb2luKSB7XG4gICAgICAgICAgICAgIC8vIGN1c3RvbSBqb2luIGNsYXVzZeuKlCBjYWxsYmFjayDtmJXtg5zsnZggb24g66mU7ISc65Oc66GcIOyymOumrO2VqeuLiOuLpC5cbiAgICAgICAgICAgICAgbG9hZGVyTGluZXMucHVzaChcbiAgICAgICAgICAgICAgICBgLiR7am9pbk1ldGhvZH0oeyAke2pvaW4uYXN9OiBcIiR7am9pbi50YWJsZX1cIiB9LCAoaikgPT4ge2AsXG4gICAgICAgICAgICAgICAgYGoub24oUHVyaS5yYXdTdHJpbmcoXCIke2pvaW4uY3VzdG9tfVwiKSk7YCxcbiAgICAgICAgICAgICAgICBcIn0pXCIsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgICAgICAgIGAuJHtqb2luTWV0aG9kfSh7ICR7am9pbi5hc306IFwiJHtqb2luLnRhYmxlfVwiIH0sIFwiJHtqb2luLmZyb219XCIsIFwiJHtqb2luLnRvfVwiKWAsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyDsnoXssrTsoIEgc2VsZWN0IOq1rOyhsCDsg53shLEgKHJlZklkIO2PrO2VqClcbiAgICAgICAgICBjb25zdCBzZWxlY3RPYmogPSB0aGlzLmJ1aWxkTmVzdGVkU2VsZWN0T2JqZWN0KGxvYWRlci5zZWxlY3QpO1xuICAgICAgICAgIHNlbGVjdE9iai5yZWZJZCA9IGBcIiR7dGhyb3VnaC50YWJsZX0uJHt0aHJvdWdoLmZyb21Db2x9XCJgO1xuICAgICAgICAgIGxvYWRlckxpbmVzLnB1c2goXG4gICAgICAgICAgICBgLndoZXJlSW4oXCIke3Rocm91Z2gudGFibGV9LiR7dGhyb3VnaC5mcm9tQ29sfVwiLCBmcm9tSWRzIGFzICR7ZnJvbUlkc1R5cGV9KWAsXG4gICAgICAgICAgICBgLnNlbGVjdCgke3RoaXMuc3RyaW5naWZ5TmVzdGVkU2VsZWN0T2JqZWN0KHNlbGVjdE9iail9KTtgLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKGB9LGApO1xuXG4gICAgICAgIC8vIOykkeyyqSBsb2FkZXJzIOyymOumrFxuICAgICAgICBpZiAobG9hZGVyLmxvYWRlcnMgJiYgbG9hZGVyLmxvYWRlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIGxvYWRlckxpbmVzLnB1c2goXCJsb2FkZXJzOiBbXCIsIC4uLmdlbmVyYXRlTG9hZGVyQ29kZShsb2FkZXIubG9hZGVycyksIFwiXSxcIik7XG4gICAgICAgIH1cblxuICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFwifSxcIik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBsb2FkZXJMaW5lcztcbiAgICB9O1xuXG4gICAgbGluZXMucHVzaCguLi5nZW5lcmF0ZUxvYWRlckNvZGUobG9hZGVycykpO1xuICAgIGxpbmVzLnB1c2goYF1gKTtcblxuICAgIHJldHVybiBsaW5lcy5qb2luKFwiXFxuXCIpO1xuICB9XG5cbiAgLypcbiAgICBzdWJzZXQgU0VMRUNUL0pPSU4vTE9BREVSIOqysOqzvCDrpqzthLRcbiAgKi9cbiAgZ2V0U3Vic2V0UXVlcnkoc3Vic2V0S2V5OiBzdHJpbmcpOiBTdWJzZXRRdWVyeSB7XG4gICAgY29uc3Qgc3Vic2V0ID0gdGhpcy5nZXRTdWJzZXRGaWVsZHNGb3JRdWVyeShzdWJzZXRLZXkpO1xuXG4gICAgY29uc3QgcmVzdWx0OiBTdWJzZXRRdWVyeSA9IHRoaXMucmVzb2x2ZVN1YnNldFF1ZXJ5KFwiXCIsIHN1YnNldCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qXG4gICAqL1xuICByZXNvbHZlU3Vic2V0UXVlcnkoXG4gICAgcHJlZml4OiBzdHJpbmcsXG4gICAgZmllbGRzOiBzdHJpbmdbXSxcbiAgICBpc0FscmVhZHlPdXRlckpvaW5lZDogYm9vbGVhbiA9IGZhbHNlLFxuICApOiBTdWJzZXRRdWVyeSB7XG4gICAgLy8gcHJlZml4IOy5mO2ZmCAocHJlZml464qUIFRvT25lUmVsYXRpb27snbQg67O17IiY66GcIOu2meydgCDqsr3smrAg66qo65GQIF9f66GcIOuzgOqyveuQqClcbiAgICBwcmVmaXggPSBwcmVmaXgucmVwbGFjZSgvXFwuL2csIFwiX19cIik7XG5cbiAgICAvLyDshJzruIzshYvsnYQgMeuOgeyKpOunjCDrtoTrpqztlZjsl6wg6re466O57ZWRXG4gICAgY29uc3Qgc3Vic2V0R3JvdXAgPSBncm91cChmaWVsZHMsIChmaWVsZCkgPT4ge1xuICAgICAgaWYgKGZpZWxkLmluY2x1ZGVzKFwiLlwiKSkge1xuICAgICAgICBjb25zdCBbcmVsXSA9IGZpZWxkLnNwbGl0KFwiLlwiKTtcbiAgICAgICAgcmV0dXJuIHJlbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gT2JqZWN0LmtleXMoc3Vic2V0R3JvdXApLnJlZHVjZShcbiAgICAgIChyLCBncm91cEtleSkgPT4ge1xuICAgICAgICBjb25zdCBmaWVsZHMgPSBzdWJzZXRHcm91cFtncm91cEtleV07XG4gICAgICAgIGFzc2VydChmaWVsZHMgIT09IHVuZGVmaW5lZCwgXCJmaWVsZHMgaXMgdW5kZWZpbmVkXCIpO1xuXG4gICAgICAgIC8vIO2YhOyerCDthYzsnbTruJQg7ZWE65Oc7IWL7J2AIHNlbGVjdCwgdmlydHVhbOyXkCDstpTqsIDtlZjqs6Ag66as7YS0XG4gICAgICAgIGlmIChncm91cEtleSA9PT0gXCJcIikge1xuICAgICAgICAgIGNvbnN0IHJlYWxGaWVsZHMgPSBmaWVsZHMuZmlsdGVyKChmaWVsZCkgPT4gIWlzVmlydHVhbFByb3AodGhpcy5wcm9wc0RpY3RbZmllbGRdKSk7XG4gICAgICAgICAgLy8gdmlydHVhbFR5cGU6IFwiY29kZVwiICjrmJDripQgdW5kZWZpbmVkKeyduCB2aXJ0dWFsIHByb3Drp4wgci52aXJ0dWFs7JeQIOy2lOqwgFxuICAgICAgICAgIC8vIHZpcnR1YWxUeXBlOiBcInF1ZXJ5XCLsnbgg6rK97JqwIOyCrOyaqeyekOqwgCBhcHBlbmRTZWxlY3TroZwg7KeB7KCRIOy2lOqwgO2VmOuvgOuhnCDsoJzsmbhcbiAgICAgICAgICBjb25zdCB2aXJ0dWFsQ29kZUZpZWxkcyA9IGZpZWxkcy5maWx0ZXIoKGZpZWxkKSA9PlxuICAgICAgICAgICAgaXNWaXJ0dWFsQ29kZVByb3AodGhpcy5wcm9wc0RpY3RbZmllbGRdKSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKHByZWZpeCA9PT0gXCJcIikge1xuICAgICAgICAgICAgLy8g7ZiE7J6sIO2FjOydtOu4lOyduCDqsr3smrBcbiAgICAgICAgICAgIHIuc2VsZWN0ID0gci5zZWxlY3QuY29uY2F0KHJlYWxGaWVsZHMubWFwKChmaWVsZCkgPT4gdGhpcy5nZXRGdWxsRmllbGROYW1lKGZpZWxkKSkpO1xuICAgICAgICAgICAgci52aXJ0dWFsID0gci52aXJ0dWFsLmNvbmNhdCh2aXJ0dWFsQ29kZUZpZWxkcyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIOuEmOyWtOyYqCDthYzsnbTruJTsnbgg6rK97JqwXG4gICAgICAgICAgICByLnNlbGVjdCA9IHIuc2VsZWN0LmNvbmNhdChcbiAgICAgICAgICAgICAgcmVhbEZpZWxkcy5tYXAoKGZpZWxkKSA9PiBgJHtwcmVmaXh9LiR7ZmllbGR9IGFzICR7cHJlZml4fV9fJHtmaWVsZH1gKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHI7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZWxhdGlvbiA9IHRoaXMucmVsYXRpb25zW2dyb3VwS2V5XTtcbiAgICAgICAgaWYgKHJlbGF0aW9uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYOyhtOyerO2VmOyngCDslYrripQgcmVsYXRpb24g7LC47KGwICR7Z3JvdXBLZXl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcmVsRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocmVsYXRpb24ud2l0aCk7XG5cbiAgICAgICAgaWYgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocmVsYXRpb24pIHx8IGlzQmVsb25nc1RvT25lUmVsYXRpb25Qcm9wKHJlbGF0aW9uKSkge1xuICAgICAgICAgIC8vIC1PbmUgUmVsYXRpb246IEpPSU4g7Jy866GcIOyymOumrFxuICAgICAgICAgIGNvbnN0IHJlbEZpZWxkcyA9IGZpZWxkcy5tYXAoKGZpZWxkKSA9PiBmaWVsZC5zcGxpdChcIi5cIikuc2xpY2UoMSkuam9pbihcIi5cIikpO1xuXG4gICAgICAgICAgLy8gLU9uZSBSZWxhdGlvbuyXkOyEnCBpZCDtlYTrk5zrp4wg7LC47KGw7ZWY64qUIOqyveyasCDrprTroIjsnbTshZgg64SY6riw7KeAIOyViuqzoCDrpqzthLRcbiAgICAgICAgICBpZiAocmVsRmllbGRzLmxlbmd0aCA9PT0gMSAmJiByZWxGaWVsZHNbMF0gPT09IFwiaWRcIikge1xuICAgICAgICAgICAgaWYgKHByZWZpeCA9PT0gXCJcIikge1xuICAgICAgICAgICAgICByLnNlbGVjdCA9IHIuc2VsZWN0LmNvbmNhdChgJHt0aGlzLnRhYmxlfS4ke2dyb3VwS2V5fV9pZGApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgci5zZWxlY3QgPSByLnNlbGVjdC5jb25jYXQoYCR7cHJlZml4fS4ke2dyb3VwS2V5fV9pZCBhcyAke3ByZWZpeH1fXyR7Z3JvdXBLZXl9X2lkYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gcjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBpbm5lck9yT3V0ZXJcbiAgICAgICAgICBjb25zdCBpbm5lck9yT3V0ZXIgPSAoKCkgPT4ge1xuICAgICAgICAgICAgaWYgKGlzQWxyZWFkeU91dGVySm9pbmVkKSB7XG4gICAgICAgICAgICAgIHJldHVybiBcIm91dGVyXCI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc09uZVRvT25lUmVsYXRpb25Qcm9wKHJlbGF0aW9uKSkge1xuICAgICAgICAgICAgICBpZiAocmVsYXRpb24uaGFzSm9pbkNvbHVtbiA9PT0gdHJ1ZSAmJiAocmVsYXRpb24ubnVsbGFibGUgPz8gZmFsc2UpID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBcImlubmVyXCI7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwib3V0ZXJcIjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKHJlbGF0aW9uLm51bGxhYmxlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwib3V0ZXJcIjtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJpbm5lclwiO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkoKTtcbiAgICAgICAgICBjb25zdCByZWxTdWJzZXRRdWVyeSA9IHJlbEVudGl0eS5yZXNvbHZlU3Vic2V0UXVlcnkoXG4gICAgICAgICAgICBgJHtwcmVmaXggIT09IFwiXCIgPyBgJHtwcmVmaXh9LmAgOiBcIlwifSR7Z3JvdXBLZXl9YCxcbiAgICAgICAgICAgIHJlbEZpZWxkcyxcbiAgICAgICAgICAgIGlubmVyT3JPdXRlciA9PT0gXCJvdXRlclwiLFxuICAgICAgICAgICk7XG4gICAgICAgICAgci5zZWxlY3QgPSByLnNlbGVjdC5jb25jYXQocmVsU3Vic2V0UXVlcnkuc2VsZWN0KTtcbiAgICAgICAgICByLnZpcnR1YWwgPSByLnZpcnR1YWwuY29uY2F0KHJlbFN1YnNldFF1ZXJ5LnZpcnR1YWwpO1xuXG4gICAgICAgICAgY29uc3Qgam9pbkFzID0gcHJlZml4ID09PSBcIlwiID8gZ3JvdXBLZXkgOiBgJHtwcmVmaXh9X18ke2dyb3VwS2V5fWA7XG4gICAgICAgICAgY29uc3QgZnJvbVRhYmxlID0gcHJlZml4ID09PSBcIlwiID8gdGhpcy50YWJsZSA6IHByZWZpeDtcblxuICAgICAgICAgIGxldCBqb2luQ2xhdXNlOlxuICAgICAgICAgICAgfCB7XG4gICAgICAgICAgICAgICAgZnJvbTogc3RyaW5nO1xuICAgICAgICAgICAgICAgIHRvOiBzdHJpbmc7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHwge1xuICAgICAgICAgICAgICAgIGN1c3RvbTogc3RyaW5nO1xuICAgICAgICAgICAgICB9O1xuICAgICAgICAgIGlmIChyZWxhdGlvbi5jdXN0b21Kb2luQ2xhdXNlKSB7XG4gICAgICAgICAgICBqb2luQ2xhdXNlID0ge1xuICAgICAgICAgICAgICBjdXN0b206IHJlbGF0aW9uLmN1c3RvbUpvaW5DbGF1c2UsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsZXQgZnJvbTogc3RyaW5nLCB0bzogc3RyaW5nO1xuICAgICAgICAgICAgaWYgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocmVsYXRpb24pKSB7XG4gICAgICAgICAgICAgIGlmIChyZWxhdGlvbi5oYXNKb2luQ29sdW1uKSB7XG4gICAgICAgICAgICAgICAgZnJvbSA9IGAke2Zyb21UYWJsZX0uJHtyZWxhdGlvbi5uYW1lfV9pZGA7XG4gICAgICAgICAgICAgICAgdG8gPSBgJHtqb2luQXN9LmlkYDtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBmcm9tID0gYCR7ZnJvbVRhYmxlfS5pZGA7XG4gICAgICAgICAgICAgICAgdG8gPSBgJHtqb2luQXN9LiR7aW5mbGVjdGlvbi51bmRlcnNjb3JlKHRoaXMubmFtZXMuZnMucmVwbGFjZSgvLS9nLCBcIl9cIikpfV9pZGA7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGZyb20gPSBgJHtmcm9tVGFibGV9LiR7cmVsYXRpb24ubmFtZX1faWRgO1xuICAgICAgICAgICAgICB0byA9IGAke2pvaW5Bc30uaWRgO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgam9pbkNsYXVzZSA9IHtcbiAgICAgICAgICAgICAgZnJvbSxcbiAgICAgICAgICAgICAgdG8sXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHIuam9pbnMucHVzaCh7XG4gICAgICAgICAgICBhczogam9pbkFzLFxuICAgICAgICAgICAgam9pbjogaW5uZXJPck91dGVyLFxuICAgICAgICAgICAgdGFibGU6IHJlbEVudGl0eS50YWJsZSxcbiAgICAgICAgICAgIC4uLmpvaW5DbGF1c2UsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyBCZWxvbmdzVG9PbmUg67CR7JeQIEhhc01hbnnqsIAg67aZ7J2AIOqyveyasFxuICAgICAgICAgIGlmIChyZWxTdWJzZXRRdWVyeS5sb2FkZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbnZlcnRlZExvYWRlcnMgPSByZWxTdWJzZXRRdWVyeS5sb2FkZXJzLm1hcCgobG9hZGVyKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IG5ld0FzID0gW2dyb3VwS2V5LCBsb2FkZXIuYXNdLmpvaW4oXCJfX1wiKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICBhczogbmV3QXMsXG4gICAgICAgICAgICAgICAgdGFibGU6IGxvYWRlci50YWJsZSxcbiAgICAgICAgICAgICAgICBtYW55Sm9pbjogbG9hZGVyLm1hbnlKb2luLFxuICAgICAgICAgICAgICAgIG9uZUpvaW5zOiBsb2FkZXIub25lSm9pbnMsXG4gICAgICAgICAgICAgICAgc2VsZWN0OiBsb2FkZXIuc2VsZWN0LFxuICAgICAgICAgICAgICAgIGxvYWRlcnM6IGxvYWRlci5sb2FkZXJzLFxuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIHIubG9hZGVycyA9IFsuLi5yLmxvYWRlcnMsIC4uLmNvbnZlcnRlZExvYWRlcnNdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHIuam9pbnMgPSByLmpvaW5zLmNvbmNhdChyZWxTdWJzZXRRdWVyeS5qb2lucyk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNIYXNNYW55UmVsYXRpb25Qcm9wKHJlbGF0aW9uKSB8fCBpc01hbnlUb01hbnlSZWxhdGlvblByb3AocmVsYXRpb24pKSB7XG4gICAgICAgICAgLy8gLU1hbnkgUmVsYXRpb246IExvYWRlciDroZwg7LKY66asXG4gICAgICAgICAgY29uc3QgcmVsRmllbGRzID0gZmllbGRzLm1hcCgoZmllbGQpID0+IGZpZWxkLnNwbGl0KFwiLlwiKS5zbGljZSgxKS5qb2luKFwiLlwiKSk7XG4gICAgICAgICAgY29uc3QgcmVsU3Vic2V0UXVlcnkgPSByZWxFbnRpdHkucmVzb2x2ZVN1YnNldFF1ZXJ5KFwiXCIsIHJlbEZpZWxkcyk7XG5cbiAgICAgICAgICBsZXQgbWFueUpvaW46IFN1YnNldFF1ZXJ5W1wibG9hZGVyc1wiXVtudW1iZXJdW1wibWFueUpvaW5cIl07XG4gICAgICAgICAgaWYgKGlzSGFzTWFueVJlbGF0aW9uUHJvcChyZWxhdGlvbikpIHtcbiAgICAgICAgICAgIGNvbnN0IGZyb21Db2wgPSByZWxhdGlvbj8uZnJvbUNvbHVtbiA/PyBcImlkXCI7XG4gICAgICAgICAgICBtYW55Sm9pbiA9IHtcbiAgICAgICAgICAgICAgZnJvbVRhYmxlOiB0aGlzLnRhYmxlLFxuICAgICAgICAgICAgICBmcm9tQ29sLFxuICAgICAgICAgICAgICBpZEZpZWxkOiBwcmVmaXggPT09IFwiXCIgPyBgJHtmcm9tQ29sfWAgOiBgJHtwcmVmaXh9X18ke2Zyb21Db2x9YCxcbiAgICAgICAgICAgICAgdG9UYWJsZTogcmVsRW50aXR5LnRhYmxlLFxuICAgICAgICAgICAgICB0b0NvbDogcmVsYXRpb24uam9pbkNvbHVtbixcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIGlmIChpc01hbnlUb01hbnlSZWxhdGlvblByb3AocmVsYXRpb24pKSB7XG4gICAgICAgICAgICBtYW55Sm9pbiA9IHtcbiAgICAgICAgICAgICAgZnJvbVRhYmxlOiB0aGlzLnRhYmxlLFxuICAgICAgICAgICAgICBmcm9tQ29sOiBcImlkXCIsXG4gICAgICAgICAgICAgIGlkRmllbGQ6IHByZWZpeCA9PT0gXCJcIiA/IGBpZGAgOiBgJHtwcmVmaXh9X19pZGAsXG4gICAgICAgICAgICAgIHRocm91Z2g6IHtcbiAgICAgICAgICAgICAgICB0YWJsZTogcmVsYXRpb24uam9pblRhYmxlLFxuICAgICAgICAgICAgICAgIGZyb21Db2w6IGAke2luZmxlY3Rpb24uc2luZ3VsYXJpemUodGhpcy50YWJsZSl9X2lkYCxcbiAgICAgICAgICAgICAgICB0b0NvbDogYCR7aW5mbGVjdGlvbi5zaW5ndWxhcml6ZShyZWxFbnRpdHkudGFibGUpfV9pZGAsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIHRvVGFibGU6IHJlbEVudGl0eS50YWJsZSxcbiAgICAgICAgICAgICAgdG9Db2w6IFwiaWRcIixcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcigpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHIubG9hZGVycy5wdXNoKHtcbiAgICAgICAgICAgIGFzOiBncm91cEtleSxcbiAgICAgICAgICAgIHRhYmxlOiByZWxFbnRpdHkudGFibGUsXG4gICAgICAgICAgICBtYW55Sm9pbixcbiAgICAgICAgICAgIG9uZUpvaW5zOiByZWxTdWJzZXRRdWVyeS5qb2lucyxcbiAgICAgICAgICAgIHNlbGVjdDogcmVsU3Vic2V0UXVlcnkuc2VsZWN0LFxuICAgICAgICAgICAgbG9hZGVyczogcmVsU3Vic2V0UXVlcnkubG9hZGVycyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByO1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgc2VsZWN0OiBbXSxcbiAgICAgICAgdmlydHVhbDogW10sXG4gICAgICAgIGpvaW5zOiBbXSxcbiAgICAgICAgbG9hZGVyczogW10sXG4gICAgICB9IGFzIFN1YnNldFF1ZXJ5LFxuICAgICk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qXG4gICAgRmllbGRFeHByW10g7J2EIEVudGl0eVByb3BOb2RlW10g66GcIOuzgO2ZmFxuICAqL1xuICBmaWVsZEV4cHJzVG9Qcm9wTm9kZXMoZmllbGRFeHByczogc3RyaW5nW10sIGVudGl0eTogRW50aXR5ID0gdGhpcyk6IEVudGl0eVByb3BOb2RlW10ge1xuICAgIGNvbnN0IGdyb3VwcyA9IGZpZWxkRXhwcnMucmVkdWNlKFxuICAgICAgKHJlc3VsdCwgZmllbGRFeHByKSA9PiB7XG4gICAgICAgIGxldCBrZXk6IHN0cmluZywgdmFsdWU6IHN0cmluZywgZWxzZUV4cHI6IHN0cmluZ1tdO1xuICAgICAgICBpZiAoZmllbGRFeHByLmluY2x1ZGVzKFwiLlwiKSkge1xuICAgICAgICAgIFtrZXksIC4uLmVsc2VFeHByXSA9IGZpZWxkRXhwci5zcGxpdChcIi5cIik7XG4gICAgICAgICAgdmFsdWUgPSBlbHNlRXhwci5qb2luKFwiLlwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBrZXkgPSBcIlwiO1xuICAgICAgICAgIHZhbHVlID0gZmllbGRFeHByO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdFtrZXldID0gKHJlc3VsdFtrZXldID8/IFtdKS5jb25jYXQodmFsdWUpO1xuXG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9LFxuICAgICAge30gYXMge1xuICAgICAgICBbazogc3RyaW5nXTogc3RyaW5nW107XG4gICAgICB9LFxuICAgICk7XG5cbiAgICByZXR1cm4gT2JqZWN0LmtleXMoZ3JvdXBzKS5mbGF0TWFwPEVudGl0eVByb3BOb2RlLCBFbnRpdHlQcm9wTm9kZVtdPigoa2V5KSA9PiB7XG4gICAgICBjb25zdCBncm91cCA9IGdyb3Vwc1trZXldO1xuXG4gICAgICAvLyDsnbzrsJggcHJvcCDsspjrpqxcbiAgICAgIGlmIChrZXkgPT09IFwiXCIpIHtcbiAgICAgICAgcmV0dXJuIGdyb3VwLm1hcCgocHJvcE5hbWUpID0+IHtcbiAgICAgICAgICBjb25zdCBwcm9wID0gZW50aXR5LnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gcHJvcE5hbWUpO1xuICAgICAgICAgIGlmIChwcm9wID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgYCR7ZW50aXR5LmlkfSAtLSDsnpjrqrvrkJwgRmllbGRFeHByICcke3Byb3BOYW1lfScgKOyCrOyaqSDqsIDriqXtlZwgcHJvcHM6ICR7ZW50aXR5LnByb3BzLm1hcCgocCkgPT4gcC5uYW1lKS5qb2luKFwiLCBcIil9KWAsXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgbm9kZVR5cGU6IFwicGxhaW5cIiBhcyBjb25zdCxcbiAgICAgICAgICAgIHByb3AsXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIHJlbGF0aW9uIHByb3Ag7LKY66asXG4gICAgICBjb25zdCBwcm9wID0gZW50aXR5LnByb3BzRGljdFtrZXldO1xuICAgICAgaWYgKCFpc1JlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYOyemOuqu+uQnCBGaWVsZEV4cHIgJHtrZXl9LiR7Z3JvdXBbMF19YCk7XG4gICAgICB9XG4gICAgICBjb25zdCByZWxFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuXG4gICAgICAvLyByZWxhdGlvbiAtT25lIOyXkCBpZCDtlYTrk5wg7ZWY64KY7J24IOqyveyasFxuICAgICAgaWYgKGlzQmVsb25nc1RvT25lUmVsYXRpb25Qcm9wKHByb3ApIHx8IGlzT25lVG9PbmVSZWxhdGlvblByb3AocHJvcCkpIHtcbiAgICAgICAgaWYgKGdyb3VwLmxlbmd0aCA9PT0gMSAmJiAoZ3JvdXBbMF0gPT09IFwiaWRcIiB8fCBncm91cFswXSA9PT0gXCJpZD9cIikpIHtcbiAgICAgICAgICAvLyBpZCDtlZjrgpjrp4wg7J6I64qU7KeAIOyytO2BrO2VtOyEnCwg7ZWY64KY66eMIOyeiOycvOuptCDsg4HsnIQgcHJvcOycvOuhnCBpZOulvCDrpqzthLRcbiAgICAgICAgICBjb25zdCBpZFByb3AgPSByZWxFbnRpdHkucHJvcHNEaWN0LmlkO1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBub2RlVHlwZTogXCJwbGFpblwiIGFzIGNvbnN0LFxuICAgICAgICAgICAgcHJvcDoge1xuICAgICAgICAgICAgICAuLi5pZFByb3AsXG4gICAgICAgICAgICAgIG5hbWU6IGAke2tleX1faWRgLFxuICAgICAgICAgICAgICBudWxsYWJsZTogcHJvcC5udWxsYWJsZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyAtT25lIOq3uOyZuOydmCDqsr3smrAgb2JqZWN066GcIOumrO2EtFxuICAgICAgLy8gLU1hbnnsnZgg6rK97JqwIGFycmF566GcIOumrO2EtFxuICAgICAgLy8gUmVjdXJzaXZlIOuhnCDrjoHsiqQg7LKY66asXG4gICAgICBjb25zdCBjaGlsZHJlbiA9IHRoaXMuZmllbGRFeHByc1RvUHJvcE5vZGVzKGdyb3VwLCByZWxFbnRpdHkpO1xuICAgICAgY29uc3Qgbm9kZVR5cGUgPVxuICAgICAgICBpc0JlbG9uZ3NUb09uZVJlbGF0aW9uUHJvcChwcm9wKSB8fCBpc09uZVRvT25lUmVsYXRpb25Qcm9wKHByb3ApXG4gICAgICAgICAgPyAoXCJvYmplY3RcIiBhcyBjb25zdClcbiAgICAgICAgICA6IChcImFycmF5XCIgYXMgY29uc3QpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBub2RlVHlwZSxcbiAgICAgICAgcHJvcCxcbiAgICAgICAgY2hpbGRyZW4sXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0RmllbGRFeHBycyhwcmVmaXggPSBcIlwiLCBtYXhEZXB0aDogbnVtYmVyID0gMywgZnJvbXM6IHN0cmluZ1tdID0gW10pOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIHRoaXMucHJvcHNcbiAgICAgIC5mbGF0TWFwKChwcm9wKSA9PiB7XG4gICAgICAgIGNvbnN0IHByb3BOYW1lID0gW3ByZWZpeCwgcHJvcC5uYW1lXS5maWx0ZXIoKHYpID0+IHYgIT09IFwiXCIpLmpvaW4oXCIuXCIpO1xuICAgICAgICBpZiAocHJvcE5hbWUgPT09IHByZWZpeCkge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc1JlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICAgIGlmIChtYXhEZXB0aCA8IDApIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAoZnJvbXMuaW5jbHVkZXMocHJvcC53aXRoKSkge1xuICAgICAgICAgICAgLy8g7Jet67Cp7ZalIHJlbGF0aW9u7J24IOqyveyasCDsoJzsmbhcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyDsoJXrsKntlqUgcmVsYXRpb27snbgg6rK97JqwIHJlY3Vyc2l2ZSDsvZxcbiAgICAgICAgICBjb25zdCByZWxNZCA9IEVudGl0eU1hbmFnZXIuZ2V0KHByb3Aud2l0aCk7XG4gICAgICAgICAgcmV0dXJuIHJlbE1kLmdldEZpZWxkRXhwcnMocHJvcE5hbWUsIG1heERlcHRoIC0gMSwgWy4uLmZyb21zLCB0aGlzLmlkXSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHByb3BOYW1lO1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoKGYpID0+IGYgIT09IG51bGwpIGFzIHN0cmluZ1tdO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGF0aW9uIHByb3DsnbQg7ZiE7J6sIO2FjOydtOu4lOyXkCBGSyDsu6zrn7zsnYQg7IOd7ISx7ZWY64qU7KeAIO2ZleyduFxuICAgKihCZWxvbmdzVG9PbmUg65iQ64qUIE9uZVRvT25lKGhhc0pvaW5Db2x1bW49dHJ1ZSnsnbgg6rK97JqwIEZLIOyDneyEsSlcbiAgICovXG4gIHByaXZhdGUgaGFzRm9yZWlnbktleShwcm9wOiBSZWxhdGlvblByb3ApOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgcHJvcC5yZWxhdGlvblR5cGUgPT09IFwiQmVsb25nc1RvT25lXCIgfHxcbiAgICAgIChwcm9wLnJlbGF0aW9uVHlwZSA9PT0gXCJPbmVUb09uZVwiICYmIHByb3AuaGFzSm9pbkNvbHVtbiA9PT0gdHJ1ZSlcbiAgICApO1xuICB9XG5cbiAgZ2V0VGFibGVDb2x1bW5zKCk6IHsgbmFtZTogc3RyaW5nOyB0eXBlOiBzdHJpbmcgfVtdIHtcbiAgICByZXR1cm4gdGhpcy5wcm9wc1xuICAgICAgLm1hcCgocHJvcCkgPT4ge1xuICAgICAgICBpZiAocHJvcC50eXBlID09PSBcInJlbGF0aW9uXCIpIHtcbiAgICAgICAgICBpZiAodGhpcy5oYXNGb3JlaWduS2V5KHByb3ApKSB7XG4gICAgICAgICAgICByZXR1cm4geyBuYW1lOiBgJHtwcm9wLm5hbWV9X2lkYCwgdHlwZTogXCJpbnRfdW5zaWduZWRcIiB9O1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHsgbmFtZTogcHJvcC5uYW1lLCB0eXBlOiBwcm9wLnR5cGUgfTtcbiAgICAgIH0pXG4gICAgICAuZmlsdGVyKG5vbk51bGxhYmxlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFbnRpdHnsl5Ag7KCV7J2Y65CcIOuqqOuToCB2ZWN0b3Ig7YOA7J6FIOy7rOufvCDrsJjtmZhcbiAgICovXG4gIGdldFZlY3RvckNvbHVtbnMoKTogRW50aXR5UHJvcFtdIHtcbiAgICByZXR1cm4gdGhpcy5wcm9wcy5maWx0ZXIoKHApID0+IHAudHlwZSA9PT0gXCJ2ZWN0b3JcIik7XG4gIH1cblxuICAvKipcbiAgICog7Yq57KCVIHZlY3RvciDsu6zrn7wg67CY7ZmYXG4gICAqIEBwYXJhbSBjb2x1bW5OYW1lIC0g7Lus65+866qFICjsg53rnrUg7IucIOyyqyDrsojsp7ggdmVjdG9yIOy7rOufvClcbiAgICovXG4gIGdldFZlY3RvckNvbHVtbihjb2x1bW5OYW1lPzogc3RyaW5nKTogRW50aXR5UHJvcCB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgdmVjdG9yUHJvcHMgPSB0aGlzLmdldFZlY3RvckNvbHVtbnMoKTtcbiAgICBpZiAoY29sdW1uTmFtZSkge1xuICAgICAgcmV0dXJuIHZlY3RvclByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gY29sdW1uTmFtZSk7XG4gICAgfVxuICAgIHJldHVybiB2ZWN0b3JQcm9wc1swXTtcbiAgfVxuXG4gIC8qKlxuICAgKiDtlYTthLDrp4Eg6rCA64ql7ZWcIHByb3BzIOuwmO2ZmFxuICAgKlxuICAgKiAtIOydvOuwmCBwcm9wXG4gICAqIC0gRkvrpbwg7IOd7ISx7ZWY64qUIHJlbGF0aW9uIChCZWxvbmdzVG9PbmUsIE9uZVRvT25lIHdpdGggaGFzSm9pbkNvbHVtbilcbiAgICogICDihpIge25hbWV9X2lkIO2Yle2DnOydmCDqsIDsg4EgaW50ZWdlciBwcm9w7Jy866GcIOuzgO2ZmFxuICAgKi9cbiAgZ2V0RmlsdGVyYWJsZVByb3BzKCk6IEVudGl0eVByb3BbXSB7XG4gICAgcmV0dXJuIHRoaXMucHJvcHMuZmxhdE1hcCgocHJvcCk6IEVudGl0eVByb3AgfCBFbnRpdHlQcm9wW10gPT4ge1xuICAgICAgLy8gVmlydHVhbCBwcm9wIOygnOyZuFxuICAgICAgaWYgKGlzVmlydHVhbFByb3AocHJvcCkpIHtcbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuXG4gICAgICAvLyBSZWxhdGlvbiBwcm9wIOyymOumrFxuICAgICAgaWYgKGlzUmVsYXRpb25Qcm9wKHByb3ApKSB7XG4gICAgICAgIC8vIEZL66W8IOyDneyEse2VmOuKlCByZWxhdGlvbuunjCDtj6ztlahcbiAgICAgICAgaWYgKHRoaXMuaGFzRm9yZWlnbktleShwcm9wKSkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBuYW1lOiBgJHtwcm9wLm5hbWV9X2lkYCxcbiAgICAgICAgICAgIHR5cGU6IFwiaW50ZWdlclwiLFxuICAgICAgICAgICAgbnVsbGFibGU6IHByb3AubnVsbGFibGUsXG4gICAgICAgICAgfSBhcyBFbnRpdHlQcm9wO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBbXTtcbiAgICAgIH1cblxuICAgICAgLy8g7J2867CYIHByb3Ag7LKY66asXG4gICAgICByZXR1cm4gcHJvcDtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHJlZ2lzdGVyTW9kdWxlUGF0aHMoKSB7XG4gICAgY29uc3QgYmFzZVBhdGggPSBgJHt0aGlzLm5hbWVzLnBhcmVudEZzfWA7XG5cbiAgICAvLyBiYXNlLXNjaGVtZVxuICAgIEVudGl0eU1hbmFnZXIuc2V0TW9kdWxlUGF0aChgJHt0aGlzLmlkfUJhc2VTY2hlbWFgLCBgc29uYW11LmdlbmVyYXRlZGApO1xuXG4gICAgLy8gc3Vic2V0XG4gICAgaWYgKE9iamVjdC5rZXlzKHRoaXMuc3Vic2V0cykubGVuZ3RoID4gMCkge1xuICAgICAgRW50aXR5TWFuYWdlci5zZXRNb2R1bGVQYXRoKGAke3RoaXMuaWR9U3Vic2V0S2V5YCwgYHNvbmFtdS5nZW5lcmF0ZWRgKTtcbiAgICAgIEVudGl0eU1hbmFnZXIuc2V0TW9kdWxlUGF0aChgJHt0aGlzLmlkfVN1YnNldE1hcHBpbmdgLCBgc29uYW11LmdlbmVyYXRlZGApO1xuICAgICAgZm9yIChjb25zdCBzdWJzZXRLZXkgb2YgT2JqZWN0LmtleXModGhpcy5zdWJzZXRzKSkge1xuICAgICAgICBFbnRpdHlNYW5hZ2VyLnNldE1vZHVsZVBhdGgoXG4gICAgICAgICAgYCR7dGhpcy5pZH1TdWJzZXQke3N1YnNldEtleS50b1VwcGVyQ2FzZSgpfWAsXG4gICAgICAgICAgYHNvbmFtdS5nZW5lcmF0ZWRgLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGVudW1zXG4gICAgZm9yIChjb25zdCBlbnVtSWQgb2YgT2JqZWN0LmtleXModGhpcy5lbnVtTGFiZWxzKSkge1xuICAgICAgRW50aXR5TWFuYWdlci5zZXRNb2R1bGVQYXRoKGVudW1JZCwgYHNvbmFtdS5nZW5lcmF0ZWRgKTtcbiAgICB9XG5cbiAgICAvLyB0eXBlc1xuICAgIGNvbnN0IHR5cGVzTW9kdWxlUGF0aCA9IGAke2Jhc2VQYXRofS8ke3RoaXMubmFtZXMucGFyZW50RnN9LnR5cGVzYDtcbiAgICBjb25zdCB0eXBlc0ZpbGVQYXRoID0gcGF0aC5qb2luKFxuICAgICAgU29uYW11LmFwaVJvb3RQYXRoLFxuICAgICAgcnVudGltZVBhdGgoYGRpc3QvYXBwbGljYXRpb24vJHt0eXBlc01vZHVsZVBhdGh9LmpzYCksXG4gICAgKTtcblxuICAgIGlmIChhd2FpdCBleGlzdHModHlwZXNGaWxlUGF0aCkpIHtcbiAgICAgIGNvbnN0IGltcG9ydGVkTWVtYmVycyA9IGF3YWl0IGltcG9ydE1lbWJlcnM8ei5ab2RUeXBlQW55Pih0eXBlc0ZpbGVQYXRoKTtcbiAgICAgIHRoaXMudHlwZXMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgIGltcG9ydGVkTWVtYmVycy5tYXAoKHsgbmFtZSwgdmFsdWUgfSkgPT4ge1xuICAgICAgICAgIEVudGl0eU1hbmFnZXIuc2V0TW9kdWxlUGF0aChuYW1lLCB0eXBlc01vZHVsZVBhdGgpO1xuICAgICAgICAgIHJldHVybiBbbmFtZSwgdmFsdWVdO1xuICAgICAgICB9KSxcbiAgICAgICkgYXMgeyBbbmFtZTogc3RyaW5nXTogei5ab2RUeXBlQW55IH07XG4gICAgfVxuICB9XG5cbiAgcmVnaXN0ZXJUYWJsZVNwZWNzKCk6IHZvaWQge1xuICAgIC8vIOyhsOyduCDthYzsnbTruJQg7J24642x7IqkIOygnOyZuCAo7Lus65+8IOydtOumhOyXkCAnLifsnbQg7Y+s7ZWo65CcIOqyveyasClcbiAgICBjb25zdCB1bmlxdWVJbmRleGVzID0gdGhpcy5pbmRleGVzXG4gICAgICAuZmlsdGVyKChpZHgpID0+IGlkeC50eXBlID09PSBcInVuaXF1ZVwiKVxuICAgICAgLmZpbHRlcigoaWR4KSA9PiBpZHguY29sdW1ucy5ldmVyeSgoY29sKSA9PiAhY29sLm5hbWUuaW5jbHVkZXMoXCIuXCIpKSk7XG5cbiAgICBFbnRpdHlNYW5hZ2VyLnNldFRhYmxlU3BlYyh7XG4gICAgICBuYW1lOiB0aGlzLnRhYmxlLFxuICAgICAgdW5pcXVlSW5kZXhlcyxcbiAgICAgIGpzb25Db2x1bW5zOiB0aGlzLnByb3BzLmZpbHRlcigocCkgPT4gcC50eXBlID09PSBcImpzb25cIikubWFwKChwKSA9PiBwLm5hbWUpLFxuICAgIH0pO1xuICB9XG5cbiAgdG9Kc29uKCk6IEVudGl0eUpzb24ge1xuICAgIC8vIHN1YnNldHPsmYAgc3Vic2V0c0ludGVybmFs7J2EIFN1YnNldERlZiDtmJXtg5zroZwg67O17JuQIChjb25lIO2PrO2VqClcbiAgICBjb25zdCBzdWJzZXRzOiB7IFtrZXk6IHN0cmluZ106IGltcG9ydChcIi4uL3R5cGVzL3R5cGVzXCIpLlN1YnNldERlZiB9ID0ge307XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXModGhpcy5zdWJzZXRzKSkge1xuICAgICAgY29uc3Qgbm9ybWFsRmllbGRzOiBTdWJzZXRGaWVsZFtdID0gdGhpcy5zdWJzZXRzW2tleV07XG4gICAgICBjb25zdCBpbnRlcm5hbEZpZWxkczogU3Vic2V0RmllbGRbXSA9ICh0aGlzLnN1YnNldHNJbnRlcm5hbFtrZXldID8/IFtdKS5tYXAoKGZpZWxkKSA9PiAoe1xuICAgICAgICBmaWVsZCxcbiAgICAgICAgaW50ZXJuYWw6IHRydWUsXG4gICAgICB9KSk7XG4gICAgICBjb25zdCBmaWVsZHMgPSBbLi4ubm9ybWFsRmllbGRzLCAuLi5pbnRlcm5hbEZpZWxkc107XG5cbiAgICAgIC8vIGNvbmXsnbQg7J6I7Jy866m0IOyDiOuhnOyatCDqsJ3ssrQg7ZiV7YOc66GcLCDsl4bsnLzrqbQg67Cw7Je0IO2Yle2DnOuhnFxuICAgICAgaWYgKHRoaXMuc3Vic2V0Q29uZXNba2V5XSkge1xuICAgICAgICBzdWJzZXRzW2tleV0gPSB7XG4gICAgICAgICAgZmllbGRzLFxuICAgICAgICAgIGNvbmU6IHRoaXMuc3Vic2V0Q29uZXNba2V5XSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN1YnNldHNba2V5XSA9IGZpZWxkcztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBlbnVtc+ulvCBFbnVtRGVmIO2Yle2DnOuhnCDrs7Xsm5AgKGNvbmUg7Y+s7ZWoKVxuICAgIGNvbnN0IGVudW1zOiB7IFtrZXk6IHN0cmluZ106IGltcG9ydChcIi4uL3R5cGVzL3R5cGVzXCIpLkVudW1EZWYgfSA9IHt9O1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVzXSBvZiBPYmplY3QuZW50cmllcyh0aGlzLmVudW1MYWJlbHMpKSB7XG4gICAgICAvLyBjb25l7J20IOyeiOycvOuptCDsg4jroZzsmrQg6rCd7LK0IO2Yle2DnOuhnCwg7JeG7Jy866m0IFJlY29yZCDtmJXtg5zroZxcbiAgICAgIGlmICh0aGlzLmVudW1Db25lc1trZXldKSB7XG4gICAgICAgIGVudW1zW2tleV0gPSB7XG4gICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgIGNvbmU6IHRoaXMuZW51bUNvbmVzW2tleV0sXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbnVtc1trZXldID0gdmFsdWVzO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBpZDogdGhpcy5pZCxcbiAgICAgIHBhcmVudElkOiB0aGlzLnBhcmVudElkLFxuICAgICAgdGFibGU6IHRoaXMudGFibGUsXG4gICAgICB0aXRsZTogdGhpcy50aXRsZSxcbiAgICAgIGNvbmU6IHRoaXMuY29uZSxcbiAgICAgIHByb3BzOiB0aGlzLnByb3BzLFxuICAgICAgaW5kZXhlczogdGhpcy5pbmRleGVzLFxuICAgICAgc3Vic2V0cyxcbiAgICAgIGVudW1zLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBzYXZlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIHNvcnQ6IHN1YnNldHNcbiAgICBjb25zdCBzdWJzZXRSb3dzID0gdGhpcy5nZXRTdWJzZXRSb3dzKCk7XG4gICAgdGhpcy5zdWJzZXRzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXModGhpcy5zdWJzZXRzKS5tYXAoKFtzdWJzZXRLZXldKSA9PiB7XG4gICAgICAgIHJldHVybiBbc3Vic2V0S2V5LCB0aGlzLnN1YnNldFJvd3NUb1N1YnNldEZpZWxkcyhzdWJzZXRSb3dzLCBzdWJzZXRLZXksIGZhbHNlKV07XG4gICAgICB9KSxcbiAgICApO1xuICAgIHRoaXMuc3Vic2V0c0ludGVybmFsID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXModGhpcy5zdWJzZXRzSW50ZXJuYWwpLm1hcCgoW3N1YnNldEtleV0pID0+IHtcbiAgICAgICAgcmV0dXJuIFtzdWJzZXRLZXksIHRoaXMuc3Vic2V0Um93c1RvU3Vic2V0RmllbGRzKHN1YnNldFJvd3MsIHN1YnNldEtleSwgdHJ1ZSldO1xuICAgICAgfSksXG4gICAgKTtcblxuICAgIC8vIHNhdmVcbiAgICBjb25zdCBqc29uUGF0aCA9IHBhdGguam9pbihcbiAgICAgIFNvbmFtdS5hcGlSb290UGF0aCxcbiAgICAgIGBzcmMvYXBwbGljYXRpb24vJHt0aGlzLm5hbWVzLnBhcmVudEZzfS8ke3RoaXMubmFtZXMuZnN9LmVudGl0eS5qc29uYCxcbiAgICApO1xuICAgIGNvbnN0IGpzb24gPSB0aGlzLnRvSnNvbigpO1xuICAgIGF3YWl0IHdyaXRlRmlsZShqc29uUGF0aCwgZm9ybWF0Q29kZShKU09OLnN0cmluZ2lmeShqc29uKSwgXCJqc29uXCIsIGpzb25QYXRoKSk7XG5cbiAgICAvLyByZWxvYWRcbiAgICBhd2FpdCBFbnRpdHlNYW5hZ2VyLnJlZ2lzdGVyKGpzb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIO2FnO2UjOumvyBjb25lIOuplO2DgOuNsOydtO2EsOulvCDsg53shLHtlanri4jri6QuXG4gICAqXG4gICAqIExMTeydhCDsgqzsmqntlZjsp4Ag7JWK6rOgIGZha2VyLW1hcHBpbmdzLnRz66W8IO2ZnOyaqe2VmOyXrCDquLDrs7ggY29uZeydhCDsg53shLHtlanri4jri6QuXG4gICAqIHN0dWIgZW50aXR5IOyDneyEsSDsi5wg7J6Q64+Z7Jy866GcIO2YuOy2nOuQmOyWtCDstZzshoztlZzsnZggY29uZSDrqZTtg4DrjbDsnbTthLDrpbwg7KCc6rO17ZWp64uI64ukLlxuICAgKlxuICAgKiBAcGFyYW0gbG9jYWxlIC0g7IOd7ISxIOyLnCDsgqzsmqntlaAgbG9jYWxlICjquLDrs7jqsJI6IFNvbmFtdS5jb25maWcuaTE4bi5kZWZhdWx0TG9jYWxlIOuYkOuKlCBcImtvXCIpXG4gICAqL1xuICBhc3luYyBnZW5lcmF0ZVRlbXBsYXRlQ29uZXMobG9jYWxlPzogXCJrb1wiIHwgXCJlblwiIHwgXCJqYVwiKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBnZW5lcmF0ZVRlbXBsYXRlQ29uZXMgfSA9IGF3YWl0IGltcG9ydChcIi4vZW50aXR5LXRlbXBsYXRlLWNvbmVcIik7XG4gICAgY29uc3QgY29uZmlnTG9jYWxlID0gU29uYW11LmNvbmZpZy5pMThuPy5kZWZhdWx0TG9jYWxlO1xuICAgIGNvbnN0IGVmZmVjdGl2ZUxvY2FsZSA9XG4gICAgICBsb2NhbGUgfHxcbiAgICAgIChjb25maWdMb2NhbGUgPT09IFwia29cIiB8fCBjb25maWdMb2NhbGUgPT09IFwiZW5cIiB8fCBjb25maWdMb2NhbGUgPT09IFwiamFcIlxuICAgICAgICA/IGNvbmZpZ0xvY2FsZVxuICAgICAgICA6IFwia29cIik7XG4gICAgY29uc3QgcmVzdWx0ID0gZ2VuZXJhdGVUZW1wbGF0ZUNvbmVzKHRoaXMudG9Kc29uKCksIGVmZmVjdGl2ZUxvY2FsZSk7XG5cbiAgICAvLyDqsrDqs7zrpbwgRW50aXR57JeQIOyggeyaqSAoYXBwbHlDb25lc+yZgCDrj5nsnbztlZwg67Cp7IudKVxuICAgIGlmIChyZXN1bHQuZW50aXR5Q29uZSkge1xuICAgICAgdGhpcy5jb25lID0gcmVzdWx0LmVudGl0eUNvbmU7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbcHJvcE5hbWUsIGNvbmVdIG9mIE9iamVjdC5lbnRyaWVzKHJlc3VsdC5wcm9wQ29uZXMpKSB7XG4gICAgICBjb25zdCBwcm9wID0gdGhpcy5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IHByb3BOYW1lKTtcbiAgICAgIGlmIChwcm9wKSB7XG4gICAgICAgIChwcm9wIGFzIHsgY29uZT86IENvbmUgfSkuY29uZSA9IGNvbmU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5lbnVtQ29uZXMgPSB7IC4uLnRoaXMuZW51bUNvbmVzLCAuLi5yZXN1bHQuZW51bUNvbmVzIH07XG4gICAgdGhpcy5zdWJzZXRDb25lcyA9IHsgLi4udGhpcy5zdWJzZXRDb25lcywgLi4ucmVzdWx0LnN1YnNldENvbmVzIH07XG5cbiAgICBhd2FpdCB0aGlzLnNhdmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMTE3snYQg7IKs7Jqp7ZWY7JesIGNvbmUg66mU7YOA642w7J207YSw66W8IOyDneyEse2VqeuLiOuLpC5cbiAgICpcbiAgICogQHBhcmFtIG9wdGlvbnMucHJlc2VydmVFeGlzdGluZyAtIOq4sOyhtCBjb25lIOuztOyhtCDsl6zrtoAgKOq4sOuzuOqwkjogdHJ1ZSlcbiAgICogQHBhcmFtIG9wdGlvbnMub25seUVtcHR5IC0gZml4dHVyZUhpbnTqsIAg7JeG64qUIGNvbmXrp4wg7IOd7ISxICjquLDrs7jqsJI6IGZhbHNlKVxuICAgKiBAcGFyYW0gb3B0aW9ucy5sb2NhbGUgLSDsg53shLEg7IucIOyCrOyaqe2VoCBsb2NhbGUgKOq4sOuzuOqwkjogXCJrb1wiKVxuICAgKi9cbiAgYXN5bmMgZ2VuZXJhdGVDb25lcyhvcHRpb25zPzoge1xuICAgIHByZXNlcnZlRXhpc3Rpbmc/OiBib29sZWFuO1xuICAgIG9ubHlFbXB0eT86IGJvb2xlYW47XG4gICAgbG9jYWxlPzogXCJrb1wiIHwgXCJlblwiIHwgXCJqYVwiO1xuICB9KTogUHJvbWlzZTxpbXBvcnQoXCIuLi9jb25lL2NvbmUtZ2VuZXJhdG9yXCIpLkNvbmVHZW5lcmF0aW9uUmVzdWx0PiB7XG4gICAgY29uc3QgeyBnZW5lcmF0ZUNvbmVzIH0gPSBhd2FpdCBpbXBvcnQoXCIuLi9jb25lL2NvbmUtZ2VuZXJhdG9yXCIpO1xuICAgIGNvbnN0IGNvbnRleHQ6IGltcG9ydChcIi4uL2NvbmUvY29uZS1nZW5lcmF0b3JcIikuQ29uZUdlbmVyYXRpb25Db250ZXh0ID0ge1xuICAgICAgZW50aXR5OiB0aGlzLnRvSnNvbigpLFxuICAgICAgbG9jYWxlOiBvcHRpb25zPy5sb2NhbGUgfHwgXCJrb1wiLFxuICAgICAgZXhpc3RpbmdDb25lczogb3B0aW9ucz8ucHJlc2VydmVFeGlzdGluZyAhPT0gZmFsc2UgPyB0aGlzLmNvbGxlY3RFeGlzdGluZ0NvbmVzKCkgOiB1bmRlZmluZWQsXG4gICAgICBvbmx5RW1wdHk6IG9wdGlvbnM/Lm9ubHlFbXB0eSA/PyBmYWxzZSxcbiAgICB9O1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZ2VuZXJhdGVDb25lcyhjb250ZXh0KTtcbiAgICB0aGlzLmFwcGx5Q29uZXMocmVzdWx0KTtcbiAgICBhd2FpdCB0aGlzLnNhdmUoKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIOq4sOyhtCBjb25l65Ok7J2EIOyImOynke2VqeuLiOuLpCAoZW50aXR5LCBwcm9wcywgZW51bXMsIHN1YnNldHMpLlxuICAgKlxuICAgKiBAcmV0dXJucyDtgqTqsIAgXCJlbnRpdHk6aWRcIiwgXCJwcm9wOm5hbWVcIiwgXCJlbnVtOmVudW1JZFwiLCBcInN1YnNldDprZXlcIiDtmJXsi53snbggY29uZSDrp7VcbiAgICovXG4gIHByaXZhdGUgY29sbGVjdEV4aXN0aW5nQ29uZXMoKTogUmVjb3JkPHN0cmluZywgQ29uZT4ge1xuICAgIGNvbnN0IGNvbmVzOiBSZWNvcmQ8c3RyaW5nLCBDb25lPiA9IHt9O1xuXG4gICAgaWYgKHRoaXMuY29uZSkge1xuICAgICAgY29uZXNbYGVudGl0eToke3RoaXMuaWR9YF0gPSB0aGlzLmNvbmU7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBwcm9wIG9mIHRoaXMucHJvcHMpIHtcbiAgICAgIGlmIChwcm9wLmNvbmUpIHtcbiAgICAgICAgY29uZXNbYHByb3A6JHtwcm9wLm5hbWV9YF0gPSBwcm9wLmNvbmU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbZW51bUlkLCBjb25lXSBvZiBPYmplY3QuZW50cmllcyh0aGlzLmVudW1Db25lcykpIHtcbiAgICAgIGNvbmVzW2BlbnVtOiR7ZW51bUlkfWBdID0gY29uZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtzdWJzZXRLZXksIGNvbmVdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuc3Vic2V0Q29uZXMpKSB7XG4gICAgICBjb25lc1tgc3Vic2V0OiR7c3Vic2V0S2V5fWBdID0gY29uZTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29uZXM7XG4gIH1cblxuICAvKipcbiAgICog7IOd7ISx65CcIGNvbmXrk6TsnYQgRW50aXR57JeQIOyggeyaqe2VqeuLiOuLpC5cbiAgICpcbiAgICogQHBhcmFtIHJlc3VsdCAtIExMTeycvOuhnCDsg53shLHrkJwgY29uZSDqsrDqs7xcbiAgICovXG4gIHByaXZhdGUgYXBwbHlDb25lcyhyZXN1bHQ6IGltcG9ydChcIi4uL2NvbmUvY29uZS1nZW5lcmF0b3JcIikuQ29uZUdlbmVyYXRpb25SZXN1bHQpOiB2b2lkIHtcbiAgICBpZiAocmVzdWx0LmVudGl0eUNvbmUpIHtcbiAgICAgIHRoaXMuY29uZSA9IHJlc3VsdC5lbnRpdHlDb25lO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgW3Byb3BOYW1lLCBjb25lXSBvZiBPYmplY3QuZW50cmllcyhyZXN1bHQucHJvcENvbmVzKSkge1xuICAgICAgY29uc3QgcHJvcCA9IHRoaXMucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBwcm9wTmFtZSk7XG4gICAgICBpZiAocHJvcCkge1xuICAgICAgICAocHJvcCBhcyB7IGNvbmU/OiBDb25lIH0pLmNvbmUgPSBjb25lO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZW51bUNvbmVzID0geyAuLi50aGlzLmVudW1Db25lcywgLi4ucmVzdWx0LmVudW1Db25lcyB9O1xuICAgIHRoaXMuc3Vic2V0Q29uZXMgPSB7IC4uLnRoaXMuc3Vic2V0Q29uZXMsIC4uLnJlc3VsdC5zdWJzZXRDb25lcyB9O1xuICB9XG5cbiAgZ2V0U3Vic2V0Um93cyhcbiAgICBfc3Vic2V0cz86IHsgW2tleTogc3RyaW5nXTogc3RyaW5nW10gfSxcbiAgICBfc3Vic2V0c0ludGVybmFsPzogeyBba2V5OiBzdHJpbmddOiBzdHJpbmdbXSB9LFxuICAgIHByZWZpeGVzOiBzdHJpbmdbXSA9IFtdLFxuICApOiBFbnRpdHlTdWJzZXRSb3dbXSB7XG4gICAgaWYgKHByZWZpeGVzLmxlbmd0aCA+IDEwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgY29uc3Qgc3Vic2V0cyA9IF9zdWJzZXRzID8/IHRoaXMuc3Vic2V0cztcbiAgICBjb25zdCBzdWJzZXRzSW50ZXJuYWwgPSBfc3Vic2V0c0ludGVybmFsID8/IHRoaXMuc3Vic2V0c0ludGVybmFsO1xuICAgIGNvbnN0IHN1YnNldEtleXMgPSBPYmplY3Qua2V5cyhzdWJzZXRzKTtcbiAgICBjb25zdCBhbGxGaWVsZHMgPSB1bmlxdWUoc3Vic2V0S2V5cy5mbGF0TWFwKChrZXkpID0+IHN1YnNldHNba2V5XSkpO1xuICAgIC8vIGludGVybmFsIO2VhOuTnOuPhCBhbGxGaWVsZHPsl5Ag7Y+s7ZWoIChyZWxhdGlvbiDtg5Dsg4nsmqkpXG4gICAgY29uc3QgYWxsSW50ZXJuYWxGaWVsZHMgPSB1bmlxdWUoc3Vic2V0S2V5cy5mbGF0TWFwKChrZXkpID0+IHN1YnNldHNJbnRlcm5hbFtrZXldID8/IFtdKSk7XG4gICAgY29uc3QgY29tYmluZWRGaWVsZHMgPSB1bmlxdWUoWy4uLmFsbEZpZWxkcywgLi4uYWxsSW50ZXJuYWxGaWVsZHNdKTtcblxuICAgIHJldHVybiB0aGlzLnByb3BzLm1hcCgocHJvcCkgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICBwcm9wLnR5cGUgPT09IFwicmVsYXRpb25cIiAmJlxuICAgICAgICBjb21iaW5lZEZpZWxkcy5maW5kKChmKSA9PiBmLnN0YXJ0c1dpdGgoYCR7Wy4uLnByZWZpeGVzLCBwcm9wLm5hbWVdLmpvaW4oXCIuXCIpfS5gKSlcbiAgICAgICkge1xuICAgICAgICBjb25zdCByZWxFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChwcm9wLndpdGgpO1xuICAgICAgICBjb25zdCBjaGlsZHJlbiA9IHJlbEVudGl0eS5nZXRTdWJzZXRSb3dzKHN1YnNldHMsIHN1YnNldHNJbnRlcm5hbCwgW1xuICAgICAgICAgIC4uLnByZWZpeGVzLFxuICAgICAgICAgIGAke3Byb3AubmFtZX1gLFxuICAgICAgICBdKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGZpZWxkOiBwcm9wLm5hbWUsXG4gICAgICAgICAgY2hpbGRyZW4sXG4gICAgICAgICAgcmVsYXRpb25FbnRpdHk6IHByb3Aud2l0aCxcbiAgICAgICAgICBwcmVmaXhlcyxcbiAgICAgICAgICBpc09wZW46IGNoaWxkcmVuLmxlbmd0aCA+IDAsXG4gICAgICAgICAgaGFzOiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgICAgICBzdWJzZXRLZXlzLm1hcCgoc3Vic2V0S2V5KSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBbc3Vic2V0S2V5LCBjaGlsZHJlbi5ldmVyeSgoY2hpbGQpID0+IGNoaWxkLmhhc1tzdWJzZXRLZXldID09PSB0cnVlKV07XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApLFxuICAgICAgICAgIGlzSW50ZXJuYWw6IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgICAgIHN1YnNldEtleXMubWFwKChzdWJzZXRLZXkpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIFtzdWJzZXRLZXksIGNoaWxkcmVuLmV2ZXJ5KChjaGlsZCkgPT4gY2hpbGQuaXNJbnRlcm5hbFtzdWJzZXRLZXldID09PSB0cnVlKV07XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApLFxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBmaWVsZCA9IFsuLi5wcmVmaXhlcywgcHJvcC5uYW1lXS5qb2luKFwiLlwiKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGZpZWxkOiBwcm9wLm5hbWUsXG4gICAgICAgIGNoaWxkcmVuOiBbXSxcbiAgICAgICAgcmVsYXRpb25FbnRpdHk6IHByb3AudHlwZSA9PT0gXCJyZWxhdGlvblwiID8gcHJvcC53aXRoIDogdW5kZWZpbmVkLFxuICAgICAgICBwcmVmaXhlcyxcbiAgICAgICAgaGFzOiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgICAgc3Vic2V0S2V5cy5tYXAoKHN1YnNldEtleSkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgc3Vic2V0RmllbGRzID0gc3Vic2V0c1tzdWJzZXRLZXldO1xuICAgICAgICAgICAgY29uc3QgaGFzID0gc3Vic2V0RmllbGRzLnNvbWUoKGYpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIGYgPT09IGZpZWxkIHx8IGYuc3RhcnRzV2l0aChgJHtmaWVsZH0uYCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBbc3Vic2V0S2V5LCBoYXNdO1xuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgICBpc0ludGVybmFsOiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgICAgc3Vic2V0S2V5cy5tYXAoKHN1YnNldEtleSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgaW50ZXJuYWxGaWVsZHMgPSBzdWJzZXRzSW50ZXJuYWxbc3Vic2V0S2V5XSA/PyBbXTtcbiAgICAgICAgICAgIGNvbnN0IGlzSW50ZXJuYWwgPSBpbnRlcm5hbEZpZWxkcy5zb21lKChmKSA9PiB7XG4gICAgICAgICAgICAgIHJldHVybiBmID09PSBmaWVsZCB8fCBmLnN0YXJ0c1dpdGgoYCR7ZmllbGR9LmApO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXR1cm4gW3N1YnNldEtleSwgaXNJbnRlcm5hbF07XG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICB9O1xuICAgIH0pO1xuICB9XG5cbiAgc3Vic2V0Um93c1RvU3Vic2V0RmllbGRzKFxuICAgIHN1YnNldFJvd3M6IEVudGl0eVN1YnNldFJvd1tdLFxuICAgIHN1YnNldEtleTogc3RyaW5nLFxuICAgIGludGVybmFsOiBib29sZWFuID0gZmFsc2UsXG4gICk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBoYXNLZXkgPSBpbnRlcm5hbCA/IFwiaXNJbnRlcm5hbFwiIDogXCJoYXNcIjtcbiAgICByZXR1cm4gc3Vic2V0Um93c1xuICAgICAgLm1hcCgoc3Vic2V0Um93KSA9PiB7XG4gICAgICAgIGlmIChzdWJzZXRSb3cuY2hpbGRyZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHJldHVybiB0aGlzLnN1YnNldFJvd3NUb1N1YnNldEZpZWxkcyhzdWJzZXRSb3cuY2hpbGRyZW4sIHN1YnNldEtleSwgaW50ZXJuYWwpO1xuICAgICAgICB9IGVsc2UgaWYgKHN1YnNldFJvd1toYXNLZXldW3N1YnNldEtleV0pIHtcbiAgICAgICAgICByZXR1cm4gc3Vic2V0Um93LnByZWZpeGVzLmNvbmNhdChzdWJzZXRSb3cuZmllbGQpLmpvaW4oXCIuXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLmZpbHRlcihub25OdWxsYWJsZSlcbiAgICAgIC5mbGF0KCk7XG4gIH1cblxuICBhc3luYyBjcmVhdGVQcm9wKHByb3A6IEVudGl0eVByb3AsIGF0PzogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCFhdCkge1xuICAgICAgdGhpcy5wcm9wcy5wdXNoKHByb3ApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnByb3BzLnNwbGljZShhdCwgMCwgcHJvcCk7XG4gICAgfVxuICAgIGF3YWl0IHRoaXMuc2F2ZSgpO1xuICB9XG5cbiAgYW5hbHl6ZVN1YnNldEZpZWxkKHN1YnNldEZpZWxkOiBzdHJpbmcpOiB7XG4gICAgZW50aXR5SWQ6IHN0cmluZztcbiAgICBwcm9wTmFtZTogc3RyaW5nO1xuICB9W10ge1xuICAgIGNvbnN0IGFyciA9IHN1YnNldEZpZWxkLnNwbGl0KFwiLlwiKTtcblxuICAgIGxldCBlbnRpdHlJZCA9IHRoaXMuaWQ7XG4gICAgY29uc3QgcmVzdWx0OiB7XG4gICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgcHJvcE5hbWU6IHN0cmluZztcbiAgICB9W10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgcHJvcE5hbWUgPSBhcnJbaV07XG4gICAgICByZXN1bHQucHVzaCh7XG4gICAgICAgIGVudGl0eUlkLFxuICAgICAgICBwcm9wTmFtZSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwcm9wID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpLnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gcHJvcE5hbWUpO1xuICAgICAgaWYgKCFwcm9wKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtlbnRpdHlJZH3snZgg7J6Y66q765CcIOyEnOu4jOyFi+2CpCAke3N1YnNldEZpZWxkfWApO1xuICAgICAgfVxuICAgICAgaWYgKGlzUmVsYXRpb25Qcm9wKHByb3ApKSB7XG4gICAgICAgIGVudGl0eUlkID0gcHJvcC53aXRoO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgYXN5bmMgbW9kaWZ5UHJvcChuZXdQcm9wOiBFbnRpdHlQcm9wLCBhdDogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8g7J207KCEIO2UhOuhrSDsnbTrpoQg7KCA7J6lXG4gICAgY29uc3Qgb2xkTmFtZSA9IHRoaXMucHJvcHNbYXRdLm5hbWU7XG5cbiAgICAvLyDsoIDsnqXtlaAg7JeU7Yuw7YuwXG4gICAgY29uc3QgZW50aXRpZXM6IEVudGl0eVtdID0gW3RoaXNdO1xuXG4gICAgLy8g7J2066aE7J20IOuwlOuAkCDqsr3smrBcbiAgICBpZiAob2xkTmFtZSAhPT0gbmV3UHJvcC5uYW1lKSB7XG4gICAgICAvLyDsoITssrQg7JeU7Yuw7Yuw7JeQ7IScIO2YhOyerCDsiJjsoJXrkJwg7ZSE66Gt7J2EIOywuOyhsO2VmOqzoCDsnojripQg66qo65OgIOyEnOu4jOyFi+2VhOuTnCDssL7slYTshJwg7IiY7KCVXG4gICAgICBjb25zdCBhbGxFbnRpdHlJZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuICAgICAgZm9yIChjb25zdCByZWxFbnRpdHlJZCBvZiBhbGxFbnRpdHlJZHMpIHtcbiAgICAgICAgY29uc3QgcmVsRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocmVsRW50aXR5SWQpO1xuICAgICAgICBjb25zdCByZWxFbnRpdHlTdWJzZXRLZXlzID0gT2JqZWN0LmtleXMocmVsRW50aXR5LnN1YnNldHMpO1xuICAgICAgICBmb3IgKGNvbnN0IHN1YnNldEtleSBvZiByZWxFbnRpdHlTdWJzZXRLZXlzKSB7XG4gICAgICAgICAgY29uc3Qgc3Vic2V0ID0gcmVsRW50aXR5LnN1YnNldHNbc3Vic2V0S2V5XTtcblxuICAgICAgICAgIC8vIOyEnOu4jOyFiyDtlYTrk5zrpbwg7Iic7ZqM7ZWY66mwLCDsl5Tti7Dti7At7ZSE66GtIOuLqOychOuhnCDrtoTshJ3tlZwg7ZuEIO2YhOyerCDsl5Tti7Dti7At7ZSE66Gt6rO8IOydvOy5mO2VmOuKlCDqsr3smrAg7IiY7KCVIOyymOumrFxuICAgICAgICAgIGNvbnN0IG1vZGlmaWVkU3Vic2V0RmllbGRzID0gc3Vic2V0Lm1hcCgoc3Vic2V0RmllbGQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFuYWx5emVkID0gcmVsRW50aXR5LmFuYWx5emVTdWJzZXRGaWVsZChzdWJzZXRGaWVsZCk7XG4gICAgICAgICAgICBjb25zdCBtb2RpZmllZCA9IGFuYWx5emVkLm1hcCgoYSkgPT5cbiAgICAgICAgICAgICAgYS5wcm9wTmFtZSA9PT0gb2xkTmFtZSAmJiBhLmVudGl0eUlkID09PSB0aGlzLmlkXG4gICAgICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgICAgIC4uLmEsXG4gICAgICAgICAgICAgICAgICAgIHByb3BOYW1lOiBuZXdQcm9wLm5hbWUsXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgOiBhLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIC8vIOu2hOyEne2VnCDtlYTrk5zrpbwg64uk7IucIOyEnOu4jOyFiyDtlYTrk5zroZwg67O16rWsXG4gICAgICAgICAgICByZXR1cm4gbW9kaWZpZWQubWFwKChhKSA9PiBhLnByb3BOYW1lKS5qb2luKFwiLlwiKTtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmIChzdWJzZXQuam9pbihcIixcIikgIT09IG1vZGlmaWVkU3Vic2V0RmllbGRzLmpvaW4oXCIsXCIpKSB7XG4gICAgICAgICAgICByZWxFbnRpdHkuc3Vic2V0c1tzdWJzZXRLZXldID0gbW9kaWZpZWRTdWJzZXRGaWVsZHM7XG4gICAgICAgICAgICBlbnRpdGllcy5wdXNoKHJlbEVudGl0eSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8g7ZSE66GtIOyImOyglVxuICAgIHRoaXMucHJvcHNbYXRdID0gbmV3UHJvcDtcblxuICAgIGF3YWl0IFByb21pc2UuYWxsKGVudGl0aWVzLm1hcChhc3luYyAoZW50aXR5KSA9PiBlbnRpdHkuc2F2ZSgpKSk7XG4gIH1cblxuICBhc3luYyBkZWxQcm9wKGF0OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyDsnbTsoIQg7ZSE66GtIOydtOumhCDsoIDsnqVcbiAgICBjb25zdCBvbGROYW1lID0gdGhpcy5wcm9wc1thdF0ubmFtZTtcblxuICAgIC8vIOyggOyepe2VoCDsl5Tti7Dti7BcbiAgICBjb25zdCBlbnRpdGllczogRW50aXR5W10gPSBbdGhpc107XG5cbiAgICAvLyDsoITssrQg7JeU7Yuw7Yuw7JeQ7IScIO2YhOyerCDsgq3soJzrkJwg7ZSE66Gt7J2EIOywuOyhsO2VmOqzoCDsnojripQg66qo65OgIOyEnOu4jOyFi+2VhOuTnCDssL7slYTshJwg7KCc7Jm4XG4gICAgY29uc3QgYWxsRW50aXR5SWRzID0gRW50aXR5TWFuYWdlci5nZXRBbGxJZHMoKTtcbiAgICBmb3IgKGNvbnN0IHJlbEVudGl0eUlkIG9mIGFsbEVudGl0eUlkcykge1xuICAgICAgY29uc3QgcmVsRW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQocmVsRW50aXR5SWQpO1xuICAgICAgY29uc3QgcmVsRW50aXR5U3Vic2V0S2V5cyA9IE9iamVjdC5rZXlzKHJlbEVudGl0eS5zdWJzZXRzKTtcbiAgICAgIGZvciAoY29uc3Qgc3Vic2V0S2V5IG9mIHJlbEVudGl0eVN1YnNldEtleXMpIHtcbiAgICAgICAgY29uc3Qgc3Vic2V0ID0gcmVsRW50aXR5LnN1YnNldHNbc3Vic2V0S2V5XTtcbiAgICAgICAgLy8g7ISc67iM7IWLIO2VhOuTnOulvCDsiJztmoztlZjrqbAsIOyXlO2LsO2LsC3tlITroa0g64uo7JyE66GcIOu2hOyEne2VnCDtm4Qg7ZiE7J6sIOyXlO2LsO2LsC3tlITroa3qs7wg7J287LmY7ZWY64qUIOqyveyasCDsnbTtm4TsnZgg7ZWE65Oc66W8IOygnOyZuFxuICAgICAgICBjb25zdCBtb2RpZmllZFN1YnNldEZpZWxkcyA9IHN1YnNldFxuICAgICAgICAgIC5tYXAoKHN1YnNldEZpZWxkKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhbmFseXplZCA9IHJlbEVudGl0eS5hbmFseXplU3Vic2V0RmllbGQoc3Vic2V0RmllbGQpO1xuICAgICAgICAgICAgaWYgKGFuYWx5emVkLmZpbmQoKGEpID0+IGEucHJvcE5hbWUgPT09IG9sZE5hbWUgJiYgYS5lbnRpdHlJZCA9PT0gdGhpcy5pZCkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByZXR1cm4gc3Vic2V0RmllbGQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSlcbiAgICAgICAgICAuZmlsdGVyKG5vbk51bGxhYmxlKTtcblxuICAgICAgICBpZiAoc3Vic2V0LmpvaW4oXCIsXCIpICE9PSBtb2RpZmllZFN1YnNldEZpZWxkcy5qb2luKFwiLFwiKSkge1xuICAgICAgICAgIHJlbEVudGl0eS5zdWJzZXRzW3N1YnNldEtleV0gPSBtb2RpZmllZFN1YnNldEZpZWxkcztcbiAgICAgICAgICBlbnRpdGllcy5wdXNoKHJlbEVudGl0eSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyDtmITsnqwg7JeU7Yuw7Yuw7J2YIOyduOuNseyKpOyXkOyEnCDsoJzsmbhcbiAgICBmb3IgKGNvbnN0IGluZGV4IG9mIEVudGl0eU1hbmFnZXIuZ2V0KHRoaXMuaWQpLmluZGV4ZXMpIHtcbiAgICAgIGluZGV4LmNvbHVtbnMgPSBpbmRleC5jb2x1bW5zLmZpbHRlcigoY29sKSA9PiBjb2wubmFtZSAhPT0gb2xkTmFtZSk7XG4gICAgfVxuXG4gICAgLy8g7ZSE66GtIOyCreygnFxuICAgIHRoaXMucHJvcHMuc3BsaWNlKGF0LCAxKTtcblxuICAgIGF3YWl0IFByb21pc2UuYWxsKGVudGl0aWVzLm1hcChhc3luYyAoZW50aXR5KSA9PiBlbnRpdHkuc2F2ZSgpKSk7XG4gIH1cblxuICBnZXRFbnRpdHlJZEZyb21TdWJzZXRGaWVsZChzdWJzZXRGaWVsZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoc3Vic2V0RmllbGQuaW5jbHVkZXMoXCIuXCIpID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIHRoaXMuaWQ7XG4gICAgfVxuXG4gICAgLy8g7ISc67iM7IWLIO2VhOuTnOydmCDrp4jsp4Drp4nsnYAg7ZSE66Gt7J2066+A66GcIOygnOyZuFxuICAgIGNvbnN0IGFyciA9IHN1YnNldEZpZWxkLnNwbGl0KFwiLlwiKS5zbGljZSgwLCAtMSk7XG5cbiAgICAvLyDshJzruIzshYsg7ZWE65Oc66W8IOuCtOugpOqwgOuptOyEnCDrp4jsp4Drp4nsnLzroZwgcmVsYXRpb27rkJwg7JeU7Yuw7Yuw66W8IOywvuydjFxuICAgIGNvbnN0IGxhc3RFbnRpdHlJZCA9IGFyci5yZWR1Y2UoKGVudGl0eUlkLCBmaWVsZCkgPT4ge1xuICAgICAgY29uc3QgcmVsUHJvcCA9IEVudGl0eU1hbmFnZXIuZ2V0KGVudGl0eUlkKS5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IGZpZWxkKTtcbiAgICAgIGlmICghcmVsUHJvcCB8fCByZWxQcm9wLnR5cGUgIT09IFwicmVsYXRpb25cIikge1xuICAgICAgICBjb25zb2xlLmRlYnVnKHsgYXJyLCB0aGlzSWQ6IHRoaXMuaWQsIGVudGl0eUlkLCBmaWVsZCB9KTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDsnpjrqrvrkJwg7ISc67iM7IWL7YKkICR7c3Vic2V0RmllbGR9YCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVsUHJvcC53aXRoO1xuICAgIH0sIHRoaXMuaWQpO1xuICAgIHJldHVybiBsYXN0RW50aXR5SWQ7XG4gIH1cblxuICBhc3luYyBtb3ZlUHJvcChhdDogbnVtYmVyLCB0bzogbnVtYmVyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcHJvcCA9IHRoaXMucHJvcHNbYXRdO1xuICAgIGNvbnN0IG5ld1Byb3BzID0gWy4uLnRoaXMucHJvcHNdO1xuICAgIG5ld1Byb3BzLnNwbGljZSh0bywgMCwgcHJvcCk7XG4gICAgbmV3UHJvcHMuc3BsaWNlKGF0IDwgdG8gPyBhdCA6IGF0ICsgMSwgMSk7XG4gICAgdGhpcy5wcm9wcyA9IG5ld1Byb3BzO1xuXG4gICAgYXdhaXQgdGhpcy5zYXZlKCk7XG4gIH1cblxuICAvKipcbiAgICog7ZWE65Oc66qF7J2EIFwi7YWM7J2067iU66qFLu2VhOuTnOuqhVwiIO2YleyLneycvOuhnCDrs4DtmZhcbiAgICovXG4gIGdldEZ1bGxGaWVsZE5hbWUoZmllbGQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgaWYgKGZpZWxkLmluY2x1ZGVzKFwiLlwiKSkge1xuICAgICAgcmV0dXJuIGZpZWxkO1xuICAgIH1cbiAgICByZXR1cm4gYCR7dGhpcy50YWJsZX0uJHtmaWVsZH1gO1xuICB9XG5cbiAgLyoqXG4gICAqIOyXlO2LsO2LsOydmCBQSyDtg4DsnoXsnYQg67CY7ZmY7ZWp64uI64ukLlxuICAgKiBpZCDtlYTrk5zsnZgg7YOA7J6F7J2EIOq4sOykgOycvOuhnCBcImludGVnZXJcIiB8IFwic3RyaW5nXCIgfCBcInV1aWRcIuulvCDrsJjtmZjtlanri4jri6QuXG4gICAqL1xuICBnZXRQa1R5cGUoKTogXCJpbnRlZ2VyXCIgfCBcInN0cmluZ1wiIHwgXCJ1dWlkXCIge1xuICAgIGNvbnN0IGlkUHJvcCA9IHRoaXMucHJvcHNEaWN0LmlkO1xuICAgIGlmICghaWRQcm9wKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEVudGl0eSAke3RoaXMuaWR97JeQIGlkIO2VhOuTnOqwgCDsl4bsirXri4jri6RgKTtcbiAgICB9XG4gICAgaWYgKGlkUHJvcC50eXBlID09PSBcInN0cmluZ1wiIHx8IGlkUHJvcC50eXBlID09PSBcInV1aWRcIikge1xuICAgICAgcmV0dXJuIGlkUHJvcC50eXBlO1xuICAgIH1cbiAgICByZXR1cm4gXCJpbnRlZ2VyXCI7XG4gIH1cblxuICAvKipcbiAgICog7JeU7Yuw7Yuw7J2YIFBLIHByb3DsnYQg67CY7ZmY7ZWp64uI64ukLlxuICAgKiBsZW5ndGgg65OxIOyEuOu2gCDsoJXrs7Tsl5Ag7KCR6re87ZWgIOuVjCDsgqzsmqntlanri4jri6QuXG4gICAqL1xuICBnZXRQa1Byb3AoKTogRW50aXR5UHJvcCB7XG4gICAgY29uc3QgaWRQcm9wID0gdGhpcy5wcm9wc0RpY3QuaWQ7XG4gICAgaWYgKCFpZFByb3ApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRW50aXR5ICR7dGhpcy5pZH3sl5AgaWQg7ZWE65Oc6rCAIOyXhuyKteuLiOuLpGApO1xuICAgIH1cbiAgICByZXR1cm4gaWRQcm9wO1xuICB9XG5cbiAgLyoqXG4gICAqIOyXlO2LsO2LsOydmCBQSyDrsLDsl7Qg7YOA7J6F7J2EIOuwmO2ZmO2VqeuLiOuLpC5cbiAgICogTG9hZGVyUXVlcnnsnZggZnJvbUlkcyDtg4DsnoXsnLzroZwg7IKs7Jqp65Cp64uI64ukLlxuICAgKi9cbiAgZ2V0UGtBcnJheVR5cGUoKTogc3RyaW5nIHtcbiAgICBjb25zdCBwa1R5cGUgPSB0aGlzLmdldFBrVHlwZSgpO1xuICAgIHJldHVybiBwa1R5cGUgPT09IFwiaW50ZWdlclwiID8gXCJudW1iZXJbXVwiIDogXCJzdHJpbmdbXVwiO1xuICB9XG59XG4iXSwibmFtZXMiOlsiYXNzZXJ0Iiwid3JpdGVGaWxlIiwiaW5mbGVjdGlvbiIsInBhdGgiLCJncm91cCIsInVuaXF1ZSIsInoiLCJTb25hbXUiLCJnZXRFbnVtRGVmVmFsdWVzIiwiZ2V0U3Vic2V0RmllbGRzIiwiaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AiLCJpc0VudW1Qcm9wIiwiaXNIYXNNYW55UmVsYXRpb25Qcm9wIiwiaXNJbnRlcm5hbFN1YnNldEZpZWxkIiwiaXNNYW55VG9NYW55UmVsYXRpb25Qcm9wIiwiaXNPbmVUb09uZVJlbGF0aW9uUHJvcCIsImlzUmVsYXRpb25Qcm9wIiwiaXNWaXJ0dWFsQ29kZVByb3AiLCJpc1ZpcnR1YWxQcm9wIiwibm9ybWFsaXplU3Vic2V0RmllbGQiLCJpbXBvcnRNZW1iZXJzIiwiZm9ybWF0Q29kZSIsImV4aXN0cyIsInJ1bnRpbWVQYXRoIiwiYXNzZXJ0RGVmaW5lZCIsIm5vbk51bGxhYmxlIiwiRW50aXR5TWFuYWdlciIsIkVudGl0eSIsImlkIiwicGFyZW50SWQiLCJ0YWJsZSIsInRpdGxlIiwiY29uZSIsIm5hbWVzIiwicHJvcHMiLCJwcm9wc0RpY3QiLCJyZWxhdGlvbnMiLCJpbmRleGVzIiwic3Vic2V0cyIsInN1YnNldHNJbnRlcm5hbCIsInR5cGVzIiwiZW51bXMiLCJlbnVtTGFiZWxzIiwiZW51bUNvbmVzIiwic3Vic2V0Q29uZXMiLCJ1bmRlcnNjb3JlIiwicGx1cmFsaXplIiwibWFwIiwicHJvcCIsImluY2x1ZGVzIiwicmVwbGFjZSIsIk9iamVjdCIsImZyb21FbnRyaWVzIiwibmFtZSIsImZpbHRlciIsImtleSIsInN1YnNldERlZiIsImVudHJpZXMiLCJmaWVsZHMiLCJmIiwiQXJyYXkiLCJpc0FycmF5IiwiZW51bURlZiIsImVudW1MYWJlbCIsImVudW0iLCJrZXlzIiwicGFyZW50RnMiLCJkYXNoZXJpemUiLCJ0b0xvd2VyQ2FzZSIsImZzIiwibW9kdWxlIiwiZ2V0U3Vic2V0RmllbGRzRm9yUXVlcnkiLCJzdWJzZXRLZXkiLCJnZXRQdXJpU3Vic2V0UXVlcnkiLCJzdWJzZXQiLCJzdWJzZXRRdWVyeSIsInJlc29sdmVTdWJzZXRRdWVyeSIsImxpbmVzIiwicHVzaCIsImpvaW4iLCJqb2lucyIsImpvaW5NZXRob2QiLCJhcyIsImN1c3RvbSIsImZyb20iLCJ0byIsInNlbGVjdE9iaiIsImJ1aWxkTmVzdGVkU2VsZWN0T2JqZWN0Iiwic2VsZWN0Iiwic3RyaW5naWZ5TmVzdGVkU2VsZWN0T2JqZWN0Iiwic2VsZWN0SXRlbXMiLCJyZXN1bHQiLCJzZWxlY3RJdGVtIiwibWF0Y2giLCJjb2x1bW4iLCJhbGlhcyIsImNvbHVtblZhbHVlIiwidHJpbSIsInNwbGl0IiwicG9wIiwicGFydHMiLCJjdXJyZW50IiwiaSIsImxlbmd0aCIsInBhcnQiLCJFcnJvciIsInNsaWNlIiwibGFzdFBhcnQiLCJvYmoiLCJpbmRlbnQiLCJ3aXRoQnJhY2VzIiwic3BhY2VzIiwicmVwZWF0IiwiaW5uZXJTcGFjZXMiLCJ2YWx1ZSIsImdldFB1cmlMb2FkZXJRdWVyeSIsImxvYWRlcnMiLCJnZW5lcmF0ZUxvYWRlckNvZGUiLCJsb2FkZXJMaW5lcyIsImxvYWRlciIsInRvVGFibGUiLCJ0b0NvbCIsInRocm91Z2giLCJmcm9tVGFibGUiLCJtYW55Sm9pbiIsImZyb21FbnRpdHkiLCJnZXRCeVRhYmxlIiwiZnJvbUlkc1R5cGUiLCJnZXRQa0FycmF5VHlwZSIsImlkRmllbGQiLCJ1bmRlZmluZWQiLCJvbmVKb2lucyIsImZvckVhY2giLCJyZWZJZCIsImZyb21Db2wiLCJnZXRTdWJzZXRRdWVyeSIsInByZWZpeCIsImlzQWxyZWFkeU91dGVySm9pbmVkIiwic3Vic2V0R3JvdXAiLCJmaWVsZCIsInJlbCIsInJlZHVjZSIsInIiLCJncm91cEtleSIsInJlYWxGaWVsZHMiLCJ2aXJ0dWFsQ29kZUZpZWxkcyIsImNvbmNhdCIsImdldEZ1bGxGaWVsZE5hbWUiLCJ2aXJ0dWFsIiwicmVsYXRpb24iLCJyZWxFbnRpdHkiLCJnZXQiLCJ3aXRoIiwicmVsRmllbGRzIiwiaW5uZXJPck91dGVyIiwiaGFzSm9pbkNvbHVtbiIsIm51bGxhYmxlIiwicmVsU3Vic2V0UXVlcnkiLCJqb2luQXMiLCJqb2luQ2xhdXNlIiwiY3VzdG9tSm9pbkNsYXVzZSIsImNvbnZlcnRlZExvYWRlcnMiLCJuZXdBcyIsImZyb21Db2x1bW4iLCJqb2luQ29sdW1uIiwiam9pblRhYmxlIiwic2luZ3VsYXJpemUiLCJmaWVsZEV4cHJzVG9Qcm9wTm9kZXMiLCJmaWVsZEV4cHJzIiwiZW50aXR5IiwiZ3JvdXBzIiwiZmllbGRFeHByIiwiZWxzZUV4cHIiLCJmbGF0TWFwIiwicHJvcE5hbWUiLCJmaW5kIiwicCIsIm5vZGVUeXBlIiwiaWRQcm9wIiwiY2hpbGRyZW4iLCJnZXRGaWVsZEV4cHJzIiwibWF4RGVwdGgiLCJmcm9tcyIsInYiLCJyZWxNZCIsImhhc0ZvcmVpZ25LZXkiLCJyZWxhdGlvblR5cGUiLCJnZXRUYWJsZUNvbHVtbnMiLCJ0eXBlIiwiZ2V0VmVjdG9yQ29sdW1ucyIsImdldFZlY3RvckNvbHVtbiIsImNvbHVtbk5hbWUiLCJ2ZWN0b3JQcm9wcyIsImdldEZpbHRlcmFibGVQcm9wcyIsInJlZ2lzdGVyTW9kdWxlUGF0aHMiLCJiYXNlUGF0aCIsInNldE1vZHVsZVBhdGgiLCJ0b1VwcGVyQ2FzZSIsImVudW1JZCIsInR5cGVzTW9kdWxlUGF0aCIsInR5cGVzRmlsZVBhdGgiLCJhcGlSb290UGF0aCIsImltcG9ydGVkTWVtYmVycyIsInJlZ2lzdGVyVGFibGVTcGVjcyIsInVuaXF1ZUluZGV4ZXMiLCJpZHgiLCJjb2x1bW5zIiwiZXZlcnkiLCJjb2wiLCJzZXRUYWJsZVNwZWMiLCJqc29uQ29sdW1ucyIsInRvSnNvbiIsIm5vcm1hbEZpZWxkcyIsImludGVybmFsRmllbGRzIiwiaW50ZXJuYWwiLCJ2YWx1ZXMiLCJzYXZlIiwic3Vic2V0Um93cyIsImdldFN1YnNldFJvd3MiLCJzdWJzZXRSb3dzVG9TdWJzZXRGaWVsZHMiLCJqc29uUGF0aCIsImpzb24iLCJKU09OIiwic3RyaW5naWZ5IiwicmVnaXN0ZXIiLCJnZW5lcmF0ZVRlbXBsYXRlQ29uZXMiLCJsb2NhbGUiLCJjb25maWdMb2NhbGUiLCJjb25maWciLCJpMThuIiwiZGVmYXVsdExvY2FsZSIsImVmZmVjdGl2ZUxvY2FsZSIsImVudGl0eUNvbmUiLCJwcm9wQ29uZXMiLCJnZW5lcmF0ZUNvbmVzIiwib3B0aW9ucyIsImNvbnRleHQiLCJleGlzdGluZ0NvbmVzIiwicHJlc2VydmVFeGlzdGluZyIsImNvbGxlY3RFeGlzdGluZ0NvbmVzIiwib25seUVtcHR5IiwiYXBwbHlDb25lcyIsImNvbmVzIiwiX3N1YnNldHMiLCJfc3Vic2V0c0ludGVybmFsIiwicHJlZml4ZXMiLCJzdWJzZXRLZXlzIiwiYWxsRmllbGRzIiwiYWxsSW50ZXJuYWxGaWVsZHMiLCJjb21iaW5lZEZpZWxkcyIsInN0YXJ0c1dpdGgiLCJyZWxhdGlvbkVudGl0eSIsImlzT3BlbiIsImhhcyIsImNoaWxkIiwiaXNJbnRlcm5hbCIsInN1YnNldEZpZWxkcyIsInNvbWUiLCJoYXNLZXkiLCJzdWJzZXRSb3ciLCJmbGF0IiwiY3JlYXRlUHJvcCIsImF0Iiwic3BsaWNlIiwiYW5hbHl6ZVN1YnNldEZpZWxkIiwic3Vic2V0RmllbGQiLCJhcnIiLCJlbnRpdHlJZCIsIm1vZGlmeVByb3AiLCJuZXdQcm9wIiwib2xkTmFtZSIsImVudGl0aWVzIiwiYWxsRW50aXR5SWRzIiwiZ2V0QWxsSWRzIiwicmVsRW50aXR5SWQiLCJyZWxFbnRpdHlTdWJzZXRLZXlzIiwibW9kaWZpZWRTdWJzZXRGaWVsZHMiLCJhbmFseXplZCIsIm1vZGlmaWVkIiwiYSIsIlByb21pc2UiLCJhbGwiLCJkZWxQcm9wIiwiaW5kZXgiLCJnZXRFbnRpdHlJZEZyb21TdWJzZXRGaWVsZCIsImxhc3RFbnRpdHlJZCIsInJlbFByb3AiLCJjb25zb2xlIiwiZGVidWciLCJ0aGlzSWQiLCJtb3ZlUHJvcCIsIm5ld1Byb3BzIiwiZ2V0UGtUeXBlIiwiZ2V0UGtQcm9wIiwicGtUeXBlIl0sIm1hcHBpbmdzIjoiQUFBQSxPQUFPQSxZQUFZLFNBQVM7QUFDNUIsU0FBU0MsU0FBUyxRQUFRLG1CQUFjO0FBQ3hDLE9BQU9DLGdCQUFnQixhQUFhO0FBQ3BDLE9BQU9DLFVBQVUsT0FBTztBQUN4QixTQUFTQyxLQUFLLEVBQUVDLE1BQU0sUUFBUSxVQUFVO0FBQ3hDLFNBQVNDLENBQUMsUUFBUSxNQUFNO0FBQ3hCLFNBQVNDLE1BQU0sUUFBUSxtQkFBZ0I7QUFDdkMs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
|
|
952
|
+
//#endregion
|
|
953
|
+
init_entity();
|
|
954
|
+
export { Entity, init_entity };
|
|
955
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LmpzIiwibmFtZXMiOlsieiIsImxpbmVzOiBzdHJpbmdbXSIsImpvaW4iLCJyZXN1bHQ6IFJldHVyblR5cGU8dHlwZW9mIHRoaXMuYnVpbGROZXN0ZWRTZWxlY3RPYmplY3Q+IiwibG9hZGVyTGluZXM6IHN0cmluZ1tdIiwibG9hZGVycyIsInJlc3VsdDogU3Vic2V0UXVlcnkiLCJmaWVsZHMiLCJqb2luQ2xhdXNlOlxuICAgICAgICAgICAgfCB7XG4gICAgICAgICAgICAgICAgZnJvbTogc3RyaW5nO1xuICAgICAgICAgICAgICAgIHRvOiBzdHJpbmc7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHwge1xuICAgICAgICAgICAgICAgIGN1c3RvbTogc3RyaW5nO1xuICAgICAgICAgICAgICB9IiwiZnJvbTogc3RyaW5nIiwidG86IHN0cmluZyIsIm1hbnlKb2luOiBTdWJzZXRRdWVyeVtcImxvYWRlcnNcIl1bbnVtYmVyXVtcIm1hbnlKb2luXCJdIiwia2V5OiBzdHJpbmciLCJ2YWx1ZTogc3RyaW5nIiwiZWxzZUV4cHI6IHN0cmluZ1tdIiwiZ3JvdXAiLCJwcm9wIiwic3Vic2V0czogeyBba2V5OiBzdHJpbmddOiBpbXBvcnQoXCIuLi90eXBlcy90eXBlc1wiKS5TdWJzZXREZWYgfSIsIm5vcm1hbEZpZWxkczogU3Vic2V0RmllbGRbXSIsImludGVybmFsRmllbGRzOiBTdWJzZXRGaWVsZFtdIiwiZW51bXM6IHsgW2tleTogc3RyaW5nXTogaW1wb3J0KFwiLi4vdHlwZXMvdHlwZXNcIikuRW51bURlZiB9IiwiY29udGV4dDogaW1wb3J0KFwiLi4vY29uZS9jb25lLWdlbmVyYXRvclwiKS5Db25lR2VuZXJhdGlvbkNvbnRleHQiLCJjb25lczogUmVjb3JkPHN0cmluZywgQ29uZT4iLCJyZXN1bHQ6IHtcbiAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICBwcm9wTmFtZTogc3RyaW5nO1xuICAgIH1bXSIsImVudGl0aWVzOiBFbnRpdHlbXSJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lbnRpdHkvZW50aXR5LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSBcImFzc2VydFwiO1xuaW1wb3J0IHsgd3JpdGVGaWxlIH0gZnJvbSBcImZzL3Byb21pc2VzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5pbXBvcnQgaW5mbGVjdGlvbiBmcm9tIFwiaW5mbGVjdGlvblwiO1xuaW1wb3J0IHsgZ3JvdXAsIHVuaXF1ZSB9IGZyb20gXCJyYWRhc2hpXCI7XG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiO1xuXG5pbXBvcnQgeyBTb25hbXUgfSBmcm9tIFwiLi4vYXBpL3NvbmFtdVwiO1xuaW1wb3J0IHtcbiAgZ2V0RW51bURlZlZhbHVlcyxcbiAgZ2V0U3Vic2V0RmllbGRzLFxuICBpc0JlbG9uZ3NUb09uZVJlbGF0aW9uUHJvcCxcbiAgaXNFbnVtUHJvcCxcbiAgaXNIYXNNYW55UmVsYXRpb25Qcm9wLFxuICBpc0ludGVybmFsU3Vic2V0RmllbGQsXG4gIGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcCxcbiAgaXNPbmVUb09uZVJlbGF0aW9uUHJvcCxcbiAgaXNSZWxhdGlvblByb3AsXG4gIGlzVmlydHVhbENvZGVQcm9wLFxuICBpc1ZpcnR1YWxQcm9wLFxuICBub3JtYWxpemVTdWJzZXRGaWVsZCxcbn0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQge1xuICB0eXBlIENvbmUsXG4gIHR5cGUgRW50aXR5SW5kZXgsXG4gIHR5cGUgRW50aXR5SnNvbixcbiAgdHlwZSBFbnRpdHlQcm9wLFxuICB0eXBlIEVudGl0eVByb3BOb2RlLFxuICB0eXBlIEVudGl0eVN1YnNldFJvdyxcbiAgdHlwZSBSZWxhdGlvblByb3AsXG4gIHR5cGUgU3Vic2V0RmllbGQsXG4gIHR5cGUgU3Vic2V0UXVlcnksXG59IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgaW1wb3J0TWVtYmVycyB9IGZyb20gXCIuLi91dGlscy9lc20tdXRpbHNcIjtcbmltcG9ydCB7IGZvcm1hdENvZGUgfSBmcm9tIFwiLi4vdXRpbHMvZm9ybWF0dGVyXCI7XG5pbXBvcnQgeyBleGlzdHMgfSBmcm9tIFwiLi4vdXRpbHMvZnMtdXRpbHNcIjtcbmltcG9ydCB7IHJ1bnRpbWVQYXRoIH0gZnJvbSBcIi4uL3V0aWxzL3BhdGgtdXRpbHNcIjtcbmltcG9ydCB7IGFzc2VydERlZmluZWQsIG5vbk51bGxhYmxlIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5pbXBvcnQgeyBFbnRpdHlNYW5hZ2VyIH0gZnJvbSBcIi4vZW50aXR5LW1hbmFnZXJcIjtcblxuZXhwb3J0IGNsYXNzIEVudGl0eSB7XG4gIGlkOiBzdHJpbmc7XG4gIHBhcmVudElkPzogc3RyaW5nO1xuICB0YWJsZTogc3RyaW5nO1xuICB0aXRsZTogc3RyaW5nO1xuICBjb25lPzogQ29uZTtcbiAgbmFtZXM6IHtcbiAgICBwYXJlbnRGczogc3RyaW5nO1xuICAgIGZzOiBzdHJpbmc7XG4gICAgbW9kdWxlOiBzdHJpbmc7XG4gIH07XG4gIHByb3BzOiBFbnRpdHlQcm9wW107XG4gIHByb3BzRGljdDoge1xuICAgIFtrZXk6IHN0cmluZ106IEVudGl0eVByb3A7XG4gIH07XG4gIHJlbGF0aW9uczoge1xuICAgIFtrZXk6IHN0cmluZ106IFJlbGF0aW9uUHJvcDtcbiAgfTtcbiAgaW5kZXhlczogRW50aXR5SW5kZXhbXTtcbiAgc3Vic2V0czoge1xuICAgIFtrZXk6IHN0cmluZ106IHN0cmluZ1tdO1xuICB9O1xuICBzdWJzZXRzSW50ZXJuYWw6IHtcbiAgICBba2V5OiBzdHJpbmddOiBzdHJpbmdbXTtcbiAgfTtcbiAgdHlwZXM6IHtcbiAgICBbbmFtZTogc3RyaW5nXTogei5ab2RUeXBlQW55O1xuICB9ID0ge307XG4gIGVudW1zOiB7XG4gICAgW2VudW1JZDogc3RyaW5nXTogei5ab2RFbnVtPFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHN0cmluZz4+PjtcbiAgfSA9IHt9O1xuICBlbnVtTGFiZWxzOiB7XG4gICAgW2VudW1JZDogc3RyaW5nXToge1xuICAgICAgW2tleTogc3RyaW5nXTogc3RyaW5nO1xuICAgIH07XG4gIH0gPSB7fTtcbiAgZW51bUNvbmVzOiB7XG4gICAgW2VudW1JZDogc3RyaW5nXTogQ29uZTtcbiAgfSA9IHt9O1xuICBzdWJzZXRDb25lczoge1xuICAgIFtzdWJzZXRLZXk6IHN0cmluZ106IENvbmU7XG4gIH0gPSB7fTtcblxuICBjb25zdHJ1Y3Rvcih7IGlkLCBwYXJlbnRJZCwgdGFibGUsIHRpdGxlLCBjb25lLCBwcm9wcywgaW5kZXhlcywgc3Vic2V0cywgZW51bXMgfTogRW50aXR5SnNvbikge1xuICAgIC8vIGlkXG4gICAgdGhpcy5pZCA9IGlkO1xuICAgIHRoaXMucGFyZW50SWQgPSBwYXJlbnRJZDtcbiAgICB0aGlzLnRpdGxlID0gdGl0bGUgPz8gdGhpcy5pZDtcbiAgICB0aGlzLnRhYmxlID0gdGFibGUgPz8gaW5mbGVjdGlvbi51bmRlcnNjb3JlKGluZmxlY3Rpb24ucGx1cmFsaXplKGlkKSk7XG4gICAgdGhpcy5jb25lID0gY29uZTtcblxuICAgIC8vIHByb3BzXG4gICAgaWYgKHByb3BzKSB7XG4gICAgICB0aGlzLnByb3BzID0gcHJvcHMubWFwKChwcm9wKSA9PiB7XG4gICAgICAgIGlmIChpc0VudW1Qcm9wKHByb3ApKSB7XG4gICAgICAgICAgaWYgKHByb3AuaWQuaW5jbHVkZXMoXCIkTW9kZWxcIikpIHtcbiAgICAgICAgICAgIHByb3AuaWQgPSBwcm9wLmlkLnJlcGxhY2UoXCIkTW9kZWxcIiwgaWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvcDtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5wcm9wc0RpY3QgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICAgIHByb3BzLm1hcCgocHJvcCkgPT4ge1xuICAgICAgICAgIHJldHVybiBbcHJvcC5uYW1lLCBwcm9wXTtcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICAvLyByZWxhdGlvbnNcbiAgICAgIHRoaXMucmVsYXRpb25zID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICBwcm9wcy5maWx0ZXIoKHByb3ApID0+IGlzUmVsYXRpb25Qcm9wKHByb3ApKS5tYXAoKHByb3ApID0+IFtwcm9wLm5hbWUsIHByb3BdKSxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHJvcHMgPSBbXTtcbiAgICAgIHRoaXMucHJvcHNEaWN0ID0ge307XG4gICAgICB0aGlzLnJlbGF0aW9ucyA9IHt9O1xuICAgIH1cblxuICAgIC8vIGluZGV4ZXNcbiAgICB0aGlzLmluZGV4ZXMgPSBpbmRleGVzID8/IFtdO1xuXG4gICAgLy8gc3Vic2V0czogU3Vic2V0RGVm7JeQ7IScIFN1YnNldEZpZWxkW13rpbwg7LaU7Lac7ZWY7JesIHN1YnNldHMo7J2867CYKeyZgCBzdWJzZXRzSW50ZXJuYWwoaW50ZXJuYWwp66GcIOu2hOumrFxuICAgIHRoaXMuc3Vic2V0cyA9IHt9O1xuICAgIHRoaXMuc3Vic2V0c0ludGVybmFsID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCBzdWJzZXREZWZdIG9mIE9iamVjdC5lbnRyaWVzKHN1YnNldHMgPz8ge30pKSB7XG4gICAgICBjb25zdCBmaWVsZHMgPSBnZXRTdWJzZXRGaWVsZHMoc3Vic2V0RGVmKTtcbiAgICAgIHRoaXMuc3Vic2V0c1trZXldID0gZmllbGRzLmZpbHRlcigoZikgPT4gIWlzSW50ZXJuYWxTdWJzZXRGaWVsZChmKSkubWFwKG5vcm1hbGl6ZVN1YnNldEZpZWxkKTtcbiAgICAgIHRoaXMuc3Vic2V0c0ludGVybmFsW2tleV0gPSBmaWVsZHMuZmlsdGVyKGlzSW50ZXJuYWxTdWJzZXRGaWVsZCkubWFwKG5vcm1hbGl6ZVN1YnNldEZpZWxkKTtcblxuICAgICAgLy8gY29uZSDstpTstpxcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShzdWJzZXREZWYpICYmIFwiY29uZVwiIGluIHN1YnNldERlZiAmJiBzdWJzZXREZWYuY29uZSkge1xuICAgICAgICB0aGlzLnN1YnNldENvbmVzW2tleV0gPSBzdWJzZXREZWYuY29uZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBlbnVtczogRW51bURlZuyXkOyEnCB2YWx1ZXPsmYAgY29uZeulvCDstpTstpztlZjsl6wg7LKY66asXG4gICAgdGhpcy5lbnVtTGFiZWxzID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgT2JqZWN0LmVudHJpZXMoZW51bXMgPz8ge30pLm1hcCgoW2tleSwgZW51bURlZl0pID0+IHtcbiAgICAgICAgLy8gY29uZSDstpTstpxcbiAgICAgICAgaWYgKFwidmFsdWVzXCIgaW4gZW51bURlZiAmJiBcImNvbmVcIiBpbiBlbnVtRGVmICYmIGVudW1EZWYuY29uZSkge1xuICAgICAgICAgIHRoaXMuZW51bUNvbmVzW2tleV0gPSBlbnVtRGVmLmNvbmUgYXMgQ29uZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gW2tleSwgZ2V0RW51bURlZlZhbHVlcyhlbnVtRGVmKV07XG4gICAgICB9KSxcbiAgICApO1xuICAgIHRoaXMuZW51bXMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyh0aGlzLmVudW1MYWJlbHMpLm1hcCgoW2tleSwgZW51bUxhYmVsXSkgPT4ge1xuICAgICAgICByZXR1cm4gW2tleSwgei5lbnVtKE9iamVjdC5rZXlzKGVudW1MYWJlbCkgYXMgdW5rbm93biBhcyByZWFkb25seSBbc3RyaW5nLCAuLi5zdHJpbmdbXV0pXTtcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICAvLyBuYW1lc1xuICAgIHRoaXMubmFtZXMgPSB7XG4gICAgICBwYXJlbnRGczogaW5mbGVjdGlvbi5kYXNoZXJpemUoaW5mbGVjdGlvbi51bmRlcnNjb3JlKHBhcmVudElkID8/IGlkKSkudG9Mb3dlckNhc2UoKSxcbiAgICAgIGZzOiBpbmZsZWN0aW9uLmRhc2hlcml6ZShpbmZsZWN0aW9uLnVuZGVyc2NvcmUoaWQpKS50b0xvd2VyQ2FzZSgpLFxuICAgICAgbW9kdWxlOiBpZCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIOy/vOumrOyaqSDshJzruIzshYsg7ZWE65Oc66W8IOuwmO2ZmO2VqeuLiOuLpCAoc3Vic2V0cyArIHN1YnNldHNJbnRlcm5hbCDtlansuagpXG4gICAqL1xuICBnZXRTdWJzZXRGaWVsZHNGb3JRdWVyeShzdWJzZXRLZXk6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gWy4uLih0aGlzLnN1YnNldHNbc3Vic2V0S2V5XSA/PyBbXSksIC4uLih0aGlzLnN1YnNldHNJbnRlcm5hbFtzdWJzZXRLZXldID8/IFtdKV07XG4gIH1cblxuICAvKipcbiAgICog7KO87Ja07KeEIOydtOumhChzdWJzZXRLZXkp7J2YIHN1YnNldOydhCDsi6TsoJzroZwg6rCA7KC47Jik64qUIFB1cmkg7L2U65OcIOq1rO2YhOyytCBzdHJpbmfsnYQg67CY7ZmY7ZWp64uI64ukLlxuICAgKi9cbiAgZ2V0UHVyaVN1YnNldFF1ZXJ5KHN1YnNldEtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdWJzZXQgPSB0aGlzLmdldFN1YnNldEZpZWxkc0ZvclF1ZXJ5KHN1YnNldEtleSk7XG4gICAgY29uc3Qgc3Vic2V0UXVlcnkgPSB0aGlzLnJlc29sdmVTdWJzZXRRdWVyeShcIlwiLCBzdWJzZXQpO1xuXG4gICAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW107XG5cbiAgICAvLyBmcm9tXG4gICAgbGluZXMucHVzaChgcmV0dXJuIHFiV3JhcHBlcmApO1xuICAgIGxpbmVzLnB1c2goYC5mcm9tKFwiJHt0aGlzLnRhYmxlfVwiKWApO1xuXG4gICAgLy8gam9pblxuICAgIGZvciAoY29uc3Qgam9pbiBvZiBzdWJzZXRRdWVyeS5qb2lucykge1xuICAgICAgLy8gam9pbiDrqZTshJzrk5wg6rKw7KCVOiBpbm5lciDihpIgam9pbiwgb3V0ZXIg4oaSIGxlZnRKb2luXG4gICAgICAvLyBGSyBudWxsYWJsZSDsl6zrtoDripQgbGVmdEpvaW4g7YOA7J6FIOyLnOq3uOuLiOyymOyXkOyEnCDsnpDrj5nsnLzroZwg7YyQ64uo65CoXG4gICAgICBjb25zdCBqb2luTWV0aG9kID0gam9pbi5qb2luID09PSBcImlubmVyXCIgPyBcImpvaW5cIiA6IFwibGVmdEpvaW5cIjtcblxuICAgICAgaWYgKFwiY3VzdG9tXCIgaW4gam9pbikge1xuICAgICAgICAvLyBjdXN0b20gam9pbiBjbGF1c2XripQgcmF3IOyCrOyaqVxuICAgICAgICBsaW5lcy5wdXNoKFxuICAgICAgICAgIGAuJHtqb2luTWV0aG9kfSh7ICR7am9pbi5hc306IFwiJHtqb2luLnRhYmxlfVwiIH0sIHFiV3JhcHBlci5rbmV4LnJhdyhcXGAke2pvaW4uY3VzdG9tfVxcYCkpYCxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxpbmVzLnB1c2goYC4ke2pvaW5NZXRob2R9KHsgJHtqb2luLmFzfTogXCIke2pvaW4udGFibGV9XCIgfSwgXCIke2pvaW4uZnJvbX1cIiwgXCIke2pvaW4udG99XCIpYCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gc2VsZWN0IC0g7J6F7LK07KCBIOq1rOyhsOuhnCDsg53shLFcbiAgICBjb25zdCBzZWxlY3RPYmogPSB0aGlzLmJ1aWxkTmVzdGVkU2VsZWN0T2JqZWN0KHN1YnNldFF1ZXJ5LnNlbGVjdCk7XG4gICAgbGluZXMucHVzaChgLnNlbGVjdCgke3RoaXMuc3RyaW5naWZ5TmVzdGVkU2VsZWN0T2JqZWN0KHNlbGVjdE9iail9KTtgKTtcblxuICAgIHJldHVybiBsaW5lcy5qb2luKFwiXFxuXCIpO1xuICB9XG5cbiAgLyoqXG4gICAqICouZW50aXR5Lmpzb27snZggc3Vic2V07JeQIOuTpOyWtOyeiOuKlCDtlYTrk5wg67Cw7Je07J2EIOuwm+yVhOyEnCxcbiAgICogUHVyaeydmCBTZWxlY3RPYmplY3Qg7YOA7J6F7Jy866GcIOuzgO2ZmO2VqeuLiOuLpC5cbiAgICpcbiAgICog7JiIOiBbXCJ1c2Vycy5pZFwiLCBcInBhcmVudC5pZFwiLCBcInBhcmVudC5uYW1lXCJdXG4gICAqICAg4oaSIHsgaWQ6IFwidXNlcnMuaWRcIiwgcGFyZW50OiB7IGlkOiBcInBhcmVudC5pZFwiLCBuYW1lOiBcInBhcmVudC5uYW1lXCIgfSB9XG4gICAqXG4gICAqIOyWuOuNlOuwlOqwgCDslYTri4wg7KSR7LKpIOqwneyytOuhnCDrs4DtmZjtlajsl5Ag7Jyg7J2Y7ZWY7IS47JqULlxuICAgKiDsnbTroIfqsowg7KSR7LKpIOqwneyytOuhnCDrs4DtmZjtlZjsl6wgc2VsZWN07JeQIOuEmOqyqOyjvOuptCBQYXJzZVNlbGVjdE9iamVjdCDtg4DsnoXsnbQgam9pbuuQnCDqsJ3ssrTsnZgg7YOA7J6F7J2EIOyemCDsnqHslYTspIQg7IiYIOyeiOyKteuLiOuLpC5cbiAgICog7KaJLCBlbmhhbmNlcuyXkOyEnCByb3frpbwg67Cb7JWY7J2EIOuVjCBoeWRyYXRl65CcIOqwneyytCDsnpDssrTsnZggbnVsbGl0eeyZgCDqt7gg7JWI7Kq9IO2VhOuTnOydmCBudWxsaXR56rCAIGZrIG51bGxhYmxlIOyXrOu2gOyXkCDrlLDrnbwg7J6YIOy2lOuhoOuQqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgYnVpbGROZXN0ZWRTZWxlY3RPYmplY3QoXG4gICAgc2VsZWN0SXRlbXM6IHN0cmluZ1tdLFxuICAgIC8vIG94bGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55IC0tIOuwmO2ZmCDsmKTruIzsoJ3tirjsnZgg6rCS7J2AIHN0cmluZ+ydvCDsiJjrj4Qg7J6I6rOgIOuYkOuLpOuluCDsmKTruIzsoJ3tirjsnbwg7IiY64+EIOyeiOuKlOuNsCwg7J2066W8IOyerOq3gCDtg4DsnoXsnLzroZwg64KY7YOA64K8IOyImCDsl4bslrQgYW5566GcIOyymOumrO2VqeuLiOuLpC5cbiAgKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gICAgY29uc3QgcmVzdWx0OiBSZXR1cm5UeXBlPHR5cGVvZiB0aGlzLmJ1aWxkTmVzdGVkU2VsZWN0T2JqZWN0PiA9IHt9O1xuXG4gICAgZm9yIChjb25zdCBzZWxlY3RJdGVtIG9mIHNlbGVjdEl0ZW1zKSB7XG4gICAgICAvLyBcInVzZXJzLmlkXCIg65iQ64qUIFwidXNlcnMuaWQgYXMgdXNlcl9faWRcIiDtmJXtg5wg7YyM7IuxXG4gICAgICBjb25zdCBtYXRjaCA9IHNlbGVjdEl0ZW0ubWF0Y2goL14oLis/KSg/OiBhcyAoLispKT8kLyk7XG4gICAgICBpZiAoIW1hdGNoKSBjb250aW51ZTtcblxuICAgICAgY29uc3QgWywgY29sdW1uLCBhbGlhc10gPSBtYXRjaDtcbiAgICAgIGNvbnN0IGNvbHVtblZhbHVlID0gYFwiJHtjb2x1bW4udHJpbSgpfVwiYDtcblxuICAgICAgaWYgKCFhbGlhcyB8fCAhYWxpYXMuaW5jbHVkZXMoXCJfX1wiKSkge1xuICAgICAgICAvLyBhbGlhc+qwgCDsl4bqsbDrgpggX1/rpbwg7Y+s7ZWo7ZWY7KeAIOyViuycvOuptCDstZzsg4HsnIQg7ZWE65OcXG4gICAgICAgIGNvbnN0IGtleSA9IGFsaWFzID8/IGFzc2VydERlZmluZWQoY29sdW1uLnNwbGl0KFwiLlwiKS5wb3AoKSk7XG4gICAgICAgIHJlc3VsdFtrZXldID0gY29sdW1uVmFsdWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBhbGlhc+qwgCBfX+ulvCDtj6ztlajtlZjrqbQg7J6F7LK0IOq1rOyhsOuhnCDqt7jro7ntmZRcbiAgICAgICAgY29uc3QgcGFydHMgPSBhbGlhcy5zcGxpdChcIl9fXCIpO1xuICAgICAgICBsZXQgY3VycmVudCA9IHJlc3VsdDtcblxuICAgICAgICAvLyDrp4jsp4Drp4kg7YyM7Yq4IOyghOq5jOyngCDspJHssqkg6rCd7LK0IOyDneyEsVxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcnRzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgIGNvbnN0IHBhcnQgPSBwYXJ0c1tpXTtcbiAgICAgICAgICBpZiAocGFydCBpbiBjdXJyZW50KSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGN1cnJlbnRbcGFydF0gPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgICAgICAgLy8g7J6F66Cl7J20IFtcInVzZXJcIiwgXCJ1c2VyX19pZFwiXSDqsJnsnYAg6rK97JqwIVxuICAgICAgICAgICAgICAvLyDslaDstIjsl5Ag66eQ64+EIOyViCDrkJjsp4Drp4wg7JWI7KCE7ZWY6rKMIOyYiOyZuOulvCDrjZjsp5Hri4jri6QuXG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICBgQ29uZmxpY3QgZGV0ZWN0ZWQgaW4gc2VsZWN0IGl0ZW1zOiBwYXJlbnQgcGF0aCBcIiR7cGFydHMuc2xpY2UoMCwgaSArIDEpLmpvaW4oXCJfX1wiKX1cIiBpcyBhbHJlYWR5IHNldCBhcyBhIGZpZWxkLCBjYW5ub3QgbmVzdCBcIiR7YWxpYXN9XCIgdW5kZXIgaXQuYCxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY3VycmVudFtwYXJ0XSA9IHt9O1xuICAgICAgICAgIH1cbiAgICAgICAgICBjdXJyZW50ID0gY3VycmVudFtwYXJ0XTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOuniOyngOuniSDtjIztirjsl5Ag6rCSIOyEpOyglVxuICAgICAgICBjb25zdCBsYXN0UGFydCA9IHBhcnRzW3BhcnRzLmxlbmd0aCAtIDFdO1xuICAgICAgICBjdXJyZW50W2xhc3RQYXJ0XSA9IGNvbHVtblZhbHVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogSlNPTi5zdHJpbmdpZnnsmYAg7Jyg7IKs7ZWcIOydvOydhCDtlanri4jri6QuXG4gICAqIOuLpOunjCDso7zslrTsp4Qg6rCd7LK066W8IEpTT07snbQg7JWE64uMIFR5cGVTY3JpcHQg6rCd7LK0IOumrO2EsOuftCDsiqTtirjrp4HsnLzroZwg66eM65Ok7Ja07KSN64uI64ukLlxuICAgKiBrZXnsl5Ag65Sw7Ji07ZGc6rCAIOyXhuyWtOyalC5cbiAgICog7Lac66ClIOyYiOyLnDpcbiAgICogYGBgdHlwZXNjcmlwdFxuICAgKiB7XG4gICAqICAgaWQ6IFwidXNlcnMuaWRcIixcbiAgICogICBwYXJlbnQ6IHtcbiAgICogICAgIGlkOiBcInBhcmVudC5pZFwiLFxuICAgKiAgICAgbmFtZTogXCJwYXJlbnQubmFtZVwiLFxuICAgKiAgIH0sXG4gICAqIH1cbiAgICogYGBgXG4gICAqIEBwYXJhbSBvYmog67OA7ZmY7ZWgIOqwneyytFxuICAgKiBAcGFyYW0gaW5kZW50IOuTpOyXrOyTsOq4sCDroIjrsqhcbiAgICogQHBhcmFtIHdpdGhCcmFjZXMgdHJ1ZeuptCDspJHqtITtmLgg7Y+s7ZWoLCBmYWxzZeuptCDrgrTsmqnrp4wg67CY7ZmYXG4gICAqL1xuICBwcml2YXRlIHN0cmluZ2lmeU5lc3RlZFNlbGVjdE9iamVjdChcbiAgICAvLyBveGxpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAtLSDspJHssqkg7Jik67iM7KCd7Yq47J2YIOqwkuydgCBzdHJpbmfsnbwg7IiY64+EIOyeiOqzoCDrmJDri6Trpbgg7Jik67iM7KCd7Yq47J28IOyImOuPhCDsnojripTrjbAsIOydtOulvCDsnqzqt4Ag7YOA7J6F7Jy866GcIOuCmO2DgOuCvCDsiJgg7JeG7Ja0IGFueeuhnCDsspjrpqztlanri4jri6QuXG4gICAgb2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIGluZGVudDogbnVtYmVyID0gMCxcbiAgICB3aXRoQnJhY2VzOiBib29sZWFuID0gdHJ1ZSxcbiAgKTogc3RyaW5nIHtcbiAgICBjb25zdCBzcGFjZXMgPSBcIiAgXCIucmVwZWF0KGluZGVudCk7XG4gICAgY29uc3QgaW5uZXJTcGFjZXMgPSBcIiAgXCIucmVwZWF0KGluZGVudCArIDEpO1xuXG4gICAgY29uc3QgZW50cmllcyA9IE9iamVjdC5lbnRyaWVzKG9iaik7XG4gICAgaWYgKGVudHJpZXMubGVuZ3RoID09PSAwKSByZXR1cm4gd2l0aEJyYWNlcyA/IFwie31cIiA6IFwiXCI7XG5cbiAgICBjb25zdCBsaW5lcyA9IGVudHJpZXMubWFwKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgLy8g7Lus65+8IOqyveuhnCAo7J2066+4IOuUsOyYtO2RnCDtj6ztlagpXG4gICAgICAgIHJldHVybiBgJHtpbm5lclNwYWNlc30ke2tleX06ICR7dmFsdWV9LGA7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyDspJHssqkg6rCd7LK0ICjtla3sg4Eg7KSR6rSE7Zi4IO2PrO2VqClcbiAgICAgICAgcmV0dXJuIGAke2lubmVyU3BhY2VzfSR7a2V5fTogJHt0aGlzLnN0cmluZ2lmeU5lc3RlZFNlbGVjdE9iamVjdCh2YWx1ZSwgaW5kZW50ICsgMSwgdHJ1ZSl9LGA7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAod2l0aEJyYWNlcykge1xuICAgICAgcmV0dXJuIGB7XFxuJHtsaW5lcy5qb2luKFwiXFxuXCIpfVxcbiR7c3BhY2VzfX1gO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyDspJHqtITtmLgg7JeG7J20IOuCtOyaqeunjCDrsJjtmZggKOyVnuuSpCDqsJztlokg7KCc7Jm4KVxuICAgICAgcmV0dXJuIGxpbmVzLmpvaW4oXCJcXG5cIik7XG4gICAgfVxuICB9XG5cbiAgZ2V0UHVyaUxvYWRlclF1ZXJ5KHN1YnNldEtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBzdWJzZXQgPSB0aGlzLmdldFN1YnNldEZpZWxkc0ZvclF1ZXJ5KHN1YnNldEtleSk7XG4gICAgY29uc3QgeyBsb2FkZXJzIH0gPSB0aGlzLnJlc29sdmVTdWJzZXRRdWVyeShcIlwiLCBzdWJzZXQpO1xuXG4gICAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW2BbYF07XG5cbiAgICAvLyDsnqzqt4DsoIHsnLzroZwgbG9hZGVyIOyDneyEse2VmOuKlCDtl6ztjbwg7ZWo7IiYXG4gICAgY29uc3QgZ2VuZXJhdGVMb2FkZXJDb2RlID0gKGxvYWRlcnM6IFN1YnNldFF1ZXJ5W1wibG9hZGVyc1wiXSk6IHN0cmluZ1tdID0+IHtcbiAgICAgIGNvbnN0IGxvYWRlckxpbmVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBmb3IgKGNvbnN0IGxvYWRlciBvZiBsb2FkZXJzKSB7XG4gICAgICAgIGNvbnN0IHsgdG9UYWJsZSwgdG9Db2wsIHRocm91Z2gsIGZyb21UYWJsZSB9ID0gbG9hZGVyLm1hbnlKb2luO1xuXG4gICAgICAgIC8vIGZyb21UYWJsZeydmCBFbnRpdHnrpbwg6rCA7KC47JmA7IScIFBLIO2DgOyehSDtmZXsnbhcbiAgICAgICAgY29uc3QgZnJvbUVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0QnlUYWJsZShmcm9tVGFibGUpO1xuICAgICAgICBjb25zdCBmcm9tSWRzVHlwZSA9IGZyb21FbnRpdHkuZ2V0UGtBcnJheVR5cGUoKTtcblxuICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgIFwie1wiLFxuICAgICAgICAgIGBhczogXCIke2xvYWRlci5hc31cIixgLFxuICAgICAgICAgIGByZWZJZDogXCIke2xvYWRlci5tYW55Sm9pbi5pZEZpZWxkfVwiLGAsXG4gICAgICAgICAgYHFiOiAocWJXcmFwcGVyOiBQdXJpV3JhcHBlcjxEYXRhYmFzZVNjaGVtYUV4dGVuZD4sIGZyb21JZHM6IG51bWJlcltdIHwgc3RyaW5nW10pID0+IHtgLFxuICAgICAgICApO1xuXG4gICAgICAgIGlmICh0aHJvdWdoID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAvLyBIYXNNYW55XG4gICAgICAgICAgbG9hZGVyTGluZXMucHVzaChcbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICBcInJldHVybiBxYldyYXBwZXJcIixcbiAgICAgICAgICAgIGAuZnJvbShcIiR7dG9UYWJsZX1cIilgLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBsb2FkZXIub25lSm9pbnMuZm9yRWFjaCgoam9pbjogU3Vic2V0UXVlcnlbXCJqb2luc1wiXVtudW1iZXJdKSA9PiB7XG4gICAgICAgICAgICAvLyBGSyBudWxsYWJsZSDsl6zrtoDripQgbGVmdEpvaW4g7YOA7J6FIOyLnOq3uOuLiOyymOyXkOyEnCDsnpDrj5nsnLzroZwg7YyQ64uo65CoXG4gICAgICAgICAgICBjb25zdCBqb2luTWV0aG9kID0gam9pbi5qb2luID09PSBcImlubmVyXCIgPyBcImpvaW5cIiA6IFwibGVmdEpvaW5cIjtcbiAgICAgICAgICAgIGlmIChcImN1c3RvbVwiIGluIGpvaW4pIHtcbiAgICAgICAgICAgICAgLy8gY3VzdG9tIGpvaW4gY2xhdXNl64qUIGNhbGxiYWNrIO2Yle2DnOydmCBvbiDrqZTshJzrk5zroZwg7LKY66as7ZWp64uI64ukLlxuICAgICAgICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgICAgICAgIGAuJHtqb2luTWV0aG9kfSh7ICR7am9pbi5hc306IFwiJHtqb2luLnRhYmxlfVwiIH0sIChqKSA9PiB7YCxcbiAgICAgICAgICAgICAgICBgai5vbihQdXJpLnJhd1N0cmluZyhcIiR7am9pbi5jdXN0b219XCIpKTtgLFxuICAgICAgICAgICAgICAgIFwifSlcIixcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGxvYWRlckxpbmVzLnB1c2goXG4gICAgICAgICAgICAgICAgYC4ke2pvaW5NZXRob2R9KHsgJHtqb2luLmFzfTogXCIke2pvaW4udGFibGV9XCIgfSwgXCIke2pvaW4uZnJvbX1cIiwgXCIke2pvaW4udG99XCIpYCxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIOyeheyytOyggSBzZWxlY3Qg6rWs7KGwIOyDneyEsSAocmVmSWQg7Y+s7ZWoKVxuICAgICAgICAgIGNvbnN0IHNlbGVjdE9iaiA9IHRoaXMuYnVpbGROZXN0ZWRTZWxlY3RPYmplY3QobG9hZGVyLnNlbGVjdCk7XG4gICAgICAgICAgc2VsZWN0T2JqLnJlZklkID0gYFwiJHt0b1RhYmxlfS4ke3RvQ29sfVwiYDtcbiAgICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgICAgYC53aGVyZUluKFwiJHt0b1RhYmxlfS4ke3RvQ29sfVwiLCBmcm9tSWRzIGFzICR7ZnJvbUlkc1R5cGV9KWAsXG4gICAgICAgICAgICBgLnNlbGVjdCgke3RoaXMuc3RyaW5naWZ5TmVzdGVkU2VsZWN0T2JqZWN0KHNlbGVjdE9iail9KTtgLFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gTWFueVRvTWFueVxuICAgICAgICAgIGxvYWRlckxpbmVzLnB1c2goXG4gICAgICAgICAgICBcInJldHVybiBxYldyYXBwZXJcIixcbiAgICAgICAgICAgIGAuZnJvbShcIiR7dGhyb3VnaC50YWJsZX1cIilgLFxuICAgICAgICAgICAgYC5qb2luKFwiJHt0b1RhYmxlfVwiLCBcIiR7dGhyb3VnaC50YWJsZX0uJHt0aHJvdWdoLnRvQ29sfVwiLCBcIiR7dG9UYWJsZX0uJHt0b0NvbH1cIilgLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBsb2FkZXIub25lSm9pbnMuZm9yRWFjaCgoam9pbjogU3Vic2V0UXVlcnlbXCJqb2luc1wiXVtudW1iZXJdKSA9PiB7XG4gICAgICAgICAgICAvLyBGSyBudWxsYWJsZSDsl6zrtoDripQgbGVmdEpvaW4g7YOA7J6FIOyLnOq3uOuLiOyymOyXkOyEnCDsnpDrj5nsnLzroZwg7YyQ64uo65CoXG4gICAgICAgICAgICBjb25zdCBqb2luTWV0aG9kID0gam9pbi5qb2luID09PSBcImlubmVyXCIgPyBcImpvaW5cIiA6IFwibGVmdEpvaW5cIjtcbiAgICAgICAgICAgIGlmIChcImN1c3RvbVwiIGluIGpvaW4pIHtcbiAgICAgICAgICAgICAgLy8gY3VzdG9tIGpvaW4gY2xhdXNl64qUIGNhbGxiYWNrIO2Yle2DnOydmCBvbiDrqZTshJzrk5zroZwg7LKY66as7ZWp64uI64ukLlxuICAgICAgICAgICAgICBsb2FkZXJMaW5lcy5wdXNoKFxuICAgICAgICAgICAgICAgIGAuJHtqb2luTWV0aG9kfSh7ICR7am9pbi5hc306IFwiJHtqb2luLnRhYmxlfVwiIH0sIChqKSA9PiB7YCxcbiAgICAgICAgICAgICAgICBgai5vbihQdXJpLnJhd1N0cmluZyhcIiR7am9pbi5jdXN0b219XCIpKTtgLFxuICAgICAgICAgICAgICAgIFwifSlcIixcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGxvYWRlckxpbmVzLnB1c2goXG4gICAgICAgICAgICAgICAgYC4ke2pvaW5NZXRob2R9KHsgJHtqb2luLmFzfTogXCIke2pvaW4udGFibGV9XCIgfSwgXCIke2pvaW4uZnJvbX1cIiwgXCIke2pvaW4udG99XCIpYCxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIOyeheyytOyggSBzZWxlY3Qg6rWs7KGwIOyDneyEsSAocmVmSWQg7Y+s7ZWoKVxuICAgICAgICAgIGNvbnN0IHNlbGVjdE9iaiA9IHRoaXMuYnVpbGROZXN0ZWRTZWxlY3RPYmplY3QobG9hZGVyLnNlbGVjdCk7XG4gICAgICAgICAgc2VsZWN0T2JqLnJlZklkID0gYFwiJHt0aHJvdWdoLnRhYmxlfS4ke3Rocm91Z2guZnJvbUNvbH1cImA7XG4gICAgICAgICAgbG9hZGVyTGluZXMucHVzaChcbiAgICAgICAgICAgIGAud2hlcmVJbihcIiR7dGhyb3VnaC50YWJsZX0uJHt0aHJvdWdoLmZyb21Db2x9XCIsIGZyb21JZHMgYXMgJHtmcm9tSWRzVHlwZX0pYCxcbiAgICAgICAgICAgIGAuc2VsZWN0KCR7dGhpcy5zdHJpbmdpZnlOZXN0ZWRTZWxlY3RPYmplY3Qoc2VsZWN0T2JqKX0pO2AsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxvYWRlckxpbmVzLnB1c2goYH0sYCk7XG5cbiAgICAgICAgLy8g7KSR7LKpIGxvYWRlcnMg7LKY66asXG4gICAgICAgIGlmIChsb2FkZXIubG9hZGVycyAmJiBsb2FkZXIubG9hZGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgbG9hZGVyTGluZXMucHVzaChcImxvYWRlcnM6IFtcIiwgLi4uZ2VuZXJhdGVMb2FkZXJDb2RlKGxvYWRlci5sb2FkZXJzKSwgXCJdLFwiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxvYWRlckxpbmVzLnB1c2goXCJ9LFwiKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGxvYWRlckxpbmVzO1xuICAgIH07XG5cbiAgICBsaW5lcy5wdXNoKC4uLmdlbmVyYXRlTG9hZGVyQ29kZShsb2FkZXJzKSk7XG4gICAgbGluZXMucHVzaChgXWApO1xuXG4gICAgcmV0dXJuIGxpbmVzLmpvaW4oXCJcXG5cIik7XG4gIH1cblxuICAvKlxuICAgIHN1YnNldCBTRUxFQ1QvSk9JTi9MT0FERVIg6rKw6rO8IOumrO2EtFxuICAqL1xuICBnZXRTdWJzZXRRdWVyeShzdWJzZXRLZXk6IHN0cmluZyk6IFN1YnNldFF1ZXJ5IHtcbiAgICBjb25zdCBzdWJzZXQgPSB0aGlzLmdldFN1YnNldEZpZWxkc0ZvclF1ZXJ5KHN1YnNldEtleSk7XG5cbiAgICBjb25zdCByZXN1bHQ6IFN1YnNldFF1ZXJ5ID0gdGhpcy5yZXNvbHZlU3Vic2V0UXVlcnkoXCJcIiwgc3Vic2V0KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLypcbiAgICovXG4gIHJlc29sdmVTdWJzZXRRdWVyeShcbiAgICBwcmVmaXg6IHN0cmluZyxcbiAgICBmaWVsZHM6IHN0cmluZ1tdLFxuICAgIGlzQWxyZWFkeU91dGVySm9pbmVkOiBib29sZWFuID0gZmFsc2UsXG4gICk6IFN1YnNldFF1ZXJ5IHtcbiAgICAvLyBwcmVmaXgg7LmY7ZmYIChwcmVmaXjripQgVG9PbmVSZWxhdGlvbuydtCDrs7XsiJjroZwg67aZ7J2AIOqyveyasCDrqqjrkZAgX1/roZwg67OA6rK965CoKVxuICAgIHByZWZpeCA9IHByZWZpeC5yZXBsYWNlKC9cXC4vZywgXCJfX1wiKTtcblxuICAgIC8vIOyEnOu4jOyFi+ydhCAx646B7Iqk66eMIOu2hOumrO2VmOyXrCDqt7jro7ntlZFcbiAgICBjb25zdCBzdWJzZXRHcm91cCA9IGdyb3VwKGZpZWxkcywgKGZpZWxkKSA9PiB7XG4gICAgICBpZiAoZmllbGQuaW5jbHVkZXMoXCIuXCIpKSB7XG4gICAgICAgIGNvbnN0IFtyZWxdID0gZmllbGQuc3BsaXQoXCIuXCIpO1xuICAgICAgICByZXR1cm4gcmVsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb25zdCByZXN1bHQgPSBPYmplY3Qua2V5cyhzdWJzZXRHcm91cCkucmVkdWNlKFxuICAgICAgKHIsIGdyb3VwS2V5KSA9PiB7XG4gICAgICAgIGNvbnN0IGZpZWxkcyA9IHN1YnNldEdyb3VwW2dyb3VwS2V5XTtcbiAgICAgICAgYXNzZXJ0KGZpZWxkcyAhPT0gdW5kZWZpbmVkLCBcImZpZWxkcyBpcyB1bmRlZmluZWRcIik7XG5cbiAgICAgICAgLy8g7ZiE7J6sIO2FjOydtOu4lCDtlYTrk5zshYvsnYAgc2VsZWN0LCB2aXJ0dWFs7JeQIOy2lOqwgO2VmOqzoCDrpqzthLRcbiAgICAgICAgaWYgKGdyb3VwS2V5ID09PSBcIlwiKSB7XG4gICAgICAgICAgY29uc3QgcmVhbEZpZWxkcyA9IGZpZWxkcy5maWx0ZXIoKGZpZWxkKSA9PiAhaXNWaXJ0dWFsUHJvcCh0aGlzLnByb3BzRGljdFtmaWVsZF0pKTtcbiAgICAgICAgICAvLyB2aXJ0dWFsVHlwZTogXCJjb2RlXCIgKOuYkOuKlCB1bmRlZmluZWQp7J24IHZpcnR1YWwgcHJvcOunjCByLnZpcnR1YWzsl5Ag7LaU6rCAXG4gICAgICAgICAgLy8gdmlydHVhbFR5cGU6IFwicXVlcnlcIuyduCDqsr3smrAg7IKs7Jqp7J6Q6rCAIGFwcGVuZFNlbGVjdOuhnCDsp4HsoJEg7LaU6rCA7ZWY66+A66GcIOygnOyZuFxuICAgICAgICAgIGNvbnN0IHZpcnR1YWxDb2RlRmllbGRzID0gZmllbGRzLmZpbHRlcigoZmllbGQpID0+XG4gICAgICAgICAgICBpc1ZpcnR1YWxDb2RlUHJvcCh0aGlzLnByb3BzRGljdFtmaWVsZF0pLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICBpZiAocHJlZml4ID09PSBcIlwiKSB7XG4gICAgICAgICAgICAvLyDtmITsnqwg7YWM7J2067iU7J24IOqyveyasFxuICAgICAgICAgICAgci5zZWxlY3QgPSByLnNlbGVjdC5jb25jYXQocmVhbEZpZWxkcy5tYXAoKGZpZWxkKSA9PiB0aGlzLmdldEZ1bGxGaWVsZE5hbWUoZmllbGQpKSk7XG4gICAgICAgICAgICByLnZpcnR1YWwgPSByLnZpcnR1YWwuY29uY2F0KHZpcnR1YWxDb2RlRmllbGRzKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8g64SY7Ja07JioIO2FjOydtOu4lOyduCDqsr3smrBcbiAgICAgICAgICAgIHIuc2VsZWN0ID0gci5zZWxlY3QuY29uY2F0KFxuICAgICAgICAgICAgICByZWFsRmllbGRzLm1hcCgoZmllbGQpID0+IGAke3ByZWZpeH0uJHtmaWVsZH0gYXMgJHtwcmVmaXh9X18ke2ZpZWxkfWApLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHJlbGF0aW9uID0gdGhpcy5yZWxhdGlvbnNbZ3JvdXBLZXldO1xuICAgICAgICBpZiAocmVsYXRpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihg7KG07J6s7ZWY7KeAIOyViuuKlCByZWxhdGlvbiDssLjsobAgJHtncm91cEtleX1gKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZWxFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChyZWxhdGlvbi53aXRoKTtcblxuICAgICAgICBpZiAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChyZWxhdGlvbikgfHwgaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocmVsYXRpb24pKSB7XG4gICAgICAgICAgLy8gLU9uZSBSZWxhdGlvbjogSk9JTiDsnLzroZwg7LKY66asXG4gICAgICAgICAgY29uc3QgcmVsRmllbGRzID0gZmllbGRzLm1hcCgoZmllbGQpID0+IGZpZWxkLnNwbGl0KFwiLlwiKS5zbGljZSgxKS5qb2luKFwiLlwiKSk7XG5cbiAgICAgICAgICAvLyAtT25lIFJlbGF0aW9u7JeQ7IScIGlkIO2VhOuTnOunjCDssLjsobDtlZjripQg6rK97JqwIOumtOugiOydtOyFmCDrhJjquLDsp4Ag7JWK6rOgIOumrO2EtFxuICAgICAgICAgIGlmIChyZWxGaWVsZHMubGVuZ3RoID09PSAxICYmIHJlbEZpZWxkc1swXSA9PT0gXCJpZFwiKSB7XG4gICAgICAgICAgICBpZiAocHJlZml4ID09PSBcIlwiKSB7XG4gICAgICAgICAgICAgIHIuc2VsZWN0ID0gci5zZWxlY3QuY29uY2F0KGAke3RoaXMudGFibGV9LiR7Z3JvdXBLZXl9X2lkYCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICByLnNlbGVjdCA9IHIuc2VsZWN0LmNvbmNhdChgJHtwcmVmaXh9LiR7Z3JvdXBLZXl9X2lkIGFzICR7cHJlZml4fV9fJHtncm91cEtleX1faWRgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiByO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGlubmVyT3JPdXRlclxuICAgICAgICAgIGNvbnN0IGlubmVyT3JPdXRlciA9ICgoKSA9PiB7XG4gICAgICAgICAgICBpZiAoaXNBbHJlYWR5T3V0ZXJKb2luZWQpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIFwib3V0ZXJcIjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGlzT25lVG9PbmVSZWxhdGlvblByb3AocmVsYXRpb24pKSB7XG4gICAgICAgICAgICAgIGlmIChyZWxhdGlvbi5oYXNKb2luQ29sdW1uICYmICEocmVsYXRpb24ubnVsbGFibGUgPz8gZmFsc2UpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFwiaW5uZXJcIjtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJvdXRlclwiO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBpZiAocmVsYXRpb24ubnVsbGFibGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gXCJvdXRlclwiO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiBcImlubmVyXCI7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KSgpO1xuICAgICAgICAgIGNvbnN0IHJlbFN1YnNldFF1ZXJ5ID0gcmVsRW50aXR5LnJlc29sdmVTdWJzZXRRdWVyeShcbiAgICAgICAgICAgIGAke3ByZWZpeCAhPT0gXCJcIiA/IGAke3ByZWZpeH0uYCA6IFwiXCJ9JHtncm91cEtleX1gLFxuICAgICAgICAgICAgcmVsRmllbGRzLFxuICAgICAgICAgICAgaW5uZXJPck91dGVyID09PSBcIm91dGVyXCIsXG4gICAgICAgICAgKTtcbiAgICAgICAgICByLnNlbGVjdCA9IHIuc2VsZWN0LmNvbmNhdChyZWxTdWJzZXRRdWVyeS5zZWxlY3QpO1xuICAgICAgICAgIHIudmlydHVhbCA9IHIudmlydHVhbC5jb25jYXQocmVsU3Vic2V0UXVlcnkudmlydHVhbCk7XG5cbiAgICAgICAgICBjb25zdCBqb2luQXMgPSBwcmVmaXggPT09IFwiXCIgPyBncm91cEtleSA6IGAke3ByZWZpeH1fXyR7Z3JvdXBLZXl9YDtcbiAgICAgICAgICBjb25zdCBmcm9tVGFibGUgPSBwcmVmaXggPT09IFwiXCIgPyB0aGlzLnRhYmxlIDogcHJlZml4O1xuXG4gICAgICAgICAgbGV0IGpvaW5DbGF1c2U6XG4gICAgICAgICAgICB8IHtcbiAgICAgICAgICAgICAgICBmcm9tOiBzdHJpbmc7XG4gICAgICAgICAgICAgICAgdG86IHN0cmluZztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfCB7XG4gICAgICAgICAgICAgICAgY3VzdG9tOiBzdHJpbmc7XG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgaWYgKHJlbGF0aW9uLmN1c3RvbUpvaW5DbGF1c2UpIHtcbiAgICAgICAgICAgIGpvaW5DbGF1c2UgPSB7XG4gICAgICAgICAgICAgIGN1c3RvbTogcmVsYXRpb24uY3VzdG9tSm9pbkNsYXVzZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGxldCBmcm9tOiBzdHJpbmcsIHRvOiBzdHJpbmc7XG4gICAgICAgICAgICBpZiAoaXNPbmVUb09uZVJlbGF0aW9uUHJvcChyZWxhdGlvbikpIHtcbiAgICAgICAgICAgICAgaWYgKHJlbGF0aW9uLmhhc0pvaW5Db2x1bW4pIHtcbiAgICAgICAgICAgICAgICBmcm9tID0gYCR7ZnJvbVRhYmxlfS4ke3JlbGF0aW9uLm5hbWV9X2lkYDtcbiAgICAgICAgICAgICAgICB0byA9IGAke2pvaW5Bc30uaWRgO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGZyb20gPSBgJHtmcm9tVGFibGV9LmlkYDtcbiAgICAgICAgICAgICAgICB0byA9IGAke2pvaW5Bc30uJHtpbmZsZWN0aW9uLnVuZGVyc2NvcmUodGhpcy5uYW1lcy5mcy5yZXBsYWNlKC8tL2csIFwiX1wiKSl9X2lkYDtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZnJvbSA9IGAke2Zyb21UYWJsZX0uJHtyZWxhdGlvbi5uYW1lfV9pZGA7XG4gICAgICAgICAgICAgIHRvID0gYCR7am9pbkFzfS5pZGA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBqb2luQ2xhdXNlID0ge1xuICAgICAgICAgICAgICBmcm9tLFxuICAgICAgICAgICAgICB0byxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgci5qb2lucy5wdXNoKHtcbiAgICAgICAgICAgIGFzOiBqb2luQXMsXG4gICAgICAgICAgICBqb2luOiBpbm5lck9yT3V0ZXIsXG4gICAgICAgICAgICB0YWJsZTogcmVsRW50aXR5LnRhYmxlLFxuICAgICAgICAgICAgLi4uam9pbkNsYXVzZSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIEJlbG9uZ3NUb09uZSDrsJHsl5AgSGFzTWFueeqwgCDrtpnsnYAg6rK97JqwXG4gICAgICAgICAgaWYgKHJlbFN1YnNldFF1ZXJ5LmxvYWRlcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgY29uc3QgY29udmVydGVkTG9hZGVycyA9IHJlbFN1YnNldFF1ZXJ5LmxvYWRlcnMubWFwKChsb2FkZXIpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgbmV3QXMgPSBbZ3JvdXBLZXksIGxvYWRlci5hc10uam9pbihcIl9fXCIpO1xuICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGFzOiBuZXdBcyxcbiAgICAgICAgICAgICAgICB0YWJsZTogbG9hZGVyLnRhYmxlLFxuICAgICAgICAgICAgICAgIG1hbnlKb2luOiBsb2FkZXIubWFueUpvaW4sXG4gICAgICAgICAgICAgICAgb25lSm9pbnM6IGxvYWRlci5vbmVKb2lucyxcbiAgICAgICAgICAgICAgICBzZWxlY3Q6IGxvYWRlci5zZWxlY3QsXG4gICAgICAgICAgICAgICAgbG9hZGVyczogbG9hZGVyLmxvYWRlcnMsXG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgci5sb2FkZXJzID0gWy4uLnIubG9hZGVycywgLi4uY29udmVydGVkTG9hZGVyc107XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgci5qb2lucyA9IHIuam9pbnMuY29uY2F0KHJlbFN1YnNldFF1ZXJ5LmpvaW5zKTtcbiAgICAgICAgfSBlbHNlIGlmIChpc0hhc01hbnlSZWxhdGlvblByb3AocmVsYXRpb24pIHx8IGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcChyZWxhdGlvbikpIHtcbiAgICAgICAgICAvLyAtTWFueSBSZWxhdGlvbjogTG9hZGVyIOuhnCDsspjrpqxcbiAgICAgICAgICBjb25zdCByZWxGaWVsZHMgPSBmaWVsZHMubWFwKChmaWVsZCkgPT4gZmllbGQuc3BsaXQoXCIuXCIpLnNsaWNlKDEpLmpvaW4oXCIuXCIpKTtcbiAgICAgICAgICBjb25zdCByZWxTdWJzZXRRdWVyeSA9IHJlbEVudGl0eS5yZXNvbHZlU3Vic2V0UXVlcnkoXCJcIiwgcmVsRmllbGRzKTtcblxuICAgICAgICAgIGxldCBtYW55Sm9pbjogU3Vic2V0UXVlcnlbXCJsb2FkZXJzXCJdW251bWJlcl1bXCJtYW55Sm9pblwiXTtcbiAgICAgICAgICBpZiAoaXNIYXNNYW55UmVsYXRpb25Qcm9wKHJlbGF0aW9uKSkge1xuICAgICAgICAgICAgY29uc3QgZnJvbUNvbCA9IHJlbGF0aW9uPy5mcm9tQ29sdW1uID8/IFwiaWRcIjtcbiAgICAgICAgICAgIG1hbnlKb2luID0ge1xuICAgICAgICAgICAgICBmcm9tVGFibGU6IHRoaXMudGFibGUsXG4gICAgICAgICAgICAgIGZyb21Db2wsXG4gICAgICAgICAgICAgIGlkRmllbGQ6IHByZWZpeCA9PT0gXCJcIiA/IGAke2Zyb21Db2x9YCA6IGAke3ByZWZpeH1fXyR7ZnJvbUNvbH1gLFxuICAgICAgICAgICAgICB0b1RhYmxlOiByZWxFbnRpdHkudGFibGUsXG4gICAgICAgICAgICAgIHRvQ29sOiByZWxhdGlvbi5qb2luQ29sdW1uLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGVsc2UgaWYgKGlzTWFueVRvTWFueVJlbGF0aW9uUHJvcChyZWxhdGlvbikpIHtcbiAgICAgICAgICAgIG1hbnlKb2luID0ge1xuICAgICAgICAgICAgICBmcm9tVGFibGU6IHRoaXMudGFibGUsXG4gICAgICAgICAgICAgIGZyb21Db2w6IFwiaWRcIixcbiAgICAgICAgICAgICAgaWRGaWVsZDogcHJlZml4ID09PSBcIlwiID8gYGlkYCA6IGAke3ByZWZpeH1fX2lkYCxcbiAgICAgICAgICAgICAgdGhyb3VnaDoge1xuICAgICAgICAgICAgICAgIHRhYmxlOiByZWxhdGlvbi5qb2luVGFibGUsXG4gICAgICAgICAgICAgICAgZnJvbUNvbDogYCR7aW5mbGVjdGlvbi5zaW5ndWxhcml6ZSh0aGlzLnRhYmxlKX1faWRgLFxuICAgICAgICAgICAgICAgIHRvQ29sOiBgJHtpbmZsZWN0aW9uLnNpbmd1bGFyaXplKHJlbEVudGl0eS50YWJsZSl9X2lkYCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgdG9UYWJsZTogcmVsRW50aXR5LnRhYmxlLFxuICAgICAgICAgICAgICB0b0NvbDogXCJpZFwiLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgci5sb2FkZXJzLnB1c2goe1xuICAgICAgICAgICAgYXM6IGdyb3VwS2V5LFxuICAgICAgICAgICAgdGFibGU6IHJlbEVudGl0eS50YWJsZSxcbiAgICAgICAgICAgIG1hbnlKb2luLFxuICAgICAgICAgICAgb25lSm9pbnM6IHJlbFN1YnNldFF1ZXJ5LmpvaW5zLFxuICAgICAgICAgICAgc2VsZWN0OiByZWxTdWJzZXRRdWVyeS5zZWxlY3QsXG4gICAgICAgICAgICBsb2FkZXJzOiByZWxTdWJzZXRRdWVyeS5sb2FkZXJzLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHI7XG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBzZWxlY3Q6IFtdLFxuICAgICAgICB2aXJ0dWFsOiBbXSxcbiAgICAgICAgam9pbnM6IFtdLFxuICAgICAgICBsb2FkZXJzOiBbXSxcbiAgICAgIH0gYXMgU3Vic2V0UXVlcnksXG4gICAgKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLypcbiAgICBGaWVsZEV4cHJbXSDsnYQgRW50aXR5UHJvcE5vZGVbXSDroZwg67OA7ZmYXG4gICovXG4gIGZpZWxkRXhwcnNUb1Byb3BOb2RlcyhmaWVsZEV4cHJzOiBzdHJpbmdbXSwgZW50aXR5OiBFbnRpdHkgPSB0aGlzKTogRW50aXR5UHJvcE5vZGVbXSB7XG4gICAgY29uc3QgZ3JvdXBzID0gZmllbGRFeHBycy5yZWR1Y2UoXG4gICAgICAocmVzdWx0LCBmaWVsZEV4cHIpID0+IHtcbiAgICAgICAgbGV0IGtleTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nLCBlbHNlRXhwcjogc3RyaW5nW107XG4gICAgICAgIGlmIChmaWVsZEV4cHIuaW5jbHVkZXMoXCIuXCIpKSB7XG4gICAgICAgICAgW2tleSwgLi4uZWxzZUV4cHJdID0gZmllbGRFeHByLnNwbGl0KFwiLlwiKTtcbiAgICAgICAgICB2YWx1ZSA9IGVsc2VFeHByLmpvaW4oXCIuXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGtleSA9IFwiXCI7XG4gICAgICAgICAgdmFsdWUgPSBmaWVsZEV4cHI7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0W2tleV0gPSAocmVzdWx0W2tleV0gPz8gW10pLmNvbmNhdCh2YWx1ZSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0sXG4gICAgICB7fSBhcyB7XG4gICAgICAgIFtrOiBzdHJpbmddOiBzdHJpbmdbXTtcbiAgICAgIH0sXG4gICAgKTtcblxuICAgIHJldHVybiBPYmplY3Qua2V5cyhncm91cHMpLmZsYXRNYXA8RW50aXR5UHJvcE5vZGUsIEVudGl0eVByb3BOb2RlW10+KChrZXkpID0+IHtcbiAgICAgIGNvbnN0IGdyb3VwID0gZ3JvdXBzW2tleV07XG5cbiAgICAgIC8vIOydvOuwmCBwcm9wIOyymOumrFxuICAgICAgaWYgKGtleSA9PT0gXCJcIikge1xuICAgICAgICByZXR1cm4gZ3JvdXAubWFwKChwcm9wTmFtZSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHByb3AgPSBlbnRpdHkucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBwcm9wTmFtZSk7XG4gICAgICAgICAgaWYgKHByb3AgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgICBgJHtlbnRpdHkuaWR9IC0tIOyemOuqu+uQnCBGaWVsZEV4cHIgJyR7cHJvcE5hbWV9JyAo7IKs7JqpIOqwgOuKpe2VnCBwcm9wczogJHtlbnRpdHkucHJvcHMubWFwKChwKSA9PiBwLm5hbWUpLmpvaW4oXCIsIFwiKX0pYCxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBub2RlVHlwZTogXCJwbGFpblwiIGFzIGNvbnN0LFxuICAgICAgICAgICAgcHJvcCxcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gcmVsYXRpb24gcHJvcCDsspjrpqxcbiAgICAgIGNvbnN0IHByb3AgPSBlbnRpdHkucHJvcHNEaWN0W2tleV07XG4gICAgICBpZiAoIWlzUmVsYXRpb25Qcm9wKHByb3ApKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihg7J6Y66q765CcIEZpZWxkRXhwciAke2tleX0uJHtncm91cFswXX1gKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlbEVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KHByb3Aud2l0aCk7XG5cbiAgICAgIC8vIHJlbGF0aW9uIC1PbmUg7JeQIGlkIO2VhOuTnCDtlZjrgpjsnbgg6rK97JqwXG4gICAgICBpZiAoaXNCZWxvbmdzVG9PbmVSZWxhdGlvblByb3AocHJvcCkgfHwgaXNPbmVUb09uZVJlbGF0aW9uUHJvcChwcm9wKSkge1xuICAgICAgICBpZiAoZ3JvdXAubGVuZ3RoID09PSAxICYmIChncm91cFswXSA9PT0gXCJpZFwiIHx8IGdyb3VwWzBdID09PSBcImlkP1wiKSkge1xuICAgICAgICAgIC8vIGlkIO2VmOuCmOunjCDsnojripTsp4Ag7LK07YGs7ZW07IScLCDtlZjrgpjrp4wg7J6I7Jy866m0IOyDgeychCBwcm9w7Jy866GcIGlk66W8IOumrO2EtFxuICAgICAgICAgIGNvbnN0IGlkUHJvcCA9IHJlbEVudGl0eS5wcm9wc0RpY3QuaWQ7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5vZGVUeXBlOiBcInBsYWluXCIgYXMgY29uc3QsXG4gICAgICAgICAgICBwcm9wOiB7XG4gICAgICAgICAgICAgIC4uLmlkUHJvcCxcbiAgICAgICAgICAgICAgbmFtZTogYCR7a2V5fV9pZGAsXG4gICAgICAgICAgICAgIG51bGxhYmxlOiBwcm9wLm51bGxhYmxlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIC1PbmUg6re47Jm47J2YIOqyveyasCBvYmplY3TroZwg66as7YS0XG4gICAgICAvLyAtTWFueeydmCDqsr3smrAgYXJyYXnroZwg66as7YS0XG4gICAgICAvLyBSZWN1cnNpdmUg66GcIOuOgeyKpCDsspjrpqxcbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gdGhpcy5maWVsZEV4cHJzVG9Qcm9wTm9kZXMoZ3JvdXAsIHJlbEVudGl0eSk7XG4gICAgICBjb25zdCBub2RlVHlwZSA9XG4gICAgICAgIGlzQmVsb25nc1RvT25lUmVsYXRpb25Qcm9wKHByb3ApIHx8IGlzT25lVG9PbmVSZWxhdGlvblByb3AocHJvcClcbiAgICAgICAgICA/IChcIm9iamVjdFwiIGFzIGNvbnN0KVxuICAgICAgICAgIDogKFwiYXJyYXlcIiBhcyBjb25zdCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5vZGVUeXBlLFxuICAgICAgICBwcm9wLFxuICAgICAgICBjaGlsZHJlbixcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBnZXRGaWVsZEV4cHJzKHByZWZpeCA9IFwiXCIsIG1heERlcHRoOiBudW1iZXIgPSAzLCBmcm9tczogc3RyaW5nW10gPSBbXSk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gdGhpcy5wcm9wc1xuICAgICAgLmZsYXRNYXAoKHByb3ApID0+IHtcbiAgICAgICAgY29uc3QgcHJvcE5hbWUgPSBbcHJlZml4LCBwcm9wLm5hbWVdLmZpbHRlcigodikgPT4gdiAhPT0gXCJcIikuam9pbihcIi5cIik7XG4gICAgICAgIGlmIChwcm9wTmFtZSA9PT0gcHJlZml4KSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzUmVsYXRpb25Qcm9wKHByb3ApKSB7XG4gICAgICAgICAgaWYgKG1heERlcHRoIDwgMCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChmcm9tcy5pbmNsdWRlcyhwcm9wLndpdGgpKSB7XG4gICAgICAgICAgICAvLyDsl63rsKntlqUgcmVsYXRpb27snbgg6rK97JqwIOygnOyZuFxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIOygleuwqe2WpSByZWxhdGlvbuyduCDqsr3smrAgcmVjdXJzaXZlIOy9nFxuICAgICAgICAgIGNvbnN0IHJlbE1kID0gRW50aXR5TWFuYWdlci5nZXQocHJvcC53aXRoKTtcbiAgICAgICAgICByZXR1cm4gcmVsTWQuZ2V0RmllbGRFeHBycyhwcm9wTmFtZSwgbWF4RGVwdGggLSAxLCBbLi4uZnJvbXMsIHRoaXMuaWRdKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcHJvcE5hbWU7XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigoZikgPT4gZiAhPT0gbnVsbCk7XG4gIH1cblxuICAvKipcbiAgICogUmVsYXRpb24gcHJvcOydtCDtmITsnqwg7YWM7J2067iU7JeQIEZLIOy7rOufvOydhCDsg53shLHtlZjripTsp4Ag7ZmV7J24XG4gICAqKEJlbG9uZ3NUb09uZSDrmJDripQgT25lVG9PbmUoaGFzSm9pbkNvbHVtbj10cnVlKeyduCDqsr3smrAgRksg7IOd7ISxKVxuICAgKi9cbiAgcHJpdmF0ZSBoYXNGb3JlaWduS2V5KHByb3A6IFJlbGF0aW9uUHJvcCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICBwcm9wLnJlbGF0aW9uVHlwZSA9PT0gXCJCZWxvbmdzVG9PbmVcIiB8fFxuICAgICAgKHByb3AucmVsYXRpb25UeXBlID09PSBcIk9uZVRvT25lXCIgJiYgcHJvcC5oYXNKb2luQ29sdW1uKVxuICAgICk7XG4gIH1cblxuICBnZXRUYWJsZUNvbHVtbnMoKTogeyBuYW1lOiBzdHJpbmc7IHR5cGU6IHN0cmluZyB9W10ge1xuICAgIHJldHVybiB0aGlzLnByb3BzXG4gICAgICAubWFwKChwcm9wKSA9PiB7XG4gICAgICAgIGlmIChwcm9wLnR5cGUgPT09IFwicmVsYXRpb25cIikge1xuICAgICAgICAgIGlmICh0aGlzLmhhc0ZvcmVpZ25LZXkocHJvcCkpIHtcbiAgICAgICAgICAgIHJldHVybiB7IG5hbWU6IGAke3Byb3AubmFtZX1faWRgLCB0eXBlOiBcImludF91bnNpZ25lZFwiIH07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4geyBuYW1lOiBwcm9wLm5hbWUsIHR5cGU6IHByb3AudHlwZSB9O1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIobm9uTnVsbGFibGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVudGl0eeyXkCDsoJXsnZjrkJwg66qo65OgIHZlY3RvciDtg4DsnoUg7Lus65+8IOuwmO2ZmFxuICAgKi9cbiAgZ2V0VmVjdG9yQ29sdW1ucygpOiBFbnRpdHlQcm9wW10ge1xuICAgIHJldHVybiB0aGlzLnByb3BzLmZpbHRlcigocCkgPT4gcC50eXBlID09PSBcInZlY3RvclwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDtirnsoJUgdmVjdG9yIOy7rOufvCDrsJjtmZhcbiAgICogQHBhcmFtIGNvbHVtbk5hbWUgLSDsu6zrn7zrqoUgKOyDneuetSDsi5wg7LKrIOuyiOynuCB2ZWN0b3Ig7Lus65+8KVxuICAgKi9cbiAgZ2V0VmVjdG9yQ29sdW1uKGNvbHVtbk5hbWU/OiBzdHJpbmcpOiBFbnRpdHlQcm9wIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCB2ZWN0b3JQcm9wcyA9IHRoaXMuZ2V0VmVjdG9yQ29sdW1ucygpO1xuICAgIGlmIChjb2x1bW5OYW1lKSB7XG4gICAgICByZXR1cm4gdmVjdG9yUHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBjb2x1bW5OYW1lKTtcbiAgICB9XG4gICAgcmV0dXJuIHZlY3RvclByb3BzWzBdO1xuICB9XG5cbiAgLyoqXG4gICAqIO2VhO2EsOungSDqsIDriqXtlZwgcHJvcHMg67CY7ZmYXG4gICAqXG4gICAqIC0g7J2867CYIHByb3BcbiAgICogLSBGS+ulvCDsg53shLHtlZjripQgcmVsYXRpb24gKEJlbG9uZ3NUb09uZSwgT25lVG9PbmUgd2l0aCBoYXNKb2luQ29sdW1uKVxuICAgKiAgIOKGkiB7bmFtZX1faWQg7ZiV7YOc7J2YIOqwgOyDgSBpbnRlZ2VyIHByb3DsnLzroZwg67OA7ZmYXG4gICAqL1xuICBnZXRGaWx0ZXJhYmxlUHJvcHMoKTogRW50aXR5UHJvcFtdIHtcbiAgICByZXR1cm4gdGhpcy5wcm9wcy5mbGF0TWFwKChwcm9wKTogRW50aXR5UHJvcCB8IEVudGl0eVByb3BbXSA9PiB7XG4gICAgICAvLyBWaXJ0dWFsIHByb3Ag7KCc7Jm4XG4gICAgICBpZiAoaXNWaXJ0dWFsUHJvcChwcm9wKSkge1xuICAgICAgICByZXR1cm4gW107XG4gICAgICB9XG5cbiAgICAgIC8vIFJlbGF0aW9uIHByb3Ag7LKY66asXG4gICAgICBpZiAoaXNSZWxhdGlvblByb3AocHJvcCkpIHtcbiAgICAgICAgLy8gRkvrpbwg7IOd7ISx7ZWY64qUIHJlbGF0aW9u66eMIO2PrO2VqFxuICAgICAgICBpZiAodGhpcy5oYXNGb3JlaWduS2V5KHByb3ApKSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIG5hbWU6IGAke3Byb3AubmFtZX1faWRgLFxuICAgICAgICAgICAgdHlwZTogXCJpbnRlZ2VyXCIsXG4gICAgICAgICAgICBudWxsYWJsZTogcHJvcC5udWxsYWJsZSxcbiAgICAgICAgICB9IGFzIEVudGl0eVByb3A7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgfVxuXG4gICAgICAvLyDsnbzrsJggcHJvcCDsspjrpqxcbiAgICAgIHJldHVybiBwcm9wO1xuICAgIH0pO1xuICB9XG5cbiAgYXN5bmMgcmVnaXN0ZXJNb2R1bGVQYXRocygpIHtcbiAgICBjb25zdCBiYXNlUGF0aCA9IGAke3RoaXMubmFtZXMucGFyZW50RnN9YDtcblxuICAgIC8vIGJhc2Utc2NoZW1lXG4gICAgRW50aXR5TWFuYWdlci5zZXRNb2R1bGVQYXRoKGAke3RoaXMuaWR9QmFzZVNjaGVtYWAsIGBzb25hbXUuZ2VuZXJhdGVkYCk7XG5cbiAgICAvLyBzdWJzZXRcbiAgICBpZiAoT2JqZWN0LmtleXModGhpcy5zdWJzZXRzKS5sZW5ndGggPiAwKSB7XG4gICAgICBFbnRpdHlNYW5hZ2VyLnNldE1vZHVsZVBhdGgoYCR7dGhpcy5pZH1TdWJzZXRLZXlgLCBgc29uYW11LmdlbmVyYXRlZGApO1xuICAgICAgRW50aXR5TWFuYWdlci5zZXRNb2R1bGVQYXRoKGAke3RoaXMuaWR9U3Vic2V0TWFwcGluZ2AsIGBzb25hbXUuZ2VuZXJhdGVkYCk7XG4gICAgICBmb3IgKGNvbnN0IHN1YnNldEtleSBvZiBPYmplY3Qua2V5cyh0aGlzLnN1YnNldHMpKSB7XG4gICAgICAgIEVudGl0eU1hbmFnZXIuc2V0TW9kdWxlUGF0aChcbiAgICAgICAgICBgJHt0aGlzLmlkfVN1YnNldCR7c3Vic2V0S2V5LnRvVXBwZXJDYXNlKCl9YCxcbiAgICAgICAgICBgc29uYW11LmdlbmVyYXRlZGAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gZW51bXNcbiAgICBmb3IgKGNvbnN0IGVudW1JZCBvZiBPYmplY3Qua2V5cyh0aGlzLmVudW1MYWJlbHMpKSB7XG4gICAgICBFbnRpdHlNYW5hZ2VyLnNldE1vZHVsZVBhdGgoZW51bUlkLCBgc29uYW11LmdlbmVyYXRlZGApO1xuICAgIH1cblxuICAgIC8vIHR5cGVzXG4gICAgY29uc3QgdHlwZXNNb2R1bGVQYXRoID0gYCR7YmFzZVBhdGh9LyR7dGhpcy5uYW1lcy5wYXJlbnRGc30udHlwZXNgO1xuICAgIGNvbnN0IHR5cGVzRmlsZVBhdGggPSBwYXRoLmpvaW4oXG4gICAgICBTb25hbXUuYXBpUm9vdFBhdGgsXG4gICAgICBydW50aW1lUGF0aChgZGlzdC9hcHBsaWNhdGlvbi8ke3R5cGVzTW9kdWxlUGF0aH0uanNgKSxcbiAgICApO1xuXG4gICAgaWYgKGF3YWl0IGV4aXN0cyh0eXBlc0ZpbGVQYXRoKSkge1xuICAgICAgY29uc3QgaW1wb3J0ZWRNZW1iZXJzID0gYXdhaXQgaW1wb3J0TWVtYmVyczx6LlpvZFR5cGVBbnk+KHR5cGVzRmlsZVBhdGgpO1xuICAgICAgdGhpcy50eXBlcyA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgaW1wb3J0ZWRNZW1iZXJzLm1hcCgoeyBuYW1lLCB2YWx1ZSB9KSA9PiB7XG4gICAgICAgICAgRW50aXR5TWFuYWdlci5zZXRNb2R1bGVQYXRoKG5hbWUsIHR5cGVzTW9kdWxlUGF0aCk7XG4gICAgICAgICAgcmV0dXJuIFtuYW1lLCB2YWx1ZV07XG4gICAgICAgIH0pLFxuICAgICAgKSBhcyB7IFtuYW1lOiBzdHJpbmddOiB6LlpvZFR5cGVBbnkgfTtcbiAgICB9XG4gIH1cblxuICByZWdpc3RlclRhYmxlU3BlY3MoKTogdm9pZCB7XG4gICAgLy8g7KGw7J24IO2FjOydtOu4lCDsnbjrjbHsiqQg7KCc7Jm4ICjsu6zrn7wg7J2066aE7JeQICcuJ+ydtCDtj6ztlajrkJwg6rK97JqwKVxuICAgIGNvbnN0IHVuaXF1ZUluZGV4ZXMgPSB0aGlzLmluZGV4ZXNcbiAgICAgIC5maWx0ZXIoKGlkeCkgPT4gaWR4LnR5cGUgPT09IFwidW5pcXVlXCIpXG4gICAgICAuZmlsdGVyKChpZHgpID0+IGlkeC5jb2x1bW5zLmV2ZXJ5KChjb2wpID0+ICFjb2wubmFtZS5pbmNsdWRlcyhcIi5cIikpKTtcblxuICAgIEVudGl0eU1hbmFnZXIuc2V0VGFibGVTcGVjKHtcbiAgICAgIG5hbWU6IHRoaXMudGFibGUsXG4gICAgICB1bmlxdWVJbmRleGVzLFxuICAgICAganNvbkNvbHVtbnM6IHRoaXMucHJvcHMuZmlsdGVyKChwKSA9PiBwLnR5cGUgPT09IFwianNvblwiKS5tYXAoKHApID0+IHAubmFtZSksXG4gICAgfSk7XG4gIH1cblxuICB0b0pzb24oKTogRW50aXR5SnNvbiB7XG4gICAgLy8gc3Vic2V0c+yZgCBzdWJzZXRzSW50ZXJuYWzsnYQgU3Vic2V0RGVmIO2Yle2DnOuhnCDrs7Xsm5AgKGNvbmUg7Y+s7ZWoKVxuICAgIGNvbnN0IHN1YnNldHM6IHsgW2tleTogc3RyaW5nXTogaW1wb3J0KFwiLi4vdHlwZXMvdHlwZXNcIikuU3Vic2V0RGVmIH0gPSB7fTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyh0aGlzLnN1YnNldHMpKSB7XG4gICAgICBjb25zdCBub3JtYWxGaWVsZHM6IFN1YnNldEZpZWxkW10gPSB0aGlzLnN1YnNldHNba2V5XTtcbiAgICAgIGNvbnN0IGludGVybmFsRmllbGRzOiBTdWJzZXRGaWVsZFtdID0gKHRoaXMuc3Vic2V0c0ludGVybmFsW2tleV0gPz8gW10pLm1hcCgoZmllbGQpID0+ICh7XG4gICAgICAgIGZpZWxkLFxuICAgICAgICBpbnRlcm5hbDogdHJ1ZSxcbiAgICAgIH0pKTtcbiAgICAgIGNvbnN0IGZpZWxkcyA9IFsuLi5ub3JtYWxGaWVsZHMsIC4uLmludGVybmFsRmllbGRzXTtcblxuICAgICAgLy8gY29uZeydtCDsnojsnLzrqbQg7IOI66Gc7Jq0IOqwneyytCDtmJXtg5zroZwsIOyXhuycvOuptCDrsLDsl7Qg7ZiV7YOc66GcXG4gICAgICBpZiAodGhpcy5zdWJzZXRDb25lc1trZXldKSB7XG4gICAgICAgIHN1YnNldHNba2V5XSA9IHtcbiAgICAgICAgICBmaWVsZHMsXG4gICAgICAgICAgY29uZTogdGhpcy5zdWJzZXRDb25lc1trZXldLFxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3Vic2V0c1trZXldID0gZmllbGRzO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGVudW1z66W8IEVudW1EZWYg7ZiV7YOc66GcIOuzteybkCAoY29uZSDtj6ztlagpXG4gICAgY29uc3QgZW51bXM6IHsgW2tleTogc3RyaW5nXTogaW1wb3J0KFwiLi4vdHlwZXMvdHlwZXNcIikuRW51bURlZiB9ID0ge307XG4gICAgZm9yIChjb25zdCBba2V5LCB2YWx1ZXNdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuZW51bUxhYmVscykpIHtcbiAgICAgIC8vIGNvbmXsnbQg7J6I7Jy866m0IOyDiOuhnOyatCDqsJ3ssrQg7ZiV7YOc66GcLCDsl4bsnLzrqbQgUmVjb3JkIO2Yle2DnOuhnFxuICAgICAgaWYgKHRoaXMuZW51bUNvbmVzW2tleV0pIHtcbiAgICAgICAgZW51bXNba2V5XSA9IHtcbiAgICAgICAgICB2YWx1ZXMsXG4gICAgICAgICAgY29uZTogdGhpcy5lbnVtQ29uZXNba2V5XSxcbiAgICAgICAgfTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVudW1zW2tleV0gPSB2YWx1ZXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiB0aGlzLmlkLFxuICAgICAgcGFyZW50SWQ6IHRoaXMucGFyZW50SWQsXG4gICAgICB0YWJsZTogdGhpcy50YWJsZSxcbiAgICAgIHRpdGxlOiB0aGlzLnRpdGxlLFxuICAgICAgY29uZTogdGhpcy5jb25lLFxuICAgICAgcHJvcHM6IHRoaXMucHJvcHMsXG4gICAgICBpbmRleGVzOiB0aGlzLmluZGV4ZXMsXG4gICAgICBzdWJzZXRzLFxuICAgICAgZW51bXMsXG4gICAgfTtcbiAgfVxuXG4gIGFzeW5jIHNhdmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gc29ydDogc3Vic2V0c1xuICAgIGNvbnN0IHN1YnNldFJvd3MgPSB0aGlzLmdldFN1YnNldFJvd3MoKTtcbiAgICB0aGlzLnN1YnNldHMgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyh0aGlzLnN1YnNldHMpLm1hcCgoW3N1YnNldEtleV0pID0+IHtcbiAgICAgICAgcmV0dXJuIFtzdWJzZXRLZXksIHRoaXMuc3Vic2V0Um93c1RvU3Vic2V0RmllbGRzKHN1YnNldFJvd3MsIHN1YnNldEtleSwgZmFsc2UpXTtcbiAgICAgIH0pLFxuICAgICk7XG4gICAgdGhpcy5zdWJzZXRzSW50ZXJuYWwgPSBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBPYmplY3QuZW50cmllcyh0aGlzLnN1YnNldHNJbnRlcm5hbCkubWFwKChbc3Vic2V0S2V5XSkgPT4ge1xuICAgICAgICByZXR1cm4gW3N1YnNldEtleSwgdGhpcy5zdWJzZXRSb3dzVG9TdWJzZXRGaWVsZHMoc3Vic2V0Um93cywgc3Vic2V0S2V5LCB0cnVlKV07XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgLy8gc2F2ZVxuICAgIGNvbnN0IGpzb25QYXRoID0gcGF0aC5qb2luKFxuICAgICAgU29uYW11LmFwaVJvb3RQYXRoLFxuICAgICAgYHNyYy9hcHBsaWNhdGlvbi8ke3RoaXMubmFtZXMucGFyZW50RnN9LyR7dGhpcy5uYW1lcy5mc30uZW50aXR5Lmpzb25gLFxuICAgICk7XG4gICAgY29uc3QganNvbiA9IHRoaXMudG9Kc29uKCk7XG4gICAgYXdhaXQgd3JpdGVGaWxlKGpzb25QYXRoLCBhd2FpdCBmb3JtYXRDb2RlKEpTT04uc3RyaW5naWZ5KGpzb24pLCBcImpzb25cIiwganNvblBhdGgpKTtcblxuICAgIC8vIHJlbG9hZFxuICAgIGF3YWl0IEVudGl0eU1hbmFnZXIucmVnaXN0ZXIoanNvbik7XG4gIH1cblxuICAvKipcbiAgICog7YWc7ZSM66a/IGNvbmUg66mU7YOA642w7J207YSw66W8IOyDneyEse2VqeuLiOuLpC5cbiAgICpcbiAgICogTExN7J2EIOyCrOyaqe2VmOyngCDslYrqs6AgZmFrZXItbWFwcGluZ3MudHPrpbwg7Zmc7Jqp7ZWY7JesIOq4sOuzuCBjb25l7J2EIOyDneyEse2VqeuLiOuLpC5cbiAgICogc3R1YiBlbnRpdHkg7IOd7ISxIOyLnCDsnpDrj5nsnLzroZwg7Zi47Lac65CY7Ja0IOy1nOyGjO2VnOydmCBjb25lIOuplO2DgOuNsOydtO2EsOulvCDsoJzqs7Xtlanri4jri6QuXG4gICAqXG4gICAqIEBwYXJhbSBsb2NhbGUgLSDsg53shLEg7IucIOyCrOyaqe2VoCBsb2NhbGUgKOq4sOuzuOqwkjogU29uYW11LmNvbmZpZy5pMThuLmRlZmF1bHRMb2NhbGUg65iQ64qUIFwia29cIilcbiAgICovXG4gIGFzeW5jIGdlbmVyYXRlVGVtcGxhdGVDb25lcyhsb2NhbGU/OiBcImtvXCIgfCBcImVuXCIgfCBcImphXCIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IGdlbmVyYXRlVGVtcGxhdGVDb25lcyB9ID0gYXdhaXQgaW1wb3J0KFwiLi9lbnRpdHktdGVtcGxhdGUtY29uZVwiKTtcbiAgICBjb25zdCBjb25maWdMb2NhbGUgPSBTb25hbXUuY29uZmlnLmkxOG4/LmRlZmF1bHRMb2NhbGU7XG4gICAgY29uc3QgZWZmZWN0aXZlTG9jYWxlID1cbiAgICAgIGxvY2FsZSB8fFxuICAgICAgKGNvbmZpZ0xvY2FsZSA9PT0gXCJrb1wiIHx8IGNvbmZpZ0xvY2FsZSA9PT0gXCJlblwiIHx8IGNvbmZpZ0xvY2FsZSA9PT0gXCJqYVwiXG4gICAgICAgID8gY29uZmlnTG9jYWxlXG4gICAgICAgIDogXCJrb1wiKTtcbiAgICBjb25zdCByZXN1bHQgPSBnZW5lcmF0ZVRlbXBsYXRlQ29uZXModGhpcy50b0pzb24oKSwgZWZmZWN0aXZlTG9jYWxlKTtcblxuICAgIC8vIOqysOqzvOulvCBFbnRpdHnsl5Ag7KCB7JqpIChhcHBseUNvbmVz7JmAIOuPmeydvO2VnCDrsKnsi50pXG4gICAgaWYgKHJlc3VsdC5lbnRpdHlDb25lKSB7XG4gICAgICB0aGlzLmNvbmUgPSByZXN1bHQuZW50aXR5Q29uZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtwcm9wTmFtZSwgY29uZV0gb2YgT2JqZWN0LmVudHJpZXMocmVzdWx0LnByb3BDb25lcykpIHtcbiAgICAgIGNvbnN0IHByb3AgPSB0aGlzLnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gcHJvcE5hbWUpO1xuICAgICAgaWYgKHByb3ApIHtcbiAgICAgICAgKHByb3AgYXMgeyBjb25lPzogQ29uZSB9KS5jb25lID0gY29uZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmVudW1Db25lcyA9IHsgLi4udGhpcy5lbnVtQ29uZXMsIC4uLnJlc3VsdC5lbnVtQ29uZXMgfTtcbiAgICB0aGlzLnN1YnNldENvbmVzID0geyAuLi50aGlzLnN1YnNldENvbmVzLCAuLi5yZXN1bHQuc3Vic2V0Q29uZXMgfTtcblxuICAgIGF3YWl0IHRoaXMuc2F2ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIExMTeydhCDsgqzsmqntlZjsl6wgY29uZSDrqZTtg4DrjbDsnbTthLDrpbwg7IOd7ISx7ZWp64uI64ukLlxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucy5wcmVzZXJ2ZUV4aXN0aW5nIC0g6riw7KG0IGNvbmUg67O07KG0IOyXrOu2gCAo6riw67O46rCSOiB0cnVlKVxuICAgKiBAcGFyYW0gb3B0aW9ucy5vbmx5RW1wdHkgLSBmaXh0dXJlSGludOqwgCDsl4bripQgY29uZeunjCDsg53shLEgKOq4sOuzuOqwkjogZmFsc2UpXG4gICAqIEBwYXJhbSBvcHRpb25zLmxvY2FsZSAtIOyDneyEsSDsi5wg7IKs7Jqp7ZWgIGxvY2FsZSAo6riw67O46rCSOiBcImtvXCIpXG4gICAqL1xuICBhc3luYyBnZW5lcmF0ZUNvbmVzKG9wdGlvbnM/OiB7XG4gICAgcHJlc2VydmVFeGlzdGluZz86IGJvb2xlYW47XG4gICAgb25seUVtcHR5PzogYm9vbGVhbjtcbiAgICBsb2NhbGU/OiBcImtvXCIgfCBcImVuXCIgfCBcImphXCI7XG4gIH0pOiBQcm9taXNlPGltcG9ydChcIi4uL2NvbmUvY29uZS1nZW5lcmF0b3JcIikuQ29uZUdlbmVyYXRpb25SZXN1bHQ+IHtcbiAgICBjb25zdCB7IGdlbmVyYXRlQ29uZXMgfSA9IGF3YWl0IGltcG9ydChcIi4uL2NvbmUvY29uZS1nZW5lcmF0b3JcIik7XG4gICAgY29uc3QgY29udGV4dDogaW1wb3J0KFwiLi4vY29uZS9jb25lLWdlbmVyYXRvclwiKS5Db25lR2VuZXJhdGlvbkNvbnRleHQgPSB7XG4gICAgICBlbnRpdHk6IHRoaXMudG9Kc29uKCksXG4gICAgICBsb2NhbGU6IG9wdGlvbnM/LmxvY2FsZSB8fCBcImtvXCIsXG4gICAgICBleGlzdGluZ0NvbmVzOiBvcHRpb25zPy5wcmVzZXJ2ZUV4aXN0aW5nICE9PSBmYWxzZSA/IHRoaXMuY29sbGVjdEV4aXN0aW5nQ29uZXMoKSA6IHVuZGVmaW5lZCxcbiAgICAgIG9ubHlFbXB0eTogb3B0aW9ucz8ub25seUVtcHR5ID8/IGZhbHNlLFxuICAgIH07XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBnZW5lcmF0ZUNvbmVzKGNvbnRleHQpO1xuICAgIHRoaXMuYXBwbHlDb25lcyhyZXN1bHQpO1xuICAgIGF3YWl0IHRoaXMuc2F2ZSgpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICog6riw7KG0IGNvbmXrk6TsnYQg7IiY7KeR7ZWp64uI64ukIChlbnRpdHksIHByb3BzLCBlbnVtcywgc3Vic2V0cykuXG4gICAqXG4gICAqIEByZXR1cm5zIO2CpOqwgCBcImVudGl0eTppZFwiLCBcInByb3A6bmFtZVwiLCBcImVudW06ZW51bUlkXCIsIFwic3Vic2V0OmtleVwiIO2YleyLneyduCBjb25lIOuntVxuICAgKi9cbiAgcHJpdmF0ZSBjb2xsZWN0RXhpc3RpbmdDb25lcygpOiBSZWNvcmQ8c3RyaW5nLCBDb25lPiB7XG4gICAgY29uc3QgY29uZXM6IFJlY29yZDxzdHJpbmcsIENvbmU+ID0ge307XG5cbiAgICBpZiAodGhpcy5jb25lKSB7XG4gICAgICBjb25lc1tgZW50aXR5OiR7dGhpcy5pZH1gXSA9IHRoaXMuY29uZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHByb3Agb2YgdGhpcy5wcm9wcykge1xuICAgICAgaWYgKHByb3AuY29uZSkge1xuICAgICAgICBjb25lc1tgcHJvcDoke3Byb3AubmFtZX1gXSA9IHByb3AuY29uZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtlbnVtSWQsIGNvbmVdIG9mIE9iamVjdC5lbnRyaWVzKHRoaXMuZW51bUNvbmVzKSkge1xuICAgICAgY29uZXNbYGVudW06JHtlbnVtSWR9YF0gPSBjb25lO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgW3N1YnNldEtleSwgY29uZV0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5zdWJzZXRDb25lcykpIHtcbiAgICAgIGNvbmVzW2BzdWJzZXQ6JHtzdWJzZXRLZXl9YF0gPSBjb25lO1xuICAgIH1cblxuICAgIHJldHVybiBjb25lcztcbiAgfVxuXG4gIC8qKlxuICAgKiDsg53shLHrkJwgY29uZeuTpOydhCBFbnRpdHnsl5Ag7KCB7Jqp7ZWp64uI64ukLlxuICAgKlxuICAgKiBAcGFyYW0gcmVzdWx0IC0gTExN7Jy866GcIOyDneyEseuQnCBjb25lIOqysOqzvFxuICAgKi9cbiAgcHJpdmF0ZSBhcHBseUNvbmVzKHJlc3VsdDogaW1wb3J0KFwiLi4vY29uZS9jb25lLWdlbmVyYXRvclwiKS5Db25lR2VuZXJhdGlvblJlc3VsdCk6IHZvaWQge1xuICAgIGlmIChyZXN1bHQuZW50aXR5Q29uZSkge1xuICAgICAgdGhpcy5jb25lID0gcmVzdWx0LmVudGl0eUNvbmU7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbcHJvcE5hbWUsIGNvbmVdIG9mIE9iamVjdC5lbnRyaWVzKHJlc3VsdC5wcm9wQ29uZXMpKSB7XG4gICAgICBjb25zdCBwcm9wID0gdGhpcy5wcm9wcy5maW5kKChwKSA9PiBwLm5hbWUgPT09IHByb3BOYW1lKTtcbiAgICAgIGlmIChwcm9wKSB7XG4gICAgICAgIChwcm9wIGFzIHsgY29uZT86IENvbmUgfSkuY29uZSA9IGNvbmU7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5lbnVtQ29uZXMgPSB7IC4uLnRoaXMuZW51bUNvbmVzLCAuLi5yZXN1bHQuZW51bUNvbmVzIH07XG4gICAgdGhpcy5zdWJzZXRDb25lcyA9IHsgLi4udGhpcy5zdWJzZXRDb25lcywgLi4ucmVzdWx0LnN1YnNldENvbmVzIH07XG4gIH1cblxuICBnZXRTdWJzZXRSb3dzKFxuICAgIF9zdWJzZXRzPzogeyBba2V5OiBzdHJpbmddOiBzdHJpbmdbXSB9LFxuICAgIF9zdWJzZXRzSW50ZXJuYWw/OiB7IFtrZXk6IHN0cmluZ106IHN0cmluZ1tdIH0sXG4gICAgcHJlZml4ZXM6IHN0cmluZ1tdID0gW10sXG4gICk6IEVudGl0eVN1YnNldFJvd1tdIHtcbiAgICBpZiAocHJlZml4ZXMubGVuZ3RoID4gMTApIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBzdWJzZXRzID0gX3N1YnNldHMgPz8gdGhpcy5zdWJzZXRzO1xuICAgIGNvbnN0IHN1YnNldHNJbnRlcm5hbCA9IF9zdWJzZXRzSW50ZXJuYWwgPz8gdGhpcy5zdWJzZXRzSW50ZXJuYWw7XG4gICAgY29uc3Qgc3Vic2V0S2V5cyA9IE9iamVjdC5rZXlzKHN1YnNldHMpO1xuICAgIGNvbnN0IGFsbEZpZWxkcyA9IHVuaXF1ZShzdWJzZXRLZXlzLmZsYXRNYXAoKGtleSkgPT4gc3Vic2V0c1trZXldKSk7XG4gICAgLy8gaW50ZXJuYWwg7ZWE65Oc64+EIGFsbEZpZWxkc+yXkCDtj6ztlaggKHJlbGF0aW9uIO2DkOyDieyaqSlcbiAgICBjb25zdCBhbGxJbnRlcm5hbEZpZWxkcyA9IHVuaXF1ZShzdWJzZXRLZXlzLmZsYXRNYXAoKGtleSkgPT4gc3Vic2V0c0ludGVybmFsW2tleV0gPz8gW10pKTtcbiAgICBjb25zdCBjb21iaW5lZEZpZWxkcyA9IHVuaXF1ZShbLi4uYWxsRmllbGRzLCAuLi5hbGxJbnRlcm5hbEZpZWxkc10pO1xuXG4gICAgcmV0dXJuIHRoaXMucHJvcHMubWFwKChwcm9wKSA9PiB7XG4gICAgICBpZiAoXG4gICAgICAgIHByb3AudHlwZSA9PT0gXCJyZWxhdGlvblwiICYmXG4gICAgICAgIGNvbWJpbmVkRmllbGRzLmZpbmQoKGYpID0+IGYuc3RhcnRzV2l0aChgJHtbLi4ucHJlZml4ZXMsIHByb3AubmFtZV0uam9pbihcIi5cIil9LmApKVxuICAgICAgKSB7XG4gICAgICAgIGNvbnN0IHJlbEVudGl0eSA9IEVudGl0eU1hbmFnZXIuZ2V0KHByb3Aud2l0aCk7XG4gICAgICAgIGNvbnN0IGNoaWxkcmVuID0gcmVsRW50aXR5LmdldFN1YnNldFJvd3Moc3Vic2V0cywgc3Vic2V0c0ludGVybmFsLCBbXG4gICAgICAgICAgLi4ucHJlZml4ZXMsXG4gICAgICAgICAgYCR7cHJvcC5uYW1lfWAsXG4gICAgICAgIF0pO1xuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZmllbGQ6IHByb3AubmFtZSxcbiAgICAgICAgICBjaGlsZHJlbixcbiAgICAgICAgICByZWxhdGlvbkVudGl0eTogcHJvcC53aXRoLFxuICAgICAgICAgIHByZWZpeGVzLFxuICAgICAgICAgIGlzT3BlbjogY2hpbGRyZW4ubGVuZ3RoID4gMCxcbiAgICAgICAgICBoYXM6IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgICAgIHN1YnNldEtleXMubWFwKChzdWJzZXRLZXkpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIFtzdWJzZXRLZXksIGNoaWxkcmVuLmV2ZXJ5KChjaGlsZCkgPT4gY2hpbGQuaGFzW3N1YnNldEtleV0pXTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICksXG4gICAgICAgICAgaXNJbnRlcm5hbDogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgICAgICAgc3Vic2V0S2V5cy5tYXAoKHN1YnNldEtleSkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gW3N1YnNldEtleSwgY2hpbGRyZW4uZXZlcnkoKGNoaWxkKSA9PiBjaGlsZC5pc0ludGVybmFsW3N1YnNldEtleV0pXTtcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICksXG4gICAgICAgIH07XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZpZWxkID0gWy4uLnByZWZpeGVzLCBwcm9wLm5hbWVdLmpvaW4oXCIuXCIpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZmllbGQ6IHByb3AubmFtZSxcbiAgICAgICAgY2hpbGRyZW46IFtdLFxuICAgICAgICByZWxhdGlvbkVudGl0eTogcHJvcC50eXBlID09PSBcInJlbGF0aW9uXCIgPyBwcm9wLndpdGggOiB1bmRlZmluZWQsXG4gICAgICAgIHByZWZpeGVzLFxuICAgICAgICBoYXM6IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgICBzdWJzZXRLZXlzLm1hcCgoc3Vic2V0S2V5KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzdWJzZXRGaWVsZHMgPSBzdWJzZXRzW3N1YnNldEtleV07XG4gICAgICAgICAgICBjb25zdCBoYXMgPSBzdWJzZXRGaWVsZHMuc29tZSgoZikgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gZiA9PT0gZmllbGQgfHwgZi5zdGFydHNXaXRoKGAke2ZpZWxkfS5gKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIFtzdWJzZXRLZXksIGhhc107XG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICAgIGlzSW50ZXJuYWw6IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgICBzdWJzZXRLZXlzLm1hcCgoc3Vic2V0S2V5KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbnRlcm5hbEZpZWxkcyA9IHN1YnNldHNJbnRlcm5hbFtzdWJzZXRLZXldID8/IFtdO1xuICAgICAgICAgICAgY29uc3QgaXNJbnRlcm5hbCA9IGludGVybmFsRmllbGRzLnNvbWUoKGYpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIGYgPT09IGZpZWxkIHx8IGYuc3RhcnRzV2l0aChgJHtmaWVsZH0uYCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJldHVybiBbc3Vic2V0S2V5LCBpc0ludGVybmFsXTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgKSxcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBzdWJzZXRSb3dzVG9TdWJzZXRGaWVsZHMoXG4gICAgc3Vic2V0Um93czogRW50aXR5U3Vic2V0Um93W10sXG4gICAgc3Vic2V0S2V5OiBzdHJpbmcsXG4gICAgaW50ZXJuYWw6IGJvb2xlYW4gPSBmYWxzZSxcbiAgKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGhhc0tleSA9IGludGVybmFsID8gXCJpc0ludGVybmFsXCIgOiBcImhhc1wiO1xuICAgIHJldHVybiBzdWJzZXRSb3dzXG4gICAgICAubWFwKChzdWJzZXRSb3cpID0+IHtcbiAgICAgICAgaWYgKHN1YnNldFJvdy5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuc3Vic2V0Um93c1RvU3Vic2V0RmllbGRzKHN1YnNldFJvdy5jaGlsZHJlbiwgc3Vic2V0S2V5LCBpbnRlcm5hbCk7XG4gICAgICAgIH0gZWxzZSBpZiAoc3Vic2V0Um93W2hhc0tleV1bc3Vic2V0S2V5XSkge1xuICAgICAgICAgIHJldHVybiBzdWJzZXRSb3cucHJlZml4ZXMuY29uY2F0KHN1YnNldFJvdy5maWVsZCkuam9pbihcIi5cIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgICAuZmlsdGVyKG5vbk51bGxhYmxlKVxuICAgICAgLmZsYXQoKTtcbiAgfVxuXG4gIGFzeW5jIGNyZWF0ZVByb3AocHJvcDogRW50aXR5UHJvcCwgYXQ/OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIWF0KSB7XG4gICAgICB0aGlzLnByb3BzLnB1c2gocHJvcCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHJvcHMuc3BsaWNlKGF0LCAwLCBwcm9wKTtcbiAgICB9XG4gICAgYXdhaXQgdGhpcy5zYXZlKCk7XG4gIH1cblxuICBhbmFseXplU3Vic2V0RmllbGQoc3Vic2V0RmllbGQ6IHN0cmluZyk6IHtcbiAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgIHByb3BOYW1lOiBzdHJpbmc7XG4gIH1bXSB7XG4gICAgY29uc3QgYXJyID0gc3Vic2V0RmllbGQuc3BsaXQoXCIuXCIpO1xuXG4gICAgbGV0IGVudGl0eUlkID0gdGhpcy5pZDtcbiAgICBjb25zdCByZXN1bHQ6IHtcbiAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICBwcm9wTmFtZTogc3RyaW5nO1xuICAgIH1bXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBwcm9wTmFtZSA9IGFycltpXTtcbiAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgZW50aXR5SWQsXG4gICAgICAgIHByb3BOYW1lLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHByb3AgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCkucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBwcm9wTmFtZSk7XG4gICAgICBpZiAoIXByb3ApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2VudGl0eUlkfeydmCDsnpjrqrvrkJwg7ISc67iM7IWL7YKkICR7c3Vic2V0RmllbGR9YCk7XG4gICAgICB9XG4gICAgICBpZiAoaXNSZWxhdGlvblByb3AocHJvcCkpIHtcbiAgICAgICAgZW50aXR5SWQgPSBwcm9wLndpdGg7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBhc3luYyBtb2RpZnlQcm9wKG5ld1Byb3A6IEVudGl0eVByb3AsIGF0OiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAvLyDsnbTsoIQg7ZSE66GtIOydtOumhCDsoIDsnqVcbiAgICBjb25zdCBvbGROYW1lID0gdGhpcy5wcm9wc1thdF0ubmFtZTtcblxuICAgIC8vIOyggOyepe2VoCDsl5Tti7Dti7BcbiAgICBjb25zdCBlbnRpdGllczogRW50aXR5W10gPSBbdGhpc107XG5cbiAgICAvLyDsnbTrpoTsnbQg67CU64CQIOqyveyasFxuICAgIGlmIChvbGROYW1lICE9PSBuZXdQcm9wLm5hbWUpIHtcbiAgICAgIC8vIOyghOyytCDsl5Tti7Dti7Dsl5DshJwg7ZiE7J6sIOyImOygleuQnCDtlITroa3snYQg7LC47KGw7ZWY6rOgIOyeiOuKlCDrqqjrk6Ag7ISc67iM7IWL7ZWE65OcIOywvuyVhOyEnCDsiJjsoJVcbiAgICAgIGNvbnN0IGFsbEVudGl0eUlkcyA9IEVudGl0eU1hbmFnZXIuZ2V0QWxsSWRzKCk7XG4gICAgICBmb3IgKGNvbnN0IHJlbEVudGl0eUlkIG9mIGFsbEVudGl0eUlkcykge1xuICAgICAgICBjb25zdCByZWxFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChyZWxFbnRpdHlJZCk7XG4gICAgICAgIGNvbnN0IHJlbEVudGl0eVN1YnNldEtleXMgPSBPYmplY3Qua2V5cyhyZWxFbnRpdHkuc3Vic2V0cyk7XG4gICAgICAgIGZvciAoY29uc3Qgc3Vic2V0S2V5IG9mIHJlbEVudGl0eVN1YnNldEtleXMpIHtcbiAgICAgICAgICBjb25zdCBzdWJzZXQgPSByZWxFbnRpdHkuc3Vic2V0c1tzdWJzZXRLZXldO1xuXG4gICAgICAgICAgLy8g7ISc67iM7IWLIO2VhOuTnOulvCDsiJztmoztlZjrqbAsIOyXlO2LsO2LsC3tlITroa0g64uo7JyE66GcIOu2hOyEne2VnCDtm4Qg7ZiE7J6sIOyXlO2LsO2LsC3tlITroa3qs7wg7J287LmY7ZWY64qUIOqyveyasCDsiJjsoJUg7LKY66asXG4gICAgICAgICAgY29uc3QgbW9kaWZpZWRTdWJzZXRGaWVsZHMgPSBzdWJzZXQubWFwKChzdWJzZXRGaWVsZCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYW5hbHl6ZWQgPSByZWxFbnRpdHkuYW5hbHl6ZVN1YnNldEZpZWxkKHN1YnNldEZpZWxkKTtcbiAgICAgICAgICAgIGNvbnN0IG1vZGlmaWVkID0gYW5hbHl6ZWQubWFwKChhKSA9PlxuICAgICAgICAgICAgICBhLnByb3BOYW1lID09PSBvbGROYW1lICYmIGEuZW50aXR5SWQgPT09IHRoaXMuaWRcbiAgICAgICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uYSxcbiAgICAgICAgICAgICAgICAgICAgcHJvcE5hbWU6IG5ld1Byb3AubmFtZSxcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA6IGEsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgLy8g67aE7ISd7ZWcIO2VhOuTnOulvCDri6Tsi5wg7ISc67iM7IWLIO2VhOuTnOuhnCDrs7XqtaxcbiAgICAgICAgICAgIHJldHVybiBtb2RpZmllZC5tYXAoKGEpID0+IGEucHJvcE5hbWUpLmpvaW4oXCIuXCIpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgaWYgKHN1YnNldC5qb2luKFwiLFwiKSAhPT0gbW9kaWZpZWRTdWJzZXRGaWVsZHMuam9pbihcIixcIikpIHtcbiAgICAgICAgICAgIHJlbEVudGl0eS5zdWJzZXRzW3N1YnNldEtleV0gPSBtb2RpZmllZFN1YnNldEZpZWxkcztcbiAgICAgICAgICAgIGVudGl0aWVzLnB1c2gocmVsRW50aXR5KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyDtlITroa0g7IiY7KCVXG4gICAgdGhpcy5wcm9wc1thdF0gPSBuZXdQcm9wO1xuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoZW50aXRpZXMubWFwKGFzeW5jIChlbnRpdHkpID0+IGVudGl0eS5zYXZlKCkpKTtcbiAgfVxuXG4gIGFzeW5jIGRlbFByb3AoYXQ6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIC8vIOydtOyghCDtlITroa0g7J2066aEIOyggOyepVxuICAgIGNvbnN0IG9sZE5hbWUgPSB0aGlzLnByb3BzW2F0XS5uYW1lO1xuXG4gICAgLy8g7KCA7J6l7ZWgIOyXlO2LsO2LsFxuICAgIGNvbnN0IGVudGl0aWVzOiBFbnRpdHlbXSA9IFt0aGlzXTtcblxuICAgIC8vIOyghOyytCDsl5Tti7Dti7Dsl5DshJwg7ZiE7J6sIOyCreygnOuQnCDtlITroa3snYQg7LC47KGw7ZWY6rOgIOyeiOuKlCDrqqjrk6Ag7ISc67iM7IWL7ZWE65OcIOywvuyVhOyEnCDsoJzsmbhcbiAgICBjb25zdCBhbGxFbnRpdHlJZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuICAgIGZvciAoY29uc3QgcmVsRW50aXR5SWQgb2YgYWxsRW50aXR5SWRzKSB7XG4gICAgICBjb25zdCByZWxFbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChyZWxFbnRpdHlJZCk7XG4gICAgICBjb25zdCByZWxFbnRpdHlTdWJzZXRLZXlzID0gT2JqZWN0LmtleXMocmVsRW50aXR5LnN1YnNldHMpO1xuICAgICAgZm9yIChjb25zdCBzdWJzZXRLZXkgb2YgcmVsRW50aXR5U3Vic2V0S2V5cykge1xuICAgICAgICBjb25zdCBzdWJzZXQgPSByZWxFbnRpdHkuc3Vic2V0c1tzdWJzZXRLZXldO1xuICAgICAgICAvLyDshJzruIzshYsg7ZWE65Oc66W8IOyInO2ajO2VmOupsCwg7JeU7Yuw7YuwLe2UhOuhrSDri6jsnITroZwg67aE7ISd7ZWcIO2bhCDtmITsnqwg7JeU7Yuw7YuwLe2UhOuhreqzvCDsnbzsuZjtlZjripQg6rK97JqwIOydtO2bhOydmCDtlYTrk5zrpbwg7KCc7Jm4XG4gICAgICAgIGNvbnN0IG1vZGlmaWVkU3Vic2V0RmllbGRzID0gc3Vic2V0XG4gICAgICAgICAgLm1hcCgoc3Vic2V0RmllbGQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFuYWx5emVkID0gcmVsRW50aXR5LmFuYWx5emVTdWJzZXRGaWVsZChzdWJzZXRGaWVsZCk7XG4gICAgICAgICAgICBpZiAoYW5hbHl6ZWQuZmluZCgoYSkgPT4gYS5wcm9wTmFtZSA9PT0gb2xkTmFtZSAmJiBhLmVudGl0eUlkID09PSB0aGlzLmlkKSkge1xuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHJldHVybiBzdWJzZXRGaWVsZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICAgIC5maWx0ZXIobm9uTnVsbGFibGUpO1xuXG4gICAgICAgIGlmIChzdWJzZXQuam9pbihcIixcIikgIT09IG1vZGlmaWVkU3Vic2V0RmllbGRzLmpvaW4oXCIsXCIpKSB7XG4gICAgICAgICAgcmVsRW50aXR5LnN1YnNldHNbc3Vic2V0S2V5XSA9IG1vZGlmaWVkU3Vic2V0RmllbGRzO1xuICAgICAgICAgIGVudGl0aWVzLnB1c2gocmVsRW50aXR5KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIO2YhOyerCDsl5Tti7Dti7DsnZgg7J24642x7Iqk7JeQ7IScIOygnOyZuFxuICAgIGZvciAoY29uc3QgaW5kZXggb2YgRW50aXR5TWFuYWdlci5nZXQodGhpcy5pZCkuaW5kZXhlcykge1xuICAgICAgaW5kZXguY29sdW1ucyA9IGluZGV4LmNvbHVtbnMuZmlsdGVyKChjb2wpID0+IGNvbC5uYW1lICE9PSBvbGROYW1lKTtcbiAgICB9XG5cbiAgICAvLyDtlITroa0g7IKt7KCcXG4gICAgdGhpcy5wcm9wcy5zcGxpY2UoYXQsIDEpO1xuXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoZW50aXRpZXMubWFwKGFzeW5jIChlbnRpdHkpID0+IGVudGl0eS5zYXZlKCkpKTtcbiAgfVxuXG4gIGdldEVudGl0eUlkRnJvbVN1YnNldEZpZWxkKHN1YnNldEZpZWxkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICghc3Vic2V0RmllbGQuaW5jbHVkZXMoXCIuXCIpKSB7XG4gICAgICByZXR1cm4gdGhpcy5pZDtcbiAgICB9XG5cbiAgICAvLyDshJzruIzshYsg7ZWE65Oc7J2YIOuniOyngOunieydgCDtlITroa3snbTrr4DroZwg7KCc7Jm4XG4gICAgY29uc3QgYXJyID0gc3Vic2V0RmllbGQuc3BsaXQoXCIuXCIpLnNsaWNlKDAsIC0xKTtcblxuICAgIC8vIOyEnOu4jOyFiyDtlYTrk5zrpbwg64K066Ck6rCA66m07IScIOuniOyngOunieycvOuhnCByZWxhdGlvbuuQnCDsl5Tti7Dti7Drpbwg7LC+7J2MXG4gICAgY29uc3QgbGFzdEVudGl0eUlkID0gYXJyLnJlZHVjZSgoZW50aXR5SWQsIGZpZWxkKSA9PiB7XG4gICAgICBjb25zdCByZWxQcm9wID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpLnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gZmllbGQpO1xuICAgICAgaWYgKCFyZWxQcm9wIHx8IHJlbFByb3AudHlwZSAhPT0gXCJyZWxhdGlvblwiKSB7XG4gICAgICAgIGNvbnNvbGUuZGVidWcoeyBhcnIsIHRoaXNJZDogdGhpcy5pZCwgZW50aXR5SWQsIGZpZWxkIH0pO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYOyemOuqu+uQnCDshJzruIzshYvtgqQgJHtzdWJzZXRGaWVsZH1gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZWxQcm9wLndpdGg7XG4gICAgfSwgdGhpcy5pZCk7XG4gICAgcmV0dXJuIGxhc3RFbnRpdHlJZDtcbiAgfVxuXG4gIGFzeW5jIG1vdmVQcm9wKGF0OiBudW1iZXIsIHRvOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBwcm9wID0gdGhpcy5wcm9wc1thdF07XG4gICAgY29uc3QgbmV3UHJvcHMgPSBbLi4udGhpcy5wcm9wc107XG4gICAgbmV3UHJvcHMuc3BsaWNlKHRvLCAwLCBwcm9wKTtcbiAgICBuZXdQcm9wcy5zcGxpY2UoYXQgPCB0byA/IGF0IDogYXQgKyAxLCAxKTtcbiAgICB0aGlzLnByb3BzID0gbmV3UHJvcHM7XG5cbiAgICBhd2FpdCB0aGlzLnNhdmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDtlYTrk5zrqoXsnYQgXCLthYzsnbTruJTrqoUu7ZWE65Oc66qFXCIg7ZiV7Iud7Jy866GcIOuzgO2ZmFxuICAgKi9cbiAgZ2V0RnVsbEZpZWxkTmFtZShmaWVsZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAoZmllbGQuaW5jbHVkZXMoXCIuXCIpKSB7XG4gICAgICByZXR1cm4gZmllbGQ7XG4gICAgfVxuICAgIHJldHVybiBgJHt0aGlzLnRhYmxlfS4ke2ZpZWxkfWA7XG4gIH1cblxuICAvKipcbiAgICog7JeU7Yuw7Yuw7J2YIFBLIO2DgOyeheydhCDrsJjtmZjtlanri4jri6QuXG4gICAqIGlkIO2VhOuTnOydmCDtg4DsnoXsnYQg6riw7KSA7Jy866GcIFwiaW50ZWdlclwiIHwgXCJzdHJpbmdcIiB8IFwidXVpZFwi66W8IOuwmO2ZmO2VqeuLiOuLpC5cbiAgICovXG4gIGdldFBrVHlwZSgpOiBcImludGVnZXJcIiB8IFwic3RyaW5nXCIgfCBcInV1aWRcIiB7XG4gICAgY29uc3QgaWRQcm9wID0gdGhpcy5wcm9wc0RpY3QuaWQ7XG4gICAgaWYgKCFpZFByb3ApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRW50aXR5ICR7dGhpcy5pZH3sl5AgaWQg7ZWE65Oc6rCAIOyXhuyKteuLiOuLpGApO1xuICAgIH1cbiAgICBpZiAoaWRQcm9wLnR5cGUgPT09IFwic3RyaW5nXCIgfHwgaWRQcm9wLnR5cGUgPT09IFwidXVpZFwiKSB7XG4gICAgICByZXR1cm4gaWRQcm9wLnR5cGU7XG4gICAgfVxuICAgIHJldHVybiBcImludGVnZXJcIjtcbiAgfVxuXG4gIC8qKlxuICAgKiDsl5Tti7Dti7DsnZggUEsgcHJvcOydhCDrsJjtmZjtlanri4jri6QuXG4gICAqIGxlbmd0aCDrk7Eg7IS467aAIOygleuztOyXkCDsoJHqt7ztlaAg65WMIOyCrOyaqe2VqeuLiOuLpC5cbiAgICovXG4gIGdldFBrUHJvcCgpOiBFbnRpdHlQcm9wIHtcbiAgICBjb25zdCBpZFByb3AgPSB0aGlzLnByb3BzRGljdC5pZDtcbiAgICBpZiAoIWlkUHJvcCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFbnRpdHkgJHt0aGlzLmlkfeyXkCBpZCDtlYTrk5zqsIAg7JeG7Iq164uI64ukYCk7XG4gICAgfVxuICAgIHJldHVybiBpZFByb3A7XG4gIH1cblxuICAvKipcbiAgICog7JeU7Yuw7Yuw7J2YIFBLIOuwsOyXtCDtg4DsnoXsnYQg67CY7ZmY7ZWp64uI64ukLlxuICAgKiBMb2FkZXJRdWVyeeydmCBmcm9tSWRzIO2DgOyeheycvOuhnCDsgqzsmqnrkKnri4jri6QuXG4gICAqL1xuICBnZXRQa0FycmF5VHlwZSgpOiBzdHJpbmcge1xuICAgIGNvbnN0IHBrVHlwZSA9IHRoaXMuZ2V0UGtUeXBlKCk7XG4gICAgcmV0dXJuIHBrVHlwZSA9PT0gXCJpbnRlZ2VyXCIgPyBcIm51bWJlcltdXCIgOiBcInN0cmluZ1tdXCI7XG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7OztjQVF1QzthQWNmO2lCQVkyQjtpQkFDSDtnQkFDTDtrQkFDTzthQUNVO3NCQUNYO0NBRXBDLFNBQWIsTUFBb0I7RUFDbEI7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBS0E7RUFDQTtFQUdBO0VBR0E7RUFDQTtFQUdBO0VBR0EsUUFFSSxFQUFFO0VBQ04sUUFFSSxFQUFF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
|