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/ui/ai-client.js
CHANGED
|
@@ -1,47 +1,97 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
1
|
+
import { __esmMin } from "../_virtual/rolldown_runtime.js";
|
|
2
|
+
import { init_utils, nonNullable } from "../utils/utils.js";
|
|
3
|
+
import { Sonamu, init_sonamu } from "../api/sonamu.js";
|
|
4
|
+
import { TemplateOptions, getEnumDefValues, init_types, isInternalSubsetField, normalizeSubsetField } from "../types/types.js";
|
|
5
|
+
import { EntityManager, init_entity_manager } from "../entity/entity-manager.js";
|
|
6
|
+
import { z as z$1 } from "zod";
|
|
7
|
+
import assert from "assert";
|
|
3
8
|
import path from "path";
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
9
|
+
import fs from "fs";
|
|
10
|
+
|
|
11
|
+
//#region src/ui/ai-client.ts
|
|
12
|
+
/**
|
|
13
|
+
* Entity JSON이 entity.instructions.md의 규칙을 따르는지 검증합니다.
|
|
14
|
+
*/
|
|
15
|
+
function validateEntityJson(input) {
|
|
16
|
+
const errors = [];
|
|
17
|
+
const { entityId, props, enums } = input;
|
|
18
|
+
const hasIdProp = props?.some((p) => p.name === "id");
|
|
19
|
+
if (!hasIdProp) {
|
|
20
|
+
errors.push({
|
|
21
|
+
field: "props",
|
|
22
|
+
message: "id 프로퍼티가 필수입니다."
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
const hasCreatedAtProp = props?.some((p) => p.name === "created_at");
|
|
26
|
+
if (!hasCreatedAtProp) {
|
|
27
|
+
errors.push({
|
|
28
|
+
field: "props",
|
|
29
|
+
message: "created_at 프로퍼티가 필수입니다."
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
const orderByEnumId = `${entityId}OrderBy`;
|
|
33
|
+
const searchFieldEnumId = `${entityId}SearchField`;
|
|
34
|
+
if (!enums?.[orderByEnumId]) {
|
|
35
|
+
errors.push({
|
|
36
|
+
field: "enums",
|
|
37
|
+
message: `${orderByEnumId} enum이 필수입니다. (예: { "id-desc": "ID최신순" })`
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (!enums?.[searchFieldEnumId]) {
|
|
41
|
+
errors.push({
|
|
42
|
+
field: "enums",
|
|
43
|
+
message: `${searchFieldEnumId} enum이 필수입니다. (예: { "id": "ID" })`
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
for (const prop of props ?? []) {
|
|
47
|
+
if (prop.type === "enum" && !enums?.[prop.id]) {
|
|
48
|
+
errors.push({
|
|
49
|
+
field: `props.${prop.name}`,
|
|
50
|
+
message: `enum id "${prop.id}"가 enums에 정의되어 있지 않습니다.`
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return errors;
|
|
55
|
+
}
|
|
56
|
+
var AIClient, aiClient;
|
|
57
|
+
var init_ai_client = __esmMin((() => {
|
|
58
|
+
init_sonamu();
|
|
59
|
+
init_entity_manager();
|
|
60
|
+
init_types();
|
|
61
|
+
init_utils();
|
|
62
|
+
AIClient = class {
|
|
63
|
+
model = null;
|
|
64
|
+
aiSdk = null;
|
|
65
|
+
async init() {
|
|
66
|
+
try {
|
|
67
|
+
const { anthropic } = await import("@ai-sdk/anthropic");
|
|
68
|
+
const aiModule = await import("ai");
|
|
69
|
+
this.aiSdk = {
|
|
70
|
+
...aiModule,
|
|
71
|
+
anthropic
|
|
72
|
+
};
|
|
73
|
+
this.model = anthropic("claude-sonnet-4-6");
|
|
74
|
+
} catch (error) {
|
|
75
|
+
console.warn("AI SDK packages not installed. Install @ai-sdk/anthropic and ai to use AI features.");
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
handleFixture(messages, fixtureRecords) {
|
|
80
|
+
if (!this.aiSdk || !this.model) {
|
|
81
|
+
throw new Error("AI SDK not initialized. Call init() first.");
|
|
82
|
+
}
|
|
83
|
+
const usedEntityIds = [...new Set(fixtureRecords.map((r) => r.entityId))];
|
|
84
|
+
const entityStructures = usedEntityIds.map((entityId) => {
|
|
85
|
+
const entity = EntityManager.get(entityId);
|
|
86
|
+
return {
|
|
87
|
+
entityId: entity.id,
|
|
88
|
+
table: entity.table,
|
|
89
|
+
props: entity.props,
|
|
90
|
+
relations: entity.relations,
|
|
91
|
+
enumLabels: entity.enumLabels
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
const systemMessage = `
|
|
45
95
|
당신은 픽스쳐 레코드를 수정하고 생성할 수 있는 도우미입니다.
|
|
46
96
|
|
|
47
97
|
현재 픽스쳐 레코드:
|
|
@@ -69,153 +119,131 @@ class AIClient {
|
|
|
69
119
|
예시: 새로운 User 픽스쳐를 생성하려면:
|
|
70
120
|
createFixtures({ fixtures: [{ entityId: "User", id: -1, columns: { name: "홍길동", email: "hong@example.com" } }] })
|
|
71
121
|
`;
|
|
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
|
-
if (!this.aiSdk || !this.model) {
|
|
198
|
-
throw new Error("AI SDK not initialized. Call init() first.");
|
|
199
|
-
}
|
|
200
|
-
// entity.instructions.md 파일 읽기 (dist/ui 또는 src/ui에서 실행되므로 패키지 루트 기준으로 접근)
|
|
201
|
-
const instructionsPath = path.join(import.meta.dirname, "..", "..", "src", "ui", "entity.instructions.md");
|
|
202
|
-
const instructions = fs.readFileSync(instructionsPath, "utf-8");
|
|
203
|
-
// 현재 등록된 엔티티 정보 수집
|
|
204
|
-
const entityIds = EntityManager.getAllIds();
|
|
205
|
-
const existingEntities = entityIds.map((entityId)=>{
|
|
206
|
-
const entity = EntityManager.get(entityId);
|
|
207
|
-
return {
|
|
208
|
-
id: entity.id,
|
|
209
|
-
title: entity.title,
|
|
210
|
-
table: entity.table,
|
|
211
|
-
props: entity.props.map((p)=>({
|
|
212
|
-
name: p.name,
|
|
213
|
-
type: p.type,
|
|
214
|
-
desc: p.desc
|
|
215
|
-
}))
|
|
216
|
-
};
|
|
217
|
-
});
|
|
218
|
-
const systemMessage = `
|
|
122
|
+
const { streamText, tool } = this.aiSdk;
|
|
123
|
+
return streamText({
|
|
124
|
+
model: this.model,
|
|
125
|
+
system: systemMessage,
|
|
126
|
+
messages,
|
|
127
|
+
tools: {
|
|
128
|
+
updateFixtures: tool({
|
|
129
|
+
description: "픽스쳐 레코드의 값을 수정합니다. 사용자가 특정 컬럼이나 값을 변경해달라고 요청할 때 사용하세요.",
|
|
130
|
+
inputSchema: z$1.object({ updates: z$1.array(z$1.object({
|
|
131
|
+
fixtureId: z$1.string().describe("수정할 픽스쳐 ID (형식: EntityId#id)"),
|
|
132
|
+
updates: z$1.record(z$1.string(), z$1.unknown()).describe("컬럼명을 키로, 새 값을 값으로 하는 객체")
|
|
133
|
+
})) }),
|
|
134
|
+
execute: async ({ updates }) => {
|
|
135
|
+
const updatedRecords = fixtureRecords.map((record) => {
|
|
136
|
+
const update = updates.find((u) => u.fixtureId === record.fixtureId);
|
|
137
|
+
if (update) {
|
|
138
|
+
for (const [columnName, newValue] of Object.entries(update.updates)) {
|
|
139
|
+
record.columns[columnName].value = newValue;
|
|
140
|
+
}
|
|
141
|
+
return record;
|
|
142
|
+
}
|
|
143
|
+
return record;
|
|
144
|
+
});
|
|
145
|
+
return {
|
|
146
|
+
success: true,
|
|
147
|
+
updatedRecords
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}),
|
|
151
|
+
createFixtures: tool({
|
|
152
|
+
description: "새로운 픽스쳐 레코드를 생성합니다. 사용자가 새로운 데이터를 추가해달라고 요청할 때 사용하세요.",
|
|
153
|
+
inputSchema: z$1.object({ fixtures: z$1.array(z$1.object({
|
|
154
|
+
entityId: z$1.string().describe("생성할 엔티티 ID"),
|
|
155
|
+
id: z$1.number().describe("새 레코드의 ID (음수 권장, 예: -1, -2)"),
|
|
156
|
+
columns: z$1.record(z$1.string(), z$1.unknown()).describe("컬럼명을 키로, 값을 값으로 하는 객체")
|
|
157
|
+
})) }),
|
|
158
|
+
execute: async ({ fixtures }) => {
|
|
159
|
+
const newRecords = fixtures.map((fixture) => {
|
|
160
|
+
const entity = EntityManager.get(fixture.entityId);
|
|
161
|
+
const columns = {};
|
|
162
|
+
for (const prop of entity.props) {
|
|
163
|
+
if (prop.type === "virtual") continue;
|
|
164
|
+
let value = fixture.columns[prop.name] ?? null;
|
|
165
|
+
if (prop.name === "created_at") {
|
|
166
|
+
value = new Date().toISOString();
|
|
167
|
+
} else if (prop.type === "relation" && (prop.relationType === "HasMany" || prop.relationType === "ManyToMany")) {
|
|
168
|
+
value = Array.isArray(value) ? value : [value].filter(nonNullable);
|
|
169
|
+
}
|
|
170
|
+
columns[prop.name] = {
|
|
171
|
+
prop,
|
|
172
|
+
value
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
fixtureId: `${fixture.entityId}#${fixture.id}`,
|
|
177
|
+
entityId: fixture.entityId,
|
|
178
|
+
id: fixture.id,
|
|
179
|
+
columns,
|
|
180
|
+
fetchedRecords: [],
|
|
181
|
+
belongsRecords: [],
|
|
182
|
+
override: false
|
|
183
|
+
};
|
|
184
|
+
});
|
|
185
|
+
for (const newRecord of newRecords) {
|
|
186
|
+
for (const [_colName, col] of Object.entries(newRecord.columns)) {
|
|
187
|
+
if (col.prop.type !== "relation" || col.value === null) continue;
|
|
188
|
+
const relatedEntityId = col.prop.with;
|
|
189
|
+
const relatedIds = Array.isArray(col.value) ? col.value : [col.value];
|
|
190
|
+
for (const relatedId of relatedIds) {
|
|
191
|
+
const relatedFixtureId = `${relatedEntityId}#${relatedId}`;
|
|
192
|
+
const relatedRecord = newRecords.find((r) => r.fixtureId === relatedFixtureId);
|
|
193
|
+
if (relatedRecord) {
|
|
194
|
+
const reverseCol = Object.entries(relatedRecord.columns).find(([, c]) => c.prop.type === "relation" && c.prop.with === newRecord.entityId);
|
|
195
|
+
if (reverseCol) {
|
|
196
|
+
const [reverseColName, reverseColValue] = reverseCol;
|
|
197
|
+
const currentValue = reverseColValue.value;
|
|
198
|
+
if (reverseColValue.prop.type === "relation" && (reverseColValue.prop.relationType === "HasMany" || reverseColValue.prop.relationType === "ManyToMany")) {
|
|
199
|
+
assert(Array.isArray(currentValue), "currentValue must be an array");
|
|
200
|
+
if (!currentValue.includes(newRecord.id)) {
|
|
201
|
+
relatedRecord.columns[reverseColName] = {
|
|
202
|
+
...reverseColValue,
|
|
203
|
+
value: [...currentValue, newRecord.id]
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
} else {
|
|
207
|
+
relatedRecord.columns[reverseColName] = {
|
|
208
|
+
...reverseColValue,
|
|
209
|
+
value: newRecord.id
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return {
|
|
218
|
+
success: true,
|
|
219
|
+
updatedRecords: newRecords
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
})
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
handleEntity(messages) {
|
|
227
|
+
if (!this.aiSdk || !this.model) {
|
|
228
|
+
throw new Error("AI SDK not initialized. Call init() first.");
|
|
229
|
+
}
|
|
230
|
+
const instructionsPath = path.join(import.meta.dirname, "..", "..", "src", "ui", "entity.instructions.md");
|
|
231
|
+
const instructions = fs.readFileSync(instructionsPath, "utf-8");
|
|
232
|
+
const entityIds = EntityManager.getAllIds();
|
|
233
|
+
const existingEntities = entityIds.map((entityId) => {
|
|
234
|
+
const entity = EntityManager.get(entityId);
|
|
235
|
+
return {
|
|
236
|
+
id: entity.id,
|
|
237
|
+
title: entity.title,
|
|
238
|
+
table: entity.table,
|
|
239
|
+
props: entity.props.map((p) => ({
|
|
240
|
+
name: p.name,
|
|
241
|
+
type: p.type,
|
|
242
|
+
desc: p.desc
|
|
243
|
+
}))
|
|
244
|
+
};
|
|
245
|
+
});
|
|
246
|
+
const systemMessage = `
|
|
219
247
|
당신은 Sonamu 프레임워크에서 Entity와 Enum을 생성하는 도우미입니다.
|
|
220
248
|
|
|
221
249
|
${instructions}
|
|
@@ -281,202 +309,139 @@ updateEntity({ entityId: "Project", updates: { props: [{ name: "priority", type:
|
|
|
281
309
|
| "text 타입은 textType이 필수" | 해당 prop에 textType 추가 ("text", "mediumtext", "longtext") |
|
|
282
310
|
| "onUpdate가 필수" | 해당 relation prop에 onUpdate, onDelete 추가 ("CASCADE") |
|
|
283
311
|
`;
|
|
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
|
-
await entity.save();
|
|
416
|
-
return {
|
|
417
|
-
success: true,
|
|
418
|
-
entityId
|
|
419
|
-
};
|
|
420
|
-
} catch (e) {
|
|
421
|
-
const error = e instanceof Error ? e.message : "Unknown error";
|
|
422
|
-
return {
|
|
423
|
-
success: false,
|
|
424
|
-
entityId,
|
|
425
|
-
error
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
})
|
|
430
|
-
}
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
/**
|
|
435
|
-
* Entity JSON이 entity.instructions.md의 규칙을 따르는지 검증합니다.
|
|
436
|
-
*/ function validateEntityJson(input) {
|
|
437
|
-
const errors = [];
|
|
438
|
-
const { entityId, props, enums } = input;
|
|
439
|
-
// 1. id, created_at prop 필수
|
|
440
|
-
const hasIdProp = props?.some((p)=>p.name === "id");
|
|
441
|
-
if (!hasIdProp) {
|
|
442
|
-
errors.push({
|
|
443
|
-
field: "props",
|
|
444
|
-
message: "id 프로퍼티가 필수입니다."
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
const hasCreatedAtProp = props?.some((p)=>p.name === "created_at");
|
|
448
|
-
if (!hasCreatedAtProp) {
|
|
449
|
-
errors.push({
|
|
450
|
-
field: "props",
|
|
451
|
-
message: "created_at 프로퍼티가 필수입니다."
|
|
452
|
-
});
|
|
453
|
-
}
|
|
454
|
-
// 2. 필수 enum 검증: EntityNameOrderBy, EntityNameSearchField
|
|
455
|
-
const orderByEnumId = `${entityId}OrderBy`;
|
|
456
|
-
const searchFieldEnumId = `${entityId}SearchField`;
|
|
457
|
-
if (!enums?.[orderByEnumId]) {
|
|
458
|
-
errors.push({
|
|
459
|
-
field: "enums",
|
|
460
|
-
message: `${orderByEnumId} enum이 필수입니다. (예: { "id-desc": "ID최신순" })`
|
|
461
|
-
});
|
|
462
|
-
}
|
|
463
|
-
if (!enums?.[searchFieldEnumId]) {
|
|
464
|
-
errors.push({
|
|
465
|
-
field: "enums",
|
|
466
|
-
message: `${searchFieldEnumId} enum이 필수입니다. (예: { "id": "ID" })`
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
// 3. enum prop의 id가 enums에 정의되어 있는지 확인 (cross-field 검증)
|
|
470
|
-
for (const prop of props ?? []){
|
|
471
|
-
if (prop.type === "enum" && !enums?.[prop.id]) {
|
|
472
|
-
errors.push({
|
|
473
|
-
field: `props.${prop.name}`,
|
|
474
|
-
message: `enum id "${prop.id}"가 enums에 정의되어 있지 않습니다.`
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
return errors;
|
|
479
|
-
}
|
|
480
|
-
export const aiClient = new AIClient();
|
|
312
|
+
const { streamText, tool, stepCountIs } = this.aiSdk;
|
|
313
|
+
return streamText({
|
|
314
|
+
model: this.model,
|
|
315
|
+
system: systemMessage,
|
|
316
|
+
messages,
|
|
317
|
+
stopWhen: stepCountIs(2),
|
|
318
|
+
tools: {
|
|
319
|
+
createEntity: tool({
|
|
320
|
+
description: "새로운 Entity를 생성합니다. 사용자가 새로운 엔티티나 테이블 생성을 요청할 때 사용하세요.",
|
|
321
|
+
inputSchema: TemplateOptions.shape.entity,
|
|
322
|
+
execute: async (entity) => {
|
|
323
|
+
try {
|
|
324
|
+
const validationErrors = validateEntityJson(entity);
|
|
325
|
+
if (validationErrors.length > 0) {
|
|
326
|
+
return {
|
|
327
|
+
success: false,
|
|
328
|
+
entityId: entity.entityId,
|
|
329
|
+
error: `검증 오류: ${validationErrors.map((e) => `[${e.field}] ${e.message}`).join(", ")}`,
|
|
330
|
+
validationErrors
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
await Sonamu.syncer.createEntity({
|
|
334
|
+
subsets: { A: ["id"] },
|
|
335
|
+
enums: {},
|
|
336
|
+
...entity
|
|
337
|
+
});
|
|
338
|
+
await EntityManager.reload();
|
|
339
|
+
return {
|
|
340
|
+
success: true,
|
|
341
|
+
entityId: entity.entityId
|
|
342
|
+
};
|
|
343
|
+
} catch (e) {
|
|
344
|
+
const error = e instanceof Error ? e.message : "Unknown error";
|
|
345
|
+
return {
|
|
346
|
+
success: false,
|
|
347
|
+
entityId: entity.entityId,
|
|
348
|
+
error
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}),
|
|
353
|
+
updateEntity: tool({
|
|
354
|
+
description: "기존 Entity를 수정합니다. Enum 추가, props 추가/수정, indexes 수정, subsets 수정 등 모든 엔티티 수정 작업에 사용하세요.",
|
|
355
|
+
inputSchema: z$1.object({
|
|
356
|
+
entityId: z$1.string().describe("수정할 Entity ID"),
|
|
357
|
+
updates: TemplateOptions.shape.entity.partial().describe("수정할 필드들"),
|
|
358
|
+
mode: z$1.enum(["merge", "replace"]).optional().describe("수정 모드: merge(기본값, 기존 값에 병합) 또는 replace(전체 교체)")
|
|
359
|
+
}),
|
|
360
|
+
execute: async ({ entityId, updates, mode = "merge" }) => {
|
|
361
|
+
try {
|
|
362
|
+
const entity = EntityManager.get(entityId);
|
|
363
|
+
if (updates.entityId !== undefined) entity.id = updates.entityId;
|
|
364
|
+
if (updates.parentId !== undefined) entity.parentId = updates.parentId;
|
|
365
|
+
if (updates.title !== undefined) entity.title = updates.title;
|
|
366
|
+
if (updates.table !== undefined) entity.table = updates.table;
|
|
367
|
+
if (updates.cone !== undefined) entity.cone = updates.cone;
|
|
368
|
+
if (updates.props !== undefined) {
|
|
369
|
+
if (mode === "replace") {
|
|
370
|
+
entity.props = updates.props;
|
|
371
|
+
} else {
|
|
372
|
+
for (const newProp of updates.props) {
|
|
373
|
+
const existingIndex = entity.props.findIndex((p) => p.name === newProp.name);
|
|
374
|
+
if (existingIndex >= 0) {
|
|
375
|
+
entity.props[existingIndex] = newProp;
|
|
376
|
+
} else {
|
|
377
|
+
entity.props.push(newProp);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
if (updates.indexes !== undefined) {
|
|
383
|
+
entity.indexes = mode === "replace" ? updates.indexes : [...entity.indexes, ...updates.indexes];
|
|
384
|
+
}
|
|
385
|
+
if (updates.subsets !== undefined) {
|
|
386
|
+
const normalizedSubsets = {};
|
|
387
|
+
const normalizedSubsetsInternal = {};
|
|
388
|
+
for (const [key, fields] of Object.entries(updates.subsets)) {
|
|
389
|
+
const fieldArray = fields;
|
|
390
|
+
normalizedSubsets[key] = fieldArray.filter((f) => !isInternalSubsetField(f)).map(normalizeSubsetField);
|
|
391
|
+
normalizedSubsetsInternal[key] = fieldArray.filter(isInternalSubsetField).map(normalizeSubsetField);
|
|
392
|
+
}
|
|
393
|
+
entity.subsets = mode === "replace" ? normalizedSubsets : {
|
|
394
|
+
...entity.subsets,
|
|
395
|
+
...normalizedSubsets
|
|
396
|
+
};
|
|
397
|
+
entity.subsetsInternal = mode === "replace" ? normalizedSubsetsInternal : {
|
|
398
|
+
...entity.subsetsInternal,
|
|
399
|
+
...normalizedSubsetsInternal
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
if (updates.enums !== undefined) {
|
|
403
|
+
const convertedEnums = Object.fromEntries(Object.entries(updates.enums).map(([key, enumDef]) => [key, getEnumDefValues(enumDef)]));
|
|
404
|
+
entity.enumLabels = mode === "replace" ? convertedEnums : {
|
|
405
|
+
...entity.enumLabels,
|
|
406
|
+
...convertedEnums
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
const validationErrors = validateEntityJson({
|
|
410
|
+
...entity,
|
|
411
|
+
entityId: entity.id,
|
|
412
|
+
enums: entity.enumLabels
|
|
413
|
+
});
|
|
414
|
+
if (validationErrors.length > 0) {
|
|
415
|
+
return {
|
|
416
|
+
success: false,
|
|
417
|
+
entityId,
|
|
418
|
+
error: `검증 오류: ${validationErrors.map((e) => `[${e.field}] ${e.message}`).join(", ")}`,
|
|
419
|
+
validationErrors
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
await entity.save();
|
|
423
|
+
return {
|
|
424
|
+
success: true,
|
|
425
|
+
entityId
|
|
426
|
+
};
|
|
427
|
+
} catch (e) {
|
|
428
|
+
const error = e instanceof Error ? e.message : "Unknown error";
|
|
429
|
+
return {
|
|
430
|
+
success: false,
|
|
431
|
+
entityId,
|
|
432
|
+
error
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
})
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
aiClient = new AIClient();
|
|
442
|
+
}));
|
|
481
443
|
|
|
482
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91aS9haS1jbGllbnQudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqIGJpb21lLWlnbm9yZS1hbGwgbGludC9zdXNwaWNpb3VzL25vRXhwbGljaXRBbnk6IEFJIFNES+ydmCDtg4DsnoXsnbQg66qF7ZmV7ZWY7KeAIOyViuyVhCBhbnnrpbwg7ZeI7Jqp7ZWoICovXG5pbXBvcnQgdHlwZSB7IExhbmd1YWdlTW9kZWwsIE1vZGVsTWVzc2FnZSwgU3RyZWFtVGV4dFJlc3VsdCB9IGZyb20gXCJhaVwiO1xuaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB7IFNvbmFtdSB9IGZyb20gXCIuLi9hcGlcIjtcbmltcG9ydCB7IEVudGl0eU1hbmFnZXIgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCI7XG5pbXBvcnQge1xuICB0eXBlIEVudGl0eVByb3AsXG4gIHR5cGUgRml4dHVyZVJlY29yZCxcbiAgZ2V0RW51bURlZlZhbHVlcyxcbiAgaXNJbnRlcm5hbFN1YnNldEZpZWxkLFxuICBub3JtYWxpemVTdWJzZXRGaWVsZCxcbiAgVGVtcGxhdGVPcHRpb25zLFxufSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IG5vbk51bGxhYmxlIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5cbnR5cGUgVmFsaWRhdGlvbkVycm9yID0ge1xuICBmaWVsZDogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG59O1xuXG5jbGFzcyBBSUNsaWVudCB7XG4gIHByaXZhdGUgbW9kZWw6IExhbmd1YWdlTW9kZWwgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBhaVNkazpcbiAgICB8ICh0eXBlb2YgaW1wb3J0KFwiYWlcIikgJiB7XG4gICAgICAgIGFudGhyb3BpYz86IHR5cGVvZiBpbXBvcnQoXCJAYWktc2RrL2FudGhyb3BpY1wiKS5hbnRocm9waWM7XG4gICAgICB9KVxuICAgIHwgbnVsbCA9IG51bGw7XG5cbiAgYXN5bmMgaW5pdCgpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBhbnRocm9waWMgfSA9IGF3YWl0IGltcG9ydChcIkBhaS1zZGsvYW50aHJvcGljXCIpO1xuICAgICAgY29uc3QgYWlNb2R1bGUgPSBhd2FpdCBpbXBvcnQoXCJhaVwiKTtcbiAgICAgIHRoaXMuYWlTZGsgPSB7IC4uLmFpTW9kdWxlLCBhbnRocm9waWMgfTtcbiAgICAgIHRoaXMubW9kZWwgPSBhbnRocm9waWMoXCJjbGF1ZGUtc29ubmV0LTQtNlwiKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBcIkFJIFNESyBwYWNrYWdlcyBub3QgaW5zdGFsbGVkLiBJbnN0YWxsIEBhaS1zZGsvYW50aHJvcGljIGFuZCBhaSB0byB1c2UgQUkgZmVhdHVyZXMuXCIsXG4gICAgICApO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlRml4dHVyZShcbiAgICBtZXNzYWdlczogTW9kZWxNZXNzYWdlW10sXG4gICAgZml4dHVyZVJlY29yZHM6IEZpeHR1cmVSZWNvcmRbXSxcbiAgKTogU3RyZWFtVGV4dFJlc3VsdDxhbnksIGFueT4ge1xuICAgIGlmICghdGhpcy5haVNkayB8fCAhdGhpcy5tb2RlbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQUkgU0RLIG5vdCBpbml0aWFsaXplZC4gQ2FsbCBpbml0KCkgZmlyc3QuXCIpO1xuICAgIH1cblxuICAgIC8vIO2YhOyerCBmaXh0dXJlUmVjb3Jkc+yXkOyEnCDsgqzsmqnrkJwg7JeU7Yuw7Yuw65Ok7J2YIOq1rOyhsCDsoJXrs7Qg7IiY7KeRXG4gICAgY29uc3QgdXNlZEVudGl0eUlkcyA9IFsuLi5uZXcgU2V0KGZpeHR1cmVSZWNvcmRzLm1hcCgocikgPT4gci5lbnRpdHlJZCkpXTtcbiAgICBjb25zdCBlbnRpdHlTdHJ1Y3R1cmVzID0gdXNlZEVudGl0eUlkcy5tYXAoKGVudGl0eUlkKSA9PiB7XG4gICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVudGl0eUlkOiBlbnRpdHkuaWQsXG4gICAgICAgIHRhYmxlOiBlbnRpdHkudGFibGUsXG4gICAgICAgIHByb3BzOiBlbnRpdHkucHJvcHMsXG4gICAgICAgIHJlbGF0aW9uczogZW50aXR5LnJlbGF0aW9ucyxcbiAgICAgICAgZW51bUxhYmVsczogZW50aXR5LmVudW1MYWJlbHMsXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgY29uc3Qgc3lzdGVtTWVzc2FnZSA9IGBcbiAgICAgICAg64u57Iug7J2AIO2UveyKpOyzkCDroIjsvZTrk5zrpbwg7IiY7KCV7ZWY6rOgIOyDneyEse2VoCDsiJgg7J6I64qUIOuPhOyasOuvuOyeheuLiOuLpC5cblxuICAgICAgICDtmITsnqwg7ZS97Iqk7LOQIOugiOy9lOuTnDpcbiAgICAgICAgJHtKU09OLnN0cmluZ2lmeShmaXh0dXJlUmVjb3JkcywgbnVsbCwgMil9XG5cbiAgICAgICAg7JeU7Yuw7YuwIOq1rOyhsCDsoJXrs7Q6XG4gICAgICAgICR7SlNPTi5zdHJpbmdpZnkoZW50aXR5U3RydWN0dXJlcywgbnVsbCwgMil9XG5cbiAgICAgICAgIyMg7ZS97Iqk7LOQIOyImOyglVxuICAgICAgICDsgqzsmqnsnpDqsIAg7ZS97Iqk7LOQIOqwkiDsiJjsoJXsnYQg7JqU7LKt7ZWY66m0IHVwZGF0ZUZpeHR1cmVzIOuPhOq1rOulvCDsgqzsmqntlZjsl6wg67OA6rK97IKs7ZWt7J2EIOyggeyaqe2VmOyEuOyalC5cbiAgICAgICAgLSBmaXh0dXJlSWQ6IOyImOygle2VoCDtlL3siqTss5AgSUQgKO2YleyLnTogXCJFbnRpdHlJZCNpZFwiKVxuICAgICAgICAtIHVwZGF0ZXM6IOy7rOufvOuqheydhCDtgqTroZwsIOyDiCDqsJLsnYQg6rCS7Jy866GcIO2VmOuKlCDqsJ3ssrRcblxuICAgICAgICDsmIjsi5w6IFwiVXNlciMxXCIg7ZS97Iqk7LOQ7J2YIFwibmFtZVwiIOy7rOufvOydhCBcIu2Zjeq4uOuPmVwi7Jy866GcIOuzgOqyve2VmOugpOuptDpcbiAgICAgICAgdXBkYXRlRml4dHVyZXMoeyB1cGRhdGVzOiBbeyBmaXh0dXJlSWQ6IFwiVXNlciMxXCIsIHVwZGF0ZXM6IHsgbmFtZTogXCLtmY3quLjrj5lcIiB9IH1dIH0pXG5cbiAgICAgICAg67OA6rK965CgIOy7rOufvOydmCB0eXBl7J20IHJlbGF0aW9u7J24IOqyveyasCwg6rSA66CoIOyXlO2LsO2LsOyXkOuPhCDrsJjsmIHrkJjslrTslbwg7ZWgIOy7rOufvOydtCDsnojripTsp4Ag7ZmV7J247ZWY7IS47JqULlxuXG4gICAgICAgICMjIO2UveyKpOyzkCDsg53shLFcbiAgICAgICAg7IKs7Jqp7J6Q6rCAIOyDiOuhnOyatCDtlL3siqTss5Ag7IOd7ISx7J2EIOyalOyyre2VmOuptCBjcmVhdGVGaXh0dXJlcyDrj4Tqtazrpbwg7IKs7Jqp7ZWY7IS47JqULlxuICAgICAgICAtIGVudGl0eUlkOiDsg53shLHtlaAg7JeU7Yuw7YuwIElEXG4gICAgICAgIC0gaWQ6IOyDiCDroIjsvZTrk5zsnZggSUQgKOq4sOyhtCDtlL3siqTss5DsmYAg7KSR67O165CY7KeAIOyViuuKlCDsnYzsiJgg7IKs7JqpIOq2jOyepSwg7JiIOiAtMSwgLTIpXG4gICAgICAgIC0gY29sdW1uczog7Lus65+866qF7J2EIO2CpOuhnCwg6rCS7J2EIOqwkuycvOuhnCDtlZjripQg6rCd7LK0ICjsl5Tti7Dti7Ag6rWs7KGwIOywuOqzoClcblxuICAgICAgICDsmIjsi5w6IOyDiOuhnOyatCBVc2VyIO2UveyKpOyzkOulvCDsg53shLHtlZjroKTrqbQ6XG4gICAgICAgIGNyZWF0ZUZpeHR1cmVzKHsgZml4dHVyZXM6IFt7IGVudGl0eUlkOiBcIlVzZXJcIiwgaWQ6IC0xLCBjb2x1bW5zOiB7IG5hbWU6IFwi7ZmN6ri464+ZXCIsIGVtYWlsOiBcImhvbmdAZXhhbXBsZS5jb21cIiB9IH1dIH0pXG4gICAgICBgO1xuXG4gICAgY29uc3QgeyBzdHJlYW1UZXh0LCB0b29sIH0gPSB0aGlzLmFpU2RrO1xuXG4gICAgcmV0dXJuIHN0cmVhbVRleHQoe1xuICAgICAgbW9kZWw6IHRoaXMubW9kZWwsXG4gICAgICBzeXN0ZW06IHN5c3RlbU1lc3NhZ2UsXG4gICAgICBtZXNzYWdlcyxcbiAgICAgIHRvb2xzOiB7XG4gICAgICAgIHVwZGF0ZUZpeHR1cmVzOiB0b29sKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwi7ZS97Iqk7LOQIOugiOy9lOuTnOydmCDqsJLsnYQg7IiY7KCV7ZWp64uI64ukLiDsgqzsmqnsnpDqsIAg7Yq57KCVIOy7rOufvOydtOuCmCDqsJLsnYQg67OA6rK97ZW064us65286rOgIOyalOyyre2VoCDrlYwg7IKs7Jqp7ZWY7IS47JqULlwiLFxuICAgICAgICAgIGlucHV0U2NoZW1hOiB6Lm9iamVjdCh7XG4gICAgICAgICAgICB1cGRhdGVzOiB6LmFycmF5KFxuICAgICAgICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgICAgZml4dHVyZUlkOiB6LnN0cmluZygpLmRlc2NyaWJlKFwi7IiY7KCV7ZWgIO2UveyKpOyzkCBJRCAo7ZiV7IudOiBFbnRpdHlJZCNpZClcIiksXG4gICAgICAgICAgICAgICAgdXBkYXRlczogelxuICAgICAgICAgICAgICAgICAgLnJlY29yZCh6LnN0cmluZygpLCB6LnVua25vd24oKSlcbiAgICAgICAgICAgICAgICAgIC5kZXNjcmliZShcIuy7rOufvOuqheydhCDtgqTroZwsIOyDiCDqsJLsnYQg6rCS7Jy866GcIO2VmOuKlCDqsJ3ssrRcIiksXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBleGVjdXRlOiBhc3luYyAoe1xuICAgICAgICAgICAgdXBkYXRlcyxcbiAgICAgICAgICB9OiB7XG4gICAgICAgICAgICB1cGRhdGVzOiBBcnJheTx7IGZpeHR1cmVJZDogc3RyaW5nOyB1cGRhdGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9PjtcbiAgICAgICAgICB9KTogUHJvbWlzZTx7IHN1Y2Nlc3M6IGJvb2xlYW47IHVwZGF0ZWRSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gfT4gPT4ge1xuICAgICAgICAgICAgLy8gZml4dHVyZVJlY29yZHPrpbwg67O17IKs7ZWY6rOgIOyXheuNsOydtO2KuCDsoIHsmqlcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWRSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gPSBmaXh0dXJlUmVjb3Jkcy5tYXAoKHJlY29yZCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB1cGRhdGUgPSB1cGRhdGVzLmZpbmQoXG4gICAgICAgICAgICAgICAgKHU6IHsgZml4dHVyZUlkOiBzdHJpbmcgfSkgPT4gdS5maXh0dXJlSWQgPT09IHJlY29yZC5maXh0dXJlSWQsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGlmICh1cGRhdGUpIHtcbiAgICAgICAgICAgICAgICAvLyBjb2x1bW5z7J2YIHZhbHVl66W8IOyXheuNsOydtO2KuFxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2NvbHVtbk5hbWUsIG5ld1ZhbHVlXSBvZiBPYmplY3QuZW50cmllcyh1cGRhdGUudXBkYXRlcykpIHtcbiAgICAgICAgICAgICAgICAgIHJlY29yZC5jb2x1bW5zW2NvbHVtbk5hbWVdLnZhbHVlID1cbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWUgYXMgRml4dHVyZVJlY29yZFtcImNvbHVtbnNcIl1bc3RyaW5nXVtcInZhbHVlXCJdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVjb3JkO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcmV0dXJuIHJlY29yZDtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCB1cGRhdGVkUmVjb3JkcyB9O1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgICBjcmVhdGVGaXh0dXJlczogdG9vbCh7XG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICBcIuyDiOuhnOyatCDtlL3siqTss5Ag66CI7L2U65Oc66W8IOyDneyEse2VqeuLiOuLpC4g7IKs7Jqp7J6Q6rCAIOyDiOuhnOyatCDrjbDsnbTthLDrpbwg7LaU6rCA7ZW064us65286rOgIOyalOyyre2VoCDrlYwg7IKs7Jqp7ZWY7IS47JqULlwiLFxuICAgICAgICAgIGlucHV0U2NoZW1hOiB6Lm9iamVjdCh7XG4gICAgICAgICAgICBmaXh0dXJlczogei5hcnJheShcbiAgICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICAgIGVudGl0eUlkOiB6LnN0cmluZygpLmRlc2NyaWJlKFwi7IOd7ISx7ZWgIOyXlO2LsO2LsCBJRFwiKSxcbiAgICAgICAgICAgICAgICBpZDogei5udW1iZXIoKS5kZXNjcmliZShcIuyDiCDroIjsvZTrk5zsnZggSUQgKOydjOyImCDqtozsnqUsIOyYiDogLTEsIC0yKVwiKSxcbiAgICAgICAgICAgICAgICBjb2x1bW5zOiB6XG4gICAgICAgICAgICAgICAgICAucmVjb3JkKHouc3RyaW5nKCksIHoudW5rbm93bigpKVxuICAgICAgICAgICAgICAgICAgLmRlc2NyaWJlKFwi7Lus65+866qF7J2EIO2CpOuhnCwg6rCS7J2EIOqwkuycvOuhnCDtlZjripQg6rCd7LK0XCIpLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSksXG4gICAgICAgICAgZXhlY3V0ZTogYXN5bmMgKHtcbiAgICAgICAgICAgIGZpeHR1cmVzLFxuICAgICAgICAgIH06IHtcbiAgICAgICAgICAgIGZpeHR1cmVzOiBBcnJheTx7IGVudGl0eUlkOiBzdHJpbmc7IGlkOiBudW1iZXI7IGNvbHVtbnM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IH0+O1xuICAgICAgICAgIH0pOiBQcm9taXNlPHsgc3VjY2VzczogYm9vbGVhbjsgdXBkYXRlZFJlY29yZHM6IEZpeHR1cmVSZWNvcmRbXSB9PiA9PiB7XG4gICAgICAgICAgICBjb25zdCBuZXdSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gPSBmaXh0dXJlcy5tYXAoXG4gICAgICAgICAgICAgIChmaXh0dXJlOiB7IGVudGl0eUlkOiBzdHJpbmc7IGlkOiBudW1iZXI7IGNvbHVtbnM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IH0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChmaXh0dXJlLmVudGl0eUlkKTtcblxuICAgICAgICAgICAgICAgIC8vIOyXlO2LsO2LsCBwcm9wc+ulvCDquLDrsJjsnLzroZwgY29sdW1ucyDqtazshLFcbiAgICAgICAgICAgICAgICBjb25zdCBjb2x1bW5zOiBGaXh0dXJlUmVjb3JkW1wiY29sdW1uc1wiXSA9IHt9O1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcHJvcCBvZiBlbnRpdHkucHJvcHMpIHtcbiAgICAgICAgICAgICAgICAgIGlmIChwcm9wLnR5cGUgPT09IFwidmlydHVhbFwiKSBjb250aW51ZTtcblxuICAgICAgICAgICAgICAgICAgbGV0IHZhbHVlID0gZml4dHVyZS5jb2x1bW5zW3Byb3AubmFtZV0gPz8gbnVsbDtcblxuICAgICAgICAgICAgICAgICAgaWYgKHByb3AubmFtZSA9PT0gXCJjcmVhdGVkX2F0XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g7ZiE7J6sIOyLnOqwhOycvOuhnCDshKTsoJVcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgICAgICBwcm9wLnR5cGUgPT09IFwicmVsYXRpb25cIiAmJlxuICAgICAgICAgICAgICAgICAgICAocHJvcC5yZWxhdGlvblR5cGUgPT09IFwiSGFzTWFueVwiIHx8IHByb3AucmVsYXRpb25UeXBlID09PSBcIk1hbnlUb01hbnlcIilcbiAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAvLyDrsLDsl7TroZwg67OA7ZmYXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZSA6IFt2YWx1ZV0uZmlsdGVyKG5vbk51bGxhYmxlKTtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgY29sdW1uc1twcm9wLm5hbWVdID0ge1xuICAgICAgICAgICAgICAgICAgICBwcm9wLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUgYXMgRml4dHVyZVJlY29yZFtcImNvbHVtbnNcIl1bc3RyaW5nXVtcInZhbHVlXCJdLFxuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgZml4dHVyZUlkOiBgJHtmaXh0dXJlLmVudGl0eUlkfSMke2ZpeHR1cmUuaWR9YCxcbiAgICAgICAgICAgICAgICAgIGVudGl0eUlkOiBmaXh0dXJlLmVudGl0eUlkLFxuICAgICAgICAgICAgICAgICAgaWQ6IGZpeHR1cmUuaWQsXG4gICAgICAgICAgICAgICAgICBjb2x1bW5zLFxuICAgICAgICAgICAgICAgICAgZmV0Y2hlZFJlY29yZHM6IFtdLFxuICAgICAgICAgICAgICAgICAgYmVsb25nc1JlY29yZHM6IFtdLFxuICAgICAgICAgICAgICAgICAgb3ZlcnJpZGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAvLyDsg4gg66CI7L2U65Oc65Ok7J2YIHJlbGF0aW9uIOy7rOufvOydhCDtmZXsnbjtlZjsl6wg6riw7KG0IOugiOy9lOuTnOuTpOydmCDsl63rsKntlqUgcmVsYXRpb24g7JeF642w7J207Yq4XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5ld1JlY29yZCBvZiBuZXdSZWNvcmRzKSB7XG4gICAgICAgICAgICAgIGZvciAoY29uc3QgW19jb2xOYW1lLCBjb2xdIG9mIE9iamVjdC5lbnRyaWVzKG5ld1JlY29yZC5jb2x1bW5zKSkge1xuICAgICAgICAgICAgICAgIGlmIChjb2wucHJvcC50eXBlICE9PSBcInJlbGF0aW9uXCIgfHwgY29sLnZhbHVlID09PSBudWxsKSBjb250aW51ZTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHlJZCA9IGNvbC5wcm9wLndpdGg7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVsYXRlZElkcyA9IEFycmF5LmlzQXJyYXkoY29sLnZhbHVlKSA/IGNvbC52YWx1ZSA6IFtjb2wudmFsdWVdO1xuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWxhdGVkSWQgb2YgcmVsYXRlZElkcykge1xuICAgICAgICAgICAgICAgICAgY29uc3QgcmVsYXRlZEZpeHR1cmVJZCA9IGAke3JlbGF0ZWRFbnRpdHlJZH0jJHtyZWxhdGVkSWR9YDtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRSZWNvcmQgPSBuZXdSZWNvcmRzLmZpbmQoKHIpID0+IHIuZml4dHVyZUlkID09PSByZWxhdGVkRml4dHVyZUlkKTtcblxuICAgICAgICAgICAgICAgICAgaWYgKHJlbGF0ZWRSZWNvcmQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g7Jet67Cp7ZalIHJlbGF0aW9uIOywvuq4sFxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXZlcnNlQ29sID0gT2JqZWN0LmVudHJpZXMocmVsYXRlZFJlY29yZC5jb2x1bW5zKS5maW5kKFxuICAgICAgICAgICAgICAgICAgICAgIChbLCBjXSkgPT4gYy5wcm9wLnR5cGUgPT09IFwicmVsYXRpb25cIiAmJiBjLnByb3Aud2l0aCA9PT0gbmV3UmVjb3JkLmVudGl0eUlkLFxuICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXZlcnNlQ29sKSB7XG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgW3JldmVyc2VDb2xOYW1lLCByZXZlcnNlQ29sVmFsdWVdID0gcmV2ZXJzZUNvbDtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VmFsdWUgPSByZXZlcnNlQ29sVmFsdWUudmFsdWU7XG5cbiAgICAgICAgICAgICAgICAgICAgICAvLyDsl63rsKntlqXsnbQg67Cw7Je07J24IOqyveyasCAoSGFzTWFueSwgTWFueVRvTWFueSlcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICByZXZlcnNlQ29sVmFsdWUucHJvcC50eXBlID09PSBcInJlbGF0aW9uXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChyZXZlcnNlQ29sVmFsdWUucHJvcC5yZWxhdGlvblR5cGUgPT09IFwiSGFzTWFueVwiIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJldmVyc2VDb2xWYWx1ZS5wcm9wLnJlbGF0aW9uVHlwZSA9PT0gXCJNYW55VG9NYW55XCIpXG4gICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnQoQXJyYXkuaXNBcnJheShjdXJyZW50VmFsdWUpLCBcImN1cnJlbnRWYWx1ZSBtdXN0IGJlIGFuIGFycmF5XCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjdXJyZW50VmFsdWUuaW5jbHVkZXMobmV3UmVjb3JkLmlkKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWxhdGVkUmVjb3JkLmNvbHVtbnNbcmV2ZXJzZUNvbE5hbWVdID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnJldmVyc2VDb2xWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogWy4uLmN1cnJlbnRWYWx1ZSwgbmV3UmVjb3JkLmlkXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8g7Jet67Cp7Zal7J20IOuLqOydvCDqsJLsnbgg6rK97JqwIChCZWxvbmdzVG9PbmUsIE9uZVRvT25lKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRlZFJlY29yZC5jb2x1bW5zW3JldmVyc2VDb2xOYW1lXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucmV2ZXJzZUNvbFZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogbmV3UmVjb3JkLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSwgdXBkYXRlZFJlY29yZHM6IG5ld1JlY29yZHMgfTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBoYW5kbGVFbnRpdHkobWVzc2FnZXM6IE1vZGVsTWVzc2FnZVtdKTogU3RyZWFtVGV4dFJlc3VsdDxhbnksIGFueT4ge1xuICAgIGlmICghdGhpcy5haVNkayB8fCAhdGhpcy5tb2RlbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQUkgU0RLIG5vdCBpbml0aWFsaXplZC4gQ2FsbCBpbml0KCkgZmlyc3QuXCIpO1xuICAgIH1cblxuICAgIC8vIGVudGl0eS5pbnN0cnVjdGlvbnMubWQg7YyM7J28IOydveq4sCAoZGlzdC91aSDrmJDripQgc3JjL3Vp7JeQ7IScIOyLpO2WieuQmOuvgOuhnCDtjKjtgqTsp4Ag66Oo7Yq4IOq4sOykgOycvOuhnCDsoJHqt7wpXG4gICAgY29uc3QgaW5zdHJ1Y3Rpb25zUGF0aCA9IHBhdGguam9pbihcbiAgICAgIGltcG9ydC5tZXRhLmRpcm5hbWUsXG4gICAgICBcIi4uXCIsXG4gICAgICBcIi4uXCIsXG4gICAgICBcInNyY1wiLFxuICAgICAgXCJ1aVwiLFxuICAgICAgXCJlbnRpdHkuaW5zdHJ1Y3Rpb25zLm1kXCIsXG4gICAgKTtcbiAgICBjb25zdCBpbnN0cnVjdGlvbnMgPSBmcy5yZWFkRmlsZVN5bmMoaW5zdHJ1Y3Rpb25zUGF0aCwgXCJ1dGYtOFwiKTtcblxuICAgIC8vIO2YhOyerCDrk7HroZ3rkJwg7JeU7Yuw7YuwIOygleuztCDsiJjsp5FcbiAgICBjb25zdCBlbnRpdHlJZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuICAgIGNvbnN0IGV4aXN0aW5nRW50aXRpZXMgPSBlbnRpdHlJZHMubWFwKChlbnRpdHlJZCkgPT4ge1xuICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaWQ6IGVudGl0eS5pZCxcbiAgICAgICAgdGl0bGU6IGVudGl0eS50aXRsZSxcbiAgICAgICAgdGFibGU6IGVudGl0eS50YWJsZSxcbiAgICAgICAgcHJvcHM6IGVudGl0eS5wcm9wcy5tYXAoKHApID0+ICh7XG4gICAgICAgICAgbmFtZTogcC5uYW1lLFxuICAgICAgICAgIHR5cGU6IHAudHlwZSxcbiAgICAgICAgICBkZXNjOiBwLmRlc2MsXG4gICAgICAgIH0pKSxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBjb25zdCBzeXN0ZW1NZXNzYWdlID0gYFxu64u57Iug7J2AIFNvbmFtdSDtlITroIjsnoTsm4ztgazsl5DshJwgRW50aXR57JmAIEVudW3snYQg7IOd7ISx7ZWY64qUIOuPhOyasOuvuOyeheuLiOuLpC5cblxuJHtpbnN0cnVjdGlvbnN9XG5cbiMjIO2YhOyerCDrk7HroZ3rkJwgRW50aXR5IOuqqeuhnVxu64uk66W4IOyXlO2LsO2LsOyZgCDqtIDqs4QocmVsYXRpb24p66W8IOunuuqxsOuCmCBzdWJzZXTsl5DshJwg7LC47KGw7ZWgIOuVjCDrsJjrk5zsi5wg7JWE656YIOygleuztOulvCDtmZXsnbjtlZjshLjsmpQuXG5cbiR7SlNPTi5zdHJpbmdpZnkoZXhpc3RpbmdFbnRpdGllcywgbnVsbCwgMil9XG5cbiMjIFRvb2wg7IKs7JqpIOqwgOydtOuTnFxuXG4jIyMgRW50aXR5IOyDneyEsSAoY3JlYXRlRW50aXR5KVxu7IKs7Jqp7J6Q6rCAIOyDiOuhnOyatCBFbnRpdHkg7IOd7ISx7J2EIOyalOyyre2VmOuptCBjcmVhdGVFbnRpdHkg64+E6rWs66W8IOyCrOyaqe2VmOyEuOyalC5cbi0gZW50aXR5SWQ6IFBhc2NhbENhc2XroZwg65CcIEVudGl0eSBJRCAo7JiIOiBcIlVzZXJcIiwgXCJQcm9kdWN0Q2F0ZWdvcnlcIilcbi0gdGl0bGU6IO2VnOq4gCDsoJzrqqkgKOyYiDogXCLsgqzsmqnsnpBcIiwgXCLsg4Htkogg7Lm07YWM6rOg66asXCIpXG4tIHRhYmxlOiBzbmFrZV9jYXNl66GcIOuQnCDthYzsnbTruJTrqoUgKOyYiDogXCJ1c2Vyc1wiLCBcInByb2R1Y3RfY2F0ZWdvcmllc1wiKVxuLSBwYXJlbnRJZDog67aA66qoIEVudGl0eSBJRCAo7ISg7YOd7IKs7ZWtKVxuLSBwcm9wczogRW50aXR57J2YIO2UhOuhnO2NvO2LsCDrsLDsl7QgKOychCDrrLjshJzsnZggUHJvcGVydHkgVHlwZXMg7LC46rOgKVxuLSBpbmRleGVzOiDsnbjrjbHsiqQg67Cw7Je0XG4tIHN1YnNldHM6IOyEnOu4jOyFiyDsoJXsnZggKOq4sOuzuOqwkjogeyBBOiBbXCJpZFwiXSB9KVxuLSBlbnVtczogRW51bSDsoJXsnZhcblxuIyMjIEVudGl0eSDsiJjsoJUgKHVwZGF0ZUVudGl0eSlcbuq4sOyhtCBFbnRpdHnrpbwg7IiY7KCV7ZWgIOuVjCB1cGRhdGVFbnRpdHkg64+E6rWs66W8IOyCrOyaqe2VmOyEuOyalC4gRW51bSDstpTqsIAsIHByb3BzIOy2lOqwgC/siJjsoJUsIGluZGV4ZXMg7IiY7KCVIOuTsSDrqqjrk6Ag7IiY7KCVIOyekeyXheyXkCDsgqzsmqntlanri4jri6QuXG4tIGVudGl0eUlkOiDsiJjsoJXtlaAgRW50aXR5IElEXG4tIHVwZGF0ZXM6IOyImOygle2VoCDtlYTrk5zrk6QgKOu2gOu2hCDsl4XrjbDsnbTtirgpXG4gIC0gdGl0bGU6IOyXlO2LsO2LsCDtlZzquIAg7KCc66qpXG4gIC0gdGFibGU6IO2FjOydtOu4lOuqhVxuICAtIHByb3BzOiDstpTqsIDtlaAg7ZSE66Gc7Y287YuwIOuwsOyXtCAo6riw7KG0IHByb3Bz7JeQIOy2lOqwgCwg6rCZ7J2AIOydtOumhOydtOuptCDqtZDssrQpXG4gIC0gaW5kZXhlczog7LaU6rCA7ZWgIOyduOuNseyKpCDrsLDsl7QgKOq4sOyhtCBpbmRleGVz7JeQIOy2lOqwgClcbiAgLSBzdWJzZXRzOiDshJzruIzshYsg7KCV7J2YICjquLDsobQgc3Vic2V0c+yXkCDrs5HtlakpXG4gIC0gZW51bUxhYmVsczogRW51bSDsoJXsnZggKOq4sOyhtCBlbnVtTGFiZWxz7JeQIOuzke2VqSlcbi0gbW9kZTogXCJtZXJnZVwiKOq4sOuzuOqwkikg65iQ64qUIFwicmVwbGFjZVwiXG4gIC0gbWVyZ2U6IOq4sOyhtCDqsJLsl5Ag67OR7ZWpXG4gIC0gcmVwbGFjZTog7ZW064u5IO2VhOuTnCDsoITssrQg6rWQ7LK0XG5cbuyYiOyLnDogRW1wbG95ZWXsl5Ag7IOIIEVudW0g7LaU6rCAXG51cGRhdGVFbnRpdHkoeyBlbnRpdHlJZDogXCJFbXBsb3llZVwiLCB1cGRhdGVzOiB7IGVudW1MYWJlbHM6IHsgXCJFbXBsb3llZVJvbGVcIjogeyBcImFkbWluXCI6IFwi6rSA66as7J6QXCIsIFwidXNlclwiOiBcIuydvOuwmFwiIH0gfSB9IH0pXG5cbuyYiOyLnDogUHJvamVjdOyXkCDsg4gg7ZSE66Gc7Y287YuwIOy2lOqwgFxudXBkYXRlRW50aXR5KHsgZW50aXR5SWQ6IFwiUHJvamVjdFwiLCB1cGRhdGVzOiB7IHByb3BzOiBbeyBuYW1lOiBcInByaW9yaXR5XCIsIHR5cGU6IFwiaW50ZWdlclwiLCBkZXNjOiBcIuyasOyEoOyInOychFwiIH1dIH0gfSlcblxuIyMg7ZWE7IiYIOyCrO2VrVxuLSBFbnRpdHnsnZggcHJvcHPsl5DripQg7LWc7IaM7ZWcIGlkKGludGVnZXIsIHVuc2lnbmVkKSwgY3JlYXRlZF9hdCh0aW1lc3RhbXAp6rCAIO2PrO2VqOuQmOyWtOyVvCDtlanri4jri6QuXG4tIHJlbGF0aW9uIO2VhOuTnOuKlCBvblVwZGF0ZSwgb25EZWxldGXqsIAg7ZWE7IiY7J6F64uI64ukLiAo7JiI7Jm4OiBPbmVUb09uZeyXkOyEnCBoYXNKb2luQ29sdW1u7J20IGZhbHNl7J24IOqyveyasClcbi0gRW51bSBJROuKlCDrs7TthrUgRW50aXR5SWQgKyDsho3shLHrqoUg7ZiV7YOc7J6F64uI64ukICjsmIg6IFVzZXJTdGF0dXMsIFByb2R1Y3RUeXBlKVxuLSBzdWJzZXTsl5DshJwg64uk66W4IOyXlO2LsO2LsOydmCDtlITroZztjbzti7Drpbwg7LC47KGw7ZWgIOuVjOuKlCDrsJjrk5zsi5wg7ZW064u5IOyXlO2LsO2LsOydmCDsi6TsoJwg7ZSE66Gc7Y287Yuw66qF7J2EIOyCrOyaqe2VmOyEuOyalC5cblxuIyMg6rKA7KadIOyYpOulmCDsspjrpqxcbuuPhOq1rCDtmLjstpwg6rKw6rO866GcIOqygOymnSDsmKTrpZgodmFsaWRhdGlvbkVycm9ycynqsIAg67CY7ZmY65CY66m0OlxuMS4g7Jik66WYIOuplOyLnOyngOulvCDrtoTshJ3tlZjsl6wg66y47KCc7KCQ7J2EIO2MjOyVhe2VmOyEuOyalC5cbjIuIOyYpOulmOulvCDsiJjsoJXtlZwg642w7J207YSw66GcIGNyZWF0ZUVudGl0eeulvCDri6Tsi5wg7Zi47Lac7ZWY7IS47JqULlxuMy4g7IKs7Jqp7J6Q7JeQ6rKMIOyYpOulmOulvCDqt7jrjIDroZwg7KCE64us7ZWY7KeAIOunkOqzoCwg7IiY7KCVIO2bhCDsnqzsi5zrj4TtlZjshLjsmpQuXG5cbiMjIyDsnbzrsJjsoIHsnbgg6rKA7KadIOyYpOulmOyZgCDsiJjsoJUg67Cp67KVXG58IOyYpOulmCDrqZTsi5zsp4AgfCDsiJjsoJUg67Cp67KVIHxcbnwtLS0tLS0tLS0tLS18LS0tLS0tLS0tLXxcbnwgXCJpZCDtlITroZztjbzti7DqsIAg7ZWE7IiYXCIgfCBwcm9wc+yXkCB7IG5hbWU6IFwiaWRcIiwgdHlwZTogXCJpbnRlZ2VyXCIsIHVuc2lnbmVkOiB0cnVlIH0g7LaU6rCAIHxcbnwgXCJjcmVhdGVkX2F0IO2UhOuhnO2NvO2LsOqwgCDtlYTsiJhcIiB8IHByb3Bz7JeQIHsgbmFtZTogXCJjcmVhdGVkX2F0XCIsIHR5cGU6IFwidGltZXN0YW1wXCIsIGRiRGVmYXVsdDogXCJDVVJSRU5UX1RJTUVTVEFNUFwiIH0g7LaU6rCAIHxcbnwgXCJYeHhPcmRlckJ5IGVudW3snbQg7ZWE7IiYXCIgfCBlbnVtc+yXkCB7IFwiWHh4T3JkZXJCeVwiOiB7IFwiaWQtZGVzY1wiOiBcIklE7LWc7Iug7IicXCIgfSB9IOy2lOqwgCB8XG58IFwiWHh4U2VhcmNoRmllbGQgZW51beydtCDtlYTsiJhcIiB8IGVudW1z7JeQIHsgXCJYeHhTZWFyY2hGaWVsZFwiOiB7IFwiaWRcIjogXCJJRFwiIH0gfSDstpTqsIAgfFxufCBcInN0cmluZyDtg4DsnoXsnYAgbGVuZ3Ro6rCAIO2VhOyImFwiIHwg7ZW064u5IHByb3Dsl5AgbGVuZ3RoIOy2lOqwgCAo7JiIOiAyNTUpIHxcbnwgXCJ0ZXh0IO2DgOyeheydgCB0ZXh0VHlwZeydtCDtlYTsiJhcIiB8IO2VtOuLuSBwcm9w7JeQIHRleHRUeXBlIOy2lOqwgCAoXCJ0ZXh0XCIsIFwibWVkaXVtdGV4dFwiLCBcImxvbmd0ZXh0XCIpIHxcbnwgXCJvblVwZGF0ZeqwgCDtlYTsiJhcIiB8IO2VtOuLuSByZWxhdGlvbiBwcm9w7JeQIG9uVXBkYXRlLCBvbkRlbGV0ZSDstpTqsIAgKFwiQ0FTQ0FERVwiKSB8XG4gICAgICBgO1xuXG4gICAgY29uc3QgeyBzdHJlYW1UZXh0LCB0b29sLCBzdGVwQ291bnRJcyB9ID0gdGhpcy5haVNkaztcblxuICAgIHJldHVybiBzdHJlYW1UZXh0KHtcbiAgICAgIG1vZGVsOiB0aGlzLm1vZGVsIGFzIHVua25vd24gYXMgTGFuZ3VhZ2VNb2RlbCxcbiAgICAgIHN5c3RlbTogc3lzdGVtTWVzc2FnZSxcbiAgICAgIG1lc3NhZ2VzLFxuICAgICAgc3RvcFdoZW46IHN0ZXBDb3VudElzKDIpLFxuICAgICAgdG9vbHM6IHtcbiAgICAgICAgY3JlYXRlRW50aXR5OiB0b29sKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwi7IOI66Gc7Jq0IEVudGl0eeulvCDsg53shLHtlanri4jri6QuIOyCrOyaqeyekOqwgCDsg4jroZzsmrQg7JeU7Yuw7Yuw64KYIO2FjOydtOu4lCDsg53shLHsnYQg7JqU7LKt7ZWgIOuVjCDsgqzsmqntlZjshLjsmpQuXCIsXG4gICAgICAgICAgaW5wdXRTY2hlbWE6IFRlbXBsYXRlT3B0aW9ucy5zaGFwZS5lbnRpdHksXG4gICAgICAgICAgZXhlY3V0ZTogYXN5bmMgKFxuICAgICAgICAgICAgZW50aXR5OiB6LmluZmVyPHR5cGVvZiBUZW1wbGF0ZU9wdGlvbnMuc2hhcGUuZW50aXR5PixcbiAgICAgICAgICApOiBQcm9taXNlPHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGJvb2xlYW47XG4gICAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgICAgZXJyb3I/OiBzdHJpbmc7XG4gICAgICAgICAgICB2YWxpZGF0aW9uRXJyb3JzPzogVmFsaWRhdGlvbkVycm9yW107XG4gICAgICAgICAgfT4gPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgLy8g7J6F66ClIOqygOymnVxuICAgICAgICAgICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGVFbnRpdHlKc29uKGVudGl0eSk7XG5cbiAgICAgICAgICAgICAgaWYgKHZhbGlkYXRpb25FcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIGVudGl0eUlkOiBlbnRpdHkuZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgICBlcnJvcjogYOqygOymnSDsmKTrpZg6ICR7dmFsaWRhdGlvbkVycm9ycy5tYXAoKGUpID0+IGBbJHtlLmZpZWxkfV0gJHtlLm1lc3NhZ2V9YCkuam9pbihcIiwgXCIpfWAsXG4gICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBhd2FpdCBTb25hbXUuc3luY2VyLmNyZWF0ZUVudGl0eSh7XG4gICAgICAgICAgICAgICAgc3Vic2V0czogeyBBOiBbXCJpZFwiXSB9LFxuICAgICAgICAgICAgICAgIGVudW1zOiB7fSxcbiAgICAgICAgICAgICAgICAuLi5lbnRpdHksXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIC8vIEVudGl0eU1hbmFnZXIg66as66Gc65OcXG4gICAgICAgICAgICAgIGF3YWl0IEVudGl0eU1hbmFnZXIucmVsb2FkKCk7XG5cbiAgICAgICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSwgZW50aXR5SWQ6IGVudGl0eS5lbnRpdHlJZCB9O1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFwiVW5rbm93biBlcnJvclwiO1xuICAgICAgICAgICAgICByZXR1cm4geyBzdWNjZXNzOiBmYWxzZSwgZW50aXR5SWQ6IGVudGl0eS5lbnRpdHlJZCwgZXJyb3IgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICAgdXBkYXRlRW50aXR5OiB0b29sKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwi6riw7KG0IEVudGl0eeulvCDsiJjsoJXtlanri4jri6QuIEVudW0g7LaU6rCALCBwcm9wcyDstpTqsIAv7IiY7KCVLCBpbmRleGVzIOyImOyglSwgc3Vic2V0cyDsiJjsoJUg65OxIOuqqOuToCDsl5Tti7Dti7Ag7IiY7KCVIOyekeyXheyXkCDsgqzsmqntlZjshLjsmpQuXCIsXG4gICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHtcbiAgICAgICAgICAgIGVudGl0eUlkOiB6LnN0cmluZygpLmRlc2NyaWJlKFwi7IiY7KCV7ZWgIEVudGl0eSBJRFwiKSxcbiAgICAgICAgICAgIHVwZGF0ZXM6IFRlbXBsYXRlT3B0aW9ucy5zaGFwZS5lbnRpdHkucGFydGlhbCgpLmRlc2NyaWJlKFwi7IiY7KCV7ZWgIO2VhOuTnOuTpFwiKSxcbiAgICAgICAgICAgIG1vZGU6IHpcbiAgICAgICAgICAgICAgLmVudW0oW1wibWVyZ2VcIiwgXCJyZXBsYWNlXCJdKVxuICAgICAgICAgICAgICAub3B0aW9uYWwoKVxuICAgICAgICAgICAgICAuZGVzY3JpYmUoXCLsiJjsoJUg66qo65OcOiBtZXJnZSjquLDrs7jqsJIsIOq4sOyhtCDqsJLsl5Ag67OR7ZWpKSDrmJDripQgcmVwbGFjZSjsoITssrQg6rWQ7LK0KVwiKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBleGVjdXRlOiBhc3luYyAoe1xuICAgICAgICAgICAgZW50aXR5SWQsXG4gICAgICAgICAgICB1cGRhdGVzLFxuICAgICAgICAgICAgbW9kZSA9IFwibWVyZ2VcIixcbiAgICAgICAgICB9OiB7XG4gICAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgICAgdXBkYXRlczogUGFydGlhbDx6LmluZmVyPHR5cGVvZiBUZW1wbGF0ZU9wdGlvbnMuc2hhcGUuZW50aXR5Pj47XG4gICAgICAgICAgICBtb2RlPzogXCJtZXJnZVwiIHwgXCJyZXBsYWNlXCI7XG4gICAgICAgICAgfSk6IFByb21pc2U8e1xuICAgICAgICAgICAgc3VjY2VzczogYm9vbGVhbjtcbiAgICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgICBlcnJvcj86IHN0cmluZztcbiAgICAgICAgICAgIHZhbGlkYXRpb25FcnJvcnM/OiBWYWxpZGF0aW9uRXJyb3JbXTtcbiAgICAgICAgICB9PiA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgICAgICAgICAgLy8gVXBkYXRlIGJhc2ljIHByb3BlcnRpZXNcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMuZW50aXR5SWQgIT09IHVuZGVmaW5lZCkgZW50aXR5LmlkID0gdXBkYXRlcy5lbnRpdHlJZDtcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMucGFyZW50SWQgIT09IHVuZGVmaW5lZCkgZW50aXR5LnBhcmVudElkID0gdXBkYXRlcy5wYXJlbnRJZDtcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMudGl0bGUgIT09IHVuZGVmaW5lZCkgZW50aXR5LnRpdGxlID0gdXBkYXRlcy50aXRsZTtcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMudGFibGUgIT09IHVuZGVmaW5lZCkgZW50aXR5LnRhYmxlID0gdXBkYXRlcy50YWJsZTtcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMuY29uZSAhPT0gdW5kZWZpbmVkKSBlbnRpdHkuY29uZSA9IHVwZGF0ZXMuY29uZTtcblxuICAgICAgICAgICAgICAvLyBwcm9wczogbWVyZ2Ug7IucIOydtOumhCDquLDspIAg67OR7ZWpLCByZXBsYWNlIOyLnCDqtZDssrRcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMucHJvcHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGlmIChtb2RlID09PSBcInJlcGxhY2VcIikge1xuICAgICAgICAgICAgICAgICAgZW50aXR5LnByb3BzID0gdXBkYXRlcy5wcm9wcyBhcyBFbnRpdHlQcm9wW107XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgbmV3UHJvcCBvZiB1cGRhdGVzLnByb3BzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nSW5kZXggPSBlbnRpdHkucHJvcHMuZmluZEluZGV4KChwKSA9PiBwLm5hbWUgPT09IG5ld1Byb3AubmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChleGlzdGluZ0luZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICBlbnRpdHkucHJvcHNbZXhpc3RpbmdJbmRleF0gPSBuZXdQcm9wIGFzIEVudGl0eVByb3A7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgZW50aXR5LnByb3BzLnB1c2gobmV3UHJvcCBhcyBFbnRpdHlQcm9wKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIGluZGV4ZXM6IG1lcmdlIOyLnCDstpTqsIAsIHJlcGxhY2Ug7IucIOq1kOyytFxuICAgICAgICAgICAgICBpZiAodXBkYXRlcy5pbmRleGVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBlbnRpdHkuaW5kZXhlcyA9XG4gICAgICAgICAgICAgICAgICBtb2RlID09PSBcInJlcGxhY2VcIiA/IHVwZGF0ZXMuaW5kZXhlcyA6IFsuLi5lbnRpdHkuaW5kZXhlcywgLi4udXBkYXRlcy5pbmRleGVzXTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIHN1YnNldHMsIHN1YnNldHNJbnRlcm5hbDogYXNzaWdu7Jy866GcIOuzke2VqSDrmJDripQg6rWQ7LK0XG4gICAgICAgICAgICAgIGlmICh1cGRhdGVzLnN1YnNldHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIC8vIE5vcm1hbGl6ZSBzdWJzZXQgZmllbGRzOiBzZXBhcmF0ZSBpbnRvIHN1YnNldHMgKG5vcm1hbCkgYW5kIHN1YnNldHNJbnRlcm5hbCAoaW50ZXJuYWwpXG4gICAgICAgICAgICAgICAgY29uc3Qgbm9ybWFsaXplZFN1YnNldHM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nW10gfSA9IHt9O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRTdWJzZXRzSW50ZXJuYWw6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nW10gfSA9IHt9O1xuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBba2V5LCBmaWVsZHNdIG9mIE9iamVjdC5lbnRyaWVzKHVwZGF0ZXMuc3Vic2V0cykpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZpZWxkQXJyYXkgPSBmaWVsZHMgYXMgc3RyaW5nW107XG4gICAgICAgICAgICAgICAgICBub3JtYWxpemVkU3Vic2V0c1trZXldID0gZmllbGRBcnJheVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKChmOiBzdHJpbmcpID0+ICFpc0ludGVybmFsU3Vic2V0RmllbGQoZikpXG4gICAgICAgICAgICAgICAgICAgIC5tYXAobm9ybWFsaXplU3Vic2V0RmllbGQpO1xuICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZFN1YnNldHNJbnRlcm5hbFtrZXldID0gZmllbGRBcnJheVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGlzSW50ZXJuYWxTdWJzZXRGaWVsZClcbiAgICAgICAgICAgICAgICAgICAgLm1hcChub3JtYWxpemVTdWJzZXRGaWVsZCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZW50aXR5LnN1YnNldHMgPVxuICAgICAgICAgICAgICAgICAgbW9kZSA9PT0gXCJyZXBsYWNlXCJcbiAgICAgICAgICAgICAgICAgICAgPyBub3JtYWxpemVkU3Vic2V0c1xuICAgICAgICAgICAgICAgICAgICA6IHsgLi4uZW50aXR5LnN1YnNldHMsIC4uLm5vcm1hbGl6ZWRTdWJzZXRzIH07XG4gICAgICAgICAgICAgICAgZW50aXR5LnN1YnNldHNJbnRlcm5hbCA9XG4gICAgICAgICAgICAgICAgICBtb2RlID09PSBcInJlcGxhY2VcIlxuICAgICAgICAgICAgICAgICAgICA/IG5vcm1hbGl6ZWRTdWJzZXRzSW50ZXJuYWxcbiAgICAgICAgICAgICAgICAgICAgOiB7IC4uLmVudGl0eS5zdWJzZXRzSW50ZXJuYWwsIC4uLm5vcm1hbGl6ZWRTdWJzZXRzSW50ZXJuYWwgfTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmICh1cGRhdGVzLmVudW1zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb252ZXJ0ZWRFbnVtcyA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKHVwZGF0ZXMuZW51bXMpLm1hcCgoW2tleSwgZW51bURlZl0pID0+IFtcbiAgICAgICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgICAgICBnZXRFbnVtRGVmVmFsdWVzKGVudW1EZWYpLFxuICAgICAgICAgICAgICAgICAgXSksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBlbnRpdHkuZW51bUxhYmVscyA9XG4gICAgICAgICAgICAgICAgICBtb2RlID09PSBcInJlcGxhY2VcIiA/IGNvbnZlcnRlZEVudW1zIDogeyAuLi5lbnRpdHkuZW51bUxhYmVscywgLi4uY29udmVydGVkRW51bXMgfTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIOyggOyepSDsoIQg6rKA7KadXG4gICAgICAgICAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0ZUVudGl0eUpzb24oe1xuICAgICAgICAgICAgICAgIC4uLmVudGl0eSxcbiAgICAgICAgICAgICAgICBlbnRpdHlJZDogZW50aXR5LmlkLFxuICAgICAgICAgICAgICAgIGVudW1zOiBlbnRpdHkuZW51bUxhYmVscyxcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgaWYgKHZhbGlkYXRpb25FcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIGVudGl0eUlkLFxuICAgICAgICAgICAgICAgICAgZXJyb3I6IGDqsoDspp0g7Jik66WYOiAke3ZhbGlkYXRpb25FcnJvcnMubWFwKChlKSA9PiBgWyR7ZS5maWVsZH1dICR7ZS5tZXNzYWdlfWApLmpvaW4oXCIsIFwiKX1gLFxuICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcblxuICAgICAgICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCBlbnRpdHlJZCB9O1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFwiVW5rbm93biBlcnJvclwiO1xuICAgICAgICAgICAgICByZXR1cm4geyBzdWNjZXNzOiBmYWxzZSwgZW50aXR5SWQsIGVycm9yIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogRW50aXR5IEpTT07snbQgZW50aXR5Lmluc3RydWN0aW9ucy5tZOydmCDqt5zsuZnsnYQg65Sw66W064qU7KeAIOqygOymne2VqeuLiOuLpC5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVFbnRpdHlKc29uKGlucHV0OiBUZW1wbGF0ZU9wdGlvbnNbXCJlbnRpdHlcIl0pOiBWYWxpZGF0aW9uRXJyb3JbXSB7XG4gIGNvbnN0IGVycm9yczogVmFsaWRhdGlvbkVycm9yW10gPSBbXTtcbiAgY29uc3QgeyBlbnRpdHlJZCwgcHJvcHMsIGVudW1zIH0gPSBpbnB1dDtcblxuICAvLyAxLiBpZCwgY3JlYXRlZF9hdCBwcm9wIO2VhOyImFxuICBjb25zdCBoYXNJZFByb3AgPSBwcm9wcz8uc29tZSgocCkgPT4gcC5uYW1lID09PSBcImlkXCIpO1xuICBpZiAoIWhhc0lkUHJvcCkge1xuICAgIGVycm9ycy5wdXNoKHsgZmllbGQ6IFwicHJvcHNcIiwgbWVzc2FnZTogXCJpZCDtlITroZztjbzti7DqsIAg7ZWE7IiY7J6F64uI64ukLlwiIH0pO1xuICB9XG4gIGNvbnN0IGhhc0NyZWF0ZWRBdFByb3AgPSBwcm9wcz8uc29tZSgocCkgPT4gcC5uYW1lID09PSBcImNyZWF0ZWRfYXRcIik7XG4gIGlmICghaGFzQ3JlYXRlZEF0UHJvcCkge1xuICAgIGVycm9ycy5wdXNoKHsgZmllbGQ6IFwicHJvcHNcIiwgbWVzc2FnZTogXCJjcmVhdGVkX2F0IO2UhOuhnO2NvO2LsOqwgCDtlYTsiJjsnoXri4jri6QuXCIgfSk7XG4gIH1cblxuICAvLyAyLiDtlYTsiJggZW51bSDqsoDspp06IEVudGl0eU5hbWVPcmRlckJ5LCBFbnRpdHlOYW1lU2VhcmNoRmllbGRcbiAgY29uc3Qgb3JkZXJCeUVudW1JZCA9IGAke2VudGl0eUlkfU9yZGVyQnlgO1xuICBjb25zdCBzZWFyY2hGaWVsZEVudW1JZCA9IGAke2VudGl0eUlkfVNlYXJjaEZpZWxkYDtcblxuICBpZiAoIWVudW1zPy5bb3JkZXJCeUVudW1JZF0pIHtcbiAgICBlcnJvcnMucHVzaCh7XG4gICAgICBmaWVsZDogXCJlbnVtc1wiLFxuICAgICAgbWVzc2FnZTogYCR7b3JkZXJCeUVudW1JZH0gZW51beydtCDtlYTsiJjsnoXri4jri6QuICjsmIg6IHsgXCJpZC1kZXNjXCI6IFwiSUTstZzsi6DsiJxcIiB9KWAsXG4gICAgfSk7XG4gIH1cbiAgaWYgKCFlbnVtcz8uW3NlYXJjaEZpZWxkRW51bUlkXSkge1xuICAgIGVycm9ycy5wdXNoKHtcbiAgICAgIGZpZWxkOiBcImVudW1zXCIsXG4gICAgICBtZXNzYWdlOiBgJHtzZWFyY2hGaWVsZEVudW1JZH0gZW51beydtCDtlYTsiJjsnoXri4jri6QuICjsmIg6IHsgXCJpZFwiOiBcIklEXCIgfSlgLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gMy4gZW51bSBwcm9w7J2YIGlk6rCAIGVudW1z7JeQIOygleydmOuQmOyWtCDsnojripTsp4Ag7ZmV7J24IChjcm9zcy1maWVsZCDqsoDspp0pXG4gIGZvciAoY29uc3QgcHJvcCBvZiBwcm9wcyA/PyBbXSkge1xuICAgIGlmIChwcm9wLnR5cGUgPT09IFwiZW51bVwiICYmICFlbnVtcz8uW3Byb3AuaWRdKSB7XG4gICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgIGZpZWxkOiBgcHJvcHMuJHtwcm9wLm5hbWV9YCxcbiAgICAgICAgbWVzc2FnZTogYGVudW0gaWQgXCIke3Byb3AuaWR9XCLqsIAgZW51bXPsl5Ag7KCV7J2Y65CY7Ja0IOyeiOyngCDslYrsirXri4jri6QuYCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlcnJvcnM7XG59XG5cbmV4cG9ydCBjb25zdCBhaUNsaWVudCA9IG5ldyBBSUNsaWVudCgpO1xuIl0sIm5hbWVzIjpbImFzc2VydCIsImZzIiwicGF0aCIsInoiLCJTb25hbXUiLCJFbnRpdHlNYW5hZ2VyIiwiZ2V0RW51bURlZlZhbHVlcyIsImlzSW50ZXJuYWxTdWJzZXRGaWVsZCIsIm5vcm1hbGl6ZVN1YnNldEZpZWxkIiwiVGVtcGxhdGVPcHRpb25zIiwibm9uTnVsbGFibGUiLCJBSUNsaWVudCIsIm1vZGVsIiwiYWlTZGsiLCJpbml0IiwiYW50aHJvcGljIiwiYWlNb2R1bGUiLCJlcnJvciIsImNvbnNvbGUiLCJ3YXJuIiwiaGFuZGxlRml4dHVyZSIsIm1lc3NhZ2VzIiwiZml4dHVyZVJlY29yZHMiLCJFcnJvciIsInVzZWRFbnRpdHlJZHMiLCJTZXQiLCJtYXAiLCJyIiwiZW50aXR5SWQiLCJlbnRpdHlTdHJ1Y3R1cmVzIiwiZW50aXR5IiwiZ2V0IiwiaWQiLCJ0YWJsZSIsInByb3BzIiwicmVsYXRpb25zIiwiZW51bUxhYmVscyIsInN5c3RlbU1lc3NhZ2UiLCJKU09OIiwic3RyaW5naWZ5Iiwic3RyZWFtVGV4dCIsInRvb2wiLCJzeXN0ZW0iLCJ0b29scyIsInVwZGF0ZUZpeHR1cmVzIiwiZGVzY3JpcHRpb24iLCJpbnB1dFNjaGVtYSIsIm9iamVjdCIsInVwZGF0ZXMiLCJhcnJheSIsImZpeHR1cmVJZCIsInN0cmluZyIsImRlc2NyaWJlIiwicmVjb3JkIiwidW5rbm93biIsImV4ZWN1dGUiLCJ1cGRhdGVkUmVjb3JkcyIsInVwZGF0ZSIsImZpbmQiLCJ1IiwiY29sdW1uTmFtZSIsIm5ld1ZhbHVlIiwiT2JqZWN0IiwiZW50cmllcyIsImNvbHVtbnMiLCJ2YWx1ZSIsInN1Y2Nlc3MiLCJjcmVhdGVGaXh0dXJlcyIsImZpeHR1cmVzIiwibnVtYmVyIiwibmV3UmVjb3JkcyIsImZpeHR1cmUiLCJwcm9wIiwidHlwZSIsIm5hbWUiLCJEYXRlIiwidG9JU09TdHJpbmciLCJyZWxhdGlvblR5cGUiLCJBcnJheSIsImlzQXJyYXkiLCJmaWx0ZXIiLCJmZXRjaGVkUmVjb3JkcyIsImJlbG9uZ3NSZWNvcmRzIiwib3ZlcnJpZGUiLCJuZXdSZWNvcmQiLCJfY29sTmFtZSIsImNvbCIsInJlbGF0ZWRFbnRpdHlJZCIsIndpdGgiLCJyZWxhdGVkSWRzIiwicmVsYXRlZElkIiwicmVsYXRlZEZpeHR1cmVJZCIsInJlbGF0ZWRSZWNvcmQiLCJyZXZlcnNlQ29sIiwiYyIsInJldmVyc2VDb2xOYW1lIiwicmV2ZXJzZUNvbFZhbHVlIiwiY3VycmVudFZhbHVlIiwiaW5jbHVkZXMiLCJoYW5kbGVFbnRpdHkiLCJpbnN0cnVjdGlvbnNQYXRoIiwiam9pbiIsImRpcm5hbWUiLCJpbnN0cnVjdGlvbnMiLCJyZWFkRmlsZVN5bmMiLCJlbnRpdHlJZHMiLCJnZXRBbGxJZHMiLCJleGlzdGluZ0VudGl0aWVzIiwidGl0bGUiLCJwIiwiZGVzYyIsInN0ZXBDb3VudElzIiwic3RvcFdoZW4iLCJjcmVhdGVFbnRpdHkiLCJzaGFwZSIsInZhbGlkYXRpb25FcnJvcnMiLCJ2YWxpZGF0ZUVudGl0eUpzb24iLCJsZW5ndGgiLCJlIiwiZmllbGQiLCJtZXNzYWdlIiwic3luY2VyIiwic3Vic2V0cyIsIkEiLCJlbnVtcyIsInJlbG9hZCIsInVwZGF0ZUVudGl0eSIsInBhcnRpYWwiLCJtb2RlIiwiZW51bSIsIm9wdGlvbmFsIiwidW5kZWZpbmVkIiwicGFyZW50SWQiLCJjb25lIiwibmV3UHJvcCIsImV4aXN0aW5nSW5kZXgiLCJmaW5kSW5kZXgiLCJwdXNoIiwiaW5kZXhlcyIsIm5vcm1hbGl6ZWRTdWJzZXRzIiwibm9ybWFsaXplZFN1YnNldHNJbnRlcm5hbCIsImtleSIsImZpZWxkcyIsImZpZWxkQXJyYXkiLCJmIiwic3Vic2V0c0ludGVybmFsIiwiY29udmVydGVkRW51bXMiLCJmcm9tRW50cmllcyIsImVudW1EZWYiLCJzYXZlIiwiaW5wdXQiLCJlcnJvcnMiLCJoYXNJZFByb3AiLCJzb21lIiwiaGFzQ3JlYXRlZEF0UHJvcCIsIm9yZGVyQnlFbnVtSWQiLCJzZWFyY2hGaWVsZEVudW1JZCIsImFpQ2xpZW50Il0sIm1hcHBpbmdzIjoiQUFBQSxpRkFBaUYsR0FFakYsT0FBT0EsWUFBWSxTQUFTO0FBQzVCLE9BQU9DLFFBQVEsS0FBSztBQUNwQixPQUFPQyxVQUFVLE9BQU87QUFDeEIsU0FBU0MsQ0FBQyxRQUFRLE1BQU07QUFDeEIsU0FBU0MsTUFBTSxRQUFRLGtC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
|
|
444
|
+
//#endregion
|
|
445
|
+
init_ai_client();
|
|
446
|
+
export { aiClient, init_ai_client };
|
|
447
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWktY2xpZW50LmpzIiwibmFtZXMiOlsiZXJyb3JzOiBWYWxpZGF0aW9uRXJyb3JbXSIsInoiLCJ1cGRhdGVkUmVjb3JkczogRml4dHVyZVJlY29yZFtdIiwibmV3UmVjb3JkczogRml4dHVyZVJlY29yZFtdIiwiY29sdW1uczogRml4dHVyZVJlY29yZFtcImNvbHVtbnNcIl0iLCJub3JtYWxpemVkU3Vic2V0czogeyBba2V5OiBzdHJpbmddOiBzdHJpbmdbXSB9Iiwibm9ybWFsaXplZFN1YnNldHNJbnRlcm5hbDogeyBba2V5OiBzdHJpbmddOiBzdHJpbmdbXSB9Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3VpL2FpLWNsaWVudC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgYXNzZXJ0IGZyb20gXCJhc3NlcnRcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbi8qIG94bGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi8gLy8gQUkgU0RL7J2YIO2DgOyeheydtCDrqoXtmZXtlZjsp4Ag7JWK7JWEIGFueeulvCDtl4jsmqntlahcbmltcG9ydCB7IHR5cGUgTGFuZ3VhZ2VNb2RlbCwgdHlwZSBNb2RlbE1lc3NhZ2UsIHR5cGUgU3RyZWFtVGV4dFJlc3VsdCB9IGZyb20gXCJhaVwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcblxuaW1wb3J0IHsgU29uYW11IH0gZnJvbSBcIi4uL2FwaS9zb25hbXVcIjtcbmltcG9ydCB7IEVudGl0eU1hbmFnZXIgfSBmcm9tIFwiLi4vZW50aXR5L2VudGl0eS1tYW5hZ2VyXCI7XG5pbXBvcnQge1xuICBnZXRFbnVtRGVmVmFsdWVzLFxuICBpc0ludGVybmFsU3Vic2V0RmllbGQsXG4gIG5vcm1hbGl6ZVN1YnNldEZpZWxkLFxuICBUZW1wbGF0ZU9wdGlvbnMsXG59IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgdHlwZSBFbnRpdHlQcm9wLCB0eXBlIEZpeHR1cmVSZWNvcmQgfSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IG5vbk51bGxhYmxlIH0gZnJvbSBcIi4uL3V0aWxzL3V0aWxzXCI7XG5cbnR5cGUgVmFsaWRhdGlvbkVycm9yID0ge1xuICBmaWVsZDogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG59O1xuXG5jbGFzcyBBSUNsaWVudCB7XG4gIHByaXZhdGUgbW9kZWw6IExhbmd1YWdlTW9kZWwgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBhaVNkazpcbiAgICB8ICh0eXBlb2YgaW1wb3J0KFwiYWlcIikgJiB7XG4gICAgICAgIGFudGhyb3BpYz86IHR5cGVvZiBpbXBvcnQoXCJAYWktc2RrL2FudGhyb3BpY1wiKS5hbnRocm9waWM7XG4gICAgICB9KVxuICAgIHwgbnVsbCA9IG51bGw7XG5cbiAgYXN5bmMgaW5pdCgpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgeyBhbnRocm9waWMgfSA9IGF3YWl0IGltcG9ydChcIkBhaS1zZGsvYW50aHJvcGljXCIpO1xuICAgICAgY29uc3QgYWlNb2R1bGUgPSBhd2FpdCBpbXBvcnQoXCJhaVwiKTtcbiAgICAgIHRoaXMuYWlTZGsgPSB7IC4uLmFpTW9kdWxlLCBhbnRocm9waWMgfTtcbiAgICAgIHRoaXMubW9kZWwgPSBhbnRocm9waWMoXCJjbGF1ZGUtc29ubmV0LTQtNlwiKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICBcIkFJIFNESyBwYWNrYWdlcyBub3QgaW5zdGFsbGVkLiBJbnN0YWxsIEBhaS1zZGsvYW50aHJvcGljIGFuZCBhaSB0byB1c2UgQUkgZmVhdHVyZXMuXCIsXG4gICAgICApO1xuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgaGFuZGxlRml4dHVyZShcbiAgICBtZXNzYWdlczogTW9kZWxNZXNzYWdlW10sXG4gICAgZml4dHVyZVJlY29yZHM6IEZpeHR1cmVSZWNvcmRbXSxcbiAgKTogU3RyZWFtVGV4dFJlc3VsdDxhbnksIGFueT4ge1xuICAgIGlmICghdGhpcy5haVNkayB8fCAhdGhpcy5tb2RlbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQUkgU0RLIG5vdCBpbml0aWFsaXplZC4gQ2FsbCBpbml0KCkgZmlyc3QuXCIpO1xuICAgIH1cblxuICAgIC8vIO2YhOyerCBmaXh0dXJlUmVjb3Jkc+yXkOyEnCDsgqzsmqnrkJwg7JeU7Yuw7Yuw65Ok7J2YIOq1rOyhsCDsoJXrs7Qg7IiY7KeRXG4gICAgY29uc3QgdXNlZEVudGl0eUlkcyA9IFsuLi5uZXcgU2V0KGZpeHR1cmVSZWNvcmRzLm1hcCgocikgPT4gci5lbnRpdHlJZCkpXTtcbiAgICBjb25zdCBlbnRpdHlTdHJ1Y3R1cmVzID0gdXNlZEVudGl0eUlkcy5tYXAoKGVudGl0eUlkKSA9PiB7XG4gICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVudGl0eUlkOiBlbnRpdHkuaWQsXG4gICAgICAgIHRhYmxlOiBlbnRpdHkudGFibGUsXG4gICAgICAgIHByb3BzOiBlbnRpdHkucHJvcHMsXG4gICAgICAgIHJlbGF0aW9uczogZW50aXR5LnJlbGF0aW9ucyxcbiAgICAgICAgZW51bUxhYmVsczogZW50aXR5LmVudW1MYWJlbHMsXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgY29uc3Qgc3lzdGVtTWVzc2FnZSA9IGBcbiAgICAgICAg64u57Iug7J2AIO2UveyKpOyzkCDroIjsvZTrk5zrpbwg7IiY7KCV7ZWY6rOgIOyDneyEse2VoCDsiJgg7J6I64qUIOuPhOyasOuvuOyeheuLiOuLpC5cblxuICAgICAgICDtmITsnqwg7ZS97Iqk7LOQIOugiOy9lOuTnDpcbiAgICAgICAgJHtKU09OLnN0cmluZ2lmeShmaXh0dXJlUmVjb3JkcywgbnVsbCwgMil9XG5cbiAgICAgICAg7JeU7Yuw7YuwIOq1rOyhsCDsoJXrs7Q6XG4gICAgICAgICR7SlNPTi5zdHJpbmdpZnkoZW50aXR5U3RydWN0dXJlcywgbnVsbCwgMil9XG5cbiAgICAgICAgIyMg7ZS97Iqk7LOQIOyImOyglVxuICAgICAgICDsgqzsmqnsnpDqsIAg7ZS97Iqk7LOQIOqwkiDsiJjsoJXsnYQg7JqU7LKt7ZWY66m0IHVwZGF0ZUZpeHR1cmVzIOuPhOq1rOulvCDsgqzsmqntlZjsl6wg67OA6rK97IKs7ZWt7J2EIOyggeyaqe2VmOyEuOyalC5cbiAgICAgICAgLSBmaXh0dXJlSWQ6IOyImOygle2VoCDtlL3siqTss5AgSUQgKO2YleyLnTogXCJFbnRpdHlJZCNpZFwiKVxuICAgICAgICAtIHVwZGF0ZXM6IOy7rOufvOuqheydhCDtgqTroZwsIOyDiCDqsJLsnYQg6rCS7Jy866GcIO2VmOuKlCDqsJ3ssrRcblxuICAgICAgICDsmIjsi5w6IFwiVXNlciMxXCIg7ZS97Iqk7LOQ7J2YIFwibmFtZVwiIOy7rOufvOydhCBcIu2Zjeq4uOuPmVwi7Jy866GcIOuzgOqyve2VmOugpOuptDpcbiAgICAgICAgdXBkYXRlRml4dHVyZXMoeyB1cGRhdGVzOiBbeyBmaXh0dXJlSWQ6IFwiVXNlciMxXCIsIHVwZGF0ZXM6IHsgbmFtZTogXCLtmY3quLjrj5lcIiB9IH1dIH0pXG5cbiAgICAgICAg67OA6rK965CgIOy7rOufvOydmCB0eXBl7J20IHJlbGF0aW9u7J24IOqyveyasCwg6rSA66CoIOyXlO2LsO2LsOyXkOuPhCDrsJjsmIHrkJjslrTslbwg7ZWgIOy7rOufvOydtCDsnojripTsp4Ag7ZmV7J247ZWY7IS47JqULlxuXG4gICAgICAgICMjIO2UveyKpOyzkCDsg53shLFcbiAgICAgICAg7IKs7Jqp7J6Q6rCAIOyDiOuhnOyatCDtlL3siqTss5Ag7IOd7ISx7J2EIOyalOyyre2VmOuptCBjcmVhdGVGaXh0dXJlcyDrj4Tqtazrpbwg7IKs7Jqp7ZWY7IS47JqULlxuICAgICAgICAtIGVudGl0eUlkOiDsg53shLHtlaAg7JeU7Yuw7YuwIElEXG4gICAgICAgIC0gaWQ6IOyDiCDroIjsvZTrk5zsnZggSUQgKOq4sOyhtCDtlL3siqTss5DsmYAg7KSR67O165CY7KeAIOyViuuKlCDsnYzsiJgg7IKs7JqpIOq2jOyepSwg7JiIOiAtMSwgLTIpXG4gICAgICAgIC0gY29sdW1uczog7Lus65+866qF7J2EIO2CpOuhnCwg6rCS7J2EIOqwkuycvOuhnCDtlZjripQg6rCd7LK0ICjsl5Tti7Dti7Ag6rWs7KGwIOywuOqzoClcblxuICAgICAgICDsmIjsi5w6IOyDiOuhnOyatCBVc2VyIO2UveyKpOyzkOulvCDsg53shLHtlZjroKTrqbQ6XG4gICAgICAgIGNyZWF0ZUZpeHR1cmVzKHsgZml4dHVyZXM6IFt7IGVudGl0eUlkOiBcIlVzZXJcIiwgaWQ6IC0xLCBjb2x1bW5zOiB7IG5hbWU6IFwi7ZmN6ri464+ZXCIsIGVtYWlsOiBcImhvbmdAZXhhbXBsZS5jb21cIiB9IH1dIH0pXG4gICAgICBgO1xuXG4gICAgY29uc3QgeyBzdHJlYW1UZXh0LCB0b29sIH0gPSB0aGlzLmFpU2RrO1xuXG4gICAgcmV0dXJuIHN0cmVhbVRleHQoe1xuICAgICAgbW9kZWw6IHRoaXMubW9kZWwsXG4gICAgICBzeXN0ZW06IHN5c3RlbU1lc3NhZ2UsXG4gICAgICBtZXNzYWdlcyxcbiAgICAgIHRvb2xzOiB7XG4gICAgICAgIHVwZGF0ZUZpeHR1cmVzOiB0b29sKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwi7ZS97Iqk7LOQIOugiOy9lOuTnOydmCDqsJLsnYQg7IiY7KCV7ZWp64uI64ukLiDsgqzsmqnsnpDqsIAg7Yq57KCVIOy7rOufvOydtOuCmCDqsJLsnYQg67OA6rK97ZW064us65286rOgIOyalOyyre2VoCDrlYwg7IKs7Jqp7ZWY7IS47JqULlwiLFxuICAgICAgICAgIGlucHV0U2NoZW1hOiB6Lm9iamVjdCh7XG4gICAgICAgICAgICB1cGRhdGVzOiB6LmFycmF5KFxuICAgICAgICAgICAgICB6Lm9iamVjdCh7XG4gICAgICAgICAgICAgICAgZml4dHVyZUlkOiB6LnN0cmluZygpLmRlc2NyaWJlKFwi7IiY7KCV7ZWgIO2UveyKpOyzkCBJRCAo7ZiV7IudOiBFbnRpdHlJZCNpZClcIiksXG4gICAgICAgICAgICAgICAgdXBkYXRlczogelxuICAgICAgICAgICAgICAgICAgLnJlY29yZCh6LnN0cmluZygpLCB6LnVua25vd24oKSlcbiAgICAgICAgICAgICAgICAgIC5kZXNjcmliZShcIuy7rOufvOuqheydhCDtgqTroZwsIOyDiCDqsJLsnYQg6rCS7Jy866GcIO2VmOuKlCDqsJ3ssrRcIiksXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBleGVjdXRlOiBhc3luYyAoe1xuICAgICAgICAgICAgdXBkYXRlcyxcbiAgICAgICAgICB9OiB7XG4gICAgICAgICAgICB1cGRhdGVzOiBBcnJheTx7IGZpeHR1cmVJZDogc3RyaW5nOyB1cGRhdGVzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB9PjtcbiAgICAgICAgICB9KTogUHJvbWlzZTx7IHN1Y2Nlc3M6IGJvb2xlYW47IHVwZGF0ZWRSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gfT4gPT4ge1xuICAgICAgICAgICAgLy8gZml4dHVyZVJlY29yZHPrpbwg67O17IKs7ZWY6rOgIOyXheuNsOydtO2KuCDsoIHsmqlcbiAgICAgICAgICAgIGNvbnN0IHVwZGF0ZWRSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gPSBmaXh0dXJlUmVjb3Jkcy5tYXAoKHJlY29yZCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB1cGRhdGUgPSB1cGRhdGVzLmZpbmQoXG4gICAgICAgICAgICAgICAgKHU6IHsgZml4dHVyZUlkOiBzdHJpbmcgfSkgPT4gdS5maXh0dXJlSWQgPT09IHJlY29yZC5maXh0dXJlSWQsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGlmICh1cGRhdGUpIHtcbiAgICAgICAgICAgICAgICAvLyBjb2x1bW5z7J2YIHZhbHVl66W8IOyXheuNsOydtO2KuFxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgW2NvbHVtbk5hbWUsIG5ld1ZhbHVlXSBvZiBPYmplY3QuZW50cmllcyh1cGRhdGUudXBkYXRlcykpIHtcbiAgICAgICAgICAgICAgICAgIHJlY29yZC5jb2x1bW5zW2NvbHVtbk5hbWVdLnZhbHVlID1cbiAgICAgICAgICAgICAgICAgICAgbmV3VmFsdWUgYXMgRml4dHVyZVJlY29yZFtcImNvbHVtbnNcIl1bc3RyaW5nXVtcInZhbHVlXCJdO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gcmVjb3JkO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcmV0dXJuIHJlY29yZDtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCB1cGRhdGVkUmVjb3JkcyB9O1xuICAgICAgICAgIH0sXG4gICAgICAgIH0pLFxuICAgICAgICBjcmVhdGVGaXh0dXJlczogdG9vbCh7XG4gICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICBcIuyDiOuhnOyatCDtlL3siqTss5Ag66CI7L2U65Oc66W8IOyDneyEse2VqeuLiOuLpC4g7IKs7Jqp7J6Q6rCAIOyDiOuhnOyatCDrjbDsnbTthLDrpbwg7LaU6rCA7ZW064us65286rOgIOyalOyyre2VoCDrlYwg7IKs7Jqp7ZWY7IS47JqULlwiLFxuICAgICAgICAgIGlucHV0U2NoZW1hOiB6Lm9iamVjdCh7XG4gICAgICAgICAgICBmaXh0dXJlczogei5hcnJheShcbiAgICAgICAgICAgICAgei5vYmplY3Qoe1xuICAgICAgICAgICAgICAgIGVudGl0eUlkOiB6LnN0cmluZygpLmRlc2NyaWJlKFwi7IOd7ISx7ZWgIOyXlO2LsO2LsCBJRFwiKSxcbiAgICAgICAgICAgICAgICBpZDogei5udW1iZXIoKS5kZXNjcmliZShcIuyDiCDroIjsvZTrk5zsnZggSUQgKOydjOyImCDqtozsnqUsIOyYiDogLTEsIC0yKVwiKSxcbiAgICAgICAgICAgICAgICBjb2x1bW5zOiB6XG4gICAgICAgICAgICAgICAgICAucmVjb3JkKHouc3RyaW5nKCksIHoudW5rbm93bigpKVxuICAgICAgICAgICAgICAgICAgLmRlc2NyaWJlKFwi7Lus65+866qF7J2EIO2CpOuhnCwg6rCS7J2EIOqwkuycvOuhnCDtlZjripQg6rCd7LK0XCIpLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgfSksXG4gICAgICAgICAgZXhlY3V0ZTogYXN5bmMgKHtcbiAgICAgICAgICAgIGZpeHR1cmVzLFxuICAgICAgICAgIH06IHtcbiAgICAgICAgICAgIGZpeHR1cmVzOiBBcnJheTx7IGVudGl0eUlkOiBzdHJpbmc7IGlkOiBudW1iZXI7IGNvbHVtbnM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IH0+O1xuICAgICAgICAgIH0pOiBQcm9taXNlPHsgc3VjY2VzczogYm9vbGVhbjsgdXBkYXRlZFJlY29yZHM6IEZpeHR1cmVSZWNvcmRbXSB9PiA9PiB7XG4gICAgICAgICAgICBjb25zdCBuZXdSZWNvcmRzOiBGaXh0dXJlUmVjb3JkW10gPSBmaXh0dXJlcy5tYXAoXG4gICAgICAgICAgICAgIChmaXh0dXJlOiB7IGVudGl0eUlkOiBzdHJpbmc7IGlkOiBudW1iZXI7IGNvbHVtbnM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IH0pID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChmaXh0dXJlLmVudGl0eUlkKTtcblxuICAgICAgICAgICAgICAgIC8vIOyXlO2LsO2LsCBwcm9wc+ulvCDquLDrsJjsnLzroZwgY29sdW1ucyDqtazshLFcbiAgICAgICAgICAgICAgICBjb25zdCBjb2x1bW5zOiBGaXh0dXJlUmVjb3JkW1wiY29sdW1uc1wiXSA9IHt9O1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcHJvcCBvZiBlbnRpdHkucHJvcHMpIHtcbiAgICAgICAgICAgICAgICAgIGlmIChwcm9wLnR5cGUgPT09IFwidmlydHVhbFwiKSBjb250aW51ZTtcblxuICAgICAgICAgICAgICAgICAgbGV0IHZhbHVlID0gZml4dHVyZS5jb2x1bW5zW3Byb3AubmFtZV0gPz8gbnVsbDtcblxuICAgICAgICAgICAgICAgICAgaWYgKHByb3AubmFtZSA9PT0gXCJjcmVhdGVkX2F0XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g7ZiE7J6sIOyLnOqwhOycvOuhnCDshKTsoJVcbiAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgICAgICBwcm9wLnR5cGUgPT09IFwicmVsYXRpb25cIiAmJlxuICAgICAgICAgICAgICAgICAgICAocHJvcC5yZWxhdGlvblR5cGUgPT09IFwiSGFzTWFueVwiIHx8IHByb3AucmVsYXRpb25UeXBlID09PSBcIk1hbnlUb01hbnlcIilcbiAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAvLyDrsLDsl7TroZwg67OA7ZmYXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlID0gQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyB2YWx1ZSA6IFt2YWx1ZV0uZmlsdGVyKG5vbk51bGxhYmxlKTtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgY29sdW1uc1twcm9wLm5hbWVdID0ge1xuICAgICAgICAgICAgICAgICAgICBwcm9wLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdmFsdWUgYXMgRml4dHVyZVJlY29yZFtcImNvbHVtbnNcIl1bc3RyaW5nXVtcInZhbHVlXCJdLFxuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgZml4dHVyZUlkOiBgJHtmaXh0dXJlLmVudGl0eUlkfSMke2ZpeHR1cmUuaWR9YCxcbiAgICAgICAgICAgICAgICAgIGVudGl0eUlkOiBmaXh0dXJlLmVudGl0eUlkLFxuICAgICAgICAgICAgICAgICAgaWQ6IGZpeHR1cmUuaWQsXG4gICAgICAgICAgICAgICAgICBjb2x1bW5zLFxuICAgICAgICAgICAgICAgICAgZmV0Y2hlZFJlY29yZHM6IFtdLFxuICAgICAgICAgICAgICAgICAgYmVsb25nc1JlY29yZHM6IFtdLFxuICAgICAgICAgICAgICAgICAgb3ZlcnJpZGU6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAvLyDsg4gg66CI7L2U65Oc65Ok7J2YIHJlbGF0aW9uIOy7rOufvOydhCDtmZXsnbjtlZjsl6wg6riw7KG0IOugiOy9lOuTnOuTpOydmCDsl63rsKntlqUgcmVsYXRpb24g7JeF642w7J207Yq4XG4gICAgICAgICAgICBmb3IgKGNvbnN0IG5ld1JlY29yZCBvZiBuZXdSZWNvcmRzKSB7XG4gICAgICAgICAgICAgIGZvciAoY29uc3QgW19jb2xOYW1lLCBjb2xdIG9mIE9iamVjdC5lbnRyaWVzKG5ld1JlY29yZC5jb2x1bW5zKSkge1xuICAgICAgICAgICAgICAgIGlmIChjb2wucHJvcC50eXBlICE9PSBcInJlbGF0aW9uXCIgfHwgY29sLnZhbHVlID09PSBudWxsKSBjb250aW51ZTtcblxuICAgICAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRFbnRpdHlJZCA9IGNvbC5wcm9wLndpdGg7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVsYXRlZElkcyA9IEFycmF5LmlzQXJyYXkoY29sLnZhbHVlKSA/IGNvbC52YWx1ZSA6IFtjb2wudmFsdWVdO1xuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCByZWxhdGVkSWQgb2YgcmVsYXRlZElkcykge1xuICAgICAgICAgICAgICAgICAgY29uc3QgcmVsYXRlZEZpeHR1cmVJZCA9IGAke3JlbGF0ZWRFbnRpdHlJZH0jJHtyZWxhdGVkSWR9YDtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHJlbGF0ZWRSZWNvcmQgPSBuZXdSZWNvcmRzLmZpbmQoKHIpID0+IHIuZml4dHVyZUlkID09PSByZWxhdGVkRml4dHVyZUlkKTtcblxuICAgICAgICAgICAgICAgICAgaWYgKHJlbGF0ZWRSZWNvcmQpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8g7Jet67Cp7ZalIHJlbGF0aW9uIOywvuq4sFxuICAgICAgICAgICAgICAgICAgICBjb25zdCByZXZlcnNlQ29sID0gT2JqZWN0LmVudHJpZXMocmVsYXRlZFJlY29yZC5jb2x1bW5zKS5maW5kKFxuICAgICAgICAgICAgICAgICAgICAgIChbLCBjXSkgPT4gYy5wcm9wLnR5cGUgPT09IFwicmVsYXRpb25cIiAmJiBjLnByb3Aud2l0aCA9PT0gbmV3UmVjb3JkLmVudGl0eUlkLFxuICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZXZlcnNlQ29sKSB7XG4gICAgICAgICAgICAgICAgICAgICAgY29uc3QgW3JldmVyc2VDb2xOYW1lLCByZXZlcnNlQ29sVmFsdWVdID0gcmV2ZXJzZUNvbDtcbiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50VmFsdWUgPSByZXZlcnNlQ29sVmFsdWUudmFsdWU7XG5cbiAgICAgICAgICAgICAgICAgICAgICAvLyDsl63rsKntlqXsnbQg67Cw7Je07J24IOqyveyasCAoSGFzTWFueSwgTWFueVRvTWFueSlcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICByZXZlcnNlQ29sVmFsdWUucHJvcC50eXBlID09PSBcInJlbGF0aW9uXCIgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIChyZXZlcnNlQ29sVmFsdWUucHJvcC5yZWxhdGlvblR5cGUgPT09IFwiSGFzTWFueVwiIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJldmVyc2VDb2xWYWx1ZS5wcm9wLnJlbGF0aW9uVHlwZSA9PT0gXCJNYW55VG9NYW55XCIpXG4gICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhc3NlcnQoQXJyYXkuaXNBcnJheShjdXJyZW50VmFsdWUpLCBcImN1cnJlbnRWYWx1ZSBtdXN0IGJlIGFuIGFycmF5XCIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFjdXJyZW50VmFsdWUuaW5jbHVkZXMobmV3UmVjb3JkLmlkKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICByZWxhdGVkUmVjb3JkLmNvbHVtbnNbcmV2ZXJzZUNvbE5hbWVdID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnJldmVyc2VDb2xWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogWy4uLmN1cnJlbnRWYWx1ZSwgbmV3UmVjb3JkLmlkXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8g7Jet67Cp7Zal7J20IOuLqOydvCDqsJLsnbgg6rK97JqwIChCZWxvbmdzVG9PbmUsIE9uZVRvT25lKVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVsYXRlZFJlY29yZC5jb2x1bW5zW3JldmVyc2VDb2xOYW1lXSA9IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucmV2ZXJzZUNvbFZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogbmV3UmVjb3JkLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSwgdXBkYXRlZFJlY29yZHM6IG5ld1JlY29yZHMgfTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBoYW5kbGVFbnRpdHkobWVzc2FnZXM6IE1vZGVsTWVzc2FnZVtdKTogU3RyZWFtVGV4dFJlc3VsdDxhbnksIGFueT4ge1xuICAgIGlmICghdGhpcy5haVNkayB8fCAhdGhpcy5tb2RlbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQUkgU0RLIG5vdCBpbml0aWFsaXplZC4gQ2FsbCBpbml0KCkgZmlyc3QuXCIpO1xuICAgIH1cblxuICAgIC8vIGVudGl0eS5pbnN0cnVjdGlvbnMubWQg7YyM7J28IOydveq4sCAoZGlzdC91aSDrmJDripQgc3JjL3Vp7JeQ7IScIOyLpO2WieuQmOuvgOuhnCDtjKjtgqTsp4Ag66Oo7Yq4IOq4sOykgOycvOuhnCDsoJHqt7wpXG4gICAgY29uc3QgaW5zdHJ1Y3Rpb25zUGF0aCA9IHBhdGguam9pbihcbiAgICAgIGltcG9ydC5tZXRhLmRpcm5hbWUsXG4gICAgICBcIi4uXCIsXG4gICAgICBcIi4uXCIsXG4gICAgICBcInNyY1wiLFxuICAgICAgXCJ1aVwiLFxuICAgICAgXCJlbnRpdHkuaW5zdHJ1Y3Rpb25zLm1kXCIsXG4gICAgKTtcbiAgICBjb25zdCBpbnN0cnVjdGlvbnMgPSBmcy5yZWFkRmlsZVN5bmMoaW5zdHJ1Y3Rpb25zUGF0aCwgXCJ1dGYtOFwiKTtcblxuICAgIC8vIO2YhOyerCDrk7HroZ3rkJwg7JeU7Yuw7YuwIOygleuztCDsiJjsp5FcbiAgICBjb25zdCBlbnRpdHlJZHMgPSBFbnRpdHlNYW5hZ2VyLmdldEFsbElkcygpO1xuICAgIGNvbnN0IGV4aXN0aW5nRW50aXRpZXMgPSBlbnRpdHlJZHMubWFwKChlbnRpdHlJZCkgPT4ge1xuICAgICAgY29uc3QgZW50aXR5ID0gRW50aXR5TWFuYWdlci5nZXQoZW50aXR5SWQpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaWQ6IGVudGl0eS5pZCxcbiAgICAgICAgdGl0bGU6IGVudGl0eS50aXRsZSxcbiAgICAgICAgdGFibGU6IGVudGl0eS50YWJsZSxcbiAgICAgICAgcHJvcHM6IGVudGl0eS5wcm9wcy5tYXAoKHApID0+ICh7XG4gICAgICAgICAgbmFtZTogcC5uYW1lLFxuICAgICAgICAgIHR5cGU6IHAudHlwZSxcbiAgICAgICAgICBkZXNjOiBwLmRlc2MsXG4gICAgICAgIH0pKSxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBjb25zdCBzeXN0ZW1NZXNzYWdlID0gYFxu64u57Iug7J2AIFNvbmFtdSDtlITroIjsnoTsm4ztgazsl5DshJwgRW50aXR57JmAIEVudW3snYQg7IOd7ISx7ZWY64qUIOuPhOyasOuvuOyeheuLiOuLpC5cblxuJHtpbnN0cnVjdGlvbnN9XG5cbiMjIO2YhOyerCDrk7HroZ3rkJwgRW50aXR5IOuqqeuhnVxu64uk66W4IOyXlO2LsO2LsOyZgCDqtIDqs4QocmVsYXRpb24p66W8IOunuuqxsOuCmCBzdWJzZXTsl5DshJwg7LC47KGw7ZWgIOuVjCDrsJjrk5zsi5wg7JWE656YIOygleuztOulvCDtmZXsnbjtlZjshLjsmpQuXG5cbiR7SlNPTi5zdHJpbmdpZnkoZXhpc3RpbmdFbnRpdGllcywgbnVsbCwgMil9XG5cbiMjIFRvb2wg7IKs7JqpIOqwgOydtOuTnFxuXG4jIyMgRW50aXR5IOyDneyEsSAoY3JlYXRlRW50aXR5KVxu7IKs7Jqp7J6Q6rCAIOyDiOuhnOyatCBFbnRpdHkg7IOd7ISx7J2EIOyalOyyre2VmOuptCBjcmVhdGVFbnRpdHkg64+E6rWs66W8IOyCrOyaqe2VmOyEuOyalC5cbi0gZW50aXR5SWQ6IFBhc2NhbENhc2XroZwg65CcIEVudGl0eSBJRCAo7JiIOiBcIlVzZXJcIiwgXCJQcm9kdWN0Q2F0ZWdvcnlcIilcbi0gdGl0bGU6IO2VnOq4gCDsoJzrqqkgKOyYiDogXCLsgqzsmqnsnpBcIiwgXCLsg4Htkogg7Lm07YWM6rOg66asXCIpXG4tIHRhYmxlOiBzbmFrZV9jYXNl66GcIOuQnCDthYzsnbTruJTrqoUgKOyYiDogXCJ1c2Vyc1wiLCBcInByb2R1Y3RfY2F0ZWdvcmllc1wiKVxuLSBwYXJlbnRJZDog67aA66qoIEVudGl0eSBJRCAo7ISg7YOd7IKs7ZWtKVxuLSBwcm9wczogRW50aXR57J2YIO2UhOuhnO2NvO2LsCDrsLDsl7QgKOychCDrrLjshJzsnZggUHJvcGVydHkgVHlwZXMg7LC46rOgKVxuLSBpbmRleGVzOiDsnbjrjbHsiqQg67Cw7Je0XG4tIHN1YnNldHM6IOyEnOu4jOyFiyDsoJXsnZggKOq4sOuzuOqwkjogeyBBOiBbXCJpZFwiXSB9KVxuLSBlbnVtczogRW51bSDsoJXsnZhcblxuIyMjIEVudGl0eSDsiJjsoJUgKHVwZGF0ZUVudGl0eSlcbuq4sOyhtCBFbnRpdHnrpbwg7IiY7KCV7ZWgIOuVjCB1cGRhdGVFbnRpdHkg64+E6rWs66W8IOyCrOyaqe2VmOyEuOyalC4gRW51bSDstpTqsIAsIHByb3BzIOy2lOqwgC/siJjsoJUsIGluZGV4ZXMg7IiY7KCVIOuTsSDrqqjrk6Ag7IiY7KCVIOyekeyXheyXkCDsgqzsmqntlanri4jri6QuXG4tIGVudGl0eUlkOiDsiJjsoJXtlaAgRW50aXR5IElEXG4tIHVwZGF0ZXM6IOyImOygle2VoCDtlYTrk5zrk6QgKOu2gOu2hCDsl4XrjbDsnbTtirgpXG4gIC0gdGl0bGU6IOyXlO2LsO2LsCDtlZzquIAg7KCc66qpXG4gIC0gdGFibGU6IO2FjOydtOu4lOuqhVxuICAtIHByb3BzOiDstpTqsIDtlaAg7ZSE66Gc7Y287YuwIOuwsOyXtCAo6riw7KG0IHByb3Bz7JeQIOy2lOqwgCwg6rCZ7J2AIOydtOumhOydtOuptCDqtZDssrQpXG4gIC0gaW5kZXhlczog7LaU6rCA7ZWgIOyduOuNseyKpCDrsLDsl7QgKOq4sOyhtCBpbmRleGVz7JeQIOy2lOqwgClcbiAgLSBzdWJzZXRzOiDshJzruIzshYsg7KCV7J2YICjquLDsobQgc3Vic2V0c+yXkCDrs5HtlakpXG4gIC0gZW51bUxhYmVsczogRW51bSDsoJXsnZggKOq4sOyhtCBlbnVtTGFiZWxz7JeQIOuzke2VqSlcbi0gbW9kZTogXCJtZXJnZVwiKOq4sOuzuOqwkikg65iQ64qUIFwicmVwbGFjZVwiXG4gIC0gbWVyZ2U6IOq4sOyhtCDqsJLsl5Ag67OR7ZWpXG4gIC0gcmVwbGFjZTog7ZW064u5IO2VhOuTnCDsoITssrQg6rWQ7LK0XG5cbuyYiOyLnDogRW1wbG95ZWXsl5Ag7IOIIEVudW0g7LaU6rCAXG51cGRhdGVFbnRpdHkoeyBlbnRpdHlJZDogXCJFbXBsb3llZVwiLCB1cGRhdGVzOiB7IGVudW1MYWJlbHM6IHsgXCJFbXBsb3llZVJvbGVcIjogeyBcImFkbWluXCI6IFwi6rSA66as7J6QXCIsIFwidXNlclwiOiBcIuydvOuwmFwiIH0gfSB9IH0pXG5cbuyYiOyLnDogUHJvamVjdOyXkCDsg4gg7ZSE66Gc7Y287YuwIOy2lOqwgFxudXBkYXRlRW50aXR5KHsgZW50aXR5SWQ6IFwiUHJvamVjdFwiLCB1cGRhdGVzOiB7IHByb3BzOiBbeyBuYW1lOiBcInByaW9yaXR5XCIsIHR5cGU6IFwiaW50ZWdlclwiLCBkZXNjOiBcIuyasOyEoOyInOychFwiIH1dIH0gfSlcblxuIyMg7ZWE7IiYIOyCrO2VrVxuLSBFbnRpdHnsnZggcHJvcHPsl5DripQg7LWc7IaM7ZWcIGlkKGludGVnZXIsIHVuc2lnbmVkKSwgY3JlYXRlZF9hdCh0aW1lc3RhbXAp6rCAIO2PrO2VqOuQmOyWtOyVvCDtlanri4jri6QuXG4tIHJlbGF0aW9uIO2VhOuTnOuKlCBvblVwZGF0ZSwgb25EZWxldGXqsIAg7ZWE7IiY7J6F64uI64ukLiAo7JiI7Jm4OiBPbmVUb09uZeyXkOyEnCBoYXNKb2luQ29sdW1u7J20IGZhbHNl7J24IOqyveyasClcbi0gRW51bSBJROuKlCDrs7TthrUgRW50aXR5SWQgKyDsho3shLHrqoUg7ZiV7YOc7J6F64uI64ukICjsmIg6IFVzZXJTdGF0dXMsIFByb2R1Y3RUeXBlKVxuLSBzdWJzZXTsl5DshJwg64uk66W4IOyXlO2LsO2LsOydmCDtlITroZztjbzti7Drpbwg7LC47KGw7ZWgIOuVjOuKlCDrsJjrk5zsi5wg7ZW064u5IOyXlO2LsO2LsOydmCDsi6TsoJwg7ZSE66Gc7Y287Yuw66qF7J2EIOyCrOyaqe2VmOyEuOyalC5cblxuIyMg6rKA7KadIOyYpOulmCDsspjrpqxcbuuPhOq1rCDtmLjstpwg6rKw6rO866GcIOqygOymnSDsmKTrpZgodmFsaWRhdGlvbkVycm9ycynqsIAg67CY7ZmY65CY66m0OlxuMS4g7Jik66WYIOuplOyLnOyngOulvCDrtoTshJ3tlZjsl6wg66y47KCc7KCQ7J2EIO2MjOyVhe2VmOyEuOyalC5cbjIuIOyYpOulmOulvCDsiJjsoJXtlZwg642w7J207YSw66GcIGNyZWF0ZUVudGl0eeulvCDri6Tsi5wg7Zi47Lac7ZWY7IS47JqULlxuMy4g7IKs7Jqp7J6Q7JeQ6rKMIOyYpOulmOulvCDqt7jrjIDroZwg7KCE64us7ZWY7KeAIOunkOqzoCwg7IiY7KCVIO2bhCDsnqzsi5zrj4TtlZjshLjsmpQuXG5cbiMjIyDsnbzrsJjsoIHsnbgg6rKA7KadIOyYpOulmOyZgCDsiJjsoJUg67Cp67KVXG58IOyYpOulmCDrqZTsi5zsp4AgfCDsiJjsoJUg67Cp67KVIHxcbnwtLS0tLS0tLS0tLS18LS0tLS0tLS0tLXxcbnwgXCJpZCDtlITroZztjbzti7DqsIAg7ZWE7IiYXCIgfCBwcm9wc+yXkCB7IG5hbWU6IFwiaWRcIiwgdHlwZTogXCJpbnRlZ2VyXCIsIHVuc2lnbmVkOiB0cnVlIH0g7LaU6rCAIHxcbnwgXCJjcmVhdGVkX2F0IO2UhOuhnO2NvO2LsOqwgCDtlYTsiJhcIiB8IHByb3Bz7JeQIHsgbmFtZTogXCJjcmVhdGVkX2F0XCIsIHR5cGU6IFwidGltZXN0YW1wXCIsIGRiRGVmYXVsdDogXCJDVVJSRU5UX1RJTUVTVEFNUFwiIH0g7LaU6rCAIHxcbnwgXCJYeHhPcmRlckJ5IGVudW3snbQg7ZWE7IiYXCIgfCBlbnVtc+yXkCB7IFwiWHh4T3JkZXJCeVwiOiB7IFwiaWQtZGVzY1wiOiBcIklE7LWc7Iug7IicXCIgfSB9IOy2lOqwgCB8XG58IFwiWHh4U2VhcmNoRmllbGQgZW51beydtCDtlYTsiJhcIiB8IGVudW1z7JeQIHsgXCJYeHhTZWFyY2hGaWVsZFwiOiB7IFwiaWRcIjogXCJJRFwiIH0gfSDstpTqsIAgfFxufCBcInN0cmluZyDtg4DsnoXsnYAgbGVuZ3Ro6rCAIO2VhOyImFwiIHwg7ZW064u5IHByb3Dsl5AgbGVuZ3RoIOy2lOqwgCAo7JiIOiAyNTUpIHxcbnwgXCJ0ZXh0IO2DgOyeheydgCB0ZXh0VHlwZeydtCDtlYTsiJhcIiB8IO2VtOuLuSBwcm9w7JeQIHRleHRUeXBlIOy2lOqwgCAoXCJ0ZXh0XCIsIFwibWVkaXVtdGV4dFwiLCBcImxvbmd0ZXh0XCIpIHxcbnwgXCJvblVwZGF0ZeqwgCDtlYTsiJhcIiB8IO2VtOuLuSByZWxhdGlvbiBwcm9w7JeQIG9uVXBkYXRlLCBvbkRlbGV0ZSDstpTqsIAgKFwiQ0FTQ0FERVwiKSB8XG4gICAgICBgO1xuXG4gICAgY29uc3QgeyBzdHJlYW1UZXh0LCB0b29sLCBzdGVwQ291bnRJcyB9ID0gdGhpcy5haVNkaztcblxuICAgIHJldHVybiBzdHJlYW1UZXh0KHtcbiAgICAgIG1vZGVsOiB0aGlzLm1vZGVsIGFzIHVua25vd24gYXMgTGFuZ3VhZ2VNb2RlbCxcbiAgICAgIHN5c3RlbTogc3lzdGVtTWVzc2FnZSxcbiAgICAgIG1lc3NhZ2VzLFxuICAgICAgc3RvcFdoZW46IHN0ZXBDb3VudElzKDIpLFxuICAgICAgdG9vbHM6IHtcbiAgICAgICAgY3JlYXRlRW50aXR5OiB0b29sKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwi7IOI66Gc7Jq0IEVudGl0eeulvCDsg53shLHtlanri4jri6QuIOyCrOyaqeyekOqwgCDsg4jroZzsmrQg7JeU7Yuw7Yuw64KYIO2FjOydtOu4lCDsg53shLHsnYQg7JqU7LKt7ZWgIOuVjCDsgqzsmqntlZjshLjsmpQuXCIsXG4gICAgICAgICAgaW5wdXRTY2hlbWE6IFRlbXBsYXRlT3B0aW9ucy5zaGFwZS5lbnRpdHksXG4gICAgICAgICAgZXhlY3V0ZTogYXN5bmMgKFxuICAgICAgICAgICAgZW50aXR5OiB6LmluZmVyPHR5cGVvZiBUZW1wbGF0ZU9wdGlvbnMuc2hhcGUuZW50aXR5PixcbiAgICAgICAgICApOiBQcm9taXNlPHtcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGJvb2xlYW47XG4gICAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgICAgZXJyb3I/OiBzdHJpbmc7XG4gICAgICAgICAgICB2YWxpZGF0aW9uRXJyb3JzPzogVmFsaWRhdGlvbkVycm9yW107XG4gICAgICAgICAgfT4gPT4ge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgLy8g7J6F66ClIOqygOymnVxuICAgICAgICAgICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGVFbnRpdHlKc29uKGVudGl0eSk7XG5cbiAgICAgICAgICAgICAgaWYgKHZhbGlkYXRpb25FcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIGVudGl0eUlkOiBlbnRpdHkuZW50aXR5SWQsXG4gICAgICAgICAgICAgICAgICBlcnJvcjogYOqygOymnSDsmKTrpZg6ICR7dmFsaWRhdGlvbkVycm9ycy5tYXAoKGUpID0+IGBbJHtlLmZpZWxkfV0gJHtlLm1lc3NhZ2V9YCkuam9pbihcIiwgXCIpfWAsXG4gICAgICAgICAgICAgICAgICB2YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBhd2FpdCBTb25hbXUuc3luY2VyLmNyZWF0ZUVudGl0eSh7XG4gICAgICAgICAgICAgICAgc3Vic2V0czogeyBBOiBbXCJpZFwiXSB9LFxuICAgICAgICAgICAgICAgIGVudW1zOiB7fSxcbiAgICAgICAgICAgICAgICAuLi5lbnRpdHksXG4gICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgIC8vIEVudGl0eU1hbmFnZXIg66as66Gc65OcXG4gICAgICAgICAgICAgIGF3YWl0IEVudGl0eU1hbmFnZXIucmVsb2FkKCk7XG5cbiAgICAgICAgICAgICAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSwgZW50aXR5SWQ6IGVudGl0eS5lbnRpdHlJZCB9O1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFwiVW5rbm93biBlcnJvclwiO1xuICAgICAgICAgICAgICByZXR1cm4geyBzdWNjZXNzOiBmYWxzZSwgZW50aXR5SWQ6IGVudGl0eS5lbnRpdHlJZCwgZXJyb3IgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9LFxuICAgICAgICB9KSxcbiAgICAgICAgdXBkYXRlRW50aXR5OiB0b29sKHtcbiAgICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwi6riw7KG0IEVudGl0eeulvCDsiJjsoJXtlanri4jri6QuIEVudW0g7LaU6rCALCBwcm9wcyDstpTqsIAv7IiY7KCVLCBpbmRleGVzIOyImOyglSwgc3Vic2V0cyDsiJjsoJUg65OxIOuqqOuToCDsl5Tti7Dti7Ag7IiY7KCVIOyekeyXheyXkCDsgqzsmqntlZjshLjsmpQuXCIsXG4gICAgICAgICAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHtcbiAgICAgICAgICAgIGVudGl0eUlkOiB6LnN0cmluZygpLmRlc2NyaWJlKFwi7IiY7KCV7ZWgIEVudGl0eSBJRFwiKSxcbiAgICAgICAgICAgIHVwZGF0ZXM6IFRlbXBsYXRlT3B0aW9ucy5zaGFwZS5lbnRpdHkucGFydGlhbCgpLmRlc2NyaWJlKFwi7IiY7KCV7ZWgIO2VhOuTnOuTpFwiKSxcbiAgICAgICAgICAgIG1vZGU6IHpcbiAgICAgICAgICAgICAgLmVudW0oW1wibWVyZ2VcIiwgXCJyZXBsYWNlXCJdKVxuICAgICAgICAgICAgICAub3B0aW9uYWwoKVxuICAgICAgICAgICAgICAuZGVzY3JpYmUoXCLsiJjsoJUg66qo65OcOiBtZXJnZSjquLDrs7jqsJIsIOq4sOyhtCDqsJLsl5Ag67OR7ZWpKSDrmJDripQgcmVwbGFjZSjsoITssrQg6rWQ7LK0KVwiKSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBleGVjdXRlOiBhc3luYyAoe1xuICAgICAgICAgICAgZW50aXR5SWQsXG4gICAgICAgICAgICB1cGRhdGVzLFxuICAgICAgICAgICAgbW9kZSA9IFwibWVyZ2VcIixcbiAgICAgICAgICB9OiB7XG4gICAgICAgICAgICBlbnRpdHlJZDogc3RyaW5nO1xuICAgICAgICAgICAgdXBkYXRlczogUGFydGlhbDx6LmluZmVyPHR5cGVvZiBUZW1wbGF0ZU9wdGlvbnMuc2hhcGUuZW50aXR5Pj47XG4gICAgICAgICAgICBtb2RlPzogXCJtZXJnZVwiIHwgXCJyZXBsYWNlXCI7XG4gICAgICAgICAgfSk6IFByb21pc2U8e1xuICAgICAgICAgICAgc3VjY2VzczogYm9vbGVhbjtcbiAgICAgICAgICAgIGVudGl0eUlkOiBzdHJpbmc7XG4gICAgICAgICAgICBlcnJvcj86IHN0cmluZztcbiAgICAgICAgICAgIHZhbGlkYXRpb25FcnJvcnM/OiBWYWxpZGF0aW9uRXJyb3JbXTtcbiAgICAgICAgICB9PiA9PiB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAgICAgICAgICAgLy8gVXBkYXRlIGJhc2ljIHByb3BlcnRpZXNcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMuZW50aXR5SWQgIT09IHVuZGVmaW5lZCkgZW50aXR5LmlkID0gdXBkYXRlcy5lbnRpdHlJZDtcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMucGFyZW50SWQgIT09IHVuZGVmaW5lZCkgZW50aXR5LnBhcmVudElkID0gdXBkYXRlcy5wYXJlbnRJZDtcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMudGl0bGUgIT09IHVuZGVmaW5lZCkgZW50aXR5LnRpdGxlID0gdXBkYXRlcy50aXRsZTtcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMudGFibGUgIT09IHVuZGVmaW5lZCkgZW50aXR5LnRhYmxlID0gdXBkYXRlcy50YWJsZTtcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMuY29uZSAhPT0gdW5kZWZpbmVkKSBlbnRpdHkuY29uZSA9IHVwZGF0ZXMuY29uZTtcblxuICAgICAgICAgICAgICAvLyBwcm9wczogbWVyZ2Ug7IucIOydtOumhCDquLDspIAg67OR7ZWpLCByZXBsYWNlIOyLnCDqtZDssrRcbiAgICAgICAgICAgICAgaWYgKHVwZGF0ZXMucHJvcHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIGlmIChtb2RlID09PSBcInJlcGxhY2VcIikge1xuICAgICAgICAgICAgICAgICAgZW50aXR5LnByb3BzID0gdXBkYXRlcy5wcm9wcyBhcyBFbnRpdHlQcm9wW107XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgbmV3UHJvcCBvZiB1cGRhdGVzLnByb3BzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4aXN0aW5nSW5kZXggPSBlbnRpdHkucHJvcHMuZmluZEluZGV4KChwKSA9PiBwLm5hbWUgPT09IG5ld1Byb3AubmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChleGlzdGluZ0luZGV4ID49IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICBlbnRpdHkucHJvcHNbZXhpc3RpbmdJbmRleF0gPSBuZXdQcm9wIGFzIEVudGl0eVByb3A7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgZW50aXR5LnByb3BzLnB1c2gobmV3UHJvcCBhcyBFbnRpdHlQcm9wKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIGluZGV4ZXM6IG1lcmdlIOyLnCDstpTqsIAsIHJlcGxhY2Ug7IucIOq1kOyytFxuICAgICAgICAgICAgICBpZiAodXBkYXRlcy5pbmRleGVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBlbnRpdHkuaW5kZXhlcyA9XG4gICAgICAgICAgICAgICAgICBtb2RlID09PSBcInJlcGxhY2VcIiA/IHVwZGF0ZXMuaW5kZXhlcyA6IFsuLi5lbnRpdHkuaW5kZXhlcywgLi4udXBkYXRlcy5pbmRleGVzXTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIHN1YnNldHMsIHN1YnNldHNJbnRlcm5hbDogYXNzaWdu7Jy866GcIOuzke2VqSDrmJDripQg6rWQ7LK0XG4gICAgICAgICAgICAgIGlmICh1cGRhdGVzLnN1YnNldHMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIC8vIE5vcm1hbGl6ZSBzdWJzZXQgZmllbGRzOiBzZXBhcmF0ZSBpbnRvIHN1YnNldHMgKG5vcm1hbCkgYW5kIHN1YnNldHNJbnRlcm5hbCAoaW50ZXJuYWwpXG4gICAgICAgICAgICAgICAgY29uc3Qgbm9ybWFsaXplZFN1YnNldHM6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nW10gfSA9IHt9O1xuICAgICAgICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWRTdWJzZXRzSW50ZXJuYWw6IHsgW2tleTogc3RyaW5nXTogc3RyaW5nW10gfSA9IHt9O1xuXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBba2V5LCBmaWVsZHNdIG9mIE9iamVjdC5lbnRyaWVzKHVwZGF0ZXMuc3Vic2V0cykpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGZpZWxkQXJyYXkgPSBmaWVsZHMgYXMgc3RyaW5nW107XG4gICAgICAgICAgICAgICAgICBub3JtYWxpemVkU3Vic2V0c1trZXldID0gZmllbGRBcnJheVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKChmOiBzdHJpbmcpID0+ICFpc0ludGVybmFsU3Vic2V0RmllbGQoZikpXG4gICAgICAgICAgICAgICAgICAgIC5tYXAobm9ybWFsaXplU3Vic2V0RmllbGQpO1xuICAgICAgICAgICAgICAgICAgbm9ybWFsaXplZFN1YnNldHNJbnRlcm5hbFtrZXldID0gZmllbGRBcnJheVxuICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGlzSW50ZXJuYWxTdWJzZXRGaWVsZClcbiAgICAgICAgICAgICAgICAgICAgLm1hcChub3JtYWxpemVTdWJzZXRGaWVsZCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZW50aXR5LnN1YnNldHMgPVxuICAgICAgICAgICAgICAgICAgbW9kZSA9PT0gXCJyZXBsYWNlXCJcbiAgICAgICAgICAgICAgICAgICAgPyBub3JtYWxpemVkU3Vic2V0c1xuICAgICAgICAgICAgICAgICAgICA6IHsgLi4uZW50aXR5LnN1YnNldHMsIC4uLm5vcm1hbGl6ZWRTdWJzZXRzIH07XG4gICAgICAgICAgICAgICAgZW50aXR5LnN1YnNldHNJbnRlcm5hbCA9XG4gICAgICAgICAgICAgICAgICBtb2RlID09PSBcInJlcGxhY2VcIlxuICAgICAgICAgICAgICAgICAgICA/IG5vcm1hbGl6ZWRTdWJzZXRzSW50ZXJuYWxcbiAgICAgICAgICAgICAgICAgICAgOiB7IC4uLmVudGl0eS5zdWJzZXRzSW50ZXJuYWwsIC4uLm5vcm1hbGl6ZWRTdWJzZXRzSW50ZXJuYWwgfTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmICh1cGRhdGVzLmVudW1zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjb252ZXJ0ZWRFbnVtcyA9IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgICAgICAgICAgICAgIE9iamVjdC5lbnRyaWVzKHVwZGF0ZXMuZW51bXMpLm1hcCgoW2tleSwgZW51bURlZl0pID0+IFtcbiAgICAgICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgICAgICBnZXRFbnVtRGVmVmFsdWVzKGVudW1EZWYpLFxuICAgICAgICAgICAgICAgICAgXSksXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBlbnRpdHkuZW51bUxhYmVscyA9XG4gICAgICAgICAgICAgICAgICBtb2RlID09PSBcInJlcGxhY2VcIiA/IGNvbnZlcnRlZEVudW1zIDogeyAuLi5lbnRpdHkuZW51bUxhYmVscywgLi4uY29udmVydGVkRW51bXMgfTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIOyggOyepSDsoIQg6rKA7KadXG4gICAgICAgICAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0ZUVudGl0eUpzb24oe1xuICAgICAgICAgICAgICAgIC4uLmVudGl0eSxcbiAgICAgICAgICAgICAgICBlbnRpdHlJZDogZW50aXR5LmlkLFxuICAgICAgICAgICAgICAgIGVudW1zOiBlbnRpdHkuZW51bUxhYmVscyxcbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgaWYgKHZhbGlkYXRpb25FcnJvcnMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgIGVudGl0eUlkLFxuICAgICAgICAgICAgICAgICAgZXJyb3I6IGDqsoDspp0g7Jik66WYOiAke3ZhbGlkYXRpb25FcnJvcnMubWFwKChlKSA9PiBgWyR7ZS5maWVsZH1dICR7ZS5tZXNzYWdlfWApLmpvaW4oXCIsIFwiKX1gLFxuICAgICAgICAgICAgICAgICAgdmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgYXdhaXQgZW50aXR5LnNhdmUoKTtcblxuICAgICAgICAgICAgICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCBlbnRpdHlJZCB9O1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICBjb25zdCBlcnJvciA9IGUgaW5zdGFuY2VvZiBFcnJvciA/IGUubWVzc2FnZSA6IFwiVW5rbm93biBlcnJvclwiO1xuICAgICAgICAgICAgICByZXR1cm4geyBzdWNjZXNzOiBmYWxzZSwgZW50aXR5SWQsIGVycm9yIH07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSxcbiAgICAgICAgfSksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogRW50aXR5IEpTT07snbQgZW50aXR5Lmluc3RydWN0aW9ucy5tZOydmCDqt5zsuZnsnYQg65Sw66W064qU7KeAIOqygOymne2VqeuLiOuLpC5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVFbnRpdHlKc29uKGlucHV0OiBUZW1wbGF0ZU9wdGlvbnNbXCJlbnRpdHlcIl0pOiBWYWxpZGF0aW9uRXJyb3JbXSB7XG4gIGNvbnN0IGVycm9yczogVmFsaWRhdGlvbkVycm9yW10gPSBbXTtcbiAgY29uc3QgeyBlbnRpdHlJZCwgcHJvcHMsIGVudW1zIH0gPSBpbnB1dDtcblxuICAvLyAxLiBpZCwgY3JlYXRlZF9hdCBwcm9wIO2VhOyImFxuICBjb25zdCBoYXNJZFByb3AgPSBwcm9wcz8uc29tZSgocCkgPT4gcC5uYW1lID09PSBcImlkXCIpO1xuICBpZiAoIWhhc0lkUHJvcCkge1xuICAgIGVycm9ycy5wdXNoKHsgZmllbGQ6IFwicHJvcHNcIiwgbWVzc2FnZTogXCJpZCDtlITroZztjbzti7DqsIAg7ZWE7IiY7J6F64uI64ukLlwiIH0pO1xuICB9XG4gIGNvbnN0IGhhc0NyZWF0ZWRBdFByb3AgPSBwcm9wcz8uc29tZSgocCkgPT4gcC5uYW1lID09PSBcImNyZWF0ZWRfYXRcIik7XG4gIGlmICghaGFzQ3JlYXRlZEF0UHJvcCkge1xuICAgIGVycm9ycy5wdXNoKHsgZmllbGQ6IFwicHJvcHNcIiwgbWVzc2FnZTogXCJjcmVhdGVkX2F0IO2UhOuhnO2NvO2LsOqwgCDtlYTsiJjsnoXri4jri6QuXCIgfSk7XG4gIH1cblxuICAvLyAyLiDtlYTsiJggZW51bSDqsoDspp06IEVudGl0eU5hbWVPcmRlckJ5LCBFbnRpdHlOYW1lU2VhcmNoRmllbGRcbiAgY29uc3Qgb3JkZXJCeUVudW1JZCA9IGAke2VudGl0eUlkfU9yZGVyQnlgO1xuICBjb25zdCBzZWFyY2hGaWVsZEVudW1JZCA9IGAke2VudGl0eUlkfVNlYXJjaEZpZWxkYDtcblxuICBpZiAoIWVudW1zPy5bb3JkZXJCeUVudW1JZF0pIHtcbiAgICBlcnJvcnMucHVzaCh7XG4gICAgICBmaWVsZDogXCJlbnVtc1wiLFxuICAgICAgbWVzc2FnZTogYCR7b3JkZXJCeUVudW1JZH0gZW51beydtCDtlYTsiJjsnoXri4jri6QuICjsmIg6IHsgXCJpZC1kZXNjXCI6IFwiSUTstZzsi6DsiJxcIiB9KWAsXG4gICAgfSk7XG4gIH1cbiAgaWYgKCFlbnVtcz8uW3NlYXJjaEZpZWxkRW51bUlkXSkge1xuICAgIGVycm9ycy5wdXNoKHtcbiAgICAgIGZpZWxkOiBcImVudW1zXCIsXG4gICAgICBtZXNzYWdlOiBgJHtzZWFyY2hGaWVsZEVudW1JZH0gZW51beydtCDtlYTsiJjsnoXri4jri6QuICjsmIg6IHsgXCJpZFwiOiBcIklEXCIgfSlgLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gMy4gZW51bSBwcm9w7J2YIGlk6rCAIGVudW1z7JeQIOygleydmOuQmOyWtCDsnojripTsp4Ag7ZmV7J24IChjcm9zcy1maWVsZCDqsoDspp0pXG4gIGZvciAoY29uc3QgcHJvcCBvZiBwcm9wcyA/PyBbXSkge1xuICAgIGlmIChwcm9wLnR5cGUgPT09IFwiZW51bVwiICYmICFlbnVtcz8uW3Byb3AuaWRdKSB7XG4gICAgICBlcnJvcnMucHVzaCh7XG4gICAgICAgIGZpZWxkOiBgcHJvcHMuJHtwcm9wLm5hbWV9YCxcbiAgICAgICAgbWVzc2FnZTogYGVudW0gaWQgXCIke3Byb3AuaWR9XCLqsIAgZW51bXPsl5Ag7KCV7J2Y65CY7Ja0IOyeiOyngCDslYrsirXri4jri6QuYCxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlcnJvcnM7XG59XG5cbmV4cG9ydCBjb25zdCBhaUNsaWVudCA9IG5ldyBBSUNsaWVudCgpO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQW1oQkEsU0FBUyxtQkFBbUIsT0FBcUQ7Q0FDL0UsTUFBTUEsU0FBNEIsRUFBRTtDQUNwQyxNQUFNLEVBQUUsVUFBVSxPQUFPLFVBQVU7Q0FHbkMsTUFBTSxZQUFZLE9BQU8sTUFBTSxNQUFNLEVBQUUsU0FBUyxLQUFLO0FBQ3JELEtBQUksQ0FBQyxXQUFXO0FBQ2QsU0FBTyxLQUFLO0dBQUUsT0FBTztHQUFTLFNBQVM7R0FBbUIsQ0FBQzs7Q0FFN0QsTUFBTSxtQkFBbUIsT0FBTyxNQUFNLE1BQU0sRUFBRSxTQUFTLGFBQWE7QUFDcEUsS0FBSSxDQUFDLGtCQUFrQjtBQUNyQixTQUFPLEtBQUs7R0FBRSxPQUFPO0dBQVMsU0FBUztHQUEyQixDQUFDOztDQUlyRSxNQUFNLGdCQUFnQixHQUFHLFNBQVM7Q0FDbEMsTUFBTSxvQkFBb0IsR0FBRyxTQUFTO0FBRXRDLEtBQUksQ0FBQyxRQUFRLGdCQUFnQjtBQUMzQixTQUFPLEtBQUs7R0FDVixPQUFPO0dBQ1AsU0FBUyxHQUFHLGNBQWM7R0FDM0IsQ0FBQzs7QUFFSixLQUFJLENBQUMsUUFBUSxvQkFBb0I7QUFDL0IsU0FBTyxLQUFLO0dBQ1YsT0FBTztHQUNQLFNBQVMsR0FBRyxrQkFBa0I7R0FDL0IsQ0FBQzs7QUFJSixNQUFLLE1BQU0sUUFBUSxTQUFTLEVBQUUsRUFBRTtBQUM5QixNQUFJLEtBQUssU0FBUyxVQUFVLENBQUMsUUFBUSxLQUFLLEtBQUs7QUFDN0MsVUFBTyxLQUFLO0lBQ1YsT0FBTyxTQUFTLEtBQUs7SUFDckIsU0FBUyxZQUFZLEtBQUssR0FB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
|