sonamu 0.7.3 → 0.7.5
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/api/config.d.ts +1 -4
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +1 -1
- package/dist/api/sonamu.d.ts +2 -0
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +19 -47
- package/dist/bin/cli.js +6 -6
- package/dist/database/base-model.d.ts +1 -1
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.js +15 -4
- package/dist/database/code-generator.d.ts.map +1 -1
- package/dist/database/code-generator.js +3 -3
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +1 -1
- package/dist/database/puri-wrapper.d.ts +11 -11
- package/dist/database/puri-wrapper.d.ts.map +1 -1
- package/dist/database/puri-wrapper.js +7 -11
- package/dist/database/puri.d.ts +36 -17
- package/dist/database/puri.d.ts.map +1 -1
- package/dist/database/puri.js +54 -7
- package/dist/database/puri.types.d.ts +54 -17
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/puri.types.js +2 -4
- package/dist/database/puri.types.test-d.js +129 -0
- package/dist/database/upsert-builder.d.ts +16 -10
- package/dist/database/upsert-builder.d.ts.map +1 -1
- package/dist/database/upsert-builder.js +10 -19
- package/dist/entity/entity-manager.d.ts +113 -22
- package/dist/entity/entity-manager.d.ts.map +1 -1
- package/dist/entity/entity-manager.js +1 -1
- package/dist/entity/entity.d.ts +34 -0
- package/dist/entity/entity.d.ts.map +1 -1
- package/dist/entity/entity.js +110 -37
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/migration/code-generation.d.ts.map +1 -1
- package/dist/migration/code-generation.js +341 -149
- package/dist/migration/migration-set.d.ts.map +1 -1
- package/dist/migration/migration-set.js +21 -5
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +7 -1
- package/dist/migration/postgresql-schema-reader.d.ts +11 -1
- package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
- package/dist/migration/postgresql-schema-reader.js +111 -10
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +5 -4
- package/dist/template/implementations/generated.template.d.ts.map +1 -1
- package/dist/template/implementations/generated.template.js +12 -2
- package/dist/template/implementations/generated_sso.template.d.ts +3 -3
- package/dist/template/implementations/generated_sso.template.d.ts.map +1 -1
- package/dist/template/implementations/generated_sso.template.js +50 -2
- package/dist/template/implementations/model.template.js +6 -6
- package/dist/template/implementations/model_test.template.js +4 -4
- package/dist/template/implementations/view_enums_dropdown.template.js +2 -2
- package/dist/template/implementations/view_enums_select.template.js +2 -2
- package/dist/template/implementations/view_form.template.d.ts.map +1 -1
- package/dist/template/implementations/view_form.template.js +12 -9
- package/dist/template/implementations/view_id_async_select.template.js +4 -4
- package/dist/template/implementations/view_list.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list.template.js +12 -9
- package/dist/template/implementations/view_search_input.template.js +2 -2
- package/dist/template/template.js +2 -2
- package/dist/template/zod-converter.d.ts.map +1 -1
- package/dist/template/zod-converter.js +17 -2
- package/dist/testing/fixture-manager.d.ts +2 -1
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +29 -29
- package/dist/types/types.d.ts +593 -68
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +113 -9
- package/dist/vector/chunking.d.ts +25 -0
- package/dist/vector/chunking.d.ts.map +1 -0
- package/dist/vector/chunking.js +97 -0
- package/dist/vector/config.d.ts +12 -0
- package/dist/vector/config.d.ts.map +1 -0
- package/dist/vector/config.js +83 -0
- package/dist/vector/embedding.d.ts +42 -0
- package/dist/vector/embedding.d.ts.map +1 -0
- package/dist/vector/embedding.js +147 -0
- package/dist/vector/types.d.ts +105 -0
- package/dist/vector/types.d.ts.map +1 -0
- package/dist/vector/types.js +5 -0
- package/dist/vector/vector-search.d.ts +47 -0
- package/dist/vector/vector-search.d.ts.map +1 -0
- package/dist/vector/vector-search.js +176 -0
- package/package.json +11 -11
- package/src/api/config.ts +0 -4
- package/src/api/sonamu.ts +21 -36
- package/src/bin/cli.ts +5 -5
- package/src/database/base-model.ts +20 -11
- package/src/database/code-generator.ts +6 -2
- package/src/database/db.ts +1 -0
- package/src/database/puri-wrapper.ts +22 -16
- package/src/database/puri.ts +150 -27
- package/src/database/puri.types.test-d.ts +457 -0
- package/src/database/puri.types.ts +231 -33
- package/src/database/upsert-builder.ts +43 -34
- package/src/entity/entity-manager.ts +2 -2
- package/src/entity/entity.ts +134 -44
- package/src/index.ts +6 -0
- package/src/migration/code-generation.ts +377 -174
- package/src/migration/migration-set.ts +22 -3
- package/src/migration/migrator.ts +6 -0
- package/src/migration/postgresql-schema-reader.ts +121 -21
- package/src/syncer/syncer.ts +4 -3
- package/src/template/implementations/generated.template.ts +51 -9
- package/src/template/implementations/generated_sso.template.ts +71 -2
- package/src/template/implementations/model.template.ts +5 -5
- package/src/template/implementations/model_test.template.ts +3 -3
- package/src/template/implementations/view_enums_dropdown.template.ts +1 -1
- package/src/template/implementations/view_enums_select.template.ts +1 -1
- package/src/template/implementations/view_form.template.ts +11 -8
- package/src/template/implementations/view_id_async_select.template.ts +3 -3
- package/src/template/implementations/view_list.template.ts +11 -8
- package/src/template/implementations/view_search_input.template.ts +1 -1
- package/src/template/template.ts +1 -1
- package/src/template/zod-converter.ts +20 -0
- package/src/testing/fixture-manager.ts +31 -30
- package/src/types/types.ts +226 -48
- package/src/vector/chunking.ts +115 -0
- package/src/vector/config.ts +68 -0
- package/src/vector/embedding.ts +193 -0
- package/src/vector/types.ts +122 -0
- package/src/vector/vector-search.ts +261 -0
- package/dist/template/implementations/view_enums_buttonset.template.d.ts +0 -17
- package/dist/template/implementations/view_enums_buttonset.template.d.ts.map +0 -1
- package/dist/template/implementations/view_enums_buttonset.template.js +0 -31
- package/dist/template/implementations/view_list_columns.template.d.ts +0 -17
- package/dist/template/implementations/view_list_columns.template.d.ts.map +0 -1
- package/dist/template/implementations/view_list_columns.template.js +0 -49
- package/src/template/implementations/view_enums_buttonset.template.ts +0 -34
- package/src/template/implementations/view_list_columns.template.ts +0 -53
|
@@ -1,27 +1,24 @@
|
|
|
1
1
|
import equal from "fast-deep-equal";
|
|
2
|
-
import { alphabetical, diff,
|
|
2
|
+
import { alphabetical, diff, omit } from "radashi";
|
|
3
3
|
import { Naite } from "../index.js";
|
|
4
4
|
import { formatCode } from "../utils/formatter.js";
|
|
5
5
|
import { differenceWith, intersectionBy } from "../utils/utils.js";
|
|
6
6
|
/**
|
|
7
7
|
* 테이블 생성하는 케이스 - 컬럼/인덱스 생성
|
|
8
8
|
*/ async function generateCreateCode_ColumnAndIndexes(table, columns, indexes) {
|
|
9
|
-
|
|
10
|
-
const [ngramIndexes, standardIndexes] = fork(indexes, (i)=>i.type === "fulltext" && i.parser === "ngram");
|
|
9
|
+
const columnDefs = genColumnDefinitions(table, columns);
|
|
11
10
|
// 컬럼, 인덱스 처리
|
|
12
11
|
const lines = [
|
|
13
12
|
'import { Knex } from "knex";',
|
|
14
13
|
"",
|
|
15
14
|
"export async function up(knex: Knex): Promise<void> {",
|
|
16
15
|
`await knex.schema.createTable("${table}", (table) => {`,
|
|
17
|
-
|
|
18
|
-
...genColumnDefinitions(columns),
|
|
19
|
-
"",
|
|
20
|
-
"// indexes",
|
|
21
|
-
...standardIndexes.map((index)=>genIndexDefinition(index, table)),
|
|
16
|
+
...columnDefs.builder,
|
|
22
17
|
"});",
|
|
23
|
-
//
|
|
24
|
-
...
|
|
18
|
+
// raw 구문 (Generated Column 등)
|
|
19
|
+
...columnDefs.raw,
|
|
20
|
+
// index는 knex.raw로 처리하므로 createTable 밖에서 실행
|
|
21
|
+
...indexes.map((index)=>genIndexDefinition(index, table)),
|
|
25
22
|
"}",
|
|
26
23
|
"",
|
|
27
24
|
"export async function down(knex: Knex): Promise<void> {",
|
|
@@ -37,56 +34,113 @@ import { differenceWith, intersectionBy } from "../utils/utils.js";
|
|
|
37
34
|
}
|
|
38
35
|
/**
|
|
39
36
|
* MigrationColumn[] 읽어서 컬럼 정의하는 구문 생성
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
37
|
+
* @returns builder: table builder 메서드, raw: knex.raw() 구문
|
|
38
|
+
*/ function genColumnDefinitions(table, columns) {
|
|
39
|
+
const result = {
|
|
40
|
+
builder: [],
|
|
41
|
+
raw: []
|
|
42
|
+
};
|
|
43
|
+
for (const column of columns){
|
|
44
|
+
// Generated Column은 raw로 처리
|
|
45
|
+
if (column.generated) {
|
|
46
|
+
result.raw.push(genGeneratedColumnDefinition(table, column));
|
|
47
|
+
continue;
|
|
45
48
|
}
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
49
|
+
// 일반 컬럼은 builder로 처리
|
|
50
|
+
result.builder.push(genNormalColumnDefinition(column));
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Generated Column 정의 생성 (ALTER TABLE ADD COLUMN 사용)
|
|
56
|
+
*/ function genGeneratedColumnDefinition(table, column) {
|
|
57
|
+
if (!column.generated) {
|
|
58
|
+
throw new Error("Generated column definition required");
|
|
59
|
+
}
|
|
60
|
+
const pgType = getPgTypeForColumn(column);
|
|
61
|
+
const storageType = column.generated.type === "VIRTUAL" ? " VIRTUAL" : " STORED";
|
|
62
|
+
const nullableClause = column.nullable ? "" : " NOT NULL";
|
|
63
|
+
return `await knex.raw(\`ALTER TABLE "${table}" ADD COLUMN "${column.name}" ${pgType} GENERATED ALWAYS AS (${column.generated.expression})${storageType}${nullableClause}\`);`;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* 일반 컬럼 정의 생성 (table.xxx() 체인)
|
|
67
|
+
*/ function genNormalColumnDefinition(column) {
|
|
68
|
+
const chains = [];
|
|
69
|
+
if (column.name === "id") {
|
|
70
|
+
return `table.increments().primary();`;
|
|
71
|
+
}
|
|
72
|
+
// 배열 타입 처리
|
|
73
|
+
if (column.type.endsWith("[]")) {
|
|
74
|
+
const elementType = column.type.slice(0, -2); // "integer[]" -> "integer"
|
|
75
|
+
const pgType = getPgArrayType(column, elementType);
|
|
76
|
+
chains.push(`specificType('${column.name}', '${pgType}')`);
|
|
77
|
+
} else if (column.type === "vector") {
|
|
78
|
+
// Knex는 vector 타입을 직접 지원하지 않으므로 specificType 사용
|
|
79
|
+
chains.push(`specificType('${column.name}', 'vector(${column.dimensions})')`);
|
|
80
|
+
} else if (column.type === "numberOrNumeric") {
|
|
81
|
+
// number
|
|
82
|
+
if (column.numberType === "real") {
|
|
83
|
+
chains.push(`float('${column.name}')`);
|
|
84
|
+
} else if (column.numberType === "double precision") {
|
|
85
|
+
chains.push(`double('${column.name}')`);
|
|
86
|
+
} else if ((column.numberType ?? "numeric") === "numeric") {
|
|
87
|
+
chains.push(`decimal('${column.name}', ${column.precision}, ${column.scale})`);
|
|
88
|
+
}
|
|
89
|
+
} else if (column.type === "string") {
|
|
90
|
+
// string
|
|
91
|
+
if (column.length !== undefined) {
|
|
92
|
+
chains.push(`string('${column.name}', ${column.length})`);
|
|
73
93
|
} else {
|
|
74
|
-
|
|
75
|
-
let extraType;
|
|
76
|
-
chains.push(`${column.type}('${column.name}'${column.length ? `, ${column.length}` : ""}${extraType ? `, '${extraType}'` : ""})`);
|
|
94
|
+
chains.push(`text('${column.name}')`);
|
|
77
95
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
96
|
+
} else if (column.type === "date") {
|
|
97
|
+
// date
|
|
98
|
+
chains.push(`timestamp('${column.name}', { useTz: true })`);
|
|
99
|
+
} else if (column.type === "json") {
|
|
100
|
+
// json
|
|
101
|
+
chains.push(`jsonb('${column.name}')`);
|
|
102
|
+
} else {
|
|
103
|
+
// type, length
|
|
104
|
+
let extraType;
|
|
105
|
+
chains.push(`${column.type}('${column.name}'${column.length ? `, ${column.length}` : ""}${extraType ? `, '${extraType}'` : ""})`);
|
|
106
|
+
}
|
|
107
|
+
// nullable
|
|
108
|
+
chains.push(column.nullable ? "nullable()" : "notNullable()");
|
|
109
|
+
// defaultTo
|
|
110
|
+
if (column.defaultTo !== undefined) {
|
|
111
|
+
if (typeof column.defaultTo === "string" && column.defaultTo.startsWith(`"`)) {
|
|
112
|
+
chains.push(`defaultTo(${column.defaultTo})`);
|
|
113
|
+
} else {
|
|
114
|
+
chains.push(`defaultTo(knex.raw('${column.defaultTo}'))`);
|
|
87
115
|
}
|
|
88
|
-
|
|
89
|
-
}
|
|
116
|
+
}
|
|
117
|
+
return `table.${chains.join(".")};`;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* MigrationColumn의 타입을 PostgreSQL 타입 문자열로 변환
|
|
121
|
+
*/ function getPgTypeForColumn(column) {
|
|
122
|
+
if (column.type.endsWith("[]")) {
|
|
123
|
+
const elementType = column.type.slice(0, -2);
|
|
124
|
+
return getPgArrayType(column, elementType);
|
|
125
|
+
}
|
|
126
|
+
switch(column.type){
|
|
127
|
+
case "string":
|
|
128
|
+
return column.length !== undefined ? `varchar(${column.length})` : "text";
|
|
129
|
+
case "bigInteger":
|
|
130
|
+
return "bigint";
|
|
131
|
+
case "numberOrNumeric":
|
|
132
|
+
if (column.numberType === "real") return "real";
|
|
133
|
+
if (column.numberType === "double precision") return "double precision";
|
|
134
|
+
return `numeric(${column.precision}, ${column.scale})`;
|
|
135
|
+
case "date":
|
|
136
|
+
return "timestamptz";
|
|
137
|
+
case "json":
|
|
138
|
+
return "jsonb";
|
|
139
|
+
case "vector":
|
|
140
|
+
return `vector(${column.dimensions})`;
|
|
141
|
+
default:
|
|
142
|
+
return column.type;
|
|
143
|
+
}
|
|
90
144
|
}
|
|
91
145
|
function getPgArrayType(column, elementType) {
|
|
92
146
|
if (elementType === "numberOrNumeric") {
|
|
@@ -103,22 +157,56 @@ function getPgArrayType(column, elementType) {
|
|
|
103
157
|
if (elementType === "boolean") return "boolean[]";
|
|
104
158
|
if (elementType === "uuid") return "uuid[]";
|
|
105
159
|
if (elementType === "enum") return "text[]";
|
|
160
|
+
if (elementType === "vector") return `vector(${column.dimensions})[]`;
|
|
106
161
|
throw new Error(`Unknown array element type: ${elementType}`);
|
|
107
162
|
}
|
|
108
163
|
/**
|
|
109
164
|
* 개별 인덱스 정의 생성
|
|
110
165
|
*/ function genIndexDefinition(index, table) {
|
|
166
|
+
if (index.type === "hnsw" || index.type === "ivfflat") {
|
|
167
|
+
return genVectorIndexDefinition(index, table);
|
|
168
|
+
}
|
|
111
169
|
const methodMap = {
|
|
112
|
-
index: "
|
|
113
|
-
fulltext: "
|
|
114
|
-
unique: "
|
|
170
|
+
index: "INDEX",
|
|
171
|
+
fulltext: "INDEX",
|
|
172
|
+
unique: "UNIQUE INDEX"
|
|
115
173
|
};
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
174
|
+
const nullsNotDistinctClause = index.nullsNotDistinct === undefined ? "" : ` NULLS ${index.nullsNotDistinct ? "NOT DISTINCT" : "DISTINCT"}`;
|
|
175
|
+
return `await knex.raw(
|
|
176
|
+
\`CREATE ${methodMap[index.type]} ${index.name} ON ${table} (${index.columns.map((col)=>{
|
|
177
|
+
const sortOrderClause = col.sortOrder === undefined ? "" : ` ${col.sortOrder}`;
|
|
178
|
+
const nullsFirstClause = col.nullsFirst === undefined ? "" : ` NULLS ${col.nullsFirst ? "FIRST" : "LAST"}`;
|
|
179
|
+
return `${col.name}${sortOrderClause}${nullsFirstClause}`;
|
|
180
|
+
}).join(", ")})${nullsNotDistinctClause};\`
|
|
120
181
|
);`;
|
|
121
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* @description
|
|
185
|
+
* - HNSW (Hierarchical Navigable Small World): 느린 빌드, 빠른 검색 속도, 높은 메모리 및 정확도
|
|
186
|
+
* - IVFFlat (Inverted File with Flat Compression): 빠른 빌드, 중간 검색 속도, 낮은 메모리
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* // HNSW 인덱스 (권장 - 빠른 검색, 높은 정확도)
|
|
190
|
+
* CREATE INDEX idx_embedding ON items USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);
|
|
191
|
+
*
|
|
192
|
+
* // IVFFlat 인덱스 (대용량 데이터, 비용 중요 시)
|
|
193
|
+
* CREATE INDEX idx_embedding ON items USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
|
|
194
|
+
*/ function genVectorIndexDefinition(index, table) {
|
|
195
|
+
const column = index.columns[0];
|
|
196
|
+
const vectorOps = column.vectorOps ?? "vector_cosine_ops";
|
|
197
|
+
// HNSW (Hierarchical Navigable Small World) - 권장: 빠른 검색, 높은 정확도
|
|
198
|
+
if (index.type === "hnsw") {
|
|
199
|
+
const m = index.m ?? 16;
|
|
200
|
+
const efConstruction = index.efConstruction ?? 64;
|
|
201
|
+
return `await knex.raw(\`CREATE INDEX ${index.name} ON ${table} USING hnsw (${column.name} ${vectorOps}) WITH (m = ${m}, ef_construction = ${efConstruction})\`);`;
|
|
202
|
+
}
|
|
203
|
+
// IVFFlat (Inverted File with Flat Compression) - 대용량, 비용 중요 시
|
|
204
|
+
if (index.type === "ivfflat") {
|
|
205
|
+
const lists = index.lists ?? 100;
|
|
206
|
+
return `await knex.raw(\`CREATE INDEX ${index.name} ON ${table} USING ivfflat (${column.name} ${vectorOps}) WITH (lists = ${lists})\`);`;
|
|
207
|
+
}
|
|
208
|
+
throw new Error(`Unknown raw SQL index type: ${index.type}`);
|
|
209
|
+
}
|
|
122
210
|
/**
|
|
123
211
|
* 테이블 생성하는 케이스 - FK 생성
|
|
124
212
|
*/ async function generateCreateCode_Foreign(table, foreigns) {
|
|
@@ -192,12 +280,11 @@ function getPgArrayType(column, elementType) {
|
|
|
192
280
|
const alterColumnLinesTo = getAlterColumnLinesTo(alterColumnsTo, entityColumns, table, dbForeigns);
|
|
193
281
|
// 인덱스의 add, drop 여부 확인
|
|
194
282
|
const alterIndexesTo = getAlterIndexesTo(entityIndexes, dbIndexes);
|
|
195
|
-
// fulltext index 분리
|
|
196
|
-
const [ngramIndexes, standardIndexes] = fork(alterIndexesTo.add, (i)=>i.type === "fulltext" && i.parser === "ngram");
|
|
197
283
|
// 인덱스가 삭제되는 경우, 컬럼과 같이 삭제된 케이스에는 drop에서 제외해야함!
|
|
198
|
-
const indexNeedsToDrop = alterIndexesTo.drop.filter((index)=>index.columns.every((
|
|
284
|
+
const indexNeedsToDrop = alterIndexesTo.drop.filter((index)=>index.columns.every(({ name })=>alterColumnsTo.drop.map((col)=>col.name).includes(name)) === false);
|
|
199
285
|
// 빈 코드 생성 방지
|
|
200
|
-
|
|
286
|
+
const hasUpChanges = alterColumnLinesTo.add.up.builder.length > 0 || alterColumnLinesTo.add.up.raw.length > 0 || alterColumnLinesTo.drop.up.builder.length > 0 || alterColumnLinesTo.alter.up.builder.length > 0 || alterIndexesTo.add.length > 0 || indexNeedsToDrop.length > 0;
|
|
287
|
+
if (!hasUpChanges) {
|
|
201
288
|
Naite.t("migrator:generateAlterCode_ColumnAndIndexes:emptyCodeGenerationError", {
|
|
202
289
|
entityColumns,
|
|
203
290
|
dbColumns,
|
|
@@ -212,39 +299,52 @@ function getPgArrayType(column, elementType) {
|
|
|
212
299
|
"alterColumnsTo.alter.length": alterColumnsTo.alter.length,
|
|
213
300
|
"alterIndexesTo.add.length": alterIndexesTo.add.length,
|
|
214
301
|
"alterIndexesTo.drop.length": alterIndexesTo.drop.length,
|
|
215
|
-
"standardIndexes.length": standardIndexes.length,
|
|
216
302
|
"indexNeedsToDrop.length": indexNeedsToDrop.length
|
|
217
303
|
});
|
|
218
304
|
// Naite.t("migrator:generateAlterCode_ColumnAndIndexes:alterColumnsTo", alterColumnsTo);
|
|
219
305
|
// TODO: 인덱스명 변경된 경우 처리
|
|
306
|
+
// table builder 메서드로 실행할 코드 (drop → add → alter 순서)
|
|
307
|
+
const upBuilderLines = [
|
|
308
|
+
...alterColumnLinesTo.drop.up.builder.length > 0 ? alterColumnLinesTo.drop.up.builder : [],
|
|
309
|
+
...alterColumnLinesTo.add.up.builder.length > 0 ? alterColumnLinesTo.add.up.builder : [],
|
|
310
|
+
...alterColumnLinesTo.alter.up.builder.length > 0 ? alterColumnLinesTo.alter.up.builder : [],
|
|
311
|
+
...indexNeedsToDrop.map(genIndexDropDefinition)
|
|
312
|
+
];
|
|
313
|
+
// knex.raw()로 실행할 코드
|
|
314
|
+
const upRawLines = [
|
|
315
|
+
...alterColumnLinesTo.add.up.raw.length > 0 ? alterColumnLinesTo.add.up.raw : [],
|
|
316
|
+
...alterIndexesTo.add.map((index)=>genIndexDefinition(index, table))
|
|
317
|
+
];
|
|
318
|
+
// down은 up의 역순 (add.down = drop rollback, drop.down = add rollback)
|
|
319
|
+
const downBuilderLines = [
|
|
320
|
+
...alterColumnLinesTo.add.down.builder.length > 0 ? alterColumnLinesTo.add.down.builder : [],
|
|
321
|
+
...alterColumnLinesTo.alter.down.builder.length > 0 ? alterColumnLinesTo.alter.down.builder : [],
|
|
322
|
+
...alterColumnLinesTo.drop.down.builder.length > 0 ? alterColumnLinesTo.drop.down.builder : [],
|
|
323
|
+
...alterIndexesTo.add.filter((index)=>index.columns.every((indexCol)=>alterColumnsTo.add.map((col)=>col.name).includes(indexCol.name)) === false).map(genIndexDropDefinition)
|
|
324
|
+
];
|
|
325
|
+
const downRawLines = [
|
|
326
|
+
...alterColumnLinesTo.drop.down.raw.length > 0 ? alterColumnLinesTo.drop.down.raw : [],
|
|
327
|
+
...indexNeedsToDrop.map((index)=>genIndexDefinition(index, table))
|
|
328
|
+
];
|
|
220
329
|
const lines = [
|
|
221
330
|
'import { Knex } from "knex";',
|
|
222
331
|
"",
|
|
223
332
|
"export async function up(knex: Knex): Promise<void> {",
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
...alterColumnsTo.alter.length > 0 ? alterColumnLinesTo.alter.up : [],
|
|
231
|
-
// 4. add index
|
|
232
|
-
...standardIndexes.map((index)=>genIndexDefinition(index, table)),
|
|
233
|
-
// 5. drop index
|
|
234
|
-
...indexNeedsToDrop.map(genIndexDropDefinition),
|
|
235
|
-
"});",
|
|
236
|
-
// ngram은 knex.raw로 처리하므로 alterTable 밖에서 실행
|
|
237
|
-
...ngramIndexes.map((index)=>genIndexDefinition(index, table)),
|
|
333
|
+
...upBuilderLines.length > 0 ? [
|
|
334
|
+
`await knex.schema.alterTable("${table}", (table) => {`,
|
|
335
|
+
...upBuilderLines,
|
|
336
|
+
"});"
|
|
337
|
+
] : [],
|
|
338
|
+
...upRawLines,
|
|
238
339
|
"}",
|
|
239
340
|
"",
|
|
240
341
|
"export async function down(knex: Knex): Promise<void> {",
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
...
|
|
247
|
-
"});",
|
|
342
|
+
...downBuilderLines.length > 0 ? [
|
|
343
|
+
`await knex.schema.alterTable("${table}", (table) => {`,
|
|
344
|
+
...downBuilderLines,
|
|
345
|
+
"});"
|
|
346
|
+
] : [],
|
|
347
|
+
...downRawLines,
|
|
248
348
|
"}"
|
|
249
349
|
];
|
|
250
350
|
const formatted = formatCode(lines.join("\n"), "typescript", `src/migration/${table}.ts`);
|
|
@@ -272,6 +372,20 @@ function getPgArrayType(column, elementType) {
|
|
|
272
372
|
}
|
|
273
373
|
];
|
|
274
374
|
}
|
|
375
|
+
/**
|
|
376
|
+
* 컬럼 비교를 위해 Generated Column의 expression을 제외한 객체를 생성
|
|
377
|
+
*/ function normalizeColumnForComparison(col) {
|
|
378
|
+
if (col.generated) {
|
|
379
|
+
return {
|
|
380
|
+
...col,
|
|
381
|
+
generated: {
|
|
382
|
+
type: col.generated.type,
|
|
383
|
+
expression: ""
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
return col;
|
|
388
|
+
}
|
|
275
389
|
/**
|
|
276
390
|
* 각 컬럼 이름 기준으로 add, drop, alter 여부 확인
|
|
277
391
|
*/ function getAlterColumnsTo(entityColumns, dbColumns) {
|
|
@@ -282,8 +396,14 @@ function getPgArrayType(column, elementType) {
|
|
|
282
396
|
};
|
|
283
397
|
// 컬럼명 기준 비교
|
|
284
398
|
const extraColumns = {
|
|
285
|
-
db: diff(dbColumns, entityColumns, (col)=>
|
|
286
|
-
|
|
399
|
+
db: diff(dbColumns, entityColumns, (col)=>[
|
|
400
|
+
col.name,
|
|
401
|
+
col.generated?.type
|
|
402
|
+
].join("///")),
|
|
403
|
+
entity: diff(entityColumns, dbColumns, (col)=>[
|
|
404
|
+
col.name,
|
|
405
|
+
col.generated?.type
|
|
406
|
+
].join("///"))
|
|
287
407
|
};
|
|
288
408
|
if (extraColumns.entity.length > 0) {
|
|
289
409
|
columnsTo.add = columnsTo.add.concat(extraColumns.entity);
|
|
@@ -291,10 +411,16 @@ function getPgArrayType(column, elementType) {
|
|
|
291
411
|
if (extraColumns.db.length > 0) {
|
|
292
412
|
columnsTo.drop = columnsTo.drop.concat(extraColumns.db);
|
|
293
413
|
}
|
|
294
|
-
// 동일 컬럼명의 세부 필드 비교
|
|
414
|
+
// 동일 컬럼명의 세부 필드 비교 (Generated Column expression 제외)
|
|
295
415
|
const sameDbColumns = intersectionBy(dbColumns, entityColumns, (col)=>col.name);
|
|
296
416
|
const sameMdColumns = intersectionBy(entityColumns, dbColumns, (col)=>col.name);
|
|
297
|
-
columnsTo.alter = differenceWith(sameDbColumns, sameMdColumns, (a, b)=>equal(
|
|
417
|
+
columnsTo.alter = differenceWith(sameDbColumns, sameMdColumns, (a, b)=>equal({
|
|
418
|
+
...a,
|
|
419
|
+
generated: undefined
|
|
420
|
+
}, {
|
|
421
|
+
...b,
|
|
422
|
+
generated: undefined
|
|
423
|
+
}));
|
|
298
424
|
return columnsTo;
|
|
299
425
|
}
|
|
300
426
|
/**
|
|
@@ -302,27 +428,54 @@ function getPgArrayType(column, elementType) {
|
|
|
302
428
|
*/ function getAlterColumnLinesTo(columnsTo, entityColumns, table, dbForeigns) {
|
|
303
429
|
const linesTo = {
|
|
304
430
|
add: {
|
|
305
|
-
up:
|
|
306
|
-
|
|
431
|
+
up: {
|
|
432
|
+
builder: [],
|
|
433
|
+
raw: []
|
|
434
|
+
},
|
|
435
|
+
down: {
|
|
436
|
+
builder: [],
|
|
437
|
+
raw: []
|
|
438
|
+
}
|
|
307
439
|
},
|
|
308
440
|
drop: {
|
|
309
|
-
up:
|
|
310
|
-
|
|
441
|
+
up: {
|
|
442
|
+
builder: [],
|
|
443
|
+
raw: []
|
|
444
|
+
},
|
|
445
|
+
down: {
|
|
446
|
+
builder: [],
|
|
447
|
+
raw: []
|
|
448
|
+
}
|
|
311
449
|
},
|
|
312
450
|
alter: {
|
|
313
|
-
up:
|
|
314
|
-
|
|
451
|
+
up: {
|
|
452
|
+
builder: [],
|
|
453
|
+
raw: []
|
|
454
|
+
},
|
|
455
|
+
down: {
|
|
456
|
+
builder: [],
|
|
457
|
+
raw: []
|
|
458
|
+
}
|
|
315
459
|
}
|
|
316
460
|
};
|
|
317
|
-
|
|
318
|
-
|
|
461
|
+
// add columns
|
|
462
|
+
const addColumnDefs = genColumnDefinitions(table, columnsTo.add);
|
|
463
|
+
linesTo.add.up = {
|
|
464
|
+
builder: addColumnDefs.builder.length > 0 ? [
|
|
319
465
|
"// add",
|
|
320
|
-
...
|
|
321
|
-
],
|
|
322
|
-
|
|
466
|
+
...addColumnDefs.builder
|
|
467
|
+
] : [],
|
|
468
|
+
raw: addColumnDefs.raw.length > 0 ? [
|
|
469
|
+
"// add (generated)",
|
|
470
|
+
...addColumnDefs.raw
|
|
471
|
+
] : []
|
|
472
|
+
};
|
|
473
|
+
linesTo.add.down = {
|
|
474
|
+
builder: columnsTo.add.length > 0 ? [
|
|
323
475
|
"// rollback - add",
|
|
324
476
|
`table.dropColumns(${columnsTo.add.map((col)=>`'${col.name}'`).join(", ")})`
|
|
325
|
-
]
|
|
477
|
+
] : [],
|
|
478
|
+
raw: []
|
|
326
479
|
};
|
|
327
480
|
// drop할 컬럼에 걸린 FK 찾기
|
|
328
481
|
const dropColumnNames = columnsTo.drop.map((col)=>col.name);
|
|
@@ -332,56 +485,78 @@ function getPgArrayType(column, elementType) {
|
|
|
332
485
|
return `table.dropForeign([${columnsStringQuote}])`;
|
|
333
486
|
});
|
|
334
487
|
const restoreFkLines = genForeignDefinitions(table, fkToDropBeforeColumn).up;
|
|
488
|
+
// drop의 rollback시에는 generated column도 복원해야 함
|
|
489
|
+
const dropColumnDefs = genColumnDefinitions(table, columnsTo.drop);
|
|
335
490
|
linesTo.drop = {
|
|
336
|
-
up:
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
491
|
+
up: {
|
|
492
|
+
builder: [
|
|
493
|
+
...dropFkLines.length > 0 ? [
|
|
494
|
+
"// drop foreign keys on columns to be dropped",
|
|
495
|
+
...dropFkLines
|
|
496
|
+
] : [],
|
|
497
|
+
...columnsTo.drop.length > 0 ? [
|
|
498
|
+
"// drop columns",
|
|
499
|
+
`table.dropColumns(${columnsTo.drop.map((col)=>`'${col.name}'`).join(", ")})`
|
|
500
|
+
] : []
|
|
501
|
+
],
|
|
502
|
+
raw: []
|
|
503
|
+
},
|
|
504
|
+
down: {
|
|
505
|
+
builder: [
|
|
506
|
+
...dropColumnDefs.builder.length > 0 ? [
|
|
507
|
+
"// rollback - drop columns",
|
|
508
|
+
...dropColumnDefs.builder
|
|
509
|
+
] : [],
|
|
510
|
+
...restoreFkLines.length > 0 ? [
|
|
511
|
+
"// restore foreign keys",
|
|
512
|
+
...restoreFkLines
|
|
513
|
+
] : []
|
|
514
|
+
],
|
|
515
|
+
raw: dropColumnDefs.raw.length > 0 ? [
|
|
516
|
+
"// rollback - drop columns (generated)",
|
|
517
|
+
...dropColumnDefs.raw
|
|
350
518
|
] : []
|
|
351
|
-
|
|
519
|
+
}
|
|
352
520
|
};
|
|
521
|
+
// alter columns (Generated Column은 ALTER 불가하므로 drop 후 재생성)
|
|
353
522
|
linesTo.alter = columnsTo.alter.reduce((r, dbColumn)=>{
|
|
354
523
|
const entityColumn = entityColumns.find((col)=>col.name === dbColumn.name);
|
|
355
524
|
if (entityColumn === undefined) {
|
|
356
525
|
return r;
|
|
357
526
|
}
|
|
358
527
|
// 컬럼 변경사항
|
|
359
|
-
const columnDiffUp = diff(genColumnDefinitions([
|
|
528
|
+
const columnDiffUp = diff(genColumnDefinitions(table, [
|
|
360
529
|
entityColumn
|
|
361
|
-
]), genColumnDefinitions([
|
|
530
|
+
]).builder, genColumnDefinitions(table, [
|
|
362
531
|
dbColumn
|
|
363
|
-
]));
|
|
364
|
-
const columnDiffDown = diff(genColumnDefinitions([
|
|
532
|
+
]).builder);
|
|
533
|
+
const columnDiffDown = diff(genColumnDefinitions(table, [
|
|
365
534
|
dbColumn
|
|
366
|
-
]), genColumnDefinitions([
|
|
535
|
+
]).builder, genColumnDefinitions(table, [
|
|
367
536
|
entityColumn
|
|
368
|
-
]));
|
|
537
|
+
]).builder);
|
|
369
538
|
if (columnDiffUp.length > 0) {
|
|
370
|
-
r.up = [
|
|
371
|
-
...r.up,
|
|
539
|
+
r.up.builder = [
|
|
540
|
+
...r.up.builder,
|
|
372
541
|
"// alter column",
|
|
373
542
|
...columnDiffUp.map((l)=>`${l.replace(";", "")}.alter();`)
|
|
374
543
|
];
|
|
375
|
-
r.down = [
|
|
376
|
-
...r.down,
|
|
544
|
+
r.down.builder = [
|
|
545
|
+
...r.down.builder,
|
|
377
546
|
"// rollback - alter column",
|
|
378
547
|
...columnDiffDown.map((l)=>`${l.replace(";", "")}.alter();`)
|
|
379
548
|
];
|
|
380
549
|
}
|
|
381
550
|
return r;
|
|
382
551
|
}, {
|
|
383
|
-
up:
|
|
384
|
-
|
|
552
|
+
up: {
|
|
553
|
+
builder: [],
|
|
554
|
+
raw: []
|
|
555
|
+
},
|
|
556
|
+
down: {
|
|
557
|
+
builder: [],
|
|
558
|
+
raw: []
|
|
559
|
+
}
|
|
385
560
|
});
|
|
386
561
|
return linesTo;
|
|
387
562
|
}
|
|
@@ -393,15 +568,22 @@ function getPgArrayType(column, elementType) {
|
|
|
393
568
|
add: [],
|
|
394
569
|
drop: []
|
|
395
570
|
};
|
|
571
|
+
// 인덱스 고유 식별자 생성 (name을 제외한 모든 필드를 문자열로 변환하여 조합)
|
|
572
|
+
const identity = (index)=>{
|
|
573
|
+
const keys = Object.keys(index).filter((key)=>key !== "name").sort();
|
|
574
|
+
return keys.map((key)=>{
|
|
575
|
+
if (key === "name") {
|
|
576
|
+
return undefined;
|
|
577
|
+
}
|
|
578
|
+
if (key === "columns") {
|
|
579
|
+
return index[key].flatMap(identity);
|
|
580
|
+
}
|
|
581
|
+
return `${key}=${index[key]}`;
|
|
582
|
+
}).join("//");
|
|
583
|
+
};
|
|
396
584
|
const extraIndexes = {
|
|
397
|
-
db: diff(dbIndexes, entityIndexes,
|
|
398
|
-
|
|
399
|
-
col.columns.join("-")
|
|
400
|
-
].join("//")),
|
|
401
|
-
entity: diff(entityIndexes, dbIndexes, (col)=>[
|
|
402
|
-
col.type,
|
|
403
|
-
col.columns.join("-")
|
|
404
|
-
].join("//"))
|
|
585
|
+
db: diff(dbIndexes, entityIndexes.map(setMigrationIndexDefaults), identity),
|
|
586
|
+
entity: diff(entityIndexes.map(setMigrationIndexDefaults), dbIndexes, identity)
|
|
405
587
|
};
|
|
406
588
|
if (extraIndexes.entity.length > 0) {
|
|
407
589
|
indexesTo.add = indexesTo.add.concat(extraIndexes.entity);
|
|
@@ -414,12 +596,21 @@ function getPgArrayType(column, elementType) {
|
|
|
414
596
|
/**
|
|
415
597
|
* 인덱스 삭제 정의 생성
|
|
416
598
|
*/ function genIndexDropDefinition(index) {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
599
|
+
return `table.dropIndex([${index.columns.map((column)=>`'${column.name}'`).join(",")}], '${index.name}')`;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* DB 조회 결과와 비교하기 위한 인덱스 기본값 설정
|
|
603
|
+
*/ function setMigrationIndexDefaults(index) {
|
|
604
|
+
return {
|
|
605
|
+
...index,
|
|
606
|
+
columns: index.columns.map((col)=>({
|
|
607
|
+
...col,
|
|
608
|
+
sortOrder: col.sortOrder ?? "ASC",
|
|
609
|
+
// sortOrder에 따라 nullsFirst의 default 값 설정
|
|
610
|
+
nullsFirst: col.nullsFirst ?? col.sortOrder === "DESC"
|
|
611
|
+
})),
|
|
612
|
+
nullsNotDistinct: index.nullsNotDistinct ?? false
|
|
421
613
|
};
|
|
422
|
-
return `table.drop${methodMap[index.type]}([${index.columns.map((columnName)=>`'${columnName}'`).join(",")}], '${index.name}')`;
|
|
423
614
|
}
|
|
424
615
|
/**
|
|
425
616
|
* 테이블 변경 케이스 - Foreign Key 변경
|
|
@@ -566,7 +757,8 @@ function getPgArrayType(column, elementType) {
|
|
|
566
757
|
(col) => col.name === "price_krw"
|
|
567
758
|
);
|
|
568
759
|
console.debug({ entityColumn, dbColumn });
|
|
569
|
-
*/
|
|
760
|
+
*/ // ?
|
|
761
|
+
const entityIndexes = alphabetical(entitySet.indexes, (a)=>[
|
|
570
762
|
a.type,
|
|
571
763
|
...a.columns
|
|
572
764
|
].join("-"));
|
|
@@ -595,10 +787,10 @@ function getPgArrayType(column, elementType) {
|
|
|
595
787
|
const droppingColumns = diff(dbColumns, entityColumns, (col)=>col.name);
|
|
596
788
|
const alterCodes = [];
|
|
597
789
|
// 1. columnsAndIndexes 처리
|
|
598
|
-
const isEqualColumns = equal(entityColumns, dbColumns);
|
|
790
|
+
const isEqualColumns = equal(entityColumns.map(normalizeColumnForComparison), dbColumns.map(normalizeColumnForComparison));
|
|
599
791
|
const isEqualIndexes = equal(entityIndexes.map((index)=>omit(index, [
|
|
600
792
|
"parser"
|
|
601
|
-
])), dbIndexes);
|
|
793
|
+
])).map(setMigrationIndexDefaults), dbIndexes);
|
|
602
794
|
if (!isEqualColumns || !isEqualIndexes) {
|
|
603
795
|
alterCodes.push(await generateAlterCode_ColumnAndIndexes(entitySet.table, entityColumns, entityIndexes, dbColumns, dbIndexes, dbSet.foreigns));
|
|
604
796
|
}
|
|
@@ -612,4 +804,4 @@ function getPgArrayType(column, elementType) {
|
|
|
612
804
|
return alterCodes.filter((alterCode)=>alterCode !== null).flat();
|
|
613
805
|
}
|
|
614
806
|
|
|
615
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWdyYXRpb24vY29kZS1nZW5lcmF0aW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBlcXVhbCBmcm9tIFwiZmFzdC1kZWVwLWVxdWFsXCI7XG5pbXBvcnQgeyBhbHBoYWJldGljYWwsIGRpZmYsIGZvcmssIG9taXQgfSBmcm9tIFwicmFkYXNoaVwiO1xuaW1wb3J0IHsgTmFpdGUgfSBmcm9tIFwiLi5cIjtcbmltcG9ydCB0eXBlIHtcbiAgR2VuTWlncmF0aW9uQ29kZSxcbiAgTWlncmF0aW9uQ29sdW1uLFxuICBNaWdyYXRpb25Gb3JlaWduLFxuICBNaWdyYXRpb25JbmRleCxcbiAgTWlncmF0aW9uU2V0LFxufSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IGZvcm1hdENvZGUgfSBmcm9tIFwiLi4vdXRpbHMvZm9ybWF0dGVyXCI7XG5pbXBvcnQgeyBkaWZmZXJlbmNlV2l0aCwgaW50ZXJzZWN0aW9uQnkgfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcblxuLyoqXG4gKiDthYzsnbTruJQg7IOd7ISx7ZWY64qUIOy8gOydtOyKpCAtIOy7rOufvC/snbjrjbHsiqQg7IOd7ISxXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlQ3JlYXRlQ29kZV9Db2x1bW5BbmRJbmRleGVzKFxuICB0YWJsZTogc3RyaW5nLFxuICBjb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSxcbiAgaW5kZXhlczogTWlncmF0aW9uSW5kZXhbXSxcbik6IFByb21pc2U8R2VuTWlncmF0aW9uQ29kZT4ge1xuICAvLyBmdWxsdGV4dCBpbmRleCDrtoTrpqxcbiAgY29uc3QgW25ncmFtSW5kZXhlcywgc3RhbmRhcmRJbmRleGVzXSA9IGZvcmsoXG4gICAgaW5kZXhlcyxcbiAgICAoaSkgPT4gaS50eXBlID09PSBcImZ1bGx0ZXh0XCIgJiYgaS5wYXJzZXIgPT09IFwibmdyYW1cIixcbiAgKTtcblxuICAvLyDsu6zrn7wsIOyduOuNseyKpCDsspjrpqxcbiAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW1xuICAgICdpbXBvcnQgeyBLbmV4IH0gZnJvbSBcImtuZXhcIjsnLFxuICAgIFwiXCIsXG4gICAgXCJleHBvcnQgYXN5bmMgZnVuY3Rpb24gdXAoa25leDogS25leCk6IFByb21pc2U8dm9pZD4ge1wiLFxuICAgIGBhd2FpdCBrbmV4LnNjaGVtYS5jcmVhdGVUYWJsZShcIiR7dGFibGV9XCIsICh0YWJsZSkgPT4ge2AsXG4gICAgXCIvLyBjb2x1bW5zXCIsXG4gICAgLi4uZ2VuQ29sdW1uRGVmaW5pdGlvbnMoY29sdW1ucyksXG4gICAgXCJcIixcbiAgICBcIi8vIGluZGV4ZXNcIixcbiAgICAuLi5zdGFuZGFyZEluZGV4ZXMubWFwKChpbmRleCkgPT4gZ2VuSW5kZXhEZWZpbml0aW9uKGluZGV4LCB0YWJsZSkpLFxuICAgIFwifSk7XCIsXG4gICAgLy8gbmdyYW3snYAga25leC5yYXfroZwg7LKY66as7ZWY66+A66GcIGNyZWF0ZVRhYmxlIOuwluyXkOyEnCDsi6TtlolcbiAgICAuLi5uZ3JhbUluZGV4ZXMubWFwKChpbmRleCkgPT4gZ2VuSW5kZXhEZWZpbml0aW9uKGluZGV4LCB0YWJsZSkpLFxuICAgIFwifVwiLFxuICAgIFwiXCIsXG4gICAgXCJleHBvcnQgYXN5bmMgZnVuY3Rpb24gZG93bihrbmV4OiBLbmV4KTogUHJvbWlzZTx2b2lkPiB7XCIsXG4gICAgYCByZXR1cm4ga25leC5zY2hlbWEuZHJvcFRhYmxlKFwiJHt0YWJsZX1cIik7YCxcbiAgICBcIn1cIixcbiAgXTtcbiAgcmV0dXJuIHtcbiAgICB0YWJsZSxcbiAgICB0eXBlOiBcIm5vcm1hbFwiLFxuICAgIHRpdGxlOiBgY3JlYXRlX18ke3RhYmxlfWAsXG4gICAgZm9ybWF0dGVkOiBmb3JtYXRDb2RlKGxpbmVzLmpvaW4oXCJcXG5cIiksIFwidHlwZXNjcmlwdFwiLCBgc3JjL21pZ3JhdGlvbi8ke3RhYmxlfS50c2ApLFxuICB9O1xufVxuXG4vKipcbiAqIE1pZ3JhdGlvbkNvbHVtbltdIOydveyWtOyEnCDsu6zrn7wg7KCV7J2Y7ZWY64qUIOq1rOusuCDsg53shLFcbiAqL1xuZnVuY3Rpb24gZ2VuQ29sdW1uRGVmaW5pdGlvbnMoY29sdW1uczogTWlncmF0aW9uQ29sdW1uW10pOiBzdHJpbmdbXSB7XG4gIHJldHVybiBjb2x1bW5zLm1hcCgoY29sdW1uKSA9PiB7XG4gICAgY29uc3QgY2hhaW5zOiBzdHJpbmdbXSA9IFtdO1xuICAgIGlmIChjb2x1bW4ubmFtZSA9PT0gXCJpZFwiKSB7XG4gICAgICByZXR1cm4gYHRhYmxlLmluY3JlbWVudHMoKS5wcmltYXJ5KCk7YDtcbiAgICB9XG5cbiAgICAvLyDrsLDsl7Qg7YOA7J6FIOyymOumrFxuICAgIGlmIChjb2x1bW4udHlwZS5lbmRzV2l0aChcIltdXCIpKSB7XG4gICAgICBjb25zdCBlbGVtZW50VHlwZSA9IGNvbHVtbi50eXBlLnNsaWNlKDAsIC0yKTsgLy8gXCJpbnRlZ2VyW11cIiAtPiBcImludGVnZXJcIlxuICAgICAgY29uc3QgcGdUeXBlID0gZ2V0UGdBcnJheVR5cGUoY29sdW1uLCBlbGVtZW50VHlwZSk7XG4gICAgICBjaGFpbnMucHVzaChgc3BlY2lmaWNUeXBlKCcke2NvbHVtbi5uYW1lfScsICcke3BnVHlwZX0nKWApO1xuICAgIH0gZWxzZSBpZiAoY29sdW1uLnR5cGUgPT09IFwibnVtYmVyT3JOdW1lcmljXCIpIHtcbiAgICAgIC8vIG51bWJlclxuICAgICAgaWYgKGNvbHVtbi5udW1iZXJUeXBlID09PSBcInJlYWxcIikge1xuICAgICAgICBjaGFpbnMucHVzaChgZmxvYXQoJyR7Y29sdW1uLm5hbWV9JylgKTtcbiAgICAgIH0gZWxzZSBpZiAoY29sdW1uLm51bWJlclR5cGUgPT09IFwiZG91YmxlIHByZWNpc2lvblwiKSB7XG4gICAgICAgIGNoYWlucy5wdXNoKGBkb3VibGUoJyR7Y29sdW1uLm5hbWV9JylgKTtcbiAgICAgIH0gZWxzZSBpZiAoKGNvbHVtbi5udW1iZXJUeXBlID8/IFwibnVtZXJpY1wiKSA9PT0gXCJudW1lcmljXCIpIHtcbiAgICAgICAgY2hhaW5zLnB1c2goYGRlY2ltYWwoJyR7Y29sdW1uLm5hbWV9JywgJHtjb2x1bW4ucHJlY2lzaW9ufSwgJHtjb2x1bW4uc2NhbGV9KWApO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY29sdW1uLnR5cGUgPT09IFwic3RyaW5nXCIpIHtcbiAgICAgIC8vIHN0cmluZ1xuICAgICAgaWYgKGNvbHVtbi5sZW5ndGggIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjaGFpbnMucHVzaChgc3RyaW5nKCcke2NvbHVtbi5uYW1lfScsICR7Y29sdW1uLmxlbmd0aH0pYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjaGFpbnMucHVzaChgdGV4dCgnJHtjb2x1bW4ubmFtZX0nKWApO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY29sdW1uLnR5cGUgPT09IFwiZGF0ZVwiKSB7XG4gICAgICAvLyBkYXRlXG4gICAgICBjaGFpbnMucHVzaChgdGltZXN0YW1wKCcke2NvbHVtbi5uYW1lfScsIHsgdXNlVHo6IHRydWUgfSlgKTtcbiAgICB9IGVsc2UgaWYgKGNvbHVtbi50eXBlID09PSBcImpzb25cIikge1xuICAgICAgLy8ganNvblxuICAgICAgY2hhaW5zLnB1c2goYGpzb25iKCcke2NvbHVtbi5uYW1lfScpYCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIHR5cGUsIGxlbmd0aFxuICAgICAgbGV0IGV4dHJhVHlwZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgY2hhaW5zLnB1c2goXG4gICAgICAgIGAke2NvbHVtbi50eXBlfSgnJHtjb2x1bW4ubmFtZX0nJHtcbiAgICAgICAgICBjb2x1bW4ubGVuZ3RoID8gYCwgJHtjb2x1bW4ubGVuZ3RofWAgOiBcIlwiXG4gICAgICAgIH0ke2V4dHJhVHlwZSA/IGAsICcke2V4dHJhVHlwZX0nYCA6IFwiXCJ9KWAsXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIG51bGxhYmxlXG4gICAgY2hhaW5zLnB1c2goY29sdW1uLm51bGxhYmxlID8gXCJudWxsYWJsZSgpXCIgOiBcIm5vdE51bGxhYmxlKClcIik7XG5cbiAgICAvLyBkZWZhdWx0VG9cbiAgICBpZiAoY29sdW1uLmRlZmF1bHRUbyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZW9mIGNvbHVtbi5kZWZhdWx0VG8gPT09IFwic3RyaW5nXCIgJiYgY29sdW1uLmRlZmF1bHRUby5zdGFydHNXaXRoKGBcImApKSB7XG4gICAgICAgIGNoYWlucy5wdXNoKGBkZWZhdWx0VG8oJHtjb2x1bW4uZGVmYXVsdFRvfSlgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNoYWlucy5wdXNoKGBkZWZhdWx0VG8oa25leC5yYXcoJyR7Y29sdW1uLmRlZmF1bHRUb30nKSlgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYHRhYmxlLiR7Y2hhaW5zLmpvaW4oXCIuXCIpfTtgO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0UGdBcnJheVR5cGUoY29sdW1uOiBNaWdyYXRpb25Db2x1bW4sIGVsZW1lbnRUeXBlOiBzdHJpbmcpOiBzdHJpbmcge1xuICBpZiAoZWxlbWVudFR5cGUgPT09IFwibnVtYmVyT3JOdW1lcmljXCIpIHtcbiAgICBpZiAoY29sdW1uLm51bWJlclR5cGUgPT09IFwicmVhbFwiKSByZXR1cm4gXCJyZWFsW11cIjtcbiAgICBpZiAoY29sdW1uLm51bWJlclR5cGUgPT09IFwiZG91YmxlIHByZWNpc2lvblwiKSByZXR1cm4gXCJkb3VibGUgcHJlY2lzaW9uW11cIjtcbiAgICByZXR1cm4gYG51bWVyaWMoJHtjb2x1bW4ucHJlY2lzaW9ufSwgJHtjb2x1bW4uc2NhbGV9KVtdYDtcbiAgfVxuICBpZiAoZWxlbWVudFR5cGUgPT09IFwic3RyaW5nXCIpIHtcbiAgICByZXR1cm4gY29sdW1uLmxlbmd0aCA/IGB2YXJjaGFyKCR7Y29sdW1uLmxlbmd0aH0pW11gIDogXCJ0ZXh0W11cIjtcbiAgfVxuICBpZiAoZWxlbWVudFR5cGUgPT09IFwiZGF0ZVwiKSByZXR1cm4gXCJ0aW1lc3RhbXB0eltdXCI7XG4gIGlmIChlbGVtZW50VHlwZSA9PT0gXCJpbnRlZ2VyXCIpIHJldHVybiBcImludGVnZXJbXVwiO1xuICBpZiAoZWxlbWVudFR5cGUgPT09IFwiYmlnSW50ZWdlclwiKSByZXR1cm4gXCJiaWdpbnRbXVwiO1xuICBpZiAoZWxlbWVudFR5cGUgPT09IFwiYm9vbGVhblwiKSByZXR1cm4gXCJib29sZWFuW11cIjtcbiAgaWYgKGVsZW1lbnRUeXBlID09PSBcInV1aWRcIikgcmV0dXJuIFwidXVpZFtdXCI7XG4gIGlmIChlbGVtZW50VHlwZSA9PT0gXCJlbnVtXCIpIHJldHVybiBcInRleHRbXVwiO1xuXG4gIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBhcnJheSBlbGVtZW50IHR5cGU6ICR7ZWxlbWVudFR5cGV9YCk7XG59XG5cbi8qKlxuICog6rCc67OEIOyduOuNseyKpCDsoJXsnZgg7IOd7ISxXG4gKi9cbmZ1bmN0aW9uIGdlbkluZGV4RGVmaW5pdGlvbihpbmRleDogTWlncmF0aW9uSW5kZXgsIHRhYmxlOiBzdHJpbmcpIHtcbiAgY29uc3QgbWV0aG9kTWFwID0ge1xuICAgIGluZGV4OiBcImluZGV4XCIsXG4gICAgZnVsbHRleHQ6IFwiaW5kZXhcIixcbiAgICB1bmlxdWU6IFwidW5pcXVlXCIsXG4gIH07XG5cbiAgaWYgKGluZGV4LnR5cGUgPT09IFwiZnVsbHRleHRcIiAmJiBpbmRleC5wYXJzZXIgPT09IFwibmdyYW1cIikge1xuICAgIHJldHVybiBgYXdhaXQga25leC5yYXcoXFxgQUxURVIgVEFCTEUgJHt0YWJsZX0gQUREIEZVTExURVhUIElOREVYICR7aW5kZXgubmFtZX0gKCR7aW5kZXguY29sdW1ucy5qb2luKFxuICAgICAgXCIsIFwiLFxuICAgICl9KSBXSVRIIFBBUlNFUiBuZ3JhbVxcYCk7YDtcbiAgfVxuXG4gIHJldHVybiBgdGFibGUuJHttZXRob2RNYXBbaW5kZXgudHlwZV19KFske2luZGV4LmNvbHVtbnNcbiAgICAubWFwKChjb2wpID0+IGAnJHtjb2x9J2ApXG4gICAgLmpvaW4oXCIsXCIpfV0sICcke2luZGV4Lm5hbWV9JyR7aW5kZXgudHlwZSA9PT0gXCJmdWxsdGV4dFwiID8gXCIsICdGVUxMVEVYVCdcIiA6IFwiXCJ9XG4gICk7YDtcbn1cblxuLyoqXG4gKiDthYzsnbTruJQg7IOd7ISx7ZWY64qUIOy8gOydtOyKpCAtIEZLIOyDneyEsVxuICovXG5hc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUNyZWF0ZUNvZGVfRm9yZWlnbihcbiAgdGFibGU6IHN0cmluZyxcbiAgZm9yZWlnbnM6IE1pZ3JhdGlvbkZvcmVpZ25bXSxcbik6IFByb21pc2U8R2VuTWlncmF0aW9uQ29kZVtdPiB7XG4gIGlmIChmb3JlaWducy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCB7IHVwLCBkb3duIH0gPSBnZW5Gb3JlaWduRGVmaW5pdGlvbnModGFibGUsIGZvcmVpZ25zKTtcbiAgaWYgKHVwLmxlbmd0aCA9PT0gMCAmJiBkb3duLmxlbmd0aCA9PT0gMCkge1xuICAgIGNvbnNvbGUubG9nKFwiZmsg6rCAIOutlOqwgCDri6TrpoXri4jri6RcIik7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW1xuICAgICdpbXBvcnQgeyBLbmV4IH0gZnJvbSBcImtuZXhcIjsnLFxuICAgIFwiXCIsXG4gICAgXCJleHBvcnQgYXN5bmMgZnVuY3Rpb24gdXAoa25leDogS25leCk6IFByb21pc2U8dm9pZD4ge1wiLFxuICAgIGByZXR1cm4ga25leC5zY2hlbWEuYWx0ZXJUYWJsZShcIiR7dGFibGV9XCIsICh0YWJsZSkgPT4ge2AsXG4gICAgXCIvLyBjcmVhdGUgZmtcIixcbiAgICAuLi51cCxcbiAgICBcIn0pO1wiLFxuICAgIFwifVwiLFxuICAgIFwiXCIsXG4gICAgXCJleHBvcnQgYXN5bmMgZnVuY3Rpb24gZG93bihrbmV4OiBLbmV4KTogUHJvbWlzZTx2b2lkPiB7XCIsXG4gICAgYHJldHVybiBrbmV4LnNjaGVtYS5hbHRlclRhYmxlKFwiJHt0YWJsZX1cIiwgKHRhYmxlKSA9PiB7YCxcbiAgICBcIi8vIGRyb3AgZmtcIixcbiAgICAuLi5kb3duLFxuICAgIFwifSk7XCIsXG4gICAgXCJ9XCIsXG4gIF07XG5cbiAgY29uc3QgZm9yZWlnbktleXNTdHJpbmcgPSBmb3JlaWducy5tYXAoKGZvcmVpZ24pID0+IGZvcmVpZ24uY29sdW1ucy5qb2luKFwiX1wiKSkuam9pbihcIl9cIik7XG4gIHJldHVybiBbXG4gICAge1xuICAgICAgdGFibGUsXG4gICAgICB0eXBlOiBcImZvcmVpZ25cIixcbiAgICAgIHRpdGxlOiBgZm9yZWlnbl9fJHt0YWJsZX1fXyR7Zm9yZWlnbktleXNTdHJpbmd9YCxcbiAgICAgIGZvcm1hdHRlZDogZm9ybWF0Q29kZShsaW5lcy5qb2luKFwiXFxuXCIpLCBcInR5cGVzY3JpcHRcIiwgYHNyYy9taWdyYXRpb24vJHt0YWJsZX0udHNgKSxcbiAgICB9LFxuICBdO1xufVxuXG4vKipcbiAqIE1pZ3JhdGlvbkZvcmVpZ25bXSDsnb3slrTshJwg7Jm467aA7YKkIGNvbnN0cmFpbnQg7KCV7J2Y7ZWY64qUIOq1rOusuCDsg53shLFcbiAqL1xuZnVuY3Rpb24gZ2VuRm9yZWlnbkRlZmluaXRpb25zKFxuICB0YWJsZTogc3RyaW5nLFxuICBmb3JlaWduczogTWlncmF0aW9uRm9yZWlnbltdLFxuKTogeyB1cDogc3RyaW5nW107IGRvd246IHN0cmluZ1tdIH0ge1xuICByZXR1cm4gZm9yZWlnbnMucmVkdWNlKFxuICAgIChyLCBmb3JlaWduKSA9PiB7XG4gICAgICBjb25zdCBjb2x1bW5zU3RyaW5nUXVvdGUgPSBmb3JlaWduLmNvbHVtbnNcbiAgICAgICAgLm1hcCgoY29sKSA9PiBgJyR7Y29sLnJlcGxhY2UoYCR7dGFibGV9LmAsIFwiXCIpfSdgKVxuICAgICAgICAuam9pbihcIixcIik7XG4gICAgICByLnVwLnB1c2goXG4gICAgICAgIGB0YWJsZS5mb3JlaWduKCcke2ZvcmVpZ24uY29sdW1ucy5qb2luKFwiLFwiKX0nKVxuICAgICAgICAgICAgLnJlZmVyZW5jZXMoJyR7Zm9yZWlnbi50b30nKVxuICAgICAgICAgICAgLm9uVXBkYXRlKCcke2ZvcmVpZ24ub25VcGRhdGV9JylcbiAgICAgICAgICAgIC5vbkRlbGV0ZSgnJHtmb3JlaWduLm9uRGVsZXRlfScpYCxcbiAgICAgICk7XG4gICAgICByLmRvd24ucHVzaChgdGFibGUuZHJvcEZvcmVpZ24oWyR7Y29sdW1uc1N0cmluZ1F1b3RlfV0pYCk7XG4gICAgICByZXR1cm4gcjtcbiAgICB9LFxuICAgIHtcbiAgICAgIHVwOiBbXSBhcyBzdHJpbmdbXSxcbiAgICAgIGRvd246IFtdIGFzIHN0cmluZ1tdLFxuICAgIH0sXG4gICk7XG59XG5cbi8qKlxuICog7YWM7J2067iUIOuzgOqyvSDsvIDsnbTsiqQgLSDsu6zrn7wv7J24642x7IqkIOuzgOqyvVxuICovXG5hc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUFsdGVyQ29kZV9Db2x1bW5BbmRJbmRleGVzKFxuICB0YWJsZTogc3RyaW5nLFxuICBlbnRpdHlDb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSxcbiAgZW50aXR5SW5kZXhlczogTWlncmF0aW9uSW5kZXhbXSxcbiAgZGJDb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSxcbiAgZGJJbmRleGVzOiBNaWdyYXRpb25JbmRleFtdLFxuICBkYkZvcmVpZ25zOiBNaWdyYXRpb25Gb3JlaWduW10sXG4pOiBQcm9taXNlPEdlbk1pZ3JhdGlvbkNvZGVbXT4ge1xuICAvKlxuICAgIOyEuOu2gCDruYTqtZAg7ZuEIOuLpOuluOygkCDssL7slYTshJwg7L2U65OcIOyDneyEsVxuXG4gICAgMS4g7Lus65+86rCv7IiYIOuLpOumhDogTUTsl5Ag7J6I7Jy864KYLCBEQuyXkCDsl4bri6TrqbQg7LaU6rCAXG4gICAgMi4g7Lus65+86rCv7IiYIOuLpOumhDogTUTsl5Ag7JeG7Jy864KYLCBEQuyXkCDsnojri6TrqbQg7IKt7KCcXG4gICAgMy4g6re47Jm4IOy7rOufvCjsu6zrn7wg6rCv7IiY6rCAIOuPmeydvO2VmOqxsOuCmCwg64uk66W4IOqyveyasCDrj5nsnbztlZwg7Lus65+864G866asKSA9PiBhbHRlclxuICAgIDQuIOuLpOuluOqxsCDri6Qg64+Z7J287ZWY6rOgIGluZGV466eMIOuzgOqyveuQmOuKlCDqsr3smrBcblxuICAgICoqIOy7rOufvOuqheydhCDrs4Dqsr3tlZjripQg6rK97Jqw64qUIOuUsOuhnCDtlbjrk6Trp4HtlZjsp4Ag7JWK7J2MXG4gICAgPT4gZHJvcC9hZGQg7ZiV7YOc7J2YIOuniOydtOq3uOugiOydtOyFmCDsvZTrk5zqsIAg7IOd7ISx65CY64qU642wLCDsiJjrj5nsnLzroZwgcmVuYW1lIOy9lOuTnOuhnCDsiJjsoJXtlZjsl6wg7LKY66asXG4gICovXG5cbiAgLy8g6rCBIOy7rOufvCDsnbTrpoQg6riw7KSA7Jy866GcIGFkZCwgZHJvcCwgYWx0ZXIg7Jes67aAIO2ZleyduFxuICBjb25zdCBhbHRlckNvbHVtbnNUbyA9IGdldEFsdGVyQ29sdW1uc1RvKGVudGl0eUNvbHVtbnMsIGRiQ29sdW1ucyk7XG5cbiAgLy8g7LaU7Lac65CcIOy7rOufvOuTpOydhCDquLDspIDsnLzroZwg6rCB6rCBIOudvOyduCDsg53shLFcbiAgY29uc3QgYWx0ZXJDb2x1bW5MaW5lc1RvID0gZ2V0QWx0ZXJDb2x1bW5MaW5lc1RvKFxuICAgIGFsdGVyQ29sdW1uc1RvLFxuICAgIGVudGl0eUNvbHVtbnMsXG4gICAgdGFibGUsXG4gICAgZGJGb3JlaWducyxcbiAgKTtcblxuICAvLyDsnbjrjbHsiqTsnZggYWRkLCBkcm9wIOyXrOu2gCDtmZXsnbhcbiAgY29uc3QgYWx0ZXJJbmRleGVzVG8gPSBnZXRBbHRlckluZGV4ZXNUbyhlbnRpdHlJbmRleGVzLCBkYkluZGV4ZXMpO1xuXG4gIC8vIGZ1bGx0ZXh0IGluZGV4IOu2hOumrFxuICBjb25zdCBbbmdyYW1JbmRleGVzLCBzdGFuZGFyZEluZGV4ZXNdID0gZm9yayhcbiAgICBhbHRlckluZGV4ZXNUby5hZGQsXG4gICAgKGkpID0+IGkudHlwZSA9PT0gXCJmdWxsdGV4dFwiICYmIGkucGFyc2VyID09PSBcIm5ncmFtXCIsXG4gICk7XG5cbiAgLy8g7J24642x7Iqk6rCAIOyCreygnOuQmOuKlCDqsr3smrAsIOy7rOufvOqzvCDqsJnsnbQg7IKt7KCc65CcIOy8gOydtOyKpOyXkOuKlCBkcm9w7JeQ7IScIOygnOyZuO2VtOyVvO2VqCFcbiAgY29uc3QgaW5kZXhOZWVkc1RvRHJvcCA9IGFsdGVySW5kZXhlc1RvLmRyb3AuZmlsdGVyKFxuICAgIChpbmRleCkgPT5cbiAgICAgIGluZGV4LmNvbHVtbnMuZXZlcnkoKGNvbE5hbWUpID0+XG4gICAgICAgIGFsdGVyQ29sdW1uc1RvLmRyb3AubWFwKChjb2wpID0+IGNvbC5uYW1lKS5pbmNsdWRlcyhjb2xOYW1lKSxcbiAgICAgICkgPT09IGZhbHNlLFxuICApO1xuXG4gIC8vIOu5iCDsvZTrk5wg7IOd7ISxIOuwqeyngFxuICBpZiAoXG4gICAgYWx0ZXJDb2x1bW5MaW5lc1RvLmFkZC51cC5sZW5ndGggPT09IDAgJiZcbiAgICBhbHRlckNvbHVtbkxpbmVzVG8uZHJvcC51cC5sZW5ndGggPT09IDAgJiZcbiAgICBhbHRlckNvbHVtbkxpbmVzVG8uYWx0ZXIudXAubGVuZ3RoID09PSAwICYmXG4gICAgc3RhbmRhcmRJbmRleGVzLmxlbmd0aCA9PT0gMCAmJlxuICAgIGluZGV4TmVlZHNUb0Ryb3AubGVuZ3RoID09PSAwXG4gICkge1xuICAgIE5haXRlLnQoXCJtaWdyYXRvcjpnZW5lcmF0ZUFsdGVyQ29kZV9Db2x1bW5BbmRJbmRleGVzOmVtcHR5Q29kZUdlbmVyYXRpb25FcnJvclwiLCB7XG4gICAgICBlbnRpdHlDb2x1bW5zLFxuICAgICAgZGJDb2x1bW5zLFxuICAgICAgZW50aXR5SW5kZXhlcyxcbiAgICAgIGRiSW5kZXhlcyxcbiAgICB9KTtcbiAgICAvLyB0aHJvdyBuZXcgRXJyb3IoXCLsu6zrn7wv7J24642x7IqkIOuzgOqyvSDsvZTrk5wg7IOd7ISxIOyYpOulmFwiKTtcbiAgfVxuICBOYWl0ZS50KFwibWlncmF0b3I6Z2VuZXJhdGVBbHRlckNvZGVfQ29sdW1uQW5kSW5kZXhlczpkZWJ1Z1wiLCB7XG4gICAgXCJhbHRlckNvbHVtbnNUby5hZGQubGVuZ3RoXCI6IGFsdGVyQ29sdW1uc1RvLmFkZC5sZW5ndGgsXG4gICAgXCJhbHRlckNvbHVtbnNUby5kcm9wLmxlbmd0aFwiOiBhbHRlckNvbHVtbnNUby5kcm9wLmxlbmd0aCxcbiAgICBcImFsdGVyQ29sdW1uc1RvLmFsdGVyLmxlbmd0aFwiOiBhbHRlckNvbHVtbnNUby5hbHRlci5sZW5ndGgsXG4gICAgXCJhbHRlckluZGV4ZXNUby5hZGQubGVuZ3RoXCI6IGFsdGVySW5kZXhlc1RvLmFkZC5sZW5ndGgsXG4gICAgXCJhbHRlckluZGV4ZXNUby5kcm9wLmxlbmd0aFwiOiBhbHRlckluZGV4ZXNUby5kcm9wLmxlbmd0aCxcbiAgICBcInN0YW5kYXJkSW5kZXhlcy5sZW5ndGhcIjogc3RhbmRhcmRJbmRleGVzLmxlbmd0aCxcbiAgICBcImluZGV4TmVlZHNUb0Ryb3AubGVuZ3RoXCI6IGluZGV4TmVlZHNUb0Ryb3AubGVuZ3RoLFxuICB9KTtcbiAgLy8gTmFpdGUudChcIm1pZ3JhdG9yOmdlbmVyYXRlQWx0ZXJDb2RlX0NvbHVtbkFuZEluZGV4ZXM6YWx0ZXJDb2x1bW5zVG9cIiwgYWx0ZXJDb2x1bW5zVG8pO1xuXG4gIC8vIFRPRE86IOyduOuNseyKpOuqhSDrs4Dqsr3rkJwg6rK97JqwIOyymOumrFxuXG4gIGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtcbiAgICAnaW1wb3J0IHsgS25leCB9IGZyb20gXCJrbmV4XCI7JyxcbiAgICBcIlwiLFxuICAgIFwiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVwKGtuZXg6IEtuZXgpOiBQcm9taXNlPHZvaWQ+IHtcIixcbiAgICBgYXdhaXQga25leC5zY2hlbWEuYWx0ZXJUYWJsZShcIiR7dGFibGV9XCIsICh0YWJsZSkgPT4ge2AsXG4gICAgLy8gMS4gYWRkIGNvbHVtblxuICAgIC4uLihhbHRlckNvbHVtbnNUby5hZGQubGVuZ3RoID4gMCA/IGFsdGVyQ29sdW1uTGluZXNUby5hZGQudXAgOiBbXSksXG4gICAgLy8gMi4gZHJvcCBjb2x1bW5cbiAgICAuLi4oYWx0ZXJDb2x1bW5zVG8uZHJvcC5sZW5ndGggPiAwID8gYWx0ZXJDb2x1bW5MaW5lc1RvLmRyb3AudXAgOiBbXSksXG4gICAgLy8gMy4gYWx0ZXIgY29sdW1uXG4gICAgLi4uKGFsdGVyQ29sdW1uc1RvLmFsdGVyLmxlbmd0aCA+IDAgPyBhbHRlckNvbHVtbkxpbmVzVG8uYWx0ZXIudXAgOiBbXSksXG4gICAgLy8gNC4gYWRkIGluZGV4XG4gICAgLi4uc3RhbmRhcmRJbmRleGVzLm1hcCgoaW5kZXgpID0+IGdlbkluZGV4RGVmaW5pdGlvbihpbmRleCwgdGFibGUpKSxcbiAgICAvLyA1LiBkcm9wIGluZGV4XG4gICAgLi4uaW5kZXhOZWVkc1RvRHJvcC5tYXAoZ2VuSW5kZXhEcm9wRGVmaW5pdGlvbiksXG4gICAgXCJ9KTtcIixcbiAgICAvLyBuZ3JhbeydgCBrbmV4LnJhd+uhnCDsspjrpqztlZjrr4DroZwgYWx0ZXJUYWJsZSDrsJbsl5DshJwg7Iuk7ZaJXG4gICAgLi4ubmdyYW1JbmRleGVzLm1hcCgoaW5kZXgpID0+IGdlbkluZGV4RGVmaW5pdGlvbihpbmRleCwgdGFibGUpKSxcbiAgICBcIn1cIixcbiAgICBcIlwiLFxuICAgIFwiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvd24oa25leDogS25leCk6IFByb21pc2U8dm9pZD4ge1wiLFxuICAgIGByZXR1cm4ga25leC5zY2hlbWEuYWx0ZXJUYWJsZShcIiR7dGFibGV9XCIsICh0YWJsZSkgPT4ge2AsXG4gICAgLi4uKGFsdGVyQ29sdW1uc1RvLmFkZC5sZW5ndGggPiAwID8gYWx0ZXJDb2x1bW5MaW5lc1RvLmFkZC5kb3duIDogW10pLFxuICAgIC4uLihhbHRlckNvbHVtbnNUby5kcm9wLmxlbmd0aCA+IDAgPyBhbHRlckNvbHVtbkxpbmVzVG8uZHJvcC5kb3duIDogW10pLFxuICAgIC4uLihhbHRlckNvbHVtbnNUby5hbHRlci5sZW5ndGggPiAwID8gYWx0ZXJDb2x1bW5MaW5lc1RvLmFsdGVyLmRvd24gOiBbXSksXG4gICAgLi4uYWx0ZXJJbmRleGVzVG8uYWRkXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAoaW5kZXgpID0+XG4gICAgICAgICAgaW5kZXguY29sdW1ucy5ldmVyeSgoY29sTmFtZSkgPT5cbiAgICAgICAgICAgIGFsdGVyQ29sdW1uc1RvLmFkZC5tYXAoKGNvbCkgPT4gY29sLm5hbWUpLmluY2x1ZGVzKGNvbE5hbWUpLFxuICAgICAgICAgICkgPT09IGZhbHNlLFxuICAgICAgKVxuICAgICAgLm1hcChnZW5JbmRleERyb3BEZWZpbml0aW9uKSxcbiAgICAuLi5pbmRleE5lZWRzVG9Ecm9wLm1hcCgoaW5kZXgpID0+IGdlbkluZGV4RGVmaW5pdGlvbihpbmRleCwgdGFibGUpKSxcbiAgICBcIn0pO1wiLFxuICAgIFwifVwiLFxuICBdO1xuXG4gIGNvbnN0IGZvcm1hdHRlZCA9IGZvcm1hdENvZGUobGluZXMuam9pbihcIlxcblwiKSwgXCJ0eXBlc2NyaXB0XCIsIGBzcmMvbWlncmF0aW9uLyR7dGFibGV9LnRzYCk7XG4gIGNvbnN0IHRpdGxlID0gW1xuICAgIFwiYWx0ZXJcIixcbiAgICB0YWJsZSxcbiAgICAuLi4oW1wiYWRkXCIsIFwiZHJvcFwiLCBcImFsdGVyXCJdIGFzIGNvbnN0KVxuICAgICAgLm1hcCgoYWN0aW9uKSA9PiB7XG4gICAgICAgIGNvbnN0IGxlbiA9IGFsdGVyQ29sdW1uc1RvW2FjdGlvbl0ubGVuZ3RoO1xuICAgICAgICBpZiAobGVuID4gMCkge1xuICAgICAgICAgIHJldHVybiBhY3Rpb24gKyBsZW47XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigocGFydCkgPT4gcGFydCAhPT0gbnVsbCksXG4gIF0uam9pbihcIl9cIik7XG5cbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICB0YWJsZSxcbiAgICAgIHRpdGxlLFxuICAgICAgZm9ybWF0dGVkLFxuICAgICAgdHlwZTogXCJub3JtYWxcIixcbiAgICB9LFxuICBdO1xufVxuXG4vKipcbiAqIOqwgSDsu6zrn7wg7J2066aEIOq4sOykgOycvOuhnCBhZGQsIGRyb3AsIGFsdGVyIOyXrOu2gCDtmZXsnbhcbiAqL1xuZnVuY3Rpb24gZ2V0QWx0ZXJDb2x1bW5zVG8oZW50aXR5Q29sdW1uczogTWlncmF0aW9uQ29sdW1uW10sIGRiQ29sdW1uczogTWlncmF0aW9uQ29sdW1uW10pIHtcbiAgY29uc3QgY29sdW1uc1RvID0ge1xuICAgIGFkZDogW10gYXMgTWlncmF0aW9uQ29sdW1uW10sXG4gICAgZHJvcDogW10gYXMgTWlncmF0aW9uQ29sdW1uW10sXG4gICAgYWx0ZXI6IFtdIGFzIE1pZ3JhdGlvbkNvbHVtbltdLFxuICB9O1xuXG4gIC8vIOy7rOufvOuqhSDquLDspIAg67mE6rWQXG4gIGNvbnN0IGV4dHJhQ29sdW1ucyA9IHtcbiAgICBkYjogZGlmZihkYkNvbHVtbnMsIGVudGl0eUNvbHVtbnMsIChjb2wpID0+IGNvbC5uYW1lKSxcbiAgICBlbnRpdHk6IGRpZmYoZW50aXR5Q29sdW1ucywgZGJDb2x1bW5zLCAoY29sKSA9PiBjb2wubmFtZSksXG4gIH07XG4gIGlmIChleHRyYUNvbHVtbnMuZW50aXR5Lmxlbmd0aCA+IDApIHtcbiAgICBjb2x1bW5zVG8uYWRkID0gY29sdW1uc1RvLmFkZC5jb25jYXQoZXh0cmFDb2x1bW5zLmVudGl0eSk7XG4gIH1cbiAgaWYgKGV4dHJhQ29sdW1ucy5kYi5sZW5ndGggPiAwKSB7XG4gICAgY29sdW1uc1RvLmRyb3AgPSBjb2x1bW5zVG8uZHJvcC5jb25jYXQoZXh0cmFDb2x1bW5zLmRiKTtcbiAgfVxuXG4gIC8vIOuPmeydvCDsu6zrn7zrqoXsnZgg7IS467aAIO2VhOuTnCDruYTqtZBcbiAgY29uc3Qgc2FtZURiQ29sdW1ucyA9IGludGVyc2VjdGlvbkJ5KGRiQ29sdW1ucywgZW50aXR5Q29sdW1ucywgKGNvbCkgPT4gY29sLm5hbWUpO1xuICBjb25zdCBzYW1lTWRDb2x1bW5zID0gaW50ZXJzZWN0aW9uQnkoZW50aXR5Q29sdW1ucywgZGJDb2x1bW5zLCAoY29sKSA9PiBjb2wubmFtZSk7XG4gIGNvbHVtbnNUby5hbHRlciA9IGRpZmZlcmVuY2VXaXRoKHNhbWVEYkNvbHVtbnMsIHNhbWVNZENvbHVtbnMsIChhLCBiKSA9PiBlcXVhbChhLCBiKSk7XG5cbiAgcmV0dXJuIGNvbHVtbnNUbztcbn1cblxuLyoqXG4gKiDstpTstpzrkJwg7Lus65+865Ok7J2EIOq4sOykgOycvOuhnCDqsIHqsIEg65287J24IOyDneyEsVxuICovXG5mdW5jdGlvbiBnZXRBbHRlckNvbHVtbkxpbmVzVG8oXG4gIGNvbHVtbnNUbzogUmV0dXJuVHlwZTx0eXBlb2YgZ2V0QWx0ZXJDb2x1bW5zVG8+LFxuICBlbnRpdHlDb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSxcbiAgdGFibGU6IHN0cmluZyxcbiAgZGJGb3JlaWduczogTWlncmF0aW9uRm9yZWlnbltdLFxuKSB7XG4gIGNvbnN0IGxpbmVzVG8gPSB7XG4gICAgYWRkOiB7XG4gICAgICB1cDogW10gYXMgc3RyaW5nW10sXG4gICAgICBkb3duOiBbXSBhcyBzdHJpbmdbXSxcbiAgICB9LFxuICAgIGRyb3A6IHtcbiAgICAgIHVwOiBbXSBhcyBzdHJpbmdbXSxcbiAgICAgIGRvd246IFtdIGFzIHN0cmluZ1tdLFxuICAgIH0sXG4gICAgYWx0ZXI6IHtcbiAgICAgIHVwOiBbXSBhcyBzdHJpbmdbXSxcbiAgICAgIGRvd246IFtdIGFzIHN0cmluZ1tdLFxuICAgIH0sXG4gIH07XG5cbiAgbGluZXNUby5hZGQgPSB7XG4gICAgdXA6IFtcIi8vIGFkZFwiLCAuLi5nZW5Db2x1bW5EZWZpbml0aW9ucyhjb2x1bW5zVG8uYWRkKV0sXG4gICAgZG93bjogW1xuICAgICAgXCIvLyByb2xsYmFjayAtIGFkZFwiLFxuICAgICAgYHRhYmxlLmRyb3BDb2x1bW5zKCR7Y29sdW1uc1RvLmFkZC5tYXAoKGNvbCkgPT4gYCcke2NvbC5uYW1lfSdgKS5qb2luKFwiLCBcIil9KWAsXG4gICAgXSxcbiAgfTtcblxuICAvLyBkcm9w7ZWgIOy7rOufvOyXkCDqsbjrprAgRksg7LC+6riwXG4gIGNvbnN0IGRyb3BDb2x1bW5OYW1lcyA9IGNvbHVtbnNUby5kcm9wLm1hcCgoY29sKSA9PiBjb2wubmFtZSk7XG4gIGNvbnN0IGZrVG9Ecm9wQmVmb3JlQ29sdW1uID0gZGJGb3JlaWducy5maWx0ZXIoKGZrKSA9PlxuICAgIGZrLmNvbHVtbnMuc29tZSgoY29sKSA9PiBkcm9wQ29sdW1uTmFtZXMuaW5jbHVkZXMoY29sKSksXG4gICk7XG5cbiAgY29uc3QgZHJvcEZrTGluZXMgPSBma1RvRHJvcEJlZm9yZUNvbHVtbi5tYXAoKGZrKSA9PiB7XG4gICAgY29uc3QgY29sdW1uc1N0cmluZ1F1b3RlID0gZmsuY29sdW1ucy5tYXAoKGNvbCkgPT4gYCcke2NvbH0nYCkuam9pbihcIixcIik7XG4gICAgcmV0dXJuIGB0YWJsZS5kcm9wRm9yZWlnbihbJHtjb2x1bW5zU3RyaW5nUXVvdGV9XSlgO1xuICB9KTtcblxuICBjb25zdCByZXN0b3JlRmtMaW5lcyA9IGdlbkZvcmVpZ25EZWZpbml0aW9ucyh0YWJsZSwgZmtUb0Ryb3BCZWZvcmVDb2x1bW4pLnVwO1xuXG4gIGxpbmVzVG8uZHJvcCA9IHtcbiAgICB1cDogW1xuICAgICAgLi4uKGRyb3BGa0xpbmVzLmxlbmd0aCA+IDBcbiAgICAgICAgPyBbXCIvLyBkcm9wIGZvcmVpZ24ga2V5cyBvbiBjb2x1bW5zIHRvIGJlIGRyb3BwZWRcIiwgLi4uZHJvcEZrTGluZXNdXG4gICAgICAgIDogW10pLFxuICAgICAgXCIvLyBkcm9wIGNvbHVtbnNcIixcbiAgICAgIGB0YWJsZS5kcm9wQ29sdW1ucygke2NvbHVtbnNUby5kcm9wLm1hcCgoY29sKSA9PiBgJyR7Y29sLm5hbWV9J2ApLmpvaW4oXCIsIFwiKX0pYCxcbiAgICBdLFxuICAgIGRvd246IFtcbiAgICAgIFwiLy8gcm9sbGJhY2sgLSBkcm9wIGNvbHVtbnNcIixcbiAgICAgIC4uLmdlbkNvbHVtbkRlZmluaXRpb25zKGNvbHVtbnNUby5kcm9wKSxcbiAgICAgIC4uLihyZXN0b3JlRmtMaW5lcy5sZW5ndGggPiAwID8gW1wiLy8gcmVzdG9yZSBmb3JlaWduIGtleXNcIiwgLi4ucmVzdG9yZUZrTGluZXNdIDogW10pLFxuICAgIF0sXG4gIH07XG4gIGxpbmVzVG8uYWx0ZXIgPSBjb2x1bW5zVG8uYWx0ZXIucmVkdWNlKFxuICAgIChyLCBkYkNvbHVtbikgPT4ge1xuICAgICAgY29uc3QgZW50aXR5Q29sdW1uID0gZW50aXR5Q29sdW1ucy5maW5kKChjb2wpID0+IGNvbC5uYW1lID09PSBkYkNvbHVtbi5uYW1lKTtcbiAgICAgIGlmIChlbnRpdHlDb2x1bW4gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gcjtcbiAgICAgIH1cblxuICAgICAgLy8g7Lus65+8IOuzgOqyveyCrO2VrVxuICAgICAgY29uc3QgY29sdW1uRGlmZlVwID0gZGlmZihcbiAgICAgICAgZ2VuQ29sdW1uRGVmaW5pdGlvbnMoW2VudGl0eUNvbHVtbl0pLFxuICAgICAgICBnZW5Db2x1bW5EZWZpbml0aW9ucyhbZGJDb2x1bW5dKSxcbiAgICAgICk7XG4gICAgICBjb25zdCBjb2x1bW5EaWZmRG93biA9IGRpZmYoXG4gICAgICAgIGdlbkNvbHVtbkRlZmluaXRpb25zKFtkYkNvbHVtbl0pLFxuICAgICAgICBnZW5Db2x1bW5EZWZpbml0aW9ucyhbZW50aXR5Q29sdW1uXSksXG4gICAgICApO1xuICAgICAgaWYgKGNvbHVtbkRpZmZVcC5sZW5ndGggPiAwKSB7XG4gICAgICAgIHIudXAgPSBbXG4gICAgICAgICAgLi4uci51cCxcbiAgICAgICAgICBcIi8vIGFsdGVyIGNvbHVtblwiLFxuICAgICAgICAgIC4uLmNvbHVtbkRpZmZVcC5tYXAoKGwpID0+IGAke2wucmVwbGFjZShcIjtcIiwgXCJcIil9LmFsdGVyKCk7YCksXG4gICAgICAgIF07XG4gICAgICAgIHIuZG93biA9IFtcbiAgICAgICAgICAuLi5yLmRvd24sXG4gICAgICAgICAgXCIvLyByb2xsYmFjayAtIGFsdGVyIGNvbHVtblwiLFxuICAgICAgICAgIC4uLmNvbHVtbkRpZmZEb3duLm1hcCgobCkgPT4gYCR7bC5yZXBsYWNlKFwiO1wiLCBcIlwiKX0uYWx0ZXIoKTtgKSxcbiAgICAgICAgXTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHI7XG4gICAgfSxcbiAgICB7XG4gICAgICB1cDogW10gYXMgc3RyaW5nW10sXG4gICAgICBkb3duOiBbXSBhcyBzdHJpbmdbXSxcbiAgICB9LFxuICApO1xuXG4gIHJldHVybiBsaW5lc1RvO1xufVxuXG4vKipcbiAqIOyduOuNseyKpOydmCBhZGQsIGRyb3Ag7Jes67aAIO2ZleyduFxuICovXG5mdW5jdGlvbiBnZXRBbHRlckluZGV4ZXNUbyhlbnRpdHlJbmRleGVzOiBNaWdyYXRpb25JbmRleFtdLCBkYkluZGV4ZXM6IE1pZ3JhdGlvbkluZGV4W10pIHtcbiAgLy8g7J24642x7IqkIOu5hOq1kFxuICBjb25zdCBpbmRleGVzVG8gPSB7XG4gICAgYWRkOiBbXSBhcyBNaWdyYXRpb25JbmRleFtdLFxuICAgIGRyb3A6IFtdIGFzIE1pZ3JhdGlvbkluZGV4W10sXG4gIH07XG4gIGNvbnN0IGV4dHJhSW5kZXhlcyA9IHtcbiAgICBkYjogZGlmZihkYkluZGV4ZXMsIGVudGl0eUluZGV4ZXMsIChjb2wpID0+IFtjb2wudHlwZSwgY29sLmNvbHVtbnMuam9pbihcIi1cIildLmpvaW4oXCIvL1wiKSksXG4gICAgZW50aXR5OiBkaWZmKGVudGl0eUluZGV4ZXMsIGRiSW5kZXhlcywgKGNvbCkgPT4gW2NvbC50eXBlLCBjb2wuY29sdW1ucy5qb2luKFwiLVwiKV0uam9pbihcIi8vXCIpKSxcbiAgfTtcbiAgaWYgKGV4dHJhSW5kZXhlcy5lbnRpdHkubGVuZ3RoID4gMCkge1xuICAgIGluZGV4ZXNUby5hZGQgPSBpbmRleGVzVG8uYWRkLmNvbmNhdChleHRyYUluZGV4ZXMuZW50aXR5KTtcbiAgfVxuICBpZiAoZXh0cmFJbmRleGVzLmRiLmxlbmd0aCA+IDApIHtcbiAgICBpbmRleGVzVG8uZHJvcCA9IGluZGV4ZXNUby5kcm9wLmNvbmNhdChleHRyYUluZGV4ZXMuZGIpO1xuICB9XG5cbiAgcmV0dXJuIGluZGV4ZXNUbztcbn1cblxuLyoqXG4gKiDsnbjrjbHsiqQg7IKt7KCcIOygleydmCDsg53shLFcbiAqL1xuZnVuY3Rpb24gZ2VuSW5kZXhEcm9wRGVmaW5pdGlvbihpbmRleDogTWlncmF0aW9uSW5kZXgpIHtcbiAgY29uc3QgbWV0aG9kTWFwID0ge1xuICAgIGluZGV4OiBcIkluZGV4XCIsXG4gICAgZnVsbHRleHQ6IFwiSW5kZXhcIixcbiAgICB1bmlxdWU6IFwiVW5pcXVlXCIsXG4gIH07XG5cbiAgcmV0dXJuIGB0YWJsZS5kcm9wJHttZXRob2RNYXBbaW5kZXgudHlwZV19KFske2luZGV4LmNvbHVtbnNcbiAgICAubWFwKChjb2x1bW5OYW1lKSA9PiBgJyR7Y29sdW1uTmFtZX0nYClcbiAgICAuam9pbihcIixcIil9XSwgJyR7aW5kZXgubmFtZX0nKWA7XG59XG5cbi8qKlxuICog7YWM7J2067iUIOuzgOqyvSDsvIDsnbTsiqQgLSBGb3JlaWduIEtleSDrs4Dqsr1cbiAqL1xuYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVBbHRlckNvZGVfRm9yZWlnbnMoXG4gIHRhYmxlOiBzdHJpbmcsXG4gIGVudGl0eUZvcmVpZ25zOiBNaWdyYXRpb25Gb3JlaWduW10sXG4gIGRiRm9yZWlnbnM6IE1pZ3JhdGlvbkZvcmVpZ25bXSxcbiAgZHJvcHBpbmdDb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSA9IFtdLFxuKTogUHJvbWlzZTxHZW5NaWdyYXRpb25Db2RlW10+IHtcbiAgLy8gY29uc29sZS5sb2coeyBlbnRpdHlGb3JlaWducywgZGJGb3JlaWducyB9KTtcblxuICBjb25zdCBnZXRLZXkgPSAobWY6IE1pZ3JhdGlvbkZvcmVpZ24pOiBzdHJpbmcgPT4ge1xuICAgIHJldHVybiBbbWYuY29sdW1ucy5qb2luKFwiLVwiKSwgbWYudG9dLmpvaW4oXCIvLy9cIik7XG4gIH07XG5cbiAgLy8g7IKt7KCc65CgIOy7rOufvOuqhSDrqqnroZ1cbiAgY29uc3QgZHJvcHBpbmdDb2x1bW5OYW1lcyA9IGRyb3BwaW5nQ29sdW1ucy5tYXAoKGNvbCkgPT4gY29sLm5hbWUpO1xuXG4gIGNvbnN0IGZrVG8gPSBlbnRpdHlGb3JlaWducy5yZWR1Y2UoXG4gICAgKHJlc3VsdCwgZW50aXR5RikgPT4ge1xuICAgICAgY29uc3QgbWF0Y2hpbmdEYkYgPSBkYkZvcmVpZ25zLmZpbmQoKGRiRikgPT4gZ2V0S2V5KGVudGl0eUYpID09PSBnZXRLZXkoZGJGKSk7XG4gICAgICBpZiAoIW1hdGNoaW5nRGJGKSB7XG4gICAgICAgIHJlc3VsdC5hZGQucHVzaChlbnRpdHlGKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgaWYgKGVxdWFsKGVudGl0eUYsIG1hdGNoaW5nRGJGKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmVzdWx0LmFsdGVyU3JjLnB1c2gobWF0Y2hpbmdEYkYpO1xuICAgICAgICByZXN1bHQuYWx0ZXJEc3QucHVzaChlbnRpdHlGKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSxcbiAgICB7XG4gICAgICBhZGQ6IFtdIGFzIE1pZ3JhdGlvbkZvcmVpZ25bXSxcbiAgICAgIGRyb3A6IFtdIGFzIE1pZ3JhdGlvbkZvcmVpZ25bXSxcbiAgICAgIGFsdGVyU3JjOiBbXSBhcyBNaWdyYXRpb25Gb3JlaWduW10sXG4gICAgICBhbHRlckRzdDogW10gYXMgTWlncmF0aW9uRm9yZWlnbltdLFxuICAgIH0sXG4gICk7XG5cbiAgLy8gZGJGb3JlaWduc+yXkOuKlCDsnojsp4Drp4wgZW50aXR5Rm9yZWlnbnPsl5DripQg7JeG64qUIOqyveyasCAo7IKt7KCc65CcIEZLKVxuICAvLyDri6gsIOyCreygnOuQoCDsu6zrn7zsnZggRkvripQg7KCc7Jm4IChnZW5lcmF0ZUFsdGVyQ29kZV9Db2x1bW5BbmRJbmRleGVz7JeQ7IScIOyymOumrClcbiAgZGJGb3JlaWducy5mb3JFYWNoKChkYkYpID0+IHtcbiAgICBjb25zdCBtYXRjaGluZ0VudGl0eUYgPSBlbnRpdHlGb3JlaWducy5maW5kKChlbnRpdHlGKSA9PiBnZXRLZXkoZW50aXR5RikgPT09IGdldEtleShkYkYpKTtcbiAgICBpZiAoIW1hdGNoaW5nRW50aXR5Rikge1xuICAgICAgLy8g7J20IEZL7J2YIOy7rOufvOydtCDsgq3soJzrkKAg7Lus65+8IOuqqeuhneyXkCDsnojripTsp4Ag7ZmV7J24XG4gICAgICBjb25zdCBpc0NvbHVtbkRyb3BwaW5nID0gZGJGLmNvbHVtbnMuc29tZSgoY29sKSA9PiBkcm9wcGluZ0NvbHVtbk5hbWVzLmluY2x1ZGVzKGNvbCkpO1xuICAgICAgLy8g7Lus65+87J20IOyCreygnOuQmOyngCDslYrripQg6rK97Jqw7JeQ66eMIEZLIGRyb3Ag66qp66Gd7JeQIOy2lOqwgFxuICAgICAgaWYgKCFpc0NvbHVtbkRyb3BwaW5nKSB7XG4gICAgICAgIGZrVG8uZHJvcC5wdXNoKGRiRik7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBjb25zdCBsaW5lc1RvID0ge1xuICAgIGFkZDogZ2VuRm9yZWlnbkRlZmluaXRpb25zKHRhYmxlLCBma1RvLmFkZCksXG4gICAgZHJvcDogZ2VuRm9yZWlnbkRlZmluaXRpb25zKHRhYmxlLCBma1RvLmRyb3ApLFxuICAgIGFsdGVyU3JjOiBnZW5Gb3JlaWduRGVmaW5pdGlvbnModGFibGUsIGZrVG8uYWx0ZXJTcmMpLFxuICAgIGFsdGVyRHN0OiBnZW5Gb3JlaWduRGVmaW5pdGlvbnModGFibGUsIGZrVG8uYWx0ZXJEc3QpLFxuICB9O1xuXG4gIC8vIGRyb3AgZmsgY29sdW1uc+yduCDqsr3smrAo7IOd7ISx65CgIOy9lOuTnCDsl4bripQg6rK97JqwKSDtjKjsiqRcbiAgY29uc3QgaGFzTGluZXMgPSBPYmplY3QudmFsdWVzKGxpbmVzVG8pLnNvbWUoKGwpID0+IGwudXAubGVuZ3RoID4gMCB8fCBsLmRvd24ubGVuZ3RoID4gMCk7XG4gIGlmICghaGFzTGluZXMpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBpZiAoXG4gICAgbGluZXNUby5hZGQudXAubGVuZ3RoID09PSAwICYmXG4gICAgbGluZXNUby5kcm9wLnVwLmxlbmd0aCA9PT0gMCAmJlxuICAgIGxpbmVzVG8uYWx0ZXJTcmMudXAubGVuZ3RoID09PSAwICYmXG4gICAgbGluZXNUby5hbHRlckRzdC51cC5sZW5ndGggPT09IDBcbiAgKSB7XG4gICAgTmFpdGUudChcIm1pZ3JhdG9yOmdlbmVyYXRlQWx0ZXJDb2RlX0ZvcmVpZ25zOmZrQ2hhbmdlQ29kZUdlbmVyYXRpb25FcnJvclwiLCB7XG4gICAgICB0YWJsZSxcbiAgICAgIGVudGl0eUZvcmVpZ25zLFxuICAgICAgZGJGb3JlaWducyxcbiAgICB9KTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJGSyDrs4Dqsr0g7L2U65OcIOyDneyEsSDsmKTrpZhcIik7XG4gIH1cblxuICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXG4gICAgJ2ltcG9ydCB7IEtuZXggfSBmcm9tIFwia25leFwiOycsXG4gICAgXCJcIixcbiAgICBcImV4cG9ydCBhc3luYyBmdW5jdGlvbiB1cChrbmV4OiBLbmV4KTogUHJvbWlzZTx2b2lkPiB7XCIsXG4gICAgYHJldHVybiBrbmV4LnNjaGVtYS5hbHRlclRhYmxlKFwiJHt0YWJsZX1cIiwgKHRhYmxlKSA9PiB7YCxcbiAgICAuLi5saW5lc1RvLmRyb3AuZG93bixcbiAgICAuLi5saW5lc1RvLmFkZC51cCxcbiAgICAuLi5saW5lc1RvLmFsdGVyU3JjLmRvd24sXG4gICAgLi4ubGluZXNUby5hbHRlckRzdC51cCxcbiAgICBcIn0pXCIsXG4gICAgXCJ9XCIsXG4gICAgXCJcIixcbiAgICBcImV4cG9ydCBhc3luYyBmdW5jdGlvbiBkb3duKGtuZXg6IEtuZXgpOiBQcm9taXNlPHZvaWQ+IHtcIixcbiAgICBgcmV0dXJuIGtuZXguc2NoZW1hLmFsdGVyVGFibGUoXCIke3RhYmxlfVwiLCAodGFibGUpID0+IHtgLFxuICAgIC4uLmxpbmVzVG8uYWRkLmRvd24sXG4gICAgLi4ubGluZXNUby5hbHRlckRzdC5kb3duLFxuICAgIC4uLmxpbmVzVG8uYWx0ZXJTcmMudXAsXG4gICAgLi4ubGluZXNUby5kcm9wLnVwLFxuICAgIFwifSlcIixcbiAgICBcIn1cIixcbiAgXTtcblxuICBjb25zdCBmb3JtYXR0ZWQgPSBmb3JtYXRDb2RlKGxpbmVzLmpvaW4oXCJcXG5cIiksIFwidHlwZXNjcmlwdFwiLCBgc3JjL21pZ3JhdGlvbi8ke3RhYmxlfS50c2ApO1xuICBjb25zdCB0aXRsZSA9IFtcbiAgICBcImFsdGVyXCIsXG4gICAgdGFibGUsXG4gICAgXCJmb3JlaWduc1wiLFxuICAgIC8vIFRPRE8g67CU64CM64qUIOu2gOu2hFxuICBdLmpvaW4oXCJfXCIpO1xuXG4gIHJldHVybiBbXG4gICAge1xuICAgICAgdGFibGUsXG4gICAgICB0aXRsZSxcbiAgICAgIGZvcm1hdHRlZCxcbiAgICAgIHR5cGU6IFwibm9ybWFsXCIsXG4gICAgfSxcbiAgXTtcbn1cblxuLyoqXG4gKiDso7zslrTsp4QgRW50aXR5U2V07J2EIOq4sOuwmOycvOuhnCDthYzsnbTruJQgQ1JFQVRFIOuniOydtOq3uOugiOydtOyFmCDsvZTrk5zrpbwg7IOd7ISx7ZWp64uI64ukLlxuICogQHBhcmFtIGVudGl0eVNldFxuICogQHJldHVybnMgQ1JFQVRFIOuniOydtOq3uOugiOydtOyFmCDsvZTrk5xcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlQ3JlYXRlQ29kZShlbnRpdHlTZXQ6IE1pZ3JhdGlvblNldCk6IFByb21pc2U8R2VuTWlncmF0aW9uQ29kZVtdPiB7XG4gIHJldHVybiBbXG4gICAgYXdhaXQgZ2VuZXJhdGVDcmVhdGVDb2RlX0NvbHVtbkFuZEluZGV4ZXMoXG4gICAgICBlbnRpdHlTZXQudGFibGUsXG4gICAgICBlbnRpdHlTZXQuY29sdW1ucyxcbiAgICAgIGVudGl0eVNldC5pbmRleGVzLFxuICAgICksXG4gICAgLi4uKGF3YWl0IGdlbmVyYXRlQ3JlYXRlQ29kZV9Gb3JlaWduKGVudGl0eVNldC50YWJsZSwgZW50aXR5U2V0LmZvcmVpZ25zKSksXG4gIF07XG59XG5cbi8qKlxuICog7KO87Ja07KeEIGVudGl0eVNldOydhCDrqqntkZzroZwsIGRiU2V07J2EIO2YhCDsg4HtmansnLzroZwg7ZWY7JesIO2FjOydtOu4lCBBTFRFUiDrp4jsnbTqt7jroIjsnbTshZgg7L2U65Oc66W8IOyDneyEse2VqeuLiOuLpC5cbiAqIEBwYXJhbSBlbnRpdHlTZXQg7ZiEIOyDge2ZqeydmCBNaWdyYXRpb25TZXRcbiAqIEBwYXJhbSBkYlNldCDrqqntkZwg7IOB7Zmp7J2YIE1pZ3JhdGlvblNldFxuICogQHJldHVybnMgQUxURVIg66eI7J206re466CI7J207IWYIOy9lOuTnFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVBbHRlckNvZGUoXG4gIGVudGl0eVNldDogTWlncmF0aW9uU2V0LFxuICBkYlNldDogTWlncmF0aW9uU2V0LFxuKTogUHJvbWlzZTxHZW5NaWdyYXRpb25Db2RlW10+IHtcbiAgY29uc3QgcmVwbGFjZUNvbHVtbkRlZmF1bHRUbyA9IChjb2w6IE1pZ3JhdGlvbkNvbHVtbikgPT4ge1xuICAgIC8vIGZsb2F07J24IOqyveyasCDquLDrs7jqsJLsnYQgMOycvOuhnCDsp4DsoJXtlZjripQg6rK97JqwIFwiMC4wMFwi7Jy866GcIOuzgO2ZmOuQmOuKlCDsvIDsnbTsiqQg64yA7J2RXG4gICAgLy8gaWYgKGNvbC50eXBlID09PSBcImZsb2F0XCIgJiYgY29sLmRlZmF1bHRUbyAmJiBTdHJpbmcoY29sLmRlZmF1bHRUbykuaW5jbHVkZXMoJ1wiJykgPT09IGZhbHNlKSB7XG4gICAgLy8gICBjb2wuZGVmYXVsdFRvID0gYFwiJHtOdW1iZXIoY29sLmRlZmF1bHRUbykudG9GaXhlZChjb2wuc2NhbGUgPz8gMil9XCJgO1xuICAgIC8vIH1cbiAgICAvLyAvLyBzdHJpbmfsnbgg6rK97JqwIOq4sOuzuOqwkuydtCDruYgg7Iqk7Yq466eB7J24IOqyveyasCDrjIDsnZFcbiAgICAvLyBpZiAoY29sLnR5cGUgPT09IFwic3RyaW5nXCIgJiYgY29sLmRlZmF1bHRUbyA9PT0gXCJcIikge1xuICAgIC8vICAgY29sLmRlZmF1bHRUbyA9ICdcIlwiJztcbiAgICAvLyB9XG4gICAgLy8gLy8gYm9vbGVhbuyduCDqsr3smrAg6riw67O46rCSIOygleq3nO2ZlCAoTXlTUUzsl5DshJzripQgVElOWUlOVCgxKeuhnCDsoIDsnqXrkJjrr4DroZwgMCDrmJDripQgMeuhnCDsoJXqt5ztmZQpXG4gICAgLy8gLy8gVE9ETzogZGIudHPsl5AgdHlwZUNhc2Ug7ISk7KCVIO2ZleyduO2VmOyXrCDsspjrpqztlZjrj4TroZ0g7IiY7KCVIO2VhOyalFxuICAgIC8vIGlmIChjb2wudHlwZSA9PT0gXCJib29sZWFuXCIgJiYgY29sLmRlZmF1bHRUbyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgLy8gICBpZiAoY29sLmRlZmF1bHRUbyA9PT0gXCIwXCIgfHwgY29sLmRlZmF1bHRUby50b0xvd2VyQ2FzZSgpID09PSBcImZhbHNlXCIpIHtcbiAgICAvLyAgICAgY29sLmRlZmF1bHRUbyA9IFwiMFwiO1xuICAgIC8vICAgfSBlbHNlIGlmIChjb2wuZGVmYXVsdFRvID09PSBcIjFcIiB8fCBjb2wuZGVmYXVsdFRvLnRvTG93ZXJDYXNlKCkgPT09IFwidHJ1ZVwiKSB7XG4gICAgLy8gICAgIGNvbC5kZWZhdWx0VG8gPSBcIjFcIjtcbiAgICAvLyAgIH1cbiAgICAvLyB9XG5cbiAgICAvLyBGSVhNRTog7J2864uoIE15U1FMIOyDge2ZqeyXkOyEnCDrsJzsg53tlojrjZgg7J207IqI7J2YIHdvcmthcm91bmQg7J2066+A66GcIFBn7JeQ7IScIOyerO2ZleyduCDtm4Qg64yA7J2RIOy2lOqwgFxuICAgIHJldHVybiBjb2w7XG4gIH07XG4gIGNvbnN0IGVudGl0eUNvbHVtbnMgPSBhbHBoYWJldGljYWwoZW50aXR5U2V0LmNvbHVtbnMsIChhKSA9PiBhLm5hbWUpLm1hcChyZXBsYWNlQ29sdW1uRGVmYXVsdFRvKTtcbiAgY29uc3QgZGJDb2x1bW5zID0gYWxwaGFiZXRpY2FsKGRiU2V0LmNvbHVtbnMsIChhKSA9PiBhLm5hbWUpLm1hcChyZXBsYWNlQ29sdW1uRGVmYXVsdFRvKTtcblxuICAvKiDrlJTrsoTquYXsmqkg7L2U65OcLCDtirnsoJUg7Lus65+87JeQ7IScIOu2iOydvOy5mCDrsJzsg53tlaAg65WMIO2ZleyduFxuICAgICAgICBjb25zdCBlbnRpdHlDb2x1bW4gPSBlbnRpdHlTZXQuY29sdW1ucy5maW5kKFxuICAgICAgICAgIChjb2wpID0+IGNvbC5uYW1lID09PSBcInByaWNlX2tyd1wiXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGRiQ29sdW1uID0gZGJTZXQuY29sdW1ucy5maW5kKFxuICAgICAgICAgIChjb2wpID0+IGNvbC5uYW1lID09PSBcInByaWNlX2tyd1wiXG4gICAgICAgICk7XG4gICAgICAgIGNvbnNvbGUuZGVidWcoeyBlbnRpdHlDb2x1bW4sIGRiQ29sdW1uIH0pO1xuICAgICAgICAgKi9cblxuICBjb25zdCBlbnRpdHlJbmRleGVzID0gYWxwaGFiZXRpY2FsKGVudGl0eVNldC5pbmRleGVzLCAoYSkgPT5cbiAgICBbYS50eXBlLCAuLi5hLmNvbHVtbnNdLmpvaW4oXCItXCIpLFxuICApO1xuICBjb25zdCBkYkluZGV4ZXMgPSBhbHBoYWJldGljYWwoZGJTZXQuaW5kZXhlcywgKGEpID0+XG4gICAgW2EudHlwZSwgLi4uYS5jb2x1bW5zXS5qb2luKFwiLVwiKSxcbiAgKTtcblxuICBjb25zdCByZXBsYWNlTm9BY3Rpb25Pbk15U1FMID0gKGY6IE1pZ3JhdGlvbkZvcmVpZ24pID0+IHtcbiAgICAvLyBNeVNRTOyXkOyEnCBSRVNUUklDVOyZgCBOTyBBQ1RJT07snYAg64+Z7J287ZWoXG4gICAgY29uc3QgeyBvbkRlbGV0ZSwgb25VcGRhdGUgfSA9IGY7XG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmYsXG4gICAgICBvblVwZGF0ZTogb25VcGRhdGUgPT09IFwiUkVTVFJJQ1RcIiA/IFwiTk8gQUNUSU9OXCIgOiBvblVwZGF0ZSxcbiAgICAgIG9uRGVsZXRlOiBvbkRlbGV0ZSA9PT0gXCJSRVNUUklDVFwiID8gXCJOTyBBQ1RJT05cIiA6IG9uRGVsZXRlLFxuICAgIH07XG4gIH07XG5cbiAgY29uc3QgZW50aXR5Rm9yZWlnbnMgPSBhbHBoYWJldGljYWwoZW50aXR5U2V0LmZvcmVpZ25zLCAoYSkgPT5cbiAgICBbYS50bywgLi4uYS5jb2x1bW5zXS5qb2luKFwiLVwiKSxcbiAgKS5tYXAoKGYpID0+IHJlcGxhY2VOb0FjdGlvbk9uTXlTUUwoZikpO1xuICBjb25zdCBkYkZvcmVpZ25zID0gYWxwaGFiZXRpY2FsKGRiU2V0LmZvcmVpZ25zLCAoYSkgPT4gW2EudG8sIC4uLmEuY29sdW1uc10uam9pbihcIi1cIikpLm1hcCgoZikgPT5cbiAgICByZXBsYWNlTm9BY3Rpb25Pbk15U1FMKGYpLFxuICApO1xuXG4gIC8vIOyCreygnOuQoCDsu6zrn7wg66qp66GdIOqzhOyCsFxuICBjb25zdCBkcm9wcGluZ0NvbHVtbnMgPSBkaWZmKGRiQ29sdW1ucywgZW50aXR5Q29sdW1ucywgKGNvbCkgPT4gY29sLm5hbWUpO1xuXG4gIGNvbnN0IGFsdGVyQ29kZXM6IChHZW5NaWdyYXRpb25Db2RlIHwgR2VuTWlncmF0aW9uQ29kZVtdIHwgbnVsbClbXSA9IFtdO1xuXG4gIC8vIDEuIGNvbHVtbnNBbmRJbmRleGVzIOyymOumrFxuICBjb25zdCBpc0VxdWFsQ29sdW1ucyA9IGVxdWFsKGVudGl0eUNvbHVtbnMsIGRiQ29sdW1ucyk7XG4gIGNvbnN0IGlzRXF1YWxJbmRleGVzID0gZXF1YWwoXG4gICAgZW50aXR5SW5kZXhlcy5tYXAoKGluZGV4KSA9PiBvbWl0KGluZGV4LCBbXCJwYXJzZXJcIl0pKSxcbiAgICBkYkluZGV4ZXMsXG4gICk7XG4gIGlmICghaXNFcXVhbENvbHVtbnMgfHwgIWlzRXF1YWxJbmRleGVzKSB7XG4gICAgYWx0ZXJDb2Rlcy5wdXNoKFxuICAgICAgYXdhaXQgZ2VuZXJhdGVBbHRlckNvZGVfQ29sdW1uQW5kSW5kZXhlcyhcbiAgICAgICAgZW50aXR5U2V0LnRhYmxlLFxuICAgICAgICBlbnRpdHlDb2x1bW5zLFxuICAgICAgICBlbnRpdHlJbmRleGVzLFxuICAgICAgICBkYkNvbHVtbnMsXG4gICAgICAgIGRiSW5kZXhlcyxcbiAgICAgICAgZGJTZXQuZm9yZWlnbnMsXG4gICAgICApLFxuICAgICk7XG4gIH1cblxuICAvLyAyLiBmb3JlaWducyDsspjrpqwgKOyCreygnOuQoCDsu6zrn7wg7KCV67O0IOyghOuLrClcbiAgaWYgKGVxdWFsKGVudGl0eUZvcmVpZ25zLCBkYkZvcmVpZ25zKSA9PT0gZmFsc2UpIHtcbiAgICBhbHRlckNvZGVzLnB1c2goXG4gICAgICBhd2FpdCBnZW5lcmF0ZUFsdGVyQ29kZV9Gb3JlaWducyhcbiAgICAgICAgZW50aXR5U2V0LnRhYmxlLFxuICAgICAgICBlbnRpdHlGb3JlaWducyxcbiAgICAgICAgZGJGb3JlaWducyxcbiAgICAgICAgZHJvcHBpbmdDb2x1bW5zLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgaWYgKGFsdGVyQ29kZXMuZXZlcnkoKGFsdGVyQ29kZSkgPT4gYWx0ZXJDb2RlID09PSBudWxsKSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHJldHVybiBhbHRlckNvZGVzLmZpbHRlcigoYWx0ZXJDb2RlKSA9PiBhbHRlckNvZGUgIT09IG51bGwpLmZsYXQoKTtcbn1cbiJdLCJuYW1lcyI6WyJlcXVhbCIsImFscGhhYmV0aWNhbCIsImRpZmYiLCJmb3JrIiwib21pdCIsIk5haXRlIiwiZm9ybWF0Q29kZSIsImRpZmZlcmVuY2VXaXRoIiwiaW50ZXJzZWN0aW9uQnkiLCJnZW5lcmF0ZUNyZWF0ZUNvZGVfQ29sdW1uQW5kSW5kZXhlcyIsInRhYmxlIiwiY29sdW1ucyIsImluZGV4ZXMiLCJuZ3JhbUluZGV4ZXMiLCJzdGFuZGFyZEluZGV4ZXMiLCJpIiwidHlwZSIsInBhcnNlciIsImxpbmVzIiwiZ2VuQ29sdW1uRGVmaW5pdGlvbnMiLCJtYXAiLCJpbmRleCIsImdlbkluZGV4RGVmaW5pdGlvbiIsInRpdGxlIiwiZm9ybWF0dGVkIiwiam9pbiIsImNvbHVtbiIsImNoYWlucyIsIm5hbWUiLCJlbmRzV2l0aCIsImVsZW1lbnRUeXBlIiwic2xpY2UiLCJwZ1R5cGUiLCJnZXRQZ0FycmF5VHlwZSIsInB1c2giLCJudW1iZXJUeXBlIiwicHJlY2lzaW9uIiwic2NhbGUiLCJsZW5ndGgiLCJ1bmRlZmluZWQiLCJleHRyYVR5cGUiLCJudWxsYWJsZSIsImRlZmF1bHRUbyIsInN0YXJ0c1dpdGgiLCJFcnJvciIsIm1ldGhvZE1hcCIsImZ1bGx0ZXh0IiwidW5pcXVlIiwiY29sIiwiZ2VuZXJhdGVDcmVhdGVDb2RlX0ZvcmVpZ24iLCJmb3JlaWducyIsInVwIiwiZG93biIsImdlbkZvcmVpZ25EZWZpbml0aW9ucyIsImNvbnNvbGUiLCJsb2ciLCJmb3JlaWduS2V5c1N0cmluZyIsImZvcmVpZ24iLCJyZWR1Y2UiLCJyIiwiY29sdW1uc1N0cmluZ1F1b3RlIiwicmVwbGFjZSIsInRvIiwib25VcGRhdGUiLCJvbkRlbGV0ZSIsImdlbmVyYXRlQWx0ZXJDb2RlX0NvbHVtbkFuZEluZGV4ZXMiLCJlbnRpdHlDb2x1bW5zIiwiZW50aXR5SW5kZXhlcyIsImRiQ29sdW1ucyIsImRiSW5kZXhlcyIsImRiRm9yZWlnbnMiLCJhbHRlckNvbHVtbnNUbyIsImdldEFsdGVyQ29sdW1uc1RvIiwiYWx0ZXJDb2x1bW5MaW5lc1RvIiwiZ2V0QWx0ZXJDb2x1bW5MaW5lc1RvIiwiYWx0ZXJJbmRleGVzVG8iLCJnZXRBbHRlckluZGV4ZXNUbyIsImFkZCIsImluZGV4TmVlZHNUb0Ryb3AiLCJkcm9wIiwiZmlsdGVyIiwiZXZlcnkiLCJjb2xOYW1lIiwiaW5jbHVkZXMiLCJhbHRlciIsInQiLCJnZW5JbmRleERyb3BEZWZpbml0aW9uIiwiYWN0aW9uIiwibGVuIiwicGFydCIsImNvbHVtbnNUbyIsImV4dHJhQ29sdW1ucyIsImRiIiwiZW50aXR5IiwiY29uY2F0Iiwic2FtZURiQ29sdW1ucyIsInNhbWVNZENvbHVtbnMiLCJhIiwiYiIsImxpbmVzVG8iLCJkcm9wQ29sdW1uTmFtZXMiLCJma1RvRHJvcEJlZm9yZUNvbHVtbiIsImZrIiwic29tZSIsImRyb3BGa0xpbmVzIiwicmVzdG9yZUZrTGluZXMiLCJkYkNvbHVtbiIsImVudGl0eUNvbHVtbiIsImZpbmQiLCJjb2x1bW5EaWZmVXAiLCJjb2x1bW5EaWZmRG93biIsImwiLCJpbmRleGVzVG8iLCJleHRyYUluZGV4ZXMiLCJjb2x1bW5OYW1lIiwiZ2VuZXJhdGVBbHRlckNvZGVfRm9yZWlnbnMiLCJlbnRpdHlGb3JlaWducyIsImRyb3BwaW5nQ29sdW1ucyIsImdldEtleSIsIm1mIiwiZHJvcHBpbmdDb2x1bW5OYW1lcyIsImZrVG8iLCJyZXN1bHQiLCJlbnRpdHlGIiwibWF0Y2hpbmdEYkYiLCJkYkYiLCJhbHRlclNyYyIsImFsdGVyRHN0IiwiZm9yRWFjaCIsIm1hdGNoaW5nRW50aXR5RiIsImlzQ29sdW1uRHJvcHBpbmciLCJoYXNMaW5lcyIsIk9iamVjdCIsInZhbHVlcyIsImdlbmVyYXRlQ3JlYXRlQ29kZSIsImVudGl0eVNldCIsImdlbmVyYXRlQWx0ZXJDb2RlIiwiZGJTZXQiLCJyZXBsYWNlQ29sdW1uRGVmYXVsdFRvIiwicmVwbGFjZU5vQWN0aW9uT25NeVNRTCIsImYiLCJhbHRlckNvZGVzIiwiaXNFcXVhbENvbHVtbnMiLCJpc0VxdWFsSW5kZXhlcyIsImFsdGVyQ29kZSIsImZsYXQiXSwibWFwcGluZ3MiOiJBQUFBLE9BQU9BLFdBQVcsa0JBQWtCO0FBQ3BDLFNBQVNDLFlBQVksRUFBRUMsSUFBSSxFQUFFQyxJQUFJLEVBQUVDLElBQUksUUFBUSxVQUFVO0FBQ3pELFNBQVNDLEtBQUssUUFBUSxjQUFLO0FBUTNCLFNBQVNDLFVBQVUsUUFBUSx3QkFBcUI7QUFDaEQsU0FBU0MsY0FBYyxFQUFFQyxjQUFjLFFBQVEsb0JBQWlCO0FBRWhFOztDQUVDLEdBQ0QsZUFBZUMsb0NBQ2JDLEtBQWEsRUFDYkMsT0FBMEIsRUFDMUJDLE9BQXlCO0lBRXpCLG9CQUFvQjtJQUNwQixNQUFNLENBQUNDLGNBQWNDLGdCQUFnQixHQUFHWCxLQUN0Q1MsU0FDQSxDQUFDRyxJQUFNQSxFQUFFQyxJQUFJLEtBQUssY0FBY0QsRUFBRUUsTUFBTSxLQUFLO0lBRy9DLGFBQWE7SUFDYixNQUFNQyxRQUFrQjtRQUN0QjtRQUNBO1FBQ0E7UUFDQSxDQUFDLCtCQUErQixFQUFFUixNQUFNLGVBQWUsQ0FBQztRQUN4RDtXQUNHUyxxQkFBcUJSO1FBQ3hCO1FBQ0E7V0FDR0csZ0JBQWdCTSxHQUFHLENBQUMsQ0FBQ0MsUUFBVUMsbUJBQW1CRCxPQUFPWDtRQUM1RDtRQUNBLDRDQUE0QztXQUN6Q0csYUFBYU8sR0FBRyxDQUFDLENBQUNDLFFBQVVDLG1CQUFtQkQsT0FBT1g7UUFDekQ7UUFDQTtRQUNBO1FBQ0EsQ0FBQywrQkFBK0IsRUFBRUEsTUFBTSxHQUFHLENBQUM7UUFDNUM7S0FDRDtJQUNELE9BQU87UUFDTEE7UUFDQU0sTUFBTTtRQUNOTyxPQUFPLENBQUMsUUFBUSxFQUFFYixPQUFPO1FBQ3pCYyxXQUFXbEIsV0FBV1ksTUFBTU8sSUFBSSxDQUFDLE9BQU8sY0FBYyxDQUFDLGNBQWMsRUFBRWYsTUFBTSxHQUFHLENBQUM7SUFDbkY7QUFDRjtBQUVBOztDQUVDLEdBQ0QsU0FBU1MscUJBQXFCUixPQUEwQjtJQUN0RCxPQUFPQSxRQUFRUyxHQUFHLENBQUMsQ0FBQ007UUFDbEIsTUFBTUMsU0FBbUIsRUFBRTtRQUMzQixJQUFJRCxPQUFPRSxJQUFJLEtBQUssTUFBTTtZQUN4QixPQUFPLENBQUMsNkJBQTZCLENBQUM7UUFDeEM7UUFFQSxXQUFXO1FBQ1gsSUFBSUYsT0FBT1YsSUFBSSxDQUFDYSxRQUFRLENBQUMsT0FBTztZQUM5QixNQUFNQyxjQUFjSixPQUFPVixJQUFJLENBQUNlLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSwyQkFBMkI7WUFDekUsTUFBTUMsU0FBU0MsZUFBZVAsUUFBUUk7WUFDdENILE9BQU9PLElBQUksQ0FBQyxDQUFDLGNBQWMsRUFBRVIsT0FBT0UsSUFBSSxDQUFDLElBQUksRUFBRUksT0FBTyxFQUFFLENBQUM7UUFDM0QsT0FBTyxJQUFJTixPQUFPVixJQUFJLEtBQUssbUJBQW1CO1lBQzVDLFNBQVM7WUFDVCxJQUFJVSxPQUFPUyxVQUFVLEtBQUssUUFBUTtnQkFDaENSLE9BQU9PLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRVIsT0FBT0UsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUN2QyxPQUFPLElBQUlGLE9BQU9TLFVBQVUsS0FBSyxvQkFBb0I7Z0JBQ25EUixPQUFPTyxJQUFJLENBQUMsQ0FBQyxRQUFRLEVBQUVSLE9BQU9FLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDeEMsT0FBTyxJQUFJLEFBQUNGLENBQUFBLE9BQU9TLFVBQVUsSUFBSSxTQUFRLE1BQU8sV0FBVztnQkFDekRSLE9BQU9PLElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRVIsT0FBT0UsSUFBSSxDQUFDLEdBQUcsRUFBRUYsT0FBT1UsU0FBUyxDQUFDLEVBQUUsRUFBRVYsT0FBT1csS0FBSyxDQUFDLENBQUMsQ0FBQztZQUMvRTtRQUNGLE9BQU8sSUFBSVgsT0FBT1YsSUFBSSxLQUFLLFVBQVU7WUFDbkMsU0FBUztZQUNULElBQUlVLE9BQU9ZLE1BQU0sS0FBS0MsV0FBVztnQkFDL0JaLE9BQU9PLElBQUksQ0FBQyxDQUFDLFFBQVEsRUFBRVIsT0FBT0UsSUFBSSxDQUFDLEdBQUcsRUFBRUYsT0FBT1ksTUFBTSxDQUFDLENBQUMsQ0FBQztZQUMxRCxPQUFPO2dCQUNMWCxPQUFPTyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUVSLE9BQU9FLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDdEM7UUFDRixPQUFPLElBQUlGLE9BQU9WLElBQUksS0FBSyxRQUFRO1lBQ2pDLE9BQU87WUFDUFcsT0FBT08sSUFBSSxDQUFDLENBQUMsV0FBVyxFQUFFUixPQUFPRSxJQUFJLENBQUMsbUJBQW1CLENBQUM7UUFDNUQsT0FBTyxJQUFJRixPQUFPVixJQUFJLEtBQUssUUFBUTtZQUNqQyxPQUFPO1lBQ1BXLE9BQU9PLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRVIsT0FBT0UsSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUN2QyxPQUFPO1lBQ0wsZUFBZTtZQUNmLElBQUlZO1lBQ0piLE9BQU9PLElBQUksQ0FDVCxHQUFHUixPQUFPVixJQUFJLENBQUMsRUFBRSxFQUFFVSxPQUFPRSxJQUFJLENBQUMsQ0FBQyxFQUM5QkYsT0FBT1ksTUFBTSxHQUFHLENBQUMsRUFBRSxFQUFFWixPQUFPWSxNQUFNLEVBQUUsR0FBRyxLQUN0Q0UsWUFBWSxDQUFDLEdBQUcsRUFBRUEsVUFBVSxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUU3QztRQUVBLFdBQVc7UUFDWGIsT0FBT08sSUFBSSxDQUFDUixPQUFPZSxRQUFRLEdBQUcsZUFBZTtRQUU3QyxZQUFZO1FBQ1osSUFBSWYsT0FBT2dCLFNBQVMsS0FBS0gsV0FBVztZQUNsQyxJQUFJLE9BQU9iLE9BQU9nQixTQUFTLEtBQUssWUFBWWhCLE9BQU9nQixTQUFTLENBQUNDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHO2dCQUM1RWhCLE9BQU9PLElBQUksQ0FBQyxDQUFDLFVBQVUsRUFBRVIsT0FBT2dCLFNBQVMsQ0FBQyxDQUFDLENBQUM7WUFDOUMsT0FBTztnQkFDTGYsT0FBT08sSUFBSSxDQUFDLENBQUMsb0JBQW9CLEVBQUVSLE9BQU9nQixTQUFTLENBQUMsR0FBRyxDQUFDO1lBQzFEO1FBQ0Y7UUFFQSxPQUFPLENBQUMsTUFBTSxFQUFFZixPQUFPRixJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDckM7QUFDRjtBQUVBLFNBQVNRLGVBQWVQLE1BQXVCLEVBQUVJLFdBQW1CO0lBQ2xFLElBQUlBLGdCQUFnQixtQkFBbUI7UUFDckMsSUFBSUosT0FBT1MsVUFBVSxLQUFLLFFBQVEsT0FBTztRQUN6QyxJQUFJVCxPQUFPUyxVQUFVLEtBQUssb0JBQW9CLE9BQU87UUFDckQsT0FBTyxDQUFDLFFBQVEsRUFBRVQsT0FBT1UsU0FBUyxDQUFDLEVBQUUsRUFBRVYsT0FBT1csS0FBSyxDQUFDLEdBQUcsQ0FBQztJQUMxRDtJQUNBLElBQUlQLGdCQUFnQixVQUFVO1FBQzVCLE9BQU9KLE9BQU9ZLE1BQU0sR0FBRyxDQUFDLFFBQVEsRUFBRVosT0FBT1ksTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHO0lBQ3pEO0lBQ0EsSUFBSVIsZ0JBQWdCLFFBQVEsT0FBTztJQUNuQyxJQUFJQSxnQkFBZ0IsV0FBVyxPQUFPO0lBQ3RDLElBQUlBLGdCQUFnQixjQUFjLE9BQU87SUFDekMsSUFBSUEsZ0JBQWdCLFdBQVcsT0FBTztJQUN0QyxJQUFJQSxnQkFBZ0IsUUFBUSxPQUFPO0lBQ25DLElBQUlBLGdCQUFnQixRQUFRLE9BQU87SUFFbkMsTUFBTSxJQUFJYyxNQUFNLENBQUMsNEJBQTRCLEVBQUVkLGFBQWE7QUFDOUQ7QUFFQTs7Q0FFQyxHQUNELFNBQVNSLG1CQUFtQkQsS0FBcUIsRUFBRVgsS0FBYTtJQUM5RCxNQUFNbUMsWUFBWTtRQUNoQnhCLE9BQU87UUFDUHlCLFVBQVU7UUFDVkMsUUFBUTtJQUNWO0lBRUEsSUFBSTFCLE1BQU1MLElBQUksS0FBSyxjQUFjSyxNQUFNSixNQUFNLEtBQUssU0FBUztRQUN6RCxPQUFPLENBQUMsNkJBQTZCLEVBQUVQLE1BQU0sb0JBQW9CLEVBQUVXLE1BQU1PLElBQUksQ0FBQyxFQUFFLEVBQUVQLE1BQU1WLE9BQU8sQ0FBQ2MsSUFBSSxDQUNsRyxNQUNBLHVCQUF1QixDQUFDO0lBQzVCO0lBRUEsT0FBTyxDQUFDLE1BQU0sRUFBRW9CLFNBQVMsQ0FBQ3hCLE1BQU1MLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRUssTUFBTVYsT0FBTyxDQUNwRFMsR0FBRyxDQUFDLENBQUM0QixNQUFRLENBQUMsQ0FBQyxFQUFFQSxJQUFJLENBQUMsQ0FBQyxFQUN2QnZCLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRUosTUFBTU8sSUFBSSxDQUFDLENBQUMsRUFBRVAsTUFBTUwsSUFBSSxLQUFLLGFBQWEsaUJBQWlCLEdBQUc7SUFDL0UsQ0FBQztBQUNMO0FBRUE7O0NBRUMsR0FDRCxlQUFlaUMsMkJBQ2J2QyxLQUFhLEVBQ2J3QyxRQUE0QjtJQUU1QixJQUFJQSxTQUFTWixNQUFNLEtBQUssR0FBRztRQUN6QixPQUFPLEVBQUU7SUFDWDtJQUVBLE1BQU0sRUFBRWEsRUFBRSxFQUFFQyxJQUFJLEVBQUUsR0FBR0Msc0JBQXNCM0MsT0FBT3dDO0lBQ2xELElBQUlDLEdBQUdiLE1BQU0sS0FBSyxLQUFLYyxLQUFLZCxNQUFNLEtBQUssR0FBRztRQUN4Q2dCLFFBQVFDLEdBQUcsQ0FBQztRQUNaLE9BQU8sRUFBRTtJQUNYO0lBRUEsTUFBTXJDLFFBQWtCO1FBQ3RCO1FBQ0E7UUFDQTtRQUNBLENBQUMsK0JBQStCLEVBQUVSLE1BQU0sZUFBZSxDQUFDO1FBQ3hEO1dBQ0d5QztRQUNIO1FBQ0E7UUFDQTtRQUNBO1FBQ0EsQ0FBQywrQkFBK0IsRUFBRXpDLE1BQU0sZUFBZSxDQUFDO1FBQ3hEO1dBQ0cwQztRQUNIO1FBQ0E7S0FDRDtJQUVELE1BQU1JLG9CQUFvQk4sU0FBUzlCLEdBQUcsQ0FBQyxDQUFDcUMsVUFBWUEsUUFBUTlDLE9BQU8sQ0FBQ2MsSUFBSSxDQUFDLE1BQU1BLElBQUksQ0FBQztJQUNwRixPQUFPO1FBQ0w7WUFDRWY7WUFDQU0sTUFBTTtZQUNOTyxPQUFPLENBQUMsU0FBUyxFQUFFYixNQUFNLEVBQUUsRUFBRThDLG1CQUFtQjtZQUNoRGhDLFdBQVdsQixXQUFXWSxNQUFNTyxJQUFJLENBQUMsT0FBTyxjQUFjLENBQUMsY0FBYyxFQUFFZixNQUFNLEdBQUcsQ0FBQztRQUNuRjtLQUNEO0FBQ0g7QUFFQTs7Q0FFQyxHQUNELFNBQVMyQyxzQkFDUDNDLEtBQWEsRUFDYndDLFFBQTRCO0lBRTVCLE9BQU9BLFNBQVNRLE1BQU0sQ0FDcEIsQ0FBQ0MsR0FBR0Y7UUFDRixNQUFNRyxxQkFBcUJILFFBQVE5QyxPQUFPLENBQ3ZDUyxHQUFHLENBQUMsQ0FBQzRCLE1BQVEsQ0FBQyxDQUFDLEVBQUVBLElBQUlhLE9BQU8sQ0FBQyxHQUFHbkQsTUFBTSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxFQUNoRGUsSUFBSSxDQUFDO1FBQ1JrQyxFQUFFUixFQUFFLENBQUNqQixJQUFJLENBQ1AsQ0FBQyxlQUFlLEVBQUV1QixRQUFROUMsT0FBTyxDQUFDYyxJQUFJLENBQUMsS0FBSzt5QkFDM0IsRUFBRWdDLFFBQVFLLEVBQUUsQ0FBQzt1QkFDZixFQUFFTCxRQUFRTSxRQUFRLENBQUM7dUJBQ25CLEVBQUVOLFFBQVFPLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFFdkNMLEVBQUVQLElBQUksQ0FBQ2xCLElBQUksQ0FBQyxDQUFDLG1CQUFtQixFQUFFMEIsbUJBQW1CLEVBQUUsQ0FBQztRQUN4RCxPQUFPRDtJQUNULEdBQ0E7UUFDRVIsSUFBSSxFQUFFO1FBQ05DLE1BQU0sRUFBRTtJQUNWO0FBRUo7QUFFQTs7Q0FFQyxHQUNELGVBQWVhLG1DQUNidkQsS0FBYSxFQUNid0QsYUFBZ0MsRUFDaENDLGFBQStCLEVBQy9CQyxTQUE0QixFQUM1QkMsU0FBMkIsRUFDM0JDLFVBQThCO0lBRTlCOzs7Ozs7Ozs7O0VBVUEsR0FFQSxzQ0FBc0M7SUFDdEMsTUFBTUMsaUJBQWlCQyxrQkFBa0JOLGVBQWVFO0lBRXhELHlCQUF5QjtJQUN6QixNQUFNSyxxQkFBcUJDLHNCQUN6QkgsZ0JBQ0FMLGVBQ0F4RCxPQUNBNEQ7SUFHRix1QkFBdUI7SUFDdkIsTUFBTUssaUJBQWlCQyxrQkFBa0JULGVBQWVFO0lBRXhELG9CQUFvQjtJQUNwQixNQUFNLENBQUN4RCxjQUFjQyxnQkFBZ0IsR0FBR1gsS0FDdEN3RSxlQUFlRSxHQUFHLEVBQ2xCLENBQUM5RCxJQUFNQSxFQUFFQyxJQUFJLEtBQUssY0FBY0QsRUFBRUUsTUFBTSxLQUFLO0lBRy9DLCtDQUErQztJQUMvQyxNQUFNNkQsbUJBQW1CSCxlQUFlSSxJQUFJLENBQUNDLE1BQU0sQ0FDakQsQ0FBQzNELFFBQ0NBLE1BQU1WLE9BQU8sQ0FBQ3NFLEtBQUssQ0FBQyxDQUFDQyxVQUNuQlgsZUFBZVEsSUFBSSxDQUFDM0QsR0FBRyxDQUFDLENBQUM0QixNQUFRQSxJQUFJcEIsSUFBSSxFQUFFdUQsUUFBUSxDQUFDRCxjQUNoRDtJQUdWLGFBQWE7SUFDYixJQUNFVCxtQkFBbUJJLEdBQUcsQ0FBQzFCLEVBQUUsQ0FBQ2IsTUFBTSxLQUFLLEtBQ3JDbUMsbUJBQW1CTSxJQUFJLENBQUM1QixFQUFFLENBQUNiLE1BQU0sS0FBSyxLQUN0Q21DLG1CQUFtQlcsS0FBSyxDQUFDakMsRUFBRSxDQUFDYixNQUFNLEtBQUssS0FDdkN4QixnQkFBZ0J3QixNQUFNLEtBQUssS0FDM0J3QyxpQkFBaUJ4QyxNQUFNLEtBQUssR0FDNUI7UUFDQWpDLE1BQU1nRixDQUFDLENBQUMsd0VBQXdFO1lBQzlFbkI7WUFDQUU7WUFDQUQ7WUFDQUU7UUFDRjtJQUNBLHlDQUF5QztJQUMzQztJQUNBaEUsTUFBTWdGLENBQUMsQ0FBQyxxREFBcUQ7UUFDM0QsNkJBQTZCZCxlQUFlTSxHQUFHLENBQUN2QyxNQUFNO1FBQ3RELDhCQUE4QmlDLGVBQWVRLElBQUksQ0FBQ3pDLE1BQU07UUFDeEQsK0JBQStCaUMsZUFBZWEsS0FBSyxDQUFDOUMsTUFBTTtRQUMxRCw2QkFBNkJxQyxlQUFlRSxHQUFHLENBQUN2QyxNQUFNO1FBQ3RELDhCQUE4QnFDLGVBQWVJLElBQUksQ0FBQ3pDLE1BQU07UUFDeEQsMEJBQTBCeEIsZ0JBQWdCd0IsTUFBTTtRQUNoRCwyQkFBMkJ3QyxpQkFBaUJ4QyxNQUFNO0lBQ3BEO0lBQ0EseUZBQXlGO0lBRXpGLHVCQUF1QjtJQUV2QixNQUFNcEIsUUFBa0I7UUFDdEI7UUFDQTtRQUNBO1FBQ0EsQ0FBQyw4QkFBOEIsRUFBRVIsTUFBTSxlQUFlLENBQUM7UUFDdkQsZ0JBQWdCO1dBQ1o2RCxlQUFlTSxHQUFHLENBQUN2QyxNQUFNLEdBQUcsSUFBSW1DLG1CQUFtQkksR0FBRyxDQUFDMUIsRUFBRSxHQUFHLEVBQUU7UUFDbEUsaUJBQWlCO1dBQ2JvQixlQUFlUSxJQUFJLENBQUN6QyxNQUFNLEdBQUcsSUFBSW1DLG1CQUFtQk0sSUFBSSxDQUFDNUIsRUFBRSxHQUFHLEVBQUU7UUFDcEUsa0JBQWtCO1dBQ2RvQixlQUFlYSxLQUFLLENBQUM5QyxNQUFNLEdBQUcsSUFBSW1DLG1CQUFtQlcsS0FBSyxDQUFDakMsRUFBRSxHQUFHLEVBQUU7UUFDdEUsZUFBZTtXQUNackMsZ0JBQWdCTSxHQUFHLENBQUMsQ0FBQ0MsUUFBVUMsbUJBQW1CRCxPQUFPWDtRQUM1RCxnQkFBZ0I7V0FDYm9FLGlCQUFpQjFELEdBQUcsQ0FBQ2tFO1FBQ3hCO1FBQ0EsMkNBQTJDO1dBQ3hDekUsYUFBYU8sR0FBRyxDQUFDLENBQUNDLFFBQVVDLG1CQUFtQkQsT0FBT1g7UUFDekQ7UUFDQTtRQUNBO1FBQ0EsQ0FBQywrQkFBK0IsRUFBRUEsTUFBTSxlQUFlLENBQUM7V0FDcEQ2RCxlQUFlTSxHQUFHLENBQUN2QyxNQUFNLEdBQUcsSUFBSW1DLG1CQUFtQkksR0FBRyxDQUFDekIsSUFBSSxHQUFHLEVBQUU7V0FDaEVtQixlQUFlUSxJQUFJLENBQUN6QyxNQUFNLEdBQUcsSUFBSW1DLG1CQUFtQk0sSUFBSSxDQUFDM0IsSUFBSSxHQUFHLEVBQUU7V0FDbEVtQixlQUFlYSxLQUFLLENBQUM5QyxNQUFNLEdBQUcsSUFBSW1DLG1CQUFtQlcsS0FBSyxDQUFDaEMsSUFBSSxHQUFHLEVBQUU7V0FDckV1QixlQUFlRSxHQUFHLENBQ2xCRyxNQUFNLENBQ0wsQ0FBQzNELFFBQ0NBLE1BQU1WLE9BQU8sQ0FBQ3NFLEtBQUssQ0FBQyxDQUFDQyxVQUNuQlgsZUFBZU0sR0FBRyxDQUFDekQsR0FBRyxDQUFDLENBQUM0QixNQUFRQSxJQUFJcEIsSUFBSSxFQUFFdUQsUUFBUSxDQUFDRCxjQUMvQyxPQUVUOUQsR0FBRyxDQUFDa0U7V0FDSlIsaUJBQWlCMUQsR0FBRyxDQUFDLENBQUNDLFFBQVVDLG1CQUFtQkQsT0FBT1g7UUFDN0Q7UUFDQTtLQUNEO0lBRUQsTUFBTWMsWUFBWWxCLFdBQVdZLE1BQU1PLElBQUksQ0FBQyxPQUFPLGNBQWMsQ0FBQyxjQUFjLEVBQUVmLE1BQU0sR0FBRyxDQUFDO0lBQ3hGLE1BQU1hLFFBQVE7UUFDWjtRQUNBYjtXQUNHLEFBQUM7WUFBQztZQUFPO1lBQVE7U0FBUSxDQUN6QlUsR0FBRyxDQUFDLENBQUNtRTtZQUNKLE1BQU1DLE1BQU1qQixjQUFjLENBQUNnQixPQUFPLENBQUNqRCxNQUFNO1lBQ3pDLElBQUlrRCxNQUFNLEdBQUc7Z0JBQ1gsT0FBT0QsU0FBU0M7WUFDbEI7WUFDQSxPQUFPO1FBQ1QsR0FDQ1IsTUFBTSxDQUFDLENBQUNTLE9BQVNBLFNBQVM7S0FDOUIsQ0FBQ2hFLElBQUksQ0FBQztJQUVQLE9BQU87UUFDTDtZQUNFZjtZQUNBYTtZQUNBQztZQUNBUixNQUFNO1FBQ1I7S0FDRDtBQUNIO0FBRUE7O0NBRUMsR0FDRCxTQUFTd0Qsa0JBQWtCTixhQUFnQyxFQUFFRSxTQUE0QjtJQUN2RixNQUFNc0IsWUFBWTtRQUNoQmIsS0FBSyxFQUFFO1FBQ1BFLE1BQU0sRUFBRTtRQUNSSyxPQUFPLEVBQUU7SUFDWDtJQUVBLFlBQVk7SUFDWixNQUFNTyxlQUFlO1FBQ25CQyxJQUFJMUYsS0FBS2tFLFdBQVdGLGVBQWUsQ0FBQ2xCLE1BQVFBLElBQUlwQixJQUFJO1FBQ3BEaUUsUUFBUTNGLEtBQUtnRSxlQUFlRSxXQUFXLENBQUNwQixNQUFRQSxJQUFJcEIsSUFBSTtJQUMxRDtJQUNBLElBQUkrRCxhQUFhRSxNQUFNLENBQUN2RCxNQUFNLEdBQUcsR0FBRztRQUNsQ29ELFVBQVViLEdBQUcsR0FBR2EsVUFBVWIsR0FBRyxDQUFDaUIsTUFBTSxDQUFDSCxhQUFhRSxNQUFNO0lBQzFEO0lBQ0EsSUFBSUYsYUFBYUMsRUFBRSxDQUFDdEQsTUFBTSxHQUFHLEdBQUc7UUFDOUJvRCxVQUFVWCxJQUFJLEdBQUdXLFVBQVVYLElBQUksQ0FBQ2UsTUFBTSxDQUFDSCxhQUFhQyxFQUFFO0lBQ3hEO0lBRUEsbUJBQW1CO0lBQ25CLE1BQU1HLGdCQUFnQnZGLGVBQWU0RCxXQUFXRixlQUFlLENBQUNsQixNQUFRQSxJQUFJcEIsSUFBSTtJQUNoRixNQUFNb0UsZ0JBQWdCeEYsZUFBZTBELGVBQWVFLFdBQVcsQ0FBQ3BCLE1BQVFBLElBQUlwQixJQUFJO0lBQ2hGOEQsVUFBVU4sS0FBSyxHQUFHN0UsZUFBZXdGLGVBQWVDLGVBQWUsQ0FBQ0MsR0FBR0MsSUFBTWxHLE1BQU1pRyxHQUFHQztJQUVsRixPQUFPUjtBQUNUO0FBRUE7O0NBRUMsR0FDRCxTQUFTaEIsc0JBQ1BnQixTQUErQyxFQUMvQ3hCLGFBQWdDLEVBQ2hDeEQsS0FBYSxFQUNiNEQsVUFBOEI7SUFFOUIsTUFBTTZCLFVBQVU7UUFDZHRCLEtBQUs7WUFDSDFCLElBQUksRUFBRTtZQUNOQyxNQUFNLEVBQUU7UUFDVjtRQUNBMkIsTUFBTTtZQUNKNUIsSUFBSSxFQUFFO1lBQ05DLE1BQU0sRUFBRTtRQUNWO1FBQ0FnQyxPQUFPO1lBQ0xqQyxJQUFJLEVBQUU7WUFDTkMsTUFBTSxFQUFFO1FBQ1Y7SUFDRjtJQUVBK0MsUUFBUXRCLEdBQUcsR0FBRztRQUNaMUIsSUFBSTtZQUFDO2VBQWFoQyxxQkFBcUJ1RSxVQUFVYixHQUFHO1NBQUU7UUFDdER6QixNQUFNO1lBQ0o7WUFDQSxDQUFDLGtCQUFrQixFQUFFc0MsVUFBVWIsR0FBRyxDQUFDekQsR0FBRyxDQUFDLENBQUM0QixNQUFRLENBQUMsQ0FBQyxFQUFFQSxJQUFJcEIsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFSCxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDL0U7SUFDSDtJQUVBLHFCQUFxQjtJQUNyQixNQUFNMkUsa0JBQWtCVixVQUFVWCxJQUFJLENBQUMzRCxHQUFHLENBQUMsQ0FBQzRCLE1BQVFBLElBQUlwQixJQUFJO0lBQzVELE1BQU15RSx1QkFBdUIvQixXQUFXVSxNQUFNLENBQUMsQ0FBQ3NCLEtBQzlDQSxHQUFHM0YsT0FBTyxDQUFDNEYsSUFBSSxDQUFDLENBQUN2RCxNQUFRb0QsZ0JBQWdCakIsUUFBUSxDQUFDbkM7SUFHcEQsTUFBTXdELGNBQWNILHFCQUFxQmpGLEdBQUcsQ0FBQyxDQUFDa0Y7UUFDNUMsTUFBTTFDLHFCQUFxQjBDLEdBQUczRixPQUFPLENBQUNTLEdBQUcsQ0FBQyxDQUFDNEIsTUFBUSxDQUFDLENBQUMsRUFBRUEsSUFBSSxDQUFDLENBQUMsRUFBRXZCLElBQUksQ0FBQztRQUNwRSxPQUFPLENBQUMsbUJBQW1CLEVBQUVtQyxtQkFBbUIsRUFBRSxDQUFDO0lBQ3JEO0lBRUEsTUFBTTZDLGlCQUFpQnBELHNCQUFzQjNDLE9BQU8yRixzQkFBc0JsRCxFQUFFO0lBRTVFZ0QsUUFBUXBCLElBQUksR0FBRztRQUNiNUIsSUFBSTtlQUNFcUQsWUFBWWxFLE1BQU0sR0FBRyxJQUNyQjtnQkFBQzttQkFBb0RrRTthQUFZLEdBQ2pFLEVBQUU7WUFDTjtZQUNBLENBQUMsa0JBQWtCLEVBQUVkLFVBQVVYLElBQUksQ0FBQzNELEdBQUcsQ0FBQyxDQUFDNEIsTUFBUSxDQUFDLENBQUMsRUFBRUEsSUFBSXBCLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRUgsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQ2hGO1FBQ0QyQixNQUFNO1lBQ0o7ZUFDR2pDLHFCQUFxQnVFLFVBQVVYLElBQUk7ZUFDbEMwQixlQUFlbkUsTUFBTSxHQUFHLElBQUk7Z0JBQUM7bUJBQThCbUU7YUFBZSxHQUFHLEVBQUU7U0FDcEY7SUFDSDtJQUNBTixRQUFRZixLQUFLLEdBQUdNLFVBQVVOLEtBQUssQ0FBQzFCLE1BQU0sQ0FDcEMsQ0FBQ0MsR0FBRytDO1FBQ0YsTUFBTUMsZUFBZXpDLGNBQWMwQyxJQUFJLENBQUMsQ0FBQzVELE1BQVFBLElBQUlwQixJQUFJLEtBQUs4RSxTQUFTOUUsSUFBSTtRQUMzRSxJQUFJK0UsaUJBQWlCcEUsV0FBVztZQUM5QixPQUFPb0I7UUFDVDtRQUVBLFVBQVU7UUFDVixNQUFNa0QsZUFBZTNHLEtBQ25CaUIscUJBQXFCO1lBQUN3RjtTQUFhLEdBQ25DeEYscUJBQXFCO1lBQUN1RjtTQUFTO1FBRWpDLE1BQU1JLGlCQUFpQjVHLEtBQ3JCaUIscUJBQXFCO1lBQUN1RjtTQUFTLEdBQy9CdkYscUJBQXFCO1lBQUN3RjtTQUFhO1FBRXJDLElBQUlFLGFBQWF2RSxNQUFNLEdBQUcsR0FBRztZQUMzQnFCLEVBQUVSLEVBQUUsR0FBRzttQkFDRlEsRUFBRVIsRUFBRTtnQkFDUDttQkFDRzBELGFBQWF6RixHQUFHLENBQUMsQ0FBQzJGLElBQU0sR0FBR0EsRUFBRWxELE9BQU8sQ0FBQyxLQUFLLElBQUksU0FBUyxDQUFDO2FBQzVEO1lBQ0RGLEVBQUVQLElBQUksR0FBRzttQkFDSk8sRUFBRVAsSUFBSTtnQkFDVDttQkFDRzBELGVBQWUxRixHQUFHLENBQUMsQ0FBQzJGLElBQU0sR0FBR0EsRUFBRWxELE9BQU8sQ0FBQyxLQUFLLElBQUksU0FBUyxDQUFDO2FBQzlEO1FBQ0g7UUFFQSxPQUFPRjtJQUNULEdBQ0E7UUFDRVIsSUFBSSxFQUFFO1FBQ05DLE1BQU0sRUFBRTtJQUNWO0lBR0YsT0FBTytDO0FBQ1Q7QUFFQTs7Q0FFQyxHQUNELFNBQVN2QixrQkFBa0JULGFBQStCLEVBQUVFLFNBQTJCO0lBQ3JGLFNBQVM7SUFDVCxNQUFNMkMsWUFBWTtRQUNoQm5DLEtBQUssRUFBRTtRQUNQRSxNQUFNLEVBQUU7SUFDVjtJQUNBLE1BQU1rQyxlQUFlO1FBQ25CckIsSUFBSTFGLEtBQUttRSxXQUFXRixlQUFlLENBQUNuQixNQUFRO2dCQUFDQSxJQUFJaEMsSUFBSTtnQkFBRWdDLElBQUlyQyxPQUFPLENBQUNjLElBQUksQ0FBQzthQUFLLENBQUNBLElBQUksQ0FBQztRQUNuRm9FLFFBQVEzRixLQUFLaUUsZUFBZUUsV0FBVyxDQUFDckIsTUFBUTtnQkFBQ0EsSUFBSWhDLElBQUk7Z0JBQUVnQyxJQUFJckMsT0FBTyxDQUFDYyxJQUFJLENBQUM7YUFBSyxDQUFDQSxJQUFJLENBQUM7SUFDekY7SUFDQSxJQUFJd0YsYUFBYXBCLE1BQU0sQ0FBQ3ZELE1BQU0sR0FBRyxHQUFHO1FBQ2xDMEUsVUFBVW5DLEdBQUcsR0FBR21DLFVBQVVuQyxHQUFHLENBQUNpQixNQUFNLENBQUNtQixhQUFhcEIsTUFBTTtJQUMxRDtJQUNBLElBQUlvQixhQUFhckIsRUFBRSxDQUFDdEQsTUFBTSxHQUFHLEdBQUc7UUFDOUIwRSxVQUFVakMsSUFBSSxHQUFHaUMsVUFBVWpDLElBQUksQ0FBQ2UsTUFBTSxDQUFDbUIsYUFBYXJCLEVBQUU7SUFDeEQ7SUFFQSxPQUFPb0I7QUFDVDtBQUVBOztDQUVDLEdBQ0QsU0FBUzFCLHVCQUF1QmpFLEtBQXFCO0lBQ25ELE1BQU13QixZQUFZO1FBQ2hCeEIsT0FBTztRQUNQeUIsVUFBVTtRQUNWQyxRQUFRO0lBQ1Y7SUFFQSxPQUFPLENBQUMsVUFBVSxFQUFFRixTQUFTLENBQUN4QixNQUFNTCxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUVLLE1BQU1WLE9BQU8sQ0FDeERTLEdBQUcsQ0FBQyxDQUFDOEYsYUFBZSxDQUFDLENBQUMsRUFBRUEsV0FBVyxDQUFDLENBQUMsRUFDckN6RixJQUFJLENBQUMsS0FBSyxJQUFJLEVBQUVKLE1BQU1PLElBQUksQ0FBQyxFQUFFLENBQUM7QUFDbkM7QUFFQTs7Q0FFQyxHQUNELGVBQWV1RiwyQkFDYnpHLEtBQWEsRUFDYjBHLGNBQWtDLEVBQ2xDOUMsVUFBOEIsRUFDOUIrQyxrQkFBcUMsRUFBRTtJQUV2QywrQ0FBK0M7SUFFL0MsTUFBTUMsU0FBUyxDQUFDQztRQUNkLE9BQU87WUFBQ0EsR0FBRzVHLE9BQU8sQ0FBQ2MsSUFBSSxDQUFDO1lBQU04RixHQUFHekQsRUFBRTtTQUFDLENBQUNyQyxJQUFJLENBQUM7SUFDNUM7SUFFQSxhQUFhO0lBQ2IsTUFBTStGLHNCQUFzQkgsZ0JBQWdCakcsR0FBRyxDQUFDLENBQUM0QixNQUFRQSxJQUFJcEIsSUFBSTtJQUVqRSxNQUFNNkYsT0FBT0wsZUFBZTFELE1BQU0sQ0FDaEMsQ0FBQ2dFLFFBQVFDO1FBQ1AsTUFBTUMsY0FBY3RELFdBQVdzQyxJQUFJLENBQUMsQ0FBQ2lCLE1BQVFQLE9BQU9LLGFBQWFMLE9BQU9PO1FBQ3hFLElBQUksQ0FBQ0QsYUFBYTtZQUNoQkYsT0FBTzdDLEdBQUcsQ0FBQzNDLElBQUksQ0FBQ3lGO1lBQ2hCLE9BQU9EO1FBQ1Q7UUFFQSxJQUFJMUgsTUFBTTJILFNBQVNDLGlCQUFpQixPQUFPO1lBQ3pDRixPQUFPSSxRQUFRLENBQUM1RixJQUFJLENBQUMwRjtZQUNyQkYsT0FBT0ssUUFBUSxDQUFDN0YsSUFBSSxDQUFDeUY7WUFDckIsT0FBT0Q7UUFDVDtRQUNBLE9BQU9BO0lBQ1QsR0FDQTtRQUNFN0MsS0FBSyxFQUFFO1FBQ1BFLE1BQU0sRUFBRTtRQUNSK0MsVUFBVSxFQUFFO1FBQ1pDLFVBQVUsRUFBRTtJQUNkO0lBR0YsbURBQW1EO0lBQ25ELDhEQUE4RDtJQUM5RHpELFdBQVcwRCxPQUFPLENBQUMsQ0FBQ0g7UUFDbEIsTUFBTUksa0JBQWtCYixlQUFlUixJQUFJLENBQUMsQ0FBQ2UsVUFBWUwsT0FBT0ssYUFBYUwsT0FBT087UUFDcEYsSUFBSSxDQUFDSSxpQkFBaUI7WUFDcEIsOEJBQThCO1lBQzlCLE1BQU1DLG1CQUFtQkwsSUFBSWxILE9BQU8sQ0FBQzRGLElBQUksQ0FBQyxDQUFDdkQsTUFBUXdFLG9CQUFvQnJDLFFBQVEsQ0FBQ25DO1lBQ2hGLGtDQUFrQztZQUNsQyxJQUFJLENBQUNrRixrQkFBa0I7Z0JBQ3JCVCxLQUFLMUMsSUFBSSxDQUFDN0MsSUFBSSxDQUFDMkY7WUFDakI7UUFDRjtJQUNGO0lBRUEsTUFBTTFCLFVBQVU7UUFDZHRCLEtBQUt4QixzQkFBc0IzQyxPQUFPK0csS0FBSzVDLEdBQUc7UUFDMUNFLE1BQU0xQixzQkFBc0IzQyxPQUFPK0csS0FBSzFDLElBQUk7UUFDNUMrQyxVQUFVekUsc0JBQXNCM0MsT0FBTytHLEtBQUtLLFFBQVE7UUFDcERDLFVBQVUxRSxzQkFBc0IzQyxPQUFPK0csS0FBS00sUUFBUTtJQUN0RDtJQUVBLHVDQUF1QztJQUN2QyxNQUFNSSxXQUFXQyxPQUFPQyxNQUFNLENBQUNsQyxTQUFTSSxJQUFJLENBQUMsQ0FBQ1EsSUFBTUEsRUFBRTVELEVBQUUsQ0FBQ2IsTUFBTSxHQUFHLEtBQUt5RSxFQUFFM0QsSUFBSSxDQUFDZCxNQUFNLEdBQUc7SUFDdkYsSUFBSSxDQUFDNkYsVUFBVTtRQUNiLE9BQU8sRUFBRTtJQUNYO0lBRUEsSUFDRWhDLFFBQVF0QixHQUFHLENBQUMxQixFQUFFLENBQUNiLE1BQU0sS0FBSyxLQUMxQjZELFFBQVFwQixJQUFJLENBQUM1QixFQUFFLENBQUNiLE1BQU0sS0FBSyxLQUMzQjZELFFBQVEyQixRQUFRLENBQUMzRSxFQUFFLENBQUNiLE1BQU0sS0FBSyxLQUMvQjZELFFBQVE0QixRQUFRLENBQUM1RSxFQUFFLENBQUNiLE1BQU0sS0FBSyxHQUMvQjtRQUNBakMsTUFBTWdGLENBQUMsQ0FBQyxtRUFBbUU7WUFDekUzRTtZQUNBMEc7WUFDQTlDO1FBQ0Y7UUFDQSxNQUFNLElBQUkxQixNQUFNO0lBQ2xCO0lBRUEsTUFBTTFCLFFBQWtCO1FBQ3RCO1FBQ0E7UUFDQTtRQUNBLENBQUMsK0JBQStCLEVBQUVSLE1BQU0sZUFBZSxDQUFDO1dBQ3JEeUYsUUFBUXBCLElBQUksQ0FBQzNCLElBQUk7V0FDakIrQyxRQUFRdEIsR0FBRyxDQUFDMUIsRUFBRTtXQUNkZ0QsUUFBUTJCLFFBQVEsQ0FBQzFFLElBQUk7V0FDckIrQyxRQUFRNEIsUUFBUSxDQUFDNUUsRUFBRTtRQUN0QjtRQUNBO1FBQ0E7UUFDQTtRQUNBLENBQUMsK0JBQStCLEVBQUV6QyxNQUFNLGVBQWUsQ0FBQztXQUNyRHlGLFFBQVF0QixHQUFHLENBQUN6QixJQUFJO1dBQ2hCK0MsUUFBUTRCLFFBQVEsQ0FBQzNFLElBQUk7V0FDckIrQyxRQUFRMkIsUUFBUSxDQUFDM0UsRUFBRTtXQUNuQmdELFFBQVFwQixJQUFJLENBQUM1QixFQUFFO1FBQ2xCO1FBQ0E7S0FDRDtJQUVELE1BQU0zQixZQUFZbEIsV0FBV1ksTUFBTU8sSUFBSSxDQUFDLE9BQU8sY0FBYyxDQUFDLGNBQWMsRUFBRWYsTUFBTSxHQUFHLENBQUM7SUFDeEYsTUFBTWEsUUFBUTtRQUNaO1FBQ0FiO1FBQ0E7S0FFRCxDQUFDZSxJQUFJLENBQUM7SUFFUCxPQUFPO1FBQ0w7WUFDRWY7WUFDQWE7WUFDQUM7WUFDQVIsTUFBTTtRQUNSO0tBQ0Q7QUFDSDtBQUVBOzs7O0NBSUMsR0FDRCxPQUFPLGVBQWVzSCxtQkFBbUJDLFNBQXVCO0lBQzlELE9BQU87UUFDTCxNQUFNOUgsb0NBQ0o4SCxVQUFVN0gsS0FBSyxFQUNmNkgsVUFBVTVILE9BQU8sRUFDakI0SCxVQUFVM0gsT0FBTztXQUVmLE1BQU1xQywyQkFBMkJzRixVQUFVN0gsS0FBSyxFQUFFNkgsVUFBVXJGLFFBQVE7S0FDekU7QUFDSDtBQUVBOzs7OztDQUtDLEdBQ0QsT0FBTyxlQUFlc0Ysa0JBQ3BCRCxTQUF1QixFQUN2QkUsS0FBbUI7SUFFbkIsTUFBTUMseUJBQXlCLENBQUMxRjtRQUM5QixrREFBa0Q7UUFDbEQsZ0dBQWdHO1FBQ2hHLDBFQUEwRTtRQUMxRSxJQUFJO1FBQ0osa0NBQWtDO1FBQ2xDLHVEQUF1RDtRQUN2RCwwQkFBMEI7UUFDMUIsSUFBSTtRQUNKLGtFQUFrRTtRQUNsRSwrQ0FBK0M7UUFDL0MsK0RBQStEO1FBQy9ELDRFQUE0RTtRQUM1RSwyQkFBMkI7UUFDM0Isa0ZBQWtGO1FBQ2xGLDJCQUEyQjtRQUMzQixNQUFNO1FBQ04sSUFBSTtRQUVKLGdFQUFnRTtRQUNoRSxPQUFPQTtJQUNUO0lBQ0EsTUFBTWtCLGdCQUFnQmpFLGFBQWFzSSxVQUFVNUgsT0FBTyxFQUFFLENBQUNzRixJQUFNQSxFQUFFckUsSUFBSSxFQUFFUixHQUFHLENBQUNzSDtJQUN6RSxNQUFNdEUsWUFBWW5FLGFBQWF3SSxNQUFNOUgsT0FBTyxFQUFFLENBQUNzRixJQUFNQSxFQUFFckUsSUFBSSxFQUFFUixHQUFHLENBQUNzSDtJQUVqRTs7Ozs7Ozs7U0FRTyxHQUVQLE1BQU12RSxnQkFBZ0JsRSxhQUFhc0ksVUFBVTNILE9BQU8sRUFBRSxDQUFDcUYsSUFDckQ7WUFBQ0EsRUFBRWpGLElBQUk7ZUFBS2lGLEVBQUV0RixPQUFPO1NBQUMsQ0FBQ2MsSUFBSSxDQUFDO0lBRTlCLE1BQU00QyxZQUFZcEUsYUFBYXdJLE1BQU03SCxPQUFPLEVBQUUsQ0FBQ3FGLElBQzdDO1lBQUNBLEVBQUVqRixJQUFJO2VBQUtpRixFQUFFdEYsT0FBTztTQUFDLENBQUNjLElBQUksQ0FBQztJQUc5QixNQUFNa0gseUJBQXlCLENBQUNDO1FBQzlCLG1DQUFtQztRQUNuQyxNQUFNLEVBQUU1RSxRQUFRLEVBQUVELFFBQVEsRUFBRSxHQUFHNkU7UUFDL0IsT0FBTztZQUNMLEdBQUdBLENBQUM7WUFDSjdFLFVBQVVBLGFBQWEsYUFBYSxjQUFjQTtZQUNsREMsVUFBVUEsYUFBYSxhQUFhLGNBQWNBO1FBQ3BEO0lBQ0Y7SUFFQSxNQUFNb0QsaUJBQWlCbkgsYUFBYXNJLFVBQVVyRixRQUFRLEVBQUUsQ0FBQytDLElBQ3ZEO1lBQUNBLEVBQUVuQyxFQUFFO2VBQUttQyxFQUFFdEYsT0FBTztTQUFDLENBQUNjLElBQUksQ0FBQyxNQUMxQkwsR0FBRyxDQUFDLENBQUN3SCxJQUFNRCx1QkFBdUJDO0lBQ3BDLE1BQU10RSxhQUFhckUsYUFBYXdJLE1BQU12RixRQUFRLEVBQUUsQ0FBQytDLElBQU07WUFBQ0EsRUFBRW5DLEVBQUU7ZUFBS21DLEVBQUV0RixPQUFPO1NBQUMsQ0FBQ2MsSUFBSSxDQUFDLE1BQU1MLEdBQUcsQ0FBQyxDQUFDd0gsSUFDMUZELHVCQUF1QkM7SUFHekIsZUFBZTtJQUNmLE1BQU12QixrQkFBa0JuSCxLQUFLa0UsV0FBV0YsZUFBZSxDQUFDbEIsTUFBUUEsSUFBSXBCLElBQUk7SUFFeEUsTUFBTWlILGFBQStELEVBQUU7SUFFdkUsMEJBQTBCO0lBQzFCLE1BQU1DLGlCQUFpQjlJLE1BQU1rRSxlQUFlRTtJQUM1QyxNQUFNMkUsaUJBQWlCL0ksTUFDckJtRSxjQUFjL0MsR0FBRyxDQUFDLENBQUNDLFFBQVVqQixLQUFLaUIsT0FBTztZQUFDO1NBQVMsSUFDbkRnRDtJQUVGLElBQUksQ0FBQ3lFLGtCQUFrQixDQUFDQyxnQkFBZ0I7UUFDdENGLFdBQVczRyxJQUFJLENBQ2IsTUFBTStCLG1DQUNKc0UsVUFBVTdILEtBQUssRUFDZndELGVBQ0FDLGVBQ0FDLFdBQ0FDLFdBQ0FvRSxNQUFNdkYsUUFBUTtJQUdwQjtJQUVBLGdDQUFnQztJQUNoQyxJQUFJbEQsTUFBTW9ILGdCQUFnQjlDLGdCQUFnQixPQUFPO1FBQy9DdUUsV0FBVzNHLElBQUksQ0FDYixNQUFNaUYsMkJBQ0pvQixVQUFVN0gsS0FBSyxFQUNmMEcsZ0JBQ0E5QyxZQUNBK0M7SUFHTjtJQUVBLElBQUl3QixXQUFXNUQsS0FBSyxDQUFDLENBQUMrRCxZQUFjQSxjQUFjLE9BQU87UUFDdkQsT0FBTyxFQUFFO0lBQ1g7SUFFQSxPQUFPSCxXQUFXN0QsTUFBTSxDQUFDLENBQUNnRSxZQUFjQSxjQUFjLE1BQU1DLElBQUk7QUFDbEUifQ==
|
|
807
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWdyYXRpb24vY29kZS1nZW5lcmF0aW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBlcXVhbCBmcm9tIFwiZmFzdC1kZWVwLWVxdWFsXCI7XG5pbXBvcnQgeyBhbHBoYWJldGljYWwsIGRpZmYsIG9taXQgfSBmcm9tIFwicmFkYXNoaVwiO1xuaW1wb3J0IHsgTmFpdGUgfSBmcm9tIFwiLi5cIjtcbmltcG9ydCB0eXBlIHtcbiAgR2VuTWlncmF0aW9uQ29kZSxcbiAgTWlncmF0aW9uQ29sdW1uLFxuICBNaWdyYXRpb25Gb3JlaWduLFxuICBNaWdyYXRpb25JbmRleCxcbiAgTWlncmF0aW9uU2V0LFxufSBmcm9tIFwiLi4vdHlwZXMvdHlwZXNcIjtcbmltcG9ydCB7IGZvcm1hdENvZGUgfSBmcm9tIFwiLi4vdXRpbHMvZm9ybWF0dGVyXCI7XG5pbXBvcnQgeyBkaWZmZXJlbmNlV2l0aCwgaW50ZXJzZWN0aW9uQnkgfSBmcm9tIFwiLi4vdXRpbHMvdXRpbHNcIjtcblxuLyoqXG4gKiDsu6zrn7wg7KCV7J2YIOqysOqzvCDtg4DsnoVcbiAqIC0gYnVpbGRlcjogS25leCB0YWJsZSBidWlsZGVyIOuplOyEnOuTnOuhnCDsi6TtlontlaAg6rWs66y4ICh0YWJsZS54eHgoKSlcbiAqIC0gcmF3OiBrbmV4LnJhdygp66GcIOyLpO2Wie2VoCDqtazrrLhcbiAqL1xudHlwZSBDb2x1bW5EZWZpbml0aW9uUmVzdWx0ID0ge1xuICBidWlsZGVyOiBzdHJpbmdbXTtcbiAgcmF3OiBzdHJpbmdbXTtcbn07XG5cbi8qKlxuICog7YWM7J2067iUIOyDneyEse2VmOuKlCDsvIDsnbTsiqQgLSDsu6zrn7wv7J24642x7IqkIOyDneyEsVxuICovXG5hc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUNyZWF0ZUNvZGVfQ29sdW1uQW5kSW5kZXhlcyhcbiAgdGFibGU6IHN0cmluZyxcbiAgY29sdW1uczogTWlncmF0aW9uQ29sdW1uW10sXG4gIGluZGV4ZXM6IE1pZ3JhdGlvbkluZGV4W10sXG4pOiBQcm9taXNlPEdlbk1pZ3JhdGlvbkNvZGU+IHtcbiAgY29uc3QgY29sdW1uRGVmcyA9IGdlbkNvbHVtbkRlZmluaXRpb25zKHRhYmxlLCBjb2x1bW5zKTtcblxuICAvLyDsu6zrn7wsIOyduOuNseyKpCDsspjrpqxcbiAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW1xuICAgICdpbXBvcnQgeyBLbmV4IH0gZnJvbSBcImtuZXhcIjsnLFxuICAgIFwiXCIsXG4gICAgXCJleHBvcnQgYXN5bmMgZnVuY3Rpb24gdXAoa25leDogS25leCk6IFByb21pc2U8dm9pZD4ge1wiLFxuICAgIGBhd2FpdCBrbmV4LnNjaGVtYS5jcmVhdGVUYWJsZShcIiR7dGFibGV9XCIsICh0YWJsZSkgPT4ge2AsXG4gICAgLi4uY29sdW1uRGVmcy5idWlsZGVyLFxuICAgIFwifSk7XCIsXG4gICAgLy8gcmF3IOq1rOusuCAoR2VuZXJhdGVkIENvbHVtbiDrk7EpXG4gICAgLi4uY29sdW1uRGVmcy5yYXcsXG4gICAgLy8gaW5kZXjripQga25leC5yYXfroZwg7LKY66as7ZWY66+A66GcIGNyZWF0ZVRhYmxlIOuwluyXkOyEnCDsi6TtlolcbiAgICAuLi5pbmRleGVzLm1hcCgoaW5kZXgpID0+IGdlbkluZGV4RGVmaW5pdGlvbihpbmRleCwgdGFibGUpKSxcbiAgICBcIn1cIixcbiAgICBcIlwiLFxuICAgIFwiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvd24oa25leDogS25leCk6IFByb21pc2U8dm9pZD4ge1wiLFxuICAgIGAgcmV0dXJuIGtuZXguc2NoZW1hLmRyb3BUYWJsZShcIiR7dGFibGV9XCIpO2AsXG4gICAgXCJ9XCIsXG4gIF07XG4gIHJldHVybiB7XG4gICAgdGFibGUsXG4gICAgdHlwZTogXCJub3JtYWxcIixcbiAgICB0aXRsZTogYGNyZWF0ZV9fJHt0YWJsZX1gLFxuICAgIGZvcm1hdHRlZDogZm9ybWF0Q29kZShsaW5lcy5qb2luKFwiXFxuXCIpLCBcInR5cGVzY3JpcHRcIiwgYHNyYy9taWdyYXRpb24vJHt0YWJsZX0udHNgKSxcbiAgfTtcbn1cblxuLyoqXG4gKiBNaWdyYXRpb25Db2x1bW5bXSDsnb3slrTshJwg7Lus65+8IOygleydmO2VmOuKlCDqtazrrLgg7IOd7ISxXG4gKiBAcmV0dXJucyBidWlsZGVyOiB0YWJsZSBidWlsZGVyIOuplOyEnOuTnCwgcmF3OiBrbmV4LnJhdygpIOq1rOusuFxuICovXG5mdW5jdGlvbiBnZW5Db2x1bW5EZWZpbml0aW9ucyh0YWJsZTogc3RyaW5nLCBjb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSk6IENvbHVtbkRlZmluaXRpb25SZXN1bHQge1xuICBjb25zdCByZXN1bHQ6IENvbHVtbkRlZmluaXRpb25SZXN1bHQgPSB7XG4gICAgYnVpbGRlcjogW10sXG4gICAgcmF3OiBbXSxcbiAgfTtcblxuICBmb3IgKGNvbnN0IGNvbHVtbiBvZiBjb2x1bW5zKSB7XG4gICAgLy8gR2VuZXJhdGVkIENvbHVtbuydgCByYXfroZwg7LKY66asXG4gICAgaWYgKGNvbHVtbi5nZW5lcmF0ZWQpIHtcbiAgICAgIHJlc3VsdC5yYXcucHVzaChnZW5HZW5lcmF0ZWRDb2x1bW5EZWZpbml0aW9uKHRhYmxlLCBjb2x1bW4pKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIC8vIOydvOuwmCDsu6zrn7zsnYAgYnVpbGRlcuuhnCDsspjrpqxcbiAgICByZXN1bHQuYnVpbGRlci5wdXNoKGdlbk5vcm1hbENvbHVtbkRlZmluaXRpb24oY29sdW1uKSk7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEdlbmVyYXRlZCBDb2x1bW4g7KCV7J2YIOyDneyEsSAoQUxURVIgVEFCTEUgQUREIENPTFVNTiDsgqzsmqkpXG4gKi9cbmZ1bmN0aW9uIGdlbkdlbmVyYXRlZENvbHVtbkRlZmluaXRpb24odGFibGU6IHN0cmluZywgY29sdW1uOiBNaWdyYXRpb25Db2x1bW4pOiBzdHJpbmcge1xuICBpZiAoIWNvbHVtbi5nZW5lcmF0ZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJHZW5lcmF0ZWQgY29sdW1uIGRlZmluaXRpb24gcmVxdWlyZWRcIik7XG4gIH1cbiAgY29uc3QgcGdUeXBlID0gZ2V0UGdUeXBlRm9yQ29sdW1uKGNvbHVtbik7XG4gIGNvbnN0IHN0b3JhZ2VUeXBlID0gY29sdW1uLmdlbmVyYXRlZC50eXBlID09PSBcIlZJUlRVQUxcIiA/IFwiIFZJUlRVQUxcIiA6IFwiIFNUT1JFRFwiO1xuICBjb25zdCBudWxsYWJsZUNsYXVzZSA9IGNvbHVtbi5udWxsYWJsZSA/IFwiXCIgOiBcIiBOT1QgTlVMTFwiO1xuICByZXR1cm4gYGF3YWl0IGtuZXgucmF3KFxcYEFMVEVSIFRBQkxFIFwiJHt0YWJsZX1cIiBBREQgQ09MVU1OIFwiJHtjb2x1bW4ubmFtZX1cIiAke3BnVHlwZX0gR0VORVJBVEVEIEFMV0FZUyBBUyAoJHtjb2x1bW4uZ2VuZXJhdGVkLmV4cHJlc3Npb259KSR7c3RvcmFnZVR5cGV9JHtudWxsYWJsZUNsYXVzZX1cXGApO2A7XG59XG5cbi8qKlxuICog7J2867CYIOy7rOufvCDsoJXsnZgg7IOd7ISxICh0YWJsZS54eHgoKSDssrTsnbgpXG4gKi9cbmZ1bmN0aW9uIGdlbk5vcm1hbENvbHVtbkRlZmluaXRpb24oY29sdW1uOiBNaWdyYXRpb25Db2x1bW4pOiBzdHJpbmcge1xuICBjb25zdCBjaGFpbnM6IHN0cmluZ1tdID0gW107XG5cbiAgaWYgKGNvbHVtbi5uYW1lID09PSBcImlkXCIpIHtcbiAgICByZXR1cm4gYHRhYmxlLmluY3JlbWVudHMoKS5wcmltYXJ5KCk7YDtcbiAgfVxuXG4gIC8vIOuwsOyXtCDtg4DsnoUg7LKY66asXG4gIGlmIChjb2x1bW4udHlwZS5lbmRzV2l0aChcIltdXCIpKSB7XG4gICAgY29uc3QgZWxlbWVudFR5cGUgPSBjb2x1bW4udHlwZS5zbGljZSgwLCAtMik7IC8vIFwiaW50ZWdlcltdXCIgLT4gXCJpbnRlZ2VyXCJcbiAgICBjb25zdCBwZ1R5cGUgPSBnZXRQZ0FycmF5VHlwZShjb2x1bW4sIGVsZW1lbnRUeXBlKTtcbiAgICBjaGFpbnMucHVzaChgc3BlY2lmaWNUeXBlKCcke2NvbHVtbi5uYW1lfScsICcke3BnVHlwZX0nKWApO1xuICB9IGVsc2UgaWYgKGNvbHVtbi50eXBlID09PSBcInZlY3RvclwiKSB7XG4gICAgLy8gS25leOuKlCB2ZWN0b3Ig7YOA7J6F7J2EIOyngeygkSDsp4Dsm5DtlZjsp4Ag7JWK7Jy866+A66GcIHNwZWNpZmljVHlwZSDsgqzsmqlcbiAgICBjaGFpbnMucHVzaChgc3BlY2lmaWNUeXBlKCcke2NvbHVtbi5uYW1lfScsICd2ZWN0b3IoJHtjb2x1bW4uZGltZW5zaW9uc30pJylgKTtcbiAgfSBlbHNlIGlmIChjb2x1bW4udHlwZSA9PT0gXCJudW1iZXJPck51bWVyaWNcIikge1xuICAgIC8vIG51bWJlclxuICAgIGlmIChjb2x1bW4ubnVtYmVyVHlwZSA9PT0gXCJyZWFsXCIpIHtcbiAgICAgIGNoYWlucy5wdXNoKGBmbG9hdCgnJHtjb2x1bW4ubmFtZX0nKWApO1xuICAgIH0gZWxzZSBpZiAoY29sdW1uLm51bWJlclR5cGUgPT09IFwiZG91YmxlIHByZWNpc2lvblwiKSB7XG4gICAgICBjaGFpbnMucHVzaChgZG91YmxlKCcke2NvbHVtbi5uYW1lfScpYCk7XG4gICAgfSBlbHNlIGlmICgoY29sdW1uLm51bWJlclR5cGUgPz8gXCJudW1lcmljXCIpID09PSBcIm51bWVyaWNcIikge1xuICAgICAgY2hhaW5zLnB1c2goYGRlY2ltYWwoJyR7Y29sdW1uLm5hbWV9JywgJHtjb2x1bW4ucHJlY2lzaW9ufSwgJHtjb2x1bW4uc2NhbGV9KWApO1xuICAgIH1cbiAgfSBlbHNlIGlmIChjb2x1bW4udHlwZSA9PT0gXCJzdHJpbmdcIikge1xuICAgIC8vIHN0cmluZ1xuICAgIGlmIChjb2x1bW4ubGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNoYWlucy5wdXNoKGBzdHJpbmcoJyR7Y29sdW1uLm5hbWV9JywgJHtjb2x1bW4ubGVuZ3RofSlgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY2hhaW5zLnB1c2goYHRleHQoJyR7Y29sdW1uLm5hbWV9JylgKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoY29sdW1uLnR5cGUgPT09IFwiZGF0ZVwiKSB7XG4gICAgLy8gZGF0ZVxuICAgIGNoYWlucy5wdXNoKGB0aW1lc3RhbXAoJyR7Y29sdW1uLm5hbWV9JywgeyB1c2VUejogdHJ1ZSB9KWApO1xuICB9IGVsc2UgaWYgKGNvbHVtbi50eXBlID09PSBcImpzb25cIikge1xuICAgIC8vIGpzb25cbiAgICBjaGFpbnMucHVzaChganNvbmIoJyR7Y29sdW1uLm5hbWV9JylgKTtcbiAgfSBlbHNlIHtcbiAgICAvLyB0eXBlLCBsZW5ndGhcbiAgICBsZXQgZXh0cmFUeXBlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgY2hhaW5zLnB1c2goXG4gICAgICBgJHtjb2x1bW4udHlwZX0oJyR7Y29sdW1uLm5hbWV9JyR7XG4gICAgICAgIGNvbHVtbi5sZW5ndGggPyBgLCAke2NvbHVtbi5sZW5ndGh9YCA6IFwiXCJcbiAgICAgIH0ke2V4dHJhVHlwZSA/IGAsICcke2V4dHJhVHlwZX0nYCA6IFwiXCJ9KWAsXG4gICAgKTtcbiAgfVxuXG4gIC8vIG51bGxhYmxlXG4gIGNoYWlucy5wdXNoKGNvbHVtbi5udWxsYWJsZSA/IFwibnVsbGFibGUoKVwiIDogXCJub3ROdWxsYWJsZSgpXCIpO1xuXG4gIC8vIGRlZmF1bHRUb1xuICBpZiAoY29sdW1uLmRlZmF1bHRUbyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHR5cGVvZiBjb2x1bW4uZGVmYXVsdFRvID09PSBcInN0cmluZ1wiICYmIGNvbHVtbi5kZWZhdWx0VG8uc3RhcnRzV2l0aChgXCJgKSkge1xuICAgICAgY2hhaW5zLnB1c2goYGRlZmF1bHRUbygke2NvbHVtbi5kZWZhdWx0VG99KWApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjaGFpbnMucHVzaChgZGVmYXVsdFRvKGtuZXgucmF3KCcke2NvbHVtbi5kZWZhdWx0VG99JykpYCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGB0YWJsZS4ke2NoYWlucy5qb2luKFwiLlwiKX07YDtcbn1cblxuLyoqXG4gKiBNaWdyYXRpb25Db2x1bW7snZgg7YOA7J6F7J2EIFBvc3RncmVTUUwg7YOA7J6FIOusuOyekOyXtOuhnCDrs4DtmZhcbiAqL1xuZnVuY3Rpb24gZ2V0UGdUeXBlRm9yQ29sdW1uKGNvbHVtbjogTWlncmF0aW9uQ29sdW1uKTogc3RyaW5nIHtcbiAgaWYgKGNvbHVtbi50eXBlLmVuZHNXaXRoKFwiW11cIikpIHtcbiAgICBjb25zdCBlbGVtZW50VHlwZSA9IGNvbHVtbi50eXBlLnNsaWNlKDAsIC0yKTtcbiAgICByZXR1cm4gZ2V0UGdBcnJheVR5cGUoY29sdW1uLCBlbGVtZW50VHlwZSk7XG4gIH1cblxuICBzd2l0Y2ggKGNvbHVtbi50eXBlKSB7XG4gICAgY2FzZSBcInN0cmluZ1wiOlxuICAgICAgcmV0dXJuIGNvbHVtbi5sZW5ndGggIT09IHVuZGVmaW5lZCA/IGB2YXJjaGFyKCR7Y29sdW1uLmxlbmd0aH0pYCA6IFwidGV4dFwiO1xuICAgIGNhc2UgXCJiaWdJbnRlZ2VyXCI6XG4gICAgICByZXR1cm4gXCJiaWdpbnRcIjtcbiAgICBjYXNlIFwibnVtYmVyT3JOdW1lcmljXCI6XG4gICAgICBpZiAoY29sdW1uLm51bWJlclR5cGUgPT09IFwicmVhbFwiKSByZXR1cm4gXCJyZWFsXCI7XG4gICAgICBpZiAoY29sdW1uLm51bWJlclR5cGUgPT09IFwiZG91YmxlIHByZWNpc2lvblwiKSByZXR1cm4gXCJkb3VibGUgcHJlY2lzaW9uXCI7XG4gICAgICByZXR1cm4gYG51bWVyaWMoJHtjb2x1bW4ucHJlY2lzaW9ufSwgJHtjb2x1bW4uc2NhbGV9KWA7XG4gICAgY2FzZSBcImRhdGVcIjpcbiAgICAgIHJldHVybiBcInRpbWVzdGFtcHR6XCI7XG4gICAgY2FzZSBcImpzb25cIjpcbiAgICAgIHJldHVybiBcImpzb25iXCI7XG4gICAgY2FzZSBcInZlY3RvclwiOlxuICAgICAgcmV0dXJuIGB2ZWN0b3IoJHtjb2x1bW4uZGltZW5zaW9uc30pYDtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGNvbHVtbi50eXBlO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldFBnQXJyYXlUeXBlKGNvbHVtbjogTWlncmF0aW9uQ29sdW1uLCBlbGVtZW50VHlwZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKGVsZW1lbnRUeXBlID09PSBcIm51bWJlck9yTnVtZXJpY1wiKSB7XG4gICAgaWYgKGNvbHVtbi5udW1iZXJUeXBlID09PSBcInJlYWxcIikgcmV0dXJuIFwicmVhbFtdXCI7XG4gICAgaWYgKGNvbHVtbi5udW1iZXJUeXBlID09PSBcImRvdWJsZSBwcmVjaXNpb25cIikgcmV0dXJuIFwiZG91YmxlIHByZWNpc2lvbltdXCI7XG4gICAgcmV0dXJuIGBudW1lcmljKCR7Y29sdW1uLnByZWNpc2lvbn0sICR7Y29sdW1uLnNjYWxlfSlbXWA7XG4gIH1cbiAgaWYgKGVsZW1lbnRUeXBlID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIGNvbHVtbi5sZW5ndGggPyBgdmFyY2hhcigke2NvbHVtbi5sZW5ndGh9KVtdYCA6IFwidGV4dFtdXCI7XG4gIH1cbiAgaWYgKGVsZW1lbnRUeXBlID09PSBcImRhdGVcIikgcmV0dXJuIFwidGltZXN0YW1wdHpbXVwiO1xuICBpZiAoZWxlbWVudFR5cGUgPT09IFwiaW50ZWdlclwiKSByZXR1cm4gXCJpbnRlZ2VyW11cIjtcbiAgaWYgKGVsZW1lbnRUeXBlID09PSBcImJpZ0ludGVnZXJcIikgcmV0dXJuIFwiYmlnaW50W11cIjtcbiAgaWYgKGVsZW1lbnRUeXBlID09PSBcImJvb2xlYW5cIikgcmV0dXJuIFwiYm9vbGVhbltdXCI7XG4gIGlmIChlbGVtZW50VHlwZSA9PT0gXCJ1dWlkXCIpIHJldHVybiBcInV1aWRbXVwiO1xuICBpZiAoZWxlbWVudFR5cGUgPT09IFwiZW51bVwiKSByZXR1cm4gXCJ0ZXh0W11cIjtcbiAgaWYgKGVsZW1lbnRUeXBlID09PSBcInZlY3RvclwiKSByZXR1cm4gYHZlY3Rvcigke2NvbHVtbi5kaW1lbnNpb25zfSlbXWA7XG5cbiAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGFycmF5IGVsZW1lbnQgdHlwZTogJHtlbGVtZW50VHlwZX1gKTtcbn1cblxuLyoqXG4gKiDqsJzrs4Qg7J24642x7IqkIOygleydmCDsg53shLFcbiAqL1xuZnVuY3Rpb24gZ2VuSW5kZXhEZWZpbml0aW9uKGluZGV4OiBNaWdyYXRpb25JbmRleCwgdGFibGU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmIChpbmRleC50eXBlID09PSBcImhuc3dcIiB8fCBpbmRleC50eXBlID09PSBcIml2ZmZsYXRcIikge1xuICAgIHJldHVybiBnZW5WZWN0b3JJbmRleERlZmluaXRpb24oaW5kZXgsIHRhYmxlKTtcbiAgfVxuXG4gIGNvbnN0IG1ldGhvZE1hcCA9IHtcbiAgICBpbmRleDogXCJJTkRFWFwiLFxuICAgIGZ1bGx0ZXh0OiBcIklOREVYXCIsXG4gICAgdW5pcXVlOiBcIlVOSVFVRSBJTkRFWFwiLFxuICB9O1xuXG4gIGNvbnN0IG51bGxzTm90RGlzdGluY3RDbGF1c2UgPVxuICAgIGluZGV4Lm51bGxzTm90RGlzdGluY3QgPT09IHVuZGVmaW5lZFxuICAgICAgPyBcIlwiXG4gICAgICA6IGAgTlVMTFMgJHtpbmRleC5udWxsc05vdERpc3RpbmN0ID8gXCJOT1QgRElTVElOQ1RcIiA6IFwiRElTVElOQ1RcIn1gO1xuXG4gIHJldHVybiBgYXdhaXQga25leC5yYXcoXG4gIFxcYENSRUFURSAke21ldGhvZE1hcFtpbmRleC50eXBlXX0gJHtpbmRleC5uYW1lfSBPTiAke3RhYmxlfSAoJHtpbmRleC5jb2x1bW5zXG4gICAgLm1hcCgoY29sKSA9PiB7XG4gICAgICBjb25zdCBzb3J0T3JkZXJDbGF1c2UgPSBjb2wuc29ydE9yZGVyID09PSB1bmRlZmluZWQgPyBcIlwiIDogYCAke2NvbC5zb3J0T3JkZXJ9YDtcbiAgICAgIGNvbnN0IG51bGxzRmlyc3RDbGF1c2UgPVxuICAgICAgICBjb2wubnVsbHNGaXJzdCA9PT0gdW5kZWZpbmVkID8gXCJcIiA6IGAgTlVMTFMgJHtjb2wubnVsbHNGaXJzdCA/IFwiRklSU1RcIiA6IFwiTEFTVFwifWA7XG4gICAgICByZXR1cm4gYCR7Y29sLm5hbWV9JHtzb3J0T3JkZXJDbGF1c2V9JHtudWxsc0ZpcnN0Q2xhdXNlfWA7XG4gICAgfSlcbiAgICAuam9pbihcIiwgXCIpfSkke251bGxzTm90RGlzdGluY3RDbGF1c2V9O1xcYFxuICApO2A7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uXG4gKiAtIEhOU1cgKEhpZXJhcmNoaWNhbCBOYXZpZ2FibGUgU21hbGwgV29ybGQpOiDripDrprAg67mM65OcLCDruaDrpbgg6rKA7IOJIOyGjeuPhCwg64aS7J2AIOuplOuqqOumrCDrsI8g7KCV7ZmV64+EXG4gKiAtIElWRkZsYXQgKEludmVydGVkIEZpbGUgd2l0aCBGbGF0IENvbXByZXNzaW9uKTog67mg66W4IOu5jOuTnCwg7KSR6rCEIOqygOyDiSDsho3rj4QsIOuCruydgCDrqZTrqqjrpqxcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gSE5TVyDsnbjrjbHsiqQgKOq2jOyepSAtIOu5oOuluCDqsoDsg4ksIOuGkuydgCDsoJXtmZXrj4QpXG4gKiBDUkVBVEUgSU5ERVggaWR4X2VtYmVkZGluZyBPTiBpdGVtcyBVU0lORyBobnN3IChlbWJlZGRpbmcgdmVjdG9yX2Nvc2luZV9vcHMpIFdJVEggKG0gPSAxNiwgZWZfY29uc3RydWN0aW9uID0gNjQpO1xuICpcbiAqIC8vIElWRkZsYXQg7J24642x7IqkICjrjIDsmqnrn4kg642w7J207YSwLCDruYTsmqkg7KSR7JqUIOyLnClcbiAqIENSRUFURSBJTkRFWCBpZHhfZW1iZWRkaW5nIE9OIGl0ZW1zIFVTSU5HIGl2ZmZsYXQgKGVtYmVkZGluZyB2ZWN0b3JfY29zaW5lX29wcykgV0lUSCAobGlzdHMgPSAxMDApO1xuICovXG5mdW5jdGlvbiBnZW5WZWN0b3JJbmRleERlZmluaXRpb24oaW5kZXg6IE1pZ3JhdGlvbkluZGV4LCB0YWJsZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgY29sdW1uID0gaW5kZXguY29sdW1uc1swXTtcbiAgY29uc3QgdmVjdG9yT3BzID0gY29sdW1uLnZlY3Rvck9wcyA/PyBcInZlY3Rvcl9jb3NpbmVfb3BzXCI7XG5cbiAgLy8gSE5TVyAoSGllcmFyY2hpY2FsIE5hdmlnYWJsZSBTbWFsbCBXb3JsZCkgLSDqtozsnqU6IOu5oOuluCDqsoDsg4ksIOuGkuydgCDsoJXtmZXrj4RcbiAgaWYgKGluZGV4LnR5cGUgPT09IFwiaG5zd1wiKSB7XG4gICAgY29uc3QgbSA9IGluZGV4Lm0gPz8gMTY7XG4gICAgY29uc3QgZWZDb25zdHJ1Y3Rpb24gPSBpbmRleC5lZkNvbnN0cnVjdGlvbiA/PyA2NDtcbiAgICByZXR1cm4gYGF3YWl0IGtuZXgucmF3KFxcYENSRUFURSBJTkRFWCAke2luZGV4Lm5hbWV9IE9OICR7dGFibGV9IFVTSU5HIGhuc3cgKCR7Y29sdW1uLm5hbWV9ICR7dmVjdG9yT3BzfSkgV0lUSCAobSA9ICR7bX0sIGVmX2NvbnN0cnVjdGlvbiA9ICR7ZWZDb25zdHJ1Y3Rpb259KVxcYCk7YDtcbiAgfVxuXG4gIC8vIElWRkZsYXQgKEludmVydGVkIEZpbGUgd2l0aCBGbGF0IENvbXByZXNzaW9uKSAtIOuMgOyaqeufiSwg67mE7JqpIOykkeyalCDsi5xcbiAgaWYgKGluZGV4LnR5cGUgPT09IFwiaXZmZmxhdFwiKSB7XG4gICAgY29uc3QgbGlzdHMgPSBpbmRleC5saXN0cyA/PyAxMDA7XG4gICAgcmV0dXJuIGBhd2FpdCBrbmV4LnJhdyhcXGBDUkVBVEUgSU5ERVggJHtpbmRleC5uYW1lfSBPTiAke3RhYmxlfSBVU0lORyBpdmZmbGF0ICgke2NvbHVtbi5uYW1lfSAke3ZlY3Rvck9wc30pIFdJVEggKGxpc3RzID0gJHtsaXN0c30pXFxgKTtgO1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHJhdyBTUUwgaW5kZXggdHlwZTogJHtpbmRleC50eXBlfWApO1xufVxuXG4vKipcbiAqIO2FjOydtOu4lCDsg53shLHtlZjripQg7LyA7J207IqkIC0gRksg7IOd7ISxXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlQ3JlYXRlQ29kZV9Gb3JlaWduKFxuICB0YWJsZTogc3RyaW5nLFxuICBmb3JlaWduczogTWlncmF0aW9uRm9yZWlnbltdLFxuKTogUHJvbWlzZTxHZW5NaWdyYXRpb25Db2RlW10+IHtcbiAgaWYgKGZvcmVpZ25zLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHsgdXAsIGRvd24gfSA9IGdlbkZvcmVpZ25EZWZpbml0aW9ucyh0YWJsZSwgZm9yZWlnbnMpO1xuICBpZiAodXAubGVuZ3RoID09PSAwICYmIGRvd24ubGVuZ3RoID09PSAwKSB7XG4gICAgY29uc29sZS5sb2coXCJmayDqsIAg662U6rCAIOuLpOumheuLiOuLpFwiKTtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBsaW5lczogc3RyaW5nW10gPSBbXG4gICAgJ2ltcG9ydCB7IEtuZXggfSBmcm9tIFwia25leFwiOycsXG4gICAgXCJcIixcbiAgICBcImV4cG9ydCBhc3luYyBmdW5jdGlvbiB1cChrbmV4OiBLbmV4KTogUHJvbWlzZTx2b2lkPiB7XCIsXG4gICAgYHJldHVybiBrbmV4LnNjaGVtYS5hbHRlclRhYmxlKFwiJHt0YWJsZX1cIiwgKHRhYmxlKSA9PiB7YCxcbiAgICBcIi8vIGNyZWF0ZSBma1wiLFxuICAgIC4uLnVwLFxuICAgIFwifSk7XCIsXG4gICAgXCJ9XCIsXG4gICAgXCJcIixcbiAgICBcImV4cG9ydCBhc3luYyBmdW5jdGlvbiBkb3duKGtuZXg6IEtuZXgpOiBQcm9taXNlPHZvaWQ+IHtcIixcbiAgICBgcmV0dXJuIGtuZXguc2NoZW1hLmFsdGVyVGFibGUoXCIke3RhYmxlfVwiLCAodGFibGUpID0+IHtgLFxuICAgIFwiLy8gZHJvcCBma1wiLFxuICAgIC4uLmRvd24sXG4gICAgXCJ9KTtcIixcbiAgICBcIn1cIixcbiAgXTtcblxuICBjb25zdCBmb3JlaWduS2V5c1N0cmluZyA9IGZvcmVpZ25zLm1hcCgoZm9yZWlnbikgPT4gZm9yZWlnbi5jb2x1bW5zLmpvaW4oXCJfXCIpKS5qb2luKFwiX1wiKTtcbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICB0YWJsZSxcbiAgICAgIHR5cGU6IFwiZm9yZWlnblwiLFxuICAgICAgdGl0bGU6IGBmb3JlaWduX18ke3RhYmxlfV9fJHtmb3JlaWduS2V5c1N0cmluZ31gLFxuICAgICAgZm9ybWF0dGVkOiBmb3JtYXRDb2RlKGxpbmVzLmpvaW4oXCJcXG5cIiksIFwidHlwZXNjcmlwdFwiLCBgc3JjL21pZ3JhdGlvbi8ke3RhYmxlfS50c2ApLFxuICAgIH0sXG4gIF07XG59XG5cbi8qKlxuICogTWlncmF0aW9uRm9yZWlnbltdIOydveyWtOyEnCDsmbjrtoDtgqQgY29uc3RyYWludCDsoJXsnZjtlZjripQg6rWs66y4IOyDneyEsVxuICovXG5mdW5jdGlvbiBnZW5Gb3JlaWduRGVmaW5pdGlvbnMoXG4gIHRhYmxlOiBzdHJpbmcsXG4gIGZvcmVpZ25zOiBNaWdyYXRpb25Gb3JlaWduW10sXG4pOiB7IHVwOiBzdHJpbmdbXTsgZG93bjogc3RyaW5nW10gfSB7XG4gIHJldHVybiBmb3JlaWducy5yZWR1Y2UoXG4gICAgKHIsIGZvcmVpZ24pID0+IHtcbiAgICAgIGNvbnN0IGNvbHVtbnNTdHJpbmdRdW90ZSA9IGZvcmVpZ24uY29sdW1uc1xuICAgICAgICAubWFwKChjb2wpID0+IGAnJHtjb2wucmVwbGFjZShgJHt0YWJsZX0uYCwgXCJcIil9J2ApXG4gICAgICAgIC5qb2luKFwiLFwiKTtcbiAgICAgIHIudXAucHVzaChcbiAgICAgICAgYHRhYmxlLmZvcmVpZ24oJyR7Zm9yZWlnbi5jb2x1bW5zLmpvaW4oXCIsXCIpfScpXG4gICAgICAgICAgICAucmVmZXJlbmNlcygnJHtmb3JlaWduLnRvfScpXG4gICAgICAgICAgICAub25VcGRhdGUoJyR7Zm9yZWlnbi5vblVwZGF0ZX0nKVxuICAgICAgICAgICAgLm9uRGVsZXRlKCcke2ZvcmVpZ24ub25EZWxldGV9JylgLFxuICAgICAgKTtcbiAgICAgIHIuZG93bi5wdXNoKGB0YWJsZS5kcm9wRm9yZWlnbihbJHtjb2x1bW5zU3RyaW5nUXVvdGV9XSlgKTtcbiAgICAgIHJldHVybiByO1xuICAgIH0sXG4gICAge1xuICAgICAgdXA6IFtdIGFzIHN0cmluZ1tdLFxuICAgICAgZG93bjogW10gYXMgc3RyaW5nW10sXG4gICAgfSxcbiAgKTtcbn1cblxuLyoqXG4gKiDthYzsnbTruJQg67OA6rK9IOy8gOydtOyKpCAtIOy7rOufvC/snbjrjbHsiqQg67OA6rK9XG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGdlbmVyYXRlQWx0ZXJDb2RlX0NvbHVtbkFuZEluZGV4ZXMoXG4gIHRhYmxlOiBzdHJpbmcsXG4gIGVudGl0eUNvbHVtbnM6IE1pZ3JhdGlvbkNvbHVtbltdLFxuICBlbnRpdHlJbmRleGVzOiBNaWdyYXRpb25JbmRleFtdLFxuICBkYkNvbHVtbnM6IE1pZ3JhdGlvbkNvbHVtbltdLFxuICBkYkluZGV4ZXM6IE1pZ3JhdGlvbkluZGV4W10sXG4gIGRiRm9yZWlnbnM6IE1pZ3JhdGlvbkZvcmVpZ25bXSxcbik6IFByb21pc2U8R2VuTWlncmF0aW9uQ29kZVtdPiB7XG4gIC8qXG4gICAg7IS467aAIOu5hOq1kCDtm4Qg64uk66W47KCQIOywvuyVhOyEnCDsvZTrk5wg7IOd7ISxXG5cbiAgICAxLiDsu6zrn7zqsK/siJgg64uk66aEOiBNROyXkCDsnojsnLzrgpgsIERC7JeQIOyXhuuLpOuptCDstpTqsIBcbiAgICAyLiDsu6zrn7zqsK/siJgg64uk66aEOiBNROyXkCDsl4bsnLzrgpgsIERC7JeQIOyeiOuLpOuptCDsgq3soJxcbiAgICAzLiDqt7jsmbgg7Lus65+8KOy7rOufvCDqsK/siJjqsIAg64+Z7J287ZWY6rGw64KYLCDri6Trpbgg6rK97JqwIOuPmeydvO2VnCDsu6zrn7zrgbzrpqwpID0+IGFsdGVyXG4gICAgNC4g64uk66W46rGwIOuLpCDrj5nsnbztlZjqs6AgaW5kZXjrp4wg67OA6rK965CY64qUIOqyveyasFxuXG4gICAgKiog7Lus65+866qF7J2EIOuzgOqyve2VmOuKlCDqsr3smrDripQg65Sw66GcIO2VuOuTpOunge2VmOyngCDslYrsnYxcbiAgICA9PiBkcm9wL2FkZCDtmJXtg5zsnZgg66eI7J206re466CI7J207IWYIOy9lOuTnOqwgCDsg53shLHrkJjripTrjbAsIOyImOuPmeycvOuhnCByZW5hbWUg7L2U65Oc66GcIOyImOygle2VmOyXrCDsspjrpqxcbiAgKi9cblxuICAvLyDqsIEg7Lus65+8IOydtOumhCDquLDspIDsnLzroZwgYWRkLCBkcm9wLCBhbHRlciDsl6zrtoAg7ZmV7J24XG4gIGNvbnN0IGFsdGVyQ29sdW1uc1RvID0gZ2V0QWx0ZXJDb2x1bW5zVG8oZW50aXR5Q29sdW1ucywgZGJDb2x1bW5zKTtcblxuICAvLyDstpTstpzrkJwg7Lus65+865Ok7J2EIOq4sOykgOycvOuhnCDqsIHqsIEg65287J24IOyDneyEsVxuICBjb25zdCBhbHRlckNvbHVtbkxpbmVzVG8gPSBnZXRBbHRlckNvbHVtbkxpbmVzVG8oXG4gICAgYWx0ZXJDb2x1bW5zVG8sXG4gICAgZW50aXR5Q29sdW1ucyxcbiAgICB0YWJsZSxcbiAgICBkYkZvcmVpZ25zLFxuICApO1xuXG4gIC8vIOyduOuNseyKpOydmCBhZGQsIGRyb3Ag7Jes67aAIO2ZleyduFxuICBjb25zdCBhbHRlckluZGV4ZXNUbyA9IGdldEFsdGVySW5kZXhlc1RvKGVudGl0eUluZGV4ZXMsIGRiSW5kZXhlcyk7XG5cbiAgLy8g7J24642x7Iqk6rCAIOyCreygnOuQmOuKlCDqsr3smrAsIOy7rOufvOqzvCDqsJnsnbQg7IKt7KCc65CcIOy8gOydtOyKpOyXkOuKlCBkcm9w7JeQ7IScIOygnOyZuO2VtOyVvO2VqCFcbiAgY29uc3QgaW5kZXhOZWVkc1RvRHJvcCA9IGFsdGVySW5kZXhlc1RvLmRyb3AuZmlsdGVyKFxuICAgIChpbmRleCkgPT5cbiAgICAgIGluZGV4LmNvbHVtbnMuZXZlcnkoKHsgbmFtZSB9KSA9PlxuICAgICAgICBhbHRlckNvbHVtbnNUby5kcm9wLm1hcCgoY29sKSA9PiBjb2wubmFtZSkuaW5jbHVkZXMobmFtZSksXG4gICAgICApID09PSBmYWxzZSxcbiAgKTtcblxuICAvLyDruYgg7L2U65OcIOyDneyEsSDrsKnsp4BcbiAgY29uc3QgaGFzVXBDaGFuZ2VzID1cbiAgICBhbHRlckNvbHVtbkxpbmVzVG8uYWRkLnVwLmJ1aWxkZXIubGVuZ3RoID4gMCB8fFxuICAgIGFsdGVyQ29sdW1uTGluZXNUby5hZGQudXAucmF3Lmxlbmd0aCA+IDAgfHxcbiAgICBhbHRlckNvbHVtbkxpbmVzVG8uZHJvcC51cC5idWlsZGVyLmxlbmd0aCA+IDAgfHxcbiAgICBhbHRlckNvbHVtbkxpbmVzVG8uYWx0ZXIudXAuYnVpbGRlci5sZW5ndGggPiAwIHx8XG4gICAgYWx0ZXJJbmRleGVzVG8uYWRkLmxlbmd0aCA+IDAgfHxcbiAgICBpbmRleE5lZWRzVG9Ecm9wLmxlbmd0aCA+IDA7XG4gIGlmICghaGFzVXBDaGFuZ2VzKSB7XG4gICAgTmFpdGUudChcIm1pZ3JhdG9yOmdlbmVyYXRlQWx0ZXJDb2RlX0NvbHVtbkFuZEluZGV4ZXM6ZW1wdHlDb2RlR2VuZXJhdGlvbkVycm9yXCIsIHtcbiAgICAgIGVudGl0eUNvbHVtbnMsXG4gICAgICBkYkNvbHVtbnMsXG4gICAgICBlbnRpdHlJbmRleGVzLFxuICAgICAgZGJJbmRleGVzLFxuICAgIH0pO1xuICAgIC8vIHRocm93IG5ldyBFcnJvcihcIuy7rOufvC/snbjrjbHsiqQg67OA6rK9IOy9lOuTnCDsg53shLEg7Jik66WYXCIpO1xuICB9XG4gIE5haXRlLnQoXCJtaWdyYXRvcjpnZW5lcmF0ZUFsdGVyQ29kZV9Db2x1bW5BbmRJbmRleGVzOmRlYnVnXCIsIHtcbiAgICBcImFsdGVyQ29sdW1uc1RvLmFkZC5sZW5ndGhcIjogYWx0ZXJDb2x1bW5zVG8uYWRkLmxlbmd0aCxcbiAgICBcImFsdGVyQ29sdW1uc1RvLmRyb3AubGVuZ3RoXCI6IGFsdGVyQ29sdW1uc1RvLmRyb3AubGVuZ3RoLFxuICAgIFwiYWx0ZXJDb2x1bW5zVG8uYWx0ZXIubGVuZ3RoXCI6IGFsdGVyQ29sdW1uc1RvLmFsdGVyLmxlbmd0aCxcbiAgICBcImFsdGVySW5kZXhlc1RvLmFkZC5sZW5ndGhcIjogYWx0ZXJJbmRleGVzVG8uYWRkLmxlbmd0aCxcbiAgICBcImFsdGVySW5kZXhlc1RvLmRyb3AubGVuZ3RoXCI6IGFsdGVySW5kZXhlc1RvLmRyb3AubGVuZ3RoLFxuICAgIFwiaW5kZXhOZWVkc1RvRHJvcC5sZW5ndGhcIjogaW5kZXhOZWVkc1RvRHJvcC5sZW5ndGgsXG4gIH0pO1xuICAvLyBOYWl0ZS50KFwibWlncmF0b3I6Z2VuZXJhdGVBbHRlckNvZGVfQ29sdW1uQW5kSW5kZXhlczphbHRlckNvbHVtbnNUb1wiLCBhbHRlckNvbHVtbnNUbyk7XG5cbiAgLy8gVE9ETzog7J24642x7Iqk66qFIOuzgOqyveuQnCDqsr3smrAg7LKY66asXG5cbiAgLy8gdGFibGUgYnVpbGRlciDrqZTshJzrk5zroZwg7Iuk7ZaJ7ZWgIOy9lOuTnCAoZHJvcCDihpIgYWRkIOKGkiBhbHRlciDsiJzshJwpXG4gIGNvbnN0IHVwQnVpbGRlckxpbmVzID0gW1xuICAgIC4uLihhbHRlckNvbHVtbkxpbmVzVG8uZHJvcC51cC5idWlsZGVyLmxlbmd0aCA+IDAgPyBhbHRlckNvbHVtbkxpbmVzVG8uZHJvcC51cC5idWlsZGVyIDogW10pLFxuICAgIC4uLihhbHRlckNvbHVtbkxpbmVzVG8uYWRkLnVwLmJ1aWxkZXIubGVuZ3RoID4gMCA/IGFsdGVyQ29sdW1uTGluZXNUby5hZGQudXAuYnVpbGRlciA6IFtdKSxcbiAgICAuLi4oYWx0ZXJDb2x1bW5MaW5lc1RvLmFsdGVyLnVwLmJ1aWxkZXIubGVuZ3RoID4gMCA/IGFsdGVyQ29sdW1uTGluZXNUby5hbHRlci51cC5idWlsZGVyIDogW10pLFxuICAgIC4uLmluZGV4TmVlZHNUb0Ryb3AubWFwKGdlbkluZGV4RHJvcERlZmluaXRpb24pLFxuICBdO1xuXG4gIC8vIGtuZXgucmF3KCnroZwg7Iuk7ZaJ7ZWgIOy9lOuTnFxuICBjb25zdCB1cFJhd0xpbmVzID0gW1xuICAgIC4uLihhbHRlckNvbHVtbkxpbmVzVG8uYWRkLnVwLnJhdy5sZW5ndGggPiAwID8gYWx0ZXJDb2x1bW5MaW5lc1RvLmFkZC51cC5yYXcgOiBbXSksXG4gICAgLi4uYWx0ZXJJbmRleGVzVG8uYWRkLm1hcCgoaW5kZXgpID0+IGdlbkluZGV4RGVmaW5pdGlvbihpbmRleCwgdGFibGUpKSxcbiAgXTtcblxuICAvLyBkb3du7J2AIHVw7J2YIOyXreyInCAoYWRkLmRvd24gPSBkcm9wIHJvbGxiYWNrLCBkcm9wLmRvd24gPSBhZGQgcm9sbGJhY2spXG4gIGNvbnN0IGRvd25CdWlsZGVyTGluZXMgPSBbXG4gICAgLi4uKGFsdGVyQ29sdW1uTGluZXNUby5hZGQuZG93bi5idWlsZGVyLmxlbmd0aCA+IDAgPyBhbHRlckNvbHVtbkxpbmVzVG8uYWRkLmRvd24uYnVpbGRlciA6IFtdKSxcbiAgICAuLi4oYWx0ZXJDb2x1bW5MaW5lc1RvLmFsdGVyLmRvd24uYnVpbGRlci5sZW5ndGggPiAwXG4gICAgICA/IGFsdGVyQ29sdW1uTGluZXNUby5hbHRlci5kb3duLmJ1aWxkZXJcbiAgICAgIDogW10pLFxuICAgIC4uLihhbHRlckNvbHVtbkxpbmVzVG8uZHJvcC5kb3duLmJ1aWxkZXIubGVuZ3RoID4gMFxuICAgICAgPyBhbHRlckNvbHVtbkxpbmVzVG8uZHJvcC5kb3duLmJ1aWxkZXJcbiAgICAgIDogW10pLFxuICAgIC4uLmFsdGVySW5kZXhlc1RvLmFkZFxuICAgICAgLmZpbHRlcihcbiAgICAgICAgKGluZGV4KSA9PlxuICAgICAgICAgIGluZGV4LmNvbHVtbnMuZXZlcnkoKGluZGV4Q29sKSA9PlxuICAgICAgICAgICAgYWx0ZXJDb2x1bW5zVG8uYWRkLm1hcCgoY29sKSA9PiBjb2wubmFtZSkuaW5jbHVkZXMoaW5kZXhDb2wubmFtZSksXG4gICAgICAgICAgKSA9PT0gZmFsc2UsXG4gICAgICApXG4gICAgICAubWFwKGdlbkluZGV4RHJvcERlZmluaXRpb24pLFxuICBdO1xuXG4gIGNvbnN0IGRvd25SYXdMaW5lcyA9IFtcbiAgICAuLi4oYWx0ZXJDb2x1bW5MaW5lc1RvLmRyb3AuZG93bi5yYXcubGVuZ3RoID4gMCA/IGFsdGVyQ29sdW1uTGluZXNUby5kcm9wLmRvd24ucmF3IDogW10pLFxuICAgIC4uLmluZGV4TmVlZHNUb0Ryb3AubWFwKChpbmRleCkgPT4gZ2VuSW5kZXhEZWZpbml0aW9uKGluZGV4LCB0YWJsZSkpLFxuICBdO1xuXG4gIGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtcbiAgICAnaW1wb3J0IHsgS25leCB9IGZyb20gXCJrbmV4XCI7JyxcbiAgICBcIlwiLFxuICAgIFwiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVwKGtuZXg6IEtuZXgpOiBQcm9taXNlPHZvaWQ+IHtcIixcbiAgICAuLi4odXBCdWlsZGVyTGluZXMubGVuZ3RoID4gMFxuICAgICAgPyBbYGF3YWl0IGtuZXguc2NoZW1hLmFsdGVyVGFibGUoXCIke3RhYmxlfVwiLCAodGFibGUpID0+IHtgLCAuLi51cEJ1aWxkZXJMaW5lcywgXCJ9KTtcIl1cbiAgICAgIDogW10pLFxuICAgIC4uLnVwUmF3TGluZXMsXG4gICAgXCJ9XCIsXG4gICAgXCJcIixcbiAgICBcImV4cG9ydCBhc3luYyBmdW5jdGlvbiBkb3duKGtuZXg6IEtuZXgpOiBQcm9taXNlPHZvaWQ+IHtcIixcbiAgICAuLi4oZG93bkJ1aWxkZXJMaW5lcy5sZW5ndGggPiAwXG4gICAgICA/IFtgYXdhaXQga25leC5zY2hlbWEuYWx0ZXJUYWJsZShcIiR7dGFibGV9XCIsICh0YWJsZSkgPT4ge2AsIC4uLmRvd25CdWlsZGVyTGluZXMsIFwifSk7XCJdXG4gICAgICA6IFtdKSxcbiAgICAuLi5kb3duUmF3TGluZXMsXG4gICAgXCJ9XCIsXG4gIF07XG5cbiAgY29uc3QgZm9ybWF0dGVkID0gZm9ybWF0Q29kZShsaW5lcy5qb2luKFwiXFxuXCIpLCBcInR5cGVzY3JpcHRcIiwgYHNyYy9taWdyYXRpb24vJHt0YWJsZX0udHNgKTtcbiAgY29uc3QgdGl0bGUgPSBbXG4gICAgXCJhbHRlclwiLFxuICAgIHRhYmxlLFxuICAgIC4uLihbXCJhZGRcIiwgXCJkcm9wXCIsIFwiYWx0ZXJcIl0gYXMgY29uc3QpXG4gICAgICAubWFwKChhY3Rpb24pID0+IHtcbiAgICAgICAgY29uc3QgbGVuID0gYWx0ZXJDb2x1bW5zVG9bYWN0aW9uXS5sZW5ndGg7XG4gICAgICAgIGlmIChsZW4gPiAwKSB7XG4gICAgICAgICAgcmV0dXJuIGFjdGlvbiArIGxlbjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0pXG4gICAgICAuZmlsdGVyKChwYXJ0KSA9PiBwYXJ0ICE9PSBudWxsKSxcbiAgXS5qb2luKFwiX1wiKTtcblxuICByZXR1cm4gW1xuICAgIHtcbiAgICAgIHRhYmxlLFxuICAgICAgdGl0bGUsXG4gICAgICBmb3JtYXR0ZWQsXG4gICAgICB0eXBlOiBcIm5vcm1hbFwiLFxuICAgIH0sXG4gIF07XG59XG5cbi8qKlxuICog7Lus65+8IOu5hOq1kOulvCDsnITtlbQgR2VuZXJhdGVkIENvbHVtbuydmCBleHByZXNzaW9u7J2EIOygnOyZuO2VnCDqsJ3ssrTrpbwg7IOd7ISxXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZUNvbHVtbkZvckNvbXBhcmlzb24oY29sOiBNaWdyYXRpb25Db2x1bW4pOiBNaWdyYXRpb25Db2x1bW4ge1xuICBpZiAoY29sLmdlbmVyYXRlZCkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi5jb2wsXG4gICAgICBnZW5lcmF0ZWQ6IHtcbiAgICAgICAgdHlwZTogY29sLmdlbmVyYXRlZC50eXBlLFxuICAgICAgICBleHByZXNzaW9uOiBcIlwiLFxuICAgICAgfSxcbiAgICB9O1xuICB9XG4gIHJldHVybiBjb2w7XG59XG5cbi8qKlxuICog6rCBIOy7rOufvCDsnbTrpoQg6riw7KSA7Jy866GcIGFkZCwgZHJvcCwgYWx0ZXIg7Jes67aAIO2ZleyduFxuICovXG5mdW5jdGlvbiBnZXRBbHRlckNvbHVtbnNUbyhlbnRpdHlDb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSwgZGJDb2x1bW5zOiBNaWdyYXRpb25Db2x1bW5bXSkge1xuICBjb25zdCBjb2x1bW5zVG8gPSB7XG4gICAgYWRkOiBbXSBhcyBNaWdyYXRpb25Db2x1bW5bXSxcbiAgICBkcm9wOiBbXSBhcyBNaWdyYXRpb25Db2x1bW5bXSxcbiAgICBhbHRlcjogW10gYXMgTWlncmF0aW9uQ29sdW1uW10sXG4gIH07XG5cbiAgLy8g7Lus65+866qFIOq4sOykgCDruYTqtZBcbiAgY29uc3QgZXh0cmFDb2x1bW5zID0ge1xuICAgIGRiOiBkaWZmKGRiQ29sdW1ucywgZW50aXR5Q29sdW1ucywgKGNvbCkgPT4gW2NvbC5uYW1lLCBjb2wuZ2VuZXJhdGVkPy50eXBlXS5qb2luKFwiLy8vXCIpKSxcbiAgICBlbnRpdHk6IGRpZmYoZW50aXR5Q29sdW1ucywgZGJDb2x1bW5zLCAoY29sKSA9PiBbY29sLm5hbWUsIGNvbC5nZW5lcmF0ZWQ/LnR5cGVdLmpvaW4oXCIvLy9cIikpLFxuICB9O1xuICBpZiAoZXh0cmFDb2x1bW5zLmVudGl0eS5sZW5ndGggPiAwKSB7XG4gICAgY29sdW1uc1RvLmFkZCA9IGNvbHVtbnNUby5hZGQuY29uY2F0KGV4dHJhQ29sdW1ucy5lbnRpdHkpO1xuICB9XG4gIGlmIChleHRyYUNvbHVtbnMuZGIubGVuZ3RoID4gMCkge1xuICAgIGNvbHVtbnNUby5kcm9wID0gY29sdW1uc1RvLmRyb3AuY29uY2F0KGV4dHJhQ29sdW1ucy5kYik7XG4gIH1cblxuICAvLyDrj5nsnbwg7Lus65+866qF7J2YIOyEuOu2gCDtlYTrk5wg67mE6rWQIChHZW5lcmF0ZWQgQ29sdW1uIGV4cHJlc3Npb24g7KCc7Jm4KVxuICBjb25zdCBzYW1lRGJDb2x1bW5zID0gaW50ZXJzZWN0aW9uQnkoZGJDb2x1bW5zLCBlbnRpdHlDb2x1bW5zLCAoY29sKSA9PiBjb2wubmFtZSk7XG4gIGNvbnN0IHNhbWVNZENvbHVtbnMgPSBpbnRlcnNlY3Rpb25CeShlbnRpdHlDb2x1bW5zLCBkYkNvbHVtbnMsIChjb2wpID0+IGNvbC5uYW1lKTtcbiAgY29sdW1uc1RvLmFsdGVyID0gZGlmZmVyZW5jZVdpdGgoXG4gICAgc2FtZURiQ29sdW1ucyxcbiAgICBzYW1lTWRDb2x1bW5zLFxuICAgIChhLCBiKSA9PiBlcXVhbCh7IC4uLmEsIGdlbmVyYXRlZDogdW5kZWZpbmVkIH0sIHsgLi4uYiwgZ2VuZXJhdGVkOiB1bmRlZmluZWQgfSksIC8vIGdlbmVyYXRlZCDsu6zrn7zsnYAgYWx0ZXLroZwg7LKY66as7ZWY7KeAIOyViuydjFxuICApO1xuXG4gIHJldHVybiBjb2x1bW5zVG87XG59XG5cbi8qKlxuICog7LaU7Lac65CcIOy7rOufvOuTpOydhCDquLDspIDsnLzroZwg6rCB6rCBIOudvOyduCDsg53shLFcbiAqL1xuZnVuY3Rpb24gZ2V0QWx0ZXJDb2x1bW5MaW5lc1RvKFxuICBjb2x1bW5zVG86IFJldHVyblR5cGU8dHlwZW9mIGdldEFsdGVyQ29sdW1uc1RvPixcbiAgZW50aXR5Q29sdW1uczogTWlncmF0aW9uQ29sdW1uW10sXG4gIHRhYmxlOiBzdHJpbmcsXG4gIGRiRm9yZWlnbnM6IE1pZ3JhdGlvbkZvcmVpZ25bXSxcbikge1xuICBjb25zdCBsaW5lc1RvID0ge1xuICAgIGFkZDoge1xuICAgICAgdXA6IHsgYnVpbGRlcjogW10gYXMgc3RyaW5nW10sIHJhdzogW10gYXMgc3RyaW5nW10gfSxcbiAgICAgIGRvd246IHsgYnVpbGRlcjogW10gYXMgc3RyaW5nW10sIHJhdzogW10gYXMgc3RyaW5nW10gfSxcbiAgICB9LFxuICAgIGRyb3A6IHtcbiAgICAgIHVwOiB7IGJ1aWxkZXI6IFtdIGFzIHN0cmluZ1tdLCByYXc6IFtdIGFzIHN0cmluZ1tdIH0sXG4gICAgICBkb3duOiB7IGJ1aWxkZXI6IFtdIGFzIHN0cmluZ1tdLCByYXc6IFtdIGFzIHN0cmluZ1tdIH0sXG4gICAgfSxcbiAgICBhbHRlcjoge1xuICAgICAgdXA6IHsgYnVpbGRlcjogW10gYXMgc3RyaW5nW10sIHJhdzogW10gYXMgc3RyaW5nW10gfSxcbiAgICAgIGRvd246IHsgYnVpbGRlcjogW10gYXMgc3RyaW5nW10sIHJhdzogW10gYXMgc3RyaW5nW10gfSxcbiAgICB9LFxuICB9O1xuXG4gIC8vIGFkZCBjb2x1bW5zXG4gIGNvbnN0IGFkZENvbHVtbkRlZnMgPSBnZW5Db2x1bW5EZWZpbml0aW9ucyh0YWJsZSwgY29sdW1uc1RvLmFkZCk7XG4gIGxpbmVzVG8uYWRkLnVwID0ge1xuICAgIGJ1aWxkZXI6IGFkZENvbHVtbkRlZnMuYnVpbGRlci5sZW5ndGggPiAwID8gW1wiLy8gYWRkXCIsIC4uLmFkZENvbHVtbkRlZnMuYnVpbGRlcl0gOiBbXSxcbiAgICByYXc6IGFkZENvbHVtbkRlZnMucmF3Lmxlbmd0aCA+IDAgPyBbXCIvLyBhZGQgKGdlbmVyYXRlZClcIiwgLi4uYWRkQ29sdW1uRGVmcy5yYXddIDogW10sXG4gIH07XG4gIGxpbmVzVG8uYWRkLmRvd24gPSB7XG4gICAgYnVpbGRlcjpcbiAgICAgIGNvbHVtbnNUby5hZGQubGVuZ3RoID4gMFxuICAgICAgICA/IFtcbiAgICAgICAgICAgIFwiLy8gcm9sbGJhY2sgLSBhZGRcIixcbiAgICAgICAgICAgIGB0YWJsZS5kcm9wQ29sdW1ucygke2NvbHVtbnNUby5hZGQubWFwKChjb2wpID0+IGAnJHtjb2wubmFtZX0nYCkuam9pbihcIiwgXCIpfSlgLFxuICAgICAgICAgIF1cbiAgICAgICAgOiBbXSxcbiAgICByYXc6IFtdLFxuICB9O1xuXG4gIC8vIGRyb3DtlaAg7Lus65+87JeQIOqxuOumsCBGSyDssL7quLBcbiAgY29uc3QgZHJvcENvbHVtbk5hbWVzID0gY29sdW1uc1RvLmRyb3AubWFwKChjb2wpID0+IGNvbC5uYW1lKTtcbiAgY29uc3QgZmtUb0Ryb3BCZWZvcmVDb2x1bW4gPSBkYkZvcmVpZ25zLmZpbHRlcigoZmspID0+XG4gICAgZmsuY29sdW1ucy5zb21lKChjb2wpID0+IGRyb3BDb2x1bW5OYW1lcy5pbmNsdWRlcyhjb2wpKSxcbiAgKTtcblxuICBjb25zdCBkcm9wRmtMaW5lcyA9IGZrVG9Ecm9wQmVmb3JlQ29sdW1uLm1hcCgoZmspID0+IHtcbiAgICBjb25zdCBjb2x1bW5zU3RyaW5nUXVvdGUgPSBmay5jb2x1bW5zLm1hcCgoY29sKSA9PiBgJyR7Y29sfSdgKS5qb2luKFwiLFwiKTtcbiAgICByZXR1cm4gYHRhYmxlLmRyb3BGb3JlaWduKFske2NvbHVtbnNTdHJpbmdRdW90ZX1dKWA7XG4gIH0pO1xuXG4gIGNvbnN0IHJlc3RvcmVGa0xpbmVzID0gZ2VuRm9yZWlnbkRlZmluaXRpb25zKHRhYmxlLCBma1RvRHJvcEJlZm9yZUNvbHVtbikudXA7XG5cbiAgLy8gZHJvcOydmCByb2xsYmFja+yLnOyXkOuKlCBnZW5lcmF0ZWQgY29sdW1u64+EIOuzteybkO2VtOyVvCDtlahcbiAgY29uc3QgZHJvcENvbHVtbkRlZnMgPSBnZW5Db2x1bW5EZWZpbml0aW9ucyh0YWJsZSwgY29sdW1uc1RvLmRyb3ApO1xuICBsaW5lc1RvLmRyb3AgPSB7XG4gICAgdXA6IHtcbiAgICAgIGJ1aWxkZXI6IFtcbiAgICAgICAgLi4uKGRyb3BGa0xpbmVzLmxlbmd0aCA+IDBcbiAgICAgICAgICA/IFtcIi8vIGRyb3AgZm9yZWlnbiBrZXlzIG9uIGNvbHVtbnMgdG8gYmUgZHJvcHBlZFwiLCAuLi5kcm9wRmtMaW5lc11cbiAgICAgICAgICA6IFtdKSxcbiAgICAgICAgLi4uKGNvbHVtbnNUby5kcm9wLmxlbmd0aCA+IDBcbiAgICAgICAgICA/IFtcbiAgICAgICAgICAgICAgXCIvLyBkcm9wIGNvbHVtbnNcIixcbiAgICAgICAgICAgICAgYHRhYmxlLmRyb3BDb2x1bW5zKCR7Y29sdW1uc1RvLmRyb3AubWFwKChjb2wpID0+IGAnJHtjb2wubmFtZX0nYCkuam9pbihcIiwgXCIpfSlgLFxuICAgICAgICAgICAgXVxuICAgICAgICAgIDogW10pLFxuICAgICAgXSxcbiAgICAgIHJhdzogW10sXG4gICAgfSxcbiAgICBkb3duOiB7XG4gICAgICBidWlsZGVyOiBbXG4gICAgICAgIC4uLihkcm9wQ29sdW1uRGVmcy5idWlsZGVyLmxlbmd0aCA+IDBcbiAgICAgICAgICA/IFtcIi8vIHJvbGxiYWNrIC0gZHJvcCBjb2x1bW5zXCIsIC4uLmRyb3BDb2x1bW5EZWZzLmJ1aWxkZXJdXG4gICAgICAgICAgOiBbXSksXG4gICAgICAgIC4uLihyZXN0b3JlRmtMaW5lcy5sZW5ndGggPiAwID8gW1wiLy8gcmVzdG9yZSBmb3JlaWduIGtleXNcIiwgLi4ucmVzdG9yZUZrTGluZXNdIDogW10pLFxuICAgICAgXSxcbiAgICAgIHJhdzpcbiAgICAgICAgZHJvcENvbHVtbkRlZnMucmF3Lmxlbmd0aCA+IDBcbiAgICAgICAgICA/IFtcIi8vIHJvbGxiYWNrIC0gZHJvcCBjb2x1bW5zIChnZW5lcmF0ZWQpXCIsIC4uLmRyb3BDb2x1bW5EZWZzLnJhd11cbiAgICAgICAgICA6IFtdLFxuICAgIH0sXG4gIH07XG5cbiAgLy8gYWx0ZXIgY29sdW1ucyAoR2VuZXJhdGVkIENvbHVtbuydgCBBTFRFUiDrtojqsIDtlZjrr4DroZwgZHJvcCDtm4Qg7J6s7IOd7ISxKVxuICBsaW5lc1RvLmFsdGVyID0gY29sdW1uc1RvLmFsdGVyLnJlZHVjZShcbiAgICAociwgZGJDb2x1bW4pID0+IHtcbiAgICAgIGNvbnN0IGVudGl0eUNvbHVtbiA9IGVudGl0eUNvbHVtbnMuZmluZCgoY29sKSA9PiBjb2wubmFtZSA9PT0gZGJDb2x1bW4ubmFtZSk7XG4gICAgICBpZiAoZW50aXR5Q29sdW1uID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHI7XG4gICAgICB9XG5cbiAgICAgIC8vIOy7rOufvCDrs4Dqsr3sgqztla1cbiAgICAgIGNvbnN0IGNvbHVtbkRpZmZVcCA9IGRpZmYoXG4gICAgICAgIGdlbkNvbHVtbkRlZmluaXRpb25zKHRhYmxlLCBbZW50aXR5Q29sdW1uXSkuYnVpbGRlcixcbiAgICAgICAgZ2VuQ29sdW1uRGVmaW5pdGlvbnModGFibGUsIFtkYkNvbHVtbl0pLmJ1aWxkZXIsXG4gICAgICApO1xuICAgICAgY29uc3QgY29sdW1uRGlmZkRvd24gPSBkaWZmKFxuICAgICAgICBnZW5Db2x1bW5EZWZpbml0aW9ucyh0YWJsZSwgW2RiQ29sdW1uXSkuYnVpbGRlcixcbiAgICAgICAgZ2VuQ29sdW1uRGVmaW5pdGlvbnModGFibGUsIFtlbnRpdHlDb2x1bW5dKS5idWlsZGVyLFxuICAgICAgKTtcbiAgICAgIGlmIChjb2x1bW5EaWZmVXAubGVuZ3RoID4gMCkge1xuICAgICAgICByLnVwLmJ1aWxkZXIgPSBbXG4gICAgICAgICAgLi4uci51cC5idWlsZGVyLFxuICAgICAgICAgIFwiLy8gYWx0ZXIgY29sdW1uXCIsXG4gICAgICAgICAgLi4uY29sdW1uRGlmZlVwLm1hcCgobCkgPT4gYCR7bC5yZXBsYWNlKFwiO1wiLCBcIlwiKX0uYWx0ZXIoKTtgKSxcbiAgICAgICAgXTtcbiAgICAgICAgci5kb3duLmJ1aWxkZXIgPSBbXG4gICAgICAgICAgLi4uci5kb3duLmJ1aWxkZXIsXG4gICAgICAgICAgXCIvLyByb2xsYmFjayAtIGFsdGVyIGNvbHVtblwiLFxuICAgICAgICAgIC4uLmNvbHVtbkRpZmZEb3duLm1hcCgobCkgPT4gYCR7bC5yZXBsYWNlKFwiO1wiLCBcIlwiKX0uYWx0ZXIoKTtgKSxcbiAgICAgICAgXTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHI7XG4gICAgfSxcbiAgICB7XG4gICAgICB1cDogeyBidWlsZGVyOiBbXSBhcyBzdHJpbmdbXSwgcmF3OiBbXSBhcyBzdHJpbmdbXSB9LFxuICAgICAgZG93bjogeyBidWlsZGVyOiBbXSBhcyBzdHJpbmdbXSwgcmF3OiBbXSBhcyBzdHJpbmdbXSB9LFxuICAgIH0sXG4gICk7XG5cbiAgcmV0dXJuIGxpbmVzVG87XG59XG5cbi8qKlxuICog7J24642x7Iqk7J2YIGFkZCwgZHJvcCDsl6zrtoAg7ZmV7J24XG4gKi9cbmZ1bmN0aW9uIGdldEFsdGVySW5kZXhlc1RvKGVudGl0eUluZGV4ZXM6IE1pZ3JhdGlvbkluZGV4W10sIGRiSW5kZXhlczogTWlncmF0aW9uSW5kZXhbXSkge1xuICAvLyDsnbjrjbHsiqQg67mE6rWQXG4gIGNvbnN0IGluZGV4ZXNUbyA9IHtcbiAgICBhZGQ6IFtdIGFzIE1pZ3JhdGlvbkluZGV4W10sXG4gICAgZHJvcDogW10gYXMgTWlncmF0aW9uSW5kZXhbXSxcbiAgfTtcblxuICAvLyDsnbjrjbHsiqQg6rOg7JygIOyLneuzhOyekCDsg53shLEgKG5hbWXsnYQg7KCc7Jm47ZWcIOuqqOuToCDtlYTrk5zrpbwg66y47J6Q7Je066GcIOuzgO2ZmO2VmOyXrCDsobDtlakpXG4gIGNvbnN0IGlkZW50aXR5ID0gPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4oaW5kZXg6IFQpOiBzdHJpbmcgPT4ge1xuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhpbmRleClcbiAgICAgIC5maWx0ZXIoKGtleSkgPT4ga2V5ICE9PSBcIm5hbWVcIilcbiAgICAgIC5zb3J0KCk7XG5cbiAgICByZXR1cm4ga2V5c1xuICAgICAgLm1hcCgoa2V5KSA9PiB7XG4gICAgICAgIGlmIChrZXkgPT09IFwibmFtZVwiKSB7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoa2V5ID09PSBcImNvbHVtbnNcIikge1xuICAgICAgICAgIHJldHVybiAoaW5kZXhba2V5XSBhcyBNaWdyYXRpb25JbmRleFtcImNvbHVtbnNcIl0pLmZsYXRNYXAoaWRlbnRpdHkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgJHtrZXl9PSR7aW5kZXhba2V5IGFzIGtleW9mIE1pZ3JhdGlvbkluZGV4XX1gO1xuICAgICAgfSlcbiAgICAgIC5qb2luKFwiLy9cIik7XG4gIH07XG5cbiAgY29uc3QgZXh0cmFJbmRleGVzID0ge1xuICAgIGRiOiBkaWZmKGRiSW5kZXhlcywgZW50aXR5SW5kZXhlcy5tYXAoc2V0TWlncmF0aW9uSW5kZXhEZWZhdWx0cyksIGlkZW50aXR5KSxcbiAgICBlbnRpdHk6IGRpZmYoZW50aXR5SW5kZXhlcy5tYXAoc2V0TWlncmF0aW9uSW5kZXhEZWZhdWx0cyksIGRiSW5kZXhlcywgaWRlbnRpdHkpLFxuICB9O1xuICBpZiAoZXh0cmFJbmRleGVzLmVudGl0eS5sZW5ndGggPiAwKSB7XG4gICAgaW5kZXhlc1RvLmFkZCA9IGluZGV4ZXNUby5hZGQuY29uY2F0KGV4dHJhSW5kZXhlcy5lbnRpdHkpO1xuICB9XG4gIGlmIChleHRyYUluZGV4ZXMuZGIubGVuZ3RoID4gMCkge1xuICAgIGluZGV4ZXNUby5kcm9wID0gaW5kZXhlc1RvLmRyb3AuY29uY2F0KGV4dHJhSW5kZXhlcy5kYik7XG4gIH1cblxuICByZXR1cm4gaW5kZXhlc1RvO1xufVxuXG4vKipcbiAqIOyduOuNseyKpCDsgq3soJwg7KCV7J2YIOyDneyEsVxuICovXG5mdW5jdGlvbiBnZW5JbmRleERyb3BEZWZpbml0aW9uKGluZGV4OiBNaWdyYXRpb25JbmRleCkge1xuICByZXR1cm4gYHRhYmxlLmRyb3BJbmRleChbJHtpbmRleC5jb2x1bW5zXG4gICAgLm1hcCgoY29sdW1uKSA9PiBgJyR7Y29sdW1uLm5hbWV9J2ApXG4gICAgLmpvaW4oXCIsXCIpfV0sICcke2luZGV4Lm5hbWV9JylgO1xufVxuXG4vKipcbiAqIERCIOyhsO2ajCDqsrDqs7zsmYAg67mE6rWQ7ZWY6riwIOychO2VnCDsnbjrjbHsiqQg6riw67O46rCSIOyEpOyglVxuICovXG5mdW5jdGlvbiBzZXRNaWdyYXRpb25JbmRleERlZmF1bHRzKGluZGV4OiBNaWdyYXRpb25JbmRleCk6IE1pZ3JhdGlvbkluZGV4IHtcbiAgcmV0dXJuIHtcbiAgICAuLi5pbmRleCxcbiAgICBjb2x1bW5zOiBpbmRleC5jb2x1bW5zLm1hcCgoY29sKSA9PiAoe1xuICAgICAgLi4uY29sLFxuICAgICAgc29ydE9yZGVyOiBjb2wuc29ydE9yZGVyID8/IFwiQVNDXCIsXG4gICAgICAvLyBzb3J0T3JkZXLsl5Ag65Sw6528IG51bGxzRmlyc3TsnZggZGVmYXVsdCDqsJIg7ISk7KCVXG4gICAgICBudWxsc0ZpcnN0OiBjb2wubnVsbHNGaXJzdCA/PyBjb2wuc29ydE9yZGVyID09PSBcIkRFU0NcIixcbiAgICB9KSksXG4gICAgbnVsbHNOb3REaXN0aW5jdDogaW5kZXgubnVsbHNOb3REaXN0aW5jdCA/PyBmYWxzZSxcbiAgfTtcbn1cblxuLyoqXG4gKiDthYzsnbTruJQg67OA6rK9IOy8gOydtOyKpCAtIEZvcmVpZ24gS2V5IOuzgOqyvVxuICovXG5hc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUFsdGVyQ29kZV9Gb3JlaWducyhcbiAgdGFibGU6IHN0cmluZyxcbiAgZW50aXR5Rm9yZWlnbnM6IE1pZ3JhdGlvbkZvcmVpZ25bXSxcbiAgZGJGb3JlaWduczogTWlncmF0aW9uRm9yZWlnbltdLFxuICBkcm9wcGluZ0NvbHVtbnM6IE1pZ3JhdGlvbkNvbHVtbltdID0gW10sXG4pOiBQcm9taXNlPEdlbk1pZ3JhdGlvbkNvZGVbXT4ge1xuICAvLyBjb25zb2xlLmxvZyh7IGVudGl0eUZvcmVpZ25zLCBkYkZvcmVpZ25zIH0pO1xuXG4gIGNvbnN0IGdldEtleSA9IChtZjogTWlncmF0aW9uRm9yZWlnbik6IHN0cmluZyA9PiB7XG4gICAgcmV0dXJuIFttZi5jb2x1bW5zLmpvaW4oXCItXCIpLCBtZi50b10uam9pbihcIi8vL1wiKTtcbiAgfTtcblxuICAvLyDsgq3soJzrkKAg7Lus65+866qFIOuqqeuhnVxuICBjb25zdCBkcm9wcGluZ0NvbHVtbk5hbWVzID0gZHJvcHBpbmdDb2x1bW5zLm1hcCgoY29sKSA9PiBjb2wubmFtZSk7XG5cbiAgY29uc3QgZmtUbyA9IGVudGl0eUZvcmVpZ25zLnJlZHVjZShcbiAgICAocmVzdWx0LCBlbnRpdHlGKSA9PiB7XG4gICAgICBjb25zdCBtYXRjaGluZ0RiRiA9IGRiRm9yZWlnbnMuZmluZCgoZGJGKSA9PiBnZXRLZXkoZW50aXR5RikgPT09IGdldEtleShkYkYpKTtcbiAgICAgIGlmICghbWF0Y2hpbmdEYkYpIHtcbiAgICAgICAgcmVzdWx0LmFkZC5wdXNoKGVudGl0eUYpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBpZiAoZXF1YWwoZW50aXR5RiwgbWF0Y2hpbmdEYkYpID09PSBmYWxzZSkge1xuICAgICAgICByZXN1bHQuYWx0ZXJTcmMucHVzaChtYXRjaGluZ0RiRik7XG4gICAgICAgIHJlc3VsdC5hbHRlckRzdC5wdXNoKGVudGl0eUYpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LFxuICAgIHtcbiAgICAgIGFkZDogW10gYXMgTWlncmF0aW9uRm9yZWlnbltdLFxuICAgICAgZHJvcDogW10gYXMgTWlncmF0aW9uRm9yZWlnbltdLFxuICAgICAgYWx0ZXJTcmM6IFtdIGFzIE1pZ3JhdGlvbkZvcmVpZ25bXSxcbiAgICAgIGFsdGVyRHN0OiBbXSBhcyBNaWdyYXRpb25Gb3JlaWduW10sXG4gICAgfSxcbiAgKTtcblxuICAvLyBkYkZvcmVpZ25z7JeQ64qUIOyeiOyngOunjCBlbnRpdHlGb3JlaWduc+yXkOuKlCDsl4bripQg6rK97JqwICjsgq3soJzrkJwgRkspXG4gIC8vIOuLqCwg7IKt7KCc65CgIOy7rOufvOydmCBGS+uKlCDsoJzsmbggKGdlbmVyYXRlQWx0ZXJDb2RlX0NvbHVtbkFuZEluZGV4ZXPsl5DshJwg7LKY66asKVxuICBkYkZvcmVpZ25zLmZvckVhY2goKGRiRikgPT4ge1xuICAgIGNvbnN0IG1hdGNoaW5nRW50aXR5RiA9IGVudGl0eUZvcmVpZ25zLmZpbmQoKGVudGl0eUYpID0+IGdldEtleShlbnRpdHlGKSA9PT0gZ2V0S2V5KGRiRikpO1xuICAgIGlmICghbWF0Y2hpbmdFbnRpdHlGKSB7XG4gICAgICAvLyDsnbQgRkvsnZgg7Lus65+87J20IOyCreygnOuQoCDsu6zrn7wg66qp66Gd7JeQIOyeiOuKlOyngCDtmZXsnbhcbiAgICAgIGNvbnN0IGlzQ29sdW1uRHJvcHBpbmcgPSBkYkYuY29sdW1ucy5zb21lKChjb2wpID0+IGRyb3BwaW5nQ29sdW1uTmFtZXMuaW5jbHVkZXMoY29sKSk7XG4gICAgICAvLyDsu6zrn7zsnbQg7IKt7KCc65CY7KeAIOyViuuKlCDqsr3smrDsl5Drp4wgRksgZHJvcCDrqqnroZ3sl5Ag7LaU6rCAXG4gICAgICBpZiAoIWlzQ29sdW1uRHJvcHBpbmcpIHtcbiAgICAgICAgZmtUby5kcm9wLnB1c2goZGJGKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIGNvbnN0IGxpbmVzVG8gPSB7XG4gICAgYWRkOiBnZW5Gb3JlaWduRGVmaW5pdGlvbnModGFibGUsIGZrVG8uYWRkKSxcbiAgICBkcm9wOiBnZW5Gb3JlaWduRGVmaW5pdGlvbnModGFibGUsIGZrVG8uZHJvcCksXG4gICAgYWx0ZXJTcmM6IGdlbkZvcmVpZ25EZWZpbml0aW9ucyh0YWJsZSwgZmtUby5hbHRlclNyYyksXG4gICAgYWx0ZXJEc3Q6IGdlbkZvcmVpZ25EZWZpbml0aW9ucyh0YWJsZSwgZmtUby5hbHRlckRzdCksXG4gIH07XG5cbiAgLy8gZHJvcCBmayBjb2x1bW5z7J24IOqyveyasCjsg53shLHrkKAg7L2U65OcIOyXhuuKlCDqsr3smrApIO2MqOyKpFxuICBjb25zdCBoYXNMaW5lcyA9IE9iamVjdC52YWx1ZXMobGluZXNUbykuc29tZSgobCkgPT4gbC51cC5sZW5ndGggPiAwIHx8IGwuZG93bi5sZW5ndGggPiAwKTtcbiAgaWYgKCFoYXNMaW5lcykge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGlmIChcbiAgICBsaW5lc1RvLmFkZC51cC5sZW5ndGggPT09IDAgJiZcbiAgICBsaW5lc1RvLmRyb3AudXAubGVuZ3RoID09PSAwICYmXG4gICAgbGluZXNUby5hbHRlclNyYy51cC5sZW5ndGggPT09IDAgJiZcbiAgICBsaW5lc1RvLmFsdGVyRHN0LnVwLmxlbmd0aCA9PT0gMFxuICApIHtcbiAgICBOYWl0ZS50KFwibWlncmF0b3I6Z2VuZXJhdGVBbHRlckNvZGVfRm9yZWlnbnM6ZmtDaGFuZ2VDb2RlR2VuZXJhdGlvbkVycm9yXCIsIHtcbiAgICAgIHRhYmxlLFxuICAgICAgZW50aXR5Rm9yZWlnbnMsXG4gICAgICBkYkZvcmVpZ25zLFxuICAgIH0pO1xuICAgIHRocm93IG5ldyBFcnJvcihcIkZLIOuzgOqyvSDsvZTrk5wg7IOd7ISxIOyYpOulmFwiKTtcbiAgfVxuXG4gIGNvbnN0IGxpbmVzOiBzdHJpbmdbXSA9IFtcbiAgICAnaW1wb3J0IHsgS25leCB9IGZyb20gXCJrbmV4XCI7JyxcbiAgICBcIlwiLFxuICAgIFwiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVwKGtuZXg6IEtuZXgpOiBQcm9taXNlPHZvaWQ+IHtcIixcbiAgICBgcmV0dXJuIGtuZXguc2NoZW1hLmFsdGVyVGFibGUoXCIke3RhYmxlfVwiLCAodGFibGUpID0+IHtgLFxuICAgIC4uLmxpbmVzVG8uZHJvcC5kb3duLFxuICAgIC4uLmxpbmVzVG8uYWRkLnVwLFxuICAgIC4uLmxpbmVzVG8uYWx0ZXJTcmMuZG93bixcbiAgICAuLi5saW5lc1RvLmFsdGVyRHN0LnVwLFxuICAgIFwifSlcIixcbiAgICBcIn1cIixcbiAgICBcIlwiLFxuICAgIFwiZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRvd24oa25leDogS25leCk6IFByb21pc2U8dm9pZD4ge1wiLFxuICAgIGByZXR1cm4ga25leC5zY2hlbWEuYWx0ZXJUYWJsZShcIiR7dGFibGV9XCIsICh0YWJsZSkgPT4ge2AsXG4gICAgLi4ubGluZXNUby5hZGQuZG93bixcbiAgICAuLi5saW5lc1RvLmFsdGVyRHN0LmRvd24sXG4gICAgLi4ubGluZXNUby5hbHRlclNyYy51cCxcbiAgICAuLi5saW5lc1RvLmRyb3AudXAsXG4gICAgXCJ9KVwiLFxuICAgIFwifVwiLFxuICBdO1xuXG4gIGNvbnN0IGZvcm1hdHRlZCA9IGZvcm1hdENvZGUobGluZXMuam9pbihcIlxcblwiKSwgXCJ0eXBlc2NyaXB0XCIsIGBzcmMvbWlncmF0aW9uLyR7dGFibGV9LnRzYCk7XG4gIGNvbnN0IHRpdGxlID0gW1xuICAgIFwiYWx0ZXJcIixcbiAgICB0YWJsZSxcbiAgICBcImZvcmVpZ25zXCIsXG4gICAgLy8gVE9ETyDrsJTrgIzripQg67aA67aEXG4gIF0uam9pbihcIl9cIik7XG5cbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICB0YWJsZSxcbiAgICAgIHRpdGxlLFxuICAgICAgZm9ybWF0dGVkLFxuICAgICAgdHlwZTogXCJub3JtYWxcIixcbiAgICB9LFxuICBdO1xufVxuXG4vKipcbiAqIOyjvOyWtOynhCBFbnRpdHlTZXTsnYQg6riw67CY7Jy866GcIO2FjOydtOu4lCBDUkVBVEUg66eI7J206re466CI7J207IWYIOy9lOuTnOulvCDsg53shLHtlanri4jri6QuXG4gKiBAcGFyYW0gZW50aXR5U2V0XG4gKiBAcmV0dXJucyBDUkVBVEUg66eI7J206re466CI7J207IWYIOy9lOuTnFxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2VuZXJhdGVDcmVhdGVDb2RlKGVudGl0eVNldDogTWlncmF0aW9uU2V0KTogUHJvbWlzZTxHZW5NaWdyYXRpb25Db2RlW10+IHtcbiAgcmV0dXJuIFtcbiAgICBhd2FpdCBnZW5lcmF0ZUNyZWF0ZUNvZGVfQ29sdW1uQW5kSW5kZXhlcyhcbiAgICAgIGVudGl0eVNldC50YWJsZSxcbiAgICAgIGVudGl0eVNldC5jb2x1bW5zLFxuICAgICAgZW50aXR5U2V0LmluZGV4ZXMsXG4gICAgKSxcbiAgICAuLi4oYXdhaXQgZ2VuZXJhdGVDcmVhdGVDb2RlX0ZvcmVpZ24oZW50aXR5U2V0LnRhYmxlLCBlbnRpdHlTZXQuZm9yZWlnbnMpKSxcbiAgXTtcbn1cblxuLyoqXG4gKiDso7zslrTsp4QgZW50aXR5U2V07J2EIOuqqe2RnOuhnCwgZGJTZXTsnYQg7ZiEIOyDge2ZqeycvOuhnCDtlZjsl6wg7YWM7J2067iUIEFMVEVSIOuniOydtOq3uOugiOydtOyFmCDsvZTrk5zrpbwg7IOd7ISx7ZWp64uI64ukLlxuICogQHBhcmFtIGVudGl0eVNldCDtmIQg7IOB7Zmp7J2YIE1pZ3JhdGlvblNldFxuICogQHBhcmFtIGRiU2V0IOuqqe2RnCDsg4HtmansnZggTWlncmF0aW9uU2V0XG4gKiBAcmV0dXJucyBBTFRFUiDrp4jsnbTqt7jroIjsnbTshZgg7L2U65OcXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUFsdGVyQ29kZShcbiAgZW50aXR5U2V0OiBNaWdyYXRpb25TZXQsXG4gIGRiU2V0OiBNaWdyYXRpb25TZXQsXG4pOiBQcm9taXNlPEdlbk1pZ3JhdGlvbkNvZGVbXT4ge1xuICBjb25zdCByZXBsYWNlQ29sdW1uRGVmYXVsdFRvID0gKGNvbDogTWlncmF0aW9uQ29sdW1uKSA9PiB7XG4gICAgLy8gZmxvYXTsnbgg6rK97JqwIOq4sOuzuOqwkuydhCAw7Jy866GcIOyngOygle2VmOuKlCDqsr3smrAgXCIwLjAwXCLsnLzroZwg67OA7ZmY65CY64qUIOy8gOydtOyKpCDrjIDsnZFcbiAgICAvLyBpZiAoY29sLnR5cGUgPT09IFwiZmxvYXRcIiAmJiBjb2wuZGVmYXVsdFRvICYmIFN0cmluZyhjb2wuZGVmYXVsdFRvKS5pbmNsdWRlcygnXCInKSA9PT0gZmFsc2UpIHtcbiAgICAvLyAgIGNvbC5kZWZhdWx0VG8gPSBgXCIke051bWJlcihjb2wuZGVmYXVsdFRvKS50b0ZpeGVkKGNvbC5zY2FsZSA/PyAyKX1cImA7XG4gICAgLy8gfVxuICAgIC8vIC8vIHN0cmluZ+yduCDqsr3smrAg6riw67O46rCS7J20IOu5iCDsiqTtirjrp4Hsnbgg6rK97JqwIOuMgOydkVxuICAgIC8vIGlmIChjb2wudHlwZSA9PT0gXCJzdHJpbmdcIiAmJiBjb2wuZGVmYXVsdFRvID09PSBcIlwiKSB7XG4gICAgLy8gICBjb2wuZGVmYXVsdFRvID0gJ1wiXCInO1xuICAgIC8vIH1cbiAgICAvLyAvLyBib29sZWFu7J24IOqyveyasCDquLDrs7jqsJIg7KCV6rec7ZmUIChNeVNRTOyXkOyEnOuKlCBUSU5ZSU5UKDEp66GcIOyggOyepeuQmOuvgOuhnCAwIOuYkOuKlCAx66GcIOygleq3nO2ZlClcbiAgICAvLyAvLyBUT0RPOiBkYi50c+yXkCB0eXBlQ2FzZSDshKTsoJUg7ZmV7J247ZWY7JesIOyymOumrO2VmOuPhOuhnSDsiJjsoJUg7ZWE7JqUXG4gICAgLy8gaWYgKGNvbC50eXBlID09PSBcImJvb2xlYW5cIiAmJiBjb2wuZGVmYXVsdFRvICE9PSB1bmRlZmluZWQpIHtcbiAgICAvLyAgIGlmIChjb2wuZGVmYXVsdFRvID09PSBcIjBcIiB8fCBjb2wuZGVmYXVsdFRvLnRvTG93ZXJDYXNlKCkgPT09IFwiZmFsc2VcIikge1xuICAgIC8vICAgICBjb2wuZGVmYXVsdFRvID0gXCIwXCI7XG4gICAgLy8gICB9IGVsc2UgaWYgKGNvbC5kZWZhdWx0VG8gPT09IFwiMVwiIHx8IGNvbC5kZWZhdWx0VG8udG9Mb3dlckNhc2UoKSA9PT0gXCJ0cnVlXCIpIHtcbiAgICAvLyAgICAgY29sLmRlZmF1bHRUbyA9IFwiMVwiO1xuICAgIC8vICAgfVxuICAgIC8vIH1cblxuICAgIC8vIEZJWE1FOiDsnbzri6ggTXlTUUwg7IOB7Zmp7JeQ7IScIOuwnOyDne2WiOuNmCDsnbTsiojsnZggd29ya2Fyb3VuZCDsnbTrr4DroZwgUGfsl5DshJwg7J6s7ZmV7J24IO2bhCDrjIDsnZEg7LaU6rCAXG4gICAgcmV0dXJuIGNvbDtcbiAgfTtcbiAgY29uc3QgZW50aXR5Q29sdW1ucyA9IGFscGhhYmV0aWNhbChlbnRpdHlTZXQuY29sdW1ucywgKGEpID0+IGEubmFtZSkubWFwKHJlcGxhY2VDb2x1bW5EZWZhdWx0VG8pO1xuICBjb25zdCBkYkNvbHVtbnMgPSBhbHBoYWJldGljYWwoZGJTZXQuY29sdW1ucywgKGEpID0+IGEubmFtZSkubWFwKHJlcGxhY2VDb2x1bW5EZWZhdWx0VG8pO1xuXG4gIC8qIOuUlOuyhOq5heyaqSDsvZTrk5wsIO2KueyglSDsu6zrn7zsl5DshJwg67aI7J287LmYIOuwnOyDne2VoCDrlYwg7ZmV7J24XG4gICAgICAgIGNvbnN0IGVudGl0eUNvbHVtbiA9IGVudGl0eVNldC5jb2x1bW5zLmZpbmQoXG4gICAgICAgICAgKGNvbCkgPT4gY29sLm5hbWUgPT09IFwicHJpY2Vfa3J3XCJcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3QgZGJDb2x1bW4gPSBkYlNldC5jb2x1bW5zLmZpbmQoXG4gICAgICAgICAgKGNvbCkgPT4gY29sLm5hbWUgPT09IFwicHJpY2Vfa3J3XCJcbiAgICAgICAgKTtcbiAgICAgICAgY29uc29sZS5kZWJ1Zyh7IGVudGl0eUNvbHVtbiwgZGJDb2x1bW4gfSk7XG4gICAgICAgICAqL1xuXG4gIC8vID9cbiAgY29uc3QgZW50aXR5SW5kZXhlcyA9IGFscGhhYmV0aWNhbChlbnRpdHlTZXQuaW5kZXhlcywgKGEpID0+IFthLnR5cGUsIC4uLmEuY29sdW1uc10uam9pbihcIi1cIikpO1xuICBjb25zdCBkYkluZGV4ZXMgPSBhbHBoYWJldGljYWwoZGJTZXQuaW5kZXhlcywgKGEpID0+IFthLnR5cGUsIC4uLmEuY29sdW1uc10uam9pbihcIi1cIikpO1xuXG4gIGNvbnN0IHJlcGxhY2VOb0FjdGlvbk9uTXlTUUwgPSAoZjogTWlncmF0aW9uRm9yZWlnbikgPT4ge1xuICAgIC8vIE15U1FM7JeQ7IScIFJFU1RSSUNU7JmAIE5PIEFDVElPTuydgCDrj5nsnbztlahcbiAgICBjb25zdCB7IG9uRGVsZXRlLCBvblVwZGF0ZSB9ID0gZjtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uZixcbiAgICAgIG9uVXBkYXRlOiBvblVwZGF0ZSA9PT0gXCJSRVNUUklDVFwiID8gXCJOTyBBQ1RJT05cIiA6IG9uVXBkYXRlLFxuICAgICAgb25EZWxldGU6IG9uRGVsZXRlID09PSBcIlJFU1RSSUNUXCIgPyBcIk5PIEFDVElPTlwiIDogb25EZWxldGUsXG4gICAgfTtcbiAgfTtcblxuICBjb25zdCBlbnRpdHlGb3JlaWducyA9IGFscGhhYmV0aWNhbChlbnRpdHlTZXQuZm9yZWlnbnMsIChhKSA9PlxuICAgIFthLnRvLCAuLi5hLmNvbHVtbnNdLmpvaW4oXCItXCIpLFxuICApLm1hcCgoZikgPT4gcmVwbGFjZU5vQWN0aW9uT25NeVNRTChmKSk7XG4gIGNvbnN0IGRiRm9yZWlnbnMgPSBhbHBoYWJldGljYWwoZGJTZXQuZm9yZWlnbnMsIChhKSA9PiBbYS50bywgLi4uYS5jb2x1bW5zXS5qb2luKFwiLVwiKSkubWFwKChmKSA9PlxuICAgIHJlcGxhY2VOb0FjdGlvbk9uTXlTUUwoZiksXG4gICk7XG5cbiAgLy8g7IKt7KCc65CgIOy7rOufvCDrqqnroZ0g6rOE7IKwXG4gIGNvbnN0IGRyb3BwaW5nQ29sdW1ucyA9IGRpZmYoZGJDb2x1bW5zLCBlbnRpdHlDb2x1bW5zLCAoY29sKSA9PiBjb2wubmFtZSk7XG5cbiAgY29uc3QgYWx0ZXJDb2RlczogKEdlbk1pZ3JhdGlvbkNvZGUgfCBHZW5NaWdyYXRpb25Db2RlW10gfCBudWxsKVtdID0gW107XG5cbiAgLy8gMS4gY29sdW1uc0FuZEluZGV4ZXMg7LKY66asXG4gIGNvbnN0IGlzRXF1YWxDb2x1bW5zID0gZXF1YWwoXG4gICAgZW50aXR5Q29sdW1ucy5tYXAobm9ybWFsaXplQ29sdW1uRm9yQ29tcGFyaXNvbiksXG4gICAgZGJDb2x1bW5zLm1hcChub3JtYWxpemVDb2x1bW5Gb3JDb21wYXJpc29uKSxcbiAgKTtcbiAgY29uc3QgaXNFcXVhbEluZGV4ZXMgPSBlcXVhbChcbiAgICBlbnRpdHlJbmRleGVzLm1hcCgoaW5kZXgpID0+IG9taXQoaW5kZXgsIFtcInBhcnNlclwiXSkpLm1hcChzZXRNaWdyYXRpb25JbmRleERlZmF1bHRzKSxcbiAgICBkYkluZGV4ZXMsXG4gICk7XG4gIGlmICghaXNFcXVhbENvbHVtbnMgfHwgIWlzRXF1YWxJbmRleGVzKSB7XG4gICAgYWx0ZXJDb2Rlcy5wdXNoKFxuICAgICAgYXdhaXQgZ2VuZXJhdGVBbHRlckNvZGVfQ29sdW1uQW5kSW5kZXhlcyhcbiAgICAgICAgZW50aXR5U2V0LnRhYmxlLFxuICAgICAgICBlbnRpdHlDb2x1bW5zLFxuICAgICAgICBlbnRpdHlJbmRleGVzLFxuICAgICAgICBkYkNvbHVtbnMsXG4gICAgICAgIGRiSW5kZXhlcyxcbiAgICAgICAgZGJTZXQuZm9yZWlnbnMsXG4gICAgICApLFxuICAgICk7XG4gIH1cblxuICAvLyAyLiBmb3JlaWducyDsspjrpqwgKOyCreygnOuQoCDsu6zrn7wg7KCV67O0IOyghOuLrClcbiAgaWYgKGVxdWFsKGVudGl0eUZvcmVpZ25zLCBkYkZvcmVpZ25zKSA9PT0gZmFsc2UpIHtcbiAgICBhbHRlckNvZGVzLnB1c2goXG4gICAgICBhd2FpdCBnZW5lcmF0ZUFsdGVyQ29kZV9Gb3JlaWducyhcbiAgICAgICAgZW50aXR5U2V0LnRhYmxlLFxuICAgICAgICBlbnRpdHlGb3JlaWducyxcbiAgICAgICAgZGJGb3JlaWducyxcbiAgICAgICAgZHJvcHBpbmdDb2x1bW5zLFxuICAgICAgKSxcbiAgICApO1xuICB9XG5cbiAgaWYgKGFsdGVyQ29kZXMuZXZlcnkoKGFsdGVyQ29kZSkgPT4gYWx0ZXJDb2RlID09PSBudWxsKSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHJldHVybiBhbHRlckNvZGVzLmZpbHRlcigoYWx0ZXJDb2RlKSA9PiBhbHRlckNvZGUgIT09IG51bGwpLmZsYXQoKTtcbn1cbiJdLCJuYW1lcyI6WyJlcXVhbCIsImFscGhhYmV0aWNhbCIsImRpZmYiLCJvbWl0IiwiTmFpdGUiLCJmb3JtYXRDb2RlIiwiZGlmZmVyZW5jZVdpdGgiLCJpbnRlcnNlY3Rpb25CeSIsImdlbmVyYXRlQ3JlYXRlQ29kZV9Db2x1bW5BbmRJbmRleGVzIiwidGFibGUiLCJjb2x1bW5zIiwiaW5kZXhlcyIsImNvbHVtbkRlZnMiLCJnZW5Db2x1bW5EZWZpbml0aW9ucyIsImxpbmVzIiwiYnVpbGRlciIsInJhdyIsIm1hcCIsImluZGV4IiwiZ2VuSW5kZXhEZWZpbml0aW9uIiwidHlwZSIsInRpdGxlIiwiZm9ybWF0dGVkIiwiam9pbiIsInJlc3VsdCIsImNvbHVtbiIsImdlbmVyYXRlZCIsInB1c2giLCJnZW5HZW5lcmF0ZWRDb2x1bW5EZWZpbml0aW9uIiwiZ2VuTm9ybWFsQ29sdW1uRGVmaW5pdGlvbiIsIkVycm9yIiwicGdUeXBlIiwiZ2V0UGdUeXBlRm9yQ29sdW1uIiwic3RvcmFnZVR5cGUiLCJudWxsYWJsZUNsYXVzZSIsIm51bGxhYmxlIiwibmFtZSIsImV4cHJlc3Npb24iLCJjaGFpbnMiLCJlbmRzV2l0aCIsImVsZW1lbnRUeXBlIiwic2xpY2UiLCJnZXRQZ0FycmF5VHlwZSIsImRpbWVuc2lvbnMiLCJudW1iZXJUeXBlIiwicHJlY2lzaW9uIiwic2NhbGUiLCJsZW5ndGgiLCJ1bmRlZmluZWQiLCJleHRyYVR5cGUiLCJkZWZhdWx0VG8iLCJzdGFydHNXaXRoIiwiZ2VuVmVjdG9ySW5kZXhEZWZpbml0aW9uIiwibWV0aG9kTWFwIiwiZnVsbHRleHQiLCJ1bmlxdWUiLCJudWxsc05vdERpc3RpbmN0Q2xhdXNlIiwibnVsbHNOb3REaXN0aW5jdCIsImNvbCIsInNvcnRPcmRlckNsYXVzZSIsInNvcnRPcmRlciIsIm51bGxzRmlyc3RDbGF1c2UiLCJudWxsc0ZpcnN0IiwidmVjdG9yT3BzIiwibSIsImVmQ29uc3RydWN0aW9uIiwibGlzdHMiLCJnZW5lcmF0ZUNyZWF0ZUNvZGVfRm9yZWlnbiIsImZvcmVpZ25zIiwidXAiLCJkb3duIiwiZ2VuRm9yZWlnbkRlZmluaXRpb25zIiwiY29uc29sZSIsImxvZyIsImZvcmVpZ25LZXlzU3RyaW5nIiwiZm9yZWlnbiIsInJlZHVjZSIsInIiLCJjb2x1bW5zU3RyaW5nUXVvdGUiLCJyZXBsYWNlIiwidG8iLCJvblVwZGF0ZSIsIm9uRGVsZXRlIiwiZ2VuZXJhdGVBbHRlckNvZGVfQ29sdW1uQW5kSW5kZXhlcyIsImVudGl0eUNvbHVtbnMiLCJlbnRpdHlJbmRleGVzIiwiZGJDb2x1bW5zIiwiZGJJbmRleGVzIiwiZGJGb3JlaWducyIsImFsdGVyQ29sdW1uc1RvIiwiZ2V0QWx0ZXJDb2x1bW5zVG8iLCJhbHRlckNvbHVtbkxpbmVzVG8iLCJnZXRBbHRlckNvbHVtbkxpbmVzVG8iLCJhbHRlckluZGV4ZXNUbyIsImdldEFsdGVySW5kZXhlc1RvIiwiaW5kZXhOZWVkc1RvRHJvcCIsImRyb3AiLCJmaWx0ZXIiLCJldmVyeSIsImluY2x1ZGVzIiwiaGFzVXBDaGFuZ2VzIiwiYWRkIiwiYWx0ZXIiLCJ0IiwidXBCdWlsZGVyTGluZXMiLCJnZW5JbmRleERyb3BEZWZpbml0aW9uIiwidXBSYXdMaW5lcyIsImRvd25CdWlsZGVyTGluZXMiLCJpbmRleENvbCIsImRvd25SYXdMaW5lcyIsImFjdGlvbiIsImxlbiIsInBhcnQiLCJub3JtYWxpemVDb2x1bW5Gb3JDb21wYXJpc29uIiwiY29sdW1uc1RvIiwiZXh0cmFDb2x1bW5zIiwiZGIiLCJlbnRpdHkiLCJjb25jYXQiLCJzYW1lRGJDb2x1bW5zIiwic2FtZU1kQ29sdW1ucyIsImEiLCJiIiwibGluZXNUbyIsImFkZENvbHVtbkRlZnMiLCJkcm9wQ29sdW1uTmFtZXMiLCJma1RvRHJvcEJlZm9yZUNvbHVtbiIsImZrIiwic29tZSIsImRyb3BGa0xpbmVzIiwicmVzdG9yZUZrTGluZXMiLCJkcm9wQ29sdW1uRGVmcyIsImRiQ29sdW1uIiwiZW50aXR5Q29sdW1uIiwiZmluZCIsImNvbHVtbkRpZmZVcCIsImNvbHVtbkRpZmZEb3duIiwibCIsImluZGV4ZXNUbyIsImlkZW50aXR5Iiwia2V5cyIsIk9iamVjdCIsImtleSIsInNvcnQiLCJmbGF0TWFwIiwiZXh0cmFJbmRleGVzIiwic2V0TWlncmF0aW9uSW5kZXhEZWZhdWx0cyIsImdlbmVyYXRlQWx0ZXJDb2RlX0ZvcmVpZ25zIiwiZW50aXR5Rm9yZWlnbnMiLCJkcm9wcGluZ0NvbHVtbnMiLCJnZXRLZXkiLCJtZiIsImRyb3BwaW5nQ29sdW1uTmFtZXMiLCJma1RvIiwiZW50aXR5RiIsIm1hdGNoaW5nRGJGIiwiZGJGIiwiYWx0ZXJTcmMiLCJhbHRlckRzdCIsImZvckVhY2giLCJtYXRjaGluZ0VudGl0eUYiLCJpc0NvbHVtbkRyb3BwaW5nIiwiaGFzTGluZXMiLCJ2YWx1ZXMiLCJnZW5lcmF0ZUNyZWF0ZUNvZGUiLCJlbnRpdHlTZXQiLCJnZW5lcmF0ZUFsdGVyQ29kZSIsImRiU2V0IiwicmVwbGFjZUNvbHVtbkRlZmF1bHRUbyIsInJlcGxhY2VOb0FjdGlvbk9uTXlTUUwiLCJmIiwiYWx0ZXJDb2RlcyIsImlzRXF1YWxDb2x1bW5zIiwiaXNFcXVhbEluZGV4ZXMiLCJhbHRlckNvZGUiLCJmbGF0Il0sIm1hcHBpbmdzIjoiQUFBQSxPQUFPQSxXQUFXLGtCQUFrQjtBQUNwQyxTQUFTQyxZQUFZLEVBQUVDLElBQUksRUFBRUMsSUFBSSxRQUFRLFVBQVU7QUFDbkQsU0FBU0MsS0FBSyxRQUFRLGNBQUs7QUFRM0IsU0FBU0MsVUFBVSxRQUFRLHdCQUFxQjtBQUNoRCxTQUFTQyxjQUFjLEVBQUVDLGNBQWMsUUFBUSxvQkFBaUI7QUFZaEU7O0NBRUMsR0FDRCxlQUFlQyxvQ0FDYkMsS0FBYSxFQUNiQyxPQUEwQixFQUMxQkMsT0FBeUI7SUFFekIsTUFBTUMsYUFBYUMscUJBQXFCSixPQUFPQztJQUUvQyxhQUFhO0lBQ2IsTUFBTUksUUFBa0I7UUFDdEI7UUFDQTtRQUNBO1FBQ0EsQ0FBQywrQkFBK0IsRUFBRUwsTUFBTSxlQUFlLENBQUM7V0FDckRHLFdBQVdHLE9BQU87UUFDckI7UUFDQSw4QkFBOEI7V0FDM0JILFdBQVdJLEdBQUc7UUFDakIsNENBQTRDO1dBQ3pDTCxRQUFRTSxHQUFHLENBQUMsQ0FBQ0MsUUFBVUMsbUJBQW1CRCxPQUFPVDtRQUNwRDtRQUNBO1FBQ0E7UUFDQSxDQUFDLCtCQUErQixFQUFFQSxNQUFNLEdBQUcsQ0FBQztRQUM1QztLQUNEO0lBQ0QsT0FBTztRQUNMQTtRQUNBVyxNQUFNO1FBQ05DLE9BQU8sQ0FBQyxRQUFRLEVBQUVaLE9BQU87UUFDekJhLFdBQVdqQixXQUFXUyxNQUFNUyxJQUFJLENBQUMsT0FBTyxjQUFjLENBQUMsY0FBYyxFQUFF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
|