sonamu 0.9.19 → 0.10.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/dist/_virtual/_rolldown/runtime.js +36 -0
- package/dist/ai/agents/agent.js +5 -7
- package/dist/ai/agents/index.js +1 -2
- package/dist/ai/agents/types.js +1 -1
- package/dist/ai/index.js +1 -2
- package/dist/ai/providers/rtzr/api.js +2 -3
- package/dist/ai/providers/rtzr/error.js +14 -29
- package/dist/ai/providers/rtzr/index.js +1 -2
- package/dist/ai/providers/rtzr/model.js +13 -20
- package/dist/ai/providers/rtzr/options.js +2 -3
- package/dist/ai/providers/rtzr/provider.js +2 -3
- package/dist/ai/providers/rtzr/utils.js +12 -21
- package/dist/api/base-frame.js +4 -4
- package/dist/api/caster.js +21 -38
- package/dist/api/code-converters.js +41 -98
- package/dist/api/config.d.ts +1 -10
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +9 -8
- package/dist/api/context.js +2 -3
- package/dist/api/decorators.js +80 -116
- package/dist/api/index.js +2 -3
- package/dist/api/secret.js +6 -10
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +200 -387
- package/dist/api/validator.js +5 -8
- package/dist/api/websocket-helpers.js +21 -32
- package/dist/auth/audit-log/builders.js +2 -3
- package/dist/auth/audit-log/events.js +2 -2
- package/dist/auth/audit-log/plugin.js +30 -61
- package/dist/auth/audit-log-ingestor.js +19 -41
- package/dist/auth/auth-generator.js +16 -41
- package/dist/auth/better-auth-entities.js +3 -4
- package/dist/auth/index.js +2 -3
- package/dist/auth/knex-adapter.js +18 -45
- package/dist/auth/plugins/entity-definitions/admin.js +2 -2
- package/dist/auth/plugins/entity-definitions/anonymous.js +2 -2
- package/dist/auth/plugins/entity-definitions/api-key.js +2 -2
- package/dist/auth/plugins/entity-definitions/audit-log.js +2 -2
- package/dist/auth/plugins/entity-definitions/index.js +2 -3
- package/dist/auth/plugins/entity-definitions/jwt.js +2 -2
- package/dist/auth/plugins/entity-definitions/organization.js +2 -2
- package/dist/auth/plugins/entity-definitions/passkey.js +2 -2
- package/dist/auth/plugins/entity-definitions/phone-number.js +2 -2
- package/dist/auth/plugins/entity-definitions/sso.js +2 -2
- package/dist/auth/plugins/entity-definitions/two-factor.js +2 -2
- package/dist/auth/plugins/entity-definitions/types.js +1 -1
- package/dist/auth/plugins/entity-definitions/username.js +2 -2
- package/dist/auth/plugins/index.js +1 -2
- package/dist/auth/plugins/wrappers/admin.js +2 -3
- package/dist/auth/plugins/wrappers/anonymous.js +2 -3
- package/dist/auth/plugins/wrappers/api-key.js +2 -3
- package/dist/auth/plugins/wrappers/index.js +1 -2
- package/dist/auth/plugins/wrappers/jwt.js +2 -3
- package/dist/auth/plugins/wrappers/organization.js +2 -3
- package/dist/auth/plugins/wrappers/passkey.js +2 -3
- package/dist/auth/plugins/wrappers/phone-number.js +2 -3
- package/dist/auth/plugins/wrappers/sso.js +2 -3
- package/dist/auth/plugins/wrappers/two-factor.js +2 -3
- package/dist/auth/plugins/wrappers/username.js +2 -3
- package/dist/bin/build-config.js +2 -2
- package/dist/bin/cli.js +151 -258
- package/dist/bin/fixture.d.ts.map +1 -1
- package/dist/bin/fixture.js +55 -97
- package/dist/bin/hmr-hook-register.js +3 -3
- package/dist/bin/migrate-targets.d.ts +3 -0
- package/dist/bin/migrate-targets.d.ts.map +1 -0
- package/dist/bin/migrate-targets.js +11 -0
- package/dist/bin/test-command.js +25 -55
- package/dist/bin/ts-loader-register.js +5 -6
- package/dist/bin/ts-loader-registration.js +6 -13
- package/dist/cache/cache-manager.js +3 -4
- package/dist/cache/decorator.js +11 -21
- package/dist/cache/drivers.js +2 -3
- package/dist/cache/index.js +2 -3
- package/dist/cache/types.js +1 -1
- package/dist/cache-control/cache-control.js +21 -34
- package/dist/cache-control/types.js +1 -1
- package/dist/compress/compress.js +10 -10
- package/dist/compress/index.js +1 -2
- package/dist/compress/types.js +1 -1
- package/dist/cone/cone-generator.js +25 -63
- package/dist/database/_batch_update.js +26 -46
- package/dist/database/base-model.js +44 -97
- package/dist/database/base-model.types.js +1 -1
- package/dist/database/db.d.ts +8 -14
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +127 -72
- package/dist/database/knex.js +5 -8
- package/dist/database/puri-subset.types.js +1 -1
- package/dist/database/puri-wrapper.js +11 -15
- package/dist/database/puri.js +117 -234
- package/dist/database/puri.types.js +3 -4
- package/dist/database/transaction-context.js +4 -5
- package/dist/database/upsert-builder.js +109 -176
- package/dist/dict/en.d.ts +1 -0
- package/dist/dict/en.d.ts.map +1 -1
- package/dist/dict/en.js +4 -4
- package/dist/dict/index.js +2 -3
- package/dist/dict/ko.d.ts +1 -0
- package/dist/dict/ko.d.ts.map +1 -1
- package/dist/dict/ko.js +4 -4
- package/dist/dict/rc-keys.js +3 -4
- package/dist/dict/sd.js +8 -19
- package/dist/dict/sonamu-dictionary.js +141 -284
- package/dist/dict/types.js +1 -1
- package/dist/dict/utils.js +4 -5
- package/dist/entity/entity-manager.d.ts +2 -2
- package/dist/entity/entity-manager.js +34 -82
- package/dist/entity/entity-template-cone.js +33 -66
- package/dist/entity/entity.js +156 -310
- package/dist/env.d.ts +14 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +75 -0
- package/dist/exceptions/error-handler.js +2 -3
- package/dist/exceptions/so-exceptions.js +7 -5
- package/dist/filter/index.js +1 -2
- package/dist/filter/types.js +3 -4
- package/dist/filter/utils.js +21 -54
- package/dist/index.js +8 -7
- package/dist/logger/category.js +6 -12
- package/dist/logger/configure.js +23 -34
- package/dist/migration/code-generation.js +146 -314
- package/dist/migration/index-where-predicate.js +52 -144
- package/dist/migration/migration-set.js +19 -33
- package/dist/migration/migrator.d.ts +2 -0
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +69 -53
- package/dist/migration/postgresql-schema-reader.js +126 -225
- package/dist/migration/slack-confirm.d.ts +1 -0
- package/dist/migration/slack-confirm.d.ts.map +1 -1
- package/dist/migration/slack-confirm.js +28 -38
- package/dist/migration/types.js +1 -1
- package/dist/naite/messaging-types.js +1 -1
- package/dist/naite/naite-reporter.js +15 -32
- package/dist/naite/naite.js +43 -76
- package/dist/ssr/index.js +6 -9
- package/dist/ssr/registry.js +10 -18
- package/dist/ssr/renderer.js +10 -21
- package/dist/ssr/types.js +1 -1
- package/dist/storage/base-file.js +5 -10
- package/dist/storage/buffered-file.js +3 -4
- package/dist/storage/drivers.js +2 -3
- package/dist/storage/index.js +2 -3
- package/dist/storage/s3-driver.js +5 -9
- package/dist/storage/storage-manager.js +5 -5
- package/dist/storage/types.js +1 -1
- package/dist/storage/uploaded-file.js +4 -6
- package/dist/stream/index.js +1 -2
- package/dist/stream/sse.js +8 -13
- package/dist/stream/ws-audience-resolver.js +5 -5
- package/dist/stream/ws-audience.js +3 -4
- package/dist/stream/ws-cluster-bus.js +3 -4
- package/dist/stream/ws-core.js +1 -1
- package/dist/stream/ws-delivery.js +11 -25
- package/dist/stream/ws-local-connection-store.js +9 -18
- package/dist/stream/ws-presence-store.js +43 -97
- package/dist/stream/ws-registry.js +17 -22
- package/dist/stream/ws-telemetry-memory.js +38 -45
- package/dist/stream/ws-telemetry-trace.js +4 -6
- package/dist/stream/ws-telemetry.js +82 -135
- package/dist/stream/ws.js +47 -91
- package/dist/syncer/api-parser.js +81 -147
- package/dist/syncer/checksum.js +9 -20
- package/dist/syncer/code-generator.js +29 -47
- package/dist/syncer/entity-operations.js +17 -27
- package/dist/syncer/event-batcher.js +8 -15
- package/dist/syncer/file-patterns.js +3 -4
- package/dist/syncer/file-tracking.js +6 -10
- package/dist/syncer/index.js +1 -2
- package/dist/syncer/module-loader.js +10 -26
- package/dist/syncer/syncer-actions.js +19 -37
- package/dist/syncer/syncer.js +46 -98
- package/dist/syncer/watcher.js +12 -26
- package/dist/tasks/decorator.js +7 -11
- package/dist/tasks/step-wrapper.js +7 -8
- package/dist/tasks/workflow-manager.js +18 -25
- package/dist/template/entity-converter.js +40 -64
- package/dist/template/helpers.js +32 -63
- package/dist/template/implementations/entity.template.js +7 -11
- package/dist/template/implementations/entry-server.template.js +2 -3
- package/dist/template/implementations/generated.template.js +25 -51
- package/dist/template/implementations/generated_http.template.js +31 -58
- package/dist/template/implementations/generated_sso.template.js +45 -85
- package/dist/template/implementations/init_types.template.js +4 -7
- package/dist/template/implementations/model.template.js +5 -10
- package/dist/template/implementations/model_test.template.js +2 -3
- package/dist/template/implementations/queries.template.js +4 -7
- package/dist/template/implementations/sd.template.js +17 -35
- package/dist/template/implementations/services.template.js +18 -30
- package/dist/template/implementations/view_form.template.js +72 -125
- package/dist/template/implementations/view_id_all_select.template.js +2 -3
- package/dist/template/implementations/view_list.template.js +86 -143
- package/dist/template/implementations/view_search_input.template.js +2 -3
- package/dist/template/index.js +5 -8
- package/dist/template/template-manager.js +13 -26
- package/dist/template/template-types.js +2 -3
- package/dist/template/template.js +7 -11
- package/dist/template/zod-converter.js +173 -348
- package/dist/testing/_relation-graph.js +18 -37
- package/dist/testing/bootstrap.js +5 -8
- package/dist/testing/data-explorer.js +34 -78
- package/dist/testing/dev-test-routes.js +54 -60
- package/dist/testing/dev-vitest-manager.js +33 -84
- package/dist/testing/faker-mappings.js +3 -4
- package/dist/testing/fixture-generator.d.ts +2 -1
- package/dist/testing/fixture-generator.d.ts.map +1 -1
- package/dist/testing/fixture-generator.js +159 -321
- package/dist/testing/fixture-loader.js +2 -2
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +124 -227
- package/dist/testing/global-setup.d.ts.map +1 -1
- package/dist/testing/global-setup.js +29 -17
- package/dist/testing/index.js +1 -2
- package/dist/testing/naite-vitest-reporter.js +2 -3
- package/dist/testing/parallel-db-manager.js +5 -3
- package/dist/testing/vitest-helpers.d.ts.map +1 -1
- package/dist/testing/vitest-helpers.js +15 -12
- package/dist/types/types.d.ts +14 -14
- package/dist/types/types.js +27 -50
- package/dist/ui/ai-api.js +6 -11
- package/dist/ui/ai-client.js +86 -134
- package/dist/ui/api.js +99 -195
- package/dist/ui/cdd-service.js +78 -130
- package/dist/ui/cdd-types.js +1 -1
- package/dist/ui-web/assets/{index-Df8q-fhb.js → index-DFStGyd0.js} +49 -49
- package/dist/ui-web/assets/index-Dx4ap5i4.css +1 -0
- package/dist/ui-web/index.html +2 -2
- package/dist/utils/async-utils.js +13 -25
- package/dist/utils/class-name.js +3 -4
- package/dist/utils/console-util.js +11 -26
- package/dist/utils/controller.d.ts.map +1 -1
- package/dist/utils/controller.js +14 -12
- package/dist/utils/esm-utils.js +5 -8
- package/dist/utils/formatter.js +10 -22
- package/dist/utils/fs-utils.js +14 -25
- package/dist/utils/lodash-able.js +3 -4
- package/dist/utils/model.js +7 -14
- package/dist/utils/object-utils.js +41 -73
- package/dist/utils/path-utils.js +5 -9
- package/dist/utils/process-utils.js +4 -7
- package/dist/utils/sql-parser.js +6 -13
- package/dist/utils/type-utils.js +16 -26
- package/dist/utils/utils.js +18 -40
- package/dist/utils/zod-error.js +9 -16
- package/dist/vector/chunking.js +24 -37
- package/dist/vector/config.js +2 -2
- package/dist/vector/embedding.js +8 -19
- package/dist/vector/index.js +1 -2
- package/dist/vector/types.js +1 -1
- package/package.json +7 -7
- package/src/__tests__/env.test.ts +127 -0
- package/src/api/__tests__/config.test.ts +10 -1
- package/src/api/config.ts +4 -12
- package/src/api/sonamu.ts +14 -4
- package/src/bin/__tests__/migrate-targets.test.ts +28 -0
- package/src/bin/__tests__/test-command.test.ts +82 -1
- package/src/bin/cli.ts +9 -18
- package/src/bin/fixture.ts +5 -4
- package/src/bin/migrate-targets.ts +7 -0
- package/src/bin/test-command.ts +2 -2
- package/src/database/__tests__/db.test.ts +175 -0
- package/src/database/db.ts +193 -71
- package/src/dict/en.ts +2 -0
- package/src/dict/ko.ts +2 -0
- package/src/env.ts +123 -0
- package/src/migration/__tests__/migrator.test.ts +149 -0
- package/src/migration/migrator.ts +74 -17
- package/src/migration/slack-confirm.ts +21 -0
- package/src/skills/sonamu/database.md +1 -1
- package/src/skills/sonamu/entity-basic.md +31 -0
- package/src/skills/sonamu/puri.md +22 -0
- package/src/skills/sonamu/testing-devrunner.md +1 -1
- package/src/skills/sonamu/upsert.md +53 -6
- package/src/stream/ws-telemetry-memory.ts +2 -2
- package/src/testing/fixture-generator.ts +2 -1
- package/src/testing/fixture-manager.ts +3 -4
- package/src/testing/global-setup.ts +42 -18
- package/src/testing/vitest-helpers.ts +14 -0
- package/src/utils/controller.ts +14 -7
- package/tsdown.api.config.ts +6 -0
- package/dist/_virtual/rolldown_runtime.js +0 -39
- package/dist/ui-web/assets/index-D4rYm-Xz.css +0 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { __esmMin } from "../_virtual/
|
|
2
|
-
|
|
1
|
+
import { __esmMin } from "../_virtual/_rolldown/runtime.js";
|
|
3
2
|
//#region src/compress/compress.ts
|
|
4
3
|
/**
|
|
5
4
|
* CompressConfig가 비활성화 상태인지 확인합니다.
|
|
@@ -18,18 +17,16 @@ function isCompressDisabled(config) {
|
|
|
18
17
|
* @param defaultOptions 전역 compress 설정 (true일 때 사용)
|
|
19
18
|
*/
|
|
20
19
|
function toFastifyCompressOption(config, defaultOptions) {
|
|
21
|
-
if (config ===
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
if (config === true) {
|
|
25
|
-
return defaultOptions ?? {};
|
|
26
|
-
}
|
|
20
|
+
if (config === void 0) return;
|
|
21
|
+
if (config === true) return defaultOptions ?? {};
|
|
27
22
|
return config;
|
|
28
23
|
}
|
|
29
24
|
var CompressPresets;
|
|
30
25
|
var init_compress = __esmMin((() => {
|
|
31
26
|
CompressPresets = {
|
|
27
|
+
/** 압축 비활성화 */
|
|
32
28
|
disabled: false,
|
|
29
|
+
/** 기본 설정 (threshold: 1024, br > gzip > deflate) */
|
|
33
30
|
default: {
|
|
34
31
|
threshold: 1024,
|
|
35
32
|
encodings: [
|
|
@@ -38,6 +35,7 @@ var init_compress = __esmMin((() => {
|
|
|
38
35
|
"deflate"
|
|
39
36
|
]
|
|
40
37
|
},
|
|
38
|
+
/** 적극적 압축 (threshold: 256) */
|
|
41
39
|
aggressive: {
|
|
42
40
|
threshold: 256,
|
|
43
41
|
encodings: [
|
|
@@ -46,18 +44,20 @@ var init_compress = __esmMin((() => {
|
|
|
46
44
|
"deflate"
|
|
47
45
|
]
|
|
48
46
|
},
|
|
47
|
+
/** 보수적 압축 (threshold: 4096, gzip만) */
|
|
49
48
|
conservative: {
|
|
50
49
|
threshold: 4096,
|
|
51
50
|
encodings: ["gzip", "deflate"]
|
|
52
51
|
},
|
|
52
|
+
/** gzip만 사용 */
|
|
53
53
|
gzipOnly: {
|
|
54
54
|
threshold: 1024,
|
|
55
55
|
encodings: ["gzip"]
|
|
56
56
|
}
|
|
57
57
|
};
|
|
58
58
|
}));
|
|
59
|
-
|
|
60
59
|
//#endregion
|
|
61
60
|
init_compress();
|
|
62
61
|
export { CompressPresets, init_compress, isCompressDisabled, toFastifyCompressOption };
|
|
63
|
-
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcHJlc3MuanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbXByZXNzL2NvbXByZXNzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHR5cGUgQ29tcHJlc3NDb25maWcsIHR5cGUgQ29tcHJlc3NPcHRpb25zIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiDslZXstpUg7ZSE66as7IWL7J6F64uI64ukLlxuICog7J2867CY7KCB7J24IOyCrOyaqSDsgqzroYDsl5Ag66ee64qUIOuvuOumrCDsoJXsnZjrkJwg7ISk7KCV7J2EIOygnOqzte2VqeuLiOuLpC5cbiAqL1xuZXhwb3J0IGNvbnN0IENvbXByZXNzUHJlc2V0cyA9IHtcbiAgLyoqIOyVley2lSDruYTtmZzshLHtmZQgKi9cbiAgZGlzYWJsZWQ6IGZhbHNlIGFzIGNvbnN0LFxuICAvKiog6riw67O4IOyEpOyglSAodGhyZXNob2xkOiAxMDI0LCBiciA+IGd6aXAgPiBkZWZsYXRlKSAqL1xuICBkZWZhdWx0OiB7XG4gICAgdGhyZXNob2xkOiAxMDI0LFxuICAgIGVuY29kaW5nczogW1wiYnJcIiwgXCJnemlwXCIsIFwiZGVmbGF0ZVwiXSBhcyAoXCJiclwiIHwgXCJnemlwXCIgfCBcImRlZmxhdGVcIilbXSxcbiAgfSxcbiAgLyoqIOyggeq3ueyggSDslZXstpUgKHRocmVzaG9sZDogMjU2KSAqL1xuICBhZ2dyZXNzaXZlOiB7XG4gICAgdGhyZXNob2xkOiAyNTYsXG4gICAgZW5jb2RpbmdzOiBbXCJiclwiLCBcImd6aXBcIiwgXCJkZWZsYXRlXCJdIGFzIChcImJyXCIgfCBcImd6aXBcIiB8IFwiZGVmbGF0ZVwiKVtdLFxuICB9LFxuICAvKiog67O07IiY7KCBIOyVley2lSAodGhyZXNob2xkOiA0MDk2LCBnemlw66eMKSAqL1xuICBjb25zZXJ2YXRpdmU6IHtcbiAgICB0aHJlc2hvbGQ6IDQwOTYsXG4gICAgZW5jb2RpbmdzOiBbXCJnemlwXCIsIFwiZGVmbGF0ZVwiXSBhcyAoXCJnemlwXCIgfCBcImRlZmxhdGVcIilbXSxcbiAgfSxcbiAgLyoqIGd6aXDrp4wg7IKs7JqpICovXG4gIGd6aXBPbmx5OiB7XG4gICAgdGhyZXNob2xkOiAxMDI0LFxuICAgIGVuY29kaW5nczogW1wiZ3ppcFwiXSBhcyBbXCJnemlwXCJdLFxuICB9LFxufSBhcyBjb25zdDtcblxuLyoqXG4gKiBDb21wcmVzc0NvbmZpZ+qwgCDruYTtmZzshLHtmZQg7IOB7YOc7J247KeAIO2ZleyduO2VqeuLiOuLpC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQ29tcHJlc3NEaXNhYmxlZChjb25maWc6IENvbXByZXNzQ29uZmlnIHwgdW5kZWZpbmVkKTogY29uZmlnIGlzIGZhbHNlIHtcbiAgcmV0dXJuIGNvbmZpZyA9PT0gZmFsc2U7XG59XG5cbi8qKlxuICogQ29tcHJlc3NDb25maWfrpbwgRmFzdGlmeSByb3V0ZSBjb21wcmVzcyDsmLXshZjsnLzroZwg67OA7ZmY7ZWp64uI64ukLlxuICogLSB1bmRlZmluZWQ6IOyghOyXrSDshKTsoJUg65Sw66aEXG4gKiAtIHRydWU6IOyVley2lSDtmZzshLHtmZQgKGdsb2JhbDogZmFsc2Xsnbwg65WMIO2VtOuLuSDrnbzsmrDtirjrp4wg7JWV7LaVKSDihpIg7KCE7JetIOyEpOyglSDsgqzsmqlcbiAqIC0gZmFsc2U6IOu5hO2ZnOyEse2ZlFxuICogLSBDb21wcmVzc09wdGlvbnM6IOyEuOu2gCDsmLXshZhcbiAqXG4gKiBAcGFyYW0gY29uZmlnIOudvOyasO2KuOuzhCBjb21wcmVzcyDshKTsoJVcbiAqIEBwYXJhbSBkZWZhdWx0T3B0aW9ucyDsoITsl60gY29tcHJlc3Mg7ISk7KCVICh0cnVl7J28IOuVjCDsgqzsmqkpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0Zhc3RpZnlDb21wcmVzc09wdGlvbihcbiAgY29uZmlnOiBDb21wcmVzc0NvbmZpZyB8IHVuZGVmaW5lZCxcbiAgZGVmYXVsdE9wdGlvbnM/OiBDb21wcmVzc09wdGlvbnMsXG4pOiBmYWxzZSB8IENvbXByZXNzT3B0aW9ucyB8IHVuZGVmaW5lZCB7XG4gIGlmIChjb25maWcgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKGNvbmZpZyA9PT0gdHJ1ZSkge1xuICAgIC8vIHRydWXripQg7KCE7JetIOyEpOygleycvOuhnCDslZXstpUg7Zmc7ISx7ZmUIChnbG9iYWw6IGZhbHNl7J28IOuVjCDtlbTri7kg65287Jqw7Yq466eMIOyVley2lSlcbiAgICByZXR1cm4gZGVmYXVsdE9wdGlvbnMgPz8ge307XG4gIH1cbiAgcmV0dXJuIGNvbmZpZztcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFrQ0EsU0FBZ0IsbUJBQW1CLFFBQXFEO0NBQ3RGLE9BQU8sV0FBVztBQUNwQjs7Ozs7Ozs7Ozs7QUFZQSxTQUFnQix3QkFDZCxRQUNBLGdCQUNxQztDQUNyQyxJQUFJLFdBQVcsUUFDYjtDQUVGLElBQUksV0FBVyxNQUViLE9BQU8sa0JBQWtCLENBQUM7Q0FFNUIsT0FBTztBQUNUOzs7Q0F0RGEsa0JBQWtCOztFQUU3QixVQUFVOztFQUVWLFNBQVM7R0FDUCxXQUFXO0dBQ1gsV0FBVztJQUFDO0lBQU07SUFBUTtHQUFTO0VBQ3JDOztFQUVBLFlBQVk7R0FDVixXQUFXO0dBQ1gsV0FBVztJQUFDO0lBQU07SUFBUTtHQUFTO0VBQ3JDOztFQUVBLGNBQWM7R0FDWixXQUFXO0dBQ1gsV0FBVyxDQUFDLFFBQVEsU0FBUztFQUMvQjs7RUFFQSxVQUFVO0dBQ1IsV0FBVztHQUNYLFdBQVcsQ0FBQyxNQUFNO0VBQ3BCO0NBQ0YifQ==
|
package/dist/compress/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { CompressPresets, init_compress, isCompressDisabled, toFastifyCompressOption } from "./compress.js";
|
|
2
|
-
|
|
3
2
|
//#region src/compress/index.ts
|
|
4
3
|
init_compress();
|
|
5
|
-
|
|
6
4
|
//#endregion
|
|
7
5
|
export { CompressPresets, isCompressDisabled, toFastifyCompressOption };
|
|
6
|
+
|
|
8
7
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbXByZXNzL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gXCIuL2NvbXByZXNzXCI7XG5leHBvcnQgdHlwZSAqIGZyb20gXCIuL3R5cGVzXCI7XG4iXSwibWFwcGluZ3MiOiIifQ==
|
package/dist/compress/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { __esmMin, __toCommonJS } from "../_virtual/
|
|
1
|
+
import { __esmMin, __toCommonJS } from "../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { api_exports, init_api } from "../api/index.js";
|
|
3
3
|
import * as path$1 from "node:path";
|
|
4
4
|
import * as fs$1 from "node:fs";
|
|
5
|
-
|
|
6
5
|
//#region src/cone/cone-generator.ts
|
|
7
6
|
/**
|
|
8
7
|
* LLM을 사용하여 Entity의 cone 메타데이터를 생성합니다.
|
|
@@ -12,14 +11,11 @@ import * as fs$1 from "node:fs";
|
|
|
12
11
|
*/
|
|
13
12
|
async function generateCones(context) {
|
|
14
13
|
const apiKey = getApiKey();
|
|
15
|
-
const
|
|
16
|
-
const { text: responseText, tokensUsed } = await callAnthropicAPI(prompt, apiKey);
|
|
14
|
+
const { text: responseText, tokensUsed } = await callAnthropicAPI(buildPrompt(context), apiKey);
|
|
17
15
|
const result = parseConeResponse(responseText);
|
|
18
16
|
result.tokensUsed = tokensUsed;
|
|
19
17
|
if (context.existingCones) {
|
|
20
|
-
if (context.onlyEmpty)
|
|
21
|
-
return mergeOnlyEmpty(result, context.existingCones);
|
|
22
|
-
}
|
|
18
|
+
if (context.onlyEmpty) return mergeOnlyEmpty(result, context.existingCones);
|
|
23
19
|
return mergeWithExisting(result, context.existingCones);
|
|
24
20
|
}
|
|
25
21
|
return result;
|
|
@@ -35,14 +31,10 @@ function getApiKey() {
|
|
|
35
31
|
const { Sonamu } = (init_api(), __toCommonJS(api_exports));
|
|
36
32
|
apiKey = Sonamu.secrets?.anthropic_api_key;
|
|
37
33
|
} catch {
|
|
38
|
-
apiKey =
|
|
39
|
-
}
|
|
40
|
-
if (!apiKey) {
|
|
41
|
-
apiKey = process.env.ANTHROPIC_API_KEY;
|
|
42
|
-
}
|
|
43
|
-
if (!apiKey) {
|
|
44
|
-
throw new Error("ANTHROPIC_API_KEY not found. " + "Set ANTHROPIC_API_KEY environment variable or add it to sonamu.secret.ts");
|
|
34
|
+
apiKey = void 0;
|
|
45
35
|
}
|
|
36
|
+
if (!apiKey) apiKey = process.env.ANTHROPIC_API_KEY;
|
|
37
|
+
if (!apiKey) throw new Error("ANTHROPIC_API_KEY not found. Set ANTHROPIC_API_KEY environment variable or add it to sonamu.secret.ts");
|
|
46
38
|
return apiKey;
|
|
47
39
|
}
|
|
48
40
|
/**
|
|
@@ -67,18 +59,14 @@ function readProjectSkills() {
|
|
|
67
59
|
for (const file of contractFiles) {
|
|
68
60
|
const filePath = path$1.join(domainDir, file);
|
|
69
61
|
const content = fs$1.readFileSync(filePath, "utf-8").trim();
|
|
70
|
-
if (content) {
|
|
71
|
-
contents.push(`--- contract/${domain}/${file} ---\n${content}`);
|
|
72
|
-
}
|
|
62
|
+
if (content) contents.push(`--- contract/${domain}/${file} ---\n${content}`);
|
|
73
63
|
}
|
|
74
64
|
}
|
|
75
65
|
}
|
|
76
66
|
const architecturePath = path$1.join(projectRoot, ".claude", "skills", "project", "architecture.md");
|
|
77
67
|
if (fs$1.existsSync(architecturePath)) {
|
|
78
68
|
const content = fs$1.readFileSync(architecturePath, "utf-8").trim();
|
|
79
|
-
if (content) {
|
|
80
|
-
contents.push(`--- architecture.md ---\n${content}`);
|
|
81
|
-
}
|
|
69
|
+
if (content) contents.push(`--- architecture.md ---\n${content}`);
|
|
82
70
|
}
|
|
83
71
|
return contents.join("\n\n");
|
|
84
72
|
} catch {
|
|
@@ -98,14 +86,13 @@ function buildPrompt(context) {
|
|
|
98
86
|
ja: "Japanese"
|
|
99
87
|
}[locale];
|
|
100
88
|
const projectContext = readProjectSkills();
|
|
101
|
-
const projectSection = projectContext ? `\nPROJECT CONTEXT (business requirements and domain knowledge):\n${projectContext}\n\nUse the above project context to understand the business domain, entity purposes, field meanings, and relationships. Generate cone metadata that reflects this project's actual requirements, not generic assumptions.\n` : "";
|
|
102
89
|
return `You are a Sonamu framework expert. Generate cone metadata for database entity fixture generation.
|
|
103
90
|
|
|
104
91
|
CRITICAL PRIORITY RULE:
|
|
105
92
|
The "note" field is the PRIMARY source for fixture data generation. When --use-llm is enabled, the fixture generator reads cone.note and asks LLM to generate contextually appropriate data BEFORE falling back to fixtureGenerator.
|
|
106
93
|
Therefore, cone.note must always contain rich, domain-specific descriptions with concrete examples and value ranges.
|
|
107
94
|
fixtureGenerator is only a FALLBACK for when LLM is unavailable (no API key). Write it as a best-effort approximation, but never rely on it as the primary generation method.
|
|
108
|
-
${
|
|
95
|
+
${projectContext ? `\nPROJECT CONTEXT (business requirements and domain knowledge):\n${projectContext}\n\nUse the above project context to understand the business domain, entity purposes, field meanings, and relationships. Generate cone metadata that reflects this project's actual requirements, not generic assumptions.\n` : ""}
|
|
109
96
|
ENTITY STRUCTURE:
|
|
110
97
|
${JSON.stringify(context.entity, null, 2)}
|
|
111
98
|
|
|
@@ -218,25 +205,19 @@ async function callAnthropicAPI(prompt, apiKey) {
|
|
|
218
205
|
try {
|
|
219
206
|
const { createAnthropic } = await import("@ai-sdk/anthropic");
|
|
220
207
|
const { generateText } = await import("ai");
|
|
221
|
-
const anthropic = createAnthropic({ apiKey });
|
|
222
208
|
const { text, usage } = await generateText({
|
|
223
|
-
model:
|
|
209
|
+
model: createAnthropic({ apiKey })("claude-sonnet-4-6"),
|
|
224
210
|
prompt
|
|
225
211
|
});
|
|
226
212
|
const tokensUsed = usage?.totalTokens || 0;
|
|
227
|
-
if (usage) {
|
|
228
|
-
console.log(`[Cone Generator] Tokens used: ${tokensUsed}`);
|
|
229
|
-
}
|
|
213
|
+
if (usage) console.log(`[Cone Generator] Tokens used: ${tokensUsed}`);
|
|
230
214
|
return {
|
|
231
215
|
text,
|
|
232
216
|
tokensUsed
|
|
233
217
|
};
|
|
234
218
|
} catch (error) {
|
|
235
219
|
if (error && typeof error === "object" && "statusCode" in error) {
|
|
236
|
-
|
|
237
|
-
if (statusCode === 429) {
|
|
238
|
-
throw new Error("Rate limit exceeded. Please try again later.", { cause: error });
|
|
239
|
-
}
|
|
220
|
+
if (error.statusCode === 429) throw new Error("Rate limit exceeded. Please try again later.", { cause: error });
|
|
240
221
|
}
|
|
241
222
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
242
223
|
throw new Error(`LLM API failed: ${message}`, { cause: error });
|
|
@@ -254,9 +235,7 @@ function parseConeResponse(text) {
|
|
|
254
235
|
jsonText = jsonText.trim();
|
|
255
236
|
try {
|
|
256
237
|
const parsed = JSON.parse(jsonText);
|
|
257
|
-
if (!parsed.propCones || typeof parsed.propCones !== "object")
|
|
258
|
-
throw new Error("Invalid response: propCones is required and must be an object");
|
|
259
|
-
}
|
|
238
|
+
if (!parsed.propCones || typeof parsed.propCones !== "object") throw new Error("Invalid response: propCones is required and must be an object");
|
|
260
239
|
return {
|
|
261
240
|
entityCone: parsed.entityCone,
|
|
262
241
|
propCones: parsed.propCones,
|
|
@@ -266,7 +245,7 @@ function parseConeResponse(text) {
|
|
|
266
245
|
};
|
|
267
246
|
} catch (error) {
|
|
268
247
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
269
|
-
throw new Error(`Failed to parse LLM response: ${message}\n\
|
|
248
|
+
throw new Error(`Failed to parse LLM response: ${message}\n\nOriginal response:\n${text}\n\nCleaned JSON:\n${jsonText}`, { cause: error });
|
|
270
249
|
}
|
|
271
250
|
}
|
|
272
251
|
/**
|
|
@@ -277,26 +256,18 @@ function parseConeResponse(text) {
|
|
|
277
256
|
function mergeWithExisting(generated, existing) {
|
|
278
257
|
const result = { ...generated };
|
|
279
258
|
const entityKey = `entity:${generated.entityCone ? "present" : "missing"}`;
|
|
280
|
-
if (existing[entityKey])
|
|
281
|
-
result.entityCone = existing[entityKey];
|
|
282
|
-
}
|
|
259
|
+
if (existing[entityKey]) result.entityCone = existing[entityKey];
|
|
283
260
|
for (const propName of Object.keys(generated.propCones)) {
|
|
284
261
|
const key = `prop:${propName}`;
|
|
285
|
-
if (existing[key])
|
|
286
|
-
result.propCones[propName] = existing[key];
|
|
287
|
-
}
|
|
262
|
+
if (existing[key]) result.propCones[propName] = existing[key];
|
|
288
263
|
}
|
|
289
264
|
for (const enumId of Object.keys(generated.enumCones)) {
|
|
290
265
|
const key = `enum:${enumId}`;
|
|
291
|
-
if (existing[key])
|
|
292
|
-
result.enumCones[enumId] = existing[key];
|
|
293
|
-
}
|
|
266
|
+
if (existing[key]) result.enumCones[enumId] = existing[key];
|
|
294
267
|
}
|
|
295
268
|
for (const subsetKey of Object.keys(generated.subsetCones)) {
|
|
296
269
|
const key = `subset:${subsetKey}`;
|
|
297
|
-
if (existing[key])
|
|
298
|
-
result.subsetCones[subsetKey] = existing[key];
|
|
299
|
-
}
|
|
270
|
+
if (existing[key]) result.subsetCones[subsetKey] = existing[key];
|
|
300
271
|
}
|
|
301
272
|
return result;
|
|
302
273
|
}
|
|
@@ -308,32 +279,23 @@ function mergeWithExisting(generated, existing) {
|
|
|
308
279
|
function mergeOnlyEmpty(generated, existing) {
|
|
309
280
|
const result = { ...generated };
|
|
310
281
|
const entityKey = `entity:${generated.entityCone ? "present" : "missing"}`;
|
|
311
|
-
if (existing[entityKey]?.note)
|
|
312
|
-
result.entityCone = existing[entityKey];
|
|
313
|
-
}
|
|
282
|
+
if (existing[entityKey]?.note) result.entityCone = existing[entityKey];
|
|
314
283
|
for (const propName of Object.keys(generated.propCones)) {
|
|
315
284
|
const key = `prop:${propName}`;
|
|
316
|
-
if (existing[key]?.note)
|
|
317
|
-
result.propCones[propName] = existing[key];
|
|
318
|
-
}
|
|
285
|
+
if (existing[key]?.note) result.propCones[propName] = existing[key];
|
|
319
286
|
}
|
|
320
287
|
for (const enumId of Object.keys(generated.enumCones)) {
|
|
321
288
|
const key = `enum:${enumId}`;
|
|
322
|
-
if (existing[key]?.note)
|
|
323
|
-
result.enumCones[enumId] = existing[key];
|
|
324
|
-
}
|
|
289
|
+
if (existing[key]?.note) result.enumCones[enumId] = existing[key];
|
|
325
290
|
}
|
|
326
291
|
for (const subsetKey of Object.keys(generated.subsetCones)) {
|
|
327
292
|
const key = `subset:${subsetKey}`;
|
|
328
|
-
if (existing[key]?.note)
|
|
329
|
-
result.subsetCones[subsetKey] = existing[key];
|
|
330
|
-
}
|
|
293
|
+
if (existing[key]?.note) result.subsetCones[subsetKey] = existing[key];
|
|
331
294
|
}
|
|
332
295
|
return result;
|
|
333
296
|
}
|
|
334
|
-
var init_cone_generator = __esmMin((() => {}));
|
|
335
|
-
|
|
336
297
|
//#endregion
|
|
337
|
-
|
|
298
|
+
__esmMin((() => {}))();
|
|
338
299
|
export { generateCones };
|
|
339
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZS1nZW5lcmF0b3IuanMiLCJuYW1lcyI6WyJhcGlLZXk6IHN0cmluZyB8IHVuZGVmaW5lZCIsImNvbnRlbnRzOiBzdHJpbmdbXSIsInBhdGgiLCJmcyIsImVycm9yOiB1bmtub3duIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmUvY29uZS1nZW5lcmF0b3IudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCAqIGFzIHBhdGggZnJvbSBcIm5vZGU6cGF0aFwiO1xuXG5pbXBvcnQgeyB0eXBlIENvbmUsIHR5cGUgRW50aXR5SnNvbiB9IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuXG4vKipcbiAqIENvbmUg7IOd7ISxIOy7qO2FjeyKpO2KuFxuICpcbiAqIEVudGl0eSDsoJXrs7TsmYAg7IOd7ISxIOyYteyFmOydhCDri7Tqs6Ag7J6I7Iq164uI64ukLlxuICovXG5leHBvcnQgdHlwZSBDb25lR2VuZXJhdGlvbkNvbnRleHQgPSB7XG4gIGVudGl0eTogRW50aXR5SnNvbjtcbiAgbG9jYWxlPzogXCJrb1wiIHwgXCJlblwiIHwgXCJqYVwiO1xuICBleGlzdGluZ0NvbmVzPzogUmVjb3JkPHN0cmluZywgQ29uZT47XG4gIC8qKiB0cnVl7J24IOqyveyasCBub3Rl6rCAIOyXhuuKlCBjb25l66eMIOyDneyEsSAqL1xuICBvbmx5RW1wdHk/OiBib29sZWFuO1xufTtcblxuLyoqXG4gKiBDb25lIOyDneyEsSDqsrDqs7xcbiAqXG4gKiBFbnRpdHksIFByb3BzLCBTdWJzZXRzLCBFbnVtc+ydmCBjb25lIOuplO2DgOuNsOydtO2EsOulvCDri7Tqs6Ag7J6I7Iq164uI64ukLlxuICovXG5leHBvcnQgdHlwZSBDb25lR2VuZXJhdGlvblJlc3VsdCA9IHtcbiAgZW50aXR5Q29uZT86IENvbmU7XG4gIHByb3BDb25lczogUmVjb3JkPHN0cmluZywgQ29uZT47XG4gIHN1YnNldENvbmVzOiBSZWNvcmQ8c3RyaW5nLCBDb25lPjtcbiAgZW51bUNvbmVzOiBSZWNvcmQ8c3RyaW5nLCBDb25lPjtcbiAgdG9rZW5zVXNlZDogbnVtYmVyO1xufTtcblxuLyoqXG4gKiBMTE3snYQg7IKs7Jqp7ZWY7JesIEVudGl0eeydmCBjb25lIOuplO2DgOuNsOydtO2EsOulvCDsg53shLHtlanri4jri6QuXG4gKlxuICogQHBhcmFtIGNvbnRleHQgLSBFbnRpdHkg7KCV67O07JmAIOyDneyEsSDsmLXshZhcbiAqIEByZXR1cm5zIOyDneyEseuQnCBjb25lIOuplO2DgOuNsOydtO2EsFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVDb25lcyhjb250ZXh0OiBDb25lR2VuZXJhdGlvbkNvbnRleHQpOiBQcm9taXNlPENvbmVHZW5lcmF0aW9uUmVzdWx0PiB7XG4gIGNvbnN0IGFwaUtleSA9IGdldEFwaUtleSgpO1xuICBjb25zdCBwcm9tcHQgPSBidWlsZFByb21wdChjb250ZXh0KTtcbiAgY29uc3QgeyB0ZXh0OiByZXNwb25zZVRleHQsIHRva2Vuc1VzZWQgfSA9IGF3YWl0IGNhbGxBbnRocm9waWNBUEkocHJvbXB0LCBhcGlLZXkpO1xuICBjb25zdCByZXN1bHQgPSBwYXJzZUNvbmVSZXNwb25zZShyZXNwb25zZVRleHQpO1xuICByZXN1bHQudG9rZW5zVXNlZCA9IHRva2Vuc1VzZWQ7XG5cbiAgaWYgKGNvbnRleHQuZXhpc3RpbmdDb25lcykge1xuICAgIGlmIChjb250ZXh0Lm9ubHlFbXB0eSkge1xuICAgICAgcmV0dXJuIG1lcmdlT25seUVtcHR5KHJlc3VsdCwgY29udGV4dC5leGlzdGluZ0NvbmVzKTtcbiAgICB9XG4gICAgcmV0dXJuIG1lcmdlV2l0aEV4aXN0aW5nKHJlc3VsdCwgY29udGV4dC5leGlzdGluZ0NvbmVzKTtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogQVBJIO2CpOulvCDqsIDsoLjsmLXri4jri6QuXG4gKlxuICogU29uYW11LnNlY3JldCDrmJDripQg7ZmY6rK967OA7IiY7JeQ7IScIOqwgOyguOyYteuLiOuLpC5cbiAqL1xuZnVuY3Rpb24gZ2V0QXBpS2V5KCk6IHN0cmluZyB7XG4gIC8vIFNvbmFtdS5zZWNyZXTsnYAg65+w7YOA7J6E7JeQIOuhnOuTnOuQmOuvgOuhnCDrj5nsoIHsnLzroZwgaW1wb3J0XG4gIGxldCBhcGlLZXk6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICB0cnkge1xuICAgIC8vIFNvbmFtdeqwgCDstIjquLDtmZTrkJjslrQg7J6I64qUIOqyveyasFxuICAgIGNvbnN0IHsgU29uYW11IH0gPSByZXF1aXJlKFwiLi4vYXBpXCIpO1xuICAgIGFwaUtleSA9IFNvbmFtdS5zZWNyZXRzPy5hbnRocm9waWNfYXBpX2tleTtcbiAgfSBjYXRjaCB7XG4gICAgLy8gU29uYW116rCAIOy0iOq4sO2ZlOuQmOyngCDslYrsnYAg6rK97JqwICjthYzsiqTtirgg65OxKVxuICAgIGFwaUtleSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGlmICghYXBpS2V5KSB7XG4gICAgYXBpS2V5ID0gcHJvY2Vzcy5lbnYuQU5USFJPUElDX0FQSV9LRVk7XG4gIH1cblxuICBpZiAoIWFwaUtleSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIFwiQU5USFJPUElDX0FQSV9LRVkgbm90IGZvdW5kLiBcIiArXG4gICAgICAgIFwiU2V0IEFOVEhST1BJQ19BUElfS0VZIGVudmlyb25tZW50IHZhcmlhYmxlIG9yIGFkZCBpdCB0byBzb25hbXUuc2VjcmV0LnRzXCIsXG4gICAgKTtcbiAgfVxuXG4gIHJldHVybiBhcGlLZXk7XG59XG5cbi8qKlxuICog64+E66mU7J2467OEIHtkb21haW59LmNvbnRyYWN0Lm1k7JmAIGFyY2hpdGVjdHVyZS5tZOulvCDsnb3slrQg7Luo7YWN7Iqk7Yq466GcIOuwmO2ZmO2VqeuLiOuLpC5cbiAqXG4gKiAtIGNvbnRyYWN0L3tkb21haW59L3tkb21haW59LmNvbnRyYWN0Lm1kOiDrj4TrqZTsnbgg6rec7LmZ6rO8IOqysOyglSDqt7zqsbAgKOyjvCDssLjsobAg64yA7IOBKVxuICogLSAuY2xhdWRlL3NraWxscy9wcm9qZWN0L2FyY2hpdGVjdHVyZS5tZDog7JeU7Yuw7YuwIOyEpOqzhCDqtazsobAgKOuztOyhsCDssLjsobApXG4gKlxuICogY29uZSDsg53shLEg7IucIExMTeyXkOqyjCDsoITri6ztlZjsl6wg64+E66mU7J24IOunpeudveyXkCDrp57ripQg66mU7YOA642w7J207YSw66W8IOyDneyEse2VmOuPhOuhnSDtlanri4jri6QuXG4gKi9cbmZ1bmN0aW9uIHJlYWRQcm9qZWN0U2tpbGxzKCk6IHN0cmluZyB7XG4gIHRyeSB7XG4gICAgY29uc3QgeyBTb25hbXUgfSA9IHJlcXVpcmUoXCIuLi9hcGlcIik7XG4gICAgY29uc3QgcHJvamVjdFJvb3QgPSBTb25hbXUuYXBwUm9vdFBhdGg7XG4gICAgY29uc3QgY29udGVudHM6IHN0cmluZ1tdID0gW107XG5cbiAgICAvLyBjb250cmFjdC8qKi8qLmNvbnRyYWN0Lm1kIOyImOynkVxuICAgIGNvbnN0IGNvbnRyYWN0RGlyID0gcGF0aC5qb2luKHByb2plY3RSb290LCBcImNvbnRyYWN0XCIpO1xuICAgIGlmIChmcy5leGlzdHNTeW5jKGNvbnRyYWN0RGlyKSkge1xuICAgICAgY29uc3QgZG9tYWlucyA9IGZzXG4gICAgICAgIC5yZWFkZGlyU3luYyhjb250cmFjdERpciwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pXG4gICAgICAgIC5maWx0ZXIoKGQpID0+IGQuaXNEaXJlY3RvcnkoKSlcbiAgICAgICAgLm1hcCgoZCkgPT4gZC5uYW1lKTtcblxuICAgICAgZm9yIChjb25zdCBkb21haW4gb2YgZG9tYWlucykge1xuICAgICAgICBjb25zdCBkb21haW5EaXIgPSBwYXRoLmpvaW4oY29udHJhY3REaXIsIGRvbWFpbik7XG4gICAgICAgIGNvbnN0IGNvbnRyYWN0RmlsZXMgPSBmc1xuICAgICAgICAgIC5yZWFkZGlyU3luYyhkb21haW5EaXIpXG4gICAgICAgICAgLmZpbHRlcigoZjogc3RyaW5nKSA9PiBmLmVuZHNXaXRoKFwiLmNvbnRyYWN0Lm1kXCIpKTtcblxuICAgICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgY29udHJhY3RGaWxlcykge1xuICAgICAgICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5qb2luKGRvbWFpbkRpciwgZmlsZSk7XG4gICAgICAgICAgY29uc3QgY29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgXCJ1dGYtOFwiKS50cmltKCk7XG4gICAgICAgICAgaWYgKGNvbnRlbnQpIHtcbiAgICAgICAgICAgIGNvbnRlbnRzLnB1c2goYC0tLSBjb250cmFjdC8ke2RvbWFpbn0vJHtmaWxlfSAtLS1cXG4ke2NvbnRlbnR9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gLmNsYXVkZS9za2lsbHMvcHJvamVjdC9hcmNoaXRlY3R1cmUubWQg67O07KGwIOywuOyhsFxuICAgIGNvbnN0IGFyY2hpdGVjdHVyZVBhdGggPSBwYXRoLmpvaW4oXG4gICAgICBwcm9qZWN0Um9vdCxcbiAgICAgIFwiLmNsYXVkZVwiLFxuICAgICAgXCJza2lsbHNcIixcbiAgICAgIFwicHJvamVjdFwiLFxuICAgICAgXCJhcmNoaXRlY3R1cmUubWRcIixcbiAgICApO1xuICAgIGlmIChmcy5leGlzdHNTeW5jKGFyY2hpdGVjdHVyZVBhdGgpKSB7XG4gICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGFyY2hpdGVjdHVyZVBhdGgsIFwidXRmLThcIikudHJpbSgpO1xuICAgICAgaWYgKGNvbnRlbnQpIHtcbiAgICAgICAgY29udGVudHMucHVzaChgLS0tIGFyY2hpdGVjdHVyZS5tZCAtLS1cXG4ke2NvbnRlbnR9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnRlbnRzLmpvaW4oXCJcXG5cXG5cIik7XG4gIH0gY2F0Y2gge1xuICAgIC8vIFNvbmFtdSDrr7jstIjquLDtmZQg65iQ64qUIO2MjOydvCDsoJHqt7wg7Jik66WYIOyLnCDruYgg66y47J6Q7Je0IOuwmO2ZmFxuICAgIHJldHVybiBcIlwiO1xuICB9XG59XG5cbi8qKlxuICogTExNIO2UhOuhrO2UhO2KuOulvCDsg53shLHtlanri4jri6QuXG4gKlxuICogYWktY2xpZW50LnRzIO2MqO2EtOydhCDssLjqs6DtlZjsl6wg66qF7ZmV7ZWcIOyngOyLnOyCrO2VreqzvCDstpzroKUg7ZiV7Iud7J2EIOygnOqzte2VqeuLiOuLpC5cbiAqL1xuZnVuY3Rpb24gYnVpbGRQcm9tcHQoY29udGV4dDogQ29uZUdlbmVyYXRpb25Db250ZXh0KTogc3RyaW5nIHtcbiAgY29uc3QgbG9jYWxlID0gY29udGV4dC5sb2NhbGUgfHwgXCJrb1wiO1xuICBjb25zdCBsb2NhbGVEZXNjID0ge1xuICAgIGtvOiBcIktvcmVhblwiLFxuICAgIGVuOiBcIkVuZ2xpc2hcIixcbiAgICBqYTogXCJKYXBhbmVzZVwiLFxuICB9W2xvY2FsZV07XG5cbiAgY29uc3QgcHJvamVjdENvbnRleHQgPSByZWFkUHJvamVjdFNraWxscygpO1xuICBjb25zdCBwcm9qZWN0U2VjdGlvbiA9IHByb2plY3RDb250ZXh0XG4gICAgPyBgXFxuUFJPSkVDVCBDT05URVhUIChidXNpbmVzcyByZXF1aXJlbWVudHMgYW5kIGRvbWFpbiBrbm93bGVkZ2UpOlxcbiR7cHJvamVjdENvbnRleHR9XFxuXFxuVXNlIHRoZSBhYm92ZSBwcm9qZWN0IGNvbnRleHQgdG8gdW5kZXJzdGFuZCB0aGUgYnVzaW5lc3MgZG9tYWluLCBlbnRpdHkgcHVycG9zZXMsIGZpZWxkIG1lYW5pbmdzLCBhbmQgcmVsYXRpb25zaGlwcy4gR2VuZXJhdGUgY29uZSBtZXRhZGF0YSB0aGF0IHJlZmxlY3RzIHRoaXMgcHJvamVjdCdzIGFjdHVhbCByZXF1aXJlbWVudHMsIG5vdCBnZW5lcmljIGFzc3VtcHRpb25zLlxcbmBcbiAgICA6IFwiXCI7XG5cbiAgcmV0dXJuIGBZb3UgYXJlIGEgU29uYW11IGZyYW1ld29yayBleHBlcnQuIEdlbmVyYXRlIGNvbmUgbWV0YWRhdGEgZm9yIGRhdGFiYXNlIGVudGl0eSBmaXh0dXJlIGdlbmVyYXRpb24uXG5cbkNSSVRJQ0FMIFBSSU9SSVRZIFJVTEU6XG5UaGUgXCJub3RlXCIgZmllbGQgaXMgdGhlIFBSSU1BUlkgc291cmNlIGZvciBmaXh0dXJlIGRhdGEgZ2VuZXJhdGlvbi4gV2hlbiAtLXVzZS1sbG0gaXMgZW5hYmxlZCwgdGhlIGZpeHR1cmUgZ2VuZXJhdG9yIHJlYWRzIGNvbmUubm90ZSBhbmQgYXNrcyBMTE0gdG8gZ2VuZXJhdGUgY29udGV4dHVhbGx5IGFwcHJvcHJpYXRlIGRhdGEgQkVGT1JFIGZhbGxpbmcgYmFjayB0byBmaXh0dXJlR2VuZXJhdG9yLlxuVGhlcmVmb3JlLCBjb25lLm5vdGUgbXVzdCBhbHdheXMgY29udGFpbiByaWNoLCBkb21haW4tc3BlY2lmaWMgZGVzY3JpcHRpb25zIHdpdGggY29uY3JldGUgZXhhbXBsZXMgYW5kIHZhbHVlIHJhbmdlcy5cbmZpeHR1cmVHZW5lcmF0b3IgaXMgb25seSBhIEZBTExCQUNLIGZvciB3aGVuIExMTSBpcyB1bmF2YWlsYWJsZSAobm8gQVBJIGtleSkuIFdyaXRlIGl0IGFzIGEgYmVzdC1lZmZvcnQgYXBwcm94aW1hdGlvbiwgYnV0IG5ldmVyIHJlbHkgb24gaXQgYXMgdGhlIHByaW1hcnkgZ2VuZXJhdGlvbiBtZXRob2QuXG4ke3Byb2plY3RTZWN0aW9ufVxuRU5USVRZIFNUUlVDVFVSRTpcbiR7SlNPTi5zdHJpbmdpZnkoY29udGV4dC5lbnRpdHksIG51bGwsIDIpfVxuXG5MT0NBTEU6ICR7bG9jYWxlfSAoJHtsb2NhbGVEZXNjfSlcblxuSU5TVFJVQ1RJT05TOlxuMS4gRW50aXR5IGNvbmUgbWV0YWRhdGE6XG4gICAtIG5vdGU6IERlc2NyaWJlIHdoYXQgdGhpcyBlbnRpdHkgcmVwcmVzZW50cywgaXRzIHB1cnBvc2UsIHJlbGF0aW9uc2hpcHMsIGJ1c2luZXNzIGNvbnRleHQsIGFuZCBvdmVyYWxsIGd1aWRhbmNlIGZvciBnZW5lcmF0aW5nIHRlc3QgZGF0YS4gQ29tYmluZSBhbGwgcmVsZXZhbnQgaW5mb3JtYXRpb24gaW50byBvbmUgY29oZXJlbnQgZGVzY3JpcHRpb24uXG4gICAtIHRhZ3M6IFJlbGV2YW50IGNhdGVnb3JpemF0aW9uIHRhZ3NcblxuMi4gRm9yIGVhY2ggcHJvcCwgZ2VuZXJhdGUgYXBwcm9wcmlhdGUgY29uZSBtZXRhZGF0YTpcbiAgIC0gbm90ZSAoTU9TVCBJTVBPUlRBTlQpOiBEZXNjcmliZSB3aGF0IHRoaXMgZmllbGQgcmVwcmVzZW50cyBpbiBidXNpbmVzcyB0ZXJtcywgYW5kIHByb3ZpZGUgZGV0YWlsZWQgZ3VpZGFuY2UgZm9yIHJlYWxpc3RpYyB0ZXN0IGRhdGEgZ2VuZXJhdGlvbi4gSW5jbHVkZSBjb25jcmV0ZSBleGFtcGxlcywgdmFsdWUgcmFuZ2VzLCBmb3JtYXR0aW5nIHJ1bGVzLCBhbmQgZG9tYWluIGNvbnN0cmFpbnRzLiBUaGlzIGlzIHRoZSBwcmltYXJ5IGlucHV0IExMTSB1c2VzIHRvIGdlbmVyYXRlIGZpeHR1cmUgZGF0YS5cbiAgIC0gZml4dHVyZUdlbmVyYXRvcjogZmFrZXIuanMgZXhwcmVzc2lvbiBhcyBGQUxMQkFDSyBvbmx5IChzZWUgcnVsZSA5IGZvciBleGNlcHRpb25zKS4gRm9yIGZyZWUtdGV4dCBmaWVsZHMgd2hlcmUgZmFrZXIgY2Fubm90IHByb2R1Y2UgZG9tYWluLWFwcHJvcHJpYXRlIGNvbnRlbnQgKGRlc2NyaXB0aW9uLCBzdW1tYXJ5LCBub3RlLCByZWFzb24sIHRpdGxlLCBldGMuKSwgcHJlZmVyIHVzaW5nIGZha2VyLmhlbHBlcnMuYXJyYXlFbGVtZW50KFsuLi5dKSB3aXRoIDUtMTAgZG9tYWluLXNwZWNpZmljIGV4YW1wbGUgdmFsdWVzIHJhdGhlciB0aGFuIGZha2VyLmxvcmVtLiouXG5cbjMuIEZpZWxkIHR5cGUg4oaSIGZha2VyLmpzIG1hcHBpbmc6XG4gICAtIGVtYWlsIOKGkiBmYWtlci5pbnRlcm5ldC5lbWFpbCgpXG4gICAtIHBob25lIOKGkiBmYWtlci5waG9uZS5udW1iZXIoKVxuICAgLSBuYW1lL3VzZXJuYW1lIOKGkiBmYWtlci5wZXJzb24uZnVsbE5hbWUoKSAod2l0aCBsb2NhbGUpXG4gICAtIGJpcnRoX2RhdGUg4oaSIGZha2VyLmRhdGUuYmlydGhkYXRlKHsgbWluOiAxOCwgbWF4OiA2NSwgbW9kZTogJ2FnZScgfSlcbiAgIC0gc2FsYXJ5IOKGkiBmYWtlci5udW1iZXIuaW50KHsgbWluOiAzMF8wMDBfMDAwLCBtYXg6IDE1MF8wMDBfMDAwIH0pIGZvciBrbyBsb2NhbGVcbiAgIC0gY29tcGFueV9uYW1lIOKGkiBmYWtlci5jb21wYW55Lm5hbWUoKVxuICAgLSBhZGRyZXNzIOKGkiBmYWtlci5sb2NhdGlvbi5zdHJlZXRBZGRyZXNzKClcblxuNC4gUmVsYXRpb24gZmllbGRzIChCZWxvbmdzVG9PbmUsIE9uZVRvT25lIHdpdGggaGFzSm9pbkNvbHVtbik6XG4gICAtIEFsd2F5cyBhZGQgZGF0YVNvdXJjZTogeyBzdHJhdGVneTogXCJyZWNlbnRcIiwgY29uZmlnOiB7IGxpbWl0OiAzLTUgfSB9XG4gICAtIG5vdGU6IEV4cGxhaW4gd2hhdCB0aGlzIHJlbGF0aW9uIHJlcHJlc2VudHMgYW5kIHRoYXQgaXQgcmVmZXJlbmNlcyBleGlzdGluZyBkYXRhXG5cbjUuIFN1YnNldHMgY29uZSBtZXRhZGF0YSAoSU1QT1JUQU5UIC0gZ2VuZXJhdGUgZm9yIEFMTCBzdWJzZXRzKTpcbiAgIC0gbm90ZTogRGVzY3JpYmUgd2hhdCB0aGlzIHN1YnNldCByZXByZXNlbnRzLCB3aGF0IGZpZWxkcyBpdCBpbmNsdWRlcywgYW5kIHdoZW4gdG8gdXNlIGl0XG5cbjYuIEVudW1zIGNvbmUgbWV0YWRhdGEgKElNUE9SVEFOVCAtIGdlbmVyYXRlIGZvciBBTEwgZW51bXMpOlxuICAgLSBub3RlOiBEZXNjcmliZSB3aGF0IHRoaXMgZW51bSByZXByZXNlbnRzLiBJZiBhbnkgcHJvcCB1c2VzIHRoaXMgZW51bSB0eXBlLCBpbmNsdWRlIHRoZSBzYW1lIGd1aWRhbmNlIGZyb20gdGhhdCBwcm9wJ3Mgbm90ZS5cbiAgIC0gRm9yIGVhY2ggZW51bSB2YWx1ZSwgcHJvdmlkZSBub3RlIGV4cGxhaW5pbmcgd2hhdCB0aGF0IHNwZWNpZmljIHZhbHVlIG1lYW5zXG5cbjcuIEtvcmVhbiBmaWVsZCBuYW1lcyAobG9jYWxlPWtvKTpcbiAgIC0gSW5mZXIgbWVhbmluZyBhbmQgZ2VuZXJhdGUgYXBwcm9wcmlhdGUgZmFrZXJcbiAgIC0gXCLsnbTrpoRcIiDihpIgZmFrZXIucGVyc29uLmZ1bGxOYW1lKClcbiAgIC0gXCLsg53rhYTsm5TsnbxcIiDihpIgZmFrZXIuZGF0ZS5iaXJ0aGRhdGUoKVxuICAgLSBcIuyjvOyGjFwiIOKGkiBmYWtlci5sb2NhdGlvbi5zdHJlZXRBZGRyZXNzKClcblxuOC4gTG9jYWxlLXNwZWNpZmljIHZhbHVlczpcbiAgIC0ga286IEtvcmVhbiBuYW1lcywgYWRkcmVzc2VzLCBwaG9uZSBudW1iZXJzICgwMTAtWFhYWC1YWFhYIGZvcm1hdClcbiAgIC0gZW46IEVuZ2xpc2ggbmFtZXMsIFVTIGFkZHJlc3Nlc1xuICAgLSBqYTogSmFwYW5lc2UgbmFtZXMsIGFkZHJlc3Nlc1xuXG45LiBDb3JyZWxhdGVkIGZpZWxkcyAoSU1QT1JUQU5UIC0gZG8gTk9UIHVzZSBmaXh0dXJlR2VuZXJhdG9yIGZvciB0aGVzZSk6XG4gICBJZiBtdWx0aXBsZSBwcm9wcyBhcmUgc2VtYW50aWNhbGx5IHJlbGF0ZWQgYW5kIG11c3QgYmUgY29uc2lzdGVudCB3aXRoIGVhY2ggb3RoZXIgKGUuZy4gbmFtZSArIG5hbWVfZW4sIG5hbWUgKyBuYW1lX2phLCB0aXRsZSArIHRpdGxlX2VuKSwgZG8gTk9UIHNldCBmaXh0dXJlR2VuZXJhdG9yIG9uIGFueSBvZiB0aGVtLlxuICAgSW5zdGVhZCwgc2V0IG9ubHkgbm90ZSB3aXRoIGEgY2xlYXIgZGVzY3JpcHRpb24gdGhhdCBleHBsYWlucyB0aGUgcmVsYXRpb25zaGlwLlxuICAgRXhhbXBsZTogaWYgbmFtZSBpcyBhIEtvcmVhbiBmdWxsIG5hbWUgbGlrZSBcIuq5gOuvvOyImFwiLCB0aGVuIG5hbWVfZW4gbXVzdCBiZSBpdHMgcm9tYW5pemVkIGZvcm0gXCJLaW0gTWluc3VcIi5cbiAgIFRoZSBmaXh0dXJlIGdlbmVyYXRvciB3aWxsIHBhc3MgYWxsIHN1Y2ggcHJvcHMgdG9nZXRoZXIgdG8gTExNIGluIGEgc2luZ2xlIGNhbGwgdG8gZW5zdXJlIGNvbnNpc3RlbmN5LlxuICAgRGV0ZWN0aW9uIHJ1bGU6IGlmIGEgcHJvcCBuYW1lIG1hdGNoZXMgYW5vdGhlciBwcm9wIG5hbWUgd2l0aCBhIGxvY2FsZSBzdWZmaXggKF9lbiwgX2tvLCBfamEsIF9jbikgb3IgdmljZSB2ZXJzYSwgdHJlYXQgdGhlbSBhcyBjb3JyZWxhdGVkLlxuXG4xMC4gU3RyaW5nIFBLIGlkOlxuICAgLSBOZXZlciBzZXQgZml4dHVyZVN0cmF0ZWd5OiBcInNlcXVlbmNlXCIgb24gYW4gaWQgcHJvcCB3aXRoIHR5cGUgXCJzdHJpbmdcIi5cbiAgIC0gRG8gbm90IHNldCBmaXh0dXJlR2VuZXJhdG9yIGVpdGhlciDigJQgZml4dHVyZS1nZW5lcmF0b3IgYXV0b21hdGljYWxseSBnZW5lcmF0ZXMgYWxwaGFudW1lcmljKDMyKS5cbiAgIC0gSW4gbm90ZSwgZGVzY3JpYmUgaG93IHRoZSBpZCBpcyBnZW5lcmF0ZWQgKGUuZy4gcmFuZG9tIHN0cmluZyBnZW5lcmF0ZWQgYnkgYmV0dGVyLWF1dGgpLlxuXG4xMS4gZml4dHVyZUNvbXBhbmlvbnMgKElNUE9SVEFOVCAtIG5ldmVyIGdlbmVyYXRlIG9yIG1vZGlmeSk6XG4gICAtIGZpeHR1cmVDb21wYW5pb25zIGlzIHVzZXItZGVjbGFyZWQgbWV0YWRhdGEgdGhhdCB0cmlnZ2VycyBhdXRvbWF0aWMgY29tcGFuaW9uIGZpeHR1cmUgY3JlYXRpb24gd2hlbiBhIHBhcmVudCBmaXh0dXJlIGlzIGdlbmVyYXRlZC5cbiAgIC0gRG8gTk9UIGdlbmVyYXRlIG9yIHN1Z2dlc3QgZml4dHVyZUNvbXBhbmlvbnMgZm9yIGFueSBwcm9wLiBPbmx5IHVzZXJzIGRlY2xhcmUgdGhpcyBpbnRlbnRpb25hbGx5LlxuICAgLSBJZiBhIHByb3AncyBleGlzdGluZyBjb25lIGFscmVhZHkgY29udGFpbnMgZml4dHVyZUNvbXBhbmlvbnMsIHByZXNlcnZlIGl0IGV4YWN0bHkgYXMtaXMgaW4gdGhlIHByb3BDb25lcyBvdXRwdXQuIERvIG5vdCByZW1vdmUsIGFsdGVyLCBvciBvbWl0IGl0LlxuICAgLSBFeGFtcGxlOiBpZiBVc2VyIGVudGl0eSdzIFwiaWRcIiBwcm9wIGNvbmUgaGFzIGZpeHR1cmVDb21wYW5pb25zLCBpbmNsdWRlIGl0IHVuY2hhbmdlZCBpbiBwcm9wQ29uZXNbXCJpZFwiXS5cblxuJHtcbiAgY29udGV4dC5leGlzdGluZ0NvbmVzXG4gICAgPyBgXG5FWElTVElORyBDT05FUyAocHJlc2VydmUgdGhlc2UgaWYgcHJlc2VudCk6XG4ke0pTT04uc3RyaW5naWZ5KGNvbnRleHQuZXhpc3RpbmdDb25lcywgbnVsbCwgMil9XG5gXG4gICAgOiBcIlwiXG59XG5cbk9VVFBVVCBGT1JNQVQ6XG5SZXR1cm4gT05MWSB2YWxpZCBKU09OIChubyBtYXJrZG93biwgbm8gY29kZSBibG9ja3MpLiBVc2UgdGhpcyBleGFjdCBzdHJ1Y3R1cmU6XG57XG4gIFwiZW50aXR5Q29uZVwiOiB7XG4gICAgXCJub3RlXCI6IFwiRGVzY3JpcHRpb24gb2YgdGhlIGVudGl0eSwgaXRzIHB1cnBvc2UsIGFuZCBndWlkYW5jZSBmb3IgZml4dHVyZSBnZW5lcmF0aW9uXCIsXG4gICAgXCJ0YWdzXCI6IFtcIm9wdGlvbmFsXCIsIFwidGFnc1wiXVxuICB9LFxuICBcInByb3BDb25lc1wiOiB7XG4gICAgXCJwcm9wX25hbWVcIjoge1xuICAgICAgXCJub3RlXCI6IFwiRGVzY3JpcHRpb24gb2YgdGhpcyBmaWVsZCBhbmQgZ3VpZGFuY2UgZm9yIHJlYWxpc3RpYyB0ZXN0IGRhdGEgZ2VuZXJhdGlvblwiLFxuICAgICAgXCJmaXh0dXJlR2VuZXJhdG9yXCI6IFwiZmFrZXIueHh4Lnl5eSgpXCIsXG4gICAgICBcImRhdGFTb3VyY2VcIjogeyBcInN0cmF0ZWd5XCI6IFwicmVjZW50XCIsIFwiY29uZmlnXCI6IHsgXCJsaW1pdFwiOiA1IH0gfVxuICAgIH1cbiAgfSxcbiAgXCJzdWJzZXRDb25lc1wiOiB7XG4gICAgXCJBXCI6IHtcbiAgICAgIFwibm90ZVwiOiBcIkRlc2NyaXB0aW9uIG9mIHN1YnNldCBBLCB3aGF0IGZpZWxkcyBpdCBpbmNsdWRlcywgYW5kIHdoZW4gdG8gdXNlIGl0XCJcbiAgICB9XG4gIH0sXG4gIFwiZW51bUNvbmVzXCI6IHtcbiAgICBcIkVudW1OYW1lXCI6IHtcbiAgICAgIFwibm90ZVwiOiBcIkRlc2NyaXB0aW9uIG9mIHRoZSBlbnVtIGFuZCBndWlkYW5jZSBmb3IgZ2VuZXJhdGluZyB2YWx1ZXNcIixcbiAgICAgIFwidmFsdWVzXCI6IHtcbiAgICAgICAgXCJWQUxVRV9LRVlcIjoge1xuICAgICAgICAgIFwibm90ZVwiOiBcIiR7bG9jYWxlRGVzY30gZGVzY3JpcHRpb24gb2YgdGhpcyBlbnVtIHZhbHVlXCJcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5JTVBPUlRBTlQ6IFJldHVybiBwdXJlIEpTT04gb25seS4gRG8gTk9UIHdyYXAgaW4gbWFya2Rvd24gY29kZSBibG9ja3MuYDtcbn1cblxuLyoqXG4gKiBBbnRocm9waWMgQVBJ66W8IO2YuOy2nO2VmOyXrCBMTE0g7J2R64u17J2EIOuwm+yKteuLiOuLpC5cbiAqXG4gKiBAcGFyYW0gcHJvbXB0IC0g7IOd7ISx7ZWgIO2UhOuhrO2UhO2KuFxuICogQHBhcmFtIGFwaUtleSAtIEFudGhyb3BpYyBBUEkg7YKkXG4gKiBAcmV0dXJucyBMTE0g7J2R64u1IO2FjeyKpO2KuCDrsI8g7Yag7YGwIOyCrOyaqeufiVxuICovXG5hc3luYyBmdW5jdGlvbiBjYWxsQW50aHJvcGljQVBJKFxuICBwcm9tcHQ6IHN0cmluZyxcbiAgYXBpS2V5OiBzdHJpbmcsXG4pOiBQcm9taXNlPHsgdGV4dDogc3RyaW5nOyB0b2tlbnNVc2VkOiBudW1iZXIgfT4ge1xuICB0cnkge1xuICAgIC8vIEBhaS1zZGsvYW50aHJvcGlj6rO8IGFpIO2MqO2CpOyngOuKlCBvcHRpb25hbCBkZXBlbmRlbmN57J2066+A66GcIOuPmeyggSBpbXBvcnRcbiAgICBjb25zdCB7IGNyZWF0ZUFudGhyb3BpYyB9ID0gYXdhaXQgaW1wb3J0KFwiQGFpLXNkay9hbnRocm9waWNcIik7XG4gICAgY29uc3QgeyBnZW5lcmF0ZVRleHQgfSA9IGF3YWl0IGltcG9ydChcImFpXCIpO1xuXG4gICAgY29uc3QgYW50aHJvcGljID0gY3JlYXRlQW50aHJvcGljKHtcbiAgICAgIGFwaUtleSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHsgdGV4dCwgdXNhZ2UgfSA9IGF3YWl0IGdlbmVyYXRlVGV4dCh7XG4gICAgICBtb2RlbDogYW50aHJvcGljKFwiY2xhdWRlLXNvbm5ldC00LTZcIiksXG4gICAgICBwcm9tcHQsXG4gICAgfSk7XG5cbiAgICBjb25zdCB0b2tlbnNVc2VkID0gdXNhZ2U/LnRvdGFsVG9rZW5zIHx8IDA7XG4gICAgaWYgKHVzYWdlKSB7XG4gICAgICBjb25zb2xlLmxvZyhgW0NvbmUgR2VuZXJhdG9yXSBUb2tlbnMgdXNlZDogJHt0b2tlbnNVc2VkfWApO1xuICAgIH1cblxuICAgIHJldHVybiB7IHRleHQsIHRva2Vuc1VzZWQgfTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBpZiAoZXJyb3IgJiYgdHlwZW9mIGVycm9yID09PSBcIm9iamVjdFwiICYmIFwic3RhdHVzQ29kZVwiIGluIGVycm9yKSB7XG4gICAgICBjb25zdCBzdGF0dXNDb2RlID0gKGVycm9yIGFzIHsgc3RhdHVzQ29kZTogbnVtYmVyIH0pLnN0YXR1c0NvZGU7XG4gICAgICBpZiAoc3RhdHVzQ29kZSA9PT0gNDI5KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlJhdGUgbGltaXQgZXhjZWVkZWQuIFBsZWFzZSB0cnkgYWdhaW4gbGF0ZXIuXCIsIHsgY2F1c2U6IGVycm9yIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG1lc3NhZ2UgPSBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IubWVzc2FnZSA6IFwiVW5rbm93biBlcnJvclwiO1xuICAgIHRocm93IG5ldyBFcnJvcihgTExNIEFQSSBmYWlsZWQ6ICR7bWVzc2FnZX1gLCB7IGNhdXNlOiBlcnJvciB9KTtcbiAgfVxufVxuXG4vKipcbiAqIExMTSDsnZHri7XsnYQg7YyM7Iux7ZWY7JesIENvbmVHZW5lcmF0aW9uUmVzdWx066GcIOuzgO2ZmO2VqeuLiOuLpC5cbiAqXG4gKiBNYXJrZG93biDsvZTrk5wg67iU66Gd7J20IO2PrO2VqOuQmOyWtCDsnojsnLzrqbQg7KCc6rGw7ZWp64uI64ukLlxuICovXG5mdW5jdGlvbiBwYXJzZUNvbmVSZXNwb25zZSh0ZXh0OiBzdHJpbmcpOiBDb25lR2VuZXJhdGlvblJlc3VsdCB7XG4gIGxldCBqc29uVGV4dCA9IHRleHQudHJpbSgpO1xuICBqc29uVGV4dCA9IGpzb25UZXh0LnJlcGxhY2UoL15gYGBqc29uXFxzKi9pLCBcIlwiKTtcbiAganNvblRleHQgPSBqc29uVGV4dC5yZXBsYWNlKC9gYGBcXHMqJC8sIFwiXCIpO1xuICBqc29uVGV4dCA9IGpzb25UZXh0LnRyaW0oKTtcblxuICB0cnkge1xuICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UoanNvblRleHQpO1xuXG4gICAgaWYgKCFwYXJzZWQucHJvcENvbmVzIHx8IHR5cGVvZiBwYXJzZWQucHJvcENvbmVzICE9PSBcIm9iamVjdFwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHJlc3BvbnNlOiBwcm9wQ29uZXMgaXMgcmVxdWlyZWQgYW5kIG11c3QgYmUgYW4gb2JqZWN0XCIpO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBlbnRpdHlDb25lOiBwYXJzZWQuZW50aXR5Q29uZSxcbiAgICAgIHByb3BDb25lczogcGFyc2VkLnByb3BDb25lcyxcbiAgICAgIHN1YnNldENvbmVzOiBwYXJzZWQuc3Vic2V0Q29uZXMgfHwge30sXG4gICAgICBlbnVtQ29uZXM6IHBhcnNlZC5lbnVtQ29uZXMgfHwge30sXG4gICAgICB0b2tlbnNVc2VkOiAwLFxuICAgIH07XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogXCJVbmtub3duIGVycm9yXCI7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYEZhaWxlZCB0byBwYXJzZSBMTE0gcmVzcG9uc2U6ICR7bWVzc2FnZX1cXG5cXG5gICtcbiAgICAgICAgYE9yaWdpbmFsIHJlc3BvbnNlOlxcbiR7dGV4dH1cXG5cXG5gICtcbiAgICAgICAgYENsZWFuZWQgSlNPTjpcXG4ke2pzb25UZXh0fWAsXG4gICAgICB7IGNhdXNlOiBlcnJvciB9LFxuICAgICk7XG4gIH1cbn1cblxuLyoqXG4gKiDsg53shLHrkJwgY29uZeydhCDquLDsobQgY29uZeqzvCDrs5Htlantlanri4jri6QuXG4gKlxuICog6riw7KG0IGNvbmXsnbQg7J6I7Jy866m0IOuztOyhtO2VmOqzoCwg7JeG64qUIOqyveyasOyXkOunjCDsg53shLHrkJwgY29uZeydhCDsgqzsmqntlanri4jri6QuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlV2l0aEV4aXN0aW5nKFxuICBnZW5lcmF0ZWQ6IENvbmVHZW5lcmF0aW9uUmVzdWx0LFxuICBleGlzdGluZzogUmVjb3JkPHN0cmluZywgQ29uZT4sXG4pOiBDb25lR2VuZXJhdGlvblJlc3VsdCB7XG4gIGNvbnN0IHJlc3VsdCA9IHsgLi4uZ2VuZXJhdGVkIH07XG5cbiAgY29uc3QgZW50aXR5S2V5ID0gYGVudGl0eToke2dlbmVyYXRlZC5lbnRpdHlDb25lID8gXCJwcmVzZW50XCIgOiBcIm1pc3NpbmdcIn1gO1xuICBpZiAoZXhpc3RpbmdbZW50aXR5S2V5XSkge1xuICAgIHJlc3VsdC5lbnRpdHlDb25lID0gZXhpc3RpbmdbZW50aXR5S2V5XTtcbiAgfVxuXG4gIGZvciAoY29uc3QgcHJvcE5hbWUgb2YgT2JqZWN0LmtleXMoZ2VuZXJhdGVkLnByb3BDb25lcykpIHtcbiAgICBjb25zdCBrZXkgPSBgcHJvcDoke3Byb3BOYW1lfWA7XG4gICAgaWYgKGV4aXN0aW5nW2tleV0pIHtcbiAgICAgIHJlc3VsdC5wcm9wQ29uZXNbcHJvcE5hbWVdID0gZXhpc3Rpbmdba2V5XTtcbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IGVudW1JZCBvZiBPYmplY3Qua2V5cyhnZW5lcmF0ZWQuZW51bUNvbmVzKSkge1xuICAgIGNvbnN0IGtleSA9IGBlbnVtOiR7ZW51bUlkfWA7XG4gICAgaWYgKGV4aXN0aW5nW2tleV0pIHtcbiAgICAgIHJlc3VsdC5lbnVtQ29uZXNbZW51bUlkXSA9IGV4aXN0aW5nW2tleV07XG4gICAgfVxuICB9XG5cbiAgZm9yIChjb25zdCBzdWJzZXRLZXkgb2YgT2JqZWN0LmtleXMoZ2VuZXJhdGVkLnN1YnNldENvbmVzKSkge1xuICAgIGNvbnN0IGtleSA9IGBzdWJzZXQ6JHtzdWJzZXRLZXl9YDtcbiAgICBpZiAoZXhpc3Rpbmdba2V5XSkge1xuICAgICAgcmVzdWx0LnN1YnNldENvbmVzW3N1YnNldEtleV0gPSBleGlzdGluZ1trZXldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogbm90ZeqwgCDsl4bripQgY29uZeunjCDsg53shLHtlZjqs6Ag64KY66i47KeA64qUIOuztOyhtO2VqeuLiOuLpC5cbiAqXG4gKiDquLDsobQgY29uZeyXkCBub3Rl6rCAIOyeiOycvOuptCDrs7TsobTtlZjqs6AsIOyXhuycvOuptCDsg4jroZwg7IOd7ISx65CcIGNvbmXsnYQg7IKs7Jqp7ZWp64uI64ukLlxuICovXG5mdW5jdGlvbiBtZXJnZU9ubHlFbXB0eShcbiAgZ2VuZXJhdGVkOiBDb25lR2VuZXJhdGlvblJlc3VsdCxcbiAgZXhpc3Rpbmc6IFJlY29yZDxzdHJpbmcsIENvbmU+LFxuKTogQ29uZUdlbmVyYXRpb25SZXN1bHQge1xuICBjb25zdCByZXN1bHQgPSB7IC4uLmdlbmVyYXRlZCB9O1xuXG4gIC8vIEVudGl0eSBjb25lOiBzY2FsZeydtCDsnojsnLzrqbQg67O07KG0XG4gIGNvbnN0IGVudGl0eUtleSA9IGBlbnRpdHk6JHtnZW5lcmF0ZWQuZW50aXR5Q29uZSA/IFwicHJlc2VudFwiIDogXCJtaXNzaW5nXCJ9YDtcbiAgaWYgKGV4aXN0aW5nW2VudGl0eUtleV0/Lm5vdGUpIHtcbiAgICByZXN1bHQuZW50aXR5Q29uZSA9IGV4aXN0aW5nW2VudGl0eUtleV07XG4gIH1cblxuICAvLyBQcm9wIGNvbmVzOiBzY2FsZeydtCDsnojsnLzrqbQg67O07KG0XG4gIGZvciAoY29uc3QgcHJvcE5hbWUgb2YgT2JqZWN0LmtleXMoZ2VuZXJhdGVkLnByb3BDb25lcykpIHtcbiAgICBjb25zdCBrZXkgPSBgcHJvcDoke3Byb3BOYW1lfWA7XG4gICAgaWYgKGV4aXN0aW5nW2tleV0/Lm5vdGUpIHtcbiAgICAgIHJlc3VsdC5wcm9wQ29uZXNbcHJvcE5hbWVdID0gZXhpc3Rpbmdba2V5XTtcbiAgICB9XG4gIH1cblxuICAvLyBFbnVtIGNvbmVzOiBzY2FsZeydtCDsnojsnLzrqbQg67O07KG0XG4gIGZvciAoY29uc3QgZW51bUlkIG9mIE9iamVjdC5rZXlzKGdlbmVyYXRlZC5lbnVtQ29uZXMpKSB7XG4gICAgY29uc3Qga2V5ID0gYGVudW06JHtlbnVtSWR9YDtcbiAgICBpZiAoZXhpc3Rpbmdba2V5XT8ubm90ZSkge1xuICAgICAgcmVzdWx0LmVudW1Db25lc1tlbnVtSWRdID0gZXhpc3Rpbmdba2V5XTtcbiAgICB9XG4gIH1cblxuICAvLyBTdWJzZXQgY29uZXM6IHNjYWxl7J20IOyeiOycvOuptCDrs7TsobRcbiAgZm9yIChjb25zdCBzdWJzZXRLZXkgb2YgT2JqZWN0LmtleXMoZ2VuZXJhdGVkLnN1YnNldENvbmVzKSkge1xuICAgIGNvbnN0IGtleSA9IGBzdWJzZXQ6JHtzdWJzZXRLZXl9YDtcbiAgICBpZiAoZXhpc3Rpbmdba2V5XT8ubm90ZSkge1xuICAgICAgcmVzdWx0LnN1YnNldENvbmVzW3N1YnNldEtleV0gPSBleGlzdGluZ1trZXldO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQXFDQSxlQUFzQixjQUFjLFNBQStEO0NBQ2pHLE1BQU0sU0FBUyxXQUFXO0NBQzFCLE1BQU0sU0FBUyxZQUFZLFFBQVE7Q0FDbkMsTUFBTSxFQUFFLE1BQU0sY0FBYyxlQUFlLE1BQU0saUJBQWlCLFFBQVEsT0FBTztDQUNqRixNQUFNLFNBQVMsa0JBQWtCLGFBQWE7QUFDOUMsUUFBTyxhQUFhO0FBRXBCLEtBQUksUUFBUSxlQUFlO0FBQ3pCLE1BQUksUUFBUSxXQUFXO0FBQ3JCLFVBQU8sZUFBZSxRQUFRLFFBQVEsY0FBYzs7QUFFdEQsU0FBTyxrQkFBa0IsUUFBUSxRQUFRLGNBQWM7O0FBR3pELFFBQU87Ozs7Ozs7QUFRVCxTQUFTLFlBQW9CO0NBRTNCLElBQUlBO0FBRUosS0FBSTtFQUVGLE1BQU0sRUFBRTtBQUNSLFdBQVMsT0FBTyxTQUFTO1NBQ25CO0FBRU4sV0FBUzs7QUFHWCxLQUFJLENBQUMsUUFBUTtBQUNYLFdBQVMsUUFBUSxJQUFJOztBQUd2QixLQUFJLENBQUMsUUFBUTtBQUNYLFFBQU0sSUFBSSxNQUNSLGtDQUNFLDJFQUNIOztBQUdILFFBQU87Ozs7Ozs7Ozs7QUFXVCxTQUFTLG9CQUE0QjtBQUNuQyxLQUFJO0VBQ0YsTUFBTSxFQUFFO0VBQ1IsTUFBTSxjQUFjLE9BQU87RUFDM0IsTUFBTUMsV0FBcUIsRUFBRTtFQUc3QixNQUFNLGNBQWNDLE9BQUssS0FBSyxhQUFhLFdBQVc7QUFDdEQsTUFBSUMsS0FBRyxXQUFXLFlBQVksRUFBRTtHQUM5QixNQUFNLFVBQVVBLEtBQ2IsWUFBWSxhQUFhLEVBQUUsZUFBZSxNQUFNLENB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
|
|
300
|
+
|
|
301
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZS1nZW5lcmF0b3IuanMiLCJuYW1lcyI6WyJwYXRoIiwiZnMiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZS9jb25lLWdlbmVyYXRvci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwibm9kZTpwYXRoXCI7XG5cbmltcG9ydCB7IHR5cGUgQ29uZSwgdHlwZSBFbnRpdHlKc29uIH0gZnJvbSBcIi4uL3R5cGVzL3R5cGVzXCI7XG5cbi8qKlxuICogQ29uZSDsg53shLEg7Luo7YWN7Iqk7Yq4XG4gKlxuICogRW50aXR5IOygleuztOyZgCDsg53shLEg7Ji17IWY7J2EIOuLtOqzoCDsnojsirXri4jri6QuXG4gKi9cbmV4cG9ydCB0eXBlIENvbmVHZW5lcmF0aW9uQ29udGV4dCA9IHtcbiAgZW50aXR5OiBFbnRpdHlKc29uO1xuICBsb2NhbGU/OiBcImtvXCIgfCBcImVuXCIgfCBcImphXCI7XG4gIGV4aXN0aW5nQ29uZXM/OiBSZWNvcmQ8c3RyaW5nLCBDb25lPjtcbiAgLyoqIHRydWXsnbgg6rK97JqwIG5vdGXqsIAg7JeG64qUIGNvbmXrp4wg7IOd7ISxICovXG4gIG9ubHlFbXB0eT86IGJvb2xlYW47XG59O1xuXG4vKipcbiAqIENvbmUg7IOd7ISxIOqysOqzvFxuICpcbiAqIEVudGl0eSwgUHJvcHMsIFN1YnNldHMsIEVudW1z7J2YIGNvbmUg66mU7YOA642w7J207YSw66W8IOuLtOqzoCDsnojsirXri4jri6QuXG4gKi9cbmV4cG9ydCB0eXBlIENvbmVHZW5lcmF0aW9uUmVzdWx0ID0ge1xuICBlbnRpdHlDb25lPzogQ29uZTtcbiAgcHJvcENvbmVzOiBSZWNvcmQ8c3RyaW5nLCBDb25lPjtcbiAgc3Vic2V0Q29uZXM6IFJlY29yZDxzdHJpbmcsIENvbmU+O1xuICBlbnVtQ29uZXM6IFJlY29yZDxzdHJpbmcsIENvbmU+O1xuICB0b2tlbnNVc2VkOiBudW1iZXI7XG59O1xuXG4vKipcbiAqIExMTeydhCDsgqzsmqntlZjsl6wgRW50aXR57J2YIGNvbmUg66mU7YOA642w7J207YSw66W8IOyDneyEse2VqeuLiOuLpC5cbiAqXG4gKiBAcGFyYW0gY29udGV4dCAtIEVudGl0eSDsoJXrs7TsmYAg7IOd7ISxIOyYteyFmFxuICogQHJldHVybnMg7IOd7ISx65CcIGNvbmUg66mU7YOA642w7J207YSwXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUNvbmVzKGNvbnRleHQ6IENvbmVHZW5lcmF0aW9uQ29udGV4dCk6IFByb21pc2U8Q29uZUdlbmVyYXRpb25SZXN1bHQ+IHtcbiAgY29uc3QgYXBpS2V5ID0gZ2V0QXBpS2V5KCk7XG4gIGNvbnN0IHByb21wdCA9IGJ1aWxkUHJvbXB0KGNvbnRleHQpO1xuICBjb25zdCB7IHRleHQ6IHJlc3BvbnNlVGV4dCwgdG9rZW5zVXNlZCB9ID0gYXdhaXQgY2FsbEFudGhyb3BpY0FQSShwcm9tcHQsIGFwaUtleSk7XG4gIGNvbnN0IHJlc3VsdCA9IHBhcnNlQ29uZVJlc3BvbnNlKHJlc3BvbnNlVGV4dCk7XG4gIHJlc3VsdC50b2tlbnNVc2VkID0gdG9rZW5zVXNlZDtcblxuICBpZiAoY29udGV4dC5leGlzdGluZ0NvbmVzKSB7XG4gICAgaWYgKGNvbnRleHQub25seUVtcHR5KSB7XG4gICAgICByZXR1cm4gbWVyZ2VPbmx5RW1wdHkocmVzdWx0LCBjb250ZXh0LmV4aXN0aW5nQ29uZXMpO1xuICAgIH1cbiAgICByZXR1cm4gbWVyZ2VXaXRoRXhpc3RpbmcocmVzdWx0LCBjb250ZXh0LmV4aXN0aW5nQ29uZXMpO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBBUEkg7YKk66W8IOqwgOyguOyYteuLiOuLpC5cbiAqXG4gKiBTb25hbXUuc2VjcmV0IOuYkOuKlCDtmZjqsr3rs4DsiJjsl5DshJwg6rCA7KC47Ji164uI64ukLlxuICovXG5mdW5jdGlvbiBnZXRBcGlLZXkoKTogc3RyaW5nIHtcbiAgLy8gU29uYW11LnNlY3JldOydgCDrn7Dtg4DsnoTsl5Ag66Gc65Oc65CY66+A66GcIOuPmeyggeycvOuhnCBpbXBvcnRcbiAgbGV0IGFwaUtleTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gIHRyeSB7XG4gICAgLy8gU29uYW116rCAIOy0iOq4sO2ZlOuQmOyWtCDsnojripQg6rK97JqwXG4gICAgY29uc3QgeyBTb25hbXUgfSA9IHJlcXVpcmUoXCIuLi9hcGlcIik7XG4gICAgYXBpS2V5ID0gU29uYW11LnNlY3JldHM/LmFudGhyb3BpY19hcGlfa2V5O1xuICB9IGNhdGNoIHtcbiAgICAvLyBTb25hbXXqsIAg7LSI6riw7ZmU65CY7KeAIOyViuydgCDqsr3smrAgKO2FjOyKpO2KuCDrk7EpXG4gICAgYXBpS2V5ID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgaWYgKCFhcGlLZXkpIHtcbiAgICBhcGlLZXkgPSBwcm9jZXNzLmVudi5BTlRIUk9QSUNfQVBJX0tFWTtcbiAgfVxuXG4gIGlmICghYXBpS2V5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgXCJBTlRIUk9QSUNfQVBJX0tFWSBub3QgZm91bmQuIFwiICtcbiAgICAgICAgXCJTZXQgQU5USFJPUElDX0FQSV9LRVkgZW52aXJvbm1lbnQgdmFyaWFibGUgb3IgYWRkIGl0IHRvIHNvbmFtdS5zZWNyZXQudHNcIixcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIGFwaUtleTtcbn1cblxuLyoqXG4gKiDrj4TrqZTsnbjrs4Qge2RvbWFpbn0uY29udHJhY3QubWTsmYAgYXJjaGl0ZWN0dXJlLm1k66W8IOydveyWtCDsu6jthY3siqTtirjroZwg67CY7ZmY7ZWp64uI64ukLlxuICpcbiAqIC0gY29udHJhY3Qve2RvbWFpbn0ve2RvbWFpbn0uY29udHJhY3QubWQ6IOuPhOuplOyduCDqt5zsuZnqs7wg6rKw7KCVIOq3vOqxsCAo7KO8IOywuOyhsCDrjIDsg4EpXG4gKiAtIC5jbGF1ZGUvc2tpbGxzL3Byb2plY3QvYXJjaGl0ZWN0dXJlLm1kOiDsl5Tti7Dti7Ag7ISk6rOEIOq1rOyhsCAo67O07KGwIOywuOyhsClcbiAqXG4gKiBjb25lIOyDneyEsSDsi5wgTExN7JeQ6rKMIOyghOuLrO2VmOyXrCDrj4TrqZTsnbgg66el65297JeQIOunnuuKlCDrqZTtg4DrjbDsnbTthLDrpbwg7IOd7ISx7ZWY64+E66GdIO2VqeuLiOuLpC5cbiAqL1xuZnVuY3Rpb24gcmVhZFByb2plY3RTa2lsbHMoKTogc3RyaW5nIHtcbiAgdHJ5IHtcbiAgICBjb25zdCB7IFNvbmFtdSB9ID0gcmVxdWlyZShcIi4uL2FwaVwiKTtcbiAgICBjb25zdCBwcm9qZWN0Um9vdCA9IFNvbmFtdS5hcHBSb290UGF0aDtcbiAgICBjb25zdCBjb250ZW50czogc3RyaW5nW10gPSBbXTtcblxuICAgIC8vIGNvbnRyYWN0LyoqLyouY29udHJhY3QubWQg7IiY7KeRXG4gICAgY29uc3QgY29udHJhY3REaXIgPSBwYXRoLmpvaW4ocHJvamVjdFJvb3QsIFwiY29udHJhY3RcIik7XG4gICAgaWYgKGZzLmV4aXN0c1N5bmMoY29udHJhY3REaXIpKSB7XG4gICAgICBjb25zdCBkb21haW5zID0gZnNcbiAgICAgICAgLnJlYWRkaXJTeW5jKGNvbnRyYWN0RGlyLCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSlcbiAgICAgICAgLmZpbHRlcigoZCkgPT4gZC5pc0RpcmVjdG9yeSgpKVxuICAgICAgICAubWFwKChkKSA9PiBkLm5hbWUpO1xuXG4gICAgICBmb3IgKGNvbnN0IGRvbWFpbiBvZiBkb21haW5zKSB7XG4gICAgICAgIGNvbnN0IGRvbWFpbkRpciA9IHBhdGguam9pbihjb250cmFjdERpciwgZG9tYWluKTtcbiAgICAgICAgY29uc3QgY29udHJhY3RGaWxlcyA9IGZzXG4gICAgICAgICAgLnJlYWRkaXJTeW5jKGRvbWFpbkRpcilcbiAgICAgICAgICAuZmlsdGVyKChmOiBzdHJpbmcpID0+IGYuZW5kc1dpdGgoXCIuY29udHJhY3QubWRcIikpO1xuXG4gICAgICAgIGZvciAoY29uc3QgZmlsZSBvZiBjb250cmFjdEZpbGVzKSB7XG4gICAgICAgICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4oZG9tYWluRGlyLCBmaWxlKTtcbiAgICAgICAgICBjb25zdCBjb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKGZpbGVQYXRoLCBcInV0Zi04XCIpLnRyaW0oKTtcbiAgICAgICAgICBpZiAoY29udGVudCkge1xuICAgICAgICAgICAgY29udGVudHMucHVzaChgLS0tIGNvbnRyYWN0LyR7ZG9tYWlufS8ke2ZpbGV9IC0tLVxcbiR7Y29udGVudH1gKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyAuY2xhdWRlL3NraWxscy9wcm9qZWN0L2FyY2hpdGVjdHVyZS5tZCDrs7TsobAg7LC47KGwXG4gICAgY29uc3QgYXJjaGl0ZWN0dXJlUGF0aCA9IHBhdGguam9pbihcbiAgICAgIHByb2plY3RSb290LFxuICAgICAgXCIuY2xhdWRlXCIsXG4gICAgICBcInNraWxsc1wiLFxuICAgICAgXCJwcm9qZWN0XCIsXG4gICAgICBcImFyY2hpdGVjdHVyZS5tZFwiLFxuICAgICk7XG4gICAgaWYgKGZzLmV4aXN0c1N5bmMoYXJjaGl0ZWN0dXJlUGF0aCkpIHtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBmcy5yZWFkRmlsZVN5bmMoYXJjaGl0ZWN0dXJlUGF0aCwgXCJ1dGYtOFwiKS50cmltKCk7XG4gICAgICBpZiAoY29udGVudCkge1xuICAgICAgICBjb250ZW50cy5wdXNoKGAtLS0gYXJjaGl0ZWN0dXJlLm1kIC0tLVxcbiR7Y29udGVudH1gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gY29udGVudHMuam9pbihcIlxcblxcblwiKTtcbiAgfSBjYXRjaCB7XG4gICAgLy8gU29uYW11IOuvuOy0iOq4sO2ZlCDrmJDripQg7YyM7J28IOygkeq3vCDsmKTrpZgg7IucIOu5iCDrrLjsnpDsl7Qg67CY7ZmYXG4gICAgcmV0dXJuIFwiXCI7XG4gIH1cbn1cblxuLyoqXG4gKiBMTE0g7ZSE66Gs7ZSE7Yq466W8IOyDneyEse2VqeuLiOuLpC5cbiAqXG4gKiBhaS1jbGllbnQudHMg7Yyo7YS07J2EIOywuOqzoO2VmOyXrCDrqoXtmZXtlZwg7KeA7Iuc7IKs7ZWt6rO8IOy2nOugpSDtmJXsi53snYQg7KCc6rO17ZWp64uI64ukLlxuICovXG5mdW5jdGlvbiBidWlsZFByb21wdChjb250ZXh0OiBDb25lR2VuZXJhdGlvbkNvbnRleHQpOiBzdHJpbmcge1xuICBjb25zdCBsb2NhbGUgPSBjb250ZXh0LmxvY2FsZSB8fCBcImtvXCI7XG4gIGNvbnN0IGxvY2FsZURlc2MgPSB7XG4gICAga286IFwiS29yZWFuXCIsXG4gICAgZW46IFwiRW5nbGlzaFwiLFxuICAgIGphOiBcIkphcGFuZXNlXCIsXG4gIH1bbG9jYWxlXTtcblxuICBjb25zdCBwcm9qZWN0Q29udGV4dCA9IHJlYWRQcm9qZWN0U2tpbGxzKCk7XG4gIGNvbnN0IHByb2plY3RTZWN0aW9uID0gcHJvamVjdENvbnRleHRcbiAgICA/IGBcXG5QUk9KRUNUIENPTlRFWFQgKGJ1c2luZXNzIHJlcXVpcmVtZW50cyBhbmQgZG9tYWluIGtub3dsZWRnZSk6XFxuJHtwcm9qZWN0Q29udGV4dH1cXG5cXG5Vc2UgdGhlIGFib3ZlIHByb2plY3QgY29udGV4dCB0byB1bmRlcnN0YW5kIHRoZSBidXNpbmVzcyBkb21haW4sIGVudGl0eSBwdXJwb3NlcywgZmllbGQgbWVhbmluZ3MsIGFuZCByZWxhdGlvbnNoaXBzLiBHZW5lcmF0ZSBjb25lIG1ldGFkYXRhIHRoYXQgcmVmbGVjdHMgdGhpcyBwcm9qZWN0J3MgYWN0dWFsIHJlcXVpcmVtZW50cywgbm90IGdlbmVyaWMgYXNzdW1wdGlvbnMuXFxuYFxuICAgIDogXCJcIjtcblxuICByZXR1cm4gYFlvdSBhcmUgYSBTb25hbXUgZnJhbWV3b3JrIGV4cGVydC4gR2VuZXJhdGUgY29uZSBtZXRhZGF0YSBmb3IgZGF0YWJhc2UgZW50aXR5IGZpeHR1cmUgZ2VuZXJhdGlvbi5cblxuQ1JJVElDQUwgUFJJT1JJVFkgUlVMRTpcblRoZSBcIm5vdGVcIiBmaWVsZCBpcyB0aGUgUFJJTUFSWSBzb3VyY2UgZm9yIGZpeHR1cmUgZGF0YSBnZW5lcmF0aW9uLiBXaGVuIC0tdXNlLWxsbSBpcyBlbmFibGVkLCB0aGUgZml4dHVyZSBnZW5lcmF0b3IgcmVhZHMgY29uZS5ub3RlIGFuZCBhc2tzIExMTSB0byBnZW5lcmF0ZSBjb250ZXh0dWFsbHkgYXBwcm9wcmlhdGUgZGF0YSBCRUZPUkUgZmFsbGluZyBiYWNrIHRvIGZpeHR1cmVHZW5lcmF0b3IuXG5UaGVyZWZvcmUsIGNvbmUubm90ZSBtdXN0IGFsd2F5cyBjb250YWluIHJpY2gsIGRvbWFpbi1zcGVjaWZpYyBkZXNjcmlwdGlvbnMgd2l0aCBjb25jcmV0ZSBleGFtcGxlcyBhbmQgdmFsdWUgcmFuZ2VzLlxuZml4dHVyZUdlbmVyYXRvciBpcyBvbmx5IGEgRkFMTEJBQ0sgZm9yIHdoZW4gTExNIGlzIHVuYXZhaWxhYmxlIChubyBBUEkga2V5KS4gV3JpdGUgaXQgYXMgYSBiZXN0LWVmZm9ydCBhcHByb3hpbWF0aW9uLCBidXQgbmV2ZXIgcmVseSBvbiBpdCBhcyB0aGUgcHJpbWFyeSBnZW5lcmF0aW9uIG1ldGhvZC5cbiR7cHJvamVjdFNlY3Rpb259XG5FTlRJVFkgU1RSVUNUVVJFOlxuJHtKU09OLnN0cmluZ2lmeShjb250ZXh0LmVudGl0eSwgbnVsbCwgMil9XG5cbkxPQ0FMRTogJHtsb2NhbGV9ICgke2xvY2FsZURlc2N9KVxuXG5JTlNUUlVDVElPTlM6XG4xLiBFbnRpdHkgY29uZSBtZXRhZGF0YTpcbiAgIC0gbm90ZTogRGVzY3JpYmUgd2hhdCB0aGlzIGVudGl0eSByZXByZXNlbnRzLCBpdHMgcHVycG9zZSwgcmVsYXRpb25zaGlwcywgYnVzaW5lc3MgY29udGV4dCwgYW5kIG92ZXJhbGwgZ3VpZGFuY2UgZm9yIGdlbmVyYXRpbmcgdGVzdCBkYXRhLiBDb21iaW5lIGFsbCByZWxldmFudCBpbmZvcm1hdGlvbiBpbnRvIG9uZSBjb2hlcmVudCBkZXNjcmlwdGlvbi5cbiAgIC0gdGFnczogUmVsZXZhbnQgY2F0ZWdvcml6YXRpb24gdGFnc1xuXG4yLiBGb3IgZWFjaCBwcm9wLCBnZW5lcmF0ZSBhcHByb3ByaWF0ZSBjb25lIG1ldGFkYXRhOlxuICAgLSBub3RlIChNT1NUIElNUE9SVEFOVCk6IERlc2NyaWJlIHdoYXQgdGhpcyBmaWVsZCByZXByZXNlbnRzIGluIGJ1c2luZXNzIHRlcm1zLCBhbmQgcHJvdmlkZSBkZXRhaWxlZCBndWlkYW5jZSBmb3IgcmVhbGlzdGljIHRlc3QgZGF0YSBnZW5lcmF0aW9uLiBJbmNsdWRlIGNvbmNyZXRlIGV4YW1wbGVzLCB2YWx1ZSByYW5nZXMsIGZvcm1hdHRpbmcgcnVsZXMsIGFuZCBkb21haW4gY29uc3RyYWludHMuIFRoaXMgaXMgdGhlIHByaW1hcnkgaW5wdXQgTExNIHVzZXMgdG8gZ2VuZXJhdGUgZml4dHVyZSBkYXRhLlxuICAgLSBmaXh0dXJlR2VuZXJhdG9yOiBmYWtlci5qcyBleHByZXNzaW9uIGFzIEZBTExCQUNLIG9ubHkgKHNlZSBydWxlIDkgZm9yIGV4Y2VwdGlvbnMpLiBGb3IgZnJlZS10ZXh0IGZpZWxkcyB3aGVyZSBmYWtlciBjYW5ub3QgcHJvZHVjZSBkb21haW4tYXBwcm9wcmlhdGUgY29udGVudCAoZGVzY3JpcHRpb24sIHN1bW1hcnksIG5vdGUsIHJlYXNvbiwgdGl0bGUsIGV0Yy4pLCBwcmVmZXIgdXNpbmcgZmFrZXIuaGVscGVycy5hcnJheUVsZW1lbnQoWy4uLl0pIHdpdGggNS0xMCBkb21haW4tc3BlY2lmaWMgZXhhbXBsZSB2YWx1ZXMgcmF0aGVyIHRoYW4gZmFrZXIubG9yZW0uKi5cblxuMy4gRmllbGQgdHlwZSDihpIgZmFrZXIuanMgbWFwcGluZzpcbiAgIC0gZW1haWwg4oaSIGZha2VyLmludGVybmV0LmVtYWlsKClcbiAgIC0gcGhvbmUg4oaSIGZha2VyLnBob25lLm51bWJlcigpXG4gICAtIG5hbWUvdXNlcm5hbWUg4oaSIGZha2VyLnBlcnNvbi5mdWxsTmFtZSgpICh3aXRoIGxvY2FsZSlcbiAgIC0gYmlydGhfZGF0ZSDihpIgZmFrZXIuZGF0ZS5iaXJ0aGRhdGUoeyBtaW46IDE4LCBtYXg6IDY1LCBtb2RlOiAnYWdlJyB9KVxuICAgLSBzYWxhcnkg4oaSIGZha2VyLm51bWJlci5pbnQoeyBtaW46IDMwXzAwMF8wMDAsIG1heDogMTUwXzAwMF8wMDAgfSkgZm9yIGtvIGxvY2FsZVxuICAgLSBjb21wYW55X25hbWUg4oaSIGZha2VyLmNvbXBhbnkubmFtZSgpXG4gICAtIGFkZHJlc3Mg4oaSIGZha2VyLmxvY2F0aW9uLnN0cmVldEFkZHJlc3MoKVxuXG40LiBSZWxhdGlvbiBmaWVsZHMgKEJlbG9uZ3NUb09uZSwgT25lVG9PbmUgd2l0aCBoYXNKb2luQ29sdW1uKTpcbiAgIC0gQWx3YXlzIGFkZCBkYXRhU291cmNlOiB7IHN0cmF0ZWd5OiBcInJlY2VudFwiLCBjb25maWc6IHsgbGltaXQ6IDMtNSB9IH1cbiAgIC0gbm90ZTogRXhwbGFpbiB3aGF0IHRoaXMgcmVsYXRpb24gcmVwcmVzZW50cyBhbmQgdGhhdCBpdCByZWZlcmVuY2VzIGV4aXN0aW5nIGRhdGFcblxuNS4gU3Vic2V0cyBjb25lIG1ldGFkYXRhIChJTVBPUlRBTlQgLSBnZW5lcmF0ZSBmb3IgQUxMIHN1YnNldHMpOlxuICAgLSBub3RlOiBEZXNjcmliZSB3aGF0IHRoaXMgc3Vic2V0IHJlcHJlc2VudHMsIHdoYXQgZmllbGRzIGl0IGluY2x1ZGVzLCBhbmQgd2hlbiB0byB1c2UgaXRcblxuNi4gRW51bXMgY29uZSBtZXRhZGF0YSAoSU1QT1JUQU5UIC0gZ2VuZXJhdGUgZm9yIEFMTCBlbnVtcyk6XG4gICAtIG5vdGU6IERlc2NyaWJlIHdoYXQgdGhpcyBlbnVtIHJlcHJlc2VudHMuIElmIGFueSBwcm9wIHVzZXMgdGhpcyBlbnVtIHR5cGUsIGluY2x1ZGUgdGhlIHNhbWUgZ3VpZGFuY2UgZnJvbSB0aGF0IHByb3AncyBub3RlLlxuICAgLSBGb3IgZWFjaCBlbnVtIHZhbHVlLCBwcm92aWRlIG5vdGUgZXhwbGFpbmluZyB3aGF0IHRoYXQgc3BlY2lmaWMgdmFsdWUgbWVhbnNcblxuNy4gS29yZWFuIGZpZWxkIG5hbWVzIChsb2NhbGU9a28pOlxuICAgLSBJbmZlciBtZWFuaW5nIGFuZCBnZW5lcmF0ZSBhcHByb3ByaWF0ZSBmYWtlclxuICAgLSBcIuydtOumhFwiIOKGkiBmYWtlci5wZXJzb24uZnVsbE5hbWUoKVxuICAgLSBcIuyDneuFhOyblOydvFwiIOKGkiBmYWtlci5kYXRlLmJpcnRoZGF0ZSgpXG4gICAtIFwi7KO87IaMXCIg4oaSIGZha2VyLmxvY2F0aW9uLnN0cmVldEFkZHJlc3MoKVxuXG44LiBMb2NhbGUtc3BlY2lmaWMgdmFsdWVzOlxuICAgLSBrbzogS29yZWFuIG5hbWVzLCBhZGRyZXNzZXMsIHBob25lIG51bWJlcnMgKDAxMC1YWFhYLVhYWFggZm9ybWF0KVxuICAgLSBlbjogRW5nbGlzaCBuYW1lcywgVVMgYWRkcmVzc2VzXG4gICAtIGphOiBKYXBhbmVzZSBuYW1lcywgYWRkcmVzc2VzXG5cbjkuIENvcnJlbGF0ZWQgZmllbGRzIChJTVBPUlRBTlQgLSBkbyBOT1QgdXNlIGZpeHR1cmVHZW5lcmF0b3IgZm9yIHRoZXNlKTpcbiAgIElmIG11bHRpcGxlIHByb3BzIGFyZSBzZW1hbnRpY2FsbHkgcmVsYXRlZCBhbmQgbXVzdCBiZSBjb25zaXN0ZW50IHdpdGggZWFjaCBvdGhlciAoZS5nLiBuYW1lICsgbmFtZV9lbiwgbmFtZSArIG5hbWVfamEsIHRpdGxlICsgdGl0bGVfZW4pLCBkbyBOT1Qgc2V0IGZpeHR1cmVHZW5lcmF0b3Igb24gYW55IG9mIHRoZW0uXG4gICBJbnN0ZWFkLCBzZXQgb25seSBub3RlIHdpdGggYSBjbGVhciBkZXNjcmlwdGlvbiB0aGF0IGV4cGxhaW5zIHRoZSByZWxhdGlvbnNoaXAuXG4gICBFeGFtcGxlOiBpZiBuYW1lIGlzIGEgS29yZWFuIGZ1bGwgbmFtZSBsaWtlIFwi6rmA66+87IiYXCIsIHRoZW4gbmFtZV9lbiBtdXN0IGJlIGl0cyByb21hbml6ZWQgZm9ybSBcIktpbSBNaW5zdVwiLlxuICAgVGhlIGZpeHR1cmUgZ2VuZXJhdG9yIHdpbGwgcGFzcyBhbGwgc3VjaCBwcm9wcyB0b2dldGhlciB0byBMTE0gaW4gYSBzaW5nbGUgY2FsbCB0byBlbnN1cmUgY29uc2lzdGVuY3kuXG4gICBEZXRlY3Rpb24gcnVsZTogaWYgYSBwcm9wIG5hbWUgbWF0Y2hlcyBhbm90aGVyIHByb3AgbmFtZSB3aXRoIGEgbG9jYWxlIHN1ZmZpeCAoX2VuLCBfa28sIF9qYSwgX2NuKSBvciB2aWNlIHZlcnNhLCB0cmVhdCB0aGVtIGFzIGNvcnJlbGF0ZWQuXG5cbjEwLiBTdHJpbmcgUEsgaWQ6XG4gICAtIE5ldmVyIHNldCBmaXh0dXJlU3RyYXRlZ3k6IFwic2VxdWVuY2VcIiBvbiBhbiBpZCBwcm9wIHdpdGggdHlwZSBcInN0cmluZ1wiLlxuICAgLSBEbyBub3Qgc2V0IGZpeHR1cmVHZW5lcmF0b3IgZWl0aGVyIOKAlCBmaXh0dXJlLWdlbmVyYXRvciBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlcyBhbHBoYW51bWVyaWMoMzIpLlxuICAgLSBJbiBub3RlLCBkZXNjcmliZSBob3cgdGhlIGlkIGlzIGdlbmVyYXRlZCAoZS5nLiByYW5kb20gc3RyaW5nIGdlbmVyYXRlZCBieSBiZXR0ZXItYXV0aCkuXG5cbjExLiBmaXh0dXJlQ29tcGFuaW9ucyAoSU1QT1JUQU5UIC0gbmV2ZXIgZ2VuZXJhdGUgb3IgbW9kaWZ5KTpcbiAgIC0gZml4dHVyZUNvbXBhbmlvbnMgaXMgdXNlci1kZWNsYXJlZCBtZXRhZGF0YSB0aGF0IHRyaWdnZXJzIGF1dG9tYXRpYyBjb21wYW5pb24gZml4dHVyZSBjcmVhdGlvbiB3aGVuIGEgcGFyZW50IGZpeHR1cmUgaXMgZ2VuZXJhdGVkLlxuICAgLSBEbyBOT1QgZ2VuZXJhdGUgb3Igc3VnZ2VzdCBmaXh0dXJlQ29tcGFuaW9ucyBmb3IgYW55IHByb3AuIE9ubHkgdXNlcnMgZGVjbGFyZSB0aGlzIGludGVudGlvbmFsbHkuXG4gICAtIElmIGEgcHJvcCdzIGV4aXN0aW5nIGNvbmUgYWxyZWFkeSBjb250YWlucyBmaXh0dXJlQ29tcGFuaW9ucywgcHJlc2VydmUgaXQgZXhhY3RseSBhcy1pcyBpbiB0aGUgcHJvcENvbmVzIG91dHB1dC4gRG8gbm90IHJlbW92ZSwgYWx0ZXIsIG9yIG9taXQgaXQuXG4gICAtIEV4YW1wbGU6IGlmIFVzZXIgZW50aXR5J3MgXCJpZFwiIHByb3AgY29uZSBoYXMgZml4dHVyZUNvbXBhbmlvbnMsIGluY2x1ZGUgaXQgdW5jaGFuZ2VkIGluIHByb3BDb25lc1tcImlkXCJdLlxuXG4ke1xuICBjb250ZXh0LmV4aXN0aW5nQ29uZXNcbiAgICA/IGBcbkVYSVNUSU5HIENPTkVTIChwcmVzZXJ2ZSB0aGVzZSBpZiBwcmVzZW50KTpcbiR7SlNPTi5zdHJpbmdpZnkoY29udGV4dC5leGlzdGluZ0NvbmVzLCBudWxsLCAyKX1cbmBcbiAgICA6IFwiXCJcbn1cblxuT1VUUFVUIEZPUk1BVDpcblJldHVybiBPTkxZIHZhbGlkIEpTT04gKG5vIG1hcmtkb3duLCBubyBjb2RlIGJsb2NrcykuIFVzZSB0aGlzIGV4YWN0IHN0cnVjdHVyZTpcbntcbiAgXCJlbnRpdHlDb25lXCI6IHtcbiAgICBcIm5vdGVcIjogXCJEZXNjcmlwdGlvbiBvZiB0aGUgZW50aXR5LCBpdHMgcHVycG9zZSwgYW5kIGd1aWRhbmNlIGZvciBmaXh0dXJlIGdlbmVyYXRpb25cIixcbiAgICBcInRhZ3NcIjogW1wib3B0aW9uYWxcIiwgXCJ0YWdzXCJdXG4gIH0sXG4gIFwicHJvcENvbmVzXCI6IHtcbiAgICBcInByb3BfbmFtZVwiOiB7XG4gICAgICBcIm5vdGVcIjogXCJEZXNjcmlwdGlvbiBvZiB0aGlzIGZpZWxkIGFuZCBndWlkYW5jZSBmb3IgcmVhbGlzdGljIHRlc3QgZGF0YSBnZW5lcmF0aW9uXCIsXG4gICAgICBcImZpeHR1cmVHZW5lcmF0b3JcIjogXCJmYWtlci54eHgueXl5KClcIixcbiAgICAgIFwiZGF0YVNvdXJjZVwiOiB7IFwic3RyYXRlZ3lcIjogXCJyZWNlbnRcIiwgXCJjb25maWdcIjogeyBcImxpbWl0XCI6IDUgfSB9XG4gICAgfVxuICB9LFxuICBcInN1YnNldENvbmVzXCI6IHtcbiAgICBcIkFcIjoge1xuICAgICAgXCJub3RlXCI6IFwiRGVzY3JpcHRpb24gb2Ygc3Vic2V0IEEsIHdoYXQgZmllbGRzIGl0IGluY2x1ZGVzLCBhbmQgd2hlbiB0byB1c2UgaXRcIlxuICAgIH1cbiAgfSxcbiAgXCJlbnVtQ29uZXNcIjoge1xuICAgIFwiRW51bU5hbWVcIjoge1xuICAgICAgXCJub3RlXCI6IFwiRGVzY3JpcHRpb24gb2YgdGhlIGVudW0gYW5kIGd1aWRhbmNlIGZvciBnZW5lcmF0aW5nIHZhbHVlc1wiLFxuICAgICAgXCJ2YWx1ZXNcIjoge1xuICAgICAgICBcIlZBTFVFX0tFWVwiOiB7XG4gICAgICAgICAgXCJub3RlXCI6IFwiJHtsb2NhbGVEZXNjfSBkZXNjcmlwdGlvbiBvZiB0aGlzIGVudW0gdmFsdWVcIlxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbklNUE9SVEFOVDogUmV0dXJuIHB1cmUgSlNPTiBvbmx5LiBEbyBOT1Qgd3JhcCBpbiBtYXJrZG93biBjb2RlIGJsb2Nrcy5gO1xufVxuXG4vKipcbiAqIEFudGhyb3BpYyBBUEnrpbwg7Zi47Lac7ZWY7JesIExMTSDsnZHri7XsnYQg67Cb7Iq164uI64ukLlxuICpcbiAqIEBwYXJhbSBwcm9tcHQgLSDsg53shLHtlaAg7ZSE66Gs7ZSE7Yq4XG4gKiBAcGFyYW0gYXBpS2V5IC0gQW50aHJvcGljIEFQSSDtgqRcbiAqIEByZXR1cm5zIExMTSDsnZHri7Ug7YWN7Iqk7Yq4IOuwjyDthqDtgbAg7IKs7Jqp65+JXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNhbGxBbnRocm9waWNBUEkoXG4gIHByb21wdDogc3RyaW5nLFxuICBhcGlLZXk6IHN0cmluZyxcbik6IFByb21pc2U8eyB0ZXh0OiBzdHJpbmc7IHRva2Vuc1VzZWQ6IG51bWJlciB9PiB7XG4gIHRyeSB7XG4gICAgLy8gQGFpLXNkay9hbnRocm9waWPqs7wgYWkg7Yyo7YKk7KeA64qUIG9wdGlvbmFsIGRlcGVuZGVuY3nsnbTrr4DroZwg64+Z7KCBIGltcG9ydFxuICAgIGNvbnN0IHsgY3JlYXRlQW50aHJvcGljIH0gPSBhd2FpdCBpbXBvcnQoXCJAYWktc2RrL2FudGhyb3BpY1wiKTtcbiAgICBjb25zdCB7IGdlbmVyYXRlVGV4dCB9ID0gYXdhaXQgaW1wb3J0KFwiYWlcIik7XG5cbiAgICBjb25zdCBhbnRocm9waWMgPSBjcmVhdGVBbnRocm9waWMoe1xuICAgICAgYXBpS2V5LFxuICAgIH0pO1xuXG4gICAgY29uc3QgeyB0ZXh0LCB1c2FnZSB9ID0gYXdhaXQgZ2VuZXJhdGVUZXh0KHtcbiAgICAgIG1vZGVsOiBhbnRocm9waWMoXCJjbGF1ZGUtc29ubmV0LTQtNlwiKSxcbiAgICAgIHByb21wdCxcbiAgICB9KTtcblxuICAgIGNvbnN0IHRva2Vuc1VzZWQgPSB1c2FnZT8udG90YWxUb2tlbnMgfHwgMDtcbiAgICBpZiAodXNhZ2UpIHtcbiAgICAgIGNvbnNvbGUubG9nKGBbQ29uZSBHZW5lcmF0b3JdIFRva2VucyB1c2VkOiAke3Rva2Vuc1VzZWR9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdGV4dCwgdG9rZW5zVXNlZCB9O1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGlmIChlcnJvciAmJiB0eXBlb2YgZXJyb3IgPT09IFwib2JqZWN0XCIgJiYgXCJzdGF0dXNDb2RlXCIgaW4gZXJyb3IpIHtcbiAgICAgIGNvbnN0IHN0YXR1c0NvZGUgPSAoZXJyb3IgYXMgeyBzdGF0dXNDb2RlOiBudW1iZXIgfSkuc3RhdHVzQ29kZTtcbiAgICAgIGlmIChzdGF0dXNDb2RlID09PSA0MjkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUmF0ZSBsaW1pdCBleGNlZWRlZC4gUGxlYXNlIHRyeSBhZ2FpbiBsYXRlci5cIiwgeyBjYXVzZTogZXJyb3IgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbWVzc2FnZSA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvci5tZXNzYWdlIDogXCJVbmtub3duIGVycm9yXCI7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBMTE0gQVBJIGZhaWxlZDogJHttZXNzYWdlfWAsIHsgY2F1c2U6IGVycm9yIH0pO1xuICB9XG59XG5cbi8qKlxuICogTExNIOydkeuLteydhCDtjIzsi7HtlZjsl6wgQ29uZUdlbmVyYXRpb25SZXN1bHTroZwg67OA7ZmY7ZWp64uI64ukLlxuICpcbiAqIE1hcmtkb3duIOy9lOuTnCDruJTroZ3snbQg7Y+s7ZWo65CY7Ja0IOyeiOycvOuptCDsoJzqsbDtlanri4jri6QuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlQ29uZVJlc3BvbnNlKHRleHQ6IHN0cmluZyk6IENvbmVHZW5lcmF0aW9uUmVzdWx0IHtcbiAgbGV0IGpzb25UZXh0ID0gdGV4dC50cmltKCk7XG4gIGpzb25UZXh0ID0ganNvblRleHQucmVwbGFjZSgvXmBgYGpzb25cXHMqL2ksIFwiXCIpO1xuICBqc29uVGV4dCA9IGpzb25UZXh0LnJlcGxhY2UoL2BgYFxccyokLywgXCJcIik7XG4gIGpzb25UZXh0ID0ganNvblRleHQudHJpbSgpO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgcGFyc2VkID0gSlNPTi5wYXJzZShqc29uVGV4dCk7XG5cbiAgICBpZiAoIXBhcnNlZC5wcm9wQ29uZXMgfHwgdHlwZW9mIHBhcnNlZC5wcm9wQ29uZXMgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgcmVzcG9uc2U6IHByb3BDb25lcyBpcyByZXF1aXJlZCBhbmQgbXVzdCBiZSBhbiBvYmplY3RcIik7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGVudGl0eUNvbmU6IHBhcnNlZC5lbnRpdHlDb25lLFxuICAgICAgcHJvcENvbmVzOiBwYXJzZWQucHJvcENvbmVzLFxuICAgICAgc3Vic2V0Q29uZXM6IHBhcnNlZC5zdWJzZXRDb25lcyB8fCB7fSxcbiAgICAgIGVudW1Db25lczogcGFyc2VkLmVudW1Db25lcyB8fCB7fSxcbiAgICAgIHRva2Vuc1VzZWQ6IDAsXG4gICAgfTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjb25zdCBtZXNzYWdlID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yLm1lc3NhZ2UgOiBcIlVua25vd24gZXJyb3JcIjtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgRmFpbGVkIHRvIHBhcnNlIExMTSByZXNwb25zZTogJHttZXNzYWdlfVxcblxcbmAgK1xuICAgICAgICBgT3JpZ2luYWwgcmVzcG9uc2U6XFxuJHt0ZXh0fVxcblxcbmAgK1xuICAgICAgICBgQ2xlYW5lZCBKU09OOlxcbiR7anNvblRleHR9YCxcbiAgICAgIHsgY2F1c2U6IGVycm9yIH0sXG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIOyDneyEseuQnCBjb25l7J2EIOq4sOyhtCBjb25l6rO8IOuzke2Vqe2VqeuLiOuLpC5cbiAqXG4gKiDquLDsobQgY29uZeydtCDsnojsnLzrqbQg67O07KG07ZWY6rOgLCDsl4bripQg6rK97Jqw7JeQ66eMIOyDneyEseuQnCBjb25l7J2EIOyCrOyaqe2VqeuLiOuLpC5cbiAqL1xuZnVuY3Rpb24gbWVyZ2VXaXRoRXhpc3RpbmcoXG4gIGdlbmVyYXRlZDogQ29uZUdlbmVyYXRpb25SZXN1bHQsXG4gIGV4aXN0aW5nOiBSZWNvcmQ8c3RyaW5nLCBDb25lPixcbik6IENvbmVHZW5lcmF0aW9uUmVzdWx0IHtcbiAgY29uc3QgcmVzdWx0ID0geyAuLi5nZW5lcmF0ZWQgfTtcblxuICBjb25zdCBlbnRpdHlLZXkgPSBgZW50aXR5OiR7Z2VuZXJhdGVkLmVudGl0eUNvbmUgPyBcInByZXNlbnRcIiA6IFwibWlzc2luZ1wifWA7XG4gIGlmIChleGlzdGluZ1tlbnRpdHlLZXldKSB7XG4gICAgcmVzdWx0LmVudGl0eUNvbmUgPSBleGlzdGluZ1tlbnRpdHlLZXldO1xuICB9XG5cbiAgZm9yIChjb25zdCBwcm9wTmFtZSBvZiBPYmplY3Qua2V5cyhnZW5lcmF0ZWQucHJvcENvbmVzKSkge1xuICAgIGNvbnN0IGtleSA9IGBwcm9wOiR7cHJvcE5hbWV9YDtcbiAgICBpZiAoZXhpc3Rpbmdba2V5XSkge1xuICAgICAgcmVzdWx0LnByb3BDb25lc1twcm9wTmFtZV0gPSBleGlzdGluZ1trZXldO1xuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3QgZW51bUlkIG9mIE9iamVjdC5rZXlzKGdlbmVyYXRlZC5lbnVtQ29uZXMpKSB7XG4gICAgY29uc3Qga2V5ID0gYGVudW06JHtlbnVtSWR9YDtcbiAgICBpZiAoZXhpc3Rpbmdba2V5XSkge1xuICAgICAgcmVzdWx0LmVudW1Db25lc1tlbnVtSWRdID0gZXhpc3Rpbmdba2V5XTtcbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IHN1YnNldEtleSBvZiBPYmplY3Qua2V5cyhnZW5lcmF0ZWQuc3Vic2V0Q29uZXMpKSB7XG4gICAgY29uc3Qga2V5ID0gYHN1YnNldDoke3N1YnNldEtleX1gO1xuICAgIGlmIChleGlzdGluZ1trZXldKSB7XG4gICAgICByZXN1bHQuc3Vic2V0Q29uZXNbc3Vic2V0S2V5XSA9IGV4aXN0aW5nW2tleV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBub3Rl6rCAIOyXhuuKlCBjb25l66eMIOyDneyEse2VmOqzoCDrgpjrqLjsp4DripQg67O07KG07ZWp64uI64ukLlxuICpcbiAqIOq4sOyhtCBjb25l7JeQIG5vdGXqsIAg7J6I7Jy866m0IOuztOyhtO2VmOqzoCwg7JeG7Jy866m0IOyDiOuhnCDsg53shLHrkJwgY29uZeydhCDsgqzsmqntlanri4jri6QuXG4gKi9cbmZ1bmN0aW9uIG1lcmdlT25seUVtcHR5KFxuICBnZW5lcmF0ZWQ6IENvbmVHZW5lcmF0aW9uUmVzdWx0LFxuICBleGlzdGluZzogUmVjb3JkPHN0cmluZywgQ29uZT4sXG4pOiBDb25lR2VuZXJhdGlvblJlc3VsdCB7XG4gIGNvbnN0IHJlc3VsdCA9IHsgLi4uZ2VuZXJhdGVkIH07XG5cbiAgLy8gRW50aXR5IGNvbmU6IHNjYWxl7J20IOyeiOycvOuptCDrs7TsobRcbiAgY29uc3QgZW50aXR5S2V5ID0gYGVudGl0eToke2dlbmVyYXRlZC5lbnRpdHlDb25lID8gXCJwcmVzZW50XCIgOiBcIm1pc3NpbmdcIn1gO1xuICBpZiAoZXhpc3RpbmdbZW50aXR5S2V5XT8ubm90ZSkge1xuICAgIHJlc3VsdC5lbnRpdHlDb25lID0gZXhpc3RpbmdbZW50aXR5S2V5XTtcbiAgfVxuXG4gIC8vIFByb3AgY29uZXM6IHNjYWxl7J20IOyeiOycvOuptCDrs7TsobRcbiAgZm9yIChjb25zdCBwcm9wTmFtZSBvZiBPYmplY3Qua2V5cyhnZW5lcmF0ZWQucHJvcENvbmVzKSkge1xuICAgIGNvbnN0IGtleSA9IGBwcm9wOiR7cHJvcE5hbWV9YDtcbiAgICBpZiAoZXhpc3Rpbmdba2V5XT8ubm90ZSkge1xuICAgICAgcmVzdWx0LnByb3BDb25lc1twcm9wTmFtZV0gPSBleGlzdGluZ1trZXldO1xuICAgIH1cbiAgfVxuXG4gIC8vIEVudW0gY29uZXM6IHNjYWxl7J20IOyeiOycvOuptCDrs7TsobRcbiAgZm9yIChjb25zdCBlbnVtSWQgb2YgT2JqZWN0LmtleXMoZ2VuZXJhdGVkLmVudW1Db25lcykpIHtcbiAgICBjb25zdCBrZXkgPSBgZW51bToke2VudW1JZH1gO1xuICAgIGlmIChleGlzdGluZ1trZXldPy5ub3RlKSB7XG4gICAgICByZXN1bHQuZW51bUNvbmVzW2VudW1JZF0gPSBleGlzdGluZ1trZXldO1xuICAgIH1cbiAgfVxuXG4gIC8vIFN1YnNldCBjb25lczogc2NhbGXsnbQg7J6I7Jy866m0IOuztOyhtFxuICBmb3IgKGNvbnN0IHN1YnNldEtleSBvZiBPYmplY3Qua2V5cyhnZW5lcmF0ZWQuc3Vic2V0Q29uZXMpKSB7XG4gICAgY29uc3Qga2V5ID0gYHN1YnNldDoke3N1YnNldEtleX1gO1xuICAgIGlmIChleGlzdGluZ1trZXldPy5ub3RlKSB7XG4gICAgICByZXN1bHQuc3Vic2V0Q29uZXNbc3Vic2V0S2V5XSA9IGV4aXN0aW5nW2tleV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7QUFxQ0EsZUFBc0IsY0FBYyxTQUErRDtDQUNqRyxNQUFNLFNBQVMsVUFBVTtDQUV6QixNQUFNLEVBQUUsTUFBTSxjQUFjLGVBQWUsTUFBTSxpQkFEbEMsWUFBWSxPQUN1QyxHQUFRLE1BQU07Q0FDaEYsTUFBTSxTQUFTLGtCQUFrQixZQUFZO0NBQzdDLE9BQU8sYUFBYTtDQUVwQixJQUFJLFFBQVEsZUFBZTtFQUN6QixJQUFJLFFBQVEsV0FDVixPQUFPLGVBQWUsUUFBUSxRQUFRLGFBQWE7RUFFckQsT0FBTyxrQkFBa0IsUUFBUSxRQUFRLGFBQWE7Q0FDeEQ7Q0FFQSxPQUFPO0FBQ1Q7Ozs7OztBQU9BLFNBQVMsWUFBb0I7Q0FFM0IsSUFBSTtDQUVKLElBQUk7RUFFRixNQUFNLEVBQUUsWUFBQSxTQUFBLEdBQUEsYUFBQSxXQUFBO0VBQ1IsU0FBUyxPQUFPLFNBQVM7Q0FDM0IsUUFBUTtFQUVOLFNBQVM7Q0FDWDtDQUVBLElBQUksQ0FBQyxRQUNILFNBQVMsUUFBUSxJQUFJO0NBR3ZCLElBQUksQ0FBQyxRQUNILE1BQU0sSUFBSSxNQUNSLHVHQUVGO0NBR0YsT0FBTztBQUNUOzs7Ozs7Ozs7QUFVQSxTQUFTLG9CQUE0QjtDQUNuQyxJQUFJO0VBQ0YsTUFBTSxFQUFFLFlBQUEsU0FBQSxHQUFBLGFBQUEsV0FBQTtFQUNSLE1BQU0sY0FBYyxPQUFPO0VBQzNCLE1BQU0sV0FBcUIsQ0FBQztFQUc1QixNQUFNLGNBQWNBLE9BQUssS0FBSyxhQUFhLFVBQVU7RUFDckQsSUFBSUMsS0FBRyxXQUFXLFdBQVcsR0FBRztHQUM5QixNQUFNLFVBQVVBLEtBQ2IsWUFBWSxhQUFhLEVBQUUsZUFBZSxLQUFLLENBQUMsQ0FBQyxDQUNqRCxRQUFRLE1BQU0sRUFBRSxZQUFZLENBQUMs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
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { __esmMin } from "../_virtual/
|
|
1
|
+
import { __esmMin } from "../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { getLogger } from "@logtape/logtape";
|
|
3
|
-
|
|
4
3
|
//#region src/database/_batch_update.ts
|
|
5
4
|
/**
|
|
6
5
|
* Batch update rows in a table. Technically its a patch since it only updates the specified columns. Any omitted columns will not be affected
|
|
@@ -13,32 +12,26 @@ import { getLogger } from "@logtape/logtape";
|
|
|
13
12
|
*/
|
|
14
13
|
async function batchUpdate(knex, tableName, ids, rows, chunkSize = 50, trx = null) {
|
|
15
14
|
const chunks = [];
|
|
16
|
-
for (let i = 0; i < rows.length; i += chunkSize)
|
|
17
|
-
chunks.push(rows.slice(i, i + chunkSize));
|
|
18
|
-
}
|
|
15
|
+
for (let i = 0; i < rows.length; i += chunkSize) chunks.push(rows.slice(i, i + chunkSize));
|
|
19
16
|
const executeUpdate = async (chunk, transaction) => {
|
|
20
|
-
|
|
21
|
-
return rawQuery.transacting(transaction);
|
|
17
|
+
return generateBatchUpdateSQL(knex, tableName, chunk, ids).transacting(transaction);
|
|
22
18
|
};
|
|
23
|
-
if (trx) {
|
|
19
|
+
if (trx) for (const chunk of chunks) {
|
|
20
|
+
logger.debug("Processing Batch Chunk in Existing Transaction: {current} / {total}", {
|
|
21
|
+
current: chunk.length,
|
|
22
|
+
total: chunks.length
|
|
23
|
+
});
|
|
24
|
+
await executeUpdate(chunk, trx);
|
|
25
|
+
}
|
|
26
|
+
else await knex.transaction(async (newTrx) => {
|
|
24
27
|
for (const chunk of chunks) {
|
|
25
|
-
logger.debug("Processing Batch Chunk in
|
|
28
|
+
logger.debug("Processing Batch Chunk in New Transaction: {current} / {total}", {
|
|
26
29
|
current: chunk.length,
|
|
27
30
|
total: chunks.length
|
|
28
31
|
});
|
|
29
|
-
await executeUpdate(chunk,
|
|
32
|
+
await executeUpdate(chunk, newTrx);
|
|
30
33
|
}
|
|
31
|
-
}
|
|
32
|
-
await knex.transaction(async (newTrx) => {
|
|
33
|
-
for (const chunk of chunks) {
|
|
34
|
-
logger.debug("Processing Batch Chunk in New Transaction: {current} / {total}", {
|
|
35
|
-
current: chunk.length,
|
|
36
|
-
total: chunks.length
|
|
37
|
-
});
|
|
38
|
-
await executeUpdate(chunk, newTrx);
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
}
|
|
34
|
+
});
|
|
42
35
|
}
|
|
43
36
|
/**
|
|
44
37
|
* Generate a set of unique keys in a data array
|
|
@@ -48,35 +41,25 @@ async function batchUpdate(knex, tableName, ids, rows, chunkSize = 50, trx = nul
|
|
|
48
41
|
* @param data
|
|
49
42
|
*/
|
|
50
43
|
function generateKeySetFromData(data) {
|
|
51
|
-
const keySet = new Set();
|
|
52
|
-
for (const row of data)
|
|
53
|
-
for (const key of Object.keys(row)) {
|
|
54
|
-
keySet.add(key);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
44
|
+
const keySet = /* @__PURE__ */ new Set();
|
|
45
|
+
for (const row of data) for (const key of Object.keys(row)) keySet.add(key);
|
|
57
46
|
return keySet;
|
|
58
47
|
}
|
|
59
48
|
function generateBatchUpdateSQL(db, tableName, data, identifiers) {
|
|
60
49
|
const keySet = generateKeySetFromData(data);
|
|
61
50
|
const allBindings = [];
|
|
62
51
|
const invalidIdentifiers = identifiers.filter((id) => !keySet.has(id));
|
|
63
|
-
if (invalidIdentifiers.length > 0) {
|
|
64
|
-
throw new Error(`Invalid identifiers: ${invalidIdentifiers.join(", ")}. Identifiers must exist in the data`);
|
|
65
|
-
}
|
|
52
|
+
if (invalidIdentifiers.length > 0) throw new Error(`Invalid identifiers: ${invalidIdentifiers.join(", ")}. Identifiers must exist in the data`);
|
|
66
53
|
const cases = [];
|
|
67
54
|
for (const key of keySet) {
|
|
68
55
|
if (identifiers.includes(key)) continue;
|
|
69
56
|
const caseBindings = [];
|
|
70
57
|
const whenClauses = [];
|
|
71
|
-
for (const row of data) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
caseBindings.push(id, row[id]);
|
|
77
|
-
}
|
|
78
|
-
caseBindings.push(row[key]);
|
|
79
|
-
}
|
|
58
|
+
for (const row of data) if (Object.hasOwn(row, key)) {
|
|
59
|
+
const whereParts = identifiers.map(() => `?? = ?`).join(" AND ");
|
|
60
|
+
whenClauses.push(`WHEN (${whereParts}) THEN ?`);
|
|
61
|
+
for (const id of identifiers) caseBindings.push(id, row[id]);
|
|
62
|
+
caseBindings.push(row[key]);
|
|
80
63
|
}
|
|
81
64
|
const whenThen = whenClauses.join(" ");
|
|
82
65
|
cases.push(`?? = CASE ${whenThen} ELSE ?? END`);
|
|
@@ -88,16 +71,13 @@ function generateBatchUpdateSQL(db, tableName, data, identifiers) {
|
|
|
88
71
|
const whereInBindings = [];
|
|
89
72
|
for (const col of identifiers) {
|
|
90
73
|
whereInBindings.push(col);
|
|
91
|
-
for (const row of data)
|
|
92
|
-
whereInBindings.push(row[col]);
|
|
93
|
-
}
|
|
74
|
+
for (const row of data) whereInBindings.push(row[col]);
|
|
94
75
|
}
|
|
95
|
-
|
|
76
|
+
return db.raw(`UPDATE ?? SET ${cases.join(", ")} WHERE ${whereInClauses}`, [
|
|
96
77
|
tableName,
|
|
97
78
|
...allBindings,
|
|
98
79
|
...whereInBindings
|
|
99
80
|
]);
|
|
100
|
-
return sql;
|
|
101
81
|
}
|
|
102
82
|
var logger;
|
|
103
83
|
var init__batch_update = __esmMin((() => {
|
|
@@ -107,8 +87,8 @@ var init__batch_update = __esmMin((() => {
|
|
|
107
87
|
"batch-update"
|
|
108
88
|
]);
|
|
109
89
|
}));
|
|
110
|
-
|
|
111
90
|
//#endregion
|
|
112
91
|
init__batch_update();
|
|
113
92
|
export { batchUpdate, init__batch_update };
|
|
114
|
-
|
|
93
|
+
|
|
94
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2JhdGNoX3VwZGF0ZS5qcyIsIm5hbWVzIjpbXSwic291cmNlcyI6WyIuLi8uLi9zcmMvZGF0YWJhc2UvX2JhdGNoX3VwZGF0ZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICDslYTrnpjsnZgg66eB7YGs7JeQ7IScIOywuOqzoO2VtOyEnCDqsIDsoLjsmKgg7IaM7Iqk7L2U65OcXG4gIGh0dHBzOi8vZ2l0aHViLmNvbS9rbmV4L2tuZXgvaXNzdWVzLzU3MTZcbiovXG5cbmltcG9ydCB7IGdldExvZ2dlciB9IGZyb20gXCJAbG9ndGFwZS9sb2d0YXBlXCI7XG5pbXBvcnQgeyB0eXBlIEtuZXggfSBmcm9tIFwia25leFwiO1xuXG5jb25zdCBsb2dnZXIgPSBnZXRMb2dnZXIoW1wic29uYW11XCIsIFwiaW50ZXJuYWxcIiwgXCJiYXRjaC11cGRhdGVcIl0pO1xuXG50eXBlIENvbHVtblZhbHVlID0gc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IG51bGw7XG5leHBvcnQgdHlwZSBSb3dXaXRoSWQ8SWQgZXh0ZW5kcyBzdHJpbmc+ID0ge1xuICBba2V5IGluIElkXTogQ29sdW1uVmFsdWU7XG59ICYgUmVjb3JkPHN0cmluZywgQ29sdW1uVmFsdWU+O1xuXG4vKipcbiAqIEJhdGNoIHVwZGF0ZSByb3dzIGluIGEgdGFibGUuIFRlY2huaWNhbGx5IGl0cyBhIHBhdGNoIHNpbmNlIGl0IG9ubHkgdXBkYXRlcyB0aGUgc3BlY2lmaWVkIGNvbHVtbnMuIEFueSBvbWl0dGVkIGNvbHVtbnMgd2lsbCBub3QgYmUgYWZmZWN0ZWRcbiAqIEBwYXJhbSBrbmV4XG4gKiBAcGFyYW0gdGFibGVOYW1lXG4gKiBAcGFyYW0gaWRzXG4gKiBAcGFyYW0gcm93c1xuICogQHBhcmFtIGNodW5rU2l6ZVxuICogQHBhcmFtIHRyeFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYmF0Y2hVcGRhdGU8SWQgZXh0ZW5kcyBzdHJpbmc+KFxuICBrbmV4OiBLbmV4LFxuICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgaWRzOiBJZFtdLFxuICByb3dzOiBSb3dXaXRoSWQ8SWQ+W10sXG4gIGNodW5rU2l6ZSA9IDUwLFxuICB0cng6IEtuZXguVHJhbnNhY3Rpb24gfCBudWxsID0gbnVsbCxcbikge1xuICBjb25zdCBjaHVua3M6IFJvd1dpdGhJZDxJZD5bXVtdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgcm93cy5sZW5ndGg7IGkgKz0gY2h1bmtTaXplKSB7XG4gICAgY2h1bmtzLnB1c2gocm93cy5zbGljZShpLCBpICsgY2h1bmtTaXplKSk7XG4gIH1cblxuICBjb25zdCBleGVjdXRlVXBkYXRlID0gYXN5bmMgKGNodW5rOiBSb3dXaXRoSWQ8SWQ+W10sIHRyYW5zYWN0aW9uOiBLbmV4LlRyYW5zYWN0aW9uKSA9PiB7XG4gICAgY29uc3QgcmF3UXVlcnkgPSBnZW5lcmF0ZUJhdGNoVXBkYXRlU1FMKGtuZXgsIHRhYmxlTmFtZSwgY2h1bmssIGlkcyk7XG4gICAgcmV0dXJuIHJhd1F1ZXJ5LnRyYW5zYWN0aW5nKHRyYW5zYWN0aW9uKTtcbiAgfTtcblxuICBpZiAodHJ4KSB7XG4gICAgZm9yIChjb25zdCBjaHVuayBvZiBjaHVua3MpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcIlByb2Nlc3NpbmcgQmF0Y2ggQ2h1bmsgaW4gRXhpc3RpbmcgVHJhbnNhY3Rpb246IHtjdXJyZW50fSAvIHt0b3RhbH1cIiwge1xuICAgICAgICBjdXJyZW50OiBjaHVuay5sZW5ndGgsXG4gICAgICAgIHRvdGFsOiBjaHVua3MubGVuZ3RoLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCBleGVjdXRlVXBkYXRlKGNodW5rLCB0cngpO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBhd2FpdCBrbmV4LnRyYW5zYWN0aW9uKGFzeW5jIChuZXdUcngpID0+IHtcbiAgICAgIGZvciAoY29uc3QgY2h1bmsgb2YgY2h1bmtzKSB7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhcIlByb2Nlc3NpbmcgQmF0Y2ggQ2h1bmsgaW4gTmV3IFRyYW5zYWN0aW9uOiB7Y3VycmVudH0gLyB7dG90YWx9XCIsIHtcbiAgICAgICAgICBjdXJyZW50OiBjaHVuay5sZW5ndGgsXG4gICAgICAgICAgdG90YWw6IGNodW5rcy5sZW5ndGgsXG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCBleGVjdXRlVXBkYXRlKGNodW5rLCBuZXdUcngpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYSBzZXQgb2YgdW5pcXVlIGtleXMgaW4gYSBkYXRhIGFycmF5XG4gKlxuICogRXhhbXBsZTpcbiAqIFsgeyBhOiAxLCBiOiAyIH0sIHsgYTogMywgYzogNCB9IF0gPT4gU2V0KFsgXCJhXCIsIFwiYlwiLCBcImNcIiBdKVxuICogQHBhcmFtIGRhdGFcbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVLZXlTZXRGcm9tRGF0YShkYXRhOiBSZWNvcmQ8c3RyaW5nLCBDb2x1bW5WYWx1ZT5bXSkge1xuICBjb25zdCBrZXlTZXQ6IFNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuICBmb3IgKGNvbnN0IHJvdyBvZiBkYXRhKSB7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMocm93KSkge1xuICAgICAga2V5U2V0LmFkZChrZXkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4ga2V5U2V0O1xufVxuXG5mdW5jdGlvbiBnZW5lcmF0ZUJhdGNoVXBkYXRlU1FMPElkIGV4dGVuZHMgc3RyaW5nPihcbiAgZGI6IEtuZXgsXG4gIHRhYmxlTmFtZTogc3RyaW5nLFxuICBkYXRhOiBSZWNvcmQ8c3RyaW5nLCBDb2x1bW5WYWx1ZT5bXSxcbiAgaWRlbnRpZmllcnM6IElkW10sXG4pOiBLbmV4LlJhdyB7XG4gIGNvbnN0IGtleVNldCA9IGdlbmVyYXRlS2V5U2V0RnJvbURhdGEoZGF0YSk7XG4gIGNvbnN0IGFsbEJpbmRpbmdzOiAoc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB8IG51bGwpW10gPSBbXTtcblxuICBjb25zdCBpbnZhbGlkSWRlbnRpZmllcnMgPSBpZGVudGlmaWVycy5maWx0ZXIoKGlkKSA9PiAha2V5U2V0LmhhcyhpZCkpO1xuICBpZiAoaW52YWxpZElkZW50aWZpZXJzLmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgSW52YWxpZCBpZGVudGlmaWVyczogJHtpbnZhbGlkSWRlbnRpZmllcnMuam9pbihcIiwgXCIpfS4gSWRlbnRpZmllcnMgbXVzdCBleGlzdCBpbiB0aGUgZGF0YWAsXG4gICAgKTtcbiAgfVxuXG4gIGNvbnN0IGNhc2VzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGZvciAoY29uc3Qga2V5IG9mIGtleVNldCkge1xuICAgIGlmIChpZGVudGlmaWVycy5pbmNsdWRlcyhrZXkgYXMgSWQpKSBjb250aW51ZTtcblxuICAgIGNvbnN0IGNhc2VCaW5kaW5nczogKHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBudWxsKVtdID0gW107XG4gICAgY29uc3Qgd2hlbkNsYXVzZXM6IHN0cmluZ1tdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHJvdyBvZiBkYXRhKSB7XG4gICAgICBpZiAoT2JqZWN0Lmhhc093bihyb3csIGtleSkpIHtcbiAgICAgICAgY29uc3Qgd2hlcmVQYXJ0cyA9IGlkZW50aWZpZXJzLm1hcCgoKSA9PiBgPz8gPSA/YCkuam9pbihcIiBBTkQgXCIpO1xuICAgICAgICB3aGVuQ2xhdXNlcy5wdXNoKGBXSEVOICgke3doZXJlUGFydHN9KSBUSEVOID9gKTtcblxuICAgICAgICAvLyBpZGVudGlmaWVyIOydtOumhOqzvCDqsJLrk6TsnYQg7LaU6rCAXG4gICAgICAgIGZvciAoY29uc3QgaWQgb2YgaWRlbnRpZmllcnMpIHtcbiAgICAgICAgICBjYXNlQmluZGluZ3MucHVzaChpZCwgcm93W2lkXSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gVEhFTiDqsJIg7LaU6rCAXG4gICAgICAgIGNhc2VCaW5kaW5ncy5wdXNoKHJvd1trZXldKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB3aGVuVGhlbiA9IHdoZW5DbGF1c2VzLmpvaW4oXCIgXCIpO1xuICAgIGNhc2VzLnB1c2goYD8/ID0gQ0FTRSAke3doZW5UaGVufSBFTFNFID8/IEVORGApO1xuXG4gICAgLy8g7Lus65+866qFIDLqsJwg7LaU6rCAIChTRVTsnZgg7Lus65+866qFLCBFTFNF7J2YIOy7rOufvOuqhSlcbiAgICBhbGxCaW5kaW5ncy5wdXNoKGtleSk7XG4gICAgYWxsQmluZGluZ3MucHVzaCguLi5jYXNlQmluZGluZ3MpO1xuICAgIGFsbEJpbmRpbmdzLnB1c2goa2V5KTtcbiAgfVxuXG4gIGNvbnN0IHdoZXJlSW5DbGF1c2VzID0gaWRlbnRpZmllcnNcbiAgICAubWFwKChfY29sKSA9PiBgPz8gSU4gKCR7ZGF0YS5tYXAoKCkgPT4gXCI/XCIpLmpvaW4oXCIsIFwiKX0pYClcbiAgICAuam9pbihcIiBBTkQgXCIpO1xuXG4gIGNvbnN0IHdoZXJlSW5CaW5kaW5nczogKHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBudWxsKVtdID0gW107XG4gIGZvciAoY29uc3QgY29sIG9mIGlkZW50aWZpZXJzKSB7XG4gICAgd2hlcmVJbkJpbmRpbmdzLnB1c2goY29sKTtcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiBkYXRhKSB7XG4gICAgICB3aGVyZUluQmluZGluZ3MucHVzaChyb3dbY29sXSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgc3FsID0gZGIucmF3KGBVUERBVEUgPz8gU0VUICR7Y2FzZXMuam9pbihcIiwgXCIpfSBXSEVSRSAke3doZXJlSW5DbGF1c2VzfWAsIFtcbiAgICB0YWJsZU5hbWUsXG4gICAgLi4uYWxsQmluZGluZ3MsXG4gICAgLi4ud2hlcmVJbkJpbmRpbmdzLFxuICBdKTtcblxuICByZXR1cm4gc3FsO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUF3QkEsZUFBc0IsWUFDcEIsTUFDQSxXQUNBLEtBQ0EsTUFDQSxZQUFZLElBQ1osTUFBK0IsTUFDL0I7Q0FDQSxNQUFN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
|