sonamu 0.8.25 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +60 -13
- package/dist/_virtual/rolldown_runtime.js +39 -0
- package/dist/ai/agents/agent.d.ts +3 -3
- package/dist/ai/agents/agent.d.ts.map +1 -1
- package/dist/ai/agents/agent.js +76 -73
- package/dist/ai/agents/index.js +3 -3
- package/dist/ai/agents/types.d.ts +3 -3
- package/dist/ai/agents/types.d.ts.map +1 -1
- package/dist/ai/agents/types.js +1 -3
- package/dist/ai/index.js +3 -2
- package/dist/ai/providers/rtzr/api.js +25 -25
- package/dist/ai/providers/rtzr/error.js +25 -26
- package/dist/ai/providers/rtzr/index.js +5 -5
- package/dist/ai/providers/rtzr/model.d.ts +1 -1
- package/dist/ai/providers/rtzr/model.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/model.js +117 -133
- package/dist/ai/providers/rtzr/options.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/options.js +35 -41
- package/dist/ai/providers/rtzr/provider.d.ts +1 -1
- package/dist/ai/providers/rtzr/provider.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/provider.js +53 -51
- package/dist/ai/providers/rtzr/utils.d.ts.map +1 -1
- package/dist/ai/providers/rtzr/utils.js +84 -84
- package/dist/api/base-frame.d.ts +2 -2
- package/dist/api/base-frame.d.ts.map +1 -1
- package/dist/api/base-frame.js +29 -19
- package/dist/api/caster.d.ts +1 -1
- package/dist/api/caster.d.ts.map +1 -1
- package/dist/api/caster.js +51 -61
- package/dist/api/code-converters.d.ts +4 -3
- package/dist/api/code-converters.d.ts.map +1 -1
- package/dist/api/code-converters.js +226 -249
- package/dist/api/config.d.ts +17 -17
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +37 -30
- package/dist/api/context.d.ts +10 -10
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +8 -2
- package/dist/api/decorators.d.ts +8 -8
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +245 -268
- package/dist/api/index.js +39 -7
- package/dist/api/secret.js +22 -15
- package/dist/api/sonamu.d.ts +15 -15
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +1012 -1131
- package/dist/api/validator.js +88 -79
- package/dist/auth/auth-generator.d.ts.map +1 -1
- package/dist/auth/auth-generator.js +203 -200
- package/dist/auth/better-auth-entities.d.ts +2 -2
- package/dist/auth/better-auth-entities.d.ts.map +1 -1
- package/dist/auth/better-auth-entities.js +369 -429
- package/dist/auth/index.js +21 -6
- package/dist/auth/knex-adapter.d.ts +2 -2
- package/dist/auth/knex-adapter.d.ts.map +1 -1
- package/dist/auth/knex-adapter.js +153 -153
- package/dist/auth/plugins/entity-definitions/admin.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/admin.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/admin.js +58 -56
- package/dist/auth/plugins/entity-definitions/anonymous.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/anonymous.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/anonymous.js +20 -20
- package/dist/auth/plugins/entity-definitions/api-key.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/api-key.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/api-key.js +185 -196
- package/dist/auth/plugins/entity-definitions/index.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/index.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/index.js +26 -29
- package/dist/auth/plugins/entity-definitions/jwt.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/jwt.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/jwt.js +62 -64
- package/dist/auth/plugins/entity-definitions/organization.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/organization.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/organization.js +362 -421
- package/dist/auth/plugins/entity-definitions/passkey.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/passkey.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/passkey.js +115 -126
- package/dist/auth/plugins/entity-definitions/phone-number.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/phone-number.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/phone-number.js +31 -40
- package/dist/auth/plugins/entity-definitions/sso.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/sso.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/sso.js +94 -107
- package/dist/auth/plugins/entity-definitions/two-factor.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/two-factor.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/two-factor.js +78 -92
- package/dist/auth/plugins/entity-definitions/types.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/types.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/types.js +1 -10
- package/dist/auth/plugins/entity-definitions/username.d.ts +1 -1
- package/dist/auth/plugins/entity-definitions/username.d.ts.map +1 -1
- package/dist/auth/plugins/entity-definitions/username.js +31 -40
- package/dist/auth/plugins/index.js +12 -3
- package/dist/auth/plugins/wrappers/admin.d.ts +2 -2
- package/dist/auth/plugins/wrappers/admin.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/admin.js +28 -29
- package/dist/auth/plugins/wrappers/anonymous.d.ts +2 -1
- package/dist/auth/plugins/wrappers/anonymous.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/anonymous.js +23 -22
- package/dist/auth/plugins/wrappers/api-key.d.ts +2 -1
- package/dist/auth/plugins/wrappers/api-key.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/api-key.js +39 -34
- package/dist/auth/plugins/wrappers/index.js +11 -11
- package/dist/auth/plugins/wrappers/jwt.d.ts +2 -1
- package/dist/auth/plugins/wrappers/jwt.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/jwt.js +31 -26
- package/dist/auth/plugins/wrappers/organization.d.ts +2 -1
- package/dist/auth/plugins/wrappers/organization.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/organization.js +65 -62
- package/dist/auth/plugins/wrappers/passkey.d.ts +2 -1
- package/dist/auth/plugins/wrappers/passkey.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/passkey.js +33 -28
- package/dist/auth/plugins/wrappers/phone-number.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/phone-number.js +26 -23
- package/dist/auth/plugins/wrappers/sso.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/sso.js +37 -31
- package/dist/auth/plugins/wrappers/two-factor.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/two-factor.js +31 -28
- package/dist/auth/plugins/wrappers/username.d.ts.map +1 -1
- package/dist/auth/plugins/wrappers/username.js +23 -23
- package/dist/bin/build-config.js +31 -31
- package/dist/bin/cli.js +1063 -1204
- package/dist/bin/fixture.d.ts.map +1 -1
- package/dist/bin/fixture.js +266 -259
- package/dist/bin/hmr-hook-register.d.ts.map +1 -1
- package/dist/bin/hmr-hook-register.js +19 -18
- package/dist/bin/test-command.d.ts.map +1 -1
- package/dist/bin/test-command.js +180 -177
- package/dist/bin/ts-loader-register.js +13 -6
- package/dist/bin/ts-loader-registration.d.ts.map +1 -1
- package/dist/bin/ts-loader-registration.js +28 -38
- package/dist/cache/cache-manager.d.ts +1 -1
- package/dist/cache/cache-manager.d.ts.map +1 -1
- package/dist/cache/cache-manager.js +20 -15
- package/dist/cache/decorator.d.ts +1 -1
- package/dist/cache/decorator.d.ts.map +1 -1
- package/dist/cache/decorator.js +84 -76
- package/dist/cache/drivers.js +21 -34
- package/dist/cache/index.js +10 -7
- package/dist/cache/types.d.ts +2 -2
- package/dist/cache/types.d.ts.map +1 -1
- package/dist/cache/types.js +1 -6
- package/dist/cache-control/cache-control.d.ts +2 -2
- package/dist/cache-control/cache-control.d.ts.map +1 -1
- package/dist/cache-control/cache-control.js +106 -122
- package/dist/cache-control/types.d.ts +2 -2
- package/dist/cache-control/types.d.ts.map +1 -1
- package/dist/cache-control/types.js +1 -19
- package/dist/compress/compress.d.ts +1 -1
- package/dist/compress/compress.d.ts.map +1 -1
- package/dist/compress/compress.js +58 -56
- package/dist/compress/index.js +7 -2
- package/dist/compress/types.js +1 -11
- package/dist/cone/cone-generator.d.ts +1 -1
- package/dist/cone/cone-generator.d.ts.map +1 -1
- package/dist/cone/cone-generator.js +216 -219
- package/dist/database/_batch_update.d.ts +1 -1
- package/dist/database/_batch_update.d.ts.map +1 -1
- package/dist/database/_batch_update.js +107 -102
- package/dist/database/base-model.d.ts +8 -9
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.js +371 -392
- package/dist/database/base-model.types.d.ts +5 -5
- package/dist/database/base-model.types.d.ts.map +1 -1
- package/dist/database/base-model.types.js +1 -20
- package/dist/database/db.d.ts +5 -2
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +185 -171
- package/dist/database/knex.d.ts +1 -1
- package/dist/database/knex.d.ts.map +1 -1
- package/dist/database/knex.js +48 -42
- package/dist/database/puri-subset.types.d.ts +7 -8
- package/dist/database/puri-subset.types.d.ts.map +1 -1
- package/dist/database/puri-subset.types.js +1 -16
- package/dist/database/puri-wrapper.d.ts +6 -6
- package/dist/database/puri-wrapper.d.ts.map +1 -1
- package/dist/database/puri-wrapper.js +99 -101
- package/dist/database/puri.d.ts +4 -5
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +1021 -1227
- package/dist/database/puri.types.d.ts +6 -6
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/puri.types.js +15 -6
- package/dist/database/transaction-context.d.ts +2 -2
- package/dist/database/transaction-context.d.ts.map +1 -1
- package/dist/database/transaction-context.js +22 -13
- package/dist/database/upsert-builder.d.ts +3 -3
- package/dist/database/upsert-builder.d.ts.map +1 -1
- package/dist/database/upsert-builder.js +405 -465
- package/dist/dict/en.js +72 -74
- package/dist/dict/index.js +13 -13
- package/dist/dict/ko.js +72 -74
- package/dist/dict/rc-keys.js +150 -168
- package/dist/dict/sd.d.ts +3 -1
- package/dist/dict/sd.d.ts.map +1 -1
- package/dist/dict/sd.js +54 -40
- package/dist/dict/sonamu-dictionary.d.ts +1 -1
- package/dist/dict/sonamu-dictionary.d.ts.map +1 -1
- package/dist/dict/sonamu-dictionary.js +887 -955
- package/dist/dict/types.js +1 -7
- package/dist/dict/utils.js +26 -24
- package/dist/entity/entity-manager.d.ts +9 -9
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +226 -223
- package/dist/entity/entity-template-cone.d.ts +1 -1
- package/dist/entity/entity-template-cone.d.ts.map +1 -1
- package/dist/entity/entity-template-cone.js +152 -151
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +952 -1089
- package/dist/exceptions/error-handler.d.ts +1 -1
- package/dist/exceptions/error-handler.d.ts.map +1 -1
- package/dist/exceptions/error-handler.js +32 -27
- package/dist/exceptions/so-exceptions.d.ts +1 -1
- package/dist/exceptions/so-exceptions.d.ts.map +1 -1
- package/dist/exceptions/so-exceptions.js +61 -68
- package/dist/filter/index.js +9 -3
- package/dist/filter/types.js +92 -88
- package/dist/filter/utils.d.ts +1 -1
- package/dist/filter/utils.d.ts.map +1 -1
- package/dist/filter/utils.js +147 -161
- package/dist/index.js +87 -40
- package/dist/logger/category.d.ts.map +1 -1
- package/dist/logger/category.js +30 -29
- package/dist/logger/configure.d.ts.map +1 -1
- package/dist/logger/configure.js +83 -107
- package/dist/migration/code-generation.d.ts +2 -2
- package/dist/migration/code-generation.d.ts.map +1 -1
- package/dist/migration/code-generation.js +1385 -1578
- package/dist/migration/migration-set.d.ts +1 -1
- package/dist/migration/migration-set.d.ts.map +1 -1
- package/dist/migration/migration-set.js +177 -227
- package/dist/migration/migrator.d.ts +4 -3
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +340 -345
- package/dist/migration/postgresql-schema-reader.d.ts +2 -2
- package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
- package/dist/migration/postgresql-schema-reader.js +506 -564
- package/dist/migration/slack-confirm.d.ts +2 -2
- package/dist/migration/slack-confirm.d.ts.map +1 -1
- package/dist/migration/slack-confirm.js +205 -193
- package/dist/migration/types.d.ts +2 -2
- package/dist/migration/types.d.ts.map +1 -1
- package/dist/migration/types.js +1 -3
- package/dist/naite/messaging-types.d.ts +1 -0
- package/dist/naite/messaging-types.d.ts.map +1 -1
- package/dist/naite/messaging-types.js +1 -7
- package/dist/naite/naite-reporter.d.ts +2 -2
- package/dist/naite/naite-reporter.d.ts.map +1 -1
- package/dist/naite/naite-reporter.js +127 -120
- package/dist/naite/naite.d.ts +3 -2
- package/dist/naite/naite.d.ts.map +1 -1
- package/dist/naite/naite.js +266 -300
- package/dist/ssr/index.d.ts +2 -2
- package/dist/ssr/index.d.ts.map +1 -1
- package/dist/ssr/index.js +13 -3
- package/dist/ssr/registry.d.ts +1 -1
- package/dist/ssr/registry.d.ts.map +1 -1
- package/dist/ssr/registry.js +45 -37
- package/dist/ssr/renderer.d.ts +4 -4
- package/dist/ssr/renderer.d.ts.map +1 -1
- package/dist/ssr/renderer.js +84 -91
- package/dist/ssr/types.d.ts +2 -2
- package/dist/ssr/types.d.ts.map +1 -1
- package/dist/ssr/types.js +1 -3
- package/dist/storage/base-file.js +54 -41
- package/dist/storage/buffered-file.d.ts +2 -2
- package/dist/storage/buffered-file.d.ts.map +1 -1
- package/dist/storage/buffered-file.js +51 -44
- package/dist/storage/drivers.d.ts +2 -2
- package/dist/storage/drivers.d.ts.map +1 -1
- package/dist/storage/drivers.js +12 -7
- package/dist/storage/index.js +14 -7
- package/dist/storage/s3-driver.d.ts +2 -2
- package/dist/storage/s3-driver.d.ts.map +1 -1
- package/dist/storage/s3-driver.js +52 -48
- package/dist/storage/storage-manager.d.ts +2 -2
- package/dist/storage/storage-manager.d.ts.map +1 -1
- package/dist/storage/storage-manager.js +33 -25
- package/dist/storage/types.d.ts +2 -2
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/types.js +1 -5
- package/dist/storage/uploaded-file.d.ts +1 -1
- package/dist/storage/uploaded-file.d.ts.map +1 -1
- package/dist/storage/uploaded-file.js +45 -35
- package/dist/stream/index.js +7 -2
- package/dist/stream/sse.d.ts +2 -2
- package/dist/stream/sse.d.ts.map +1 -1
- package/dist/stream/sse.js +72 -67
- package/dist/syncer/api-parser.d.ts +1 -1
- package/dist/syncer/api-parser.d.ts.map +1 -1
- package/dist/syncer/api-parser.js +224 -245
- package/dist/syncer/checksum.d.ts +1 -1
- package/dist/syncer/checksum.d.ts.map +1 -1
- package/dist/syncer/checksum.js +86 -72
- package/dist/syncer/code-generator.d.ts +2 -2
- package/dist/syncer/code-generator.d.ts.map +1 -1
- package/dist/syncer/code-generator.js +154 -160
- package/dist/syncer/entity-operations.d.ts +1 -1
- package/dist/syncer/entity-operations.d.ts.map +1 -1
- package/dist/syncer/entity-operations.js +63 -54
- package/dist/syncer/file-patterns.d.ts +1 -1
- package/dist/syncer/file-patterns.d.ts.map +1 -1
- package/dist/syncer/file-patterns.js +38 -38
- package/dist/syncer/index.js +19 -8
- package/dist/syncer/module-loader.d.ts +5 -5
- package/dist/syncer/module-loader.d.ts.map +1 -1
- package/dist/syncer/module-loader.js +83 -78
- package/dist/syncer/syncer-actions.d.ts +2 -2
- package/dist/syncer/syncer-actions.d.ts.map +1 -1
- package/dist/syncer/syncer-actions.js +76 -91
- package/dist/syncer/syncer.d.ts +7 -6
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +426 -492
- package/dist/tasks/decorator.d.ts +3 -3
- package/dist/tasks/decorator.d.ts.map +1 -1
- package/dist/tasks/decorator.js +32 -28
- package/dist/tasks/step-wrapper.d.ts +1 -1
- package/dist/tasks/step-wrapper.d.ts.map +1 -1
- package/dist/tasks/step-wrapper.js +42 -41
- package/dist/tasks/workflow-manager.d.ts +2 -2
- package/dist/tasks/workflow-manager.d.ts.map +1 -1
- package/dist/tasks/workflow-manager.js +192 -221
- package/dist/template/entity-converter.d.ts +1 -1
- package/dist/template/entity-converter.d.ts.map +1 -1
- package/dist/template/entity-converter.js +103 -103
- package/dist/template/helpers.d.ts.map +1 -1
- package/dist/template/helpers.js +163 -163
- package/dist/template/implementations/entity.template.d.ts +1 -1
- package/dist/template/implementations/entity.template.d.ts.map +1 -1
- package/dist/template/implementations/entity.template.js +76 -85
- package/dist/template/implementations/entry-server.template.d.ts +1 -1
- package/dist/template/implementations/entry-server.template.d.ts.map +1 -1
- package/dist/template/implementations/entry-server.template.js +32 -27
- package/dist/template/implementations/generated.template.d.ts +1 -1
- package/dist/template/implementations/generated.template.d.ts.map +1 -1
- package/dist/template/implementations/generated.template.js +254 -275
- package/dist/template/implementations/generated_http.template.d.ts +2 -2
- package/dist/template/implementations/generated_http.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_http.template.js +114 -133
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_sso.template.js +249 -275
- package/dist/template/implementations/init_types.template.d.ts +1 -1
- package/dist/template/implementations/init_types.template.d.ts.map +1 -1
- package/dist/template/implementations/init_types.template.js +40 -34
- package/dist/template/implementations/model.template.d.ts +1 -1
- package/dist/template/implementations/model.template.d.ts.map +1 -1
- package/dist/template/implementations/model.template.js +56 -53
- package/dist/template/implementations/model_test.template.d.ts +1 -1
- package/dist/template/implementations/model_test.template.d.ts.map +1 -1
- package/dist/template/implementations/model_test.template.js +32 -24
- package/dist/template/implementations/queries.template.d.ts +1 -1
- package/dist/template/implementations/queries.template.d.ts.map +1 -1
- package/dist/template/implementations/queries.template.js +84 -89
- package/dist/template/implementations/sd.template.d.ts +1 -1
- package/dist/template/implementations/sd.template.d.ts.map +1 -1
- package/dist/template/implementations/sd.template.js +137 -144
- package/dist/template/implementations/services.template.d.ts +1 -1
- package/dist/template/implementations/services.template.d.ts.map +1 -1
- package/dist/template/implementations/services.template.js +164 -189
- package/dist/template/implementations/view_form.template.d.ts +1 -1
- package/dist/template/implementations/view_form.template.d.ts.map +1 -1
- package/dist/template/implementations/view_form.template.js +258 -285
- package/dist/template/implementations/view_id_all_select.template.d.ts +1 -1
- package/dist/template/implementations/view_id_all_select.template.d.ts.map +1 -1
- package/dist/template/implementations/view_id_all_select.template.js +31 -25
- package/dist/template/implementations/view_list.template.d.ts +1 -1
- package/dist/template/implementations/view_list.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list.template.js +304 -355
- package/dist/template/implementations/view_search_input.template.d.ts +1 -1
- package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
- package/dist/template/implementations/view_search_input.template.js +31 -27
- package/dist/template/index.js +21 -7
- package/dist/template/template-manager.d.ts +1 -1
- package/dist/template/template-manager.d.ts.map +1 -1
- package/dist/template/template-manager.js +132 -123
- package/dist/template/template-types.js +8 -6
- package/dist/template/template.d.ts +2 -2
- package/dist/template/template.d.ts.map +1 -1
- package/dist/template/template.js +73 -68
- package/dist/template/zod-converter.d.ts.map +1 -1
- package/dist/template/zod-converter.js +603 -657
- package/dist/testing/_relation-graph.d.ts +1 -1
- package/dist/testing/_relation-graph.d.ts.map +1 -1
- package/dist/testing/_relation-graph.js +93 -88
- package/dist/testing/bootstrap.d.ts +22 -13
- package/dist/testing/bootstrap.d.ts.map +1 -1
- package/dist/testing/bootstrap.js +114 -114
- package/dist/testing/data-explorer.d.ts +3 -3
- package/dist/testing/data-explorer.d.ts.map +1 -1
- package/dist/testing/data-explorer.js +237 -265
- package/dist/testing/dev-test-routes.d.ts +2 -2
- package/dist/testing/dev-test-routes.d.ts.map +1 -1
- package/dist/testing/dev-test-routes.js +258 -249
- package/dist/testing/dev-vitest-manager.d.ts +1 -1
- package/dist/testing/dev-vitest-manager.d.ts.map +1 -1
- package/dist/testing/dev-vitest-manager.js +514 -539
- package/dist/testing/faker-mappings.js +422 -420
- package/dist/testing/fixture-generator.d.ts +3 -3
- package/dist/testing/fixture-generator.d.ts.map +1 -1
- package/dist/testing/fixture-generator.js +1216 -1346
- package/dist/testing/fixture-loader.js +26 -25
- package/dist/testing/fixture-manager.d.ts +3 -3
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +706 -776
- package/dist/testing/global-setup.js +53 -49
- package/dist/testing/index.js +19 -11
- package/dist/testing/naite-vitest-reporter.js +18 -13
- package/dist/testing/parallel-db-manager.d.ts +1 -1
- package/dist/testing/parallel-db-manager.d.ts.map +1 -1
- package/dist/testing/parallel-db-manager.js +63 -78
- package/dist/testing/vitest-helpers.d.ts +1 -1
- package/dist/testing/vitest-helpers.d.ts.map +1 -1
- package/dist/testing/vitest-helpers.js +37 -33
- package/dist/types/types.d.ts +28 -28
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +764 -890
- package/dist/ui/ai-api.d.ts +1 -1
- package/dist/ui/ai-api.d.ts.map +1 -1
- package/dist/ui/ai-api.js +52 -42
- package/dist/ui/ai-client.d.ts +1 -2
- package/dist/ui/ai-client.d.ts.map +1 -1
- package/dist/ui/ai-client.js +353 -388
- package/dist/ui/api.d.ts +1 -1
- package/dist/ui/api.d.ts.map +1 -1
- package/dist/ui/api.js +903 -1145
- package/dist/ui/cdd-service.d.ts +15 -18
- package/dist/ui/cdd-service.d.ts.map +1 -1
- package/dist/ui/cdd-service.js +406 -383
- package/dist/ui/cdd-types.d.ts +41 -68
- package/dist/ui/cdd-types.d.ts.map +1 -1
- package/dist/ui/cdd-types.js +1 -3
- package/dist/ui-web/assets/index-C-Zz-wYg.css +1 -0
- package/dist/ui-web/assets/index-DejDON8K.js +238 -0
- package/dist/ui-web/index.html +3 -3
- package/dist/utils/async-utils.js +57 -45
- package/dist/utils/console-util.d.ts.map +1 -1
- package/dist/utils/console-util.js +104 -87
- package/dist/utils/controller.js +26 -19
- package/dist/utils/esm-utils.js +49 -38
- package/dist/utils/formatter.d.ts +1 -2
- package/dist/utils/formatter.d.ts.map +1 -1
- package/dist/utils/formatter.js +89 -115
- package/dist/utils/fs-utils.d.ts.map +1 -1
- package/dist/utils/fs-utils.js +68 -65
- package/dist/utils/lodash-able.js +11 -4
- package/dist/utils/model.d.ts +1 -1
- package/dist/utils/model.d.ts.map +1 -1
- package/dist/utils/model.js +21 -19
- package/dist/utils/object-utils.js +148 -186
- package/dist/utils/path-utils.js +67 -57
- package/dist/utils/process-utils.d.ts.map +1 -1
- package/dist/utils/process-utils.js +37 -31
- package/dist/utils/sql-parser.d.ts +1 -1
- package/dist/utils/sql-parser.d.ts.map +1 -1
- package/dist/utils/sql-parser.js +40 -40
- package/dist/utils/type-utils.js +44 -43
- package/dist/utils/utils.d.ts +2 -3
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +81 -93
- package/dist/utils/zod-error.d.ts +1 -1
- package/dist/utils/zod-error.d.ts.map +1 -1
- package/dist/utils/zod-error.js +24 -17
- package/dist/vector/chunking.d.ts +1 -1
- package/dist/vector/chunking.d.ts.map +1 -1
- package/dist/vector/chunking.js +100 -94
- package/dist/vector/config.d.ts +1 -1
- package/dist/vector/config.d.ts.map +1 -1
- package/dist/vector/config.js +76 -78
- package/dist/vector/embedding.d.ts +1 -1
- package/dist/vector/embedding.d.ts.map +1 -1
- package/dist/vector/embedding.js +128 -125
- package/dist/vector/index.js +5 -5
- package/dist/vector/types.js +1 -5
- package/package.json +35 -36
- package/src/ai/agents/agent.ts +12 -5
- package/src/ai/agents/types.ts +5 -5
- package/src/ai/providers/rtzr/model.ts +8 -10
- package/src/ai/providers/rtzr/options.ts +2 -1
- package/src/ai/providers/rtzr/provider.ts +5 -3
- package/src/ai/providers/rtzr/utils.ts +2 -7
- package/src/api/__tests__/config.test.ts +15 -8
- package/src/api/base-frame.ts +5 -3
- package/src/api/caster.ts +7 -6
- package/src/api/code-converters.ts +23 -26
- package/src/api/config.ts +23 -17
- package/src/api/context.ts +18 -11
- package/src/api/decorators.ts +17 -18
- package/src/api/sonamu.ts +44 -49
- package/src/auth/auth-generator.ts +4 -6
- package/src/auth/better-auth-entities.ts +3 -2
- package/src/auth/knex-adapter.ts +9 -7
- package/src/auth/plugins/entity-definitions/admin.ts +1 -1
- package/src/auth/plugins/entity-definitions/anonymous.ts +1 -1
- package/src/auth/plugins/entity-definitions/api-key.ts +1 -1
- package/src/auth/plugins/entity-definitions/index.ts +1 -1
- package/src/auth/plugins/entity-definitions/jwt.ts +1 -1
- package/src/auth/plugins/entity-definitions/organization.ts +1 -1
- package/src/auth/plugins/entity-definitions/passkey.ts +1 -1
- package/src/auth/plugins/entity-definitions/phone-number.ts +1 -1
- package/src/auth/plugins/entity-definitions/sso.ts +1 -1
- package/src/auth/plugins/entity-definitions/two-factor.ts +1 -1
- package/src/auth/plugins/entity-definitions/types.ts +1 -1
- package/src/auth/plugins/entity-definitions/username.ts +1 -1
- package/src/auth/plugins/wrappers/admin.ts +3 -1
- package/src/auth/plugins/wrappers/anonymous.ts +3 -1
- package/src/auth/plugins/wrappers/api-key.ts +3 -1
- package/src/auth/plugins/wrappers/jwt.ts +3 -1
- package/src/auth/plugins/wrappers/organization.ts +3 -1
- package/src/auth/plugins/wrappers/passkey.ts +3 -1
- package/src/auth/plugins/wrappers/phone-number.ts +3 -1
- package/src/auth/plugins/wrappers/sso.ts +2 -1
- package/src/auth/plugins/wrappers/two-factor.ts +3 -1
- package/src/auth/plugins/wrappers/username.ts +3 -1
- package/src/bin/__tests__/ts-loader-register.test.ts +7 -12
- package/src/bin/build-config.ts +3 -3
- package/src/bin/cli.ts +27 -25
- package/src/bin/fixture.ts +4 -2
- package/src/bin/hmr-hook-register.ts +1 -0
- package/src/bin/test-command.ts +4 -2
- package/src/bin/ts-loader-registration.ts +6 -22
- package/src/cache/cache-manager.ts +2 -1
- package/src/cache/decorator.ts +2 -2
- package/src/cache/types.ts +3 -3
- package/src/cache-control/cache-control.ts +3 -2
- package/src/cache-control/types.ts +2 -2
- package/src/compress/compress.ts +1 -1
- package/src/cone/cone-generator.ts +7 -5
- package/src/database/_batch_update.ts +1 -1
- package/src/database/base-model.ts +20 -14
- package/src/database/base-model.types.ts +12 -11
- package/src/database/db.ts +56 -21
- package/src/database/knex.ts +2 -2
- package/src/database/puri-subset.test-d.ts +130 -27
- package/src/database/puri-subset.types.ts +7 -8
- package/src/database/puri-wrapper.ts +29 -26
- package/src/database/puri.ts +36 -34
- package/src/database/puri.types.test-d.ts +6 -5
- package/src/database/puri.types.ts +9 -12
- package/src/database/transaction-context.ts +2 -2
- package/src/database/upsert-builder.ts +17 -10
- package/src/dict/sd.ts +17 -4
- package/src/dict/sonamu-dictionary.ts +23 -17
- package/src/entity/entity-manager.ts +9 -7
- package/src/entity/entity-template-cone.ts +10 -3
- package/src/entity/entity.ts +20 -16
- package/src/exceptions/error-handler.ts +2 -1
- package/src/exceptions/so-exceptions.ts +1 -1
- package/src/filter/utils.ts +3 -2
- package/src/logger/category.ts +1 -0
- package/src/logger/configure.ts +5 -5
- package/src/migration/__tests__/code-generation.search-text.test.ts +2 -3
- package/src/migration/code-generation.ts +26 -25
- package/src/migration/migration-set.ts +16 -18
- package/src/migration/migrator.ts +38 -33
- package/src/migration/postgresql-schema-reader.ts +12 -12
- package/src/migration/slack-confirm.ts +5 -4
- package/src/migration/types.ts +2 -2
- package/src/naite/messaging-types.ts +1 -1
- package/src/naite/naite-reporter.ts +5 -3
- package/src/naite/naite.ts +12 -7
- package/src/shared/app.shared.ts.txt +2 -2
- package/src/shared/web.shared.ts.txt +2 -2
- package/src/skills/AGENTS.md +19 -18
- package/src/skills/commands/sonamu-skills.md +9 -9
- package/src/skills/sonamu/SKILL.md +126 -76
- package/src/skills/sonamu/ai-agents.md +27 -26
- package/src/skills/sonamu/api.md +81 -69
- package/src/skills/sonamu/auth-migration.md +13 -27
- package/src/skills/sonamu/auth-plugins.md +41 -31
- package/src/skills/sonamu/auth.md +30 -24
- package/src/skills/sonamu/cdd.md +26 -17
- package/src/skills/sonamu/cone.md +50 -50
- package/src/skills/sonamu/config.md +74 -51
- package/src/skills/sonamu/create-sonamu.md +31 -19
- package/src/skills/sonamu/database.md +43 -26
- package/src/skills/sonamu/entity-basic.md +61 -61
- package/src/skills/sonamu/entity-relations.md +84 -80
- package/src/skills/sonamu/entity-validation-checklist.md +19 -15
- package/src/skills/sonamu/fixture-cli.md +52 -30
- package/src/skills/sonamu/framework-change.md +9 -7
- package/src/skills/sonamu/frontend.md +64 -82
- package/src/skills/sonamu/i18n.md +45 -37
- package/src/skills/sonamu/migration.md +54 -31
- package/src/skills/sonamu/model.md +98 -66
- package/src/skills/sonamu/naite.md +34 -32
- package/src/skills/sonamu/project-init.md +28 -8
- package/src/skills/sonamu/puri.md +82 -91
- package/src/skills/sonamu/scaffolding.md +44 -32
- package/src/skills/sonamu/skill-contribution.md +50 -45
- package/src/skills/sonamu/subset.md +13 -13
- package/src/skills/sonamu/tasks.md +73 -58
- package/src/skills/sonamu/testing-devrunner.md +56 -36
- package/src/skills/sonamu/testing.md +23 -58
- package/src/skills/sonamu/upsert.md +32 -31
- package/src/skills/sonamu/vector.md +37 -36
- package/src/ssr/index.ts +2 -12
- package/src/ssr/registry.ts +1 -1
- package/src/ssr/renderer.ts +7 -5
- package/src/ssr/types.ts +2 -2
- package/src/storage/buffered-file.ts +4 -2
- package/src/storage/drivers.ts +3 -2
- package/src/storage/s3-driver.ts +7 -4
- package/src/storage/storage-manager.ts +3 -2
- package/src/storage/types.ts +3 -2
- package/src/storage/uploaded-file.ts +1 -1
- package/src/stream/sse.ts +2 -2
- package/src/syncer/api-parser.ts +8 -5
- package/src/syncer/checksum.ts +9 -5
- package/src/syncer/code-generator.ts +16 -8
- package/src/syncer/entity-operations.ts +5 -3
- package/src/syncer/file-patterns.ts +2 -1
- package/src/syncer/module-loader.ts +9 -6
- package/src/syncer/syncer-actions.ts +5 -3
- package/src/syncer/syncer.ts +18 -24
- package/src/tasks/decorator.ts +10 -8
- package/src/tasks/step-wrapper.ts +1 -1
- package/src/tasks/workflow-manager.ts +18 -15
- package/src/template/__tests__/generated.template.search-text.test.ts +1 -0
- package/src/template/entity-converter.ts +4 -2
- package/src/template/generated.template.test-d.ts +2 -1
- package/src/template/helpers.ts +5 -2
- package/src/template/implementations/entity.template.ts +9 -8
- package/src/template/implementations/entry-server.template.ts +1 -1
- package/src/template/implementations/generated.template.ts +21 -29
- package/src/template/implementations/generated_http.template.ts +9 -6
- package/src/template/implementations/generated_sso.template.ts +6 -4
- package/src/template/implementations/init_types.template.ts +3 -2
- package/src/template/implementations/model.template.ts +4 -2
- package/src/template/implementations/model_test.template.ts +3 -2
- package/src/template/implementations/queries.template.ts +6 -14
- package/src/template/implementations/sd.template.ts +4 -2
- package/src/template/implementations/services.template.ts +7 -11
- package/src/template/implementations/view_form.template.ts +5 -3
- package/src/template/implementations/view_id_all_select.template.ts +3 -2
- package/src/template/implementations/view_list.template.ts +7 -5
- package/src/template/implementations/view_search_input.template.ts +3 -2
- package/src/template/template-manager.ts +4 -3
- package/src/template/template.ts +4 -3
- package/src/template/zod-converter.ts +10 -7
- package/src/testing/__tests__/dev-test-routes.test.ts +3 -2
- package/src/testing/__tests__/dev-vitest-manager.test.ts +1 -0
- package/src/testing/_relation-graph.ts +2 -2
- package/src/testing/bootstrap.ts +55 -27
- package/src/testing/data-explorer.ts +5 -4
- package/src/testing/dev-test-routes.ts +8 -5
- package/src/testing/dev-vitest-manager.ts +13 -12
- package/src/testing/fixture-generator.ts +15 -21
- package/src/testing/fixture-manager.ts +21 -17
- package/src/testing/parallel-db-manager.ts +2 -1
- package/src/testing/vitest-helpers.ts +2 -1
- package/src/types/__tests__/entity-json-schema-search-text.test.ts +1 -0
- package/src/types/types.ts +8 -8
- package/src/typings/knex.d.ts +4 -4
- package/src/ui/ai-api.ts +5 -3
- package/src/ui/ai-client.ts +7 -6
- package/src/ui/api.ts +42 -39
- package/src/ui/cdd-service.ts +268 -257
- package/src/ui/cdd-types.ts +40 -75
- package/src/utils/console-util.ts +3 -1
- package/src/utils/formatter.ts +94 -102
- package/src/utils/fs-utils.ts +2 -1
- package/src/utils/model.ts +2 -2
- package/src/utils/object-utils.ts +3 -3
- package/src/utils/process-utils.ts +2 -1
- package/src/utils/sql-parser.ts +10 -1
- package/src/utils/type-utils.ts +3 -3
- package/src/utils/utils.ts +9 -7
- package/src/utils/zod-error.ts +1 -1
- package/src/vector/chunking.ts +1 -1
- package/src/vector/config.ts +1 -1
- package/src/vector/embedding.ts +11 -9
- package/tsdown.api.config.ts +50 -0
- package/.swcrc.project-default +0 -18
- package/dist/api/__tests__/config.test.js +0 -189
- package/dist/bin/__tests__/test-command.test.js +0 -112
- package/dist/bin/__tests__/ts-loader-register.test.js +0 -45
- package/dist/database/puri-subset.test-d.js +0 -81
- package/dist/database/puri.types.test-d.js +0 -129
- package/dist/migration/__tests__/code-generation.search-text.test.js +0 -435
- package/dist/template/__tests__/generated.template.search-text.test.js +0 -99
- package/dist/template/generated.template.test-d.js +0 -24
- package/dist/testing/__tests__/dev-test-routes.test.js +0 -144
- package/dist/testing/__tests__/dev-vitest-manager.test.js +0 -152
- package/dist/types/__tests__/entity-json-schema-search-text.test.js +0 -256
- package/dist/typings/knex.d.js +0 -3
- package/dist/ui-web/assets/index-BrQKU3j9.css +0 -1
- package/dist/ui-web/assets/index-CxiydzeC.js +0 -257
package/dist/ui/cdd-service.js
CHANGED
|
@@ -1,403 +1,426 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import os from "os";
|
|
1
|
+
import { __esmMin } from "../_virtual/rolldown_runtime.js";
|
|
2
|
+
import { Sonamu, init_sonamu } from "../api/sonamu.js";
|
|
4
3
|
import path from "path";
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
throw new Error(`경로가 contract/ 디렉터리 밖을 참조합니다: ${filePath}`);
|
|
14
|
-
}
|
|
4
|
+
import os from "os";
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
import { spawn } from "child_process";
|
|
7
|
+
|
|
8
|
+
//#region src/ui/cdd-service.ts
|
|
9
|
+
/** contract/ 디렉터리 절대 경로 반환 (apiRootPath 기준) */
|
|
10
|
+
function getContractDir() {
|
|
11
|
+
return path.join(Sonamu.apiRootPath, "..", "..", "contract");
|
|
15
12
|
}
|
|
16
|
-
/**
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return undefined;
|
|
13
|
+
/** 프로젝트 루트 경로 반환 */
|
|
14
|
+
function getProjectRoot() {
|
|
15
|
+
return path.join(Sonamu.apiRootPath, "..", "..");
|
|
20
16
|
}
|
|
21
|
-
/**
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const relPath = path.relative(relativeTo, fullPath);
|
|
29
|
-
if (entry.isDirectory()) {
|
|
30
|
-
const children = scanDirectory(fullPath, relativeTo);
|
|
31
|
-
nodes.push({
|
|
32
|
-
name: entry.name,
|
|
33
|
-
path: relPath,
|
|
34
|
-
type: "directory",
|
|
35
|
-
children
|
|
36
|
-
});
|
|
37
|
-
} else if (entry.isFile()) {
|
|
38
|
-
const fileType = detectFileType(entry.name);
|
|
39
|
-
if (fileType) {
|
|
40
|
-
nodes.push({
|
|
41
|
-
name: entry.name,
|
|
42
|
-
path: relPath,
|
|
43
|
-
type: "file",
|
|
44
|
-
fileType
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
return nodes;
|
|
17
|
+
/** 경로가 contract/ 디렉터리 내부인지 검증 */
|
|
18
|
+
function assertInsideContractDir(filePath) {
|
|
19
|
+
const contractDir = getContractDir();
|
|
20
|
+
const resolved = path.resolve(contractDir, filePath);
|
|
21
|
+
if (!resolved.startsWith(contractDir + path.sep) && resolved !== contractDir) {
|
|
22
|
+
throw new Error(`경로가 contract/ 디렉터리 밖을 참조합니다: ${filePath}`);
|
|
23
|
+
}
|
|
50
24
|
}
|
|
51
|
-
/**
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
tree: []
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
const tree = scanDirectory(contractDir, contractDir);
|
|
60
|
-
return {
|
|
61
|
-
exists: true,
|
|
62
|
-
tree
|
|
63
|
-
};
|
|
25
|
+
/** 파일명에서 CddFileType 판별 */
|
|
26
|
+
function detectFileType(fileName) {
|
|
27
|
+
if (fileName.endsWith(".contract.md")) return "contract";
|
|
28
|
+
if (fileName.endsWith(".rules.json")) return "rules";
|
|
29
|
+
return undefined;
|
|
64
30
|
}
|
|
65
|
-
/**
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
31
|
+
/** 디렉터리를 재귀 탐색하여 CddTreeNode 트리를 생성 */
|
|
32
|
+
function scanDirectory(dirPath, relativeTo) {
|
|
33
|
+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
34
|
+
const nodes = [];
|
|
35
|
+
for (const entry of entries) {
|
|
36
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
37
|
+
const relPath = path.relative(relativeTo, fullPath);
|
|
38
|
+
if (entry.isDirectory()) {
|
|
39
|
+
if (entry.name === "rules") continue;
|
|
40
|
+
const children = scanDirectory(fullPath, relativeTo);
|
|
41
|
+
if (children.length > 0) {
|
|
42
|
+
nodes.push({
|
|
43
|
+
name: entry.name,
|
|
44
|
+
path: relPath,
|
|
45
|
+
type: "directory",
|
|
46
|
+
children
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
} else if (entry.isFile()) {
|
|
50
|
+
const fileType = detectFileType(entry.name);
|
|
51
|
+
if (fileType && fileType !== "rules") {
|
|
52
|
+
nodes.push({
|
|
53
|
+
name: entry.name,
|
|
54
|
+
path: relPath,
|
|
55
|
+
type: "file",
|
|
56
|
+
fileType
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return nodes;
|
|
71
62
|
}
|
|
72
|
-
/**
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
schema,
|
|
87
|
-
fileType: fileType ?? "contract"
|
|
88
|
-
};
|
|
63
|
+
/** contract/ 디렉터리의 트리 구조를 반환 */
|
|
64
|
+
function getCddTree() {
|
|
65
|
+
const contractDir = getContractDir();
|
|
66
|
+
if (!fs.existsSync(contractDir)) {
|
|
67
|
+
return {
|
|
68
|
+
exists: false,
|
|
69
|
+
tree: []
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const tree = scanDirectory(contractDir, contractDir);
|
|
73
|
+
return {
|
|
74
|
+
exists: true,
|
|
75
|
+
tree
|
|
76
|
+
};
|
|
89
77
|
}
|
|
90
|
-
/**
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
78
|
+
/** 파일 내용을 읽어 반환 (contract.md → markdown 원문, rules.json → JSON 문자열) */
|
|
79
|
+
function readContent(filePath) {
|
|
80
|
+
assertInsideContractDir(filePath);
|
|
81
|
+
const contractDir = getContractDir();
|
|
82
|
+
const absPath = path.resolve(contractDir, filePath);
|
|
83
|
+
if (!fs.existsSync(absPath)) {
|
|
84
|
+
throw new Error(`파일을 찾을 수 없습니다: ${filePath}`);
|
|
85
|
+
}
|
|
86
|
+
const content = fs.readFileSync(absPath, "utf-8");
|
|
87
|
+
const fileType = detectFileType(path.basename(filePath));
|
|
88
|
+
return {
|
|
89
|
+
content,
|
|
90
|
+
fileType: fileType ?? "contract"
|
|
91
|
+
};
|
|
103
92
|
}
|
|
104
|
-
/**
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
};
|
|
118
|
-
/** 앱 번들 CLI 경로를 resolve. wait=false이면 --wait 플래그를 생략 */ function resolveEditorCli(options) {
|
|
119
|
-
const wait = options?.wait ?? true;
|
|
120
|
-
const appName = Sonamu.config.externalEditor ?? "Visual Studio Code";
|
|
121
|
-
const mapping = EDITOR_CLI_MAP[appName];
|
|
122
|
-
if (!mapping) {
|
|
123
|
-
throw new Error(`지원되지 않는 에디터입니다: ${appName} (지원: ${Object.keys(EDITOR_CLI_MAP).join(", ")})`);
|
|
124
|
-
}
|
|
125
|
-
const searchPaths = [
|
|
126
|
-
`/Applications/${appName}.app`,
|
|
127
|
-
`${os.homedir()}/Applications/${appName}.app`
|
|
128
|
-
];
|
|
129
|
-
const bundlePath = searchPaths.find((p)=>fs.existsSync(p));
|
|
130
|
-
if (!bundlePath) {
|
|
131
|
-
throw new Error(`앱 번들을 찾을 수 없습니다: ${appName} (/Applications 확인)`);
|
|
132
|
-
}
|
|
133
|
-
const cliBin = path.join(bundlePath, mapping.cli);
|
|
134
|
-
if (!fs.existsSync(cliBin)) {
|
|
135
|
-
throw new Error(`에디터 CLI를 찾을 수 없습니다: ${cliBin}`);
|
|
136
|
-
}
|
|
137
|
-
return {
|
|
138
|
-
bin: cliBin,
|
|
139
|
-
args: wait ? [
|
|
140
|
-
mapping.waitFlag
|
|
141
|
-
] : []
|
|
142
|
-
};
|
|
93
|
+
/** 파일을 외부 에디터로 직접 편집 */
|
|
94
|
+
async function editContent(filePath) {
|
|
95
|
+
assertInsideContractDir(filePath);
|
|
96
|
+
const contractDir = getContractDir();
|
|
97
|
+
const absPath = path.resolve(contractDir, filePath);
|
|
98
|
+
if (!fs.existsSync(absPath)) {
|
|
99
|
+
throw new Error(`파일을 찾을 수 없습니다: ${filePath}`);
|
|
100
|
+
}
|
|
101
|
+
const editor = resolveEditorCli();
|
|
102
|
+
await runEditor(editor, absPath);
|
|
103
|
+
return {
|
|
104
|
+
success: true,
|
|
105
|
+
filePath
|
|
106
|
+
};
|
|
143
107
|
}
|
|
144
|
-
/**
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
108
|
+
/** 앱 번들 CLI 경로를 resolve. wait=false이면 --wait 플래그를 생략 */
|
|
109
|
+
function resolveEditorCli(options) {
|
|
110
|
+
const wait = options?.wait ?? true;
|
|
111
|
+
const appName = Sonamu.config.externalEditor ?? "Visual Studio Code";
|
|
112
|
+
const mapping = EDITOR_CLI_MAP[appName];
|
|
113
|
+
if (!mapping) {
|
|
114
|
+
throw new Error(`지원되지 않는 에디터입니다: ${appName} (지원: ${Object.keys(EDITOR_CLI_MAP).join(", ")})`);
|
|
115
|
+
}
|
|
116
|
+
const searchPaths = [`/Applications/${appName}.app`, `${os.homedir()}/Applications/${appName}.app`];
|
|
117
|
+
const bundlePath = searchPaths.find((p) => fs.existsSync(p));
|
|
118
|
+
if (!bundlePath) {
|
|
119
|
+
throw new Error(`앱 번들을 찾을 수 없습니다: ${appName} (/Applications 확인)`);
|
|
120
|
+
}
|
|
121
|
+
const cliBin = path.join(bundlePath, mapping.cli);
|
|
122
|
+
if (!fs.existsSync(cliBin)) {
|
|
123
|
+
throw new Error(`에디터 CLI를 찾을 수 없습니다: ${cliBin}`);
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
bin: cliBin,
|
|
127
|
+
args: wait ? [mapping.waitFlag] : []
|
|
128
|
+
};
|
|
163
129
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
130
|
+
/** 에디터 CLI를 실행하고 탭이 닫힐 때까지 대기 */
|
|
131
|
+
function runEditor(editor, filePath) {
|
|
132
|
+
return new Promise((resolve, reject) => {
|
|
133
|
+
const child = spawn(editor.bin, [...editor.args, filePath], { stdio: "inherit" });
|
|
134
|
+
child.on("error", (err) => {
|
|
135
|
+
reject(new Error(`에디터 실행 실패 (${editor.bin}): ${err.message}`));
|
|
136
|
+
});
|
|
137
|
+
child.on("close", (code) => {
|
|
138
|
+
if (code === 0) {
|
|
139
|
+
resolve();
|
|
140
|
+
} else {
|
|
141
|
+
reject(new Error(`에디터가 비정상 종료되었습니다 (exit code: ${code})`));
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
});
|
|
176
145
|
}
|
|
177
|
-
/**
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const fileType = detectFileType(entry.name);
|
|
190
|
-
if (!fileType) continue;
|
|
191
|
-
try {
|
|
192
|
-
const raw = fs.readFileSync(fullPath, "utf-8");
|
|
193
|
-
const doc = JSON.parse(raw);
|
|
194
|
-
if (doc.schema === schemaId) {
|
|
195
|
-
refs.push({
|
|
196
|
-
path: path.relative(relativeTo, fullPath),
|
|
197
|
-
fileType,
|
|
198
|
-
name: entry.name
|
|
199
|
-
});
|
|
200
|
-
}
|
|
201
|
-
} catch {
|
|
202
|
-
// JSON 파싱 실패 시 무시
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
return refs;
|
|
146
|
+
/** 소스 파일을 외부 에디터로 열기 (대기하지 않음) */
|
|
147
|
+
function openSourceFile(filePath) {
|
|
148
|
+
const absPath = path.isAbsolute(filePath) ? filePath : path.resolve(Sonamu.apiRootPath, filePath);
|
|
149
|
+
if (!fs.existsSync(absPath)) {
|
|
150
|
+
throw new Error(`파일을 찾을 수 없습니다: ${filePath}`);
|
|
151
|
+
}
|
|
152
|
+
const editor = resolveEditorCli({ wait: false });
|
|
153
|
+
const child = spawn(editor.bin, [...editor.args, absPath], {
|
|
154
|
+
stdio: "ignore",
|
|
155
|
+
detached: true
|
|
156
|
+
});
|
|
157
|
+
child.unref();
|
|
207
158
|
}
|
|
208
|
-
/**
|
|
209
|
-
|
|
159
|
+
/** contract/rules/ 디렉터리 내 .rules.json 파일 목록 반환 */
|
|
160
|
+
function listRules() {
|
|
161
|
+
const contractDir = getContractDir();
|
|
162
|
+
const rulesDir = path.join(contractDir, "rules");
|
|
163
|
+
if (!fs.existsSync(rulesDir)) return { rules: [] };
|
|
164
|
+
const entries = fs.readdirSync(rulesDir, { withFileTypes: true });
|
|
165
|
+
const rules = [];
|
|
166
|
+
for (const entry of entries) {
|
|
167
|
+
if (!entry.isFile() || !entry.name.endsWith(".rules.json")) continue;
|
|
168
|
+
const key = entry.name.replace(/\.rules\.json$/, "");
|
|
169
|
+
const relPath = `rules/${entry.name}`;
|
|
170
|
+
const absPath = path.join(rulesDir, entry.name);
|
|
171
|
+
try {
|
|
172
|
+
const raw = fs.readFileSync(absPath, "utf-8");
|
|
173
|
+
const doc = JSON.parse(raw);
|
|
174
|
+
rules.push({
|
|
175
|
+
key,
|
|
176
|
+
path: relPath,
|
|
177
|
+
description: typeof doc.description === "string" ? doc.description : "",
|
|
178
|
+
ruleCount: Array.isArray(doc.rules) ? doc.rules.length : 0
|
|
179
|
+
});
|
|
180
|
+
} catch (err) {
|
|
181
|
+
rules.push({
|
|
182
|
+
key,
|
|
183
|
+
path: relPath,
|
|
184
|
+
description: "",
|
|
185
|
+
ruleCount: 0,
|
|
186
|
+
parseError: err instanceof Error ? err.message : String(err)
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return { rules };
|
|
210
191
|
}
|
|
211
|
-
/**
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
192
|
+
/** rules 파일 상세 반환 */
|
|
193
|
+
function readRule(ruleKey) {
|
|
194
|
+
const contractDir = getContractDir();
|
|
195
|
+
const absPath = path.join(contractDir, "rules", `${ruleKey}.rules.json`);
|
|
196
|
+
if (!fs.existsSync(absPath)) {
|
|
197
|
+
throw new Error(`Rules 파일을 찾을 수 없습니다: ${ruleKey}`);
|
|
198
|
+
}
|
|
199
|
+
const raw = fs.readFileSync(absPath, "utf-8");
|
|
200
|
+
const doc = JSON.parse(raw);
|
|
201
|
+
return {
|
|
202
|
+
key: ruleKey,
|
|
203
|
+
path: `rules/${ruleKey}.rules.json`,
|
|
204
|
+
description: typeof doc.description === "string" ? doc.description : "",
|
|
205
|
+
rules: Array.isArray(doc.rules) ? doc.rules : []
|
|
206
|
+
};
|
|
217
207
|
}
|
|
218
|
-
/**
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
return {
|
|
251
|
-
schemas
|
|
252
|
-
};
|
|
208
|
+
/** rules 파일에 규칙 추가 */
|
|
209
|
+
function addRule(req) {
|
|
210
|
+
const contractDir = getContractDir();
|
|
211
|
+
const rulesDir = path.join(contractDir, "rules");
|
|
212
|
+
const absPath = path.join(rulesDir, `${req.ruleKey}.rules.json`);
|
|
213
|
+
if (!fs.existsSync(absPath)) {
|
|
214
|
+
throw new Error(`Rules 파일을 찾을 수 없습니다: ${req.ruleKey}`);
|
|
215
|
+
}
|
|
216
|
+
const raw = fs.readFileSync(absPath, "utf-8");
|
|
217
|
+
const doc = JSON.parse(raw);
|
|
218
|
+
const rules = Array.isArray(doc.rules) ? doc.rules : [];
|
|
219
|
+
const nextId = generateNextRuleId(rules);
|
|
220
|
+
const newEntry = {
|
|
221
|
+
id: nextId,
|
|
222
|
+
when: req.when,
|
|
223
|
+
instruction: req.instruction
|
|
224
|
+
};
|
|
225
|
+
if (req.examples && req.examples.length > 0) {
|
|
226
|
+
newEntry.examples = req.examples;
|
|
227
|
+
}
|
|
228
|
+
rules.push(newEntry);
|
|
229
|
+
doc.rules = rules;
|
|
230
|
+
fs.writeFileSync(absPath, `${JSON.stringify(doc, null, 2)}\n`, "utf-8");
|
|
231
|
+
return {
|
|
232
|
+
key: req.ruleKey,
|
|
233
|
+
path: `rules/${req.ruleKey}.rules.json`,
|
|
234
|
+
description: typeof doc.description === "string" ? doc.description : "",
|
|
235
|
+
rules
|
|
236
|
+
};
|
|
253
237
|
}
|
|
254
|
-
/**
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
238
|
+
/** 기존 id 패턴을 분석하여 다음 순번 id 생성 */
|
|
239
|
+
function generateNextRuleId(rules) {
|
|
240
|
+
if (rules.length === 0) return "R-001";
|
|
241
|
+
const numericPattern = /^(.+?)(\d+)$/;
|
|
242
|
+
let bestPrefix = "R-";
|
|
243
|
+
let maxNum = 0;
|
|
244
|
+
for (const rule of rules) {
|
|
245
|
+
const match = numericPattern.exec(rule.id);
|
|
246
|
+
if (match) {
|
|
247
|
+
const prefix = match[1];
|
|
248
|
+
const num = Number.parseInt(match[2], 10);
|
|
249
|
+
if (num > maxNum) {
|
|
250
|
+
bestPrefix = prefix;
|
|
251
|
+
maxNum = num;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const nextNum = maxNum + 1;
|
|
256
|
+
const padLen = Math.max(3, String(maxNum).length);
|
|
257
|
+
return `${bestPrefix}${String(nextNum).padStart(padLen, "0")}`;
|
|
272
258
|
}
|
|
273
|
-
/**
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
259
|
+
/** describe/test 패턴 파싱 */
|
|
260
|
+
function parseAcEntries(content) {
|
|
261
|
+
const entries = [];
|
|
262
|
+
const lines = content.split("\n");
|
|
263
|
+
let currentDescribe = null;
|
|
264
|
+
let describeDepth = 0;
|
|
265
|
+
let braceDepth = 0;
|
|
266
|
+
let pendingTestAs = false;
|
|
267
|
+
let testAsBraceDepth = 0;
|
|
268
|
+
let testAsNeedName = false;
|
|
269
|
+
for (const line of lines) {
|
|
270
|
+
const trimmed = line.trim();
|
|
271
|
+
const describeMatch = trimmed.match(/^describe\(["'`](.+?)["'`]/);
|
|
272
|
+
if (describeMatch) {
|
|
273
|
+
currentDescribe = describeMatch[1];
|
|
274
|
+
describeDepth = braceDepth;
|
|
275
|
+
}
|
|
276
|
+
const testMatch = trimmed.match(/^(?:test|it)\(["'`](.+?)["'`]/);
|
|
277
|
+
if (testMatch) {
|
|
278
|
+
entries.push({
|
|
279
|
+
describe: currentDescribe,
|
|
280
|
+
test: testMatch[1]
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
if (!pendingTestAs && trimmed.match(/^testAs\s*\(/)) {
|
|
284
|
+
const inlineMatch = trimmed.match(/^testAs\s*\(\s*\{[^}]*\}\s*,\s*["'`](.+?)["'`]/);
|
|
285
|
+
if (inlineMatch) {
|
|
286
|
+
entries.push({
|
|
287
|
+
describe: currentDescribe,
|
|
288
|
+
test: inlineMatch[1]
|
|
289
|
+
});
|
|
290
|
+
} else {
|
|
291
|
+
pendingTestAs = true;
|
|
292
|
+
testAsBraceDepth = 0;
|
|
293
|
+
testAsNeedName = false;
|
|
294
|
+
for (const ch of trimmed) {
|
|
295
|
+
if (ch === "{") testAsBraceDepth++;
|
|
296
|
+
if (ch === "}") testAsBraceDepth--;
|
|
297
|
+
}
|
|
298
|
+
if (testAsBraceDepth <= 0) {
|
|
299
|
+
testAsNeedName = true;
|
|
300
|
+
const nameMatch = trimmed.match(/}\s*,\s*["'`](.+?)["'`]/);
|
|
301
|
+
if (nameMatch) {
|
|
302
|
+
entries.push({
|
|
303
|
+
describe: currentDescribe,
|
|
304
|
+
test: nameMatch[1]
|
|
305
|
+
});
|
|
306
|
+
pendingTestAs = false;
|
|
307
|
+
testAsNeedName = false;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
} else if (pendingTestAs) {
|
|
312
|
+
if (!testAsNeedName) {
|
|
313
|
+
for (const ch of trimmed) {
|
|
314
|
+
if (ch === "{") testAsBraceDepth++;
|
|
315
|
+
if (ch === "}") testAsBraceDepth--;
|
|
316
|
+
}
|
|
317
|
+
if (testAsBraceDepth <= 0) {
|
|
318
|
+
testAsNeedName = true;
|
|
319
|
+
const nameMatch = trimmed.match(/}\s*,\s*["'`](.+?)["'`]/);
|
|
320
|
+
if (nameMatch) {
|
|
321
|
+
entries.push({
|
|
322
|
+
describe: currentDescribe,
|
|
323
|
+
test: nameMatch[1]
|
|
324
|
+
});
|
|
325
|
+
pendingTestAs = false;
|
|
326
|
+
testAsNeedName = false;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
} else {
|
|
330
|
+
const nameMatch = trimmed.match(/^["'`](.+?)["'`]/);
|
|
331
|
+
if (nameMatch) {
|
|
332
|
+
entries.push({
|
|
333
|
+
describe: currentDescribe,
|
|
334
|
+
test: nameMatch[1]
|
|
335
|
+
});
|
|
336
|
+
pendingTestAs = false;
|
|
337
|
+
testAsNeedName = false;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
for (const ch of trimmed) {
|
|
342
|
+
if (ch === "{") braceDepth++;
|
|
343
|
+
if (ch === "}") {
|
|
344
|
+
braceDepth--;
|
|
345
|
+
if (currentDescribe && braceDepth <= describeDepth) {
|
|
346
|
+
currentDescribe = null;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return entries;
|
|
286
352
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
done: 0
|
|
308
|
-
}
|
|
309
|
-
},
|
|
310
|
-
documents: []
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
const documents = [];
|
|
314
|
-
const statusDistribution = {
|
|
315
|
-
draft: 0,
|
|
316
|
-
specifying: 0,
|
|
317
|
-
implementing: 0,
|
|
318
|
-
validating: 0,
|
|
319
|
-
done: 0
|
|
320
|
-
};
|
|
321
|
-
function scanForDashboard(dirPath) {
|
|
322
|
-
const entries = fs.readdirSync(dirPath, {
|
|
323
|
-
withFileTypes: true
|
|
324
|
-
});
|
|
325
|
-
for (const entry of entries){
|
|
326
|
-
const fullPath = path.join(dirPath, entry.name);
|
|
327
|
-
if (entry.isDirectory()) {
|
|
328
|
-
if (entry.name === "schemas") continue;
|
|
329
|
-
scanForDashboard(fullPath);
|
|
330
|
-
} else if (entry.isFile()) {
|
|
331
|
-
const fileType = detectFileType(entry.name);
|
|
332
|
-
if (!fileType) continue;
|
|
333
|
-
const relPath = path.relative(contractDir, fullPath);
|
|
334
|
-
try {
|
|
335
|
-
const raw = fs.readFileSync(fullPath, "utf-8");
|
|
336
|
-
const doc = JSON.parse(raw);
|
|
337
|
-
const summary = {
|
|
338
|
-
path: relPath,
|
|
339
|
-
name: entry.name,
|
|
340
|
-
fileType,
|
|
341
|
-
schemaId: typeof doc.schema === "string" ? doc.schema : undefined,
|
|
342
|
-
lastModified: typeof doc.lastModified === "string" ? doc.lastModified : undefined
|
|
343
|
-
};
|
|
344
|
-
if (fileType === "contract") {
|
|
345
|
-
const features = doc.features;
|
|
346
|
-
if (features && typeof features === "object" && !Array.isArray(features)) {
|
|
347
|
-
summary.featureCount = Object.keys(features).length;
|
|
348
|
-
}
|
|
349
|
-
} else {
|
|
350
|
-
const status = typeof doc.status === "string" ? doc.status : "draft";
|
|
351
|
-
summary.status = VALID_SPEC_STATUSES.has(status) ? status : "draft";
|
|
352
|
-
statusDistribution[summary.status]++;
|
|
353
|
-
if (Array.isArray(doc.acceptanceCriteria)) {
|
|
354
|
-
summary.acceptanceCriteriaCount = doc.acceptanceCriteria.length;
|
|
355
|
-
}
|
|
356
|
-
if (Array.isArray(doc.sources)) {
|
|
357
|
-
summary.sourceCount = doc.sources.length;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
documents.push(summary);
|
|
361
|
-
} catch (err) {
|
|
362
|
-
documents.push({
|
|
363
|
-
path: relPath,
|
|
364
|
-
name: entry.name,
|
|
365
|
-
fileType,
|
|
366
|
-
parseError: err instanceof Error ? err.message : String(err)
|
|
367
|
-
});
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
scanForDashboard(contractDir);
|
|
373
|
-
const totalContracts = documents.filter((d)=>d.fileType === "contract" && !d.parseError).length;
|
|
374
|
-
const totalSpecs = documents.filter((d)=>d.fileType === "spec" && !d.parseError).length;
|
|
375
|
-
return {
|
|
376
|
-
exists: true,
|
|
377
|
-
stats: {
|
|
378
|
-
totalContracts,
|
|
379
|
-
totalSpecs,
|
|
380
|
-
statusDistribution
|
|
381
|
-
},
|
|
382
|
-
documents
|
|
383
|
-
};
|
|
353
|
+
/** 프로젝트 내 *.test.ts 파일을 스캔하여 AC 목록 반환 */
|
|
354
|
+
function getAcList() {
|
|
355
|
+
const projectRoot = getProjectRoot();
|
|
356
|
+
const files = findTestFiles(projectRoot);
|
|
357
|
+
const acFiles = [];
|
|
358
|
+
for (const absPath of files) {
|
|
359
|
+
const content = fs.readFileSync(absPath, "utf-8");
|
|
360
|
+
const entries = parseAcEntries(content);
|
|
361
|
+
if (entries.length > 0) {
|
|
362
|
+
acFiles.push({
|
|
363
|
+
path: path.relative(projectRoot, absPath),
|
|
364
|
+
entries
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
const total = acFiles.reduce((sum, f) => sum + f.entries.length, 0);
|
|
369
|
+
return {
|
|
370
|
+
files: acFiles,
|
|
371
|
+
total
|
|
372
|
+
};
|
|
384
373
|
}
|
|
385
|
-
/**
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
374
|
+
/** *.test.ts 파일을 재귀 탐색 (node_modules, dist 제외) */
|
|
375
|
+
function findTestFiles(dir) {
|
|
376
|
+
const results = [];
|
|
377
|
+
const IGNORE = new Set([
|
|
378
|
+
"node_modules",
|
|
379
|
+
"dist",
|
|
380
|
+
".git",
|
|
381
|
+
"contract"
|
|
382
|
+
]);
|
|
383
|
+
function walk(currentDir) {
|
|
384
|
+
let entries;
|
|
385
|
+
try {
|
|
386
|
+
entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
387
|
+
} catch {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
for (const entry of entries) {
|
|
391
|
+
if (IGNORE.has(entry.name)) continue;
|
|
392
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
393
|
+
if (entry.isDirectory()) {
|
|
394
|
+
walk(fullPath);
|
|
395
|
+
} else if (entry.isFile() && entry.name.endsWith(".test.ts")) {
|
|
396
|
+
results.push(fullPath);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
walk(dir);
|
|
401
|
+
results.sort();
|
|
402
|
+
return results;
|
|
401
403
|
}
|
|
404
|
+
var EDITOR_CLI_MAP;
|
|
405
|
+
var init_cdd_service = __esmMin((() => {
|
|
406
|
+
init_sonamu();
|
|
407
|
+
EDITOR_CLI_MAP = {
|
|
408
|
+
"Visual Studio Code": {
|
|
409
|
+
cli: "Contents/Resources/app/bin/code",
|
|
410
|
+
waitFlag: "--wait"
|
|
411
|
+
},
|
|
412
|
+
Zed: {
|
|
413
|
+
cli: "Contents/MacOS/cli",
|
|
414
|
+
waitFlag: "--wait"
|
|
415
|
+
},
|
|
416
|
+
Cursor: {
|
|
417
|
+
cli: "Contents/Resources/app/bin/cursor",
|
|
418
|
+
waitFlag: "--wait"
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
}));
|
|
402
422
|
|
|
403
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91aS9jZGQtc2VydmljZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBzcGF3biB9IGZyb20gXCJjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgb3MgZnJvbSBcIm9zXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IHsgU29uYW11IH0gZnJvbSBcIi4uL2FwaS9zb25hbXVcIjtcbmltcG9ydCB0eXBlIHtcbiAgQ2RkQ29udGVudEVudmVsb3BlLFxuICBDZGREYXNoYm9hcmREYXRhLFxuICBDZGREb2N1bWVudFN1bW1hcnksXG4gIENkZEZpbGVUeXBlLFxuICBDZGRTY2hlbWEsXG4gIENkZFNjaGVtYURldGFpbEVudmVsb3BlLFxuICBDZGRTY2hlbWFSZWZlcmVuY2UsXG4gIENkZFNjaGVtYVN1bW1hcnksXG4gIENkZFNwZWNTdGF0dXMsXG4gIENkZFRyZWVOb2RlLFxufSBmcm9tIFwiLi9jZGQtdHlwZXNcIjtcblxuZXhwb3J0IHR5cGUge1xuICBDZGRDb250ZW50RW52ZWxvcGUsXG4gIENkZERhc2hib2FyZERhdGEsXG4gIENkZERvY3VtZW50U3VtbWFyeSxcbiAgQ2RkRmlsZVR5cGUsXG4gIENkZFNjaGVtYSxcbiAgQ2RkU2NoZW1hRGV0YWlsRW52ZWxvcGUsXG4gIENkZFNjaGVtYUZpZWxkLFxuICBDZGRTY2hlbWFGaWVsZFR5cGUsXG4gIENkZFNjaGVtYVJlZmVyZW5jZSxcbiAgQ2RkU2NoZW1hU3VtbWFyeSxcbiAgQ2RkU3BlY1N0YXR1cyxcbiAgQ2RkVHJlZU5vZGUsXG59IGZyb20gXCIuL2NkZC10eXBlc1wiO1xuXG4vKiogY29udHJhY3QvIOuUlOugie2EsOumrCDsoIjrjIAg6rK966GcIOuwmO2ZmCAoYXBpUm9vdFBhdGgg6riw7KSAKSAqL1xuZnVuY3Rpb24gZ2V0Q29udHJhY3REaXIoKTogc3RyaW5nIHtcbiAgcmV0dXJuIHBhdGguam9pbihTb25hbXUuYXBpUm9vdFBhdGgsIFwiLi5cIiwgXCIuLlwiLCBcImNvbnRyYWN0XCIpO1xufVxuXG4vKiog6rK966Gc6rCAIGNvbnRyYWN0LyDrlJTroInthLDrpqwg64K067aA7J247KeAIOqygOymnSAqL1xuZnVuY3Rpb24gYXNzZXJ0SW5zaWRlQ29udHJhY3REaXIoZmlsZVBhdGg6IHN0cmluZyk6IHZvaWQge1xuICBjb25zdCBjb250cmFjdERpciA9IGdldENvbnRyYWN0RGlyKCk7XG4gIGNvbnN0IHJlc29sdmVkID0gcGF0aC5yZXNvbHZlKGNvbnRyYWN0RGlyLCBmaWxlUGF0aCk7XG4gIGlmICghcmVzb2x2ZWQuc3RhcnRzV2l0aChjb250cmFjdERpciArIHBhdGguc2VwKSAmJiByZXNvbHZlZCAhPT0gY29udHJhY3REaXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYOqyveuhnOqwgCBjb250cmFjdC8g65SU66CJ7YSw66asIOuwluydhCDssLjsobDtlanri4jri6Q6ICR7ZmlsZVBhdGh9YCk7XG4gIH1cbn1cblxuLyoqIO2MjOydvOuqheyXkOyEnCBDZGRGaWxlVHlwZSDtjJDrs4QgKi9cbmZ1bmN0aW9uIGRldGVjdEZpbGVUeXBlKGZpbGVOYW1lOiBzdHJpbmcpOiBDZGRGaWxlVHlwZSB8IHVuZGVmaW5lZCB7XG4gIGlmIChmaWxlTmFtZS5lbmRzV2l0aChcIi5jb250cmFjdC5qc29uXCIpKSByZXR1cm4gXCJjb250cmFjdFwiO1xuICBpZiAoZmlsZU5hbWUuZW5kc1dpdGgoXCIuc3BlYy5qc29uXCIpKSByZXR1cm4gXCJzcGVjXCI7XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKiDrlJTroInthLDrpqzrpbwg7J6s6reAIO2DkOyDie2VmOyXrCBDZGRUcmVlTm9kZSDtirjrpqzrpbwg7IOd7ISxICovXG5mdW5jdGlvbiBzY2FuRGlyZWN0b3J5KGRpclBhdGg6IHN0cmluZywgcmVsYXRpdmVUbzogc3RyaW5nKTogQ2RkVHJlZU5vZGVbXSB7XG4gIGNvbnN0IGVudHJpZXMgPSBmcy5yZWFkZGlyU3luYyhkaXJQYXRoLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XG4gIGNvbnN0IG5vZGVzOiBDZGRUcmVlTm9kZVtdID0gW107XG5cbiAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgY29uc3QgZnVsbFBhdGggPSBwYXRoLmpvaW4oZGlyUGF0aCwgZW50cnkubmFtZSk7XG4gICAgY29uc3QgcmVsUGF0aCA9IHBhdGgucmVsYXRpdmUocmVsYXRpdmVUbywgZnVsbFBhdGgpO1xuXG4gICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gc2NhbkRpcmVjdG9yeShmdWxsUGF0aCwgcmVsYXRpdmVUbyk7XG4gICAgICBub2Rlcy5wdXNoKHtcbiAgICAgICAgbmFtZTogZW50cnkubmFtZSxcbiAgICAgICAgcGF0aDogcmVsUGF0aCxcbiAgICAgICAgdHlwZTogXCJkaXJlY3RvcnlcIixcbiAgICAgICAgY2hpbGRyZW4sXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGVudHJ5LmlzRmlsZSgpKSB7XG4gICAgICBjb25zdCBmaWxlVHlwZSA9IGRldGVjdEZpbGVUeXBlKGVudHJ5Lm5hbWUpO1xuICAgICAgaWYgKGZpbGVUeXBlKSB7XG4gICAgICAgIG5vZGVzLnB1c2goe1xuICAgICAgICAgIG5hbWU6IGVudHJ5Lm5hbWUsXG4gICAgICAgICAgcGF0aDogcmVsUGF0aCxcbiAgICAgICAgICB0eXBlOiBcImZpbGVcIixcbiAgICAgICAgICBmaWxlVHlwZSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5vZGVzO1xufVxuXG4vKiogY29udHJhY3QvIOuUlOugie2EsOumrOydmCDtirjrpqwg6rWs7KGw66W8IOuwmO2ZmCAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldENkZFRyZWUoKTogeyBleGlzdHM6IGJvb2xlYW47IHRyZWU6IENkZFRyZWVOb2RlW10gfSB7XG4gIGNvbnN0IGNvbnRyYWN0RGlyID0gZ2V0Q29udHJhY3REaXIoKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGNvbnRyYWN0RGlyKSkge1xuICAgIHJldHVybiB7IGV4aXN0czogZmFsc2UsIHRyZWU6IFtdIH07XG4gIH1cbiAgY29uc3QgdHJlZSA9IHNjYW5EaXJlY3RvcnkoY29udHJhY3REaXIsIGNvbnRyYWN0RGlyKTtcbiAgcmV0dXJuIHsgZXhpc3RzOiB0cnVlLCB0cmVlIH07XG59XG5cbi8qKiBzY2hlbWEgSUTroZwgc2NoZW1hIO2MjOydvOydhCDssL7slYQg67CY7ZmYICovXG5mdW5jdGlvbiByZXNvbHZlU2NoZW1hKHNjaGVtYUlkOiBzdHJpbmcpOiBDZGRTY2hlbWEgfCBudWxsIHtcbiAgY29uc3QgY29udHJhY3REaXIgPSBnZXRDb250cmFjdERpcigpO1xuICBjb25zdCBzY2hlbWFQYXRoID0gcGF0aC5qb2luKGNvbnRyYWN0RGlyLCBcInNjaGVtYXNcIiwgYCR7c2NoZW1hSWR9LnNjaGVtYS5qc29uYCk7XG4gIGlmICghZnMuZXhpc3RzU3luYyhzY2hlbWFQYXRoKSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHJhdyA9IGZzLnJlYWRGaWxlU3luYyhzY2hlbWFQYXRoLCBcInV0Zi04XCIpO1xuICByZXR1cm4gSlNPTi5wYXJzZShyYXcpIGFzIENkZFNjaGVtYTtcbn1cblxuLyoqIEpTT04g7YyM7J287J2YIOyghOyytCDrgrTsmqnsnYQg7J297Ja0IHNjaGVtYeyZgCDtlajqu5ggZW52ZWxvcGXroZwg67CY7ZmYICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZENvbnRlbnQoZmlsZVBhdGg6IHN0cmluZyk6IENkZENvbnRlbnRFbnZlbG9wZSB7XG4gIGFzc2VydEluc2lkZUNvbnRyYWN0RGlyKGZpbGVQYXRoKTtcblxuICBjb25zdCBjb250cmFjdERpciA9IGdldENvbnRyYWN0RGlyKCk7XG4gIGNvbnN0IGFic1BhdGggPSBwYXRoLnJlc29sdmUoY29udHJhY3REaXIsIGZpbGVQYXRoKTtcblxuICBpZiAoIWZzLmV4aXN0c1N5bmMoYWJzUGF0aCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYO2MjOydvOydhCDssL7snYQg7IiYIOyXhuyKteuLiOuLpDogJHtmaWxlUGF0aH1gKTtcbiAgfVxuXG4gIGNvbnN0IHJhdyA9IGZzLnJlYWRGaWxlU3luYyhhYnNQYXRoLCBcInV0Zi04XCIpO1xuICBjb25zdCBkb2N1bWVudCA9IEpTT04ucGFyc2UocmF3KSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgY29uc3QgZmlsZVR5cGUgPSBkZXRlY3RGaWxlVHlwZShwYXRoLmJhc2VuYW1lKGZpbGVQYXRoKSk7XG4gIGNvbnN0IHNjaGVtYUlkID0gdHlwZW9mIGRvY3VtZW50LnNjaGVtYSA9PT0gXCJzdHJpbmdcIiA/IGRvY3VtZW50LnNjaGVtYSA6IG51bGw7XG4gIGNvbnN0IHNjaGVtYSA9IHNjaGVtYUlkID8gcmVzb2x2ZVNjaGVtYShzY2hlbWFJZCkgOiBudWxsO1xuXG4gIHJldHVybiB7XG4gICAgZG9jdW1lbnQsXG4gICAgc2NoZW1hLFxuICAgIGZpbGVUeXBlOiBmaWxlVHlwZSA/PyBcImNvbnRyYWN0XCIsXG4gIH07XG59XG5cbi8qKiBKU09OIO2MjOydvOydhCDsmbjrtoAg7JeQ65SU7YSw66GcIOyngeygkSDtjrjsp5EgKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBlZGl0Q29udGVudChcbiAgZmlsZVBhdGg6IHN0cmluZyxcbik6IFByb21pc2U8eyBzdWNjZXNzOiBib29sZWFuOyBmaWxlUGF0aDogc3RyaW5nIH0+IHtcbiAgYXNzZXJ0SW5zaWRlQ29udHJhY3REaXIoZmlsZVBhdGgpO1xuXG4gIGNvbnN0IGNvbnRyYWN0RGlyID0gZ2V0Q29udHJhY3REaXIoKTtcbiAgY29uc3QgYWJzUGF0aCA9IHBhdGgucmVzb2x2ZShjb250cmFjdERpciwgZmlsZVBhdGgpO1xuXG4gIGlmICghZnMuZXhpc3RzU3luYyhhYnNQYXRoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihg7YyM7J287J2EIOywvuydhCDsiJgg7JeG7Iq164uI64ukOiAke2ZpbGVQYXRofWApO1xuICB9XG5cbiAgY29uc3QgZWRpdG9yID0gcmVzb2x2ZUVkaXRvckNsaSgpO1xuICBhd2FpdCBydW5FZGl0b3IoZWRpdG9yLCBhYnNQYXRoKTtcblxuICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCBmaWxlUGF0aCB9O1xufVxuXG4vKiog7JeQ65SU7YSw67OEIOyVsSDrsojrk6Qg64K0IENMSSDqsr3roZwgKyAtLXdhaXQg7ZSM656Y6re4IOunpO2VkSAqL1xuY29uc3QgRURJVE9SX0NMSV9NQVA6IFJlY29yZDxzdHJpbmcsIHsgY2xpOiBzdHJpbmc7IHdhaXRGbGFnOiBzdHJpbmcgfT4gPSB7XG4gIFwiVmlzdWFsIFN0dWRpbyBDb2RlXCI6IHsgY2xpOiBcIkNvbnRlbnRzL1Jlc291cmNlcy9hcHAvYmluL2NvZGVcIiwgd2FpdEZsYWc6IFwiLS13YWl0XCIgfSxcbiAgWmVkOiB7IGNsaTogXCJDb250ZW50cy9NYWNPUy9jbGlcIiwgd2FpdEZsYWc6IFwiLS13YWl0XCIgfSxcbiAgQ3Vyc29yOiB7IGNsaTogXCJDb250ZW50cy9SZXNvdXJjZXMvYXBwL2Jpbi9jdXJzb3JcIiwgd2FpdEZsYWc6IFwiLS13YWl0XCIgfSxcbn07XG5cbi8qKiDslbEg67KI65OkIENMSSDqsr3roZzrpbwgcmVzb2x2ZS4gd2FpdD1mYWxzZeydtOuptCAtLXdhaXQg7ZSM656Y6re466W8IOyDneuetSAqL1xuZnVuY3Rpb24gcmVzb2x2ZUVkaXRvckNsaShvcHRpb25zPzogeyB3YWl0PzogYm9vbGVhbiB9KTogeyBiaW46IHN0cmluZzsgYXJnczogc3RyaW5nW10gfSB7XG4gIGNvbnN0IHdhaXQgPSBvcHRpb25zPy53YWl0ID8/IHRydWU7XG4gIGNvbnN0IGFwcE5hbWUgPSBTb25hbXUuY29uZmlnLmV4dGVybmFsRWRpdG9yID8/IFwiVmlzdWFsIFN0dWRpbyBDb2RlXCI7XG4gIGNvbnN0IG1hcHBpbmcgPSBFRElUT1JfQ0xJX01BUFthcHBOYW1lXTtcbiAgaWYgKCFtYXBwaW5nKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYOyngOybkOuQmOyngCDslYrripQg7JeQ65SU7YSw7J6F64uI64ukOiAke2FwcE5hbWV9ICjsp4Dsm5A6ICR7T2JqZWN0LmtleXMoRURJVE9SX0NMSV9NQVApLmpvaW4oXCIsIFwiKX0pYCxcbiAgICApO1xuICB9XG5cbiAgY29uc3Qgc2VhcmNoUGF0aHMgPSBbXG4gICAgYC9BcHBsaWNhdGlvbnMvJHthcHBOYW1lfS5hcHBgLFxuICAgIGAke29zLmhvbWVkaXIoKX0vQXBwbGljYXRpb25zLyR7YXBwTmFtZX0uYXBwYCxcbiAgXTtcbiAgY29uc3QgYnVuZGxlUGF0aCA9IHNlYXJjaFBhdGhzLmZpbmQoKHApID0+IGZzLmV4aXN0c1N5bmMocCkpO1xuICBpZiAoIWJ1bmRsZVBhdGgpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYOyVsSDrsojrk6TsnYQg7LC+7J2EIOyImCDsl4bsirXri4jri6Q6ICR7YXBwTmFtZX0gKC9BcHBsaWNhdGlvbnMg7ZmV7J24KWApO1xuICB9XG5cbiAgY29uc3QgY2xpQmluID0gcGF0aC5qb2luKGJ1bmRsZVBhdGgsIG1hcHBpbmcuY2xpKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGNsaUJpbikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYOyXkOuUlO2EsCBDTEnrpbwg7LC+7J2EIOyImCDsl4bsirXri4jri6Q6ICR7Y2xpQmlufWApO1xuICB9XG5cbiAgcmV0dXJuIHsgYmluOiBjbGlCaW4sIGFyZ3M6IHdhaXQgPyBbbWFwcGluZy53YWl0RmxhZ10gOiBbXSB9O1xufVxuXG4vKiog7JeQ65SU7YSwIENMSeulvCDsi6TtlontlZjqs6Ag7YOt7J20IOuLq+2ekCDrlYzquYzsp4Ag64yA6riwICovXG5mdW5jdGlvbiBydW5FZGl0b3IoZWRpdG9yOiB7IGJpbjogc3RyaW5nOyBhcmdzOiBzdHJpbmdbXSB9LCBmaWxlUGF0aDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3QgY2hpbGQgPSBzcGF3bihlZGl0b3IuYmluLCBbLi4uZWRpdG9yLmFyZ3MsIGZpbGVQYXRoXSwge1xuICAgICAgc3RkaW86IFwiaW5oZXJpdFwiLFxuICAgIH0pO1xuXG4gICAgY2hpbGQub24oXCJlcnJvclwiLCAoZXJyKSA9PiB7XG4gICAgICByZWplY3QobmV3IEVycm9yKGDsl5DrlJTthLAg7Iuk7ZaJIOyLpO2MqCAoJHtlZGl0b3IuYmlufSk6ICR7ZXJyLm1lc3NhZ2V9YCkpO1xuICAgIH0pO1xuXG4gICAgY2hpbGQub24oXCJjbG9zZVwiLCAoY29kZSkgPT4ge1xuICAgICAgaWYgKGNvZGUgPT09IDApIHtcbiAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihg7JeQ65SU7YSw6rCAIOu5hOygleyDgSDsooXro4zrkJjsl4jsirXri4jri6QgKGV4aXQgY29kZTogJHtjb2RlfSlgKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNjaGVtYSDqtIDrpqwgQVBJXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuLyoqIGNvbnRyYWN0L3NjaGVtYXMvIOuUlOugie2EsOumrCDrgrQgLnNjaGVtYS5qc29uIO2MjOydvCDqsr3roZwg66qp66GdIOuwmO2ZmCAqL1xuZnVuY3Rpb24gc2NhblNjaGVtYUZpbGVzKCk6IHsgYWJzUGF0aDogc3RyaW5nOyByZWxQYXRoOiBzdHJpbmc7IGZpbGVOYW1lOiBzdHJpbmcgfVtdIHtcbiAgY29uc3Qgc2NoZW1hc0RpciA9IHBhdGguam9pbihnZXRDb250cmFjdERpcigpLCBcInNjaGVtYXNcIik7XG4gIGlmICghZnMuZXhpc3RzU3luYyhzY2hlbWFzRGlyKSkgcmV0dXJuIFtdO1xuXG4gIHJldHVybiBmc1xuICAgIC5yZWFkZGlyU3luYyhzY2hlbWFzRGlyLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSlcbiAgICAuZmlsdGVyKChlKSA9PiBlLmlzRmlsZSgpICYmIGUubmFtZS5lbmRzV2l0aChcIi5zY2hlbWEuanNvblwiKSlcbiAgICAubWFwKChlKSA9PiAoe1xuICAgICAgYWJzUGF0aDogcGF0aC5qb2luKHNjaGVtYXNEaXIsIGUubmFtZSksXG4gICAgICByZWxQYXRoOiBgc2NoZW1hcy8ke2UubmFtZX1gLFxuICAgICAgZmlsZU5hbWU6IGUubmFtZSxcbiAgICB9KSk7XG59XG5cbi8qKiDtirnsoJUgc2NoZW1hSWTrpbwg7LC47KGw7ZWY64qUIGNvbnRyYWN0L3NwZWMg66y47ISc65Ok7J2EIOyerOq3gCDsiJjsp5EgKi9cbmZ1bmN0aW9uIGNvbGxlY3RTY2hlbWFSZWZlcmVuY2VzKFxuICBzY2hlbWFJZDogc3RyaW5nLFxuICBkaXJQYXRoOiBzdHJpbmcsXG4gIHJlbGF0aXZlVG86IHN0cmluZyxcbik6IENkZFNjaGVtYVJlZmVyZW5jZVtdIHtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGRpclBhdGgpKSByZXR1cm4gW107XG4gIGNvbnN0IHJlZnM6IENkZFNjaGVtYVJlZmVyZW5jZVtdID0gW107XG4gIGNvbnN0IGVudHJpZXMgPSBmcy5yZWFkZGlyU3luYyhkaXJQYXRoLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XG5cbiAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgY29uc3QgZnVsbFBhdGggPSBwYXRoLmpvaW4oZGlyUGF0aCwgZW50cnkubmFtZSk7XG4gICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgIGlmIChlbnRyeS5uYW1lID09PSBcInNjaGVtYXNcIikgY29udGludWU7XG4gICAgICByZWZzLnB1c2goLi4uY29sbGVjdFNjaGVtYVJlZmVyZW5jZXMoc2NoZW1hSWQsIGZ1bGxQYXRoLCByZWxhdGl2ZVRvKSk7XG4gICAgfSBlbHNlIGlmIChlbnRyeS5pc0ZpbGUoKSkge1xuICAgICAgY29uc3QgZmlsZVR5cGUgPSBkZXRlY3RGaWxlVHlwZShlbnRyeS5uYW1lKTtcbiAgICAgIGlmICghZmlsZVR5cGUpIGNvbnRpbnVlO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmF3ID0gZnMucmVhZEZpbGVTeW5jKGZ1bGxQYXRoLCBcInV0Zi04XCIpO1xuICAgICAgICBjb25zdCBkb2MgPSBKU09OLnBhcnNlKHJhdykgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG4gICAgICAgIGlmIChkb2Muc2NoZW1hID09PSBzY2hlbWFJZCkge1xuICAgICAgICAgIHJlZnMucHVzaCh7XG4gICAgICAgICAgICBwYXRoOiBwYXRoLnJlbGF0aXZlKHJlbGF0aXZlVG8sIGZ1bGxQYXRoKSxcbiAgICAgICAgICAgIGZpbGVUeXBlLFxuICAgICAgICAgICAgbmFtZTogZW50cnkubmFtZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8vIEpTT04g7YyM7IuxIOyLpO2MqCDsi5wg66y07IucXG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiByZWZzO1xufVxuXG4vKiogc2NoZW1hIO2MjOydvOuqheyXkOyEnCDquLDrjIDrkJjripQgaWQg7LaU7LacICovXG5mdW5jdGlvbiBleHBlY3RlZFNjaGVtYUlkKGZpbGVOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gZmlsZU5hbWUucmVwbGFjZSgvXFwuc2NoZW1hXFwuanNvbiQvLCBcIlwiKTtcbn1cblxuLyoqIHNjaGVtYXMvIO2VmOychCDqsr3roZzqsIAgY29udHJhY3Qvc2NoZW1hcy8g64K067aA7J247KeAIOqygOymnSAqL1xuZnVuY3Rpb24gYXNzZXJ0SW5zaWRlU2NoZW1hRGlyKHNjaGVtYUtleTogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IHNjaGVtYXNEaXIgPSBwYXRoLmpvaW4oZ2V0Q29udHJhY3REaXIoKSwgXCJzY2hlbWFzXCIpO1xuICBjb25zdCByZXNvbHZlZCA9IHBhdGgucmVzb2x2ZShzY2hlbWFzRGlyLCBgJHtzY2hlbWFLZXl9LnNjaGVtYS5qc29uYCk7XG4gIGlmICghcmVzb2x2ZWQuc3RhcnRzV2l0aChzY2hlbWFzRGlyICsgcGF0aC5zZXApICYmIHJlc29sdmVkICE9PSBzY2hlbWFzRGlyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGDsnKDtmqjtlZjsp4Ag7JWK7J2AIOyKpO2CpOuniCDtgqTsnoXri4jri6Q6ICR7c2NoZW1hS2V5fWApO1xuICB9XG59XG5cbi8qKiBzY2hlbWEg66qp66GdIOuwmO2ZmCAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3RTY2hlbWFzKCk6IHsgc2NoZW1hczogQ2RkU2NoZW1hU3VtbWFyeVtdIH0ge1xuICBjb25zdCBjb250cmFjdERpciA9IGdldENvbnRyYWN0RGlyKCk7XG4gIGNvbnN0IGZpbGVzID0gc2NhblNjaGVtYUZpbGVzKCk7XG4gIGNvbnN0IHNjaGVtYXM6IENkZFNjaGVtYVN1bW1hcnlbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykge1xuICAgIGNvbnN0IGtleSA9IGV4cGVjdGVkU2NoZW1hSWQoZmlsZS5maWxlTmFtZSk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJhdyA9IGZzLnJlYWRGaWxlU3luYyhmaWxlLmFic1BhdGgsIFwidXRmLThcIik7XG4gICAgICBjb25zdCBzY2hlbWEgPSBKU09OLnBhcnNlKHJhdykgYXMgQ2RkU2NoZW1hO1xuICAgICAgY29uc3QgcmVmcyA9IGNvbGxlY3RTY2hlbWFSZWZlcmVuY2VzKHNjaGVtYS5pZCwgY29udHJhY3REaXIsIGNvbnRyYWN0RGlyKTtcbiAgICAgIHNjaGVtYXMucHVzaCh7XG4gICAgICAgIGtleSxcbiAgICAgICAgaWQ6IHNjaGVtYS5pZCxcbiAgICAgICAgcGF0aDogZmlsZS5yZWxQYXRoLFxuICAgICAgICB0eXBlOiBzY2hlbWEudHlwZSxcbiAgICAgICAgZmllbGRDb3VudDogc2NoZW1hLmZpZWxkcy5sZW5ndGgsXG4gICAgICAgIHJlZmVyZW5jZUNvdW50OiByZWZzLmxlbmd0aCxcbiAgICAgICAgaGFzSWRNaXNtYXRjaDogc2NoZW1hLmlkICE9PSBrZXksXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHNjaGVtYXMucHVzaCh7XG4gICAgICAgIGtleSxcbiAgICAgICAgaWQ6IGtleSxcbiAgICAgICAgcGF0aDogZmlsZS5yZWxQYXRoLFxuICAgICAgICB0eXBlOiBcImNvbnRyYWN0XCIsXG4gICAgICAgIGZpZWxkQ291bnQ6IDAsXG4gICAgICAgIHJlZmVyZW5jZUNvdW50OiAwLFxuICAgICAgICBoYXNJZE1pc21hdGNoOiBmYWxzZSxcbiAgICAgICAgcGFyc2VFcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHsgc2NoZW1hcyB9O1xufVxuXG4vKiogc2NoZW1hIOyDgeyEuCDrsJjtmZggKO2MjOydvOuqhSDquLDrsJgga2V566GcIOyhsO2ajCkgKi9cbmV4cG9ydCBmdW5jdGlvbiByZWFkU2NoZW1hKHNjaGVtYUtleTogc3RyaW5nKTogQ2RkU2NoZW1hRGV0YWlsRW52ZWxvcGUge1xuICBhc3NlcnRJbnNpZGVTY2hlbWFEaXIoc2NoZW1hS2V5KTtcblxuICBjb25zdCBjb250cmFjdERpciA9IGdldENvbnRyYWN0RGlyKCk7XG4gIGNvbnN0IGFic1BhdGggPSBwYXRoLmpvaW4oY29udHJhY3REaXIsIFwic2NoZW1hc1wiLCBgJHtzY2hlbWFLZXl9LnNjaGVtYS5qc29uYCk7XG5cbiAgaWYgKCFmcy5leGlzdHNTeW5jKGFic1BhdGgpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGDsiqTtgqTrp4jrpbwg7LC+7J2EIOyImCDsl4bsirXri4jri6Q6ICR7c2NoZW1hS2V5fWApO1xuICB9XG5cbiAgY29uc3QgcmF3ID0gZnMucmVhZEZpbGVTeW5jKGFic1BhdGgsIFwidXRmLThcIik7XG4gIGNvbnN0IHNjaGVtYSA9IEpTT04ucGFyc2UocmF3KSBhcyBDZGRTY2hlbWE7XG4gIGNvbnN0IHJlbFBhdGggPSBwYXRoLnJlbGF0aXZlKGNvbnRyYWN0RGlyLCBhYnNQYXRoKTtcbiAgY29uc3QgcmVmZXJlbmNlcyA9IGNvbGxlY3RTY2hlbWFSZWZlcmVuY2VzKHNjaGVtYS5pZCwgY29udHJhY3REaXIsIGNvbnRyYWN0RGlyKTtcblxuICByZXR1cm4ge1xuICAgIGtleTogc2NoZW1hS2V5LFxuICAgIHBhdGg6IHJlbFBhdGgsXG4gICAgc2NoZW1hLFxuICAgIHJlZmVyZW5jZXMsXG4gICAgaGFzSWRNaXNtYXRjaDogc2NoZW1hLmlkICE9PSBzY2hlbWFLZXksXG4gIH07XG59XG5cbi8qKiBzY2hlbWEg7YyM7J287J2EIOyZuOu2gCDsl5DrlJTthLDroZwg7Y647KeRICjtjIzsnbzrqoUg6riw67CYIGtleeuhnCDsobDtmowpICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZWRpdFNjaGVtYShcbiAgc2NoZW1hS2V5OiBzdHJpbmcsXG4pOiBQcm9taXNlPHsgc3VjY2VzczogYm9vbGVhbjsgc2NoZW1hS2V5OiBzdHJpbmcgfT4ge1xuICBhc3NlcnRJbnNpZGVTY2hlbWFEaXIoc2NoZW1hS2V5KTtcblxuICBjb25zdCBjb250cmFjdERpciA9IGdldENvbnRyYWN0RGlyKCk7XG4gIGNvbnN0IGFic1BhdGggPSBwYXRoLmpvaW4oY29udHJhY3REaXIsIFwic2NoZW1hc1wiLCBgJHtzY2hlbWFLZXl9LnNjaGVtYS5qc29uYCk7XG5cbiAgaWYgKCFmcy5leGlzdHNTeW5jKGFic1BhdGgpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGDsiqTtgqTrp4jrpbwg7LC+7J2EIOyImCDsl4bsirXri4jri6Q6ICR7c2NoZW1hS2V5fWApO1xuICB9XG5cbiAgY29uc3QgZWRpdG9yID0gcmVzb2x2ZUVkaXRvckNsaSgpO1xuICBhd2FpdCBydW5FZGl0b3IoZWRpdG9yLCBhYnNQYXRoKTtcblxuICByZXR1cm4geyBzdWNjZXNzOiB0cnVlLCBzY2hlbWFLZXkgfTtcbn1cblxuY29uc3QgVkFMSURfU1BFQ19TVEFUVVNFUyA9IG5ldyBTZXQ8Q2RkU3BlY1N0YXR1cz4oW1xuICBcImRyYWZ0XCIsXG4gIFwic3BlY2lmeWluZ1wiLFxuICBcImltcGxlbWVudGluZ1wiLFxuICBcInZhbGlkYXRpbmdcIixcbiAgXCJkb25lXCIsXG5dKTtcblxuLyoqIOuqqOuToCBjb250cmFjdC9zcGVjIOusuOyEnOulvCDsiqTsupTtlZjsl6wg64yA7Iuc67O065OcIO2GteqzhOulvCDrsJjtmZggKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREYXNoYm9hcmQoKTogQ2RkRGFzaGJvYXJkRGF0YSB7XG4gIGNvbnN0IGNvbnRyYWN0RGlyID0gZ2V0Q29udHJhY3REaXIoKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGNvbnRyYWN0RGlyKSkge1xuICAgIHJldHVybiB7XG4gICAgICBleGlzdHM6IGZhbHNlLFxuICAgICAgc3RhdHM6IHtcbiAgICAgICAgdG90YWxDb250cmFjdHM6IDAsXG4gICAgICAgIHRvdGFsU3BlY3M6IDAsXG4gICAgICAgIHN0YXR1c0Rpc3RyaWJ1dGlvbjogeyBkcmFmdDogMCwgc3BlY2lmeWluZzogMCwgaW1wbGVtZW50aW5nOiAwLCB2YWxpZGF0aW5nOiAwLCBkb25lOiAwIH0sXG4gICAgICB9LFxuICAgICAgZG9jdW1lbnRzOiBbXSxcbiAgICB9O1xuICB9XG5cbiAgY29uc3QgZG9jdW1lbnRzOiBDZGREb2N1bWVudFN1bW1hcnlbXSA9IFtdO1xuICBjb25zdCBzdGF0dXNEaXN0cmlidXRpb246IFJlY29yZDxDZGRTcGVjU3RhdHVzLCBudW1iZXI+ID0ge1xuICAgIGRyYWZ0OiAwLFxuICAgIHNwZWNpZnlpbmc6IDAsXG4gICAgaW1wbGVtZW50aW5nOiAwLFxuICAgIHZhbGlkYXRpbmc6IDAsXG4gICAgZG9uZTogMCxcbiAgfTtcblxuICBmdW5jdGlvbiBzY2FuRm9yRGFzaGJvYXJkKGRpclBhdGg6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGVudHJpZXMgPSBmcy5yZWFkZGlyU3luYyhkaXJQYXRoLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSk7XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbihkaXJQYXRoLCBlbnRyeS5uYW1lKTtcbiAgICAgIGlmIChlbnRyeS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgIGlmIChlbnRyeS5uYW1lID09PSBcInNjaGVtYXNcIikgY29udGludWU7XG4gICAgICAgIHNjYW5Gb3JEYXNoYm9hcmQoZnVsbFBhdGgpO1xuICAgICAgfSBlbHNlIGlmIChlbnRyeS5pc0ZpbGUoKSkge1xuICAgICAgICBjb25zdCBmaWxlVHlwZSA9IGRldGVjdEZpbGVUeXBlKGVudHJ5Lm5hbWUpO1xuICAgICAgICBpZiAoIWZpbGVUeXBlKSBjb250aW51ZTtcbiAgICAgICAgY29uc3QgcmVsUGF0aCA9IHBhdGgucmVsYXRpdmUoY29udHJhY3REaXIsIGZ1bGxQYXRoKTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCByYXcgPSBmcy5yZWFkRmlsZVN5bmMoZnVsbFBhdGgsIFwidXRmLThcIik7XG4gICAgICAgICAgY29uc3QgZG9jID0gSlNPTi5wYXJzZShyYXcpIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXG4gICAgICAgICAgY29uc3Qgc3VtbWFyeTogQ2RkRG9jdW1lbnRTdW1tYXJ5ID0ge1xuICAgICAgICAgICAgcGF0aDogcmVsUGF0aCxcbiAgICAgICAgICAgIG5hbWU6IGVudHJ5Lm5hbWUsXG4gICAgICAgICAgICBmaWxlVHlwZSxcbiAgICAgICAgICAgIHNjaGVtYUlkOiB0eXBlb2YgZG9jLnNjaGVtYSA9PT0gXCJzdHJpbmdcIiA/IGRvYy5zY2hlbWEgOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBsYXN0TW9kaWZpZWQ6IHR5cGVvZiBkb2MubGFzdE1vZGlmaWVkID09PSBcInN0cmluZ1wiID8gZG9jLmxhc3RNb2RpZmllZCA6IHVuZGVmaW5lZCxcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgaWYgKGZpbGVUeXBlID09PSBcImNvbnRyYWN0XCIpIHtcbiAgICAgICAgICAgIGNvbnN0IGZlYXR1cmVzID0gZG9jLmZlYXR1cmVzO1xuICAgICAgICAgICAgaWYgKGZlYXR1cmVzICYmIHR5cGVvZiBmZWF0dXJlcyA9PT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheShmZWF0dXJlcykpIHtcbiAgICAgICAgICAgICAgc3VtbWFyeS5mZWF0dXJlQ291bnQgPSBPYmplY3Qua2V5cyhmZWF0dXJlcykubGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzdGF0dXMgPSB0eXBlb2YgZG9jLnN0YXR1cyA9PT0gXCJzdHJpbmdcIiA/IGRvYy5zdGF0dXMgOiBcImRyYWZ0XCI7XG4gICAgICAgICAgICBzdW1tYXJ5LnN0YXR1cyA9IFZBTElEX1NQRUNfU1RBVFVTRVMuaGFzKHN0YXR1cyBhcyBDZGRTcGVjU3RhdHVzKVxuICAgICAgICAgICAgICA/IChzdGF0dXMgYXMgQ2RkU3BlY1N0YXR1cylcbiAgICAgICAgICAgICAgOiBcImRyYWZ0XCI7XG4gICAgICAgICAgICBzdGF0dXNEaXN0cmlidXRpb25bc3VtbWFyeS5zdGF0dXNdKys7XG5cbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRvYy5hY2NlcHRhbmNlQ3JpdGVyaWEpKSB7XG4gICAgICAgICAgICAgIHN1bW1hcnkuYWNjZXB0YW5jZUNyaXRlcmlhQ291bnQgPSBkb2MuYWNjZXB0YW5jZUNyaXRlcmlhLmxlbmd0aDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRvYy5zb3VyY2VzKSkge1xuICAgICAgICAgICAgICBzdW1tYXJ5LnNvdXJjZUNvdW50ID0gZG9jLnNvdXJjZXMubGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGRvY3VtZW50cy5wdXNoKHN1bW1hcnkpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICBkb2N1bWVudHMucHVzaCh7XG4gICAgICAgICAgICBwYXRoOiByZWxQYXRoLFxuICAgICAgICAgICAgbmFtZTogZW50cnkubmFtZSxcbiAgICAgICAgICAgIGZpbGVUeXBlLFxuICAgICAgICAgICAgcGFyc2VFcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc2NhbkZvckRhc2hib2FyZChjb250cmFjdERpcik7XG5cbiAgY29uc3QgdG90YWxDb250cmFjdHMgPSBkb2N1bWVudHMuZmlsdGVyKChkKSA9PiBkLmZpbGVUeXBlID09PSBcImNvbnRyYWN0XCIgJiYgIWQucGFyc2VFcnJvcikubGVuZ3RoO1xuICBjb25zdCB0b3RhbFNwZWNzID0gZG9jdW1lbnRzLmZpbHRlcigoZCkgPT4gZC5maWxlVHlwZSA9PT0gXCJzcGVjXCIgJiYgIWQucGFyc2VFcnJvcikubGVuZ3RoO1xuXG4gIHJldHVybiB7XG4gICAgZXhpc3RzOiB0cnVlLFxuICAgIHN0YXRzOiB7IHRvdGFsQ29udHJhY3RzLCB0b3RhbFNwZWNzLCBzdGF0dXNEaXN0cmlidXRpb24gfSxcbiAgICBkb2N1bWVudHMsXG4gIH07XG59XG5cbi8qKiDshozsiqQg7YyM7J287J2EIOyZuOu2gCDsl5DrlJTthLDroZwg7Je06riwICjrjIDquLDtlZjsp4Ag7JWK7J2MKSAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9wZW5Tb3VyY2VGaWxlKGZpbGVQYXRoOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgYWJzUGF0aCA9IHBhdGguaXNBYnNvbHV0ZShmaWxlUGF0aCkgPyBmaWxlUGF0aCA6IHBhdGgucmVzb2x2ZShTb25hbXUuYXBpUm9vdFBhdGgsIGZpbGVQYXRoKTtcblxuICBpZiAoIWZzLmV4aXN0c1N5bmMoYWJzUGF0aCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYO2MjOydvOydhCDssL7snYQg7IiYIOyXhuyKteuLiOuLpDogJHtmaWxlUGF0aH1gKTtcbiAgfVxuXG4gIGNvbnN0IGVkaXRvciA9IHJlc29sdmVFZGl0b3JDbGkoeyB3YWl0OiBmYWxzZSB9KTtcbiAgY29uc3QgY2hpbGQgPSBzcGF3bihlZGl0b3IuYmluLCBbLi4uZWRpdG9yLmFyZ3MsIGFic1BhdGhdLCB7XG4gICAgc3RkaW86IFwiaWdub3JlXCIsXG4gICAgZGV0YWNoZWQ6IHRydWUsXG4gIH0pO1xuICBjaGlsZC51bnJlZigpO1xufVxuIl0sIm5hbWVzIjpbInNwYXduIiwiZnMiLCJvcyIsInBhdGgiLCJTb25hbXUiLCJnZXRDb250cmFjdERpciIsImpvaW4iLCJhcGlSb290UGF0aCIsImFzc2VydEluc2lkZUNvbnRyYWN0RGlyIiwiZmlsZVBhdGgiLCJjb250cmFjdERpciIsInJlc29sdmVkIiwicmVzb2x2ZSIsInN0YXJ0c1dpdGgiLCJzZXAiLCJFcnJvciIsImRldGVjdEZpbGVUeXBlIiwiZmlsZU5hbWUiLCJlbmRzV2l0aCIsInVuZGVmaW5lZCIsInNjYW5EaXJlY3RvcnkiLCJkaXJQYXRoIiwicmVsYXRpdmVUbyIsImVudHJpZXMiLCJyZWFkZGlyU3luYyIsIndpdGhGaWxlVHlwZXMiLCJub2RlcyIsImVudHJ5IiwiZnVsbFBhdGgiLCJuYW1lIiwicmVsUGF0aCIsInJlbGF0aXZlIiwiaXNEaXJlY3RvcnkiLCJjaGlsZHJlbiIsInB1c2giLCJ0eXBlIiwiaXNGaWxlIiwiZmlsZVR5cGUiLCJnZXRDZGRUcmVlIiwiZXhpc3RzU3luYyIsImV4aXN0cyIsInRyZWUiLCJyZXNvbHZlU2NoZW1hIiwic2NoZW1hSWQiLCJzY2hlbWFQYXRoIiwicmF3IiwicmVhZEZpbGVTeW5jIiwiSlNPTiIsInBhcnNlIiwicmVhZENvbnRlbnQiLCJhYnNQYXRoIiwiZG9jdW1lbnQiLCJiYXNlbmFtZSIsInNjaGVtYSIsImVkaXRDb250ZW50IiwiZWRpdG9yIiwicmVzb2x2ZUVkaXRvckNsaSIsInJ1bkVkaXRvciIsInN1Y2Nlc3MiLCJFRElUT1JfQ0xJX01BUCIsImNsaSIsIndhaXRGbGFnIiwiWmVkIiwiQ3Vyc29yIiwib3B0aW9ucyIsIndhaXQiLCJhcHBOYW1lIiwiY29uZmlnIiwiZXh0ZXJuYWxFZGl0b3IiLCJtYXBwaW5nIiwiT2JqZWN0Iiwia2V5cyIsInNlYXJjaFBhdGhzIiwiaG9tZWRpciIsImJ1bmRsZVBhdGgiLCJmaW5kIiwicCIsImNsaUJpbiIsImJpbiIsImFyZ3MiLCJQcm9taXNlIiwicmVqZWN0IiwiY2hpbGQiLCJzdGRpbyIsIm9uIiwiZXJyIiwibWVzc2FnZSIsImNvZGUiLCJzY2FuU2NoZW1hRmlsZXMiLCJzY2hlbWFzRGlyIiwiZmlsdGVyIiwiZSIsIm1hcCIsImNvbGxlY3RTY2hlbWFSZWZlcmVuY2VzIiwicmVmcyIsImRvYyIsImV4cGVjdGVkU2NoZW1hSWQiLCJyZXBsYWNlIiwiYXNzZXJ0SW5zaWRlU2NoZW1hRGlyIiwic2NoZW1hS2V5IiwibGlzdFNjaGVtYXMiLCJmaWxlcyIsInNjaGVtYXMiLCJmaWxlIiwia2V5IiwiaWQiLCJmaWVsZENvdW50IiwiZmllbGRzIiwibGVuZ3RoIiwicmVmZXJlbmNlQ291bnQiLCJoYXNJZE1pc21hdGNoIiwicGFyc2VFcnJvciIsIlN0cmluZyIsInJlYWRTY2hlbWEiLCJyZWZlcmVuY2VzIiwiZWRpdFNjaGVtYSIsIlZBTElEX1NQRUNfU1RBVFVTRVMiLCJTZXQiLCJnZXREYXNoYm9hcmQiLCJzdGF0cyIsInRvdGFsQ29udHJhY3RzIiwidG90YWxTcGVjcyIsInN0YXR1c0Rpc3RyaWJ1dGlvbiIsImRyYWZ0Iiwic3BlY2lmeWluZyIsImltcGxlbWVudGluZyIsInZhbGlkYXRpbmciLCJkb25lIiwiZG9jdW1lbnRzIiwic2NhbkZvckRhc2hib2FyZCIsInN1bW1hcnkiLCJsYXN0TW9kaWZpZWQiLCJmZWF0dXJlcyIsIkFycmF5IiwiaXNBcnJheSIsImZlYXR1cmVDb3VudCIsInN0YXR1cyIsImhhcyIsImFjY2VwdGFuY2VDcml0ZXJpYSIsImFjY2VwdGFuY2VDcml0ZXJpYUNvdW50Iiwic291cmNlcyIsInNvdXJjZUNvdW50IiwiZCIsIm9wZW5Tb3VyY2VGaWxlIiwiaXNBYnNvbHV0ZSIsImRldGFjaGVkIiwidW5yZWYiXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLEtBQUssUUFBUSxnQkFBZ0I7QUFDdEMsT0FBT0MsUUFBUSxLQUFLO0FBQ3BCLE9BQU9DLFFBQVEsS0FBSztBQUNwQixPQUFPQyxVQUFVLE9BQU87QUFDeEIsU0FBU0MsTUFBTSxRQUFRLG1CQUFnQjtBQTZCdkMsNkNBQTZDLEdBQzdDLFNBQVNDO0lBQ1AsT0FBT0YsS0FBS0csSUFBSSxDQUFDRixPQUFPRyxXQUFXLEVBQUUsTUFBTSxNQUFNO0FBQ25EO0FBRUEsK0JBQStCLEdBQy9CLFNBQVNDLHdCQUF3QkMsUUFBZ0I7SUFDL0MsTUFBTUMsY0FBY0w7SUFDcEIsTUFBTU0sV0FBV1IsS0FBS1MsT0FBTyxDQUFDRixhQUFhRDtJQUMzQyxJQUFJLENBQUNFLFNBQVNFLFVBQVUsQ0FBQ0gsY0FBY1AsS0FBS1csR0FBRyxLQUFLSCxhQUFhRCxhQUFhO1FBQzVFLE1BQU0sSUFBSUssTUFBTSxDQUFDLDZCQUE2QixFQUFFTixVQUFVO0lBQzVEO0FBQ0Y7QUFFQSx5QkFBeUIsR0FDekIsU0FBU08sZUFBZUMsUUFBZ0I7SUFDdEMsSUFBSUEsU0FBU0MsUUFBUSxDQUFDLG1CQUFtQixPQUFPO0lBQ2hELElBQUlELFNBQVNDLFFBQVEsQ0FBQyxlQUFlLE9BQU87SUFDNUMsT0FBT0M7QUFDVDtBQUVBLHFDQUFxQyxHQUNyQyxTQUFTQyxjQUFjQyxPQUFlLEVBQUVDLFVBQWtCO0lBQ3hELE1BQU1DLFVBQVV0QixHQUFHdUIsV0FBVyxDQUFDSCxTQUFTO1FBQUVJLGVBQWU7SUFBSztJQUM5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
|
|
423
|
+
//#endregion
|
|
424
|
+
init_cdd_service();
|
|
425
|
+
export { addRule, editContent, getAcList, getCddTree, init_cdd_service, listRules, openSourceFile, readContent, readRule };
|
|
426
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RkLXNlcnZpY2UuanMiLCJuYW1lcyI6WyJub2RlczogQ2RkVHJlZU5vZGVbXSIsInJ1bGVzOiBDZGRSdWxlU3VtbWFyeVtdIiwicnVsZXM6IENkZFJ1bGVFbnRyeVtdIiwibmV3RW50cnk6IENkZFJ1bGVFbnRyeSIsImVudHJpZXM6IENkZEFjRW50cnlbXSIsImN1cnJlbnREZXNjcmliZTogc3RyaW5nIHwgbnVsbCIsImFjRmlsZXM6IENkZEFjRmlsZVtdIiwicmVzdWx0czogc3RyaW5nW10iLCJlbnRyaWVzOiBmcy5EaXJlbnRbXSIsIkVESVRPUl9DTElfTUFQOiBSZWNvcmQ8c3RyaW5nLCB7IGNsaTogc3RyaW5nOyB3YWl0RmxhZzogc3RyaW5nIH0+Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3VpL2NkZC1zZXJ2aWNlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHNwYXduIH0gZnJvbSBcImNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCBmcyBmcm9tIFwiZnNcIjtcbmltcG9ydCBvcyBmcm9tIFwib3NcIjtcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XG5cbmltcG9ydCB7IFNvbmFtdSB9IGZyb20gXCIuLi9hcGkvc29uYW11XCI7XG5pbXBvcnQge1xuICB0eXBlIENkZEFjRW50cnksXG4gIHR5cGUgQ2RkQWNGaWxlLFxuICB0eXBlIENkZEFjTGlzdFJlc3VsdCxcbiAgdHlwZSBDZGRBZGRSdWxlUmVxdWVzdCxcbiAgdHlwZSBDZGRDb250ZW50UmVzdWx0LFxuICB0eXBlIENkZEZpbGVUeXBlLFxuICB0eXBlIENkZFJ1bGVEZXRhaWwsXG4gIHR5cGUgQ2RkUnVsZUVudHJ5LFxuICB0eXBlIENkZFJ1bGVTdW1tYXJ5LFxuICB0eXBlIENkZFRyZWVOb2RlLFxufSBmcm9tIFwiLi9jZGQtdHlwZXNcIjtcblxuZXhwb3J0IHR5cGUge1xuICBDZGRBY0VudHJ5LFxuICBDZGRBY0ZpbGUsXG4gIENkZEFjTGlzdFJlc3VsdCxcbiAgQ2RkQWRkUnVsZVJlcXVlc3QsXG4gIENkZENvbnRlbnRSZXN1bHQsXG4gIENkZEZpbGVUeXBlLFxuICBDZGRSdWxlRGV0YWlsLFxuICBDZGRSdWxlRW50cnksXG4gIENkZFJ1bGVTdW1tYXJ5LFxuICBDZGRUcmVlTm9kZSxcbn0gZnJvbSBcIi4vY2RkLXR5cGVzXCI7XG5cbi8qKiBjb250cmFjdC8g65SU66CJ7YSw66asIOygiOuMgCDqsr3roZwg67CY7ZmYIChhcGlSb290UGF0aCDquLDspIApICovXG5mdW5jdGlvbiBnZXRDb250cmFjdERpcigpOiBzdHJpbmcge1xuICByZXR1cm4gcGF0aC5qb2luKFNvbmFtdS5hcGlSb290UGF0aCwgXCIuLlwiLCBcIi4uXCIsIFwiY29udHJhY3RcIik7XG59XG5cbi8qKiDtlITroZzsoJ3tirgg66Oo7Yq4IOqyveuhnCDrsJjtmZggKi9cbmZ1bmN0aW9uIGdldFByb2plY3RSb290KCk6IHN0cmluZyB7XG4gIHJldHVybiBwYXRoLmpvaW4oU29uYW11LmFwaVJvb3RQYXRoLCBcIi4uXCIsIFwiLi5cIik7XG59XG5cbi8qKiDqsr3roZzqsIAgY29udHJhY3QvIOuUlOugie2EsOumrCDrgrTrtoDsnbjsp4Ag6rKA7KadICovXG5mdW5jdGlvbiBhc3NlcnRJbnNpZGVDb250cmFjdERpcihmaWxlUGF0aDogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IGNvbnRyYWN0RGlyID0gZ2V0Q29udHJhY3REaXIoKTtcbiAgY29uc3QgcmVzb2x2ZWQgPSBwYXRoLnJlc29sdmUoY29udHJhY3REaXIsIGZpbGVQYXRoKTtcbiAgaWYgKCFyZXNvbHZlZC5zdGFydHNXaXRoKGNvbnRyYWN0RGlyICsgcGF0aC5zZXApICYmIHJlc29sdmVkICE9PSBjb250cmFjdERpcikge1xuICAgIHRocm93IG5ldyBFcnJvcihg6rK966Gc6rCAIGNvbnRyYWN0LyDrlJTroInthLDrpqwg67CW7J2EIOywuOyhsO2VqeuLiOuLpDogJHtmaWxlUGF0aH1gKTtcbiAgfVxufVxuXG4vKiog7YyM7J2866qF7JeQ7IScIENkZEZpbGVUeXBlIO2MkOuzhCAqL1xuZnVuY3Rpb24gZGV0ZWN0RmlsZVR5cGUoZmlsZU5hbWU6IHN0cmluZyk6IENkZEZpbGVUeXBlIHwgdW5kZWZpbmVkIHtcbiAgaWYgKGZpbGVOYW1lLmVuZHNXaXRoKFwiLmNvbnRyYWN0Lm1kXCIpKSByZXR1cm4gXCJjb250cmFjdFwiO1xuICBpZiAoZmlsZU5hbWUuZW5kc1dpdGgoXCIucnVsZXMuanNvblwiKSkgcmV0dXJuIFwicnVsZXNcIjtcbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqIOuUlOugie2EsOumrOulvCDsnqzqt4Ag7YOQ7IOJ7ZWY7JesIENkZFRyZWVOb2RlIO2KuOumrOulvCDsg53shLEgKi9cbmZ1bmN0aW9uIHNjYW5EaXJlY3RvcnkoZGlyUGF0aDogc3RyaW5nLCByZWxhdGl2ZVRvOiBzdHJpbmcpOiBDZGRUcmVlTm9kZVtdIHtcbiAgY29uc3QgZW50cmllcyA9IGZzLnJlYWRkaXJTeW5jKGRpclBhdGgsIHsgd2l0aEZpbGVUeXBlczogdHJ1ZSB9KTtcbiAgY29uc3Qgbm9kZXM6IENkZFRyZWVOb2RlW10gPSBbXTtcblxuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICBjb25zdCBmdWxsUGF0aCA9IHBhdGguam9pbihkaXJQYXRoLCBlbnRyeS5uYW1lKTtcbiAgICBjb25zdCByZWxQYXRoID0gcGF0aC5yZWxhdGl2ZShyZWxhdGl2ZVRvLCBmdWxsUGF0aCk7XG5cbiAgICBpZiAoZW50cnkuaXNEaXJlY3RvcnkoKSkge1xuICAgICAgaWYgKGVudHJ5Lm5hbWUgPT09IFwicnVsZXNcIikgY29udGludWU7XG4gICAgICBjb25zdCBjaGlsZHJlbiA9IHNjYW5EaXJlY3RvcnkoZnVsbFBhdGgsIHJlbGF0aXZlVG8pO1xuICAgICAgaWYgKGNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbm9kZXMucHVzaCh7XG4gICAgICAgICAgbmFtZTogZW50cnkubmFtZSxcbiAgICAgICAgICBwYXRoOiByZWxQYXRoLFxuICAgICAgICAgIHR5cGU6IFwiZGlyZWN0b3J5XCIsXG4gICAgICAgICAgY2hpbGRyZW4sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZW50cnkuaXNGaWxlKCkpIHtcbiAgICAgIGNvbnN0IGZpbGVUeXBlID0gZGV0ZWN0RmlsZVR5cGUoZW50cnkubmFtZSk7XG4gICAgICBpZiAoZmlsZVR5cGUgJiYgZmlsZVR5cGUgIT09IFwicnVsZXNcIikge1xuICAgICAgICBub2Rlcy5wdXNoKHtcbiAgICAgICAgICBuYW1lOiBlbnRyeS5uYW1lLFxuICAgICAgICAgIHBhdGg6IHJlbFBhdGgsXG4gICAgICAgICAgdHlwZTogXCJmaWxlXCIsXG4gICAgICAgICAgZmlsZVR5cGUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBub2Rlcztcbn1cblxuLyoqIGNvbnRyYWN0LyDrlJTroInthLDrpqzsnZgg7Yq466asIOq1rOyhsOulvCDrsJjtmZggKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDZGRUcmVlKCk6IHsgZXhpc3RzOiBib29sZWFuOyB0cmVlOiBDZGRUcmVlTm9kZVtdIH0ge1xuICBjb25zdCBjb250cmFjdERpciA9IGdldENvbnRyYWN0RGlyKCk7XG4gIGlmICghZnMuZXhpc3RzU3luYyhjb250cmFjdERpcikpIHtcbiAgICByZXR1cm4geyBleGlzdHM6IGZhbHNlLCB0cmVlOiBbXSB9O1xuICB9XG4gIGNvbnN0IHRyZWUgPSBzY2FuRGlyZWN0b3J5KGNvbnRyYWN0RGlyLCBjb250cmFjdERpcik7XG4gIHJldHVybiB7IGV4aXN0czogdHJ1ZSwgdHJlZSB9O1xufVxuXG4vKiog7YyM7J28IOuCtOyaqeydhCDsnb3slrQg67CY7ZmYIChjb250cmFjdC5tZCDihpIgbWFya2Rvd24g7JuQ66y4LCBydWxlcy5qc29uIOKGkiBKU09OIOusuOyekOyXtCkgKi9cbmV4cG9ydCBmdW5jdGlvbiByZWFkQ29udGVudChmaWxlUGF0aDogc3RyaW5nKTogQ2RkQ29udGVudFJlc3VsdCB7XG4gIGFzc2VydEluc2lkZUNvbnRyYWN0RGlyKGZpbGVQYXRoKTtcblxuICBjb25zdCBjb250cmFjdERpciA9IGdldENvbnRyYWN0RGlyKCk7XG4gIGNvbnN0IGFic1BhdGggPSBwYXRoLnJlc29sdmUoY29udHJhY3REaXIsIGZpbGVQYXRoKTtcblxuICBpZiAoIWZzLmV4aXN0c1N5bmMoYWJzUGF0aCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYO2MjOydvOydhCDssL7snYQg7IiYIOyXhuyKteuLiOuLpDogJHtmaWxlUGF0aH1gKTtcbiAgfVxuXG4gIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYWJzUGF0aCwgXCJ1dGYtOFwiKTtcbiAgY29uc3QgZmlsZVR5cGUgPSBkZXRlY3RGaWxlVHlwZShwYXRoLmJhc2VuYW1lKGZpbGVQYXRoKSk7XG5cbiAgcmV0dXJuIHtcbiAgICBjb250ZW50LFxuICAgIGZpbGVUeXBlOiBmaWxlVHlwZSA/PyBcImNvbnRyYWN0XCIsXG4gIH07XG59XG5cbi8qKiDtjIzsnbzsnYQg7Jm467aAIOyXkOuUlO2EsOuhnCDsp4HsoJEg7Y647KeRICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZWRpdENvbnRlbnQoXG4gIGZpbGVQYXRoOiBzdHJpbmcsXG4pOiBQcm9taXNlPHsgc3VjY2VzczogYm9vbGVhbjsgZmlsZVBhdGg6IHN0cmluZyB9PiB7XG4gIGFzc2VydEluc2lkZUNvbnRyYWN0RGlyKGZpbGVQYXRoKTtcblxuICBjb25zdCBjb250cmFjdERpciA9IGdldENvbnRyYWN0RGlyKCk7XG4gIGNvbnN0IGFic1BhdGggPSBwYXRoLnJlc29sdmUoY29udHJhY3REaXIsIGZpbGVQYXRoKTtcblxuICBpZiAoIWZzLmV4aXN0c1N5bmMoYWJzUGF0aCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYO2MjOydvOydhCDssL7snYQg7IiYIOyXhuyKteuLiOuLpDogJHtmaWxlUGF0aH1gKTtcbiAgfVxuXG4gIGNvbnN0IGVkaXRvciA9IHJlc29sdmVFZGl0b3JDbGkoKTtcbiAgYXdhaXQgcnVuRWRpdG9yKGVkaXRvciwgYWJzUGF0aCk7XG5cbiAgcmV0dXJuIHsgc3VjY2VzczogdHJ1ZSwgZmlsZVBhdGggfTtcbn1cblxuLyoqIOyXkOuUlO2EsOuzhCDslbEg67KI65OkIOuCtCBDTEkg6rK966GcICsgLS13YWl0IO2UjOuemOq3uCDrp6TtlZEgKi9cbmNvbnN0IEVESVRPUl9DTElfTUFQOiBSZWNvcmQ8c3RyaW5nLCB7IGNsaTogc3RyaW5nOyB3YWl0RmxhZzogc3RyaW5nIH0+ID0ge1xuICBcIlZpc3VhbCBTdHVkaW8gQ29kZVwiOiB7IGNsaTogXCJDb250ZW50cy9SZXNvdXJjZXMvYXBwL2Jpbi9jb2RlXCIsIHdhaXRGbGFnOiBcIi0td2FpdFwiIH0sXG4gIFplZDogeyBjbGk6IFwiQ29udGVudHMvTWFjT1MvY2xpXCIsIHdhaXRGbGFnOiBcIi0td2FpdFwiIH0sXG4gIEN1cnNvcjogeyBjbGk6IFwiQ29udGVudHMvUmVzb3VyY2VzL2FwcC9iaW4vY3Vyc29yXCIsIHdhaXRGbGFnOiBcIi0td2FpdFwiIH0sXG59O1xuXG4vKiog7JWxIOuyiOuTpCBDTEkg6rK966Gc66W8IHJlc29sdmUuIHdhaXQ9ZmFsc2XsnbTrqbQgLS13YWl0IO2UjOuemOq3uOulvCDsg53rnrUgKi9cbmZ1bmN0aW9uIHJlc29sdmVFZGl0b3JDbGkob3B0aW9ucz86IHsgd2FpdD86IGJvb2xlYW4gfSk6IHsgYmluOiBzdHJpbmc7IGFyZ3M6IHN0cmluZ1tdIH0ge1xuICBjb25zdCB3YWl0ID0gb3B0aW9ucz8ud2FpdCA/PyB0cnVlO1xuICBjb25zdCBhcHBOYW1lID0gU29uYW11LmNvbmZpZy5leHRlcm5hbEVkaXRvciA/PyBcIlZpc3VhbCBTdHVkaW8gQ29kZVwiO1xuICBjb25zdCBtYXBwaW5nID0gRURJVE9SX0NMSV9NQVBbYXBwTmFtZV07XG4gIGlmICghbWFwcGluZykge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGDsp4Dsm5DrkJjsp4Ag7JWK64qUIOyXkOuUlO2EsOyeheuLiOuLpDogJHthcHBOYW1lfSAo7KeA7JuQOiAke09iamVjdC5rZXlzKEVESVRPUl9DTElfTUFQKS5qb2luKFwiLCBcIil9KWAsXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IHNlYXJjaFBhdGhzID0gW1xuICAgIGAvQXBwbGljYXRpb25zLyR7YXBwTmFtZX0uYXBwYCxcbiAgICBgJHtvcy5ob21lZGlyKCl9L0FwcGxpY2F0aW9ucy8ke2FwcE5hbWV9LmFwcGAsXG4gIF07XG4gIGNvbnN0IGJ1bmRsZVBhdGggPSBzZWFyY2hQYXRocy5maW5kKChwKSA9PiBmcy5leGlzdHNTeW5jKHApKTtcbiAgaWYgKCFidW5kbGVQYXRoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGDslbEg67KI65Ok7J2EIOywvuydhCDsiJgg7JeG7Iq164uI64ukOiAke2FwcE5hbWV9ICgvQXBwbGljYXRpb25zIO2ZleyduClgKTtcbiAgfVxuXG4gIGNvbnN0IGNsaUJpbiA9IHBhdGguam9pbihidW5kbGVQYXRoLCBtYXBwaW5nLmNsaSk7XG4gIGlmICghZnMuZXhpc3RzU3luYyhjbGlCaW4pKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGDsl5DrlJTthLAgQ0xJ66W8IOywvuydhCDsiJgg7JeG7Iq164uI64ukOiAke2NsaUJpbn1gKTtcbiAgfVxuXG4gIHJldHVybiB7IGJpbjogY2xpQmluLCBhcmdzOiB3YWl0ID8gW21hcHBpbmcud2FpdEZsYWddIDogW10gfTtcbn1cblxuLyoqIOyXkOuUlO2EsCBDTEnrpbwg7Iuk7ZaJ7ZWY6rOgIO2DreydtCDri6vtnpAg65WM6rmM7KeAIOuMgOq4sCAqL1xuZnVuY3Rpb24gcnVuRWRpdG9yKGVkaXRvcjogeyBiaW46IHN0cmluZzsgYXJnczogc3RyaW5nW10gfSwgZmlsZVBhdGg6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IGNoaWxkID0gc3Bhd24oZWRpdG9yLmJpbiwgWy4uLmVkaXRvci5hcmdzLCBmaWxlUGF0aF0sIHtcbiAgICAgIHN0ZGlvOiBcImluaGVyaXRcIixcbiAgICB9KTtcblxuICAgIGNoaWxkLm9uKFwiZXJyb3JcIiwgKGVycikgPT4ge1xuICAgICAgcmVqZWN0KG5ldyBFcnJvcihg7JeQ65SU7YSwIOyLpO2WiSDsi6TtjKggKCR7ZWRpdG9yLmJpbn0pOiAke2Vyci5tZXNzYWdlfWApKTtcbiAgICB9KTtcblxuICAgIGNoaWxkLm9uKFwiY2xvc2VcIiwgKGNvZGUpID0+IHtcbiAgICAgIGlmIChjb2RlID09PSAwKSB7XG4gICAgICAgIHJlc29sdmUoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoYOyXkOuUlO2EsOqwgCDruYTsoJXsg4Eg7KKF66OM65CY7JeI7Iq164uI64ukIChleGl0IGNvZGU6ICR7Y29kZX0pYCkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cblxuLyoqIOyGjOyKpCDtjIzsnbzsnYQg7Jm467aAIOyXkOuUlO2EsOuhnCDsl7TquLAgKOuMgOq4sO2VmOyngCDslYrsnYwpICovXG5leHBvcnQgZnVuY3Rpb24gb3BlblNvdXJjZUZpbGUoZmlsZVBhdGg6IHN0cmluZyk6IHZvaWQge1xuICBjb25zdCBhYnNQYXRoID0gcGF0aC5pc0Fic29sdXRlKGZpbGVQYXRoKSA/IGZpbGVQYXRoIDogcGF0aC5yZXNvbHZlKFNvbmFtdS5hcGlSb290UGF0aCwgZmlsZVBhdGgpO1xuXG4gIGlmICghZnMuZXhpc3RzU3luYyhhYnNQYXRoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihg7YyM7J287J2EIOywvuydhCDsiJgg7JeG7Iq164uI64ukOiAke2ZpbGVQYXRofWApO1xuICB9XG5cbiAgY29uc3QgZWRpdG9yID0gcmVzb2x2ZUVkaXRvckNsaSh7IHdhaXQ6IGZhbHNlIH0pO1xuICBjb25zdCBjaGlsZCA9IHNwYXduKGVkaXRvci5iaW4sIFsuLi5lZGl0b3IuYXJncywgYWJzUGF0aF0sIHtcbiAgICBzdGRpbzogXCJpZ25vcmVcIixcbiAgICBkZXRhY2hlZDogdHJ1ZSxcbiAgfSk7XG4gIGNoaWxkLnVucmVmKCk7XG59XG5cbi8qID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICogUnVsZXMgQVBJXG4gKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0gKi9cblxuLyoqIGNvbnRyYWN0L3J1bGVzLyDrlJTroInthLDrpqwg64K0IC5ydWxlcy5qc29uIO2MjOydvCDrqqnroZ0g67CY7ZmYICovXG5leHBvcnQgZnVuY3Rpb24gbGlzdFJ1bGVzKCk6IHsgcnVsZXM6IENkZFJ1bGVTdW1tYXJ5W10gfSB7XG4gIGNvbnN0IGNvbnRyYWN0RGlyID0gZ2V0Q29udHJhY3REaXIoKTtcbiAgY29uc3QgcnVsZXNEaXIgPSBwYXRoLmpvaW4oY29udHJhY3REaXIsIFwicnVsZXNcIik7XG4gIGlmICghZnMuZXhpc3RzU3luYyhydWxlc0RpcikpIHJldHVybiB7IHJ1bGVzOiBbXSB9O1xuXG4gIGNvbnN0IGVudHJpZXMgPSBmcy5yZWFkZGlyU3luYyhydWxlc0RpciwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pO1xuICBjb25zdCBydWxlczogQ2RkUnVsZVN1bW1hcnlbXSA9IFtdO1xuXG4gIGZvciAoY29uc3QgZW50cnkgb2YgZW50cmllcykge1xuICAgIGlmICghZW50cnkuaXNGaWxlKCkgfHwgIWVudHJ5Lm5hbWUuZW5kc1dpdGgoXCIucnVsZXMuanNvblwiKSkgY29udGludWU7XG5cbiAgICBjb25zdCBrZXkgPSBlbnRyeS5uYW1lLnJlcGxhY2UoL1xcLnJ1bGVzXFwuanNvbiQvLCBcIlwiKTtcbiAgICBjb25zdCByZWxQYXRoID0gYHJ1bGVzLyR7ZW50cnkubmFtZX1gO1xuICAgIGNvbnN0IGFic1BhdGggPSBwYXRoLmpvaW4ocnVsZXNEaXIsIGVudHJ5Lm5hbWUpO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJhdyA9IGZzLnJlYWRGaWxlU3luYyhhYnNQYXRoLCBcInV0Zi04XCIpO1xuICAgICAgY29uc3QgZG9jID0gSlNPTi5wYXJzZShyYXcpIGFzIHsgZGVzY3JpcHRpb24/OiBzdHJpbmc7IHJ1bGVzPzogdW5rbm93bltdIH07XG4gICAgICBydWxlcy5wdXNoKHtcbiAgICAgICAga2V5LFxuICAgICAgICBwYXRoOiByZWxQYXRoLFxuICAgICAgICBkZXNjcmlwdGlvbjogdHlwZW9mIGRvYy5kZXNjcmlwdGlvbiA9PT0gXCJzdHJpbmdcIiA/IGRvYy5kZXNjcmlwdGlvbiA6IFwiXCIsXG4gICAgICAgIHJ1bGVDb3VudDogQXJyYXkuaXNBcnJheShkb2MucnVsZXMpID8gZG9jLnJ1bGVzLmxlbmd0aCA6IDAsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJ1bGVzLnB1c2goe1xuICAgICAgICBrZXksXG4gICAgICAgIHBhdGg6IHJlbFBhdGgsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBcIlwiLFxuICAgICAgICBydWxlQ291bnQ6IDAsXG4gICAgICAgIHBhcnNlRXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiBTdHJpbmcoZXJyKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IHJ1bGVzIH07XG59XG5cbi8qKiBydWxlcyDtjIzsnbwg7IOB7IS4IOuwmO2ZmCAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlYWRSdWxlKHJ1bGVLZXk6IHN0cmluZyk6IENkZFJ1bGVEZXRhaWwge1xuICBjb25zdCBjb250cmFjdERpciA9IGdldENvbnRyYWN0RGlyKCk7XG4gIGNvbnN0IGFic1BhdGggPSBwYXRoLmpvaW4oY29udHJhY3REaXIsIFwicnVsZXNcIiwgYCR7cnVsZUtleX0ucnVsZXMuanNvbmApO1xuXG4gIGlmICghZnMuZXhpc3RzU3luYyhhYnNQYXRoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgUnVsZXMg7YyM7J287J2EIOywvuydhCDsiJgg7JeG7Iq164uI64ukOiAke3J1bGVLZXl9YCk7XG4gIH1cblxuICBjb25zdCByYXcgPSBmcy5yZWFkRmlsZVN5bmMoYWJzUGF0aCwgXCJ1dGYtOFwiKTtcbiAgY29uc3QgZG9jID0gSlNPTi5wYXJzZShyYXcpIGFzIHsgZGVzY3JpcHRpb24/OiBzdHJpbmc7IHJ1bGVzPzogQ2RkUnVsZUVudHJ5W10gfTtcblxuICByZXR1cm4ge1xuICAgIGtleTogcnVsZUtleSxcbiAgICBwYXRoOiBgcnVsZXMvJHtydWxlS2V5fS5ydWxlcy5qc29uYCxcbiAgICBkZXNjcmlwdGlvbjogdHlwZW9mIGRvYy5kZXNjcmlwdGlvbiA9PT0gXCJzdHJpbmdcIiA/IGRvYy5kZXNjcmlwdGlvbiA6IFwiXCIsXG4gICAgcnVsZXM6IEFycmF5LmlzQXJyYXkoZG9jLnJ1bGVzKSA/IGRvYy5ydWxlcyA6IFtdLFxuICB9O1xufVxuXG4vKiogcnVsZXMg7YyM7J287JeQIOq3nOy5mSDstpTqsIAgKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRSdWxlKHJlcTogQ2RkQWRkUnVsZVJlcXVlc3QpOiBDZGRSdWxlRGV0YWlsIHtcbiAgY29uc3QgY29udHJhY3REaXIgPSBnZXRDb250cmFjdERpcigpO1xuICBjb25zdCBydWxlc0RpciA9IHBhdGguam9pbihjb250cmFjdERpciwgXCJydWxlc1wiKTtcbiAgY29uc3QgYWJzUGF0aCA9IHBhdGguam9pbihydWxlc0RpciwgYCR7cmVxLnJ1bGVLZXl9LnJ1bGVzLmpzb25gKTtcblxuICBpZiAoIWZzLmV4aXN0c1N5bmMoYWJzUGF0aCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFJ1bGVzIO2MjOydvOydhCDssL7snYQg7IiYIOyXhuyKteuLiOuLpDogJHtyZXEucnVsZUtleX1gKTtcbiAgfVxuXG4gIGNvbnN0IHJhdyA9IGZzLnJlYWRGaWxlU3luYyhhYnNQYXRoLCBcInV0Zi04XCIpO1xuICBjb25zdCBkb2MgPSBKU09OLnBhcnNlKHJhdykgYXMgeyBkZXNjcmlwdGlvbj86IHN0cmluZzsgcnVsZXM/OiBDZGRSdWxlRW50cnlbXSB9O1xuICBjb25zdCBydWxlczogQ2RkUnVsZUVudHJ5W10gPSBBcnJheS5pc0FycmF5KGRvYy5ydWxlcykgPyBkb2MucnVsZXMgOiBbXTtcblxuICBjb25zdCBuZXh0SWQgPSBnZW5lcmF0ZU5leHRSdWxlSWQocnVsZXMpO1xuICBjb25zdCBuZXdFbnRyeTogQ2RkUnVsZUVudHJ5ID0ge1xuICAgIGlkOiBuZXh0SWQsXG4gICAgd2hlbjogcmVxLndoZW4sXG4gICAgaW5zdHJ1Y3Rpb246IHJlcS5pbnN0cnVjdGlvbixcbiAgfTtcbiAgaWYgKHJlcS5leGFtcGxlcyAmJiByZXEuZXhhbXBsZXMubGVuZ3RoID4gMCkge1xuICAgIG5ld0VudHJ5LmV4YW1wbGVzID0gcmVxLmV4YW1wbGVzO1xuICB9XG5cbiAgcnVsZXMucHVzaChuZXdFbnRyeSk7XG4gIGRvYy5ydWxlcyA9IHJ1bGVzO1xuXG4gIGZzLndyaXRlRmlsZVN5bmMoYWJzUGF0aCwgYCR7SlNPTi5zdHJpbmdpZnkoZG9jLCBudWxsLCAyKX1cXG5gLCBcInV0Zi04XCIpO1xuXG4gIHJldHVybiB7XG4gICAga2V5OiByZXEucnVsZUtleSxcbiAgICBwYXRoOiBgcnVsZXMvJHtyZXEucnVsZUtleX0ucnVsZXMuanNvbmAsXG4gICAgZGVzY3JpcHRpb246IHR5cGVvZiBkb2MuZGVzY3JpcHRpb24gPT09IFwic3RyaW5nXCIgPyBkb2MuZGVzY3JpcHRpb24gOiBcIlwiLFxuICAgIHJ1bGVzLFxuICB9O1xufVxuXG4vKiog6riw7KG0IGlkIO2MqO2EtOydhCDrtoTshJ3tlZjsl6wg64uk7J2MIOyInOuyiCBpZCDsg53shLEgKi9cbmZ1bmN0aW9uIGdlbmVyYXRlTmV4dFJ1bGVJZChydWxlczogQ2RkUnVsZUVudHJ5W10pOiBzdHJpbmcge1xuICBpZiAocnVsZXMubGVuZ3RoID09PSAwKSByZXR1cm4gXCJSLTAwMVwiO1xuXG4gIGNvbnN0IG51bWVyaWNQYXR0ZXJuID0gL14oLis/KShcXGQrKSQvO1xuICBsZXQgYmVzdFByZWZpeCA9IFwiUi1cIjtcbiAgbGV0IG1heE51bSA9IDA7XG5cbiAgZm9yIChjb25zdCBydWxlIG9mIHJ1bGVzKSB7XG4gICAgY29uc3QgbWF0Y2ggPSBudW1lcmljUGF0dGVybi5leGVjKHJ1bGUuaWQpO1xuICAgIGlmIChtYXRjaCkge1xuICAgICAgY29uc3QgcHJlZml4ID0gbWF0Y2hbMV07XG4gICAgICBjb25zdCBudW0gPSBOdW1iZXIucGFyc2VJbnQobWF0Y2hbMl0sIDEwKTtcbiAgICAgIGlmIChudW0gPiBtYXhOdW0pIHtcbiAgICAgICAgYmVzdFByZWZpeCA9IHByZWZpeDtcbiAgICAgICAgbWF4TnVtID0gbnVtO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IG5leHROdW0gPSBtYXhOdW0gKyAxO1xuICBjb25zdCBwYWRMZW4gPSBNYXRoLm1heCgzLCBTdHJpbmcobWF4TnVtKS5sZW5ndGgpO1xuICByZXR1cm4gYCR7YmVzdFByZWZpeH0ke1N0cmluZyhuZXh0TnVtKS5wYWRTdGFydChwYWRMZW4sIFwiMFwiKX1gO1xufVxuXG4vKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIEFDIEFQSSAobW9kdWxlcy9jZGQgYWMtbGlzdCDtjIzsi7Eg66Gc7KeBIOuzteyCrClcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqL1xuXG4vKiogZGVzY3JpYmUvdGVzdCDtjKjthLQg7YyM7IuxICovXG5mdW5jdGlvbiBwYXJzZUFjRW50cmllcyhjb250ZW50OiBzdHJpbmcpOiBDZGRBY0VudHJ5W10ge1xuICBjb25zdCBlbnRyaWVzOiBDZGRBY0VudHJ5W10gPSBbXTtcbiAgY29uc3QgbGluZXMgPSBjb250ZW50LnNwbGl0KFwiXFxuXCIpO1xuXG4gIGxldCBjdXJyZW50RGVzY3JpYmU6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBsZXQgZGVzY3JpYmVEZXB0aCA9IDA7XG4gIGxldCBicmFjZURlcHRoID0gMDtcbiAgbGV0IHBlbmRpbmdUZXN0QXMgPSBmYWxzZTtcbiAgbGV0IHRlc3RBc0JyYWNlRGVwdGggPSAwO1xuICBsZXQgdGVzdEFzTmVlZE5hbWUgPSBmYWxzZTtcblxuICBmb3IgKGNvbnN0IGxpbmUgb2YgbGluZXMpIHtcbiAgICBjb25zdCB0cmltbWVkID0gbGluZS50cmltKCk7XG5cbiAgICBjb25zdCBkZXNjcmliZU1hdGNoID0gdHJpbW1lZC5tYXRjaCgvXmRlc2NyaWJlXFwoW1wiJ2BdKC4rPylbXCInYF0vKTtcbiAgICBpZiAoZGVzY3JpYmVNYXRjaCkge1xuICAgICAgY3VycmVudERlc2NyaWJlID0gZGVzY3JpYmVNYXRjaFsxXTtcbiAgICAgIGRlc2NyaWJlRGVwdGggPSBicmFjZURlcHRoO1xuICAgIH1cblxuICAgIGNvbnN0IHRlc3RNYXRjaCA9IHRyaW1tZWQubWF0Y2goL14oPzp0ZXN0fGl0KVxcKFtcIidgXSguKz8pW1wiJ2BdLyk7XG4gICAgaWYgKHRlc3RNYXRjaCkge1xuICAgICAgZW50cmllcy5wdXNoKHtcbiAgICAgICAgZGVzY3JpYmU6IGN1cnJlbnREZXNjcmliZSxcbiAgICAgICAgdGVzdDogdGVzdE1hdGNoWzFdLFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKCFwZW5kaW5nVGVzdEFzICYmIHRyaW1tZWQubWF0Y2goL150ZXN0QXNcXHMqXFwoLykpIHtcbiAgICAgIGNvbnN0IGlubGluZU1hdGNoID0gdHJpbW1lZC5tYXRjaCgvXnRlc3RBc1xccypcXChcXHMqXFx7W159XSpcXH1cXHMqLFxccypbXCInYF0oLis/KVtcIidgXS8pO1xuICAgICAgaWYgKGlubGluZU1hdGNoKSB7XG4gICAgICAgIGVudHJpZXMucHVzaCh7IGRlc2NyaWJlOiBjdXJyZW50RGVzY3JpYmUsIHRlc3Q6IGlubGluZU1hdGNoWzFdIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcGVuZGluZ1Rlc3RBcyA9IHRydWU7XG4gICAgICAgIHRlc3RBc0JyYWNlRGVwdGggPSAwO1xuICAgICAgICB0ZXN0QXNOZWVkTmFtZSA9IGZhbHNlO1xuICAgICAgICBmb3IgKGNvbnN0IGNoIG9mIHRyaW1tZWQpIHtcbiAgICAgICAgICBpZiAoY2ggPT09IFwie1wiKSB0ZXN0QXNCcmFjZURlcHRoKys7XG4gICAgICAgICAgaWYgKGNoID09PSBcIn1cIikgdGVzdEFzQnJhY2VEZXB0aC0tO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0ZXN0QXNCcmFjZURlcHRoIDw9IDApIHtcbiAgICAgICAgICB0ZXN0QXNOZWVkTmFtZSA9IHRydWU7XG4gICAgICAgICAgY29uc3QgbmFtZU1hdGNoID0gdHJpbW1lZC5tYXRjaCgvfVxccyosXFxzKltcIidgXSguKz8pW1wiJ2BdLyk7XG4gICAgICAgICAgaWYgKG5hbWVNYXRjaCkge1xuICAgICAgICAgICAgZW50cmllcy5wdXNoKHsgZGVzY3JpYmU6IGN1cnJlbnREZXNjcmliZSwgdGVzdDogbmFtZU1hdGNoWzFdIH0pO1xuICAgICAgICAgICAgcGVuZGluZ1Rlc3RBcyA9IGZhbHNlO1xuICAgICAgICAgICAgdGVzdEFzTmVlZE5hbWUgPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHBlbmRpbmdUZXN0QXMpIHtcbiAgICAgIGlmICghdGVzdEFzTmVlZE5hbWUpIHtcbiAgICAgICAgZm9yIChjb25zdCBjaCBvZiB0cmltbWVkKSB7XG4gICAgICAgICAgaWYgKGNoID09PSBcIntcIikgdGVzdEFzQnJhY2VEZXB0aCsrO1xuICAgICAgICAgIGlmIChjaCA9PT0gXCJ9XCIpIHRlc3RBc0JyYWNlRGVwdGgtLTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGVzdEFzQnJhY2VEZXB0aCA8PSAwKSB7XG4gICAgICAgICAgdGVzdEFzTmVlZE5hbWUgPSB0cnVlO1xuICAgICAgICAgIGNvbnN0IG5hbWVNYXRjaCA9IHRyaW1tZWQubWF0Y2goL31cXHMqLFxccypbXCInYF0oLis/KVtcIidgXS8pO1xuICAgICAgICAgIGlmIChuYW1lTWF0Y2gpIHtcbiAgICAgICAgICAgIGVudHJpZXMucHVzaCh7IGRlc2NyaWJlOiBjdXJyZW50RGVzY3JpYmUsIHRlc3Q6IG5hbWVNYXRjaFsxXSB9KTtcbiAgICAgICAgICAgIHBlbmRpbmdUZXN0QXMgPSBmYWxzZTtcbiAgICAgICAgICAgIHRlc3RBc05lZWROYW1lID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBuYW1lTWF0Y2ggPSB0cmltbWVkLm1hdGNoKC9eW1wiJ2BdKC4rPylbXCInYF0vKTtcbiAgICAgICAgaWYgKG5hbWVNYXRjaCkge1xuICAgICAgICAgIGVudHJpZXMucHVzaCh7IGRlc2NyaWJlOiBjdXJyZW50RGVzY3JpYmUsIHRlc3Q6IG5hbWVNYXRjaFsxXSB9KTtcbiAgICAgICAgICBwZW5kaW5nVGVzdEFzID0gZmFsc2U7XG4gICAgICAgICAgdGVzdEFzTmVlZE5hbWUgPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgY2ggb2YgdHJpbW1lZCkge1xuICAgICAgaWYgKGNoID09PSBcIntcIikgYnJhY2VEZXB0aCsrO1xuICAgICAgaWYgKGNoID09PSBcIn1cIikge1xuICAgICAgICBicmFjZURlcHRoLS07XG4gICAgICAgIGlmIChjdXJyZW50RGVzY3JpYmUgJiYgYnJhY2VEZXB0aCA8PSBkZXNjcmliZURlcHRoKSB7XG4gICAgICAgICAgY3VycmVudERlc2NyaWJlID0gbnVsbDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBlbnRyaWVzO1xufVxuXG4vKiog7ZSE66Gc7KCd7Yq4IOuCtCAqLnRlc3QudHMg7YyM7J287J2EIOyKpOy6lO2VmOyXrCBBQyDrqqnroZ0g67CY7ZmYICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QWNMaXN0KCk6IENkZEFjTGlzdFJlc3VsdCB7XG4gIGNvbnN0IHByb2plY3RSb290ID0gZ2V0UHJvamVjdFJvb3QoKTtcbiAgY29uc3QgZmlsZXMgPSBmaW5kVGVzdEZpbGVzKHByb2plY3RSb290KTtcblxuICBjb25zdCBhY0ZpbGVzOiBDZGRBY0ZpbGVbXSA9IFtdO1xuICBmb3IgKGNvbnN0IGFic1BhdGggb2YgZmlsZXMpIHtcbiAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGFic1BhdGgsIFwidXRmLThcIik7XG4gICAgY29uc3QgZW50cmllcyA9IHBhcnNlQWNFbnRyaWVzKGNvbnRlbnQpO1xuICAgIGlmIChlbnRyaWVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGFjRmlsZXMucHVzaCh7XG4gICAgICAgIHBhdGg6IHBhdGgucmVsYXRpdmUocHJvamVjdFJvb3QsIGFic1BhdGgpLFxuICAgICAgICBlbnRyaWVzLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgdG90YWwgPSBhY0ZpbGVzLnJlZHVjZSgoc3VtLCBmKSA9PiBzdW0gKyBmLmVudHJpZXMubGVuZ3RoLCAwKTtcbiAgcmV0dXJuIHsgZmlsZXM6IGFjRmlsZXMsIHRvdGFsIH07XG59XG5cbi8qKiAqLnRlc3QudHMg7YyM7J287J2EIOyerOq3gCDtg5Dsg4kgKG5vZGVfbW9kdWxlcywgZGlzdCDsoJzsmbgpICovXG5mdW5jdGlvbiBmaW5kVGVzdEZpbGVzKGRpcjogc3RyaW5nKTogc3RyaW5nW10ge1xuICBjb25zdCByZXN1bHRzOiBzdHJpbmdbXSA9IFtdO1xuICBjb25zdCBJR05PUkUgPSBuZXcgU2V0KFtcIm5vZGVfbW9kdWxlc1wiLCBcImRpc3RcIiwgXCIuZ2l0XCIsIFwiY29udHJhY3RcIl0pO1xuXG4gIGZ1bmN0aW9uIHdhbGsoY3VycmVudERpcjogc3RyaW5nKTogdm9pZCB7XG4gICAgbGV0IGVudHJpZXM6IGZzLkRpcmVudFtdO1xuICAgIHRyeSB7XG4gICAgICBlbnRyaWVzID0gZnMucmVhZGRpclN5bmMoY3VycmVudERpciwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pO1xuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICAgIGlmIChJR05PUkUuaGFzKGVudHJ5Lm5hbWUpKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IGZ1bGxQYXRoID0gcGF0aC5qb2luKGN1cnJlbnREaXIsIGVudHJ5Lm5hbWUpO1xuICAgICAgaWYgKGVudHJ5LmlzRGlyZWN0b3J5KCkpIHtcbiAgICAgICAgd2FsayhmdWxsUGF0aCk7XG4gICAgICB9IGVsc2UgaWYgKGVudHJ5LmlzRmlsZSgpICYmIGVudHJ5Lm5hbWUuZW5kc1dpdGgoXCIudGVzdC50c1wiKSkge1xuICAgICAgICByZXN1bHRzLnB1c2goZnVsbFBhdGgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHdhbGsoZGlyKTtcbiAgcmVzdWx0cy5zb3J0KCk7XG4gIHJldHVybiByZXN1bHRzO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFpQ0EsU0FBUyxpQkFBeUI7QUFDaEMsUUFBTyxLQUFLLEtBQUssT0FBTyxhQUFhLE1BQU0sTUFBTSxXQUFXOzs7QUFJOUQsU0FBUyxpQkFBeUI7QUFDaEMsUUFBTyxLQUFLLEtBQUssT0FBTyxhQUFhLE1BQU0sS0FBSzs7O0FBSWxELFNBQVMsd0JBQXdCLFVBQXdCO0NBQ3ZELE1BQU0sY0FBYyxnQkFBZ0I7Q0FDcEMsTUFBTSxXQUFXLEtBQUssUUFBUSxhQUFhLFNBQVM7QUFDcEQsS0FBSSxDQUFDLFNBQVMsV0FBVyxjQUFjLEtBQUssSUFBSSxJQUFJLGFBQWEsYUFBYTtBQUM1RSxRQUFNLElBQUksTUFBTSxnQ0FBZ0MsV0FBVzs7OztBQUsvRCxTQUFTLGVBQWUsVUFBMkM7QUFDakUsS0FBSSxTQUFTLFNBQVMsZUFBZSxDQUFFLFFBQU87QUFD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
|