sonamu 0.9.20 → 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 +6 -6
- 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/testing-devrunner.md +1 -1
- 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,12 +1,11 @@
|
|
|
1
|
-
import { __esmMin } from "../_virtual/
|
|
1
|
+
import { __esmMin } from "../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { group } from "radashi";
|
|
3
3
|
import assert from "assert";
|
|
4
|
-
|
|
5
4
|
//#region src/migration/postgresql-schema-reader.ts
|
|
6
5
|
var PostgreSQLSchemaReaderClass, PostgreSQLSchemaReader;
|
|
7
6
|
var init_postgresql_schema_reader = __esmMin((() => {
|
|
8
7
|
PostgreSQLSchemaReaderClass = class {
|
|
9
|
-
genericIndexTypes = new Set([
|
|
8
|
+
genericIndexTypes = /* @__PURE__ */ new Set([
|
|
10
9
|
"btree",
|
|
11
10
|
"hash",
|
|
12
11
|
"gin",
|
|
@@ -24,44 +23,32 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
24
23
|
try {
|
|
25
24
|
[dbColumns, dbIndexes, dbForeigns] = await this.readTable(compareDB, table);
|
|
26
25
|
} catch (e) {
|
|
27
|
-
if (e instanceof Error && e.message.includes("Table not found"))
|
|
28
|
-
return null;
|
|
29
|
-
}
|
|
26
|
+
if (e instanceof Error && e.message.includes("Table not found")) return null;
|
|
30
27
|
console.error(e);
|
|
31
28
|
return null;
|
|
32
29
|
}
|
|
33
30
|
const vectorDimensions = await this.getVectorDimensions(compareDB, table);
|
|
34
31
|
const columns = dbColumns.map((dbColumn) => {
|
|
35
32
|
const dbColType = this.resolveDBColType(dbColumn);
|
|
36
|
-
if (dbColType.type === "vector")
|
|
37
|
-
dbColType.dimensions = vectorDimensions[dbColumn.column_name] ?? 0;
|
|
38
|
-
}
|
|
33
|
+
if (dbColType.type === "vector") dbColType.dimensions = vectorDimensions[dbColumn.column_name] ?? 0;
|
|
39
34
|
return {
|
|
40
35
|
name: dbColumn.column_name,
|
|
41
36
|
nullable: dbColumn.is_nullable === "YES",
|
|
42
37
|
...dbColType,
|
|
43
38
|
...(() => {
|
|
44
|
-
if (dbColumn.is_generated === "s" || dbColumn.is_generated === "v") {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
} };
|
|
49
|
-
}
|
|
39
|
+
if (dbColumn.is_generated === "s" || dbColumn.is_generated === "v") return { generated: {
|
|
40
|
+
type: dbColumn.is_generated === "s" ? "STORED" : "VIRTUAL",
|
|
41
|
+
expression: dbColumn.generation_expression ?? ""
|
|
42
|
+
} };
|
|
50
43
|
return {};
|
|
51
44
|
})(),
|
|
52
45
|
...(() => {
|
|
53
|
-
if (dbColumn.is_generated === "s" || dbColumn.is_generated === "v") {
|
|
54
|
-
return {};
|
|
55
|
-
}
|
|
46
|
+
if (dbColumn.is_generated === "s" || dbColumn.is_generated === "v") return {};
|
|
56
47
|
if (dbColumn.column_default !== null) {
|
|
57
48
|
let defaultValue = dbColumn.column_default;
|
|
58
|
-
if (defaultValue.startsWith("nextval(")) {
|
|
59
|
-
return {};
|
|
60
|
-
}
|
|
49
|
+
if (defaultValue.startsWith("nextval(")) return {};
|
|
61
50
|
defaultValue = defaultValue.replace(/::[\w\s]+$/g, "");
|
|
62
|
-
if (defaultValue.startsWith("'") && defaultValue.endsWith("'"))
|
|
63
|
-
defaultValue = defaultValue.replaceAll("'", "\"");
|
|
64
|
-
}
|
|
51
|
+
if (defaultValue.startsWith("'") && defaultValue.endsWith("'")) defaultValue = defaultValue.replaceAll("'", "\"");
|
|
65
52
|
return { defaultTo: defaultValue };
|
|
66
53
|
}
|
|
67
54
|
return {};
|
|
@@ -69,63 +56,60 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
69
56
|
};
|
|
70
57
|
});
|
|
71
58
|
const dbIndexesGroup = group(dbIndexes.filter((dbIndex) => !dbIndex.is_primary && !dbForeigns.find((dbForeign) => dbIndex.index_name.includes(dbForeign.constraint_name))), (dbIndex) => dbIndex.index_name);
|
|
72
|
-
const indexes = Object.keys(dbIndexesGroup).map((indexName) => {
|
|
73
|
-
const currentIndexes = dbIndexesGroup[indexName]?.toSorted((left, right) => left.column_order - right.column_order);
|
|
74
|
-
assert(currentIndexes);
|
|
75
|
-
const firstIndex = currentIndexes[0];
|
|
76
|
-
const parsedIndexDefinition = this.parseIndexDefinition(firstIndex.index_definition);
|
|
77
|
-
const restoredIndexType = this.restoreMigrationIndexType(firstIndex, parsedIndexDefinition.accessMethod);
|
|
78
|
-
const using = this.restoreGenericUsing(parsedIndexDefinition.accessMethod ?? firstIndex.index_type);
|
|
79
|
-
return {
|
|
80
|
-
type: restoredIndexType,
|
|
81
|
-
name: indexName,
|
|
82
|
-
columns: currentIndexes.map((idx) => ({
|
|
83
|
-
name: idx.column_name,
|
|
84
|
-
...this.extractIndexColumnOpclass(parsedIndexDefinition.columnDefinitions[idx.column_order - 1]) ? { opclass: this.extractIndexColumnOpclass(parsedIndexDefinition.columnDefinitions[idx.column_order - 1]) } : {},
|
|
85
|
-
...using === "btree" ? {
|
|
86
|
-
sortOrder: idx.sort_order,
|
|
87
|
-
nullsFirst: idx.nulls_first
|
|
88
|
-
} : {}
|
|
89
|
-
})),
|
|
90
|
-
nullsNotDistinct: firstIndex.nulls_not_distinct,
|
|
91
|
-
...firstIndex.predicate ? { where: firstIndex.predicate } : {},
|
|
92
|
-
...using ? { using } : {},
|
|
93
|
-
...this.parseVectorIndexOptions(restoredIndexType, parsedIndexDefinition.withOptions)
|
|
94
|
-
};
|
|
95
|
-
});
|
|
96
|
-
const foreigns = dbForeigns.map((dbForeign) => {
|
|
97
|
-
return {
|
|
98
|
-
columns: [dbForeign.column_name],
|
|
99
|
-
to: `${dbForeign.foreign_table_name}.${dbForeign.foreign_column_name}`,
|
|
100
|
-
onUpdate: this.mapConstraintAction(dbForeign.update_rule),
|
|
101
|
-
onDelete: this.mapConstraintAction(dbForeign.delete_rule)
|
|
102
|
-
};
|
|
103
|
-
});
|
|
104
59
|
return {
|
|
105
60
|
table,
|
|
106
61
|
columns,
|
|
107
|
-
indexes
|
|
108
|
-
|
|
62
|
+
indexes: Object.keys(dbIndexesGroup).map((indexName) => {
|
|
63
|
+
const currentIndexes = dbIndexesGroup[indexName]?.toSorted((left, right) => left.column_order - right.column_order);
|
|
64
|
+
assert(currentIndexes);
|
|
65
|
+
const firstIndex = currentIndexes[0];
|
|
66
|
+
const parsedIndexDefinition = this.parseIndexDefinition(firstIndex.index_definition);
|
|
67
|
+
const restoredIndexType = this.restoreMigrationIndexType(firstIndex, parsedIndexDefinition.accessMethod);
|
|
68
|
+
const using = this.restoreGenericUsing(parsedIndexDefinition.accessMethod ?? firstIndex.index_type);
|
|
69
|
+
return {
|
|
70
|
+
type: restoredIndexType,
|
|
71
|
+
name: indexName,
|
|
72
|
+
columns: currentIndexes.map((idx) => ({
|
|
73
|
+
name: idx.column_name,
|
|
74
|
+
...this.extractIndexColumnOpclass(parsedIndexDefinition.columnDefinitions[idx.column_order - 1]) ? { opclass: this.extractIndexColumnOpclass(parsedIndexDefinition.columnDefinitions[idx.column_order - 1]) } : {},
|
|
75
|
+
...using === "btree" ? {
|
|
76
|
+
sortOrder: idx.sort_order,
|
|
77
|
+
nullsFirst: idx.nulls_first
|
|
78
|
+
} : {}
|
|
79
|
+
})),
|
|
80
|
+
nullsNotDistinct: firstIndex.nulls_not_distinct,
|
|
81
|
+
...firstIndex.predicate ? { where: firstIndex.predicate } : {},
|
|
82
|
+
...using ? { using } : {},
|
|
83
|
+
...this.parseVectorIndexOptions(restoredIndexType, parsedIndexDefinition.withOptions)
|
|
84
|
+
};
|
|
85
|
+
}),
|
|
86
|
+
foreigns: dbForeigns.map((dbForeign) => {
|
|
87
|
+
return {
|
|
88
|
+
columns: [dbForeign.column_name],
|
|
89
|
+
to: `${dbForeign.foreign_table_name}.${dbForeign.foreign_column_name}`,
|
|
90
|
+
onUpdate: this.mapConstraintAction(dbForeign.update_rule),
|
|
91
|
+
onDelete: this.mapConstraintAction(dbForeign.delete_rule)
|
|
92
|
+
};
|
|
93
|
+
})
|
|
109
94
|
};
|
|
110
95
|
}
|
|
111
96
|
/**
|
|
112
97
|
* PostgreSQL의 constraint action을 Knex 형식으로 변환
|
|
113
98
|
*/
|
|
114
99
|
mapConstraintAction(action) {
|
|
115
|
-
|
|
100
|
+
return {
|
|
116
101
|
"NO ACTION": "NO ACTION",
|
|
117
102
|
RESTRICT: "RESTRICT",
|
|
118
103
|
CASCADE: "CASCADE",
|
|
119
104
|
"SET NULL": "SET NULL",
|
|
120
105
|
"SET DEFAULT": "SET DEFAULT"
|
|
121
|
-
};
|
|
122
|
-
return actionMap[action] ?? "NO ACTION";
|
|
106
|
+
}[action] ?? "NO ACTION";
|
|
123
107
|
}
|
|
124
108
|
/**
|
|
125
109
|
* 기존 테이블 읽어서 cols, indexes, foreigns 반환
|
|
126
110
|
*/
|
|
127
111
|
async readTable(compareDB, tableName) {
|
|
128
|
-
const
|
|
112
|
+
const columns = (await compareDB.raw(`
|
|
129
113
|
SELECT
|
|
130
114
|
c.column_name,
|
|
131
115
|
c.data_type,
|
|
@@ -152,12 +136,11 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
152
136
|
WHERE c.table_name = ?
|
|
153
137
|
AND c.table_schema = 'public'
|
|
154
138
|
ORDER BY c.ordinal_position
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
const indexesQuery = `
|
|
139
|
+
`, [tableName])).rows;
|
|
140
|
+
if (columns.length === 0) throw new Error(`Table not found: ${tableName}`);
|
|
141
|
+
return [
|
|
142
|
+
columns,
|
|
143
|
+
(await compareDB.raw(`
|
|
161
144
|
SELECT
|
|
162
145
|
i.relname AS index_name,
|
|
163
146
|
CASE
|
|
@@ -217,9 +200,8 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
217
200
|
WHERE t.relname = ?
|
|
218
201
|
AND (u.attnum > 0 OR (am.amname = 'pgroonga' AND u.attnum = 0))
|
|
219
202
|
ORDER BY i.relname, u.ord;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const foreignsQuery = `
|
|
203
|
+
`, [tableName])).rows,
|
|
204
|
+
(await compareDB.raw(`
|
|
223
205
|
SELECT
|
|
224
206
|
tc.constraint_name,
|
|
225
207
|
kcu.column_name,
|
|
@@ -239,62 +221,39 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
239
221
|
AND rc.constraint_schema = tc.table_schema
|
|
240
222
|
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
241
223
|
AND tc.table_name = ?
|
|
242
|
-
|
|
243
|
-
const foreigns = (await compareDB.raw(foreignsQuery, [tableName])).rows;
|
|
244
|
-
return [
|
|
245
|
-
columns,
|
|
246
|
-
indexes,
|
|
247
|
-
foreigns
|
|
224
|
+
`, [tableName])).rows
|
|
248
225
|
];
|
|
249
226
|
}
|
|
250
227
|
restoreMigrationIndexType(index, accessMethod) {
|
|
251
228
|
const resolvedAccessMethod = (accessMethod ?? index.index_type).toLowerCase();
|
|
252
|
-
if (resolvedAccessMethod === "hnsw" || resolvedAccessMethod === "ivfflat")
|
|
253
|
-
return resolvedAccessMethod;
|
|
254
|
-
}
|
|
229
|
+
if (resolvedAccessMethod === "hnsw" || resolvedAccessMethod === "ivfflat") return resolvedAccessMethod;
|
|
255
230
|
return index.is_unique ? "unique" : "index";
|
|
256
231
|
}
|
|
257
232
|
restoreGenericUsing(accessMethod) {
|
|
258
|
-
if (!accessMethod)
|
|
259
|
-
return undefined;
|
|
260
|
-
}
|
|
233
|
+
if (!accessMethod) return;
|
|
261
234
|
const normalized = accessMethod.toLowerCase();
|
|
262
|
-
if (!this.genericIndexTypes.has(normalized))
|
|
263
|
-
return undefined;
|
|
264
|
-
}
|
|
235
|
+
if (!this.genericIndexTypes.has(normalized)) return;
|
|
265
236
|
return normalized;
|
|
266
237
|
}
|
|
267
238
|
parseVectorIndexOptions(type, withOptions) {
|
|
268
|
-
if (type === "hnsw") {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
}
|
|
274
|
-
if (type === "ivfflat") {
|
|
275
|
-
return this.parseIntegerOption(withOptions.lists) !== undefined ? { lists: this.parseIntegerOption(withOptions.lists) } : {};
|
|
276
|
-
}
|
|
239
|
+
if (type === "hnsw") return {
|
|
240
|
+
...this.parseIntegerOption(withOptions.m) !== void 0 ? { m: this.parseIntegerOption(withOptions.m) } : {},
|
|
241
|
+
...this.parseIntegerOption(withOptions.ef_construction) !== void 0 ? { efConstruction: this.parseIntegerOption(withOptions.ef_construction) } : {}
|
|
242
|
+
};
|
|
243
|
+
if (type === "ivfflat") return this.parseIntegerOption(withOptions.lists) !== void 0 ? { lists: this.parseIntegerOption(withOptions.lists) } : {};
|
|
277
244
|
return {};
|
|
278
245
|
}
|
|
279
246
|
parseIntegerOption(value) {
|
|
280
|
-
if (!value)
|
|
281
|
-
return undefined;
|
|
282
|
-
}
|
|
247
|
+
if (!value) return;
|
|
283
248
|
const parsed = Number.parseInt(value, 10);
|
|
284
|
-
return Number.isNaN(parsed) ?
|
|
249
|
+
return Number.isNaN(parsed) ? void 0 : parsed;
|
|
285
250
|
}
|
|
286
251
|
extractIndexColumnOpclass(columnDefinition) {
|
|
287
|
-
if (!columnDefinition)
|
|
288
|
-
return undefined;
|
|
289
|
-
}
|
|
252
|
+
if (!columnDefinition) return;
|
|
290
253
|
const trimmed = columnDefinition.replace(/\s+NULLS\s+(FIRST|LAST)\s*$/i, "").replace(/\s+(ASC|DESC)\s*$/i, "").trim();
|
|
291
254
|
const tokens = this.tokenizeTopLevel(trimmed);
|
|
292
|
-
if (tokens.length < 2)
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
if (tokens[tokens.length - 2]?.toUpperCase() === "COLLATE") {
|
|
296
|
-
return undefined;
|
|
297
|
-
}
|
|
255
|
+
if (tokens.length < 2) return;
|
|
256
|
+
if (tokens[tokens.length - 2]?.toUpperCase() === "COLLATE") return;
|
|
298
257
|
return tokens.at(-1);
|
|
299
258
|
}
|
|
300
259
|
parseIndexDefinition(indexDefinition) {
|
|
@@ -306,19 +265,16 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
306
265
|
const withMatch = /\bWITH\s*\(/i.exec(indexDefinition);
|
|
307
266
|
const withStart = withMatch ? indexDefinition.indexOf("(", withMatch.index) : -1;
|
|
308
267
|
const withEnd = withStart >= 0 ? this.findMatchingParenthesis(indexDefinition, withStart) : -1;
|
|
309
|
-
const withOptions = withStart >= 0 && withEnd > withStart ? this.parseIndexOptionEntries(indexDefinition.slice(withStart + 1, withEnd)) : {};
|
|
310
268
|
return {
|
|
311
269
|
accessMethod,
|
|
312
270
|
columnDefinitions,
|
|
313
|
-
withOptions
|
|
271
|
+
withOptions: withStart >= 0 && withEnd > withStart ? this.parseIndexOptionEntries(indexDefinition.slice(withStart + 1, withEnd)) : {}
|
|
314
272
|
};
|
|
315
273
|
}
|
|
316
274
|
parseIndexOptionEntries(optionSource) {
|
|
317
275
|
return this.splitTopLevel(optionSource, ",").reduce((result, entry) => {
|
|
318
276
|
const matched = entry.trim().match(/^([a-z_][\w]*)\s*=\s*(.+)$/i);
|
|
319
|
-
if (!matched)
|
|
320
|
-
return result;
|
|
321
|
-
}
|
|
277
|
+
if (!matched) return result;
|
|
322
278
|
const [, key, rawValue] = matched;
|
|
323
279
|
result[key.toLowerCase()] = rawValue.trim().replace(/^['"]|['"]$/g, "");
|
|
324
280
|
return result;
|
|
@@ -350,9 +306,7 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
350
306
|
inDoubleQuote = !inDoubleQuote;
|
|
351
307
|
continue;
|
|
352
308
|
}
|
|
353
|
-
if (inSingleQuote || inDoubleQuote)
|
|
354
|
-
continue;
|
|
355
|
-
}
|
|
309
|
+
if (inSingleQuote || inDoubleQuote) continue;
|
|
356
310
|
if (char === "(") {
|
|
357
311
|
parenDepth += 1;
|
|
358
312
|
continue;
|
|
@@ -375,9 +329,7 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
375
329
|
}
|
|
376
330
|
}
|
|
377
331
|
const tail = source.slice(start).trim();
|
|
378
|
-
if (tail.length > 0)
|
|
379
|
-
items.push(tail);
|
|
380
|
-
}
|
|
332
|
+
if (tail.length > 0) items.push(tail);
|
|
381
333
|
return items;
|
|
382
334
|
}
|
|
383
335
|
tokenizeTopLevel(source) {
|
|
@@ -388,22 +340,16 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
388
340
|
let inSingleQuote = false;
|
|
389
341
|
let inDoubleQuote = false;
|
|
390
342
|
const pushToken = (endIndex) => {
|
|
391
|
-
if (start < 0)
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
343
|
+
if (start < 0) return;
|
|
394
344
|
const token = source.slice(start, endIndex).trim();
|
|
395
|
-
if (token.length > 0)
|
|
396
|
-
tokens.push(token);
|
|
397
|
-
}
|
|
345
|
+
if (token.length > 0) tokens.push(token);
|
|
398
346
|
start = -1;
|
|
399
347
|
};
|
|
400
348
|
for (let index = 0; index < source.length; index += 1) {
|
|
401
349
|
const char = source[index];
|
|
402
350
|
const nextChar = source[index + 1];
|
|
403
351
|
if (char === "'" && !inDoubleQuote) {
|
|
404
|
-
if (start < 0)
|
|
405
|
-
start = index;
|
|
406
|
-
}
|
|
352
|
+
if (start < 0) start = index;
|
|
407
353
|
if (inSingleQuote && nextChar === "'") {
|
|
408
354
|
index += 1;
|
|
409
355
|
continue;
|
|
@@ -412,9 +358,7 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
412
358
|
continue;
|
|
413
359
|
}
|
|
414
360
|
if (char === "\"" && !inSingleQuote) {
|
|
415
|
-
if (start < 0)
|
|
416
|
-
start = index;
|
|
417
|
-
}
|
|
361
|
+
if (start < 0) start = index;
|
|
418
362
|
if (inDoubleQuote && nextChar === "\"") {
|
|
419
363
|
index += 1;
|
|
420
364
|
continue;
|
|
@@ -424,9 +368,7 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
424
368
|
}
|
|
425
369
|
if (!inSingleQuote && !inDoubleQuote) {
|
|
426
370
|
if (char === "(") {
|
|
427
|
-
if (start < 0)
|
|
428
|
-
start = index;
|
|
429
|
-
}
|
|
371
|
+
if (start < 0) start = index;
|
|
430
372
|
parenDepth += 1;
|
|
431
373
|
continue;
|
|
432
374
|
}
|
|
@@ -435,9 +377,7 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
435
377
|
continue;
|
|
436
378
|
}
|
|
437
379
|
if (char === "[") {
|
|
438
|
-
if (start < 0)
|
|
439
|
-
start = index;
|
|
440
|
-
}
|
|
380
|
+
if (start < 0) start = index;
|
|
441
381
|
bracketDepth += 1;
|
|
442
382
|
continue;
|
|
443
383
|
}
|
|
@@ -450,9 +390,7 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
450
390
|
continue;
|
|
451
391
|
}
|
|
452
392
|
}
|
|
453
|
-
if (start < 0)
|
|
454
|
-
start = index;
|
|
455
|
-
}
|
|
393
|
+
if (start < 0) start = index;
|
|
456
394
|
}
|
|
457
395
|
pushToken(source.length);
|
|
458
396
|
return tokens;
|
|
@@ -480,18 +418,14 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
480
418
|
inDoubleQuote = !inDoubleQuote;
|
|
481
419
|
continue;
|
|
482
420
|
}
|
|
483
|
-
if (inSingleQuote || inDoubleQuote)
|
|
484
|
-
continue;
|
|
485
|
-
}
|
|
421
|
+
if (inSingleQuote || inDoubleQuote) continue;
|
|
486
422
|
if (char === "(") {
|
|
487
423
|
depth += 1;
|
|
488
424
|
continue;
|
|
489
425
|
}
|
|
490
426
|
if (char === ")") {
|
|
491
427
|
depth -= 1;
|
|
492
|
-
if (depth === 0)
|
|
493
|
-
return index;
|
|
494
|
-
}
|
|
428
|
+
if (depth === 0) return index;
|
|
495
429
|
}
|
|
496
430
|
}
|
|
497
431
|
return -1;
|
|
@@ -501,7 +435,7 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
501
435
|
* PK 타입 변경 시 관련 FK 제약조건을 삭제/복구하기 위해 사용됩니다.
|
|
502
436
|
*/
|
|
503
437
|
async getReferencingForeignKeys(db, tableName) {
|
|
504
|
-
|
|
438
|
+
return (await db.raw(`
|
|
505
439
|
SELECT
|
|
506
440
|
tc.table_name,
|
|
507
441
|
tc.constraint_name,
|
|
@@ -523,9 +457,7 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
523
457
|
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
524
458
|
AND ccu.table_name = ?
|
|
525
459
|
AND tc.table_schema = 'public'
|
|
526
|
-
|
|
527
|
-
const result = await db.raw(query, [tableName]);
|
|
528
|
-
return result.rows.map((row) => ({
|
|
460
|
+
`, [tableName])).rows.map((row) => ({
|
|
529
461
|
tableName: row.table_name,
|
|
530
462
|
constraintName: row.constraint_name,
|
|
531
463
|
columnName: row.column_name,
|
|
@@ -540,7 +472,7 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
540
472
|
* pg_attribute의 atttypmod에서 차원 수를 추출합니다.
|
|
541
473
|
*/
|
|
542
474
|
async getVectorDimensions(compareDB, tableName) {
|
|
543
|
-
const
|
|
475
|
+
const result = await compareDB.raw(`
|
|
544
476
|
SELECT
|
|
545
477
|
a.attname as column_name,
|
|
546
478
|
a.atttypmod as dimensions
|
|
@@ -550,12 +482,9 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
550
482
|
WHERE c.relname = ?
|
|
551
483
|
AND t.typname = 'vector'
|
|
552
484
|
AND a.attnum > 0
|
|
553
|
-
|
|
554
|
-
const result = await compareDB.raw(query, [tableName]);
|
|
485
|
+
`, [tableName]);
|
|
555
486
|
const dimensions = {};
|
|
556
|
-
for (const row of result.rows)
|
|
557
|
-
dimensions[row.column_name] = row.dimensions > 0 ? row.dimensions : 0;
|
|
558
|
-
}
|
|
487
|
+
for (const row of result.rows) dimensions[row.column_name] = row.dimensions > 0 ? row.dimensions : 0;
|
|
559
488
|
return dimensions;
|
|
560
489
|
}
|
|
561
490
|
/**
|
|
@@ -564,85 +493,57 @@ var init_postgresql_schema_reader = __esmMin((() => {
|
|
|
564
493
|
resolveDBColType(dbColumn) {
|
|
565
494
|
const { udt_name: _udt_name, character_maximum_length, precision, numeric_scale } = dbColumn;
|
|
566
495
|
const { udt_name, singleOrArray } = (() => {
|
|
567
|
-
if (_udt_name.startsWith("_")) {
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
};
|
|
572
|
-
}
|
|
496
|
+
if (_udt_name.startsWith("_")) return {
|
|
497
|
+
udt_name: _udt_name.substring(1),
|
|
498
|
+
singleOrArray: "[]"
|
|
499
|
+
};
|
|
573
500
|
return {
|
|
574
501
|
udt_name: _udt_name,
|
|
575
502
|
singleOrArray: ""
|
|
576
503
|
};
|
|
577
504
|
})();
|
|
578
|
-
if (udt_name === "uuid") {
|
|
579
|
-
|
|
580
|
-
}
|
|
581
|
-
if (udt_name === "
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
}
|
|
612
|
-
if (udt_name === "
|
|
613
|
-
return {
|
|
614
|
-
type: `numberOrNumeric${singleOrArray}`,
|
|
615
|
-
numberType: "double precision"
|
|
616
|
-
};
|
|
617
|
-
}
|
|
618
|
-
if (udt_name === "bool") {
|
|
619
|
-
return { type: `boolean${singleOrArray}` };
|
|
620
|
-
}
|
|
621
|
-
if (udt_name === "timestamptz") {
|
|
622
|
-
return {
|
|
623
|
-
type: `date${singleOrArray}`,
|
|
624
|
-
...precision !== null && { precision }
|
|
625
|
-
};
|
|
626
|
-
}
|
|
627
|
-
if (udt_name === "json" || udt_name === "jsonb") {
|
|
628
|
-
return { type: "json" };
|
|
629
|
-
}
|
|
630
|
-
if (udt_name === "vector") {
|
|
631
|
-
return {
|
|
632
|
-
type: `vector${singleOrArray}`,
|
|
633
|
-
dimensions: 0
|
|
634
|
-
};
|
|
635
|
-
}
|
|
636
|
-
if (udt_name === "tsvector") {
|
|
637
|
-
return { type: "tsvector" };
|
|
638
|
-
}
|
|
505
|
+
if (udt_name === "uuid") return { type: `uuid${singleOrArray}` };
|
|
506
|
+
if (udt_name === "int4") return { type: `integer${singleOrArray}` };
|
|
507
|
+
if (udt_name === "int8") return { type: `bigInteger${singleOrArray}` };
|
|
508
|
+
if (udt_name === "varchar") return {
|
|
509
|
+
type: `string${singleOrArray}`,
|
|
510
|
+
...character_maximum_length && { length: character_maximum_length }
|
|
511
|
+
};
|
|
512
|
+
if (udt_name === "text") return { type: `string${singleOrArray}` };
|
|
513
|
+
if (udt_name === "numeric") return {
|
|
514
|
+
type: `numberOrNumeric${singleOrArray}`,
|
|
515
|
+
numberType: "numeric",
|
|
516
|
+
...precision !== null && numeric_scale !== null && {
|
|
517
|
+
precision,
|
|
518
|
+
scale: numeric_scale
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
if (udt_name === "float4") return {
|
|
522
|
+
type: `numberOrNumeric${singleOrArray}`,
|
|
523
|
+
numberType: "real"
|
|
524
|
+
};
|
|
525
|
+
if (udt_name === "float8") return {
|
|
526
|
+
type: `numberOrNumeric${singleOrArray}`,
|
|
527
|
+
numberType: "double precision"
|
|
528
|
+
};
|
|
529
|
+
if (udt_name === "bool") return { type: `boolean${singleOrArray}` };
|
|
530
|
+
if (udt_name === "timestamptz") return {
|
|
531
|
+
type: `date${singleOrArray}`,
|
|
532
|
+
...precision !== null && { precision }
|
|
533
|
+
};
|
|
534
|
+
if (udt_name === "json" || udt_name === "jsonb") return { type: "json" };
|
|
535
|
+
if (udt_name === "vector") return {
|
|
536
|
+
type: `vector${singleOrArray}`,
|
|
537
|
+
dimensions: 0
|
|
538
|
+
};
|
|
539
|
+
if (udt_name === "tsvector") return { type: "tsvector" };
|
|
639
540
|
throw new Error(`resolve 불가능한 PostgreSQL 컬럼 타입: ${udt_name}`);
|
|
640
541
|
}
|
|
641
542
|
};
|
|
642
543
|
PostgreSQLSchemaReader = new PostgreSQLSchemaReaderClass();
|
|
643
544
|
}));
|
|
644
|
-
|
|
645
545
|
//#endregion
|
|
646
546
|
init_postgresql_schema_reader();
|
|
647
547
|
export { PostgreSQLSchemaReader, init_postgresql_schema_reader };
|
|
648
|
-
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9zdGdyZXNxbC1zY2hlbWEtcmVhZGVyLmpzIiwibmFtZXMiOlsiZGJDb2x1bW5zOiBQZ0NvbHVtbltdIiwiZGJJbmRleGVzOiBQZ0luZGV4W10iLCJkYkZvcmVpZ25zOiBQZ0ZvcmVpZ25bXSIsImU6IHVua25vd24iLCJjb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSIsImluZGV4ZXM6IE1pZ3JhdGlvbkluZGV4W10iLCJmb3JlaWduczogTWlncmF0aW9uRm9yZWlnbltdIiwiYWN0aW9uTWFwOiBSZWNvcmQ8c3RyaW5nLCBSZWxhdGlvbk9uPiIsIml0ZW1zOiBzdHJpbmdbXSIsInRva2Vuczogc3RyaW5nW10iLCJkaW1lbnNpb25zOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL21pZ3JhdGlvbi9wb3N0Z3Jlc3FsLXNjaGVtYS1yZWFkZXIudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGFzc2VydCBmcm9tIFwiYXNzZXJ0XCI7XG5cbmltcG9ydCB7IHR5cGUgS25leCB9IGZyb20gXCJrbmV4XCI7XG5pbXBvcnQgeyBncm91cCB9IGZyb20gXCJyYWRhc2hpXCI7XG5cbmltcG9ydCB7XG4gIHR5cGUgTWlncmF0aW9uQ29sdW1uLFxuICB0eXBlIE1pZ3JhdGlvbkZvcmVpZ24sXG4gIHR5cGUgTWlncmF0aW9uSW5kZXgsXG4gIHR5cGUgTWlncmF0aW9uU2V0LFxuICB0eXBlIFJlbGF0aW9uT24sXG59IGZyb20gXCIuLi90eXBlcy90eXBlc1wiO1xuXG4vKipcbiAqIO2KueyglSDthYzsnbTruJTsnZggUEvrpbwg7LC47KGw7ZWY64qUIOuLpOuluCDthYzsnbTruJTsnZggRksg7KCV67O07J6F64uI64ukLlxuICogUEsg7YOA7J6FIOuzgOqyvSDsi5wg6rSA66CoIEZLIOygnOyVveyhsOqxtOydhCDsspjrpqztlZjquLAg7JyE7ZW0IOyCrOyaqeuQqeuLiOuLpC5cbiAqL1xuZXhwb3J0IHR5cGUgUmVmZXJlbmNpbmdGb3JlaWduS2V5ID0ge1xuICAvKiogRkvqsIAg7KCV7J2Y65CcIO2FjOydtOu4lOuqhSAqL1xuICB0YWJsZU5hbWU6IHN0cmluZztcbiAgLyoqIEZLIOygnOyVveyhsOqxtCDsnbTrpoQgKi9cbiAgY29uc3RyYWludE5hbWU6IHN0cmluZztcbiAgLyoqIEZLIOy7rOufvOuqhSAqL1xuICBjb2x1bW5OYW1lOiBzdHJpbmc7XG4gIC8qKiDssLjsobDtlZjripQg7YWM7J2067iU66qFIChQS+qwgCDsnojripQg7YWM7J2067iUKSAqL1xuICByZWZlcmVuY2VkVGFibGVOYW1lOiBzdHJpbmc7XG4gIC8qKiDssLjsobDtlZjripQg7Lus65+866qFICjrs7TthrUgJ2lkJykgKi9cbiAgcmVmZXJlbmNlZENvbHVtbk5hbWU6IHN0cmluZztcbiAgLyoqIE9OIFVQREFURSDslaHshZggKi9cbiAgb25VcGRhdGU6IFJlbGF0aW9uT247XG4gIC8qKiBPTiBERUxFVEUg7JWh7IWYICovXG4gIG9uRGVsZXRlOiBSZWxhdGlvbk9uO1xufTtcblxuZXhwb3J0IHR5cGUgUGdDb2x1bW4gPSB7XG4gIGNvbHVtbl9uYW1lOiBzdHJpbmc7XG4gIGRhdGFfdHlwZTogc3RyaW5nO1xuICB1ZHRfbmFtZTogc3RyaW5nO1xuICBjaGFyYWN0ZXJfbWF4aW11bV9sZW5ndGg6IG51bWJlciB8IG51bGw7XG4gIHByZWNpc2lvbjogbnVtYmVyIHwgbnVsbDtcbiAgbnVtZXJpY19zY2FsZTogbnVtYmVyIHwgbnVsbDtcbiAgaXNfbnVsbGFibGU6IHN0cmluZztcbiAgY29sdW1uX2RlZmF1bHQ6IHN0cmluZyB8IG51bGw7XG4gIGlzX2dlbmVyYXRlZDogc3RyaW5nOyAvLyAncycgPSBTVE9SRUQsICd2JyA9IFZJUlRVQUwsICcnID0gbm9uZVxuICBnZW5lcmF0aW9uX2V4cHJlc3Npb246IHN0cmluZyB8IG51bGw7XG59O1xuXG50eXBlIFBnSW5kZXggPSB7XG4gIGluZGV4X25hbWU6IHN0cmluZztcbiAgY29sdW1uX25hbWU6IHN0cmluZztcbiAgaXNfdW5pcXVlOiBib29sZWFuO1xuICBpc19wcmltYXJ5OiBib29sZWFuO1xuICBpbmRleF90eXBlOiBzdHJpbmc7XG4gIG51bGxzX2ZpcnN0OiBib29sZWFuO1xuICBzb3J0X29yZGVyOiBcIkFTQ1wiIHwgXCJERVNDXCI7XG4gIG51bGxzX25vdF9kaXN0aW5jdDogYm9vbGVhbjtcbiAgY29sdW1uX29yZGVyOiBudW1iZXI7XG4gIGluZGV4X2RlZmluaXRpb246IHN0cmluZztcbiAgcHJlZGljYXRlPzogc3RyaW5nIHwgbnVsbDtcbn07XG5cbnR5cGUgUGdGb3JlaWduID0ge1xuICBjb25zdHJhaW50X25hbWU6IHN0cmluZztcbiAgY29sdW1uX25hbWU6IHN0cmluZztcbiAgZm9yZWlnbl90YWJsZV9uYW1lOiBzdHJpbmc7XG4gIGZvcmVpZ25fY29sdW1uX25hbWU6IHN0cmluZztcbiAgdXBkYXRlX3J1bGU6IHN0cmluZztcbiAgZGVsZXRlX3J1bGU6IHN0cmluZztcbn07XG5cbnR5cGUgUmF3Q2FwYWJsZUtuZXggPSBQaWNrPEtuZXgsIFwicmF3XCI+O1xuXG5jbGFzcyBQb3N0Z3JlU1FMU2NoZW1hUmVhZGVyQ2xhc3Mge1xuICBwcml2YXRlIHJlYWRvbmx5IGdlbmVyaWNJbmRleFR5cGVzID0gbmV3IFNldChbXCJidHJlZVwiLCBcImhhc2hcIiwgXCJnaW5cIiwgXCJnaXN0XCIsIFwicGdyb29uZ2FcIl0pO1xuXG4gIC8qKlxuICAgKiBEQuyXkOyEnCDthYzsnbTruJQg7KCV67O066W8IOydveyWtOyEnCBNaWdyYXRpb25TZXTsnYQg66eM65Ok7Ja07Ji164uI64ukLlxuICAgKiBAcGFyYW0gY29tcGFyZURCIEtuZXgg7J247Iqk7YS07IqkXG4gICAqIEBwYXJhbSB0YWJsZSDthYzsnbTruJQg7J2066aEXG4gICAqIEByZXR1cm5zIE1pZ3JhdGlvblNldCDqsJ3ssrRcbiAgICovXG4gIGFzeW5jIGdldE1pZ3JhdGlvblNldEZyb21EQihcbiAgICBjb21wYXJlREI6IFJhd0NhcGFibGVLbmV4LFxuICAgIHRhYmxlOiBzdHJpbmcsXG4gICk6IFByb21pc2U8TWlncmF0aW9uU2V0IHwgbnVsbD4ge1xuICAgIGxldCBkYkNvbHVtbnM6IFBnQ29sdW1uW10sIGRiSW5kZXhlczogUGdJbmRleFtdLCBkYkZvcmVpZ25zOiBQZ0ZvcmVpZ25bXTtcbiAgICB0cnkge1xuICAgICAgW2RiQ29sdW1ucywgZGJJbmRleGVzLCBkYkZvcmVpZ25zXSA9IGF3YWl0IHRoaXMucmVhZFRhYmxlKGNvbXBhcmVEQiwgdGFibGUpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIGlmIChlIGluc3RhbmNlb2YgRXJyb3IgJiYgZS5tZXNzYWdlLmluY2x1ZGVzKFwiVGFibGUgbm90IGZvdW5kXCIpKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIHZlY3RvciDsu6zrn7zsnZggZGltZW5zaW9ucyDsobDtmoxcbiAgICBjb25zdCB2ZWN0b3JEaW1lbnNpb25zID0gYXdhaXQgdGhpcy5nZXRWZWN0b3JEaW1lbnNpb25zKGNvbXBhcmVEQiwgdGFibGUpO1xuXG4gICAgY29uc3QgY29sdW1uczogTWlncmF0aW9uQ29sdW1uW10gPSBkYkNvbHVtbnMubWFwKChkYkNvbHVtbikgPT4ge1xuICAgICAgY29uc3QgZGJDb2xUeXBlID0gdGhpcy5yZXNvbHZlREJDb2xUeXBlKGRiQ29sdW1uKTtcblxuICAgICAgLy8gdmVjdG9yIO2DgOyeheyduCDqsr3smrAgZGltZW5zaW9ucyDshKTsoJVcbiAgICAgIGlmIChkYkNvbFR5cGUudHlwZSA9PT0gXCJ2ZWN0b3JcIikge1xuICAgICAgICBkYkNvbFR5cGUuZGltZW5zaW9ucyA9IHZlY3RvckRpbWVuc2lvbnNbZGJDb2x1bW4uY29sdW1uX25hbWVdID8/IDA7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIG5hbWU6IGRiQ29sdW1uLmNvbHVtbl9uYW1lLFxuICAgICAgICBudWxsYWJsZTogZGJDb2x1bW4uaXNfbnVsbGFibGUgPT09IFwiWUVTXCIsXG4gICAgICAgIC4uLmRiQ29sVHlwZSxcbiAgICAgICAgLy8gR2VuZXJhdGVkIENvbHVtbiDsspjrpqxcbiAgICAgICAgLi4uKCgpID0+IHtcbiAgICAgICAgICBpZiAoZGJDb2x1bW4uaXNfZ2VuZXJhdGVkID09PSBcInNcIiB8fCBkYkNvbHVtbi5pc19nZW5lcmF0ZWQgPT09IFwidlwiKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBnZW5lcmF0ZWQ6IHtcbiAgICAgICAgICAgICAgICB0eXBlOiBkYkNvbHVtbi5pc19nZW5lcmF0ZWQgPT09IFwic1wiID8gXCJTVE9SRURcIiA6IFwiVklSVFVBTFwiLFxuICAgICAgICAgICAgICAgIGV4cHJlc3Npb246IGRiQ29sdW1uLmdlbmVyYXRpb25fZXhwcmVzc2lvbiA/PyBcIlwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICB9KSgpLFxuICAgICAgICAvLyBEZWZhdWx0IOqwkiDsspjrpqwgKEdlbmVyYXRlZCBDb2x1bW7snbQg7JWE64uMIOqyveyasOunjClcbiAgICAgICAgLi4uKCgpID0+IHtcbiAgICAgICAgICAvLyBHZW5lcmF0ZWQgQ29sdW1u7J2AIGRlZmF1bHQg6rCS7J20IOyXhuydjFxuICAgICAgICAgIGlmIChkYkNvbHVtbi5pc19nZW5lcmF0ZWQgPT09IFwic1wiIHx8IGRiQ29sdW1uLmlzX2dlbmVyYXRlZCA9PT0gXCJ2XCIpIHtcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoZGJDb2x1bW4uY29sdW1uX2RlZmF1bHQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIC8vIFBvc3RncmVTUUwgZGVmYXVsdCDqsJIg7KCV66asIChuZXh0dmFsLCBDVVJSRU5UX1RJTUVTVEFNUCDrk7EpXG4gICAgICAgICAgICBsZXQgZGVmYXVsdFZhbHVlID0gZGJDb2x1bW4uY29sdW1uX2RlZmF1bHQ7XG5cbiAgICAgICAgICAgIC8vIG5leHR2YWwg7KCc6rGwIChTRVJJQUwg7YOA7J6FKVxuICAgICAgICAgICAgaWYgKGRlZmF1bHRWYWx1ZS5zdGFydHNXaXRoKFwibmV4dHZhbChcIikpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHt9O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyDtg4DsnoUg7LqQ7Iqk7YyFIOygnOqxsCAo7JiIOiAnMSc6OmludGVnZXIg4oaSIDEpXG4gICAgICAgICAgICBkZWZhdWx0VmFsdWUgPSBkZWZhdWx0VmFsdWUucmVwbGFjZSgvOjpbXFx3XFxzXSskL2csIFwiXCIpO1xuXG4gICAgICAgICAgICAvLyDrlLDsmLTtkZzqsIAgc2luZ2xlIHF1b3Rl7J24IOqyveyasCBkb3VibGUgcXVvdGXroZwg67OA7ZmYXG4gICAgICAgICAgICBpZiAoZGVmYXVsdFZhbHVlLnN0YXJ0c1dpdGgoXCInXCIpICYmIGRlZmF1bHRWYWx1ZS5lbmRzV2l0aChcIidcIikpIHtcbiAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlID0gZGVmYXVsdFZhbHVlLnJlcGxhY2VBbGwoXCInXCIsICdcIicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBkZWZhdWx0VG86IGRlZmF1bHRWYWx1ZSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgfSkoKSxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBQUklNQVJZIEtFWeyZgCBmb3JlaWduIGtleeyaqSDsnbjrjbHsiqQg7KCc7Jm4XG4gICAgY29uc3QgZGJJbmRleGVzR3JvdXAgPSBncm91cChcbiAgICAgIGRiSW5kZXhlcy5maWx0ZXIoXG4gICAgICAgIChkYkluZGV4KSA9PlxuICAgICAgICAgICFkYkluZGV4LmlzX3ByaW1hcnkgJiZcbiAgICAgICAgICAhZGJGb3JlaWducy5maW5kKChkYkZvcmVpZ24pID0+IGRiSW5kZXguaW5kZXhfbmFtZS5pbmNsdWRlcyhkYkZvcmVpZ24uY29uc3RyYWludF9uYW1lKSksXG4gICAgICApLFxuICAgICAgKGRiSW5kZXgpID0+IGRiSW5kZXguaW5kZXhfbmFtZSxcbiAgICApO1xuXG4gICAgLy8gaW5kZXhlcyDsspjrpqxcbiAgICBjb25zdCBpbmRleGVzOiBNaWdyYXRpb25JbmRleFtdID0gT2JqZWN0LmtleXMoZGJJbmRleGVzR3JvdXApLm1hcCgoaW5kZXhOYW1lKSA9PiB7XG4gICAgICBjb25zdCBjdXJyZW50SW5kZXhlcyA9IGRiSW5kZXhlc0dyb3VwW2luZGV4TmFtZV0/LnRvU29ydGVkKFxuICAgICAgICAobGVmdCwgcmlnaHQpID0+IGxlZnQuY29sdW1uX29yZGVyIC0gcmlnaHQuY29sdW1uX29yZGVyLFxuICAgICAgKTtcbiAgICAgIGFzc2VydChjdXJyZW50SW5kZXhlcyk7XG5cbiAgICAgIGNvbnN0IGZpcnN0SW5kZXggPSBjdXJyZW50SW5kZXhlc1swXTtcbiAgICAgIGNvbnN0IHBhcnNlZEluZGV4RGVmaW5pdGlvbiA9IHRoaXMucGFyc2VJbmRleERlZmluaXRpb24oZmlyc3RJbmRleC5pbmRleF9kZWZpbml0aW9uKTtcbiAgICAgIGNvbnN0IHJlc3RvcmVkSW5kZXhUeXBlID0gdGhpcy5yZXN0b3JlTWlncmF0aW9uSW5kZXhUeXBlKFxuICAgICAgICBmaXJzdEluZGV4LFxuICAgICAgICBwYXJzZWRJbmRleERlZmluaXRpb24uYWNjZXNzTWV0aG9kLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IHVzaW5nID0gdGhpcy5yZXN0b3JlR2VuZXJpY1VzaW5nKFxuICAgICAgICBwYXJzZWRJbmRleERlZmluaXRpb24uYWNjZXNzTWV0aG9kID8/IGZpcnN0SW5kZXguaW5kZXhfdHlwZSxcbiAgICAgICk7XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IHJlc3RvcmVkSW5kZXhUeXBlLFxuICAgICAgICBuYW1lOiBpbmRleE5hbWUsXG4gICAgICAgIGNvbHVtbnM6IGN1cnJlbnRJbmRleGVzLm1hcCgoaWR4KSA9PiAoe1xuICAgICAgICAgIG5hbWU6IGlkeC5jb2x1bW5fbmFtZSxcbiAgICAgICAgICAuLi4odGhpcy5leHRyYWN0SW5kZXhDb2x1bW5PcGNsYXNzKFxuICAgICAgICAgICAgcGFyc2VkSW5kZXhEZWZpbml0aW9uLmNvbHVtbkRlZmluaXRpb25zW2lkeC5jb2x1bW5fb3JkZXIgLSAxXSxcbiAgICAgICAgICApXG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICBvcGNsYXNzOiB0aGlzLmV4dHJhY3RJbmRleENvbHVtbk9wY2xhc3MoXG4gICAgICAgICAgICAgICAgICBwYXJzZWRJbmRleERlZmluaXRpb24uY29sdW1uRGVmaW5pdGlvbnNbaWR4LmNvbHVtbl9vcmRlciAtIDFdLFxuICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDoge30pLFxuICAgICAgICAgIC4uLih1c2luZyA9PT0gXCJidHJlZVwiXG4gICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICBzb3J0T3JkZXI6IGlkeC5zb3J0X29yZGVyLFxuICAgICAgICAgICAgICAgIG51bGxzRmlyc3Q6IGlkeC5udWxsc19maXJzdCxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgOiB7fSksXG4gICAgICAgIH0pKSxcblxuICAgICAgICBudWxsc05vdERpc3RpbmN0OiBmaXJzdEluZGV4Lm51bGxzX25vdF9kaXN0aW5jdCxcbiAgICAgICAgLi4uKGZpcnN0SW5kZXgucHJlZGljYXRlID8geyB3aGVyZTogZmlyc3RJbmRleC5wcmVkaWNhdGUgfSA6IHt9KSxcbiAgICAgICAgLi4uKHVzaW5nID8geyB1c2luZyB9IDoge30pLFxuICAgICAgICAuLi50aGlzLnBhcnNlVmVjdG9ySW5kZXhPcHRpb25zKHJlc3RvcmVkSW5kZXhUeXBlLCBwYXJzZWRJbmRleERlZmluaXRpb24ud2l0aE9wdGlvbnMpLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIC8vIGZvcmVpZ25zIOyymOumrFxuICAgIGNvbnN0IGZvcmVpZ25zOiBNaWdyYXRpb25Gb3JlaWduW10gPSBkYkZvcmVpZ25zLm1hcCgoZGJGb3JlaWduKSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb2x1bW5zOiBbZGJGb3JlaWduLmNvbHVtbl9uYW1lXSxcbiAgICAgICAgdG86IGAke2RiRm9yZWlnbi5mb3JlaWduX3RhYmxlX25hbWV9LiR7ZGJGb3JlaWduLmZvcmVpZ25fY29sdW1uX25hbWV9YCxcbiAgICAgICAgb25VcGRhdGU6IHRoaXMubWFwQ29uc3RyYWludEFjdGlvbihkYkZvcmVpZ24udXBkYXRlX3J1bGUpLFxuICAgICAgICBvbkRlbGV0ZTogdGhpcy5tYXBDb25zdHJhaW50QWN0aW9uKGRiRm9yZWlnbi5kZWxldGVfcnVsZSksXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRhYmxlLFxuICAgICAgY29sdW1ucyxcbiAgICAgIGluZGV4ZXMsXG4gICAgICBmb3JlaWducyxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFBvc3RncmVTUUzsnZggY29uc3RyYWludCBhY3Rpb27snYQgS25leCDtmJXsi53snLzroZwg67OA7ZmYXG4gICAqL1xuICBwcml2YXRlIG1hcENvbnN0cmFpbnRBY3Rpb24oYWN0aW9uOiBzdHJpbmcpOiBSZWxhdGlvbk9uIHtcbiAgICBjb25zdCBhY3Rpb25NYXA6IFJlY29yZDxzdHJpbmcsIFJlbGF0aW9uT24+ID0ge1xuICAgICAgXCJOTyBBQ1RJT05cIjogXCJOTyBBQ1RJT05cIixcbiAgICAgIFJFU1RSSUNUOiBcIlJFU1RSSUNUXCIsXG4gICAgICBDQVNDQURFOiBcIkNBU0NBREVcIixcbiAgICAgIFwiU0VUIE5VTExcIjogXCJTRVQgTlVMTFwiLFxuICAgICAgXCJTRVQgREVGQVVMVFwiOiBcIlNFVCBERUZBVUxUXCIsXG4gICAgfTtcbiAgICByZXR1cm4gYWN0aW9uTWFwW2FjdGlvbl0gPz8gXCJOTyBBQ1RJT05cIjtcbiAgfVxuXG4gIC8qKlxuICAgKiDquLDsobQg7YWM7J2067iUIOydveyWtOyEnCBjb2xzLCBpbmRleGVzLCBmb3JlaWducyDrsJjtmZhcbiAgICovXG4gIGFzeW5jIHJlYWRUYWJsZShcbiAgICBjb21wYXJlREI6IFJhd0NhcGFibGVLbmV4LFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICApOiBQcm9taXNlPFtQZ0NvbHVtbltdLCBQZ0luZGV4W10sIFBnRm9yZWlnbltdXT4ge1xuICAgIC8vIENvbHVtbnMg7KGw7ZqMIChHZW5lcmF0ZWQgQ29sdW1uIOygleuztCDtj6ztlagpXG4gICAgY29uc3QgY29sdW1uc1F1ZXJ5ID0gYFxuICAgICAgU0VMRUNUXG4gICAgICAgIGMuY29sdW1uX25hbWUsXG4gICAgICAgIGMuZGF0YV90eXBlLFxuICAgICAgICBjLnVkdF9uYW1lLFxuICAgICAgICBDT0FMRVNDRShcbiAgICAgICAgICBjLmNoYXJhY3Rlcl9tYXhpbXVtX2xlbmd0aCxcbiAgICAgICAgICBDQVNFIFdIRU4gYy5kYXRhX3R5cGUgPSAnQVJSQVknIEFORCBhLmF0dHR5cG1vZCA+IDBcbiAgICAgICAgICAgIFRIRU4gYS5hdHR0eXBtb2QgLSA0XG4gICAgICAgICAgICBFTFNFIE5VTExcbiAgICAgICAgICBFTkRcbiAgICAgICAgKSBBUyBjaGFyYWN0ZXJfbWF4aW11bV9sZW5ndGgsXG4gICAgICAgIENPQUxFU0NFKGMuZGF0ZXRpbWVfcHJlY2lzaW9uLCBjLm51bWVyaWNfcHJlY2lzaW9uKSBBUyBwcmVjaXNpb24sXG4gICAgICAgIGMubnVtZXJpY19zY2FsZSxcbiAgICAgICAgYy5pc19udWxsYWJsZSxcbiAgICAgICAgYy5jb2x1bW5fZGVmYXVsdCxcbiAgICAgICAgQ09BTEVTQ0UoYS5hdHRnZW5lcmF0ZWQsICcnKSBhcyBpc19nZW5lcmF0ZWQsXG4gICAgICAgIGMuZ2VuZXJhdGlvbl9leHByZXNzaW9uXG4gICAgICBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS5jb2x1bW5zIGNcbiAgICAgIExFRlQgSk9JTiBwZ19hdHRyaWJ1dGUgYSBPTiBhLmF0dG5hbWUgPSBjLmNvbHVtbl9uYW1lXG4gICAgICAgIEFORCBhLmF0dHJlbGlkID0gKFxuICAgICAgICAgIFNFTEVDVCBvaWQgRlJPTSBwZ19jbGFzcyBXSEVSRSByZWxuYW1lID0gYy50YWJsZV9uYW1lXG4gICAgICAgICAgQU5EIHJlbG5hbWVzcGFjZSA9IChTRUxFQ1Qgb2lkIEZST00gcGdfbmFtZXNwYWNlIFdIRVJFIG5zcG5hbWUgPSBjLnRhYmxlX3NjaGVtYSlcbiAgICAgICAgKVxuICAgICAgV0hFUkUgYy50YWJsZV9uYW1lID0gP1xuICAgICAgICBBTkQgYy50YWJsZV9zY2hlbWEgPSAncHVibGljJ1xuICAgICAgT1JERVIgQlkgYy5vcmRpbmFsX3Bvc2l0aW9uXG4gICAgYDtcbiAgICBjb25zdCBjb2x1bW5zID0gKGF3YWl0IGNvbXBhcmVEQi5yYXcoY29sdW1uc1F1ZXJ5LCBbdGFibGVOYW1lXSkpLnJvd3MgYXMgUGdDb2x1bW5bXTtcbiAgICBpZiAoY29sdW1ucy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGFibGUgbm90IGZvdW5kOiAke3RhYmxlTmFtZX1gKTtcbiAgICB9XG5cbiAgICAvLyBJbmRleGVzIOyhsO2ajCAoUEdyb29uZ2Eg7ZGc7ZiE7IudIOyduOuNseyKpCDtj6ztlagpXG4gICAgY29uc3QgaW5kZXhlc1F1ZXJ5ID0gYFxuICAgICAgU0VMRUNUXG4gICAgICAgICAgaS5yZWxuYW1lIEFTIGluZGV4X25hbWUsXG4gICAgICAgICAgQ0FTRVxuICAgICAgICAgICAgICBXSEVOIGFtLmFtbmFtZSA9ICdwZ3Jvb25nYScgQU5EIHUuYXR0bnVtID0gMCBUSEVOXG4gICAgICAgICAgICAgICAgICByZWdleHBfcmVwbGFjZShcbiAgICAgICAgICAgICAgICAgICAgICByZWdleHBfcmVwbGFjZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgVFJJTShwZ3Jvb25nYV9jb2wuY29sdW1uX2V4cHIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAnOjp0ZXh0JyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICdnJ1xuICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgICAgJ1soKV0nLFxuICAgICAgICAgICAgICAgICAgICAgICcnLFxuICAgICAgICAgICAgICAgICAgICAgICdnJ1xuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICBFTFNFIGEuYXR0bmFtZVxuICAgICAgICAgIEVORCBBUyBjb2x1bW5fbmFtZSxcbiAgICAgICAgICBpeC5pbmRpc3VuaXF1ZSBBUyBpc191bmlxdWUsXG4gICAgICAgICAgaXguaW5kaXNwcmltYXJ5IEFTIGlzX3ByaW1hcnksXG4gICAgICAgICAgYW0uYW1uYW1lIEFTIGluZGV4X3R5cGUsXG4gICAgICAgICAgQ09BTEVTQ0UoKHUub3B0ICYgMikgPSAyLCBGQUxTRSkgQVMgbnVsbHNfZmlyc3QsXG4gICAgICAgICAgQ0FTRSBcbiAgICAgICAgICAgICAgV0hFTiAodS5vcHQgJiAxKSA9IDEgVEhFTiAnREVTQydcbiAgICAgICAgICAgICAgRUxTRSAnQVNDJ1xuICAgICAgICAgIEVORCBBUyBzb3J0X29yZGVyLFxuICAgICAgICAgIGl4LmluZG51bGxzbm90ZGlzdGluY3QgQVMgbnVsbHNfbm90X2Rpc3RpbmN0LFxuICAgICAgICAgIHUub3JkIEFTIGNvbHVtbl9vcmRlcixcbiAgICAgICAgICBwZ19nZXRfaW5kZXhkZWYoaXguaW5kZXhyZWxpZCkgQVMgaW5kZXhfZGVmaW5pdGlvbixcbiAgICAgICAgICBwZ19nZXRfZXhwcihpeC5pbmRwcmVkLCBpeC5pbmRyZWxpZCkgQVMgcHJlZGljYXRlXG4gICAgICBGUk9NIHBnX2NsYXNzIHRcbiAgICAgIEpPSU4gcGdfaW5kZXggaXggT04gdC5vaWQgPSBpeC5pbmRyZWxpZFxuICAgICAgSk9JTiBwZ19jbGFzcyBpIE9OIGkub2lkID0gaXguaW5kZXhyZWxpZFxuICAgICAgSk9JTiBwZ19hbSBhbSBPTiBpLnJlbGFtID0gYW0ub2lkXG4gICAgICBKT0lOIExBVEVSQUwgdW5uZXN0KGl4LmluZGtleSwgaXguaW5kb3B0aW9uKVxuICAgICAgICAgIFdJVEggT1JESU5BTElUWSBBUyB1KGF0dG51bSwgb3B0LCBvcmQpIE9OIHRydWVcbiAgICAgIExFRlQgSk9JTiBwZ19hdHRyaWJ1dGUgYSBPTiBhLmF0dHJlbGlkID0gdC5vaWQgXG4gICAgICAgICAgQU5EIGEuYXR0bnVtID0gdS5hdHRudW0gXG4gICAgICAgICAgQU5EIHUuYXR0bnVtID4gMFxuICAgICAgTEVGVCBKT0lOIExBVEVSQUwgKFxuICAgICAgICAgIFNFTEVDVCBcbiAgICAgICAgICAgICAgdW5uZXN0KFxuICAgICAgICAgICAgICAgICAgQ0FTRSBcbiAgICAgICAgICAgICAgICAgICAgICBXSEVOIHBnX2dldF9leHByKGl4LmluZGV4cHJzLCBpeC5pbmRyZWxpZCkgfiAnXkFSUkFZXFxcXFsnIFRIRU5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nX3RvX2FycmF5KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnZXhwX3JlcGxhY2UoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGdfZ2V0X2V4cHIoaXguaW5kZXhwcnMsIGl4LmluZHJlbGlkKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXkFSUkFZXFxcXFsoLiopXFxcXF0kJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnXFxcXDEnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJywgJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgRUxTRVxuICAgICAgICAgICAgICAgICAgICAgICAgICBBUlJBWVtwZ19nZXRfZXhwcihpeC5pbmRleHBycywgaXguaW5kcmVsaWQpXVxuICAgICAgICAgICAgICAgICAgRU5EXG4gICAgICAgICAgICAgICkgYXMgY29sdW1uX2V4cHJcbiAgICAgICkgcGdyb29uZ2FfY29sIE9OIGFtLmFtbmFtZSA9ICdwZ3Jvb25nYScgQU5EIHUuYXR0bnVtID0gMFxuICAgICAgV0hFUkUgdC5yZWxuYW1lID0gP1xuICAgICAgICAgIEFORCAodS5hdHRudW0gPiAwIE9SIChhbS5hbW5hbWUgPSAncGdyb29uZ2EnIEFORCB1LmF0dG51bSA9IDApKVxuICAgICAgT1JERVIgQlkgaS5yZWxuYW1lLCB1Lm9yZDtcbmA7XG4gICAgY29uc3QgaW5kZXhlcyA9IChhd2FpdCBjb21wYXJlREIucmF3KGluZGV4ZXNRdWVyeSwgW3RhYmxlTmFtZV0pKS5yb3dzO1xuXG4gICAgLy8gRm9yZWlnbiBLZXlzIOyhsO2ajFxuICAgIGNvbnN0IGZvcmVpZ25zUXVlcnkgPSBgXG4gICAgICBTRUxFQ1RcbiAgICAgICAgdGMuY29uc3RyYWludF9uYW1lLFxuICAgICAgICBrY3UuY29sdW1uX25hbWUsXG4gICAgICAgIGNjdS50YWJsZV9uYW1lIEFTIGZvcmVpZ25fdGFibGVfbmFtZSxcbiAgICAgICAgY2N1LmNvbHVtbl9uYW1lIEFTIGZvcmVpZ25fY29sdW1uX25hbWUsXG4gICAgICAgIHJjLnVwZGF0ZV9ydWxlLFxuICAgICAgICByYy5kZWxldGVfcnVsZVxuICAgICAgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEudGFibGVfY29uc3RyYWludHMgQVMgdGNcbiAgICAgIEpPSU4gaW5mb3JtYXRpb25fc2NoZW1hLmtleV9jb2x1bW5fdXNhZ2UgQVMga2N1XG4gICAgICAgIE9OIHRjLmNvbnN0cmFpbnRfbmFtZSA9IGtjdS5jb25zdHJhaW50X25hbWVcbiAgICAgICAgQU5EIHRjLnRhYmxlX3NjaGVtYSA9IGtjdS50YWJsZV9zY2hlbWFcbiAgICAgIEpPSU4gaW5mb3JtYXRpb25fc2NoZW1hLmNvbnN0cmFpbnRfY29sdW1uX3VzYWdlIEFTIGNjdVxuICAgICAgICBPTiBjY3UuY29uc3RyYWludF9uYW1lID0gdGMuY29uc3RyYWludF9uYW1lXG4gICAgICAgIEFORCBjY3UudGFibGVfc2NoZW1hID0gdGMudGFibGVfc2NoZW1hXG4gICAgICBKT0lOIGluZm9ybWF0aW9uX3NjaGVtYS5yZWZlcmVudGlhbF9jb25zdHJhaW50cyBBUyByY1xuICAgICAgICBPTiByYy5jb25zdHJhaW50X25hbWUgPSB0Yy5jb25zdHJhaW50X25hbWVcbiAgICAgICAgQU5EIHJjLmNvbnN0cmFpbnRfc2NoZW1hID0gdGMudGFibGVfc2NoZW1hXG4gICAgICBXSEVSRSB0Yy5jb25zdHJhaW50X3R5cGUgPSAnRk9SRUlHTiBLRVknXG4gICAgICAgIEFORCB0Yy50YWJsZV9uYW1lID0gP1xuICAgIGA7XG4gICAgY29uc3QgZm9yZWlnbnMgPSAoYXdhaXQgY29tcGFyZURCLnJhdyhmb3JlaWduc1F1ZXJ5LCBbdGFibGVOYW1lXSkpLnJvd3M7XG5cbiAgICByZXR1cm4gW2NvbHVtbnMsIGluZGV4ZXMsIGZvcmVpZ25zXTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzdG9yZU1pZ3JhdGlvbkluZGV4VHlwZShcbiAgICBpbmRleDogUGljazxQZ0luZGV4LCBcImlzX3VuaXF1ZVwiIHwgXCJpbmRleF90eXBlXCI+LFxuICAgIGFjY2Vzc01ldGhvZD86IHN0cmluZyxcbiAgKTogTWlncmF0aW9uSW5kZXhbXCJ0eXBlXCJdIHtcbiAgICBjb25zdCByZXNvbHZlZEFjY2Vzc01ldGhvZCA9IChhY2Nlc3NNZXRob2QgPz8gaW5kZXguaW5kZXhfdHlwZSkudG9Mb3dlckNhc2UoKTtcblxuICAgIGlmIChyZXNvbHZlZEFjY2Vzc01ldGhvZCA9PT0gXCJobnN3XCIgfHwgcmVzb2x2ZWRBY2Nlc3NNZXRob2QgPT09IFwiaXZmZmxhdFwiKSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZWRBY2Nlc3NNZXRob2Q7XG4gICAgfVxuXG4gICAgcmV0dXJuIGluZGV4LmlzX3VuaXF1ZSA/IFwidW5pcXVlXCIgOiBcImluZGV4XCI7XG4gIH1cblxuICBwcml2YXRlIHJlc3RvcmVHZW5lcmljVXNpbmcoXG4gICAgYWNjZXNzTWV0aG9kOiBzdHJpbmcgfCB1bmRlZmluZWQsXG4gICk6IE1pZ3JhdGlvbkluZGV4W1widXNpbmdcIl0gfCB1bmRlZmluZWQge1xuICAgIGlmICghYWNjZXNzTWV0aG9kKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBhY2Nlc3NNZXRob2QudG9Mb3dlckNhc2UoKTtcbiAgICBpZiAoIXRoaXMuZ2VuZXJpY0luZGV4VHlwZXMuaGFzKG5vcm1hbGl6ZWQpKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIHJldHVybiBub3JtYWxpemVkIGFzIE1pZ3JhdGlvbkluZGV4W1widXNpbmdcIl07XG4gIH1cblxuICBwcml2YXRlIHBhcnNlVmVjdG9ySW5kZXhPcHRpb25zKFxuICAgIHR5cGU6IE1pZ3JhdGlvbkluZGV4W1widHlwZVwiXSxcbiAgICB3aXRoT3B0aW9uczogUmVjb3JkPHN0cmluZywgc3RyaW5nPixcbiAgKTogUGljazxNaWdyYXRpb25JbmRleCwgXCJtXCIgfCBcImVmQ29uc3RydWN0aW9uXCIgfCBcImxpc3RzXCI+IHtcbiAgICBpZiAodHlwZSA9PT0gXCJobnN3XCIpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLih0aGlzLnBhcnNlSW50ZWdlck9wdGlvbih3aXRoT3B0aW9ucy5tKSAhPT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyB7IG06IHRoaXMucGFyc2VJbnRlZ2VyT3B0aW9uKHdpdGhPcHRpb25zLm0pIH1cbiAgICAgICAgICA6IHt9KSxcbiAgICAgICAgLi4uKHRoaXMucGFyc2VJbnRlZ2VyT3B0aW9uKHdpdGhPcHRpb25zLmVmX2NvbnN0cnVjdGlvbikgIT09IHVuZGVmaW5lZFxuICAgICAgICAgID8geyBlZkNvbnN0cnVjdGlvbjogdGhpcy5wYXJzZUludGVnZXJPcHRpb24od2l0aE9wdGlvbnMuZWZfY29uc3RydWN0aW9uKSB9XG4gICAgICAgICAgOiB7fSksXG4gICAgICB9O1xuICAgIH1cblxuICAgIGlmICh0eXBlID09PSBcIml2ZmZsYXRcIikge1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2VJbnRlZ2VyT3B0aW9uKHdpdGhPcHRpb25zLmxpc3RzKSAhPT0gdW5kZWZpbmVkXG4gICAgICAgID8geyBsaXN0czogdGhpcy5wYXJzZUludGVnZXJPcHRpb24od2l0aE9wdGlvbnMubGlzdHMpIH1cbiAgICAgICAgOiB7fTtcbiAgICB9XG5cbiAgICByZXR1cm4ge307XG4gIH1cblxuICBwcml2YXRlIHBhcnNlSW50ZWdlck9wdGlvbih2YWx1ZTogc3RyaW5nIHwgdW5kZWZpbmVkKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIXZhbHVlKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcnNlZCA9IE51bWJlci5wYXJzZUludCh2YWx1ZSwgMTApO1xuICAgIHJldHVybiBOdW1iZXIuaXNOYU4ocGFyc2VkKSA/IHVuZGVmaW5lZCA6IHBhcnNlZDtcbiAgfVxuXG4gIHByaXZhdGUgZXh0cmFjdEluZGV4Q29sdW1uT3BjbGFzcyhjb2x1bW5EZWZpbml0aW9uOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICghY29sdW1uRGVmaW5pdGlvbikge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCB0cmltbWVkID0gY29sdW1uRGVmaW5pdGlvblxuICAgICAgLnJlcGxhY2UoL1xccytOVUxMU1xccysoRklSU1R8TEFTVClcXHMqJC9pLCBcIlwiKVxuICAgICAgLnJlcGxhY2UoL1xccysoQVNDfERFU0MpXFxzKiQvaSwgXCJcIilcbiAgICAgIC50cmltKCk7XG4gICAgY29uc3QgdG9rZW5zID0gdGhpcy50b2tlbml6ZVRvcExldmVsKHRyaW1tZWQpO1xuXG4gICAgaWYgKHRva2Vucy5sZW5ndGggPCAyKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGlmICh0b2tlbnNbdG9rZW5zLmxlbmd0aCAtIDJdPy50b1VwcGVyQ2FzZSgpID09PSBcIkNPTExBVEVcIikge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gdG9rZW5zLmF0KC0xKTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VJbmRleERlZmluaXRpb24oaW5kZXhEZWZpbml0aW9uOiBzdHJpbmcpOiB7XG4gICAgYWNjZXNzTWV0aG9kPzogc3RyaW5nO1xuICAgIGNvbHVtbkRlZmluaXRpb25zOiBzdHJpbmdbXTtcbiAgICB3aXRoT3B0aW9uczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgfSB7XG4gICAgY29uc3QgYWNjZXNzTWV0aG9kID0gaW5kZXhEZWZpbml0aW9uLm1hdGNoKC9cXGJVU0lOR1xccysoW2Etel9dW1xcd10qKS9pKT8uWzFdPy50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IHVzaW5nTWF0Y2hJbmRleCA9IGluZGV4RGVmaW5pdGlvbi5zZWFyY2goL1xcYlVTSU5HXFxiL2kpO1xuICAgIGNvbnN0IGNvbHVtbnNTdGFydCA9IHVzaW5nTWF0Y2hJbmRleCA+PSAwID8gaW5kZXhEZWZpbml0aW9uLmluZGV4T2YoXCIoXCIsIHVzaW5nTWF0Y2hJbmRleCkgOiAtMTtcbiAgICBjb25zdCBjb2x1bW5zRW5kID1cbiAgICAgIGNvbHVtbnNTdGFydCA+PSAwID8gdGhpcy5maW5kTWF0Y2hpbmdQYXJlbnRoZXNpcyhpbmRleERlZmluaXRpb24sIGNvbHVtbnNTdGFydCkgOiAtMTtcbiAgICBjb25zdCBjb2x1bW5EZWZpbml0aW9ucyA9XG4gICAgICBjb2x1bW5zU3RhcnQgPj0gMCAmJiBjb2x1bW5zRW5kID4gY29sdW1uc1N0YXJ0XG4gICAgICAgID8gdGhpcy5zcGxpdFRvcExldmVsKGluZGV4RGVmaW5pdGlvbi5zbGljZShjb2x1bW5zU3RhcnQgKyAxLCBjb2x1bW5zRW5kKSwgXCIsXCIpXG4gICAgICAgIDogW107XG5cbiAgICBjb25zdCB3aXRoTWF0Y2ggPSAvXFxiV0lUSFxccypcXCgvaS5leGVjKGluZGV4RGVmaW5pdGlvbik7XG4gICAgY29uc3Qgd2l0aFN0YXJ0ID0gd2l0aE1hdGNoID8gaW5kZXhEZWZpbml0aW9uLmluZGV4T2YoXCIoXCIsIHdpdGhNYXRjaC5pbmRleCkgOiAtMTtcbiAgICBjb25zdCB3aXRoRW5kID0gd2l0aFN0YXJ0ID49IDAgPyB0aGlzLmZpbmRNYXRjaGluZ1BhcmVudGhlc2lzKGluZGV4RGVmaW5pdGlvbiwgd2l0aFN0YXJ0KSA6IC0xO1xuICAgIGNvbnN0IHdpdGhPcHRpb25zID1cbiAgICAgIHdpdGhTdGFydCA+PSAwICYmIHdpdGhFbmQgPiB3aXRoU3RhcnRcbiAgICAgICAgPyB0aGlzLnBhcnNlSW5kZXhPcHRpb25FbnRyaWVzKGluZGV4RGVmaW5pdGlvbi5zbGljZSh3aXRoU3RhcnQgKyAxLCB3aXRoRW5kKSlcbiAgICAgICAgOiB7fTtcblxuICAgIHJldHVybiB7XG4gICAgICBhY2Nlc3NNZXRob2QsXG4gICAgICBjb2x1bW5EZWZpbml0aW9ucyxcbiAgICAgIHdpdGhPcHRpb25zLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIHBhcnNlSW5kZXhPcHRpb25FbnRyaWVzKG9wdGlvblNvdXJjZTogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gICAgcmV0dXJuIHRoaXMuc3BsaXRUb3BMZXZlbChvcHRpb25Tb3VyY2UsIFwiLFwiKS5yZWR1Y2U8UmVjb3JkPHN0cmluZywgc3RyaW5nPj4oKHJlc3VsdCwgZW50cnkpID0+IHtcbiAgICAgIGNvbnN0IG1hdGNoZWQgPSBlbnRyeS50cmltKCkubWF0Y2goL14oW2Etel9dW1xcd10qKVxccyo9XFxzKiguKykkL2kpO1xuICAgICAgaWYgKCFtYXRjaGVkKSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IFssIGtleSwgcmF3VmFsdWVdID0gbWF0Y2hlZDtcbiAgICAgIHJlc3VsdFtrZXkudG9Mb3dlckNhc2UoKV0gPSByYXdWYWx1ZS50cmltKCkucmVwbGFjZSgvXlsnXCJdfFsnXCJdJC9nLCBcIlwiKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSwge30pO1xuICB9XG5cbiAgcHJpdmF0ZSBzcGxpdFRvcExldmVsKHNvdXJjZTogc3RyaW5nLCBkZWxpbWl0ZXI6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBpdGVtczogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgc3RhcnQgPSAwO1xuICAgIGxldCBwYXJlbkRlcHRoID0gMDtcbiAgICBsZXQgYnJhY2tldERlcHRoID0gMDtcbiAgICBsZXQgaW5TaW5nbGVRdW90ZSA9IGZhbHNlO1xuICAgIGxldCBpbkRvdWJsZVF1b3RlID0gZmFsc2U7XG5cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgc291cmNlLmxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgICAgY29uc3QgY2hhciA9IHNvdXJjZVtpbmRleF07XG4gICAgICBjb25zdCBuZXh0Q2hhciA9IHNvdXJjZVtpbmRleCArIDFdO1xuXG4gICAgICBpZiAoY2hhciA9PT0gXCInXCIgJiYgIWluRG91YmxlUXVvdGUpIHtcbiAgICAgICAgaWYgKGluU2luZ2xlUXVvdGUgJiYgbmV4dENoYXIgPT09IFwiJ1wiKSB7XG4gICAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpblNpbmdsZVF1b3RlID0gIWluU2luZ2xlUXVvdGU7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2hhciA9PT0gJ1wiJyAmJiAhaW5TaW5nbGVRdW90ZSkge1xuICAgICAgICBpZiAoaW5Eb3VibGVRdW90ZSAmJiBuZXh0Q2hhciA9PT0gJ1wiJykge1xuICAgICAgICAgIGluZGV4ICs9IDE7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaW5Eb3VibGVRdW90ZSA9ICFpbkRvdWJsZVF1b3RlO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluU2luZ2xlUXVvdGUgfHwgaW5Eb3VibGVRdW90ZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNoYXIgPT09IFwiKFwiKSB7XG4gICAgICAgIHBhcmVuRGVwdGggKz0gMTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoY2hhciA9PT0gXCIpXCIpIHtcbiAgICAgICAgcGFyZW5EZXB0aCAtPSAxO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGlmIChjaGFyID09PSBcIltcIikge1xuICAgICAgICBicmFja2V0RGVwdGggKz0gMTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoY2hhciA9PT0gXCJdXCIpIHtcbiAgICAgICAgYnJhY2tldERlcHRoIC09IDE7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2hhciA9PT0gZGVsaW1pdGVyICYmIHBhcmVuRGVwdGggPT09IDAgJiYgYnJhY2tldERlcHRoID09PSAwKSB7XG4gICAgICAgIGl0ZW1zLnB1c2goc291cmNlLnNsaWNlKHN0YXJ0LCBpbmRleCkudHJpbSgpKTtcbiAgICAgICAgc3RhcnQgPSBpbmRleCArIDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgdGFpbCA9IHNvdXJjZS5zbGljZShzdGFydCkudHJpbSgpO1xuICAgIGlmICh0YWlsLmxlbmd0aCA+IDApIHtcbiAgICAgIGl0ZW1zLnB1c2godGFpbCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGl0ZW1zO1xuICB9XG5cbiAgcHJpdmF0ZSB0b2tlbml6ZVRvcExldmVsKHNvdXJjZTogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHRva2Vuczogc3RyaW5nW10gPSBbXTtcbiAgICBsZXQgc3RhcnQgPSAtMTtcbiAgICBsZXQgcGFyZW5EZXB0aCA9IDA7XG4gICAgbGV0IGJyYWNrZXREZXB0aCA9IDA7XG4gICAgbGV0IGluU2luZ2xlUXVvdGUgPSBmYWxzZTtcbiAgICBsZXQgaW5Eb3VibGVRdW90ZSA9IGZhbHNlO1xuXG4gICAgY29uc3QgcHVzaFRva2VuID0gKGVuZEluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB0b2tlbiA9IHNvdXJjZS5zbGljZShzdGFydCwgZW5kSW5kZXgpLnRyaW0oKTtcbiAgICAgIGlmICh0b2tlbi5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRva2Vucy5wdXNoKHRva2VuKTtcbiAgICAgIH1cbiAgICAgIHN0YXJ0ID0gLTE7XG4gICAgfTtcblxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBzb3VyY2UubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgICBjb25zdCBjaGFyID0gc291cmNlW2luZGV4XTtcbiAgICAgIGNvbnN0IG5leHRDaGFyID0gc291cmNlW2luZGV4ICsgMV07XG5cbiAgICAgIGlmIChjaGFyID09PSBcIidcIiAmJiAhaW5Eb3VibGVRdW90ZSkge1xuICAgICAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICAgICAgc3RhcnQgPSBpbmRleDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5TaW5nbGVRdW90ZSAmJiBuZXh0Q2hhciA9PT0gXCInXCIpIHtcbiAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGluU2luZ2xlUXVvdGUgPSAhaW5TaW5nbGVRdW90ZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaGFyID09PSAnXCInICYmICFpblNpbmdsZVF1b3RlKSB7XG4gICAgICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgICAgICBzdGFydCA9IGluZGV4O1xuICAgICAgICB9XG4gICAgICAgIGlmIChpbkRvdWJsZVF1b3RlICYmIG5leHRDaGFyID09PSAnXCInKSB7XG4gICAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpbkRvdWJsZVF1b3RlID0gIWluRG91YmxlUXVvdGU7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIWluU2luZ2xlUXVvdGUgJiYgIWluRG91YmxlUXVvdGUpIHtcbiAgICAgICAgaWYgKGNoYXIgPT09IFwiKFwiKSB7XG4gICAgICAgICAgaWYgKHN0YXJ0IDwgMCkge1xuICAgICAgICAgICAgc3RhcnQgPSBpbmRleDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcGFyZW5EZXB0aCArPSAxO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjaGFyID09PSBcIilcIikge1xuICAgICAgICAgIHBhcmVuRGVwdGggLT0gMTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hhciA9PT0gXCJbXCIpIHtcbiAgICAgICAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICAgICAgICBzdGFydCA9IGluZGV4O1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmFja2V0RGVwdGggKz0gMTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hhciA9PT0gXCJdXCIpIHtcbiAgICAgICAgICBicmFja2V0RGVwdGggLT0gMTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICgvXFxzLy50ZXN0KGNoYXIpICYmIHBhcmVuRGVwdGggPT09IDAgJiYgYnJhY2tldERlcHRoID09PSAwKSB7XG4gICAgICAgICAgcHVzaFRva2VuKGluZGV4KTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICAgIHN0YXJ0ID0gaW5kZXg7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcHVzaFRva2VuKHNvdXJjZS5sZW5ndGgpO1xuICAgIHJldHVybiB0b2tlbnM7XG4gIH1cblxuICBwcml2YXRlIGZpbmRNYXRjaGluZ1BhcmVudGhlc2lzKHNvdXJjZTogc3RyaW5nLCBvcGVuSW5kZXg6IG51bWJlcik6IG51bWJlciB7XG4gICAgbGV0IGRlcHRoID0gMDtcbiAgICBsZXQgaW5TaW5nbGVRdW90ZSA9IGZhbHNlO1xuICAgIGxldCBpbkRvdWJsZVF1b3RlID0gZmFsc2U7XG5cbiAgICBmb3IgKGxldCBpbmRleCA9IG9wZW5JbmRleDsgaW5kZXggPCBzb3VyY2UubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgICBjb25zdCBjaGFyID0gc291cmNlW2luZGV4XTtcbiAgICAgIGNvbnN0IG5leHRDaGFyID0gc291cmNlW2luZGV4ICsgMV07XG5cbiAgICAgIGlmIChjaGFyID09PSBcIidcIiAmJiAhaW5Eb3VibGVRdW90ZSkge1xuICAgICAgICBpZiAoaW5TaW5nbGVRdW90ZSAmJiBuZXh0Q2hhciA9PT0gXCInXCIpIHtcbiAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGluU2luZ2xlUXVvdGUgPSAhaW5TaW5nbGVRdW90ZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaGFyID09PSAnXCInICYmICFpblNpbmdsZVF1b3RlKSB7XG4gICAgICAgIGlmIChpbkRvdWJsZVF1b3RlICYmIG5leHRDaGFyID09PSAnXCInKSB7XG4gICAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpbkRvdWJsZVF1b3RlID0gIWluRG91YmxlUXVvdGU7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoaW5TaW5nbGVRdW90ZSB8fCBpbkRvdWJsZVF1b3RlKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2hhciA9PT0gXCIoXCIpIHtcbiAgICAgICAgZGVwdGggKz0gMTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaGFyID09PSBcIilcIikge1xuICAgICAgICBkZXB0aCAtPSAxO1xuICAgICAgICBpZiAoZGVwdGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gaW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAvKipcbiAgICog7Yq57KCVIO2FjOydtOu4lOydmCBQS+ulvCDssLjsobDtlZjripQg64uk66W4IO2FjOydtOu4lOydmCBGSyDrqqnroZ3snYQg7KGw7ZqM7ZWp64uI64ukLlxuICAgKiBQSyDtg4DsnoUg67OA6rK9IOyLnCDqtIDroKggRksg7KCc7JW97KGw6rG07J2EIOyCreygnC/rs7XqtaztlZjquLAg7JyE7ZW0IOyCrOyaqeuQqeuLiOuLpC5cbiAgICovXG4gIGFzeW5jIGdldFJlZmVyZW5jaW5nRm9yZWlnbktleXMoZGI6IEtuZXgsIHRhYmxlTmFtZTogc3RyaW5nKTogUHJvbWlzZTxSZWZlcmVuY2luZ0ZvcmVpZ25LZXlbXT4ge1xuICAgIGNvbnN0IHF1ZXJ5ID0gYFxuICAgICAgU0VMRUNUXG4gICAgICAgIHRjLnRhYmxlX25hbWUsXG4gICAgICAgIHRjLmNvbnN0cmFpbnRfbmFtZSxcbiAgICAgICAga2N1LmNvbHVtbl9uYW1lLFxuICAgICAgICBjY3UudGFibGVfbmFtZSBBUyByZWZlcmVuY2VkX3RhYmxlX25hbWUsXG4gICAgICAgIGNjdS5jb2x1bW5fbmFtZSBBUyByZWZlcmVuY2VkX2NvbHVtbl9uYW1lLFxuICAgICAgICByYy51cGRhdGVfcnVsZSxcbiAgICAgICAgcmMuZGVsZXRlX3J1bGVcbiAgICAgIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlX2NvbnN0cmFpbnRzIEFTIHRjXG4gICAgICBKT0lOIGluZm9ybWF0aW9uX3NjaGVtYS5rZXlfY29sdW1uX3VzYWdlIEFTIGtjdVxuICAgICAgICBPTiB0Yy5jb25zdHJhaW50X25hbWUgPSBrY3UuY29uc3RyYWludF9uYW1lXG4gICAgICAgIEFORCB0Yy50YWJsZV9zY2hlbWEgPSBrY3UudGFibGVfc2NoZW1hXG4gICAgICBKT0lOIGluZm9ybWF0aW9uX3NjaGVtYS5jb25zdHJhaW50X2NvbHVtbl91c2FnZSBBUyBjY3VcbiAgICAgICAgT04gY2N1LmNvbnN0cmFpbnRfbmFtZSA9IHRjLmNvbnN0cmFpbnRfbmFtZVxuICAgICAgICBBTkQgY2N1LnRhYmxlX3NjaGVtYSA9IHRjLnRhYmxlX3NjaGVtYVxuICAgICAgSk9JTiBpbmZvcm1hdGlvbl9zY2hlbWEucmVmZXJlbnRpYWxfY29uc3RyYWludHMgQVMgcmNcbiAgICAgICAgT04gcmMuY29uc3RyYWludF9uYW1lID0gdGMuY29uc3RyYWludF9uYW1lXG4gICAgICAgIEFORCByYy5jb25zdHJhaW50X3NjaGVtYSA9IHRjLnRhYmxlX3NjaGVtYVxuICAgICAgV0hFUkUgdGMuY29uc3RyYWludF90eXBlID0gJ0ZPUkVJR04gS0VZJ1xuICAgICAgICBBTkQgY2N1LnRhYmxlX25hbWUgPSA/XG4gICAgICAgIEFORCB0Yy50YWJsZV9zY2hlbWEgPSAncHVibGljJ1xuICAgIGA7XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBkYi5yYXcocXVlcnksIFt0YWJsZU5hbWVdKTtcbiAgICByZXR1cm4gcmVzdWx0LnJvd3MubWFwKFxuICAgICAgKHJvdzoge1xuICAgICAgICB0YWJsZV9uYW1lOiBzdHJpbmc7XG4gICAgICAgIGNvbnN0cmFpbnRfbmFtZTogc3RyaW5nO1xuICAgICAgICBjb2x1bW5fbmFtZTogc3RyaW5nO1xuICAgICAgICByZWZlcmVuY2VkX3RhYmxlX25hbWU6IHN0cmluZztcbiAgICAgICAgcmVmZXJlbmNlZF9jb2x1bW5fbmFtZTogc3RyaW5nO1xuICAgICAgICB1cGRhdGVfcnVsZTogc3RyaW5nO1xuICAgICAgICBkZWxldGVfcnVsZTogc3RyaW5nO1xuICAgICAgfSkgPT4gKHtcbiAgICAgICAgdGFibGVOYW1lOiByb3cudGFibGVfbmFtZSxcbiAgICAgICAgY29uc3RyYWludE5hbWU6IHJvdy5jb25zdHJhaW50X25hbWUsXG4gICAgICAgIGNvbHVtbk5hbWU6IHJvdy5jb2x1bW5fbmFtZSxcbiAgICAgICAgcmVmZXJlbmNlZFRhYmxlTmFtZTogcm93LnJlZmVyZW5jZWRfdGFibGVfbmFtZSxcbiAgICAgICAgcmVmZXJlbmNlZENvbHVtbk5hbWU6IHJvdy5yZWZlcmVuY2VkX2NvbHVtbl9uYW1lLFxuICAgICAgICBvblVwZGF0ZTogdGhpcy5tYXBDb25zdHJhaW50QWN0aW9uKHJvdy51cGRhdGVfcnVsZSksXG4gICAgICAgIG9uRGVsZXRlOiB0aGlzLm1hcENvbnN0cmFpbnRBY3Rpb24ocm93LmRlbGV0ZV9ydWxlKSxcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogdmVjdG9yIOy7rOufvOydmCBkaW1lbnNpb25z66W8IOyhsO2ajO2VqeuLiOuLpC5cbiAgICogcGdfYXR0cmlidXRl7J2YIGF0dHR5cG1vZOyXkOyEnCDssKjsm5Ag7IiY66W8IOy2lOy2nO2VqeuLiOuLpC5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZ2V0VmVjdG9yRGltZW5zaW9ucyhcbiAgICBjb21wYXJlREI6IFJhd0NhcGFibGVLbmV4LFxuICAgIHRhYmxlTmFtZTogc3RyaW5nLFxuICApOiBQcm9taXNlPFJlY29yZDxzdHJpbmcsIG51bWJlcj4+IHtcbiAgICBjb25zdCBxdWVyeSA9IGBcbiAgICAgIFNFTEVDVFxuICAgICAgICBhLmF0dG5hbWUgYXMgY29sdW1uX25hbWUsXG4gICAgICAgIGEuYXR0dHlwbW9kIGFzIGRpbWVuc2lvbnNcbiAgICAgIEZST00gcGdfYXR0cmlidXRlIGFcbiAgICAgIEpPSU4gcGdfY2xhc3MgYyBPTiBhLmF0dHJlbGlkID0gYy5vaWRcbiAgICAgIEpPSU4gcGdfdHlwZSB0IE9OIGEuYXR0dHlwaWQgPSB0Lm9pZFxuICAgICAgV0hFUkUgYy5yZWxuYW1lID0gP1xuICAgICAgICBBTkQgdC50eXBuYW1lID0gJ3ZlY3RvcidcbiAgICAgICAgQU5EIGEuYXR0bnVtID4gMFxuICAgIGA7XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgY29tcGFyZURCLnJhdyhxdWVyeSwgW3RhYmxlTmFtZV0pO1xuICAgIGNvbnN0IGRpbWVuc2lvbnM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiByZXN1bHQucm93cykge1xuICAgICAgLy8gYXR0dHlwbW9k7JeQ7IScIOyLpOygnCBkaW1lbnNpb25zIOqwkiDstpTstpxcbiAgICAgIGRpbWVuc2lvbnNbcm93LmNvbHVtbl9uYW1lXSA9IHJvdy5kaW1lbnNpb25zID4gMCA/IHJvdy5kaW1lbnNpb25zIDogMDtcbiAgICB9XG4gICAgcmV0dXJuIGRpbWVuc2lvbnM7XG4gIH1cblxuICAvKipcbiAgICogUG9zdGdyZVNRTCDsu6zrn7wg7YOA7J6F7J2EIOu2hOyEne2VmOyXrCBNaWdyYXRpb25Db2x1bW4g6rCd7LK066GcIOuzgO2ZmO2VqeuLiOuLpC5cbiAgICovXG4gIHJlc29sdmVEQkNvbFR5cGUoXG4gICAgZGJDb2x1bW46IFBnQ29sdW1uLFxuICApOiBQaWNrPFxuICAgIE1pZ3JhdGlvbkNvbHVtbixcbiAgICBcInR5cGVcIiB8IFwibGVuZ3RoXCIgfCBcInByZWNpc2lvblwiIHwgXCJzY2FsZVwiIHwgXCJudW1iZXJUeXBlXCIgfCBcImRpbWVuc2lvbnNcIlxuICA+IHtcbiAgICBjb25zdCB7IHVkdF9uYW1lOiBfdWR0X25hbWUsIGNoYXJhY3Rlcl9tYXhpbXVtX2xlbmd0aCwgcHJlY2lzaW9uLCBudW1lcmljX3NjYWxlIH0gPSBkYkNvbHVtbjtcblxuICAgIGNvbnN0IHsgdWR0X25hbWUsIHNpbmdsZU9yQXJyYXkgfSA9ICgoKSA9PiB7XG4gICAgICBpZiAoX3VkdF9uYW1lLnN0YXJ0c1dpdGgoXCJfXCIpKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgdWR0X25hbWU6IF91ZHRfbmFtZS5zdWJzdHJpbmcoMSksXG4gICAgICAgICAgc2luZ2xlT3JBcnJheTogXCJbXVwiIGFzIGNvbnN0LFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdWR0X25hbWU6IF91ZHRfbmFtZSxcbiAgICAgICAgc2luZ2xlT3JBcnJheTogXCJcIiBhcyBjb25zdCxcbiAgICAgIH07XG4gICAgfSkoKTtcblxuICAgIC8vIFVVSURcbiAgICBpZiAodWR0X25hbWUgPT09IFwidXVpZFwiKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBgdXVpZCR7c2luZ2xlT3JBcnJheX1gIH07XG4gICAgfVxuXG4gICAgLy8gSW50ZWdlciB0eXBlc1xuICAgIGlmICh1ZHRfbmFtZSA9PT0gXCJpbnQ0XCIpIHtcbiAgICAgIHJldHVybiB7IHR5cGU6IGBpbnRlZ2VyJHtzaW5nbGVPckFycmF5fWAgfTtcbiAgICB9XG4gICAgaWYgKHVkdF9uYW1lID09PSBcImludDhcIikge1xuICAgICAgcmV0dXJuIHsgdHlwZTogYGJpZ0ludGVnZXIke3NpbmdsZU9yQXJyYXl9YCB9O1xuICAgIH1cblxuICAgIC8vIFN0cmluZyB0eXBlc1xuICAgIGlmICh1ZHRfbmFtZSA9PT0gXCJ2YXJjaGFyXCIpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHR5cGU6IGBzdHJpbmcke3NpbmdsZU9yQXJyYXl9YCxcbiAgICAgICAgLi4uKGNoYXJhY3Rlcl9tYXhpbXVtX2xlbmd0aCAmJiB7XG4gICAgICAgICAgbGVuZ3RoOiBjaGFyYWN0ZXJfbWF4aW11bV9sZW5ndGgsXG4gICAgICAgIH0pLFxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKHVkdF9uYW1lID09PSBcInRleHRcIikge1xuICAgICAgcmV0dXJuIHsgdHlwZTogYHN0cmluZyR7c2luZ2xlT3JBcnJheX1gIH07IC8vIFN0cmluZ1Byb3Agd2l0aG91dCBsZW5ndGhcbiAgICB9XG5cbiAgICAvLyBOdW1iZXJPck51bWVyaWMgdHlwZXNcbiAgICBpZiAodWR0X25hbWUgPT09IFwibnVtZXJpY1wiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBgbnVtYmVyT3JOdW1lcmljJHtzaW5nbGVPckFycmF5fWAsXG4gICAgICAgIG51bWJlclR5cGU6IFwibnVtZXJpY1wiLFxuICAgICAgICAuLi4ocHJlY2lzaW9uICE9PSBudWxsICYmXG4gICAgICAgICAgbnVtZXJpY19zY2FsZSAhPT0gbnVsbCAmJiB7XG4gICAgICAgICAgICBwcmVjaXNpb246IHByZWNpc2lvbixcbiAgICAgICAgICAgIHNjYWxlOiBudW1lcmljX3NjYWxlLFxuICAgICAgICAgIH0pLFxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKHVkdF9uYW1lID09PSBcImZsb2F0NFwiKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBgbnVtYmVyT3JOdW1lcmljJHtzaW5nbGVPckFycmF5fWAsIG51bWJlclR5cGU6IFwicmVhbFwiIH07XG4gICAgfVxuICAgIGlmICh1ZHRfbmFtZSA9PT0gXCJmbG9hdDhcIikge1xuICAgICAgcmV0dXJuIHsgdHlwZTogYG51bWJlck9yTnVtZXJpYyR7c2luZ2xlT3JBcnJheX1gLCBudW1iZXJUeXBlOiBcImRvdWJsZSBwcmVjaXNpb25cIiB9O1xuICAgIH1cblxuICAgIC8vIEJvb2xlYW5cbiAgICBpZiAodWR0X25hbWUgPT09IFwiYm9vbFwiKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBgYm9vbGVhbiR7c2luZ2xlT3JBcnJheX1gIH07XG4gICAgfVxuXG4gICAgLy8gVGltZXN0YW1weiB0eXBlc1xuICAgIGlmICh1ZHRfbmFtZSA9PT0gXCJ0aW1lc3RhbXB0elwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBgZGF0ZSR7c2luZ2xlT3JBcnJheX1gLFxuICAgICAgICAuLi4ocHJlY2lzaW9uICE9PSBudWxsICYmIHtcbiAgICAgICAgICBwcmVjaXNpb246IHByZWNpc2lvbixcbiAgICAgICAgfSksXG4gICAgICB9OyAvLyBEYXRlUHJvcCDihpIgdGltZXN0YW1wdHpcbiAgICB9XG5cbiAgICAvLyBKU09OXG4gICAgaWYgKHVkdF9uYW1lID09PSBcImpzb25cIiB8fCB1ZHRfbmFtZSA9PT0gXCJqc29uYlwiKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBcImpzb25cIiB9O1xuICAgIH1cblxuICAgIC8vIFZlY3RvciAocGd2ZWN0b3IpXG4gICAgaWYgKHVkdF9uYW1lID09PSBcInZlY3RvclwiKSB7XG4gICAgICAvLyB2ZWN0b3Ig7YOA7J6F7J2YIOywqOybkCDsiJjripQgY29sdW1uX2RlZmF1bHTrgpgg67OE64+EIOy/vOumrOuhnCDtmZXsnbjtlbTslbwg7ZWoXG4gICAgICAvLyDtmITsnqzripQg6riw67O46rCSIDDsnLzroZwg7ISk7KCVICjsi6TsoJwgZGltZW5zaW9uc+uKlCBnZXRNaWdyYXRpb25TZXRGcm9tRELsl5DshJwg67OE64+EIOy/vOumrOuhnCDtmZXsnbgpXG4gICAgICByZXR1cm4geyB0eXBlOiBgdmVjdG9yJHtzaW5nbGVPckFycmF5fWAsIGRpbWVuc2lvbnM6IDAgfTtcbiAgICB9XG5cbiAgICAvLyB0c3ZlY3RvciAoUG9zdGdyZVNRTCDsoITrrLgg6rKA7IOJ7JqpIO2DgOyehSlcbiAgICBpZiAodWR0X25hbWUgPT09IFwidHN2ZWN0b3JcIikge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJ0c3ZlY3RvclwiIH07XG4gICAgfVxuXG4gICAgdGhyb3cgbmV3IEVycm9yKGByZXNvbHZlIOu2iOqwgOuKpe2VnCBQb3N0Z3JlU1FMIOy7rOufvCDtg4DsnoU6ICR7dWR0X25hbWV9YCk7XG4gIH1cbn1cblxuZXhwb3J0IGNvbnN0IFBvc3RncmVTUUxTY2hlbWFSZWFkZXIgPSBuZXcgUG9zdGdyZVNRTFNjaGVtYVJlYWRlckNsYXNzKCk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Q0F3RU0sOEJBQU4sTUFBa0M7RUFDaEMsQUFBaUIsb0JBQW9CLElBQUksSUFBSTtHQUFDO0dBQVM7R0FBUTtHQUFPO0dBQVE7R0FBVyxDQUFDOzs7Ozs7O0VBUTFGLE1BQU0sc0JBQ0osV0FDQSxPQUM4QjtHQUM5QixJQUFJQSxXQUF1QkMsV0FBc0JDO0FBQ2pELE9BQUk7QUFDRixLQUFDLFdBQVcsV0FBVyxjQUFjLE1BQU0sS0FBSyxVQUFVLFdBQVcsTUFBTTtZQUNwRUMsR0FBWTtBQUNuQixRQUFJLGFBQWEsU0FBUyxFQUFFLFFBQVEsU0FBUyxrQkFBa0IsRUFBRTtBQUMvRCxZQUFPOztBQUVULFlBQVEsTUFBTSxFQUFFO0FBQ2hCLFdBQU87O0dBSVQsTUFBTSxtQkFBbUIsTUFBTSxLQUFLLG9CQUFvQixXQUFXLE1BQU07R0FFekUsTUFBTUMsVUFBNkIsVUFBVSxLQUFLLGFBQWE7SUFDN0QsTUFBTSxZQUFZLEtBQUssaUJBQWlCLFNBQVM7QUFHakQsUUFBSSxVQUFVLFNBQVMsVUFBVTtBQUMvQixlQUFVLGFBQWEsaUJBQWlCLFNBQVMsZ0JBQWdCOztBQUduRSxXQUFPO0tBQ0wsTUFBTSxTQUFTO0tBQ2YsVUFBVSxTQUFTLGdCQUFnQjtLQUNuQyxHQUFHO0tBRUgsVUFBVTtBQUNSLFVBQUksU0FBUyxpQkFBaUIsT0FBTyxTQUFTLGlCQUFpQixLQUFLO0FBQ2xFLGNBQU8sRUFDTCxXQUFXO1FBQ1QsTUFBTSxTQUFTLGlCQUFpQixNQUFNLFdBQVc7UUFDakQsWUFBWSxTQUFTLHlCQUF5QjtRQUMvQyxFQUNGOztBQUVILGFBQU8sRUFBRTtTQUNQO0tBRUosVUFBVTtBQUVSLFVBQUksU0FBUyxpQkFBaUIsT0FBTyxT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
|
|
548
|
+
|
|
549
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9zdGdyZXNxbC1zY2hlbWEtcmVhZGVyLmpzIiwibmFtZXMiOltdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWdyYXRpb24vcG9zdGdyZXNxbC1zY2hlbWEtcmVhZGVyLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSBcImFzc2VydFwiO1xuXG5pbXBvcnQgeyB0eXBlIEtuZXggfSBmcm9tIFwia25leFwiO1xuaW1wb3J0IHsgZ3JvdXAgfSBmcm9tIFwicmFkYXNoaVwiO1xuXG5pbXBvcnQge1xuICB0eXBlIE1pZ3JhdGlvbkNvbHVtbixcbiAgdHlwZSBNaWdyYXRpb25Gb3JlaWduLFxuICB0eXBlIE1pZ3JhdGlvbkluZGV4LFxuICB0eXBlIE1pZ3JhdGlvblNldCxcbiAgdHlwZSBSZWxhdGlvbk9uLFxufSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcblxuLyoqXG4gKiDtirnsoJUg7YWM7J2067iU7J2YIFBL66W8IOywuOyhsO2VmOuKlCDri6Trpbgg7YWM7J2067iU7J2YIEZLIOygleuztOyeheuLiOuLpC5cbiAqIFBLIO2DgOyehSDrs4Dqsr0g7IucIOq0gOugqCBGSyDsoJzslb3sobDqsbTsnYQg7LKY66as7ZWY6riwIOychO2VtCDsgqzsmqnrkKnri4jri6QuXG4gKi9cbmV4cG9ydCB0eXBlIFJlZmVyZW5jaW5nRm9yZWlnbktleSA9IHtcbiAgLyoqIEZL6rCAIOygleydmOuQnCDthYzsnbTruJTrqoUgKi9cbiAgdGFibGVOYW1lOiBzdHJpbmc7XG4gIC8qKiBGSyDsoJzslb3sobDqsbQg7J2066aEICovXG4gIGNvbnN0cmFpbnROYW1lOiBzdHJpbmc7XG4gIC8qKiBGSyDsu6zrn7zrqoUgKi9cbiAgY29sdW1uTmFtZTogc3RyaW5nO1xuICAvKiog7LC47KGw7ZWY64qUIO2FjOydtOu4lOuqhSAoUEvqsIAg7J6I64qUIO2FjOydtOu4lCkgKi9cbiAgcmVmZXJlbmNlZFRhYmxlTmFtZTogc3RyaW5nO1xuICAvKiog7LC47KGw7ZWY64qUIOy7rOufvOuqhSAo67O07Ya1ICdpZCcpICovXG4gIHJlZmVyZW5jZWRDb2x1bW5OYW1lOiBzdHJpbmc7XG4gIC8qKiBPTiBVUERBVEUg7JWh7IWYICovXG4gIG9uVXBkYXRlOiBSZWxhdGlvbk9uO1xuICAvKiogT04gREVMRVRFIOyVoeyFmCAqL1xuICBvbkRlbGV0ZTogUmVsYXRpb25Pbjtcbn07XG5cbmV4cG9ydCB0eXBlIFBnQ29sdW1uID0ge1xuICBjb2x1bW5fbmFtZTogc3RyaW5nO1xuICBkYXRhX3R5cGU6IHN0cmluZztcbiAgdWR0X25hbWU6IHN0cmluZztcbiAgY2hhcmFjdGVyX21heGltdW1fbGVuZ3RoOiBudW1iZXIgfCBudWxsO1xuICBwcmVjaXNpb246IG51bWJlciB8IG51bGw7XG4gIG51bWVyaWNfc2NhbGU6IG51bWJlciB8IG51bGw7XG4gIGlzX251bGxhYmxlOiBzdHJpbmc7XG4gIGNvbHVtbl9kZWZhdWx0OiBzdHJpbmcgfCBudWxsO1xuICBpc19nZW5lcmF0ZWQ6IHN0cmluZzsgLy8gJ3MnID0gU1RPUkVELCAndicgPSBWSVJUVUFMLCAnJyA9IG5vbmVcbiAgZ2VuZXJhdGlvbl9leHByZXNzaW9uOiBzdHJpbmcgfCBudWxsO1xufTtcblxudHlwZSBQZ0luZGV4ID0ge1xuICBpbmRleF9uYW1lOiBzdHJpbmc7XG4gIGNvbHVtbl9uYW1lOiBzdHJpbmc7XG4gIGlzX3VuaXF1ZTogYm9vbGVhbjtcbiAgaXNfcHJpbWFyeTogYm9vbGVhbjtcbiAgaW5kZXhfdHlwZTogc3RyaW5nO1xuICBudWxsc19maXJzdDogYm9vbGVhbjtcbiAgc29ydF9vcmRlcjogXCJBU0NcIiB8IFwiREVTQ1wiO1xuICBudWxsc19ub3RfZGlzdGluY3Q6IGJvb2xlYW47XG4gIGNvbHVtbl9vcmRlcjogbnVtYmVyO1xuICBpbmRleF9kZWZpbml0aW9uOiBzdHJpbmc7XG4gIHByZWRpY2F0ZT86IHN0cmluZyB8IG51bGw7XG59O1xuXG50eXBlIFBnRm9yZWlnbiA9IHtcbiAgY29uc3RyYWludF9uYW1lOiBzdHJpbmc7XG4gIGNvbHVtbl9uYW1lOiBzdHJpbmc7XG4gIGZvcmVpZ25fdGFibGVfbmFtZTogc3RyaW5nO1xuICBmb3JlaWduX2NvbHVtbl9uYW1lOiBzdHJpbmc7XG4gIHVwZGF0ZV9ydWxlOiBzdHJpbmc7XG4gIGRlbGV0ZV9ydWxlOiBzdHJpbmc7XG59O1xuXG50eXBlIFJhd0NhcGFibGVLbmV4ID0gUGljazxLbmV4LCBcInJhd1wiPjtcblxuY2xhc3MgUG9zdGdyZVNRTFNjaGVtYVJlYWRlckNsYXNzIHtcbiAgcHJpdmF0ZSByZWFkb25seSBnZW5lcmljSW5kZXhUeXBlcyA9IG5ldyBTZXQoW1wiYnRyZWVcIiwgXCJoYXNoXCIsIFwiZ2luXCIsIFwiZ2lzdFwiLCBcInBncm9vbmdhXCJdKTtcblxuICAvKipcbiAgICogRELsl5DshJwg7YWM7J2067iUIOygleuztOulvCDsnb3slrTshJwgTWlncmF0aW9uU2V07J2EIOunjOuTpOyWtOyYteuLiOuLpC5cbiAgICogQHBhcmFtIGNvbXBhcmVEQiBLbmV4IOyduOyKpO2EtOyKpFxuICAgKiBAcGFyYW0gdGFibGUg7YWM7J2067iUIOydtOumhFxuICAgKiBAcmV0dXJucyBNaWdyYXRpb25TZXQg6rCd7LK0XG4gICAqL1xuICBhc3luYyBnZXRNaWdyYXRpb25TZXRGcm9tREIoXG4gICAgY29tcGFyZURCOiBSYXdDYXBhYmxlS25leCxcbiAgICB0YWJsZTogc3RyaW5nLFxuICApOiBQcm9taXNlPE1pZ3JhdGlvblNldCB8IG51bGw+IHtcbiAgICBsZXQgZGJDb2x1bW5zOiBQZ0NvbHVtbltdLCBkYkluZGV4ZXM6IFBnSW5kZXhbXSwgZGJGb3JlaWduczogUGdGb3JlaWduW107XG4gICAgdHJ5IHtcbiAgICAgIFtkYkNvbHVtbnMsIGRiSW5kZXhlcywgZGJGb3JlaWduc10gPSBhd2FpdCB0aGlzLnJlYWRUYWJsZShjb21wYXJlREIsIHRhYmxlKTtcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yICYmIGUubWVzc2FnZS5pbmNsdWRlcyhcIlRhYmxlIG5vdCBmb3VuZFwiKSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH1cbiAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvLyB2ZWN0b3Ig7Lus65+87J2YIGRpbWVuc2lvbnMg7KGw7ZqMXG4gICAgY29uc3QgdmVjdG9yRGltZW5zaW9ucyA9IGF3YWl0IHRoaXMuZ2V0VmVjdG9yRGltZW5zaW9ucyhjb21wYXJlREIsIHRhYmxlKTtcblxuICAgIGNvbnN0IGNvbHVtbnM6IE1pZ3JhdGlvbkNvbHVtbltdID0gZGJDb2x1bW5zLm1hcCgoZGJDb2x1bW4pID0+IHtcbiAgICAgIGNvbnN0IGRiQ29sVHlwZSA9IHRoaXMucmVzb2x2ZURCQ29sVHlwZShkYkNvbHVtbik7XG5cbiAgICAgIC8vIHZlY3RvciDtg4DsnoXsnbgg6rK97JqwIGRpbWVuc2lvbnMg7ISk7KCVXG4gICAgICBpZiAoZGJDb2xUeXBlLnR5cGUgPT09IFwidmVjdG9yXCIpIHtcbiAgICAgICAgZGJDb2xUeXBlLmRpbWVuc2lvbnMgPSB2ZWN0b3JEaW1lbnNpb25zW2RiQ29sdW1uLmNvbHVtbl9uYW1lXSA/PyAwO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBuYW1lOiBkYkNvbHVtbi5jb2x1bW5fbmFtZSxcbiAgICAgICAgbnVsbGFibGU6IGRiQ29sdW1uLmlzX251bGxhYmxlID09PSBcIllFU1wiLFxuICAgICAgICAuLi5kYkNvbFR5cGUsXG4gICAgICAgIC8vIEdlbmVyYXRlZCBDb2x1bW4g7LKY66asXG4gICAgICAgIC4uLigoKSA9PiB7XG4gICAgICAgICAgaWYgKGRiQ29sdW1uLmlzX2dlbmVyYXRlZCA9PT0gXCJzXCIgfHwgZGJDb2x1bW4uaXNfZ2VuZXJhdGVkID09PSBcInZcIikge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgZ2VuZXJhdGVkOiB7XG4gICAgICAgICAgICAgICAgdHlwZTogZGJDb2x1bW4uaXNfZ2VuZXJhdGVkID09PSBcInNcIiA/IFwiU1RPUkVEXCIgOiBcIlZJUlRVQUxcIixcbiAgICAgICAgICAgICAgICBleHByZXNzaW9uOiBkYkNvbHVtbi5nZW5lcmF0aW9uX2V4cHJlc3Npb24gPz8gXCJcIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgfSkoKSxcbiAgICAgICAgLy8gRGVmYXVsdCDqsJIg7LKY66asIChHZW5lcmF0ZWQgQ29sdW1u7J20IOyVhOuLjCDqsr3smrDrp4wpXG4gICAgICAgIC4uLigoKSA9PiB7XG4gICAgICAgICAgLy8gR2VuZXJhdGVkIENvbHVtbuydgCBkZWZhdWx0IOqwkuydtCDsl4bsnYxcbiAgICAgICAgICBpZiAoZGJDb2x1bW4uaXNfZ2VuZXJhdGVkID09PSBcInNcIiB8fCBkYkNvbHVtbi5pc19nZW5lcmF0ZWQgPT09IFwidlwiKSB7XG4gICAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGRiQ29sdW1uLmNvbHVtbl9kZWZhdWx0ICE9PSBudWxsKSB7XG4gICAgICAgICAgICAvLyBQb3N0Z3JlU1FMIGRlZmF1bHQg6rCSIOygleumrCAobmV4dHZhbCwgQ1VSUkVOVF9USU1FU1RBTVAg65OxKVxuICAgICAgICAgICAgbGV0IGRlZmF1bHRWYWx1ZSA9IGRiQ29sdW1uLmNvbHVtbl9kZWZhdWx0O1xuXG4gICAgICAgICAgICAvLyBuZXh0dmFsIOygnOqxsCAoU0VSSUFMIO2DgOyehSlcbiAgICAgICAgICAgIGlmIChkZWZhdWx0VmFsdWUuc3RhcnRzV2l0aChcIm5leHR2YWwoXCIpKSB7XG4gICAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8g7YOA7J6FIOy6kOyKpO2MhSDsoJzqsbAgKOyYiDogJzEnOjppbnRlZ2VyIOKGkiAxKVxuICAgICAgICAgICAgZGVmYXVsdFZhbHVlID0gZGVmYXVsdFZhbHVlLnJlcGxhY2UoLzo6W1xcd1xcc10rJC9nLCBcIlwiKTtcblxuICAgICAgICAgICAgLy8g65Sw7Ji07ZGc6rCAIHNpbmdsZSBxdW90ZeyduCDqsr3smrAgZG91YmxlIHF1b3Rl66GcIOuzgO2ZmFxuICAgICAgICAgICAgaWYgKGRlZmF1bHRWYWx1ZS5zdGFydHNXaXRoKFwiJ1wiKSAmJiBkZWZhdWx0VmFsdWUuZW5kc1dpdGgoXCInXCIpKSB7XG4gICAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSA9IGRlZmF1bHRWYWx1ZS5yZXBsYWNlQWxsKFwiJ1wiLCAnXCInKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgZGVmYXVsdFRvOiBkZWZhdWx0VmFsdWUsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4ge307XG4gICAgICAgIH0pKCksXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gUFJJTUFSWSBLRVnsmYAgZm9yZWlnbiBrZXnsmqkg7J24642x7IqkIOygnOyZuFxuICAgIGNvbnN0IGRiSW5kZXhlc0dyb3VwID0gZ3JvdXAoXG4gICAgICBkYkluZGV4ZXMuZmlsdGVyKFxuICAgICAgICAoZGJJbmRleCkgPT5cbiAgICAgICAgICAhZGJJbmRleC5pc19wcmltYXJ5ICYmXG4gICAgICAgICAgIWRiRm9yZWlnbnMuZmluZCgoZGJGb3JlaWduKSA9PiBkYkluZGV4LmluZGV4X25hbWUuaW5jbHVkZXMoZGJGb3JlaWduLmNvbnN0cmFpbnRfbmFtZSkpLFxuICAgICAgKSxcbiAgICAgIChkYkluZGV4KSA9PiBkYkluZGV4LmluZGV4X25hbWUsXG4gICAgKTtcblxuICAgIC8vIGluZGV4ZXMg7LKY66asXG4gICAgY29uc3QgaW5kZXhlczogTWlncmF0aW9uSW5kZXhbXSA9IE9iamVjdC5rZXlzKGRiSW5kZXhlc0dyb3VwKS5tYXAoKGluZGV4TmFtZSkgPT4ge1xuICAgICAgY29uc3QgY3VycmVudEluZGV4ZXMgPSBkYkluZGV4ZXNHcm91cFtpbmRleE5hbWVdPy50b1NvcnRlZChcbiAgICAgICAgKGxlZnQsIHJpZ2h0KSA9PiBsZWZ0LmNvbHVtbl9vcmRlciAtIHJpZ2h0LmNvbHVtbl9vcmRlcixcbiAgICAgICk7XG4gICAgICBhc3NlcnQoY3VycmVudEluZGV4ZXMpO1xuXG4gICAgICBjb25zdCBmaXJzdEluZGV4ID0gY3VycmVudEluZGV4ZXNbMF07XG4gICAgICBjb25zdCBwYXJzZWRJbmRleERlZmluaXRpb24gPSB0aGlzLnBhcnNlSW5kZXhEZWZpbml0aW9uKGZpcnN0SW5kZXguaW5kZXhfZGVmaW5pdGlvbik7XG4gICAgICBjb25zdCByZXN0b3JlZEluZGV4VHlwZSA9IHRoaXMucmVzdG9yZU1pZ3JhdGlvbkluZGV4VHlwZShcbiAgICAgICAgZmlyc3RJbmRleCxcbiAgICAgICAgcGFyc2VkSW5kZXhEZWZpbml0aW9uLmFjY2Vzc01ldGhvZCxcbiAgICAgICk7XG4gICAgICBjb25zdCB1c2luZyA9IHRoaXMucmVzdG9yZUdlbmVyaWNVc2luZyhcbiAgICAgICAgcGFyc2VkSW5kZXhEZWZpbml0aW9uLmFjY2Vzc01ldGhvZCA/PyBmaXJzdEluZGV4LmluZGV4X3R5cGUsXG4gICAgICApO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiByZXN0b3JlZEluZGV4VHlwZSxcbiAgICAgICAgbmFtZTogaW5kZXhOYW1lLFxuICAgICAgICBjb2x1bW5zOiBjdXJyZW50SW5kZXhlcy5tYXAoKGlkeCkgPT4gKHtcbiAgICAgICAgICBuYW1lOiBpZHguY29sdW1uX25hbWUsXG4gICAgICAgICAgLi4uKHRoaXMuZXh0cmFjdEluZGV4Q29sdW1uT3BjbGFzcyhcbiAgICAgICAgICAgIHBhcnNlZEluZGV4RGVmaW5pdGlvbi5jb2x1bW5EZWZpbml0aW9uc1tpZHguY29sdW1uX29yZGVyIC0gMV0sXG4gICAgICAgICAgKVxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgb3BjbGFzczogdGhpcy5leHRyYWN0SW5kZXhDb2x1bW5PcGNsYXNzKFxuICAgICAgICAgICAgICAgICAgcGFyc2VkSW5kZXhEZWZpbml0aW9uLmNvbHVtbkRlZmluaXRpb25zW2lkeC5jb2x1bW5fb3JkZXIgLSAxXSxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA6IHt9KSxcbiAgICAgICAgICAuLi4odXNpbmcgPT09IFwiYnRyZWVcIlxuICAgICAgICAgICAgPyB7XG4gICAgICAgICAgICAgICAgc29ydE9yZGVyOiBpZHguc29ydF9vcmRlcixcbiAgICAgICAgICAgICAgICBudWxsc0ZpcnN0OiBpZHgubnVsbHNfZmlyc3QsXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDoge30pLFxuICAgICAgICB9KSksXG5cbiAgICAgICAgbnVsbHNOb3REaXN0aW5jdDogZmlyc3RJbmRleC5udWxsc19ub3RfZGlzdGluY3QsXG4gICAgICAgIC4uLihmaXJzdEluZGV4LnByZWRpY2F0ZSA/IHsgd2hlcmU6IGZpcnN0SW5kZXgucHJlZGljYXRlIH0gOiB7fSksXG4gICAgICAgIC4uLih1c2luZyA/IHsgdXNpbmcgfSA6IHt9KSxcbiAgICAgICAgLi4udGhpcy5wYXJzZVZlY3RvckluZGV4T3B0aW9ucyhyZXN0b3JlZEluZGV4VHlwZSwgcGFyc2VkSW5kZXhEZWZpbml0aW9uLndpdGhPcHRpb25zKSxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICAvLyBmb3JlaWducyDsspjrpqxcbiAgICBjb25zdCBmb3JlaWduczogTWlncmF0aW9uRm9yZWlnbltdID0gZGJGb3JlaWducy5tYXAoKGRiRm9yZWlnbikgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29sdW1uczogW2RiRm9yZWlnbi5jb2x1bW5fbmFtZV0sXG4gICAgICAgIHRvOiBgJHtkYkZvcmVpZ24uZm9yZWlnbl90YWJsZV9uYW1lfS4ke2RiRm9yZWlnbi5mb3JlaWduX2NvbHVtbl9uYW1lfWAsXG4gICAgICAgIG9uVXBkYXRlOiB0aGlzLm1hcENvbnN0cmFpbnRBY3Rpb24oZGJGb3JlaWduLnVwZGF0ZV9ydWxlKSxcbiAgICAgICAgb25EZWxldGU6IHRoaXMubWFwQ29uc3RyYWludEFjdGlvbihkYkZvcmVpZ24uZGVsZXRlX3J1bGUpLFxuICAgICAgfTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICB0YWJsZSxcbiAgICAgIGNvbHVtbnMsXG4gICAgICBpbmRleGVzLFxuICAgICAgZm9yZWlnbnMsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQb3N0Z3JlU1FM7J2YIGNvbnN0cmFpbnQgYWN0aW9u7J2EIEtuZXgg7ZiV7Iud7Jy866GcIOuzgO2ZmFxuICAgKi9cbiAgcHJpdmF0ZSBtYXBDb25zdHJhaW50QWN0aW9uKGFjdGlvbjogc3RyaW5nKTogUmVsYXRpb25PbiB7XG4gICAgY29uc3QgYWN0aW9uTWFwOiBSZWNvcmQ8c3RyaW5nLCBSZWxhdGlvbk9uPiA9IHtcbiAgICAgIFwiTk8gQUNUSU9OXCI6IFwiTk8gQUNUSU9OXCIsXG4gICAgICBSRVNUUklDVDogXCJSRVNUUklDVFwiLFxuICAgICAgQ0FTQ0FERTogXCJDQVNDQURFXCIsXG4gICAgICBcIlNFVCBOVUxMXCI6IFwiU0VUIE5VTExcIixcbiAgICAgIFwiU0VUIERFRkFVTFRcIjogXCJTRVQgREVGQVVMVFwiLFxuICAgIH07XG4gICAgcmV0dXJuIGFjdGlvbk1hcFthY3Rpb25dID8/IFwiTk8gQUNUSU9OXCI7XG4gIH1cblxuICAvKipcbiAgICog6riw7KG0IO2FjOydtOu4lCDsnb3slrTshJwgY29scywgaW5kZXhlcywgZm9yZWlnbnMg67CY7ZmYXG4gICAqL1xuICBhc3luYyByZWFkVGFibGUoXG4gICAgY29tcGFyZURCOiBSYXdDYXBhYmxlS25leCxcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgKTogUHJvbWlzZTxbUGdDb2x1bW5bXSwgUGdJbmRleFtdLCBQZ0ZvcmVpZ25bXV0+IHtcbiAgICAvLyBDb2x1bW5zIOyhsO2ajCAoR2VuZXJhdGVkIENvbHVtbiDsoJXrs7Qg7Y+s7ZWoKVxuICAgIGNvbnN0IGNvbHVtbnNRdWVyeSA9IGBcbiAgICAgIFNFTEVDVFxuICAgICAgICBjLmNvbHVtbl9uYW1lLFxuICAgICAgICBjLmRhdGFfdHlwZSxcbiAgICAgICAgYy51ZHRfbmFtZSxcbiAgICAgICAgQ09BTEVTQ0UoXG4gICAgICAgICAgYy5jaGFyYWN0ZXJfbWF4aW11bV9sZW5ndGgsXG4gICAgICAgICAgQ0FTRSBXSEVOIGMuZGF0YV90eXBlID0gJ0FSUkFZJyBBTkQgYS5hdHR0eXBtb2QgPiAwXG4gICAgICAgICAgICBUSEVOIGEuYXR0dHlwbW9kIC0gNFxuICAgICAgICAgICAgRUxTRSBOVUxMXG4gICAgICAgICAgRU5EXG4gICAgICAgICkgQVMgY2hhcmFjdGVyX21heGltdW1fbGVuZ3RoLFxuICAgICAgICBDT0FMRVNDRShjLmRhdGV0aW1lX3ByZWNpc2lvbiwgYy5udW1lcmljX3ByZWNpc2lvbikgQVMgcHJlY2lzaW9uLFxuICAgICAgICBjLm51bWVyaWNfc2NhbGUsXG4gICAgICAgIGMuaXNfbnVsbGFibGUsXG4gICAgICAgIGMuY29sdW1uX2RlZmF1bHQsXG4gICAgICAgIENPQUxFU0NFKGEuYXR0Z2VuZXJhdGVkLCAnJykgYXMgaXNfZ2VuZXJhdGVkLFxuICAgICAgICBjLmdlbmVyYXRpb25fZXhwcmVzc2lvblxuICAgICAgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEuY29sdW1ucyBjXG4gICAgICBMRUZUIEpPSU4gcGdfYXR0cmlidXRlIGEgT04gYS5hdHRuYW1lID0gYy5jb2x1bW5fbmFtZVxuICAgICAgICBBTkQgYS5hdHRyZWxpZCA9IChcbiAgICAgICAgICBTRUxFQ1Qgb2lkIEZST00gcGdfY2xhc3MgV0hFUkUgcmVsbmFtZSA9IGMudGFibGVfbmFtZVxuICAgICAgICAgIEFORCByZWxuYW1lc3BhY2UgPSAoU0VMRUNUIG9pZCBGUk9NIHBnX25hbWVzcGFjZSBXSEVSRSBuc3BuYW1lID0gYy50YWJsZV9zY2hlbWEpXG4gICAgICAgIClcbiAgICAgIFdIRVJFIGMudGFibGVfbmFtZSA9ID9cbiAgICAgICAgQU5EIGMudGFibGVfc2NoZW1hID0gJ3B1YmxpYydcbiAgICAgIE9SREVSIEJZIGMub3JkaW5hbF9wb3NpdGlvblxuICAgIGA7XG4gICAgY29uc3QgY29sdW1ucyA9IChhd2FpdCBjb21wYXJlREIucmF3KGNvbHVtbnNRdWVyeSwgW3RhYmxlTmFtZV0pKS5yb3dzIGFzIFBnQ29sdW1uW107XG4gICAgaWYgKGNvbHVtbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRhYmxlIG5vdCBmb3VuZDogJHt0YWJsZU5hbWV9YCk7XG4gICAgfVxuXG4gICAgLy8gSW5kZXhlcyDsobDtmowgKFBHcm9vbmdhIO2RnO2YhOyLnSDsnbjrjbHsiqQg7Y+s7ZWoKVxuICAgIGNvbnN0IGluZGV4ZXNRdWVyeSA9IGBcbiAgICAgIFNFTEVDVFxuICAgICAgICAgIGkucmVsbmFtZSBBUyBpbmRleF9uYW1lLFxuICAgICAgICAgIENBU0VcbiAgICAgICAgICAgICAgV0hFTiBhbS5hbW5hbWUgPSAncGdyb29uZ2EnIEFORCB1LmF0dG51bSA9IDAgVEhFTlxuICAgICAgICAgICAgICAgICAgcmVnZXhwX3JlcGxhY2UoXG4gICAgICAgICAgICAgICAgICAgICAgcmVnZXhwX3JlcGxhY2UoXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFRSSU0ocGdyb29uZ2FfY29sLmNvbHVtbl9leHByKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgJzo6dGV4dCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAnZydcbiAgICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICAgICdbKCldJyxcbiAgICAgICAgICAgICAgICAgICAgICAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAnZydcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgRUxTRSBhLmF0dG5hbWVcbiAgICAgICAgICBFTkQgQVMgY29sdW1uX25hbWUsXG4gICAgICAgICAgaXguaW5kaXN1bmlxdWUgQVMgaXNfdW5pcXVlLFxuICAgICAgICAgIGl4LmluZGlzcHJpbWFyeSBBUyBpc19wcmltYXJ5LFxuICAgICAgICAgIGFtLmFtbmFtZSBBUyBpbmRleF90eXBlLFxuICAgICAgICAgIENPQUxFU0NFKCh1Lm9wdCAmIDIpID0gMiwgRkFMU0UpIEFTIG51bGxzX2ZpcnN0LFxuICAgICAgICAgIENBU0UgXG4gICAgICAgICAgICAgIFdIRU4gKHUub3B0ICYgMSkgPSAxIFRIRU4gJ0RFU0MnXG4gICAgICAgICAgICAgIEVMU0UgJ0FTQydcbiAgICAgICAgICBFTkQgQVMgc29ydF9vcmRlcixcbiAgICAgICAgICBpeC5pbmRudWxsc25vdGRpc3RpbmN0IEFTIG51bGxzX25vdF9kaXN0aW5jdCxcbiAgICAgICAgICB1Lm9yZCBBUyBjb2x1bW5fb3JkZXIsXG4gICAgICAgICAgcGdfZ2V0X2luZGV4ZGVmKGl4LmluZGV4cmVsaWQpIEFTIGluZGV4X2RlZmluaXRpb24sXG4gICAgICAgICAgcGdfZ2V0X2V4cHIoaXguaW5kcHJlZCwgaXguaW5kcmVsaWQpIEFTIHByZWRpY2F0ZVxuICAgICAgRlJPTSBwZ19jbGFzcyB0XG4gICAgICBKT0lOIHBnX2luZGV4IGl4IE9OIHQub2lkID0gaXguaW5kcmVsaWRcbiAgICAgIEpPSU4gcGdfY2xhc3MgaSBPTiBpLm9pZCA9IGl4LmluZGV4cmVsaWRcbiAgICAgIEpPSU4gcGdfYW0gYW0gT04gaS5yZWxhbSA9IGFtLm9pZFxuICAgICAgSk9JTiBMQVRFUkFMIHVubmVzdChpeC5pbmRrZXksIGl4LmluZG9wdGlvbilcbiAgICAgICAgICBXSVRIIE9SRElOQUxJVFkgQVMgdShhdHRudW0sIG9wdCwgb3JkKSBPTiB0cnVlXG4gICAgICBMRUZUIEpPSU4gcGdfYXR0cmlidXRlIGEgT04gYS5hdHRyZWxpZCA9IHQub2lkIFxuICAgICAgICAgIEFORCBhLmF0dG51bSA9IHUuYXR0bnVtIFxuICAgICAgICAgIEFORCB1LmF0dG51bSA+IDBcbiAgICAgIExFRlQgSk9JTiBMQVRFUkFMIChcbiAgICAgICAgICBTRUxFQ1QgXG4gICAgICAgICAgICAgIHVubmVzdChcbiAgICAgICAgICAgICAgICAgIENBU0UgXG4gICAgICAgICAgICAgICAgICAgICAgV0hFTiBwZ19nZXRfZXhwcihpeC5pbmRleHBycywgaXguaW5kcmVsaWQpIH4gJ15BUlJBWVxcXFxbJyBUSEVOXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ190b19hcnJheShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2V4cF9yZXBsYWNlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBnX2dldF9leHByKGl4LmluZGV4cHJzLCBpeC5pbmRyZWxpZCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ15BUlJBWVxcXFxbKC4qKVxcXFxdJCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1xcXFwxJ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcsICdcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgIEVMU0VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgQVJSQVlbcGdfZ2V0X2V4cHIoaXguaW5kZXhwcnMsIGl4LmluZHJlbGlkKV1cbiAgICAgICAgICAgICAgICAgIEVORFxuICAgICAgICAgICAgICApIGFzIGNvbHVtbl9leHByXG4gICAgICApIHBncm9vbmdhX2NvbCBPTiBhbS5hbW5hbWUgPSAncGdyb29uZ2EnIEFORCB1LmF0dG51bSA9IDBcbiAgICAgIFdIRVJFIHQucmVsbmFtZSA9ID9cbiAgICAgICAgICBBTkQgKHUuYXR0bnVtID4gMCBPUiAoYW0uYW1uYW1lID0gJ3Bncm9vbmdhJyBBTkQgdS5hdHRudW0gPSAwKSlcbiAgICAgIE9SREVSIEJZIGkucmVsbmFtZSwgdS5vcmQ7XG5gO1xuICAgIGNvbnN0IGluZGV4ZXMgPSAoYXdhaXQgY29tcGFyZURCLnJhdyhpbmRleGVzUXVlcnksIFt0YWJsZU5hbWVdKSkucm93cztcblxuICAgIC8vIEZvcmVpZ24gS2V5cyDsobDtmoxcbiAgICBjb25zdCBmb3JlaWduc1F1ZXJ5ID0gYFxuICAgICAgU0VMRUNUXG4gICAgICAgIHRjLmNvbnN0cmFpbnRfbmFtZSxcbiAgICAgICAga2N1LmNvbHVtbl9uYW1lLFxuICAgICAgICBjY3UudGFibGVfbmFtZSBBUyBmb3JlaWduX3RhYmxlX25hbWUsXG4gICAgICAgIGNjdS5jb2x1bW5fbmFtZSBBUyBmb3JlaWduX2NvbHVtbl9uYW1lLFxuICAgICAgICByYy51cGRhdGVfcnVsZSxcbiAgICAgICAgcmMuZGVsZXRlX3J1bGVcbiAgICAgIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLnRhYmxlX2NvbnN0cmFpbnRzIEFTIHRjXG4gICAgICBKT0lOIGluZm9ybWF0aW9uX3NjaGVtYS5rZXlfY29sdW1uX3VzYWdlIEFTIGtjdVxuICAgICAgICBPTiB0Yy5jb25zdHJhaW50X25hbWUgPSBrY3UuY29uc3RyYWludF9uYW1lXG4gICAgICAgIEFORCB0Yy50YWJsZV9zY2hlbWEgPSBrY3UudGFibGVfc2NoZW1hXG4gICAgICBKT0lOIGluZm9ybWF0aW9uX3NjaGVtYS5jb25zdHJhaW50X2NvbHVtbl91c2FnZSBBUyBjY3VcbiAgICAgICAgT04gY2N1LmNvbnN0cmFpbnRfbmFtZSA9IHRjLmNvbnN0cmFpbnRfbmFtZVxuICAgICAgICBBTkQgY2N1LnRhYmxlX3NjaGVtYSA9IHRjLnRhYmxlX3NjaGVtYVxuICAgICAgSk9JTiBpbmZvcm1hdGlvbl9zY2hlbWEucmVmZXJlbnRpYWxfY29uc3RyYWludHMgQVMgcmNcbiAgICAgICAgT04gcmMuY29uc3RyYWludF9uYW1lID0gdGMuY29uc3RyYWludF9uYW1lXG4gICAgICAgIEFORCByYy5jb25zdHJhaW50X3NjaGVtYSA9IHRjLnRhYmxlX3NjaGVtYVxuICAgICAgV0hFUkUgdGMuY29uc3RyYWludF90eXBlID0gJ0ZPUkVJR04gS0VZJ1xuICAgICAgICBBTkQgdGMudGFibGVfbmFtZSA9ID9cbiAgICBgO1xuICAgIGNvbnN0IGZvcmVpZ25zID0gKGF3YWl0IGNvbXBhcmVEQi5yYXcoZm9yZWlnbnNRdWVyeSwgW3RhYmxlTmFtZV0pKS5yb3dzO1xuXG4gICAgcmV0dXJuIFtjb2x1bW5zLCBpbmRleGVzLCBmb3JlaWduc107XG4gIH1cblxuICBwcml2YXRlIHJlc3RvcmVNaWdyYXRpb25JbmRleFR5cGUoXG4gICAgaW5kZXg6IFBpY2s8UGdJbmRleCwgXCJpc191bmlxdWVcIiB8IFwiaW5kZXhfdHlwZVwiPixcbiAgICBhY2Nlc3NNZXRob2Q/OiBzdHJpbmcsXG4gICk6IE1pZ3JhdGlvbkluZGV4W1widHlwZVwiXSB7XG4gICAgY29uc3QgcmVzb2x2ZWRBY2Nlc3NNZXRob2QgPSAoYWNjZXNzTWV0aG9kID8/IGluZGV4LmluZGV4X3R5cGUpLnRvTG93ZXJDYXNlKCk7XG5cbiAgICBpZiAocmVzb2x2ZWRBY2Nlc3NNZXRob2QgPT09IFwiaG5zd1wiIHx8IHJlc29sdmVkQWNjZXNzTWV0aG9kID09PSBcIml2ZmZsYXRcIikge1xuICAgICAgcmV0dXJuIHJlc29sdmVkQWNjZXNzTWV0aG9kO1xuICAgIH1cblxuICAgIHJldHVybiBpbmRleC5pc191bmlxdWUgPyBcInVuaXF1ZVwiIDogXCJpbmRleFwiO1xuICB9XG5cbiAgcHJpdmF0ZSByZXN0b3JlR2VuZXJpY1VzaW5nKFxuICAgIGFjY2Vzc01ldGhvZDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICApOiBNaWdyYXRpb25JbmRleFtcInVzaW5nXCJdIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIWFjY2Vzc01ldGhvZCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBub3JtYWxpemVkID0gYWNjZXNzTWV0aG9kLnRvTG93ZXJDYXNlKCk7XG4gICAgaWYgKCF0aGlzLmdlbmVyaWNJbmRleFR5cGVzLmhhcyhub3JtYWxpemVkKSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4gbm9ybWFsaXplZCBhcyBNaWdyYXRpb25JbmRleFtcInVzaW5nXCJdO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVZlY3RvckluZGV4T3B0aW9ucyhcbiAgICB0eXBlOiBNaWdyYXRpb25JbmRleFtcInR5cGVcIl0sXG4gICAgd2l0aE9wdGlvbnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4sXG4gICk6IFBpY2s8TWlncmF0aW9uSW5kZXgsIFwibVwiIHwgXCJlZkNvbnN0cnVjdGlvblwiIHwgXCJsaXN0c1wiPiB7XG4gICAgaWYgKHR5cGUgPT09IFwiaG5zd1wiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi4odGhpcy5wYXJzZUludGVnZXJPcHRpb24od2l0aE9wdGlvbnMubSkgIT09IHVuZGVmaW5lZFxuICAgICAgICAgID8geyBtOiB0aGlzLnBhcnNlSW50ZWdlck9wdGlvbih3aXRoT3B0aW9ucy5tKSB9XG4gICAgICAgICAgOiB7fSksXG4gICAgICAgIC4uLih0aGlzLnBhcnNlSW50ZWdlck9wdGlvbih3aXRoT3B0aW9ucy5lZl9jb25zdHJ1Y3Rpb24pICE9PSB1bmRlZmluZWRcbiAgICAgICAgICA/IHsgZWZDb25zdHJ1Y3Rpb246IHRoaXMucGFyc2VJbnRlZ2VyT3B0aW9uKHdpdGhPcHRpb25zLmVmX2NvbnN0cnVjdGlvbikgfVxuICAgICAgICAgIDoge30pLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAodHlwZSA9PT0gXCJpdmZmbGF0XCIpIHtcbiAgICAgIHJldHVybiB0aGlzLnBhcnNlSW50ZWdlck9wdGlvbih3aXRoT3B0aW9ucy5saXN0cykgIT09IHVuZGVmaW5lZFxuICAgICAgICA/IHsgbGlzdHM6IHRoaXMucGFyc2VJbnRlZ2VyT3B0aW9uKHdpdGhPcHRpb25zLmxpc3RzKSB9XG4gICAgICAgIDoge307XG4gICAgfVxuXG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUludGVnZXJPcHRpb24odmFsdWU6IHN0cmluZyB8IHVuZGVmaW5lZCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCF2YWx1ZSkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJzZWQgPSBOdW1iZXIucGFyc2VJbnQodmFsdWUsIDEwKTtcbiAgICByZXR1cm4gTnVtYmVyLmlzTmFOKHBhcnNlZCkgPyB1bmRlZmluZWQgOiBwYXJzZWQ7XG4gIH1cblxuICBwcml2YXRlIGV4dHJhY3RJbmRleENvbHVtbk9wY2xhc3MoY29sdW1uRGVmaW5pdGlvbjogc3RyaW5nIHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBpZiAoIWNvbHVtbkRlZmluaXRpb24pIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgY29uc3QgdHJpbW1lZCA9IGNvbHVtbkRlZmluaXRpb25cbiAgICAgIC5yZXBsYWNlKC9cXHMrTlVMTFNcXHMrKEZJUlNUfExBU1QpXFxzKiQvaSwgXCJcIilcbiAgICAgIC5yZXBsYWNlKC9cXHMrKEFTQ3xERVNDKVxccyokL2ksIFwiXCIpXG4gICAgICAudHJpbSgpO1xuICAgIGNvbnN0IHRva2VucyA9IHRoaXMudG9rZW5pemVUb3BMZXZlbCh0cmltbWVkKTtcblxuICAgIGlmICh0b2tlbnMubGVuZ3RoIDwgMikge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAodG9rZW5zW3Rva2Vucy5sZW5ndGggLSAyXT8udG9VcHBlckNhc2UoKSA9PT0gXCJDT0xMQVRFXCIpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRva2Vucy5hdCgtMSk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlSW5kZXhEZWZpbml0aW9uKGluZGV4RGVmaW5pdGlvbjogc3RyaW5nKToge1xuICAgIGFjY2Vzc01ldGhvZD86IHN0cmluZztcbiAgICBjb2x1bW5EZWZpbml0aW9uczogc3RyaW5nW107XG4gICAgd2l0aE9wdGlvbnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIH0ge1xuICAgIGNvbnN0IGFjY2Vzc01ldGhvZCA9IGluZGV4RGVmaW5pdGlvbi5tYXRjaCgvXFxiVVNJTkdcXHMrKFthLXpfXVtcXHddKikvaSk/LlsxXT8udG9Mb3dlckNhc2UoKTtcbiAgICBjb25zdCB1c2luZ01hdGNoSW5kZXggPSBpbmRleERlZmluaXRpb24uc2VhcmNoKC9cXGJVU0lOR1xcYi9pKTtcbiAgICBjb25zdCBjb2x1bW5zU3RhcnQgPSB1c2luZ01hdGNoSW5kZXggPj0gMCA/IGluZGV4RGVmaW5pdGlvbi5pbmRleE9mKFwiKFwiLCB1c2luZ01hdGNoSW5kZXgpIDogLTE7XG4gICAgY29uc3QgY29sdW1uc0VuZCA9XG4gICAgICBjb2x1bW5zU3RhcnQgPj0gMCA/IHRoaXMuZmluZE1hdGNoaW5nUGFyZW50aGVzaXMoaW5kZXhEZWZpbml0aW9uLCBjb2x1bW5zU3RhcnQpIDogLTE7XG4gICAgY29uc3QgY29sdW1uRGVmaW5pdGlvbnMgPVxuICAgICAgY29sdW1uc1N0YXJ0ID49IDAgJiYgY29sdW1uc0VuZCA+IGNvbHVtbnNTdGFydFxuICAgICAgICA/IHRoaXMuc3BsaXRUb3BMZXZlbChpbmRleERlZmluaXRpb24uc2xpY2UoY29sdW1uc1N0YXJ0ICsgMSwgY29sdW1uc0VuZCksIFwiLFwiKVxuICAgICAgICA6IFtdO1xuXG4gICAgY29uc3Qgd2l0aE1hdGNoID0gL1xcYldJVEhcXHMqXFwoL2kuZXhlYyhpbmRleERlZmluaXRpb24pO1xuICAgIGNvbnN0IHdpdGhTdGFydCA9IHdpdGhNYXRjaCA/IGluZGV4RGVmaW5pdGlvbi5pbmRleE9mKFwiKFwiLCB3aXRoTWF0Y2guaW5kZXgpIDogLTE7XG4gICAgY29uc3Qgd2l0aEVuZCA9IHdpdGhTdGFydCA+PSAwID8gdGhpcy5maW5kTWF0Y2hpbmdQYXJlbnRoZXNpcyhpbmRleERlZmluaXRpb24sIHdpdGhTdGFydCkgOiAtMTtcbiAgICBjb25zdCB3aXRoT3B0aW9ucyA9XG4gICAgICB3aXRoU3RhcnQgPj0gMCAmJiB3aXRoRW5kID4gd2l0aFN0YXJ0XG4gICAgICAgID8gdGhpcy5wYXJzZUluZGV4T3B0aW9uRW50cmllcyhpbmRleERlZmluaXRpb24uc2xpY2Uod2l0aFN0YXJ0ICsgMSwgd2l0aEVuZCkpXG4gICAgICAgIDoge307XG5cbiAgICByZXR1cm4ge1xuICAgICAgYWNjZXNzTWV0aG9kLFxuICAgICAgY29sdW1uRGVmaW5pdGlvbnMsXG4gICAgICB3aXRoT3B0aW9ucyxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUluZGV4T3B0aW9uRW50cmllcyhvcHRpb25Tb3VyY2U6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLnNwbGl0VG9wTGV2ZWwob3B0aW9uU291cmNlLCBcIixcIikucmVkdWNlPFJlY29yZDxzdHJpbmcsIHN0cmluZz4+KChyZXN1bHQsIGVudHJ5KSA9PiB7XG4gICAgICBjb25zdCBtYXRjaGVkID0gZW50cnkudHJpbSgpLm1hdGNoKC9eKFthLXpfXVtcXHddKilcXHMqPVxccyooLispJC9pKTtcbiAgICAgIGlmICghbWF0Y2hlZCkge1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBbLCBrZXksIHJhd1ZhbHVlXSA9IG1hdGNoZWQ7XG4gICAgICByZXN1bHRba2V5LnRvTG93ZXJDYXNlKCldID0gcmF3VmFsdWUudHJpbSgpLnJlcGxhY2UoL15bJ1wiXXxbJ1wiXSQvZywgXCJcIik7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sIHt9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3BsaXRUb3BMZXZlbChzb3VyY2U6IHN0cmluZywgZGVsaW1pdGVyOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgaXRlbXM6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IHN0YXJ0ID0gMDtcbiAgICBsZXQgcGFyZW5EZXB0aCA9IDA7XG4gICAgbGV0IGJyYWNrZXREZXB0aCA9IDA7XG4gICAgbGV0IGluU2luZ2xlUXVvdGUgPSBmYWxzZTtcbiAgICBsZXQgaW5Eb3VibGVRdW90ZSA9IGZhbHNlO1xuXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHNvdXJjZS5sZW5ndGg7IGluZGV4ICs9IDEpIHtcbiAgICAgIGNvbnN0IGNoYXIgPSBzb3VyY2VbaW5kZXhdO1xuICAgICAgY29uc3QgbmV4dENoYXIgPSBzb3VyY2VbaW5kZXggKyAxXTtcblxuICAgICAgaWYgKGNoYXIgPT09IFwiJ1wiICYmICFpbkRvdWJsZVF1b3RlKSB7XG4gICAgICAgIGlmIChpblNpbmdsZVF1b3RlICYmIG5leHRDaGFyID09PSBcIidcIikge1xuICAgICAgICAgIGluZGV4ICs9IDE7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaW5TaW5nbGVRdW90ZSA9ICFpblNpbmdsZVF1b3RlO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNoYXIgPT09ICdcIicgJiYgIWluU2luZ2xlUXVvdGUpIHtcbiAgICAgICAgaWYgKGluRG91YmxlUXVvdGUgJiYgbmV4dENoYXIgPT09ICdcIicpIHtcbiAgICAgICAgICBpbmRleCArPSAxO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGluRG91YmxlUXVvdGUgPSAhaW5Eb3VibGVRdW90ZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChpblNpbmdsZVF1b3RlIHx8IGluRG91YmxlUXVvdGUpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChjaGFyID09PSBcIihcIikge1xuICAgICAgICBwYXJlbkRlcHRoICs9IDE7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKGNoYXIgPT09IFwiKVwiKSB7XG4gICAgICAgIHBhcmVuRGVwdGggLT0gMTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAoY2hhciA9PT0gXCJbXCIpIHtcbiAgICAgICAgYnJhY2tldERlcHRoICs9IDE7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKGNoYXIgPT09IFwiXVwiKSB7XG4gICAgICAgIGJyYWNrZXREZXB0aCAtPSAxO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNoYXIgPT09IGRlbGltaXRlciAmJiBwYXJlbkRlcHRoID09PSAwICYmIGJyYWNrZXREZXB0aCA9PT0gMCkge1xuICAgICAgICBpdGVtcy5wdXNoKHNvdXJjZS5zbGljZShzdGFydCwgaW5kZXgpLnRyaW0oKSk7XG4gICAgICAgIHN0YXJ0ID0gaW5kZXggKyAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHRhaWwgPSBzb3VyY2Uuc2xpY2Uoc3RhcnQpLnRyaW0oKTtcbiAgICBpZiAodGFpbC5sZW5ndGggPiAwKSB7XG4gICAgICBpdGVtcy5wdXNoKHRhaWwpO1xuICAgIH1cblxuICAgIHJldHVybiBpdGVtcztcbiAgfVxuXG4gIHByaXZhdGUgdG9rZW5pemVUb3BMZXZlbChzb3VyY2U6IHN0cmluZyk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCB0b2tlbnM6IHN0cmluZ1tdID0gW107XG4gICAgbGV0IHN0YXJ0ID0gLTE7XG4gICAgbGV0IHBhcmVuRGVwdGggPSAwO1xuICAgIGxldCBicmFja2V0RGVwdGggPSAwO1xuICAgIGxldCBpblNpbmdsZVF1b3RlID0gZmFsc2U7XG4gICAgbGV0IGluRG91YmxlUXVvdGUgPSBmYWxzZTtcblxuICAgIGNvbnN0IHB1c2hUb2tlbiA9IChlbmRJbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdG9rZW4gPSBzb3VyY2Uuc2xpY2Uoc3RhcnQsIGVuZEluZGV4KS50cmltKCk7XG4gICAgICBpZiAodG9rZW4ubGVuZ3RoID4gMCkge1xuICAgICAgICB0b2tlbnMucHVzaCh0b2tlbik7XG4gICAgICB9XG4gICAgICBzdGFydCA9IC0xO1xuICAgIH07XG5cbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgc291cmNlLmxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgICAgY29uc3QgY2hhciA9IHNvdXJjZVtpbmRleF07XG4gICAgICBjb25zdCBuZXh0Q2hhciA9IHNvdXJjZVtpbmRleCArIDFdO1xuXG4gICAgICBpZiAoY2hhciA9PT0gXCInXCIgJiYgIWluRG91YmxlUXVvdGUpIHtcbiAgICAgICAgaWYgKHN0YXJ0IDwgMCkge1xuICAgICAgICAgIHN0YXJ0ID0gaW5kZXg7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGluU2luZ2xlUXVvdGUgJiYgbmV4dENoYXIgPT09IFwiJ1wiKSB7XG4gICAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpblNpbmdsZVF1b3RlID0gIWluU2luZ2xlUXVvdGU7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2hhciA9PT0gJ1wiJyAmJiAhaW5TaW5nbGVRdW90ZSkge1xuICAgICAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICAgICAgc3RhcnQgPSBpbmRleDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoaW5Eb3VibGVRdW90ZSAmJiBuZXh0Q2hhciA9PT0gJ1wiJykge1xuICAgICAgICAgIGluZGV4ICs9IDE7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaW5Eb3VibGVRdW90ZSA9ICFpbkRvdWJsZVF1b3RlO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpblNpbmdsZVF1b3RlICYmICFpbkRvdWJsZVF1b3RlKSB7XG4gICAgICAgIGlmIChjaGFyID09PSBcIihcIikge1xuICAgICAgICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgICAgICAgIHN0YXJ0ID0gaW5kZXg7XG4gICAgICAgICAgfVxuICAgICAgICAgIHBhcmVuRGVwdGggKz0gMTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2hhciA9PT0gXCIpXCIpIHtcbiAgICAgICAgICBwYXJlbkRlcHRoIC09IDE7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoYXIgPT09IFwiW1wiKSB7XG4gICAgICAgICAgaWYgKHN0YXJ0IDwgMCkge1xuICAgICAgICAgICAgc3RhcnQgPSBpbmRleDtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJhY2tldERlcHRoICs9IDE7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoYXIgPT09IFwiXVwiKSB7XG4gICAgICAgICAgYnJhY2tldERlcHRoIC09IDE7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoL1xccy8udGVzdChjaGFyKSAmJiBwYXJlbkRlcHRoID09PSAwICYmIGJyYWNrZXREZXB0aCA9PT0gMCkge1xuICAgICAgICAgIHB1c2hUb2tlbihpbmRleCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHN0YXJ0IDwgMCkge1xuICAgICAgICBzdGFydCA9IGluZGV4O1xuICAgICAgfVxuICAgIH1cblxuICAgIHB1c2hUb2tlbihzb3VyY2UubGVuZ3RoKTtcbiAgICByZXR1cm4gdG9rZW5zO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kTWF0Y2hpbmdQYXJlbnRoZXNpcyhzb3VyY2U6IHN0cmluZywgb3BlbkluZGV4OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGxldCBkZXB0aCA9IDA7XG4gICAgbGV0IGluU2luZ2xlUXVvdGUgPSBmYWxzZTtcbiAgICBsZXQgaW5Eb3VibGVRdW90ZSA9IGZhbHNlO1xuXG4gICAgZm9yIChsZXQgaW5kZXggPSBvcGVuSW5kZXg7IGluZGV4IDwgc291cmNlLmxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgICAgY29uc3QgY2hhciA9IHNvdXJjZVtpbmRleF07XG4gICAgICBjb25zdCBuZXh0Q2hhciA9IHNvdXJjZVtpbmRleCArIDFdO1xuXG4gICAgICBpZiAoY2hhciA9PT0gXCInXCIgJiYgIWluRG91YmxlUXVvdGUpIHtcbiAgICAgICAgaWYgKGluU2luZ2xlUXVvdGUgJiYgbmV4dENoYXIgPT09IFwiJ1wiKSB7XG4gICAgICAgICAgaW5kZXggKz0gMTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpblNpbmdsZVF1b3RlID0gIWluU2luZ2xlUXVvdGU7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2hhciA9PT0gJ1wiJyAmJiAhaW5TaW5nbGVRdW90ZSkge1xuICAgICAgICBpZiAoaW5Eb3VibGVRdW90ZSAmJiBuZXh0Q2hhciA9PT0gJ1wiJykge1xuICAgICAgICAgIGluZGV4ICs9IDE7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaW5Eb3VibGVRdW90ZSA9ICFpbkRvdWJsZVF1b3RlO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGluU2luZ2xlUXVvdGUgfHwgaW5Eb3VibGVRdW90ZSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNoYXIgPT09IFwiKFwiKSB7XG4gICAgICAgIGRlcHRoICs9IDE7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoY2hhciA9PT0gXCIpXCIpIHtcbiAgICAgICAgZGVwdGggLT0gMTtcbiAgICAgICAgaWYgKGRlcHRoID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgLyoqXG4gICAqIO2KueyglSDthYzsnbTruJTsnZggUEvrpbwg7LC47KGw7ZWY64qUIOuLpOuluCDthYzsnbTruJTsnZggRksg66qp66Gd7J2EIOyhsO2ajO2VqeuLiOuLpC5cbiAgICogUEsg7YOA7J6FIOuzgOqyvSDsi5wg6rSA66CoIEZLIOygnOyVveyhsOqxtOydhCDsgq3soJwv67O16rWs7ZWY6riwIOychO2VtCDsgqzsmqnrkKnri4jri6QuXG4gICAqL1xuICBhc3luYyBnZXRSZWZlcmVuY2luZ0ZvcmVpZ25LZXlzKGRiOiBLbmV4LCB0YWJsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8UmVmZXJlbmNpbmdGb3JlaWduS2V5W10+IHtcbiAgICBjb25zdCBxdWVyeSA9IGBcbiAgICAgIFNFTEVDVFxuICAgICAgICB0Yy50YWJsZV9uYW1lLFxuICAgICAgICB0Yy5jb25zdHJhaW50X25hbWUsXG4gICAgICAgIGtjdS5jb2x1bW5fbmFtZSxcbiAgICAgICAgY2N1LnRhYmxlX25hbWUgQVMgcmVmZXJlbmNlZF90YWJsZV9uYW1lLFxuICAgICAgICBjY3UuY29sdW1uX25hbWUgQVMgcmVmZXJlbmNlZF9jb2x1bW5fbmFtZSxcbiAgICAgICAgcmMudXBkYXRlX3J1bGUsXG4gICAgICAgIHJjLmRlbGV0ZV9ydWxlXG4gICAgICBGUk9NIGluZm9ybWF0aW9uX3NjaGVtYS50YWJsZV9jb25zdHJhaW50cyBBUyB0Y1xuICAgICAgSk9JTiBpbmZvcm1hdGlvbl9zY2hlbWEua2V5X2NvbHVtbl91c2FnZSBBUyBrY3VcbiAgICAgICAgT04gdGMuY29uc3RyYWludF9uYW1lID0ga2N1LmNvbnN0cmFpbnRfbmFtZVxuICAgICAgICBBTkQgdGMudGFibGVfc2NoZW1hID0ga2N1LnRhYmxlX3NjaGVtYVxuICAgICAgSk9JTiBpbmZvcm1hdGlvbl9zY2hlbWEuY29uc3RyYWludF9jb2x1bW5fdXNhZ2UgQVMgY2N1XG4gICAgICAgIE9OIGNjdS5jb25zdHJhaW50X25hbWUgPSB0Yy5jb25zdHJhaW50X25hbWVcbiAgICAgICAgQU5EIGNjdS50YWJsZV9zY2hlbWEgPSB0Yy50YWJsZV9zY2hlbWFcbiAgICAgIEpPSU4gaW5mb3JtYXRpb25fc2NoZW1hLnJlZmVyZW50aWFsX2NvbnN0cmFpbnRzIEFTIHJjXG4gICAgICAgIE9OIHJjLmNvbnN0cmFpbnRfbmFtZSA9IHRjLmNvbnN0cmFpbnRfbmFtZVxuICAgICAgICBBTkQgcmMuY29uc3RyYWludF9zY2hlbWEgPSB0Yy50YWJsZV9zY2hlbWFcbiAgICAgIFdIRVJFIHRjLmNvbnN0cmFpbnRfdHlwZSA9ICdGT1JFSUdOIEtFWSdcbiAgICAgICAgQU5EIGNjdS50YWJsZV9uYW1lID0gP1xuICAgICAgICBBTkQgdGMudGFibGVfc2NoZW1hID0gJ3B1YmxpYydcbiAgICBgO1xuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZGIucmF3KHF1ZXJ5LCBbdGFibGVOYW1lXSk7XG4gICAgcmV0dXJuIHJlc3VsdC5yb3dzLm1hcChcbiAgICAgIChyb3c6IHtcbiAgICAgICAgdGFibGVfbmFtZTogc3RyaW5nO1xuICAgICAgICBjb25zdHJhaW50X25hbWU6IHN0cmluZztcbiAgICAgICAgY29sdW1uX25hbWU6IHN0cmluZztcbiAgICAgICAgcmVmZXJlbmNlZF90YWJsZV9uYW1lOiBzdHJpbmc7XG4gICAgICAgIHJlZmVyZW5jZWRfY29sdW1uX25hbWU6IHN0cmluZztcbiAgICAgICAgdXBkYXRlX3J1bGU6IHN0cmluZztcbiAgICAgICAgZGVsZXRlX3J1bGU6IHN0cmluZztcbiAgICAgIH0pID0+ICh7XG4gICAgICAgIHRhYmxlTmFtZTogcm93LnRhYmxlX25hbWUsXG4gICAgICAgIGNvbnN0cmFpbnROYW1lOiByb3cuY29uc3RyYWludF9uYW1lLFxuICAgICAgICBjb2x1bW5OYW1lOiByb3cuY29sdW1uX25hbWUsXG4gICAgICAgIHJlZmVyZW5jZWRUYWJsZU5hbWU6IHJvdy5yZWZlcmVuY2VkX3RhYmxlX25hbWUsXG4gICAgICAgIHJlZmVyZW5jZWRDb2x1bW5OYW1lOiByb3cucmVmZXJlbmNlZF9jb2x1bW5fbmFtZSxcbiAgICAgICAgb25VcGRhdGU6IHRoaXMubWFwQ29uc3RyYWludEFjdGlvbihyb3cudXBkYXRlX3J1bGUpLFxuICAgICAgICBvbkRlbGV0ZTogdGhpcy5tYXBDb25zdHJhaW50QWN0aW9uKHJvdy5kZWxldGVfcnVsZSksXG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIHZlY3RvciDsu6zrn7zsnZggZGltZW5zaW9uc+ulvCDsobDtmoztlanri4jri6QuXG4gICAqIHBnX2F0dHJpYnV0ZeydmCBhdHR0eXBtb2Tsl5DshJwg7LCo7JuQIOyImOulvCDstpTstpztlanri4jri6QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGdldFZlY3RvckRpbWVuc2lvbnMoXG4gICAgY29tcGFyZURCOiBSYXdDYXBhYmxlS25leCxcbiAgICB0YWJsZU5hbWU6IHN0cmluZyxcbiAgKTogUHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBudW1iZXI+PiB7XG4gICAgY29uc3QgcXVlcnkgPSBgXG4gICAgICBTRUxFQ1RcbiAgICAgICAgYS5hdHRuYW1lIGFzIGNvbHVtbl9uYW1lLFxuICAgICAgICBhLmF0dHR5cG1vZCBhcyBkaW1lbnNpb25zXG4gICAgICBGUk9NIHBnX2F0dHJpYnV0ZSBhXG4gICAgICBKT0lOIHBnX2NsYXNzIGMgT04gYS5hdHRyZWxpZCA9IGMub2lkXG4gICAgICBKT0lOIHBnX3R5cGUgdCBPTiBhLmF0dHR5cGlkID0gdC5vaWRcbiAgICAgIFdIRVJFIGMucmVsbmFtZSA9ID9cbiAgICAgICAgQU5EIHQudHlwbmFtZSA9ICd2ZWN0b3InXG4gICAgICAgIEFORCBhLmF0dG51bSA+IDBcbiAgICBgO1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGNvbXBhcmVEQi5yYXcocXVlcnksIFt0YWJsZU5hbWVdKTtcbiAgICBjb25zdCBkaW1lbnNpb25zOiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+ID0ge307XG4gICAgZm9yIChjb25zdCByb3cgb2YgcmVzdWx0LnJvd3MpIHtcbiAgICAgIC8vIGF0dHR5cG1vZOyXkOyEnCDsi6TsoJwgZGltZW5zaW9ucyDqsJIg7LaU7LacXG4gICAgICBkaW1lbnNpb25zW3Jvdy5jb2x1bW5fbmFtZV0gPSByb3cuZGltZW5zaW9ucyA+IDAgPyByb3cuZGltZW5zaW9ucyA6IDA7XG4gICAgfVxuICAgIHJldHVybiBkaW1lbnNpb25zO1xuICB9XG5cbiAgLyoqXG4gICAqIFBvc3RncmVTUUwg7Lus65+8IO2DgOyeheydhCDrtoTshJ3tlZjsl6wgTWlncmF0aW9uQ29sdW1uIOqwneyytOuhnCDrs4DtmZjtlanri4jri6QuXG4gICAqL1xuICByZXNvbHZlREJDb2xUeXBlKFxuICAgIGRiQ29sdW1uOiBQZ0NvbHVtbixcbiAgKTogUGljazxcbiAgICBNaWdyYXRpb25Db2x1bW4sXG4gICAgXCJ0eXBlXCIgfCBcImxlbmd0aFwiIHwgXCJwcmVjaXNpb25cIiB8IFwic2NhbGVcIiB8IFwibnVtYmVyVHlwZVwiIHwgXCJkaW1lbnNpb25zXCJcbiAgPiB7XG4gICAgY29uc3QgeyB1ZHRfbmFtZTogX3VkdF9uYW1lLCBjaGFyYWN0ZXJfbWF4aW11bV9sZW5ndGgsIHByZWNpc2lvbiwgbnVtZXJpY19zY2FsZSB9ID0gZGJDb2x1bW47XG5cbiAgICBjb25zdCB7IHVkdF9uYW1lLCBzaW5nbGVPckFycmF5IH0gPSAoKCkgPT4ge1xuICAgICAgaWYgKF91ZHRfbmFtZS5zdGFydHNXaXRoKFwiX1wiKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHVkdF9uYW1lOiBfdWR0X25hbWUuc3Vic3RyaW5nKDEpLFxuICAgICAgICAgIHNpbmdsZU9yQXJyYXk6IFwiW11cIiBhcyBjb25zdCxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIHVkdF9uYW1lOiBfdWR0X25hbWUsXG4gICAgICAgIHNpbmdsZU9yQXJyYXk6IFwiXCIgYXMgY29uc3QsXG4gICAgICB9O1xuICAgIH0pKCk7XG5cbiAgICAvLyBVVUlEXG4gICAgaWYgKHVkdF9uYW1lID09PSBcInV1aWRcIikge1xuICAgICAgcmV0dXJuIHsgdHlwZTogYHV1aWQke3NpbmdsZU9yQXJyYXl9YCB9O1xuICAgIH1cblxuICAgIC8vIEludGVnZXIgdHlwZXNcbiAgICBpZiAodWR0X25hbWUgPT09IFwiaW50NFwiKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiBgaW50ZWdlciR7c2luZ2xlT3JBcnJheX1gIH07XG4gICAgfVxuICAgIGlmICh1ZHRfbmFtZSA9PT0gXCJpbnQ4XCIpIHtcbiAgICAgIHJldHVybiB7IHR5cGU6IGBiaWdJbnRlZ2VyJHtzaW5nbGVPckFycmF5fWAgfTtcbiAgICB9XG5cbiAgICAvLyBTdHJpbmcgdHlwZXNcbiAgICBpZiAodWR0X25hbWUgPT09IFwidmFyY2hhclwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBgc3RyaW5nJHtzaW5nbGVPckFycmF5fWAsXG4gICAgICAgIC4uLihjaGFyYWN0ZXJfbWF4aW11bV9sZW5ndGggJiYge1xuICAgICAgICAgIGxlbmd0aDogY2hhcmFjdGVyX21heGltdW1fbGVuZ3RoLFxuICAgICAgICB9KSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmICh1ZHRfbmFtZSA9PT0gXCJ0ZXh0XCIpIHtcbiAgICAgIHJldHVybiB7IHR5cGU6IGBzdHJpbmcke3NpbmdsZU9yQXJyYXl9YCB9OyAvLyBTdHJpbmdQcm9wIHdpdGhvdXQgbGVuZ3RoXG4gICAgfVxuXG4gICAgLy8gTnVtYmVyT3JOdW1lcmljIHR5cGVzXG4gICAgaWYgKHVkdF9uYW1lID09PSBcIm51bWVyaWNcIikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogYG51bWJlck9yTnVtZXJpYyR7c2luZ2xlT3JBcnJheX1gLFxuICAgICAgICBudW1iZXJUeXBlOiBcIm51bWVyaWNcIixcbiAgICAgICAgLi4uKHByZWNpc2lvbiAhPT0gbnVsbCAmJlxuICAgICAgICAgIG51bWVyaWNfc2NhbGUgIT09IG51bGwgJiYge1xuICAgICAgICAgICAgcHJlY2lzaW9uOiBwcmVjaXNpb24sXG4gICAgICAgICAgICBzY2FsZTogbnVtZXJpY19zY2FsZSxcbiAgICAgICAgICB9KSxcbiAgICAgIH07XG4gICAgfVxuICAgIGlmICh1ZHRfbmFtZSA9PT0gXCJmbG9hdDRcIikge1xuICAgICAgcmV0dXJuIHsgdHlwZTogYG51bWJlck9yTnVtZXJpYyR7c2luZ2xlT3JBcnJheX1gLCBudW1iZXJUeXBlOiBcInJlYWxcIiB9O1xuICAgIH1cbiAgICBpZiAodWR0X25hbWUgPT09IFwiZmxvYXQ4XCIpIHtcbiAgICAgIHJldHVybiB7IHR5cGU6IGBudW1iZXJPck51bWVyaWMke3NpbmdsZU9yQXJyYXl9YCwgbnVtYmVyVHlwZTogXCJkb3VibGUgcHJlY2lzaW9uXCIgfTtcbiAgICB9XG5cbiAgICAvLyBCb29sZWFuXG4gICAgaWYgKHVkdF9uYW1lID09PSBcImJvb2xcIikge1xuICAgICAgcmV0dXJuIHsgdHlwZTogYGJvb2xlYW4ke3NpbmdsZU9yQXJyYXl9YCB9O1xuICAgIH1cblxuICAgIC8vIFRpbWVzdGFtcHogdHlwZXNcbiAgICBpZiAodWR0X25hbWUgPT09IFwidGltZXN0YW1wdHpcIikge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogYGRhdGUke3NpbmdsZU9yQXJyYXl9YCxcbiAgICAgICAgLi4uKHByZWNpc2lvbiAhPT0gbnVsbCAmJiB7XG4gICAgICAgICAgcHJlY2lzaW9uOiBwcmVjaXNpb24sXG4gICAgICAgIH0pLFxuICAgICAgfTsgLy8gRGF0ZVByb3Ag4oaSIHRpbWVzdGFtcHR6XG4gICAgfVxuXG4gICAgLy8gSlNPTlxuICAgIGlmICh1ZHRfbmFtZSA9PT0gXCJqc29uXCIgfHwgdWR0X25hbWUgPT09IFwianNvbmJcIikge1xuICAgICAgcmV0dXJuIHsgdHlwZTogXCJqc29uXCIgfTtcbiAgICB9XG5cbiAgICAvLyBWZWN0b3IgKHBndmVjdG9yKVxuICAgIGlmICh1ZHRfbmFtZSA9PT0gXCJ2ZWN0b3JcIikge1xuICAgICAgLy8gdmVjdG9yIO2DgOyeheydmCDssKjsm5Ag7IiY64qUIGNvbHVtbl9kZWZhdWx064KYIOuzhOuPhCDsv7zrpqzroZwg7ZmV7J247ZW07JW8IO2VqFxuICAgICAgLy8g7ZiE7J6s64qUIOq4sOuzuOqwkiAw7Jy866GcIOyEpOyglSAo7Iuk7KCcIGRpbWVuc2lvbnPripQgZ2V0TWlncmF0aW9uU2V0RnJvbURC7JeQ7IScIOuzhOuPhCDsv7zrpqzroZwg7ZmV7J24KVxuICAgICAgcmV0dXJuIHsgdHlwZTogYHZlY3RvciR7c2luZ2xlT3JBcnJheX1gLCBkaW1lbnNpb25zOiAwIH07XG4gICAgfVxuXG4gICAgLy8gdHN2ZWN0b3IgKFBvc3RncmVTUUwg7KCE66y4IOqygOyDieyaqSDtg4DsnoUpXG4gICAgaWYgKHVkdF9uYW1lID09PSBcInRzdmVjdG9yXCIpIHtcbiAgICAgIHJldHVybiB7IHR5cGU6IFwidHN2ZWN0b3JcIiB9O1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihgcmVzb2x2ZSDrtojqsIDriqXtlZwgUG9zdGdyZVNRTCDsu6zrn7wg7YOA7J6FOiAke3VkdF9uYW1lfWApO1xuICB9XG59XG5cbmV4cG9ydCBjb25zdCBQb3N0Z3JlU1FMU2NoZW1hUmVhZGVyID0gbmV3IFBvc3RncmVTUUxTY2hlbWFSZWFkZXJDbGFzcygpO1xuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Q0F3RU0sOEJBQU4sTUFBa0M7RUFDaEMsb0NBQXFDLElBQUksSUFBSTtHQUFDO0dBQVM7R0FBUTtHQUFPO0dBQVE7RUFBVSxDQUFDOzs7Ozs7O0VBUXpGLE1BQU0sc0JBQ0osV0FDQSxPQUM4QjtHQUM5QixJQUFJLFdBQXVC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
|