sonamu 0.7.21 → 0.7.23
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/ai/agents/agent.d.ts +6 -1
- package/dist/ai/agents/agent.d.ts.map +1 -1
- package/dist/ai/agents/agent.js +20 -5
- package/dist/api/base-frame.d.ts +4 -0
- package/dist/api/base-frame.d.ts.map +1 -1
- package/dist/api/base-frame.js +9 -1
- package/dist/api/caster.d.ts.map +1 -1
- package/dist/api/caster.js +2 -2
- package/dist/api/config.d.ts +35 -3
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +1 -1
- package/dist/api/decorators.d.ts +4 -4
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +80 -18
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +2 -1
- package/dist/api/secret.d.ts +7 -0
- package/dist/api/secret.d.ts.map +1 -0
- package/dist/api/secret.js +17 -0
- package/dist/api/sonamu.d.ts +17 -8
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +265 -47
- package/dist/cache/cache-manager.d.ts +11 -0
- package/dist/cache/cache-manager.d.ts.map +1 -0
- package/dist/cache/cache-manager.js +22 -0
- package/dist/cache/decorator.d.ts +31 -0
- package/dist/cache/decorator.d.ts.map +1 -0
- package/dist/cache/decorator.js +86 -0
- package/dist/cache/drivers.d.ts +33 -0
- package/dist/cache/drivers.d.ts.map +1 -0
- package/dist/cache/drivers.js +36 -0
- package/dist/cache/index.d.ts +4 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +8 -0
- package/dist/cache/types.d.ts +28 -0
- package/dist/cache/types.d.ts.map +1 -0
- package/dist/cache/types.js +6 -0
- package/dist/database/base-model.d.ts +4 -2
- package/dist/database/base-model.d.ts.map +1 -1
- package/dist/database/base-model.js +9 -4
- package/dist/database/code-generator.d.ts +3 -1
- package/dist/database/code-generator.d.ts.map +1 -1
- package/dist/database/code-generator.js +3 -2
- package/dist/database/db.d.ts +1 -1
- package/dist/database/db.d.ts.map +1 -1
- package/dist/database/db.js +5 -5
- package/dist/database/knex.d.ts +3 -0
- package/dist/database/knex.d.ts.map +1 -0
- package/dist/database/knex.js +29 -0
- package/dist/database/puri.types.d.ts.map +1 -1
- package/dist/database/puri.types.js +1 -1
- package/dist/database/upsert-builder.d.ts.map +1 -1
- package/dist/database/upsert-builder.js +49 -5
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/logger/category.d.ts +4 -0
- package/dist/logger/category.d.ts.map +1 -0
- package/dist/logger/category.js +34 -0
- package/dist/logger/configure.d.ts +9 -0
- package/dist/logger/configure.d.ts.map +1 -0
- package/dist/logger/configure.js +115 -0
- package/dist/migration/code-generation.d.ts +5 -1
- package/dist/migration/code-generation.d.ts.map +1 -1
- package/dist/migration/code-generation.js +13 -7
- package/dist/migration/migrator.d.ts +1 -1
- package/dist/migration/migrator.d.ts.map +1 -1
- package/dist/migration/migrator.js +7 -7
- package/dist/migration/postgresql-schema-reader.d.ts.map +1 -1
- package/dist/migration/postgresql-schema-reader.js +5 -3
- package/dist/naite/naite.d.ts +0 -4
- package/dist/naite/naite.d.ts.map +1 -1
- package/dist/naite/naite.js +11 -19
- package/dist/ssr/index.d.ts +4 -0
- package/dist/ssr/index.d.ts.map +1 -0
- package/dist/ssr/index.js +4 -0
- package/dist/ssr/registry.d.ts +10 -0
- package/dist/ssr/registry.d.ts.map +1 -0
- package/dist/ssr/registry.js +43 -0
- package/dist/ssr/renderer.d.ts +6 -0
- package/dist/ssr/renderer.d.ts.map +1 -0
- package/dist/ssr/renderer.js +70 -0
- package/dist/ssr/types.d.ts +19 -0
- package/dist/ssr/types.d.ts.map +1 -0
- package/dist/ssr/types.js +4 -0
- package/dist/syncer/syncer.d.ts +1 -0
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +58 -1
- package/dist/tasks/decorator.d.ts +1 -0
- package/dist/tasks/decorator.d.ts.map +1 -1
- package/dist/tasks/decorator.js +9 -7
- package/dist/tasks/step-wrapper.d.ts +5 -0
- package/dist/tasks/step-wrapper.d.ts.map +1 -1
- package/dist/tasks/step-wrapper.js +11 -6
- package/dist/tasks/workflow-manager.d.ts +2 -0
- package/dist/tasks/workflow-manager.d.ts.map +1 -1
- package/dist/tasks/workflow-manager.js +5 -2
- package/dist/template/implementations/entry-server.template.d.ts +17 -0
- package/dist/template/implementations/entry-server.template.d.ts.map +1 -0
- package/dist/template/implementations/entry-server.template.js +78 -0
- package/dist/template/implementations/model.template.d.ts.map +1 -1
- package/dist/template/implementations/model.template.js +5 -3
- package/dist/template/implementations/queries.template.d.ts +17 -0
- package/dist/template/implementations/queries.template.d.ts.map +1 -0
- package/dist/template/implementations/queries.template.js +83 -0
- package/dist/template/implementations/view_enums_select.template.d.ts.map +1 -1
- package/dist/template/implementations/view_enums_select.template.js +34 -20
- package/dist/template/implementations/view_form.template.d.ts +2 -1
- package/dist/template/implementations/view_form.template.d.ts.map +1 -1
- package/dist/template/implementations/view_form.template.js +301 -129
- package/dist/template/implementations/view_id_async_select.template.d.ts.map +1 -1
- package/dist/template/implementations/view_id_async_select.template.js +136 -57
- package/dist/template/implementations/view_list.template.d.ts +2 -0
- package/dist/template/implementations/view_list.template.d.ts.map +1 -1
- package/dist/template/implementations/view_list.template.js +392 -227
- package/dist/template/implementations/view_search_input.template.d.ts.map +1 -1
- package/dist/template/implementations/view_search_input.template.js +46 -30
- package/dist/template/zod-converter.d.ts.map +1 -1
- package/dist/template/zod-converter.js +2 -2
- package/dist/testing/bootstrap.d.ts +28 -0
- package/dist/testing/bootstrap.d.ts.map +1 -0
- package/dist/testing/bootstrap.js +120 -0
- package/dist/testing/fixture-loader.d.ts +21 -0
- package/dist/testing/fixture-loader.d.ts.map +1 -0
- package/dist/testing/fixture-loader.js +28 -0
- package/dist/testing/fixture-manager.d.ts +1 -1
- package/dist/testing/fixture-manager.d.ts.map +1 -1
- package/dist/testing/fixture-manager.js +7 -7
- package/dist/testing/index.d.ts +4 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/naite-vitest-reporter.d.ts +12 -0
- package/dist/testing/naite-vitest-reporter.d.ts.map +1 -0
- package/dist/testing/naite-vitest-reporter.js +17 -0
- package/dist/types/types.d.ts +5 -6
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +7 -8
- package/dist/ui/ai-client.d.ts +3 -1
- package/dist/ui/ai-client.d.ts.map +1 -1
- package/dist/ui/ai-client.js +27 -8
- package/dist/ui-web/assets/index-CTYv3qL6.js +92 -0
- package/dist/ui-web/index.html +1 -1
- package/package.json +43 -20
- package/src/ai/agents/agent.ts +38 -19
- package/src/api/base-frame.ts +8 -0
- package/src/api/caster.ts +6 -1
- package/src/api/config.ts +38 -4
- package/src/api/decorators.ts +106 -20
- package/src/api/index.ts +1 -0
- package/src/api/secret.ts +23 -0
- package/src/api/sonamu.ts +334 -61
- package/src/cache/cache-manager.ts +23 -0
- package/src/cache/decorator.ts +116 -0
- package/src/cache/drivers.ts +42 -0
- package/src/cache/index.ts +16 -0
- package/src/cache/types.ts +32 -0
- package/src/database/base-model.ts +7 -3
- package/src/database/code-generator.ts +3 -1
- package/src/database/db.ts +5 -5
- package/src/database/knex.ts +34 -0
- package/src/database/puri.types.ts +2 -3
- package/src/database/upsert-builder.ts +58 -4
- package/src/index.ts +4 -0
- package/src/logger/category.ts +42 -0
- package/src/logger/configure.ts +132 -0
- package/src/migration/code-generation.ts +19 -6
- package/src/migration/migrator.ts +7 -6
- package/src/migration/postgresql-schema-reader.ts +7 -2
- package/src/naite/naite.ts +10 -18
- package/src/shared/web.shared.ts.txt +1 -1
- package/src/ssr/index.ts +13 -0
- package/src/ssr/registry.ts +52 -0
- package/src/ssr/renderer.ts +105 -0
- package/src/ssr/types.ts +20 -0
- package/src/syncer/syncer.ts +59 -0
- package/src/tasks/decorator.ts +20 -4
- package/src/tasks/step-wrapper.ts +14 -5
- package/src/tasks/workflow-manager.ts +9 -1
- package/src/template/implementations/entry-server.template.ts +81 -0
- package/src/template/implementations/model.template.ts +4 -2
- package/src/template/implementations/queries.template.ts +111 -0
- package/src/template/implementations/view_enums_select.template.ts +33 -19
- package/src/template/implementations/view_form.template.ts +324 -145
- package/src/template/implementations/view_id_async_select.template.ts +145 -56
- package/src/template/implementations/view_list.template.ts +446 -236
- package/src/template/implementations/view_search_input.template.ts +45 -29
- package/src/template/zod-converter.ts +4 -1
- package/src/testing/bootstrap.ts +176 -0
- package/src/testing/fixture-loader.ts +28 -0
- package/src/testing/fixture-manager.ts +7 -6
- package/src/testing/index.ts +3 -0
- package/src/testing/naite-vitest-reporter.ts +18 -0
- package/src/types/types.ts +4 -5
- package/src/ui/ai-client.ts +82 -50
- package/dist/template/implementations/view_enums_dropdown.template.d.ts +0 -17
- package/dist/template/implementations/view_enums_dropdown.template.d.ts.map +0 -1
- package/dist/template/implementations/view_enums_dropdown.template.js +0 -50
- package/dist/ui-web/assets/index-B87IyofX.js +0 -92
- package/src/template/implementations/view_enums_dropdown.template.ts +0 -53
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
import assert from "assert";
|
|
2
1
|
import inflection from "inflection";
|
|
3
|
-
import { flat
|
|
2
|
+
import { flat } from "radashi";
|
|
4
3
|
import { z } from "zod";
|
|
5
4
|
import { EntityManager } from "../../entity/entity-manager.js";
|
|
6
|
-
import { getColumnsNode } from "../entity-converter.js";
|
|
7
5
|
import { getEnumInfoFromColName, getRelationPropFromColName } from "../helpers.js";
|
|
8
6
|
import { Template } from "../template.js";
|
|
9
|
-
import { getZodTypeById, zodTypeToRenderingNode } from "../zod-converter.js";
|
|
10
7
|
export class Template__view_list extends Template {
|
|
11
8
|
constructor(){
|
|
12
9
|
super("view_list");
|
|
13
10
|
}
|
|
14
11
|
getTargetAndPath(names) {
|
|
15
12
|
return {
|
|
16
|
-
target: "web/src/
|
|
13
|
+
target: "web/src/routes/admin",
|
|
17
14
|
path: `${names.fsPlural}/index.tsx`
|
|
18
15
|
};
|
|
19
16
|
}
|
|
@@ -21,7 +18,17 @@ export class Template__view_list extends Template {
|
|
|
21
18
|
return `<Table.Cell key="${key}"${collapsing ? " collapsing" : ""}${className ? ` className={\`${className}\`}` : ""}>${body}</Table.Cell>`;
|
|
22
19
|
}
|
|
23
20
|
renderColumn(entityId, col, names, parentObj = "row", withoutName = false) {
|
|
24
|
-
|
|
21
|
+
// 중첩 경로 처리 (예: "user.name" -> "row.user?.name")
|
|
22
|
+
let colName;
|
|
23
|
+
if (withoutName) {
|
|
24
|
+
colName = parentObj;
|
|
25
|
+
} else if (col.name.includes(".")) {
|
|
26
|
+
// 중첩 경로는 optional chaining으로 변환
|
|
27
|
+
const parts = col.name.split(".");
|
|
28
|
+
colName = `${parentObj}.${parts.join("?.")}`;
|
|
29
|
+
} else {
|
|
30
|
+
colName = `${parentObj}.${col.name}`;
|
|
31
|
+
}
|
|
25
32
|
switch(col.renderType){
|
|
26
33
|
case "string-plain":
|
|
27
34
|
case "string-date":
|
|
@@ -29,36 +36,45 @@ export class Template__view_list extends Template {
|
|
|
29
36
|
return `<>{${colName}}</>`;
|
|
30
37
|
case "number-fk_id":
|
|
31
38
|
{
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
try {
|
|
40
|
+
const baseName = col.name.includes(".") ? (col.name.split(".").pop() ?? col.name).replace("_id", "") : col.name.replace("_id", "");
|
|
41
|
+
const relPropFk = getRelationPropFromColName(entityId, baseName);
|
|
42
|
+
return `<>${relPropFk.with}#{${colName}}</>`;
|
|
43
|
+
} catch {
|
|
44
|
+
return `<>{${colName}}</>`;
|
|
45
|
+
}
|
|
34
46
|
}
|
|
35
47
|
case "string-image":
|
|
36
|
-
return `<>{${col.nullable ? `${colName} && ` : ""}<img src={${colName}} />}</>`;
|
|
48
|
+
return `<>{${col.nullable ? `${colName} && ` : ""}<img src={${colName}} alt="${col.label ?? col.name}" className="h-8 w-8 object-cover rounded" />}</>`;
|
|
37
49
|
case "datetime":
|
|
38
|
-
if (col.nullable) {
|
|
39
|
-
return `<span
|
|
50
|
+
if (col.nullable || col.name.includes(".")) {
|
|
51
|
+
return `<span>{${colName} ? datetimeF(${colName}) : '-'}</span>`;
|
|
40
52
|
} else {
|
|
41
|
-
return `<span
|
|
53
|
+
return `<span>{datetimeF(${colName})}</span>`;
|
|
42
54
|
}
|
|
43
55
|
case "string-datetime":
|
|
44
|
-
if (col.nullable) {
|
|
45
|
-
return `<span
|
|
56
|
+
if (col.nullable || col.name.includes(".")) {
|
|
57
|
+
return `<span>{${colName} ? dateF(${colName}) : '-'}</span>`;
|
|
46
58
|
} else {
|
|
47
|
-
return `<span
|
|
59
|
+
return `<span>{dateF(${colName})}</span>`;
|
|
48
60
|
}
|
|
49
61
|
case "boolean":
|
|
50
|
-
return `<>{${colName} ? <
|
|
62
|
+
return `<>{${colName} ? <Badge variant="default">O</Badge> : <Badge variant="secondary">X</Badge>}</>`;
|
|
51
63
|
case "enums":
|
|
52
64
|
{
|
|
53
|
-
|
|
54
|
-
|
|
65
|
+
try {
|
|
66
|
+
const { id: enumId } = getEnumInfoFromColName(entityId, col.name);
|
|
67
|
+
return `<>{${col.nullable ? `${colName} && ` : ""}${enumId}Label[${colName}]}</>`;
|
|
68
|
+
} catch {
|
|
69
|
+
return `<>{${colName}}</>`;
|
|
70
|
+
}
|
|
55
71
|
}
|
|
56
72
|
case "array-images":
|
|
57
|
-
return
|
|
73
|
+
return `<div className="flex gap-1">{ ${colName}?.map((r, i) => ${col.nullable ? `r && ` : ""}<img key={i} src={r} alt={\`${col.label ?? col.name} \${i + 1}\`} className="h-8 w-8 object-cover rounded" />) }</div>`;
|
|
58
74
|
case "number-plain":
|
|
59
|
-
return `<>{${col.nullable ? `${colName} && ` : ""}numF(${colName})}</>`;
|
|
75
|
+
return `<>{${col.nullable || col.name.includes(".") ? `${colName} && ` : ""}numF(${colName})}</>`;
|
|
60
76
|
case "object":
|
|
61
|
-
return
|
|
77
|
+
return `<span className="text-xs">{${col.nullable ? `${colName} ? ` : ""}JSON.stringify(${colName})${col.nullable ? ` : '-'` : ""}}</span>`;
|
|
62
78
|
case "object-pick":
|
|
63
79
|
{
|
|
64
80
|
const pickedChild = col.children?.find((child)=>child.name === col.config?.picked);
|
|
@@ -85,19 +101,21 @@ export class Template__view_list extends Template {
|
|
|
85
101
|
} else if (col.renderType === "object") {
|
|
86
102
|
try {
|
|
87
103
|
const relProp = getRelationPropFromColName(entityId, col.name);
|
|
88
|
-
const result = col.children
|
|
104
|
+
const result = (col.children ?? []).map((child)=>{
|
|
89
105
|
entityId = relProp.with;
|
|
90
106
|
names = EntityManager.getNamesFromId(relProp.with);
|
|
91
107
|
return this.renderColumnImport(entityId, child, names);
|
|
92
108
|
});
|
|
93
|
-
return flat(result
|
|
109
|
+
return flat(result);
|
|
94
110
|
} catch {
|
|
95
111
|
return [
|
|
96
112
|
null
|
|
97
113
|
];
|
|
98
114
|
}
|
|
99
115
|
} else if (col.renderType === "array") {
|
|
100
|
-
|
|
116
|
+
if (!col.element) return [
|
|
117
|
+
null
|
|
118
|
+
];
|
|
101
119
|
return this.renderColumnImport(entityId, col.element, names);
|
|
102
120
|
}
|
|
103
121
|
return [
|
|
@@ -165,32 +183,41 @@ export class Template__view_list extends Template {
|
|
|
165
183
|
}
|
|
166
184
|
getDefault(columns) {
|
|
167
185
|
const def = {
|
|
168
|
-
orderBy: "
|
|
169
|
-
search: "
|
|
186
|
+
orderBy: "",
|
|
187
|
+
search: "",
|
|
188
|
+
hasSearch: false,
|
|
189
|
+
hasOrderBy: false
|
|
170
190
|
};
|
|
171
191
|
const orderByZodType = columns.find((col)=>col.name === "orderBy")?.zodType;
|
|
172
192
|
if (orderByZodType && orderByZodType instanceof z.ZodEnum) {
|
|
173
|
-
def.orderBy = orderByZodType.
|
|
193
|
+
def.orderBy = Object.keys(orderByZodType.enum)[0];
|
|
194
|
+
def.hasOrderBy = true;
|
|
174
195
|
}
|
|
175
196
|
const searchZodType = columns.find((col)=>col.name === "search")?.zodType;
|
|
176
197
|
if (searchZodType && searchZodType instanceof z.ZodEnum) {
|
|
177
|
-
def.search = searchZodType.
|
|
198
|
+
def.search = Object.keys(searchZodType.enum)[0];
|
|
199
|
+
def.hasSearch = true;
|
|
178
200
|
}
|
|
179
201
|
return def;
|
|
180
202
|
}
|
|
181
203
|
async render({ entityId }) {
|
|
204
|
+
const { getColumnsNode } = await import("../entity-converter.js");
|
|
205
|
+
const { getZodTypeById, zodTypeToRenderingNode } = await import("../zod-converter.js");
|
|
182
206
|
const columnsNode = await getColumnsNode(entityId, "A");
|
|
183
207
|
const listParamsZodType = await getZodTypeById(`${entityId}ListParams`);
|
|
184
208
|
const listParamsNode = zodTypeToRenderingNode(listParamsZodType);
|
|
185
209
|
const names = EntityManager.getNamesFromId(entityId);
|
|
186
210
|
const entity = EntityManager.get(entityId);
|
|
187
211
|
// 실제 리스트 컬럼
|
|
188
|
-
const columns = columnsNode.children.
|
|
212
|
+
const columns = columnsNode.children.sort((a, b)=>a.name === "id" ? -1 : b.name === "id" ? 1 : 0).map((col)=>{
|
|
189
213
|
const propCandidate = entity.props.find((p)=>p.name === col.name);
|
|
214
|
+
const rendered = this.renderColumn(entityId, col, names);
|
|
190
215
|
return {
|
|
191
216
|
name: col.name,
|
|
192
|
-
label: propCandidate?.desc ?? col.label,
|
|
193
|
-
tc: `(row) => ${
|
|
217
|
+
label: col.name === "id" ? "ID" : propCandidate?.desc ?? col.label,
|
|
218
|
+
tc: `(row) => ${rendered}`,
|
|
219
|
+
fit: col.renderType === "number-id" || col.renderType === "datetime" || col.renderType === "string-datetime",
|
|
220
|
+
align: col.renderType === "number-id" ? "center" : undefined
|
|
194
221
|
};
|
|
195
222
|
});
|
|
196
223
|
// 필터 컬럼
|
|
@@ -209,17 +236,23 @@ export class Template__view_list extends Template {
|
|
|
209
236
|
let enumId;
|
|
210
237
|
if (col.renderType === "enums") {
|
|
211
238
|
if (col.name === "search") {
|
|
212
|
-
key = "
|
|
239
|
+
key = "view_enums_select";
|
|
213
240
|
enumId = `${names.capital}SearchField`;
|
|
214
241
|
targetEntityId = names.capital;
|
|
215
242
|
} else {
|
|
216
243
|
key = "view_enums_select";
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
}
|
|
222
|
-
|
|
244
|
+
// config.enumId 우선 사용
|
|
245
|
+
if (col.config && "enumId" in col.config) {
|
|
246
|
+
enumId = col.config.enumId;
|
|
247
|
+
targetEntityId = entityId;
|
|
248
|
+
} else {
|
|
249
|
+
try {
|
|
250
|
+
const { targetEntityNames, id } = getEnumInfoFromColName(entityId, col.name);
|
|
251
|
+
targetEntityId = targetEntityNames.capital;
|
|
252
|
+
enumId = id;
|
|
253
|
+
} catch {
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
223
256
|
}
|
|
224
257
|
}
|
|
225
258
|
} else {
|
|
@@ -239,232 +272,364 @@ export class Template__view_list extends Template {
|
|
|
239
272
|
}
|
|
240
273
|
});
|
|
241
274
|
}
|
|
242
|
-
//
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
275
|
+
// 컬럼에서 사용하는 enum들 수집
|
|
276
|
+
const columnEnums = [];
|
|
277
|
+
(columnsNode.children ?? []).forEach((col)=>{
|
|
278
|
+
if (col.renderType === "enums") {
|
|
279
|
+
try {
|
|
280
|
+
const { id: enumId } = getEnumInfoFromColName(entityId, col.name);
|
|
281
|
+
columnEnums.push(enumId);
|
|
282
|
+
} catch {}
|
|
283
|
+
}
|
|
284
|
+
});
|
|
247
285
|
// SearchInput
|
|
248
|
-
|
|
249
|
-
preTemplates.push({
|
|
286
|
+
preTemplates?.push({
|
|
250
287
|
key: "view_search_input",
|
|
251
288
|
options: {
|
|
252
289
|
entityId
|
|
253
290
|
}
|
|
254
291
|
});
|
|
255
292
|
// 디폴트 파라미터
|
|
256
|
-
const def = this.getDefault(filterColumns);
|
|
293
|
+
// const def = this.getDefault(filterColumns);
|
|
257
294
|
return {
|
|
258
295
|
...this.getTargetAndPath(names),
|
|
259
296
|
body: `
|
|
260
|
-
import
|
|
261
|
-
import {
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
Button,
|
|
272
|
-
Label,
|
|
273
|
-
} from 'semantic-ui-react';
|
|
274
|
-
import classNames from 'classnames';
|
|
275
|
-
import { DateTime } from "luxon";
|
|
276
|
-
import { DelButton, EditButton, AppBreadcrumbs, AddButton, useSelection, useListParams, SonamuCol, numF, formatDate, formatDateTime } from '@sonamu-kit/react-sui';
|
|
297
|
+
import { useState, Fragment } from "react";
|
|
298
|
+
import { createFileRoute, useNavigate } from "@tanstack/react-router";
|
|
299
|
+
|
|
300
|
+
import { Card, CardContent, CardHeader } from "@sonamu-kit/react-components/components";
|
|
301
|
+
import { Badge } from "@sonamu-kit/react-components/components";
|
|
302
|
+
import { Button } from "@sonamu-kit/react-components/components";
|
|
303
|
+
import { Pagination, Table, TableBody, TableCell, type TableCol, TableHead, TableHeader, TableRow } from "@sonamu-kit/react-components/components";
|
|
304
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@sonamu-kit/react-components/components";
|
|
305
|
+
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@sonamu-kit/react-components/components";
|
|
306
|
+
import { Input } from "@sonamu-kit/react-components/components";
|
|
307
|
+
import { Checkbox } from "@sonamu-kit/react-components/components";
|
|
277
308
|
|
|
309
|
+
import { useListParams, numF, dateF, datetimeF } from "@sonamu-kit/react-components/lib";
|
|
278
310
|
import { ${names.capital}SubsetA } from "@/services/sonamu.generated";
|
|
279
|
-
import { ${names.capital}Service } from
|
|
280
|
-
import { ${names.capital}ListParams } from
|
|
281
|
-
${
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
311
|
+
import { ${names.capital}Service } from "@/services/services.generated";
|
|
312
|
+
import { ${names.capital}ListParams } from "@/services/${names.fs}/${names.fs}.types";
|
|
313
|
+
import { ${(()=>{
|
|
314
|
+
// 기본 enum 수집 (filterColumns에 있는 것만)
|
|
315
|
+
const baseEnums = [];
|
|
316
|
+
if (filterColumns.some((col)=>col.name === "orderBy")) {
|
|
317
|
+
baseEnums.push(`${names.capital}OrderBy`, `${names.capital}OrderByLabel`);
|
|
318
|
+
}
|
|
319
|
+
if (filterColumns.some((col)=>col.name === "search")) {
|
|
320
|
+
baseEnums.push(`${names.capital}SearchField`, `${names.capital}SearchFieldLabel`);
|
|
321
|
+
}
|
|
322
|
+
// 필터 enum 수집 (config.enumId 우선, 없으면 getEnumInfoFromColName)
|
|
323
|
+
const filterEnumIds = filterColumns.filter((col)=>col.renderType === "enums" && col.name !== "search" && col.name !== "orderBy").map((col)=>{
|
|
324
|
+
if (col.config && "enumId" in col.config) {
|
|
325
|
+
return col.config.enumId;
|
|
326
|
+
}
|
|
327
|
+
try {
|
|
328
|
+
const { id: enumId } = getEnumInfoFromColName(entityId, col.name);
|
|
329
|
+
return enumId;
|
|
330
|
+
} catch {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
}).filter(Boolean);
|
|
334
|
+
// 모든 enum 합치고 중복 제거
|
|
335
|
+
const allEnums = [
|
|
336
|
+
...new Set([
|
|
337
|
+
...filterEnumIds,
|
|
338
|
+
...columnEnums
|
|
339
|
+
])
|
|
340
|
+
];
|
|
341
|
+
const enumImports = allEnums.flatMap((enumId)=>[
|
|
342
|
+
`${enumId}`,
|
|
343
|
+
`${enumId}Label`
|
|
344
|
+
]);
|
|
345
|
+
return [
|
|
346
|
+
...baseEnums,
|
|
347
|
+
...enumImports
|
|
348
|
+
].join(", ");
|
|
349
|
+
})()} } from "@/services/sonamu.generated";
|
|
350
|
+
${(()=>{
|
|
351
|
+
// FK 필드의 AsyncSelect 컴포넌트 import
|
|
352
|
+
const fkColumns = filterColumns.filter((col)=>col.name.endsWith("_id") && col.name !== "id");
|
|
353
|
+
return fkColumns.map((col)=>{
|
|
354
|
+
try {
|
|
355
|
+
const relProp = getRelationPropFromColName(entityId, col.name.replace("_id", ""));
|
|
356
|
+
const targetNames = EntityManager.getNamesFromId(relProp.with);
|
|
357
|
+
return `import { ${relProp.with}IdAsyncSelect } from "@/components/${targetNames.fs}/${relProp.with}IdAsyncSelect";`;
|
|
358
|
+
} catch {
|
|
359
|
+
return "";
|
|
360
|
+
}
|
|
361
|
+
}).filter(Boolean).join("\n");
|
|
362
|
+
})()}
|
|
363
|
+
${filterColumns.some((col)=>col.name === "search") ? `
|
|
364
|
+
import { ${names.capital}SearchFieldSelect } from "@/components/${names.fs}/${names.capital}SearchFieldSelect";` : ""}
|
|
365
|
+
${filterColumns.some((col)=>col.name === "orderBy") ? `
|
|
366
|
+
import { ${names.capital}OrderBySelect } from "@/components/${names.fs}/${names.capital}OrderBySelect";` : ""}
|
|
367
|
+
|
|
368
|
+
import EditIcon from "~icons/lucide/square-pen";
|
|
369
|
+
import TrashIcon from "~icons/lucide/trash-2";
|
|
370
|
+
import ListIcon from "~icons/mdi/format-list-bulleted";
|
|
371
|
+
import SearchIcon from "~icons/mdi/magnify";
|
|
372
|
+
|
|
373
|
+
export const Route = createFileRoute("/admin/${names.fsPlural}/")({\n head: () => ({\n meta: [\n { title: "${entity.title ?? names.capital} List" },\n { name: "description", content: "${entity.title ?? names.capital} 목록 관리" },\n ],\n }),\n component: ${names.capital}List,\n});\n\ntype ${names.capital}ListProps = {};
|
|
374
|
+
|
|
375
|
+
function ${names.capital}List({}: ${names.capital}ListProps) {
|
|
376
|
+
const navigate = useNavigate();
|
|
377
|
+
|
|
378
|
+
// 상태 관리
|
|
379
|
+
const [selectedItems, setSelectedItems] = useState<Set<number>>(new Set());
|
|
380
|
+
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
|
381
|
+
const [itemToDelete, setItemToDelete] = useState<{ id: number; name?: string } | null>(null);
|
|
285
382
|
|
|
286
|
-
type ${names.capital}ListProps = {};
|
|
287
|
-
export default function ${names.capital}List({}: ${names.capital}ListProps) {
|
|
288
383
|
// 리스트 필터
|
|
289
384
|
const { listParams, register } = useListParams(${names.capital}ListParams, {
|
|
290
|
-
num:
|
|
385
|
+
num: 10,
|
|
291
386
|
page: 1,
|
|
292
|
-
|
|
293
|
-
search:
|
|
387
|
+
keyword: "",${filterColumns.some((col)=>col.name === "search") ? `
|
|
388
|
+
search: ${names.capital}SearchField.options[0],` : ""}${filterColumns.some((col)=>col.name === "orderBy") ? `
|
|
389
|
+
orderBy: ${names.capital}OrderBy.options[0],` : ""}
|
|
294
390
|
});
|
|
295
391
|
|
|
296
392
|
// 리스트 쿼리
|
|
297
|
-
const { data, refetch, isLoading } = ${names.capital}Service.use${names.capitalPlural}(
|
|
393
|
+
const { data, refetch, isLoading } = ${names.capital}Service.use${names.capitalPlural}("A", listParams);
|
|
298
394
|
const { rows, total } = data ?? {};
|
|
299
395
|
|
|
300
|
-
//
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
${names.capital}Service.del(ids).then(() => {
|
|
308
|
-
refetch();
|
|
309
|
-
});
|
|
396
|
+
// 현재 경로와 타이틀
|
|
397
|
+
const PAGE = {
|
|
398
|
+
route: "/admin/${names.fsPlural}",
|
|
399
|
+
title: "${entity.title ?? names.capital}",
|
|
310
400
|
};
|
|
311
401
|
|
|
312
|
-
//
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
402
|
+
// 컬럼 정의
|
|
403
|
+
type ${names.capital}Row = NonNullable<typeof rows>[number];
|
|
404
|
+
const columns: TableCol<${names.capital}Row>[] = [
|
|
405
|
+
${columns.map((col)=>` {
|
|
406
|
+
label: "${col.label}",
|
|
407
|
+
tc: ${col.tc},${col.fit ? `
|
|
408
|
+
fit: true,` : ""}${col.align ? `
|
|
409
|
+
align: "${col.align}",` : ""}
|
|
410
|
+
}`).join(",\n")},
|
|
411
|
+
{
|
|
412
|
+
label: "Manage",
|
|
413
|
+
fit: true,
|
|
414
|
+
align: "center",
|
|
415
|
+
tc: (row) => (
|
|
416
|
+
<div className="flex items-center justify-center gap-1">
|
|
417
|
+
<Button
|
|
418
|
+
variant="yellow"
|
|
419
|
+
size="xs"
|
|
420
|
+
icon={<EditIcon />}
|
|
421
|
+
onClick={() => navigate({ to: \`\${PAGE.route}/form\`, search: { id: row.id } })}
|
|
422
|
+
/>
|
|
423
|
+
<Button
|
|
424
|
+
variant="red"
|
|
425
|
+
size="xs"
|
|
426
|
+
icon={<TrashIcon />}
|
|
427
|
+
onClick={() => handleDeleteClick(row.id)}
|
|
428
|
+
/>
|
|
429
|
+
</div>
|
|
430
|
+
),
|
|
431
|
+
},
|
|
432
|
+
];
|
|
433
|
+
|
|
434
|
+
// 선택 핸들러
|
|
435
|
+
const handleToggleItem = (id: number) => {
|
|
436
|
+
const newSelection = new Set(selectedItems);
|
|
437
|
+
if (newSelection.has(id)) {
|
|
438
|
+
newSelection.delete(id);
|
|
439
|
+
} else {
|
|
440
|
+
newSelection.add(id);
|
|
317
441
|
}
|
|
442
|
+
setSelectedItems(newSelection);
|
|
443
|
+
};
|
|
318
444
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
});
|
|
445
|
+
const isAllSelected = () => {
|
|
446
|
+
return (rows?.length ?? 0) > 0 && rows!.every((row) => selectedItems.has(row.id));
|
|
322
447
|
};
|
|
323
448
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
449
|
+
const handleSelectAll = (checked: boolean) => {
|
|
450
|
+
if (checked) {
|
|
451
|
+
setSelectedItems(new Set(rows?.map((row) => row.id) ?? []));
|
|
452
|
+
} else {
|
|
453
|
+
setSelectedItems(new Set());
|
|
454
|
+
}
|
|
328
455
|
};
|
|
329
456
|
|
|
330
|
-
//
|
|
331
|
-
const {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
toggle,
|
|
336
|
-
selectAll,
|
|
337
|
-
deselectAll,
|
|
338
|
-
handleCheckboxClick,
|
|
339
|
-
} = useSelection((rows ?? []).map((row) => row.id));
|
|
457
|
+
// 삭제 핸들러
|
|
458
|
+
const handleDeleteClick = (id: number, name?: string) => {
|
|
459
|
+
setItemToDelete({ id, name });
|
|
460
|
+
setDeleteDialogOpen(true);
|
|
461
|
+
};
|
|
340
462
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
].join("\n");
|
|
351
|
-
}).join(",\n")}];
|
|
463
|
+
const handleConfirmDelete = () => {
|
|
464
|
+
if (itemToDelete) {
|
|
465
|
+
${names.capital}Service.del([itemToDelete.id]).then(() => {
|
|
466
|
+
refetch();
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
setDeleteDialogOpen(false);
|
|
470
|
+
setItemToDelete(null);
|
|
471
|
+
};
|
|
352
472
|
|
|
353
473
|
return (
|
|
354
|
-
<div className="
|
|
355
|
-
<div className="
|
|
356
|
-
<div className="
|
|
357
|
-
|
|
358
|
-
<
|
|
359
|
-
<
|
|
360
|
-
|
|
361
|
-
<${names.capital}SearchInput
|
|
362
|
-
input={register('keyword')}
|
|
363
|
-
dropdown={register('search')}
|
|
364
|
-
/>
|
|
365
|
-
</div>
|
|
366
|
-
<div className="filters-row">
|
|
367
|
-
${filterColumns.map((col)=>{
|
|
368
|
-
return this.renderFilter(entityId, col, names);
|
|
369
|
-
}).join(" \n")}
|
|
370
|
-
</div>
|
|
371
|
-
</div>
|
|
372
|
-
|
|
373
|
-
<Segment basic padded className="contents-segment" loading={isLoading}>
|
|
374
|
-
<div className="buttons-row">
|
|
375
|
-
<div className={classNames('count', { hidden: isLoading })}>
|
|
376
|
-
{total} 건
|
|
377
|
-
</div>
|
|
378
|
-
<div className="buttons">
|
|
379
|
-
<AddButton currentRoute={PAGE.route} icon="write" label="추가" />
|
|
474
|
+
<div className="flex-1 overflow-auto">
|
|
475
|
+
<div className="max-w-[1800px] mx-auto p-8">
|
|
476
|
+
<div className="space-y-6 mb-8">
|
|
477
|
+
{/* Header */}
|
|
478
|
+
<div className="flex items-center gap-2">
|
|
479
|
+
<ListIcon className="h-5 w-5" />
|
|
480
|
+
<span className="text-lg font-semibold h-5">{PAGE.title}</span>
|
|
380
481
|
</div>
|
|
381
|
-
</div>
|
|
382
482
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
/* Header */
|
|
400
|
-
columns.map((col, index) => col.th ?? <Table.HeaderCell key={index} collapsing={col.collapsing}>{ col.label }</Table.HeaderCell>)
|
|
401
|
-
}
|
|
402
|
-
<Table.HeaderCell>관리</Table.HeaderCell>
|
|
403
|
-
</TableRow>
|
|
404
|
-
</Table.Header>
|
|
405
|
-
<Table.Body>
|
|
406
|
-
{rows &&
|
|
407
|
-
rows.map((row, rowIndex) => (
|
|
408
|
-
<Table.Row key={row.id}>
|
|
409
|
-
<Table.Cell>
|
|
410
|
-
<Checkbox
|
|
411
|
-
label={row.id}
|
|
412
|
-
checked={getSelected(row.id)}
|
|
413
|
-
onChange={() => toggle(row.id)}
|
|
414
|
-
onClick={(e) =>
|
|
415
|
-
handleCheckboxClick(e, rowIndex)
|
|
416
|
-
}
|
|
483
|
+
<Card className="shadow-sm border-border/40 overflow-hidden">
|
|
484
|
+
<CardHeader className="pb-0 px-0 pt-0">
|
|
485
|
+
{/* Filters */}
|
|
486
|
+
<div className="bg-gray-100 px-6 py-4 space-y-3">
|
|
487
|
+
<div className="flex items-center gap-3 flex-wrap">
|
|
488
|
+
${filterColumns.some((col)=>col.name === "search") ? ` <${names.capital}SearchFieldSelect
|
|
489
|
+
{...register("search")}
|
|
490
|
+
placeholder="Search Type"
|
|
491
|
+
className="w-[200px] h-8 bg-white border-gray-300 text-xs"
|
|
492
|
+
/>` : ""}
|
|
493
|
+
|
|
494
|
+
<div className="relative flex-1 max-w-xs">
|
|
495
|
+
<Input
|
|
496
|
+
{...register("keyword")}
|
|
497
|
+
placeholder="Search..."
|
|
498
|
+
className="h-8 pr-8 text-xs bg-white border-gray-300"
|
|
417
499
|
/>
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
{col.tc(row, rowIndex)}
|
|
424
|
-
</Table.Cell>
|
|
425
|
-
))
|
|
426
|
-
}
|
|
427
|
-
<Table.Cell collapsing>
|
|
428
|
-
<EditButton
|
|
429
|
-
as={Link}
|
|
430
|
-
to={\`\${PAGE.route}/form?id=\${row.id}\`}
|
|
431
|
-
state={{ from: PAGE.route }}
|
|
500
|
+
<Button
|
|
501
|
+
variant="ghost"
|
|
502
|
+
size="sm"
|
|
503
|
+
icon={<SearchIcon />}
|
|
504
|
+
className="absolute right-0 top-0 h-8 w-8 hover:bg-transparent"
|
|
432
505
|
/>
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
506
|
+
</div>
|
|
507
|
+
|
|
508
|
+
<div className="ml-auto">
|
|
509
|
+
<Button
|
|
510
|
+
className="h-8 px-4 bg-primary hover:bg-primary/90 text-white"
|
|
511
|
+
onClick={() => navigate({ to: \`\${PAGE.route}/form\` })}
|
|
512
|
+
>
|
|
513
|
+
<span className="text-xs">Create</span>
|
|
514
|
+
</Button>
|
|
515
|
+
</div>
|
|
516
|
+
</div>
|
|
517
|
+
|
|
518
|
+
<div className="flex items-center gap-3 flex-wrap">
|
|
519
|
+
${filterColumns.filter((col)=>col.name !== "search" && col.name !== "orderBy").map((col)=>{
|
|
520
|
+
if (col.renderType === "enums") {
|
|
521
|
+
try {
|
|
522
|
+
// config.enumId가 있으면 우선 사용, 없으면 getEnumInfoFromColName 시도
|
|
523
|
+
const enumId = col.config && "enumId" in col.config ? col.config.enumId : getEnumInfoFromColName(entityId, col.name).id;
|
|
524
|
+
return ` <Select key={\`${col.name}-\${listParams.${col.name}}\`} {...register("${col.name}")} clearable>
|
|
525
|
+
<SelectTrigger className="w-[200px] h-8 bg-white border-gray-300 text-xs">
|
|
526
|
+
<SelectValue placeholder="${col.label}" className="truncate" />
|
|
527
|
+
</SelectTrigger>
|
|
528
|
+
<SelectContent>
|
|
529
|
+
{${enumId}.options.map((key) => (
|
|
530
|
+
<SelectItem key={key} value={key}>
|
|
531
|
+
{${enumId}Label[key]}
|
|
532
|
+
</SelectItem>
|
|
533
|
+
))}
|
|
534
|
+
</SelectContent>
|
|
535
|
+
</Select>`;
|
|
536
|
+
} catch {
|
|
537
|
+
return "";
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
// FK 필드 (AsyncSelect)
|
|
541
|
+
if (col.name.endsWith("_id") && col.name !== "id") {
|
|
542
|
+
try {
|
|
543
|
+
const relProp = getRelationPropFromColName(entityId, col.name.replace("_id", ""));
|
|
544
|
+
return ` <${relProp.with}IdAsyncSelect
|
|
545
|
+
subset="A"
|
|
546
|
+
{...register("${col.name}")}
|
|
547
|
+
placeholder="${col.label ?? relProp.with}"
|
|
548
|
+
clearable
|
|
549
|
+
className="w-[200px] h-8 text-xs"
|
|
550
|
+
/>`;
|
|
551
|
+
} catch {
|
|
552
|
+
return "";
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
return "";
|
|
556
|
+
}).filter(Boolean).join("\n")}
|
|
557
|
+
${filterColumns.some((col)=>col.name === "orderBy") ? ` <${names.capital}OrderBySelect
|
|
558
|
+
{...register("orderBy")}
|
|
559
|
+
placeholder="Sort"
|
|
560
|
+
textPrefix="Sort: "
|
|
561
|
+
className="w-[200px] h-8 bg-white border-gray-300 text-xs"
|
|
562
|
+
/>` : ""}
|
|
563
|
+
<span className="text-xs text-muted-foreground">{total ?? 0} results</span>
|
|
564
|
+
</div>
|
|
565
|
+
</div>
|
|
566
|
+
</CardHeader>
|
|
567
|
+
|
|
568
|
+
<CardContent className="px-6 pb-6 pt-6 bg-white">
|
|
569
|
+
{/* Table */}
|
|
570
|
+
<Table>
|
|
571
|
+
<TableHeader>
|
|
572
|
+
<TableRow className="hover:bg-transparent bg-gray-100">
|
|
573
|
+
<TableHead className="h-9 text-xs w-[40px]">
|
|
574
|
+
<Checkbox
|
|
575
|
+
checked={isAllSelected()}
|
|
576
|
+
onValueChange={handleSelectAll}
|
|
577
|
+
/>
|
|
578
|
+
</TableHead>
|
|
579
|
+
{columns.map((col, idx) => (
|
|
580
|
+
<TableHead key={idx} fit={col.fit} align={col.align}>
|
|
581
|
+
{col.label}
|
|
582
|
+
</TableHead>
|
|
583
|
+
))}
|
|
584
|
+
</TableRow>
|
|
585
|
+
</TableHeader>
|
|
586
|
+
<TableBody>
|
|
587
|
+
{!isLoading && rows && rows.map((row) => (
|
|
588
|
+
<Fragment key={row.id}>
|
|
589
|
+
<TableRow>
|
|
590
|
+
<TableCell className="py-3">
|
|
591
|
+
<Checkbox
|
|
592
|
+
checked={selectedItems.has(row.id)}
|
|
593
|
+
onValueChange={() => handleToggleItem(row.id)}
|
|
594
|
+
/>
|
|
595
|
+
</TableCell>
|
|
596
|
+
{columns.map((col, idx) => (
|
|
597
|
+
<TableCell key={idx} fit={col.fit} align={col.align} className="py-3">
|
|
598
|
+
{col.tc(row)}
|
|
599
|
+
</TableCell>
|
|
600
|
+
))}
|
|
601
|
+
</TableRow>
|
|
602
|
+
</Fragment>
|
|
603
|
+
))}
|
|
604
|
+
</TableBody>
|
|
605
|
+
</Table>
|
|
450
606
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
선택 해제
|
|
461
|
-
</Button>
|
|
462
|
-
<Button size="tiny" color="red" onClick={confirmDelSelected}>
|
|
463
|
-
일괄 삭제
|
|
464
|
-
</Button>
|
|
465
|
-
</Message>
|
|
466
|
-
</Transition>
|
|
607
|
+
{/* Pagination */}
|
|
608
|
+
<Pagination
|
|
609
|
+
{...register("page")}
|
|
610
|
+
total={total ?? 0}
|
|
611
|
+
itemsPerPage={listParams.num ?? 10}
|
|
612
|
+
/>
|
|
613
|
+
</CardContent>
|
|
614
|
+
</Card>
|
|
615
|
+
</div>
|
|
467
616
|
</div>
|
|
617
|
+
|
|
618
|
+
{/* Delete Dialog */}
|
|
619
|
+
<AlertDialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
|
|
620
|
+
<AlertDialogContent>
|
|
621
|
+
<AlertDialogHeader>
|
|
622
|
+
<AlertDialogTitle>Are you sure?</AlertDialogTitle>
|
|
623
|
+
<AlertDialogDescription>
|
|
624
|
+
This action cannot be undone. This will permanently delete this item.
|
|
625
|
+
</AlertDialogDescription>
|
|
626
|
+
</AlertDialogHeader>
|
|
627
|
+
<AlertDialogFooter>
|
|
628
|
+
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
|
629
|
+
<AlertDialogAction onClick={handleConfirmDelete}>Delete</AlertDialogAction>
|
|
630
|
+
</AlertDialogFooter>
|
|
631
|
+
</AlertDialogContent>
|
|
632
|
+
</AlertDialog>
|
|
468
633
|
</div>
|
|
469
634
|
);
|
|
470
635
|
}
|
|
@@ -475,4 +640,4 @@ export default function ${names.capital}List({}: ${names.capital}ListProps) {
|
|
|
475
640
|
}
|
|
476
641
|
}
|
|
477
642
|
|
|
478
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZW1wbGF0ZS9pbXBsZW1lbnRhdGlvbnMvdmlld19saXN0LnRlbXBsYXRlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhc3NlcnQgZnJvbSBcImFzc2VydFwiO1xuaW1wb3J0IGluZmxlY3Rpb24gZnJvbSBcImluZmxlY3Rpb25cIjtcbmltcG9ydCB7IGZsYXQsIHVuaXF1ZSB9IGZyb20gXCJyYWRhc2hpXCI7XG5pbXBvcnQgeyB6IH0gZnJvbSBcInpvZFwiO1xuaW1wb3J0IHsgRW50aXR5TWFuYWdlciwgdHlwZSBFbnRpdHlOYW1lc1JlY29yZCB9IGZyb20gXCIuLi8uLi9lbnRpdHkvZW50aXR5LW1hbmFnZXJcIjtcbmltcG9ydCB0eXBlIHsgUmVuZGVyaW5nTm9kZSwgVGVtcGxhdGVLZXksIFRlbXBsYXRlT3B0aW9ucyB9IGZyb20gXCIuLi8uLi90eXBlcy90eXBlc1wiO1xuaW1wb3J0IHsgZ2V0Q29sdW1uc05vZGUgfSBmcm9tIFwiLi4vZW50aXR5LWNvbnZlcnRlclwiO1xuaW1wb3J0IHsgZ2V0RW51bUluZm9Gcm9tQ29sTmFtZSwgZ2V0UmVsYXRpb25Qcm9wRnJvbUNvbE5hbWUgfSBmcm9tIFwiLi4vaGVscGVyc1wiO1xuaW1wb3J0IHR5cGUgeyBSZW5kZXJlZFRlbXBsYXRlIH0gZnJvbSBcIi4uL3RlbXBsYXRlXCI7XG5pbXBvcnQgeyBUZW1wbGF0ZSB9IGZyb20gXCIuLi90ZW1wbGF0ZVwiO1xuaW1wb3J0IHsgZ2V0Wm9kVHlwZUJ5SWQsIHpvZFR5cGVUb1JlbmRlcmluZ05vZGUgfSBmcm9tIFwiLi4vem9kLWNvbnZlcnRlclwiO1xuXG5leHBvcnQgY2xhc3MgVGVtcGxhdGVfX3ZpZXdfbGlzdCBleHRlbmRzIFRlbXBsYXRlIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoXCJ2aWV3X2xpc3RcIik7XG4gIH1cblxuICBnZXRUYXJnZXRBbmRQYXRoKG5hbWVzOiBFbnRpdHlOYW1lc1JlY29yZCkge1xuICAgIHJldHVybiB7XG4gICAgICB0YXJnZXQ6IFwid2ViL3NyYy9wYWdlcy9hZG1pblwiLFxuICAgICAgcGF0aDogYCR7bmFtZXMuZnNQbHVyYWx9L2luZGV4LnRzeGAsXG4gICAgfTtcbiAgfVxuXG4gIHdyYXBUYyhib2R5OiBzdHJpbmcsIGtleTogc3RyaW5nLCBjb2xsYXBzaW5nOiBib29sZWFuID0gdHJ1ZSwgY2xhc3NOYW1lOiBzdHJpbmcgPSBcIlwiKSB7XG4gICAgcmV0dXJuIGA8VGFibGUuQ2VsbCBrZXk9XCIke2tleX1cIiR7Y29sbGFwc2luZyA/IFwiIGNvbGxhcHNpbmdcIiA6IFwiXCJ9JHtcbiAgICAgIGNsYXNzTmFtZSA/IGAgY2xhc3NOYW1lPXtcXGAke2NsYXNzTmFtZX1cXGB9YCA6IFwiXCJcbiAgICB9PiR7Ym9keX08L1RhYmxlLkNlbGw+YDtcbiAgfVxuXG4gIHJlbmRlckNvbHVtbihcbiAgICBlbnRpdHlJZDogc3RyaW5nLFxuICAgIGNvbDogUmVuZGVyaW5nTm9kZSxcbiAgICBuYW1lczogRW50aXR5TmFtZXNSZWNvcmQsXG4gICAgcGFyZW50T2JqOiBzdHJpbmcgPSBcInJvd1wiLFxuICAgIHdpdGhvdXROYW1lOiBib29sZWFuID0gZmFsc2UsXG4gICk6IHN0cmluZyB7XG4gICAgY29uc3QgY29sTmFtZSA9IHdpdGhvdXROYW1lID8gYCR7cGFyZW50T2JqfWAgOiBgJHtwYXJlbnRPYmp9LiR7Y29sLm5hbWV9YDtcblxuICAgIHN3aXRjaCAoY29sLnJlbmRlclR5cGUpIHtcbiAgICAgIGNhc2UgXCJzdHJpbmctcGxhaW5cIjpcbiAgICAgIGNhc2UgXCJzdHJpbmctZGF0ZVwiOlxuICAgICAgY2FzZSBcIm51bWJlci1pZFwiOlxuICAgICAgICByZXR1cm4gYDw+eyR7Y29sTmFtZX19PC8+YDtcbiAgICAgIGNhc2UgXCJudW1iZXItZmtfaWRcIjoge1xuICAgICAgICBjb25zdCByZWxQcm9wRmsgPSBnZXRSZWxhdGlvblByb3BGcm9tQ29sTmFtZShlbnRpdHlJZCwgY29sLm5hbWUucmVwbGFjZShcIl9pZFwiLCBcIlwiKSk7XG4gICAgICAgIHJldHVybiBgPD4ke3JlbFByb3BGay53aXRofSN7JHtjb2xOYW1lfX08Lz5gO1xuICAgICAgfVxuICAgICAgY2FzZSBcInN0cmluZy1pbWFnZVwiOlxuICAgICAgICByZXR1cm4gYDw+eyR7Y29sLm51bGxhYmxlID8gYCR7Y29sTmFtZX0gJiYgYCA6IFwiXCJ9PGltZyBzcmM9eyR7Y29sTmFtZX19IC8+fTwvPmA7XG4gICAgICBjYXNlIFwiZGF0ZXRpbWVcIjpcbiAgICAgICAgaWYgKGNvbC5udWxsYWJsZSkge1xuICAgICAgICAgIHJldHVybiBgPHNwYW4gY2xhc3NOYW1lPVwidGV4dC10aW55XCI+eyR7Y29sTmFtZX0gPT09IG51bGwgPyAnLScgOiBmb3JtYXREYXRlVGltZSgke2NvbE5hbWV9KX08L3NwYW4+YDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gYDxzcGFuIGNsYXNzTmFtZT1cInRleHQtdGlueVwiPntmb3JtYXREYXRlVGltZSgke2NvbE5hbWV9KX08L3NwYW4+YDtcbiAgICAgICAgfVxuICAgICAgY2FzZSBcInN0cmluZy1kYXRldGltZVwiOlxuICAgICAgICBpZiAoY29sLm51bGxhYmxlKSB7XG4gICAgICAgICAgcmV0dXJuIGA8c3BhbiBjbGFzc05hbWU9XCJ0ZXh0LXRpbnlcIj57JHtjb2xOYW1lfSA9PT0gbnVsbCA/ICctJyA6IGRhdGVGKCR7Y29sTmFtZX0pfTwvc3Bhbj5gO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBgPHNwYW4gY2xhc3NOYW1lPVwidGV4dC10aW55XCI+e2RhdGVGKCR7Y29sTmFtZX0pfTwvc3Bhbj5gO1xuICAgICAgICB9XG4gICAgICBjYXNlIFwiYm9vbGVhblwiOlxuICAgICAgICByZXR1cm4gYDw+eyR7Y29sTmFtZX0gPyA8TGFiZWwgY29sb3I9J2dyZWVuJyBjaXJjdWxhcj5PPC9MYWJlbD4gOiA8TGFiZWwgY29sb3I9J2dyZXknIGNpcmN1bGFyPlg8L0xhYmVsPiB9PC8+YDtcbiAgICAgIGNhc2UgXCJlbnVtc1wiOiB7XG4gICAgICAgIGNvbnN0IHsgaWQ6IGVudW1JZCB9ID0gZ2V0RW51bUluZm9Gcm9tQ29sTmFtZShlbnRpdHlJZCwgY29sLm5hbWUpO1xuICAgICAgICByZXR1cm4gYDw+eyR7Y29sLm51bGxhYmxlID8gYCR7Y29sTmFtZX0gJiYgYCA6IFwiXCJ9JHtlbnVtSWR9TGFiZWxbJHtjb2xOYW1lfV19PC8+YDtcbiAgICAgIH1cbiAgICAgIGNhc2UgXCJhcnJheS1pbWFnZXNcIjpcbiAgICAgICAgcmV0dXJuIGA8PnsgJHtjb2xOYW1lfS5tYXAociA9PiAke2NvbC5udWxsYWJsZSA/IGByICYmIGAgOiBcIlwifTxpbWcgc3JjPXtyfSAvPikgfTwvPmA7XG4gICAgICBjYXNlIFwibnVtYmVyLXBsYWluXCI6XG4gICAgICAgIHJldHVybiBgPD57JHtjb2wubnVsbGFibGUgPyBgJHtjb2xOYW1lfSAmJiBgIDogXCJcIn1udW1GKCR7Y29sTmFtZX0pfTwvPmA7XG4gICAgICBjYXNlIFwib2JqZWN0XCI6XG4gICAgICAgIHJldHVybiBgPD57Lyogb2JqZWN0ICR7Y29sTmFtZX0gKi99PC8+YDtcbiAgICAgIGNhc2UgXCJvYmplY3QtcGlja1wiOiB7XG4gICAgICAgIGNvbnN0IHBpY2tlZENoaWxkID0gY29sLmNoaWxkcmVuPy5maW5kKChjaGlsZCkgPT4gY2hpbGQubmFtZSA9PT0gY29sLmNvbmZpZz8ucGlja2VkKTtcbiAgICAgICAgaWYgKCFwaWNrZWRDaGlsZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgb2JqZWN0LXBpY2sg7ISg7YOdIOyLpO2MqCAo7Jik67iM7KCd7Yq4OiAke2NvbC5uYW1lfSlgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5yZW5kZXJDb2x1bW4oXG4gICAgICAgICAgZW50aXR5SWQsXG4gICAgICAgICAgcGlja2VkQ2hpbGQsXG4gICAgICAgICAgbmFtZXMsXG4gICAgICAgICAgYCR7Y29sTmFtZX0ke2NvbC5udWxsYWJsZSA/IFwiP1wiIDogXCJcIn1gLFxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgY2FzZSBcImFycmF5XCI6XG4gICAgICAgIHJldHVybiBgPD57IC8qIGFycmF5ICR7Y29sTmFtZX0gKi8gfTwvPmA7XG4gICAgICBjYXNlIFwidmVjdG9yXCI6XG4gICAgICAgIC8vIHZlY3RvciDtg4DsnoXsnYAg7LCo7JuQIOyImOunjCDtkZzsi5wgKOyLpOygnCDrjbDsnbTthLDripQg64SI66y0IOq5gClcbiAgICAgICAgcmV0dXJuIGA8Pnske2NvbC5udWxsYWJsZSA/IGAke2NvbE5hbWV9ID8gYCA6IFwiXCJ9W1ZlY3RvcjogeyR7Y29sTmFtZX0ke2NvbC5udWxsYWJsZSA/IFwiXCIgOiBcIiA/PyBbXVwifS5sZW5ndGh9ZF0ke2NvbC5udWxsYWJsZSA/IFwiIDogJy0nXCIgOiBcIlwifX08Lz5gO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGDroIzrjZQg67aI6rCAIOy7rOufvCAke2NvbC5yZW5kZXJUeXBlfWApO1xuICAgIH1cbiAgfVxuXG4gIHJlbmRlckNvbHVtbkltcG9ydChcbiAgICBlbnRpdHlJZDogc3RyaW5nLFxuICAgIGNvbDogUmVuZGVyaW5nTm9kZSxcbiAgICBuYW1lczogRW50aXR5TmFtZXNSZWNvcmQsXG4gICk6IChzdHJpbmcgfCBudWxsKVtdIHtcbiAgICBpZiAoY29sLnJlbmRlclR5cGUgPT09IFwiZW51bXNcIikge1xuICAgICAgY29uc3QgeyBpZDogZW51bUlkIH0gPSBnZXRFbnVtSW5mb0Zyb21Db2xOYW1lKG5hbWVzLmNhcGl0YWwsIGNvbC5uYW1lKTtcbiAgICAgIHJldHVybiBbYGltcG9ydCB7ICR7ZW51bUlkfUxhYmVsIH0gZnJvbSAnQC9zZXJ2aWNlcy9zb25hbXUuZ2VuZXJhdGVkJztgXTtcbiAgICB9IGVsc2UgaWYgKGNvbC5yZW5kZXJUeXBlID09PSBcIm9iamVjdFwiKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCByZWxQcm9wID0gZ2V0UmVsYXRpb25Qcm9wRnJvbUNvbE5hbWUoZW50aXR5SWQsIGNvbC5uYW1lKTtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gY29sLmNoaWxkcmVuPy5tYXAoKGNoaWxkKSA9PiB7XG4gICAgICAgICAgZW50aXR5SWQgPSByZWxQcm9wLndpdGg7XG4gICAgICAgICAgbmFtZXMgPSBFbnRpdHlNYW5hZ2VyLmdldE5hbWVzRnJvbUlkKHJlbFByb3Aud2l0aCk7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVuZGVyQ29sdW1uSW1wb3J0KGVudGl0eUlkLCBjaGlsZCwgbmFtZXMpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGZsYXQocmVzdWx0ID8/IFtdKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gW251bGxdO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY29sLnJlbmRlclR5cGUgPT09IFwiYXJyYXlcIikge1xuICAgICAgYXNzZXJ0KGNvbC5lbGVtZW50KTtcbiAgICAgIHJldHVybiB0aGlzLnJlbmRlckNvbHVtbkltcG9ydChlbnRpdHlJZCwgY29sLmVsZW1lbnQsIG5hbWVzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gW251bGxdO1xuICB9XG5cbiAgcmVuZGVyRmlsdGVySW1wb3J0KGVudGl0eUlkOiBzdHJpbmcsIGNvbDogUmVuZGVyaW5nTm9kZSwgbmFtZXM6IEVudGl0eU5hbWVzUmVjb3JkKSB7XG4gICAgaWYgKGNvbC5uYW1lID09PSBcInNlYXJjaFwiKSB7XG4gICAgICByZXR1cm4gYGltcG9ydCB7ICR7bmFtZXMuY2FwaXRhbH1TZWFyY2hJbnB1dCB9IGZyb20gXCJAL2NvbXBvbmVudHMvJHtuYW1lcy5mc30vJHtuYW1lcy5jYXBpdGFsfVNlYXJjaElucHV0XCI7YDtcbiAgICB9IGVsc2UgaWYgKGNvbC5yZW5kZXJUeXBlID09PSBcImVudW1zXCIpIHtcbiAgICAgIGlmIChjb2wubmFtZSA9PT0gXCJvcmRlckJ5XCIpIHtcbiAgICAgICAgY29uc3QgY29tcG9uZW50SWQgPSBgJHtuYW1lcy5jYXBpdGFsfSR7aW5mbGVjdGlvbi5jYW1lbGl6ZShjb2wubmFtZSl9U2VsZWN0YDtcbiAgICAgICAgcmV0dXJuIGBpbXBvcnQgeyAke2NvbXBvbmVudElkfSB9IGZyb20gXCJAL2NvbXBvbmVudHMvJHtuYW1lcy5mc30vJHtjb21wb25lbnRJZH1cIjtgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB7IGlkLCB0YXJnZXRFbnRpdHlOYW1lczogdGFyZ2V0TUROYW1lcyB9ID0gZ2V0RW51bUluZm9Gcm9tQ29sTmFtZShcbiAgICAgICAgICAgIGVudGl0eUlkLFxuICAgICAgICAgICAgY29sLm5hbWUsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCBjb21wb25lbnRJZCA9IGAke2lkfVNlbGVjdGA7XG4gICAgICAgICAgcmV0dXJuIGBpbXBvcnQgeyAke2NvbXBvbmVudElkfSB9IGZyb20gXCJAL2NvbXBvbmVudHMvJHt0YXJnZXRNRE5hbWVzLmZzfS8ke2NvbXBvbmVudElkfVwiO2A7XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjb2wucmVuZGVyVHlwZSA9PT0gXCJudW1iZXItZmtfaWRcIikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVsUHJvcCA9IGdldFJlbGF0aW9uUHJvcEZyb21Db2xOYW1lKGVudGl0eUlkLCBjb2wubmFtZS5yZXBsYWNlKFwiX2lkXCIsIFwiXCIpKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0TmFtZXMgPSBFbnRpdHlNYW5hZ2VyLmdldE5hbWVzRnJvbUlkKHJlbFByb3Aud2l0aCk7XG4gICAgICAgIGNvbnN0IGNvbXBvbmVudElkID0gYCR7cmVsUHJvcC53aXRofUlkQXN5bmNTZWxlY3RgO1xuICAgICAgICByZXR1cm4gYGltcG9ydCB7ICR7Y29tcG9uZW50SWR9IH0gZnJvbSBcIkAvY29tcG9uZW50cy8ke3RhcmdldE5hbWVzLmZzfS8ke2NvbXBvbmVudElkfVwiO2A7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihg66CM642UIOu2iOqwgOuKpe2VnCDtlYTthLAg7J6E7Y+s7Yq4ICR7Y29sLm5hbWV9ICR7Y29sLnJlbmRlclR5cGV9YCk7XG4gICAgfVxuICB9XG5cbiAgcmVuZGVyRmlsdGVyKGVudGl0eUlkOiBzdHJpbmcsIGNvbDogUmVuZGVyaW5nTm9kZSwgbmFtZXM6IEVudGl0eU5hbWVzUmVjb3JkKSB7XG4gICAgaWYgKGNvbC5uYW1lID09PSBcInNlYXJjaFwiKSB7XG4gICAgICByZXR1cm4gXCJcIjtcbiAgICB9XG5cbiAgICBjb25zdCBpc0NsZWFyYWJsZSA9IGNvbC5vcHRpb25hbCA9PT0gdHJ1ZSAmJiBjb2wubmFtZSAhPT0gXCJvcmRlckJ5XCI7XG4gICAgbGV0IGNvbXBvbmVudElkOiBzdHJpbmc7XG4gICAgaWYgKGNvbC5yZW5kZXJUeXBlID09PSBcImVudW1zXCIpIHtcbiAgICAgIGlmIChjb2wubmFtZSA9PT0gXCJvcmRlckJ5XCIpIHtcbiAgICAgICAgY29tcG9uZW50SWQgPSBgJHtuYW1lcy5jYXBpdGFsfSR7aW5mbGVjdGlvbi5jYW1lbGl6ZShjb2wubmFtZSl9U2VsZWN0YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyBpZCB9ID0gZ2V0RW51bUluZm9Gcm9tQ29sTmFtZShlbnRpdHlJZCwgY29sLm5hbWUpO1xuICAgICAgICAgIGNvbXBvbmVudElkID0gYCR7aWR9U2VsZWN0YDtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBgPCR7Y29tcG9uZW50SWR9IHsuLi5yZWdpc3RlcignJHtjb2wubmFtZX0nKX0gJHtpc0NsZWFyYWJsZSA/IFwiY2xlYXJhYmxlXCIgOiBcIlwifSAvPmA7XG4gICAgfSBlbHNlIGlmIChjb2wucmVuZGVyVHlwZSA9PT0gXCJudW1iZXItZmtfaWRcIikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVsUHJvcCA9IGdldFJlbGF0aW9uUHJvcEZyb21Db2xOYW1lKGVudGl0eUlkLCBjb2wubmFtZS5yZXBsYWNlKFwiX2lkXCIsIFwiXCIpKTtcbiAgICAgICAgY29tcG9uZW50SWQgPSBgJHtyZWxQcm9wLndpdGh9SWRBc3luY1NlbGVjdGA7XG4gICAgICAgIHJldHVybiBgPCR7Y29tcG9uZW50SWR9IHsuLi5yZWdpc3RlcignJHtjb2wubmFtZX0nKX0gJHtcbiAgICAgICAgICBpc0NsZWFyYWJsZSA/IFwiY2xlYXJhYmxlXCIgOiBcIlwiXG4gICAgICAgIH0gc3Vic2V0PVwiQVwiIC8+YDtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGDroIzrjZQg67aI6rCA64ql7ZWcIO2VhO2EsCDsnoTtj6ztirggJHtjb2wubmFtZX0gJHtjb2wucmVuZGVyVHlwZX1gKTtcbiAgICB9XG4gIH1cblxuICBnZXREZWZhdWx0KGNvbHVtbnM6IFJlbmRlcmluZ05vZGVbXSk6IHtcbiAgICBvcmRlckJ5OiBzdHJpbmc7XG4gICAgc2VhcmNoOiBzdHJpbmc7XG4gIH0ge1xuICAgIGNvbnN0IGRlZiA9IHtcbiAgICAgIG9yZGVyQnk6IFwiaWQtZGVzY1wiLFxuICAgICAgc2VhcmNoOiBcInRpdGxlXCIsXG4gICAgfTtcbiAgICBjb25zdCBvcmRlckJ5Wm9kVHlwZSA9IGNvbHVtbnMuZmluZCgoY29sKSA9PiBjb2wubmFtZSA9PT0gXCJvcmRlckJ5XCIpPy56b2RUeXBlO1xuICAgIGlmIChvcmRlckJ5Wm9kVHlwZSAmJiBvcmRlckJ5Wm9kVHlwZSBpbnN0YW5jZW9mIHouWm9kRW51bSkge1xuICAgICAgZGVmLm9yZGVyQnkgPSBvcmRlckJ5Wm9kVHlwZS5vcHRpb25zWzBdLnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIGNvbnN0IHNlYXJjaFpvZFR5cGUgPSBjb2x1bW5zLmZpbmQoKGNvbCkgPT4gY29sLm5hbWUgPT09IFwic2VhcmNoXCIpPy56b2RUeXBlO1xuICAgIGlmIChzZWFyY2hab2RUeXBlICYmIHNlYXJjaFpvZFR5cGUgaW5zdGFuY2VvZiB6LlpvZEVudW0pIHtcbiAgICAgIGRlZi5zZWFyY2ggPSBzZWFyY2hab2RUeXBlLm9wdGlvbnNbMF0udG9TdHJpbmcoKTtcbiAgICB9XG4gICAgcmV0dXJuIGRlZjtcbiAgfVxuXG4gIGFzeW5jIHJlbmRlcih7IGVudGl0eUlkIH06IFRlbXBsYXRlT3B0aW9uc1tcInZpZXdfbGlzdFwiXSkge1xuICAgIGNvbnN0IGNvbHVtbnNOb2RlID0gYXdhaXQgZ2V0Q29sdW1uc05vZGUoZW50aXR5SWQsIFwiQVwiKTtcbiAgICBjb25zdCBsaXN0UGFyYW1zWm9kVHlwZSA9IGF3YWl0IGdldFpvZFR5cGVCeUlkKGAke2VudGl0eUlkfUxpc3RQYXJhbXNgKTtcbiAgICBjb25zdCBsaXN0UGFyYW1zTm9kZSA9IHpvZFR5cGVUb1JlbmRlcmluZ05vZGUobGlzdFBhcmFtc1pvZFR5cGUpO1xuXG4gICAgY29uc3QgbmFtZXMgPSBFbnRpdHlNYW5hZ2VyLmdldE5hbWVzRnJvbUlkKGVudGl0eUlkKTtcbiAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAvLyDsi6TsoJwg66as7Iqk7Yq4IOy7rOufvFxuICAgIGNvbnN0IGNvbHVtbnMgPSAoY29sdW1uc05vZGUuY2hpbGRyZW4gYXMgUmVuZGVyaW5nTm9kZVtdKVxuICAgICAgLmZpbHRlcigoY29sKSA9PiBjb2wubmFtZSAhPT0gXCJpZFwiKVxuICAgICAgLm1hcCgoY29sKSA9PiB7XG4gICAgICAgIGNvbnN0IHByb3BDYW5kaWRhdGUgPSBlbnRpdHkucHJvcHMuZmluZCgocCkgPT4gcC5uYW1lID09PSBjb2wubmFtZSk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgbmFtZTogY29sLm5hbWUsXG4gICAgICAgICAgbGFiZWw6IHByb3BDYW5kaWRhdGU/LmRlc2MgPz8gY29sLmxhYmVsLFxuICAgICAgICAgIHRjOiBgKHJvdykgPT4gJHt0aGlzLnJlbmRlckNvbHVtbihlbnRpdHlJZCwgY29sLCBuYW1lcyl9YCxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuXG4gICAgLy8g7ZWE7YSwIOy7rOufvFxuICAgIGNvbnN0IGZpbHRlckNvbHVtbnMgPSAobGlzdFBhcmFtc05vZGUuY2hpbGRyZW4gYXMgUmVuZGVyaW5nTm9kZVtdKVxuICAgICAgLmZpbHRlcihcbiAgICAgICAgKGNvbCkgPT5cbiAgICAgICAgICBjb2wubmFtZSAhPT0gXCJpZFwiICYmXG4gICAgICAgICAgY29sLm5hbWUgIT09IFwicXVlcnlNb2RlXCIgJiZcbiAgICAgICAgICAoW1wiZW51bXNcIiwgXCJudW1iZXItaWRcIl0uaW5jbHVkZXMoY29sLnJlbmRlclR5cGUpIHx8IGNvbC5uYW1lLmVuZHNXaXRoKFwiX2lkXCIpKSxcbiAgICAgIClcbiAgICAgIC8vIG9yZGVyQnnqsIAg6rCA7J6lIOuSpOuhnCDsmKTqsowg7Iic7IScIOyhsOyglVxuICAgICAgLnNvcnQoKGEpID0+IHtcbiAgICAgICAgcmV0dXJuIGEubmFtZSA9PT0gXCJvcmRlckJ5XCIgPyAxIDogLTE7XG4gICAgICB9KTtcblxuICAgIC8vIO2VhO2EsCDsu6zrn7zsnYQg7ZSE66asIO2FnO2UjOumv+ycvOuhnCDshKTsoJVcbiAgICBjb25zdCBwcmVUZW1wbGF0ZXM6IFJlbmRlcmVkVGVtcGxhdGVbXCJwcmVUZW1wbGF0ZXNcIl0gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGNvbCBvZiBmaWx0ZXJDb2x1bW5zKSB7XG4gICAgICBsZXQga2V5OiBUZW1wbGF0ZUtleTtcbiAgICAgIGxldCB0YXJnZXRFbnRpdHlJZCA9IGVudGl0eUlkO1xuICAgICAgbGV0IGVudW1JZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgICBpZiAoY29sLnJlbmRlclR5cGUgPT09IFwiZW51bXNcIikge1xuICAgICAgICBpZiAoY29sLm5hbWUgPT09IFwic2VhcmNoXCIpIHtcbiAgICAgICAgICBrZXkgPSBcInZpZXdfZW51bXNfZHJvcGRvd25cIjtcbiAgICAgICAgICBlbnVtSWQgPSBgJHtuYW1lcy5jYXBpdGFsfVNlYXJjaEZpZWxkYDtcbiAgICAgICAgICB0YXJnZXRFbnRpdHlJZCA9IG5hbWVzLmNhcGl0YWw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAga2V5ID0gXCJ2aWV3X2VudW1zX3NlbGVjdFwiO1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCB7IHRhcmdldEVudGl0eU5hbWVzLCBpZCB9ID0gZ2V0RW51bUluZm9Gcm9tQ29sTmFtZShlbnRpdHlJZCwgY29sLm5hbWUpO1xuICAgICAgICAgICAgdGFyZ2V0RW50aXR5SWQgPSB0YXJnZXRFbnRpdHlOYW1lcy5jYXBpdGFsO1xuICAgICAgICAgICAgZW51bUlkID0gaWQ7XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGtleSA9IFwidmlld19pZF9hc3luY19zZWxlY3RcIjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCByZWxQcm9wID0gZ2V0UmVsYXRpb25Qcm9wRnJvbUNvbE5hbWUoZW50aXR5SWQsIGNvbC5uYW1lLnJlcGxhY2UoXCJfaWRcIiwgXCJcIikpO1xuICAgICAgICAgIHRhcmdldEVudGl0eUlkID0gcmVsUHJvcC53aXRoO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBwcmVUZW1wbGF0ZXMucHVzaCh7XG4gICAgICAgIGtleSxcbiAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgIGVudGl0eUlkOiB0YXJnZXRFbnRpdHlJZCxcbiAgICAgICAgICBlbnVtSWQsXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyDrpqzsiqTtirgg7Lus65+8XG4gICAgYXNzZXJ0KGNvbHVtbnNOb2RlLmNoaWxkcmVuKTtcbiAgICBjb25zdCBjb2x1bW5JbXBvcnRzID0gdW5pcXVlKFxuICAgICAgY29sdW1uc05vZGUuY2hpbGRyZW5cbiAgICAgICAgLmZsYXRNYXAoKGNvbCkgPT4ge1xuICAgICAgICAgIHJldHVybiB0aGlzLnJlbmRlckNvbHVtbkltcG9ydChlbnRpdHlJZCwgY29sLCBuYW1lcyk7XG4gICAgICAgIH0pXG4gICAgICAgIC5maWx0ZXIoKGNvbCkgPT4gY29sICE9PSBudWxsKSxcbiAgICApLmpvaW4oXCJcXG5cIik7XG5cbiAgICAvLyBTZWFyY2hJbnB1dFxuICAgIGFzc2VydChwcmVUZW1wbGF0ZXMpO1xuICAgIHByZVRlbXBsYXRlcy5wdXNoKHtcbiAgICAgIGtleTogXCJ2aWV3X3NlYXJjaF9pbnB1dFwiLFxuICAgICAgb3B0aW9uczoge1xuICAgICAgICBlbnRpdHlJZCxcbiAgICAgIH0sXG4gICAgfSk7XG5cbiAgICAvLyDrlJTtj7Ttirgg7YyM652866+47YSwXG4gICAgY29uc3QgZGVmID0gdGhpcy5nZXREZWZhdWx0KGZpbHRlckNvbHVtbnMpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLnRoaXMuZ2V0VGFyZ2V0QW5kUGF0aChuYW1lcyksXG4gICAgICBib2R5OiBgXG5pbXBvcnQgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgTGluayB9IGZyb20gJ3JlYWN0LXJvdXRlci1kb20nO1xuaW1wb3J0IHtcbiAgQnJlYWRjcnVtYixcbiAgQ2hlY2tib3gsXG4gIFBhZ2luYXRpb24sXG4gIFNlZ21lbnQsXG4gIFRhYmxlLFxuICBUYWJsZVJvdyxcbiAgTWVzc2FnZSxcbiAgVHJhbnNpdGlvbixcbiAgQnV0dG9uLFxuICBMYWJlbCxcbn0gZnJvbSAnc2VtYW50aWMtdWktcmVhY3QnO1xuaW1wb3J0IGNsYXNzTmFtZXMgZnJvbSAnY2xhc3NuYW1lcyc7XG5pbXBvcnQgeyBEYXRlVGltZSB9IGZyb20gXCJsdXhvblwiO1xuaW1wb3J0IHsgRGVsQnV0dG9uLCBFZGl0QnV0dG9uLCBBcHBCcmVhZGNydW1icywgQWRkQnV0dG9uLCB1c2VTZWxlY3Rpb24sIHVzZUxpc3RQYXJhbXMsIFNvbmFtdUNvbCwgbnVtRiwgZm9ybWF0RGF0ZSwgZm9ybWF0RGF0ZVRpbWUgfSBmcm9tICdAc29uYW11LWtpdC9yZWFjdC1zdWknO1xuXG5pbXBvcnQgeyAke25hbWVzLmNhcGl0YWx9U3Vic2V0QSB9IGZyb20gXCJAL3NlcnZpY2VzL3NvbmFtdS5nZW5lcmF0ZWRcIjtcbmltcG9ydCB7ICR7bmFtZXMuY2FwaXRhbH1TZXJ2aWNlIH0gZnJvbSAnQC9zZXJ2aWNlcy9zZXJ2aWNlcy5nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgJHtuYW1lcy5jYXBpdGFsfUxpc3RQYXJhbXMgfSBmcm9tICdAL3NlcnZpY2VzLyR7bmFtZXMuZnN9LyR7bmFtZXMuZnN9LnR5cGVzJztcbiR7Y29sdW1uSW1wb3J0c31cbiR7ZmlsdGVyQ29sdW1uc1xuICAubWFwKChjb2wpID0+IHtcbiAgICByZXR1cm4gdGhpcy5yZW5kZXJGaWx0ZXJJbXBvcnQoZW50aXR5SWQsIGNvbCwgbmFtZXMpO1xuICB9KVxuICAuam9pbihcIlxcblwiKX1cblxudHlwZSAke25hbWVzLmNhcGl0YWx9TGlzdFByb3BzID0ge307XG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAke25hbWVzLmNhcGl0YWx9TGlzdCh7fTogJHtuYW1lcy5jYXBpdGFsfUxpc3RQcm9wcykge1xuICAvLyDrpqzsiqTtirgg7ZWE7YSwXG4gIGNvbnN0IHsgbGlzdFBhcmFtcywgcmVnaXN0ZXIgfSA9IHVzZUxpc3RQYXJhbXMoJHtuYW1lcy5jYXBpdGFsfUxpc3RQYXJhbXMsIHtcbiAgICBudW06IDEyLFxuICAgIHBhZ2U6IDEsXG4gICAgb3JkZXJCeTogJyR7ZGVmLm9yZGVyQnl9JyxcbiAgICBzZWFyY2g6ICcke2RlZi5zZWFyY2h9JyxcbiAgfSk7XG5cbiAgLy8g66as7Iqk7Yq4IOy/vOumrFxuICBjb25zdCB7IGRhdGEsIHJlZmV0Y2gsIGlzTG9hZGluZyB9ID0gJHtuYW1lcy5jYXBpdGFsfVNlcnZpY2UudXNlJHtcbiAgICBuYW1lcy5jYXBpdGFsUGx1cmFsXG4gIH0oJ0EnLCBsaXN0UGFyYW1zKTtcbiAgY29uc3QgeyByb3dzLCB0b3RhbCB9ID0gZGF0YSA/PyB7fTtcblxuICAvLyDsgq3soJxcbiAgY29uc3QgY29uZmlybURlbCA9IChpZHM6IG51bWJlcltdKSA9PiB7XG4gICAgY29uc3QgYW5zd2VyID0gY29uZmlybSgn7IKt7KCc7ZWY7Iuc6rKg7Iq164uI6rmMPycpO1xuICAgIGlmICghYW5zd2VyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgJHtuYW1lcy5jYXBpdGFsfVNlcnZpY2UuZGVsKGlkcykudGhlbigoKSA9PiB7XG4gICAgICByZWZldGNoKCk7XG4gICAgfSk7XG4gIH07XG5cbiAgLy8g7J286rSEIOyCreygnFxuICBjb25zdCBjb25maXJtRGVsU2VsZWN0ZWQgPSAoKSA9PiB7XG4gICAgY29uc3QgYW5zd2VyID0gY29uZmlybShcXGBcXCR7c2VsZWN0ZWRLZXlzLmxlbmd0aH3qsbTsnYQg7J286rSEIOyCreygnO2VmOyLnOqyoOyKteuLiOq5jD9cXGApO1xuICAgIGlmICghYW5zd2VyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgJHtuYW1lcy5jYXBpdGFsfVNlcnZpY2UuZGVsKHNlbGVjdGVkS2V5cykudGhlbigoKSA9PiB7XG4gICAgICByZWZldGNoKCk7XG4gICAgfSk7XG4gIH07XG5cbiAgLy8g7ZiE7J6sIOqyveuhnOyZgCDtg4DsnbTti4BcbiAgY29uc3QgUEFHRSA9IHtcbiAgICByb3V0ZTogJy9hZG1pbi8ke25hbWVzLmZzUGx1cmFsfScsXG4gICAgdGl0bGU6ICcke2VudGl0eS50aXRsZSA/PyBuYW1lcy5jYXBpdGFsfScsXG4gIH07XG5cbiAgLy8g7ISg7YOdXG4gIGNvbnN0IHtcbiAgICBnZXRTZWxlY3RlZCxcbiAgICBpc0FsbFNlbGVjdGVkLFxuICAgIHNlbGVjdGVkS2V5cyxcbiAgICB0b2dnbGUsXG4gICAgc2VsZWN0QWxsLFxuICAgIGRlc2VsZWN0QWxsLFxuICAgIGhhbmRsZUNoZWNrYm94Q2xpY2ssXG4gIH0gPSB1c2VTZWxlY3Rpb24oKHJvd3MgPz8gW10pLm1hcCgocm93KSA9PiByb3cuaWQpKTtcblxuICAvLyDsu6zrn7xcbiAgY29uc3QgY29sdW1uczpTb25hbXVDb2w8JHtuYW1lcy5jYXBpdGFsfVN1YnNldEE+W10gPSBbJHtjb2x1bW5zXG4gICAgLm1hcCgoY29sKSA9PiB7XG4gICAgICByZXR1cm4gW1xuICAgICAgICBgeyBsYWJlbDogXCIke2NvbC5sYWJlbH1cIixgLFxuICAgICAgICBgdGM6ICR7Y29sLnRjfSwgYCxcbiAgICAgICAgYGNvbGxhcHNpbmc6ICR7W1wiVGl0bGVcIiwgXCJOYW1lXCJdLmluY2x1ZGVzKGNvbC5sYWJlbCkgPT09IGZhbHNlfSwgfWAsXG4gICAgICBdLmpvaW4oXCJcXG5cIik7XG4gICAgfSlcbiAgICAuam9pbihcIixcXG5cIil9XTtcblxuICByZXR1cm4gKFxuICAgIDxkaXYgY2xhc3NOYW1lPVwibGlzdCAke25hbWVzLmZzUGx1cmFsfS1pbmRleFwiPlxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJ0b3AtbmF2XCI+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaGVhZGVyLXJvd1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaGVhZGVyXCI+e1BBR0UudGl0bGV9PC9kaXY+XG4gICAgICAgICAgPEFwcEJyZWFkY3J1bWJzPlxuICAgICAgICAgICAgPEJyZWFkY3J1bWIuU2VjdGlvbiBhY3RpdmU+e1BBR0UudGl0bGV9PC9CcmVhZGNydW1iLlNlY3Rpb24+XG4gICAgICAgICAgPC9BcHBCcmVhZGNydW1icz5cbiAgICAgICAgICA8JHtuYW1lcy5jYXBpdGFsfVNlYXJjaElucHV0XG4gICAgICAgICAgICBpbnB1dD17cmVnaXN0ZXIoJ2tleXdvcmQnKX1cbiAgICAgICAgICAgIGRyb3Bkb3duPXtyZWdpc3Rlcignc2VhcmNoJyl9XG4gICAgICAgICAgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZmlsdGVycy1yb3dcIj5cbiAgICAgICAgICAke2ZpbHRlckNvbHVtbnNcbiAgICAgICAgICAgIC5tYXAoKGNvbCkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5yZW5kZXJGaWx0ZXIoZW50aXR5SWQsIGNvbCwgbmFtZXMpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5qb2luKFwiJm5ic3A7XFxuXCIpfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8U2VnbWVudCBiYXNpYyBwYWRkZWQgY2xhc3NOYW1lPVwiY29udGVudHMtc2VnbWVudFwiIGxvYWRpbmc9e2lzTG9hZGluZ30+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYnV0dG9ucy1yb3dcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT17Y2xhc3NOYW1lcygnY291bnQnLCB7IGhpZGRlbjogaXNMb2FkaW5nIH0pfT5cbiAgICAgICAgICAgIHt0b3RhbH0g6rG0XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJidXR0b25zXCI+XG4gICAgICAgICAgICA8QWRkQnV0dG9uIGN1cnJlbnRSb3V0ZT17UEFHRS5yb3V0ZX0gaWNvbj1cIndyaXRlXCIgbGFiZWw9XCLstpTqsIBcIiAvPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8VGFibGVcbiAgICAgICAgICBjZWxsZWRcbiAgICAgICAgICBjb21wYWN0XG4gICAgICAgICAgc2VsZWN0YWJsZVxuICAgICAgICAgIGNsYXNzTmFtZT17Y2xhc3NOYW1lcyh7IGhpZGRlbjogdG90YWwgPT09IHVuZGVmaW5lZCB8fCB0b3RhbCA9PT0gMCB9KX1cbiAgICAgICAgPlxuICAgICAgICAgIDxUYWJsZS5IZWFkZXI+XG4gICAgICAgICAgICA8VGFibGVSb3c+XG4gICAgICAgICAgICAgIDxUYWJsZS5IZWFkZXJDZWxsIGNvbGxhcHNpbmc+XG4gICAgICAgICAgICAgICAgPENoZWNrYm94XG4gICAgICAgICAgICAgICAgICBsYWJlbD1cIklEXCJcbiAgICAgICAgICAgICAgICAgIGNoZWNrZWQ9e2lzQWxsU2VsZWN0ZWR9XG4gICAgICAgICAgICAgICAgICBvbkNoYW5nZT17aXNBbGxTZWxlY3RlZCA/IGRlc2VsZWN0QWxsIDogc2VsZWN0QWxsfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIDwvVGFibGUuSGVhZGVyQ2VsbD5cbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIC8qIEhlYWRlciAqL1xuICAgICAgICAgICAgICAgIGNvbHVtbnMubWFwKChjb2wsIGluZGV4KSA9PiBjb2wudGggPz8gPFRhYmxlLkhlYWRlckNlbGwga2V5PXtpbmRleH0gY29sbGFwc2luZz17Y29sLmNvbGxhcHNpbmd9PnsgY29sLmxhYmVsIH08L1RhYmxlLkhlYWRlckNlbGw+KVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDxUYWJsZS5IZWFkZXJDZWxsPuq0gOumrDwvVGFibGUuSGVhZGVyQ2VsbD5cbiAgICAgICAgICAgIDwvVGFibGVSb3c+XG4gICAgICAgICAgPC9UYWJsZS5IZWFkZXI+XG4gICAgICAgICAgPFRhYmxlLkJvZHk+XG4gICAgICAgICAgICB7cm93cyAmJlxuICAgICAgICAgICAgICByb3dzLm1hcCgocm93LCByb3dJbmRleCkgPT4gKFxuICAgICAgICAgICAgICAgIDxUYWJsZS5Sb3cga2V5PXtyb3cuaWR9PlxuICAgICAgICAgICAgICAgICAgPFRhYmxlLkNlbGw+XG4gICAgICAgICAgICAgICAgICAgIDxDaGVja2JveFxuICAgICAgICAgICAgICAgICAgICAgIGxhYmVsPXtyb3cuaWR9XG4gICAgICAgICAgICAgICAgICAgICAgY2hlY2tlZD17Z2V0U2VsZWN0ZWQocm93LmlkKX1cbiAgICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZT17KCkgPT4gdG9nZ2xlKHJvdy5pZCl9XG4gICAgICAgICAgICAgICAgICAgICAgb25DbGljaz17KGUpID0+XG4gICAgICAgICAgICAgICAgICAgICAgICBoYW5kbGVDaGVja2JveENsaWNrKGUsIHJvd0luZGV4KVxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgIDwvVGFibGUuQ2VsbD5cbiAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgLyogQm9keSAqL1xuICAgICAgICAgICAgICAgICAgICBjb2x1bW5zLm1hcCgoY29sLCBjb2xJbmRleCkgPT4gKFxuICAgICAgICAgICAgICAgICAgICAgIDxUYWJsZS5DZWxsIGtleT17Y29sSW5kZXh9IGNvbGxhcHNpbmc9e2NvbC5jb2xsYXBzaW5nfSBjbGFzc05hbWU9e2NvbC5jbGFzc05hbWV9PlxuICAgICAgICAgICAgICAgICAgICAgICAge2NvbC50Yyhyb3csIHJvd0luZGV4KX1cbiAgICAgICAgICAgICAgICAgICAgICA8L1RhYmxlLkNlbGw+XG4gICAgICAgICAgICAgICAgICAgICkpXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICA8VGFibGUuQ2VsbCBjb2xsYXBzaW5nPlxuICAgICAgICAgICAgICAgICAgICA8RWRpdEJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgIGFzPXtMaW5rfVxuICAgICAgICAgICAgICAgICAgICAgIHRvPXtcXGBcXCR7UEFHRS5yb3V0ZX0vZm9ybT9pZD1cXCR7cm93LmlkfVxcYH1cbiAgICAgICAgICAgICAgICAgICAgICBzdGF0ZT17eyBmcm9tOiBQQUdFLnJvdXRlIH19XG4gICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgIDxEZWxCdXR0b24gb25DbGljaz17KCkgPT4gY29uZmlybURlbChbcm93LmlkXSl9IC8+XG4gICAgICAgICAgICAgICAgICA8L1RhYmxlLkNlbGw+XG4gICAgICAgICAgICAgICAgPC9UYWJsZS5Sb3c+XG4gICAgICAgICAgICAgICkpfVxuICAgICAgICAgIDwvVGFibGUuQm9keT5cbiAgICAgICAgPC9UYWJsZT5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzTmFtZT17Y2xhc3NOYW1lcygncGFnaW5hdGlvbi1yb3cnLCB7XG4gICAgICAgICAgICBoaWRkZW46ICh0b3RhbCA/PyAwKSA9PT0gMCxcbiAgICAgICAgICB9KX1cbiAgICAgICAgPlxuICAgICAgICAgIDxQYWdpbmF0aW9uXG4gICAgICAgICAgICB0b3RhbFBhZ2VzPXtNYXRoLmNlaWwoKHRvdGFsID8/IDApIC8gKGxpc3RQYXJhbXMubnVtID8/IDI0KSl9XG4gICAgICAgICAgICB7Li4ucmVnaXN0ZXIoJ3BhZ2UnKX1cbiAgICAgICAgICAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvU2VnbWVudD5cblxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJmaXhlZC1tZW51XCI+XG4gICAgICAgIDxUcmFuc2l0aW9uXG4gICAgICAgICAgdmlzaWJsZT17c2VsZWN0ZWRLZXlzLmxlbmd0aCA+IDB9XG4gICAgICAgICAgYW5pbWF0aW9uPVwic2xpZGUgbGVmdFwiXG4gICAgICAgICAgZHVyYXRpb249ezUwMH1cbiAgICAgICAgPlxuICAgICAgICAgIDxNZXNzYWdlIHNpemU9XCJzbWFsbFwiIGNvbG9yPVwidmlvbGV0XCIgY2xhc3NOYW1lPVwidGV4dC1jZW50ZXJcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cInB4LTRcIj57c2VsZWN0ZWRLZXlzLmxlbmd0aH3qsJwg7ISg7YOd65CoPC9zcGFuPlxuICAgICAgICAgICAgPEJ1dHRvbiBzaXplPVwidGlueVwiIGNvbG9yPVwidmlvbGV0XCIgb25DbGljaz17KCkgPT4gZGVzZWxlY3RBbGwoKX0+XG4gICAgICAgICAgICAgIOyEoO2DnSDtlbTsoJxcbiAgICAgICAgICAgIDwvQnV0dG9uPlxuICAgICAgICAgICAgPEJ1dHRvbiBzaXplPVwidGlueVwiIGNvbG9yPVwicmVkXCIgb25DbGljaz17Y29uZmlybURlbFNlbGVjdGVkfT5cbiAgICAgICAgICAgICAg7J286rSEIOyCreygnFxuICAgICAgICAgICAgPC9CdXR0b24+XG4gICAgICAgICAgPC9NZXNzYWdlPlxuICAgICAgICA8L1RyYW5zaXRpb24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgKTtcbn1cbiAgICAgIGAudHJpbSgpLFxuICAgICAgaW1wb3J0S2V5czogW10sXG4gICAgICBwcmVUZW1wbGF0ZXMsXG4gICAgfTtcbiAgfVxufVxuIl0sIm5hbWVzIjpbImFzc2VydCIsImluZmxlY3Rpb24iLCJmbGF0IiwidW5pcXVlIiwieiIsIkVudGl0eU1hbmFnZXIiLCJnZXRDb2x1bW5zTm9kZSIsImdldEVudW1JbmZvRnJvbUNvbE5hbWUiLCJnZXRSZWxhdGlvblByb3BGcm9tQ29sTmFtZSIsIlRlbXBsYXRlIiwiZ2V0Wm9kVHlwZUJ5SWQiLCJ6b2RUeXBlVG9SZW5kZXJpbmdOb2RlIiwiVGVtcGxhdGVfX3ZpZXdfbGlzdCIsImdldFRhcmdldEFuZFBhdGgiLCJuYW1lcyIsInRhcmdldCIsInBhdGgiLCJmc1BsdXJhbCIsIndyYXBUYyIsImJvZHkiLCJrZXkiLCJjb2xsYXBzaW5nIiwiY2xhc3NOYW1lIiwicmVuZGVyQ29sdW1uIiwiZW50aXR5SWQiLCJjb2wiLCJwYXJlbnRPYmoiLCJ3aXRob3V0TmFtZSIsImNvbE5hbWUiLCJuYW1lIiwicmVuZGVyVHlwZSIsInJlbFByb3BGayIsInJlcGxhY2UiLCJ3aXRoIiwibnVsbGFibGUiLCJpZCIsImVudW1JZCIsInBpY2tlZENoaWxkIiwiY2hpbGRyZW4iLCJmaW5kIiwiY2hpbGQiLCJjb25maWciLCJwaWNrZWQiLCJFcnJvciIsInJlbmRlckNvbHVtbkltcG9ydCIsImNhcGl0YWwiLCJyZWxQcm9wIiwicmVzdWx0IiwibWFwIiwiZ2V0TmFtZXNGcm9tSWQiLCJlbGVtZW50IiwicmVuZGVyRmlsdGVySW1wb3J0IiwiZnMiLCJjb21wb25lbnRJZCIsImNhbWVsaXplIiwidGFyZ2V0RW50aXR5TmFtZXMiLCJ0YXJnZXRNRE5hbWVzIiwidGFyZ2V0TmFtZXMiLCJyZW5kZXJGaWx0ZXIiLCJpc0NsZWFyYWJsZSIsIm9wdGlvbmFsIiwiZ2V0RGVmYXVsdCIsImNvbHVtbnMiLCJkZWYiLCJvcmRlckJ5Iiwic2VhcmNoIiwib3JkZXJCeVpvZFR5cGUiLCJ6b2RUeXBlIiwiWm9kRW51bSIsIm9wdGlvbnMiLCJ0b1N0cmluZyIsInNlYXJjaFpvZFR5cGUiLCJyZW5kZXIiLCJjb2x1bW5zTm9kZSIsImxpc3RQYXJhbXNab2RUeXBlIiwibGlzdFBhcmFtc05vZGUiLCJlbnRpdHkiLCJnZXQiLCJmaWx0ZXIiLCJwcm9wQ2FuZGlkYXRlIiwicHJvcHMiLCJwIiwibGFiZWwiLCJkZXNjIiwidGMiLCJmaWx0ZXJDb2x1bW5zIiwiaW5jbHVkZXMiLCJlbmRzV2l0aCIsInNvcnQiLCJhIiwicHJlVGVtcGxhdGVzIiwidGFyZ2V0RW50aXR5SWQiLCJwdXNoIiwiY29sdW1uSW1wb3J0cyIsImZsYXRNYXAiLCJqb2luIiwiY2FwaXRhbFBsdXJhbCIsInRpdGxlIiwidHJpbSIsImltcG9ydEtleXMiXSwibWFwcGluZ3MiOiJBQUFBLE9BQU9BLFlBQVksU0FBUztBQUM1QixPQUFPQyxnQkFBZ0IsYUFBYTtBQUNwQyxTQUFTQyxJQUFJLEVBQUVDLE1BQU0sUUFBUSxVQUFVO0FBQ3ZDLFNBQVNDLENBQUMsUUFBUSxNQUFNO0FBQ3hCLFNBQVNDLGFBQWEsUUFBZ0MsaUNBQThCO0FBRXBGLFNBQVNDLGNBQWMsUUFBUSx5QkFBc0I7QUFDckQsU0FBU0Ms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QU8sQ0FBQzt3QkFDRyxFQUFFL0IsTUFBTStCLE9BQU8sQ0FBQyxTQUFTLEVBQUUvQixNQUFNK0IsT0FBTyxDQUFDOztpREFFaEIsRUFBRS9CLE1BQU0rQixPQUFPLENBQUM7OztjQUduRCxFQUFFa0IsSUFBSUMsT0FBTyxDQUFDO2FBQ2YsRUFBRUQsSUFBSUUsTUFBTSxDQUFDOzs7O3VDQUlhLEVBQUVuRCxNQUFNK0IsT0FBTyxDQUFDLFdBQVcsRUFDOUQvQixNQUFNa0YsYUFBYSxDQUNwQjs7Ozs7Ozs7OztJQVVDLEVBQUVsRixNQUFNK0IsT0FBTyxDQUFDOzs7Ozs7Ozs7Ozs7SUFZaEIsRUFBRS9CLE1BQU0rQixPQUFPLENBQUM7Ozs7Ozs7bUJBT0QsRUFBRS9CLE1BQU1HLFFBQVEsQ0FBQztZQUN4QixFQUFFMkQsT0FBT3FCLEtBQUssSUFBSW5GLE1BQU0rQixPQUFPLENBQUM7Ozs7Ozs7Ozs7Ozs7OzswQkFlbEIsRUFBRS9CLE1BQU0rQixPQUFPLENBQUMsY0FBYyxFQUFFaUIsUUFDckRkLEdBQUcsQ0FBQyxDQUFDdkI7Z0JBQ0osT0FBTztvQkFDTCxDQUFDLFVBQVUsRUFBRUEsSUFBSXlELEtBQUssQ0FBQyxFQUFFLENBQUM7b0JBQzFCLENBQUMsSUFBSSxFQUFFekQsSUFBSTJELEVBQUUsQ0FBQyxFQUFFLENBQUM7b0JBQ2pCLENBQUMsWUFBWSxFQUFFO3dCQUFDO3dCQUFTO3FCQUFPLENBQUNFLFFBQVEsQ0FBQzdELElBQUl5RCxLQUFLLE1BQU0sTUFBTSxHQUFHLENBQUM7aUJBQ3BFLENBQUNhLElBQUksQ0FBQztZQUNULEdBQ0NBLElBQUksQ0FBQyxPQUFPOzs7eUJBR1EsRUFBRWpGLE1BQU1HLFFBQVEsQ0FBQzs7Ozs7OztXQU8vQixFQUFFSCxNQUFNK0IsT0FBTyxDQUFDOzs7Ozs7VUFNakIsRUFBRXdDLGNBQ0NyQyxHQUFHLENBQUMsQ0FBQ3ZCO2dCQUNKLE9BQU8sSUFBSSxDQUFDaUMsWUFBWSxDQUFDbEMsVUFBVUMsS0FBS1g7WUFDMUMsR0FDQ2lGLElBQUksQ0FBQyxZQUFZOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7TUFzR3hCLENBQUMsQ0FBQ0csSUFBSTtZQUNOQyxZQUFZLEVBQUU7WUFDZFQ7UUFDRjtJQUNGO0FBQ0YifQ==
|
|
643
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90ZW1wbGF0ZS9pbXBsZW1lbnRhdGlvbnMvdmlld19saXN0LnRlbXBsYXRlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBpbmZsZWN0aW9uIGZyb20gXCJpbmZsZWN0aW9uXCI7XG5pbXBvcnQgeyBmbGF0IH0gZnJvbSBcInJhZGFzaGlcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgeyBFbnRpdHlNYW5hZ2VyLCB0eXBlIEVudGl0eU5hbWVzUmVjb3JkIH0gZnJvbSBcIi4uLy4uL2VudGl0eS9lbnRpdHktbWFuYWdlclwiO1xuaW1wb3J0IHR5cGUgeyBSZW5kZXJpbmdOb2RlLCBUZW1wbGF0ZUtleSwgVGVtcGxhdGVPcHRpb25zIH0gZnJvbSBcIi4uLy4uL3R5cGVzL3R5cGVzXCI7XG5pbXBvcnQgeyBnZXRFbnVtSW5mb0Zyb21Db2xOYW1lLCBnZXRSZWxhdGlvblByb3BGcm9tQ29sTmFtZSB9IGZyb20gXCIuLi9oZWxwZXJzXCI7XG5pbXBvcnQgdHlwZSB7IFJlbmRlcmVkVGVtcGxhdGUgfSBmcm9tIFwiLi4vdGVtcGxhdGVcIjtcbmltcG9ydCB7IFRlbXBsYXRlIH0gZnJvbSBcIi4uL3RlbXBsYXRlXCI7XG5cbmV4cG9ydCBjbGFzcyBUZW1wbGF0ZV9fdmlld19saXN0IGV4dGVuZHMgVGVtcGxhdGUge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihcInZpZXdfbGlzdFwiKTtcbiAgfVxuXG4gIGdldFRhcmdldEFuZFBhdGgobmFtZXM6IEVudGl0eU5hbWVzUmVjb3JkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRhcmdldDogXCJ3ZWIvc3JjL3JvdXRlcy9hZG1pblwiLFxuICAgICAgcGF0aDogYCR7bmFtZXMuZnNQbHVyYWx9L2luZGV4LnRzeGAsXG4gICAgfTtcbiAgfVxuXG4gIHdyYXBUYyhib2R5OiBzdHJpbmcsIGtleTogc3RyaW5nLCBjb2xsYXBzaW5nOiBib29sZWFuID0gdHJ1ZSwgY2xhc3NOYW1lOiBzdHJpbmcgPSBcIlwiKSB7XG4gICAgcmV0dXJuIGA8VGFibGUuQ2VsbCBrZXk9XCIke2tleX1cIiR7Y29sbGFwc2luZyA/IFwiIGNvbGxhcHNpbmdcIiA6IFwiXCJ9JHtcbiAgICAgIGNsYXNzTmFtZSA/IGAgY2xhc3NOYW1lPXtcXGAke2NsYXNzTmFtZX1cXGB9YCA6IFwiXCJcbiAgICB9PiR7Ym9keX08L1RhYmxlLkNlbGw+YDtcbiAgfVxuXG4gIHJlbmRlckNvbHVtbihcbiAgICBlbnRpdHlJZDogc3RyaW5nLFxuICAgIGNvbDogUmVuZGVyaW5nTm9kZSxcbiAgICBuYW1lczogRW50aXR5TmFtZXNSZWNvcmQsXG4gICAgcGFyZW50T2JqOiBzdHJpbmcgPSBcInJvd1wiLFxuICAgIHdpdGhvdXROYW1lOiBib29sZWFuID0gZmFsc2UsXG4gICk6IHN0cmluZyB7XG4gICAgLy8g7KSR7LKpIOqyveuhnCDsspjrpqwgKOyYiDogXCJ1c2VyLm5hbWVcIiAtPiBcInJvdy51c2VyPy5uYW1lXCIpXG4gICAgbGV0IGNvbE5hbWU6IHN0cmluZztcbiAgICBpZiAod2l0aG91dE5hbWUpIHtcbiAgICAgIGNvbE5hbWUgPSBwYXJlbnRPYmo7XG4gICAgfSBlbHNlIGlmIChjb2wubmFtZS5pbmNsdWRlcyhcIi5cIikpIHtcbiAgICAgIC8vIOykkeyyqSDqsr3roZzripQgb3B0aW9uYWwgY2hhaW5pbmfsnLzroZwg67OA7ZmYXG4gICAgICBjb25zdCBwYXJ0cyA9IGNvbC5uYW1lLnNwbGl0KFwiLlwiKTtcbiAgICAgIGNvbE5hbWUgPSBgJHtwYXJlbnRPYmp9LiR7cGFydHMuam9pbihcIj8uXCIpfWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbE5hbWUgPSBgJHtwYXJlbnRPYmp9LiR7Y29sLm5hbWV9YDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKGNvbC5yZW5kZXJUeXBlKSB7XG4gICAgICBjYXNlIFwic3RyaW5nLXBsYWluXCI6XG4gICAgICBjYXNlIFwic3RyaW5nLWRhdGVcIjpcbiAgICAgIGNhc2UgXCJudW1iZXItaWRcIjpcbiAgICAgICAgcmV0dXJuIGA8Pnske2NvbE5hbWV9fTwvPmA7XG4gICAgICBjYXNlIFwibnVtYmVyLWZrX2lkXCI6IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBiYXNlTmFtZSA9IGNvbC5uYW1lLmluY2x1ZGVzKFwiLlwiKVxuICAgICAgICAgICAgPyAoY29sLm5hbWUuc3BsaXQoXCIuXCIpLnBvcCgpID8/IGNvbC5uYW1lKS5yZXBsYWNlKFwiX2lkXCIsIFwiXCIpXG4gICAgICAgICAgICA6IGNvbC5uYW1lLnJlcGxhY2UoXCJfaWRcIiwgXCJcIik7XG4gICAgICAgICAgY29uc3QgcmVsUHJvcEZrID0gZ2V0UmVsYXRpb25Qcm9wRnJvbUNvbE5hbWUoZW50aXR5SWQsIGJhc2VOYW1lKTtcbiAgICAgICAgICByZXR1cm4gYDw+JHtyZWxQcm9wRmsud2l0aH0jeyR7Y29sTmFtZX19PC8+YDtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgcmV0dXJuIGA8Pnske2NvbE5hbWV9fTwvPmA7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNhc2UgXCJzdHJpbmctaW1hZ2VcIjpcbiAgICAgICAgcmV0dXJuIGA8Pnske1xuICAgICAgICAgIGNvbC5udWxsYWJsZSA/IGAke2NvbE5hbWV9ICYmIGAgOiBcIlwiXG4gICAgICAgIH08aW1nIHNyYz17JHtjb2xOYW1lfX0gYWx0PVwiJHtjb2wubGFiZWwgPz8gY29sLm5hbWV9XCIgY2xhc3NOYW1lPVwiaC04IHctOCBvYmplY3QtY292ZXIgcm91bmRlZFwiIC8+fTwvPmA7XG4gICAgICBjYXNlIFwiZGF0ZXRpbWVcIjpcbiAgICAgICAgaWYgKGNvbC5udWxsYWJsZSB8fCBjb2wubmFtZS5pbmNsdWRlcyhcIi5cIikpIHtcbiAgICAgICAgICByZXR1cm4gYDxzcGFuPnske2NvbE5hbWV9ID8gZGF0ZXRpbWVGKCR7Y29sTmFtZX0pIDogJy0nfTwvc3Bhbj5gO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBgPHNwYW4+e2RhdGV0aW1lRigke2NvbE5hbWV9KX08L3NwYW4+YDtcbiAgICAgICAgfVxuICAgICAgY2FzZSBcInN0cmluZy1kYXRldGltZVwiOlxuICAgICAgICBpZiAoY29sLm51bGxhYmxlIHx8IGNvbC5uYW1lLmluY2x1ZGVzKFwiLlwiKSkge1xuICAgICAgICAgIHJldHVybiBgPHNwYW4+eyR7Y29sTmFtZX0gPyBkYXRlRigke2NvbE5hbWV9KSA6ICctJ308L3NwYW4+YDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gYDxzcGFuPntkYXRlRigke2NvbE5hbWV9KX08L3NwYW4+YDtcbiAgICAgICAgfVxuICAgICAgY2FzZSBcImJvb2xlYW5cIjpcbiAgICAgICAgcmV0dXJuIGA8Pnske2NvbE5hbWV9ID8gPEJhZGdlIHZhcmlhbnQ9XCJkZWZhdWx0XCI+TzwvQmFkZ2U+IDogPEJhZGdlIHZhcmlhbnQ9XCJzZWNvbmRhcnlcIj5YPC9CYWRnZT59PC8+YDtcbiAgICAgIGNhc2UgXCJlbnVtc1wiOiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyBpZDogZW51bUlkIH0gPSBnZXRFbnVtSW5mb0Zyb21Db2xOYW1lKGVudGl0eUlkLCBjb2wubmFtZSk7XG4gICAgICAgICAgcmV0dXJuIGA8Pnske2NvbC5udWxsYWJsZSA/IGAke2NvbE5hbWV9ICYmIGAgOiBcIlwifSR7ZW51bUlkfUxhYmVsWyR7Y29sTmFtZX1dfTwvPmA7XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIHJldHVybiBgPD57JHtjb2xOYW1lfX08Lz5gO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjYXNlIFwiYXJyYXktaW1hZ2VzXCI6XG4gICAgICAgIHJldHVybiBgPGRpdiBjbGFzc05hbWU9XCJmbGV4IGdhcC0xXCI+eyAke2NvbE5hbWV9Py5tYXAoKHIsIGkpID0+ICR7XG4gICAgICAgICAgY29sLm51bGxhYmxlID8gYHIgJiYgYCA6IFwiXCJcbiAgICAgICAgfTxpbWcga2V5PXtpfSBzcmM9e3J9IGFsdD17XFxgJHtjb2wubGFiZWwgPz8gY29sLm5hbWV9IFxcJHtpICsgMX1cXGB9IGNsYXNzTmFtZT1cImgtOCB3LTggb2JqZWN0LWNvdmVyIHJvdW5kZWRcIiAvPikgfTwvZGl2PmA7XG4gICAgICBjYXNlIFwibnVtYmVyLXBsYWluXCI6XG4gICAgICAgIHJldHVybiBgPD57JHtjb2wubnVsbGFibGUgfHwgY29sLm5hbWUuaW5jbHVkZXMoXCIuXCIpID8gYCR7Y29sTmFtZX0gJiYgYCA6IFwiXCJ9bnVtRigke2NvbE5hbWV9KX08Lz5gO1xuICAgICAgY2FzZSBcIm9iamVjdFwiOlxuICAgICAgICByZXR1cm4gYDxzcGFuIGNsYXNzTmFtZT1cInRleHQteHNcIj57JHtjb2wubnVsbGFibGUgPyBgJHtjb2xOYW1lfSA/IGAgOiBcIlwifUpTT04uc3RyaW5naWZ5KCR7Y29sTmFtZX0pJHtjb2wubnVsbGFibGUgPyBgIDogJy0nYCA6IFwiXCJ9fTwvc3Bhbj5gO1xuICAgICAgY2FzZSBcIm9iamVjdC1waWNrXCI6IHtcbiAgICAgICAgY29uc3QgcGlja2VkQ2hpbGQgPSBjb2wuY2hpbGRyZW4/LmZpbmQoKGNoaWxkKSA9PiBjaGlsZC5uYW1lID09PSBjb2wuY29uZmlnPy5waWNrZWQpO1xuICAgICAgICBpZiAoIXBpY2tlZENoaWxkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBvYmplY3QtcGljayDshKDtg50g7Iuk7YyoICjsmKTruIzsoJ3tirg6ICR7Y29sLm5hbWV9KWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnJlbmRlckNvbHVtbihcbiAgICAgICAgICBlbnRpdHlJZCxcbiAgICAgICAgICBwaWNrZWRDaGlsZCxcbiAgICAgICAgICBuYW1lcyxcbiAgICAgICAgICBgJHtjb2xOYW1lfSR7Y29sLm51bGxhYmxlID8gXCI/XCIgOiBcIlwifWAsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBjYXNlIFwiYXJyYXlcIjpcbiAgICAgICAgcmV0dXJuIGA8PnsgLyogYXJyYXkgJHtjb2xOYW1lfSAqLyB9PC8+YDtcbiAgICAgIGNhc2UgXCJ2ZWN0b3JcIjpcbiAgICAgICAgLy8gdmVjdG9yIO2DgOyeheydgCDssKjsm5Ag7IiY66eMIO2RnOyLnCAo7Iuk7KCcIOuNsOydtO2EsOuKlCDrhIjrrLQg6rmAKVxuICAgICAgICByZXR1cm4gYDw+eyR7Y29sLm51bGxhYmxlID8gYCR7Y29sTmFtZX0gPyBgIDogXCJcIn1bVmVjdG9yOiB7JHtjb2xOYW1lfSR7Y29sLm51bGxhYmxlID8gXCJcIiA6IFwiID8/IFtdXCJ9Lmxlbmd0aH1kXSR7Y29sLm51bGxhYmxlID8gXCIgOiAnLSdcIiA6IFwiXCJ9fTwvPmA7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYOugjOuNlCDrtojqsIAg7Lus65+8ICR7Y29sLnJlbmRlclR5cGV9YCk7XG4gICAgfVxuICB9XG5cbiAgcmVuZGVyQ29sdW1uSW1wb3J0KFxuICAgIGVudGl0eUlkOiBzdHJpbmcsXG4gICAgY29sOiBSZW5kZXJpbmdOb2RlLFxuICAgIG5hbWVzOiBFbnRpdHlOYW1lc1JlY29yZCxcbiAgKTogKHN0cmluZyB8IG51bGwpW10ge1xuICAgIGlmIChjb2wucmVuZGVyVHlwZSA9PT0gXCJlbnVtc1wiKSB7XG4gICAgICBjb25zdCB7IGlkOiBlbnVtSWQgfSA9IGdldEVudW1JbmZvRnJvbUNvbE5hbWUobmFtZXMuY2FwaXRhbCwgY29sLm5hbWUpO1xuICAgICAgcmV0dXJuIFtgaW1wb3J0IHsgJHtlbnVtSWR9TGFiZWwgfSBmcm9tICdAL3NlcnZpY2VzL3NvbmFtdS5nZW5lcmF0ZWQnO2BdO1xuICAgIH0gZWxzZSBpZiAoY29sLnJlbmRlclR5cGUgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlbFByb3AgPSBnZXRSZWxhdGlvblByb3BGcm9tQ29sTmFtZShlbnRpdHlJZCwgY29sLm5hbWUpO1xuICAgICAgICBjb25zdCByZXN1bHQgPSAoY29sLmNoaWxkcmVuID8/IFtdKS5tYXAoKGNoaWxkKSA9PiB7XG4gICAgICAgICAgZW50aXR5SWQgPSByZWxQcm9wLndpdGg7XG4gICAgICAgICAgbmFtZXMgPSBFbnRpdHlNYW5hZ2VyLmdldE5hbWVzRnJvbUlkKHJlbFByb3Aud2l0aCk7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucmVuZGVyQ29sdW1uSW1wb3J0KGVudGl0eUlkLCBjaGlsZCwgbmFtZXMpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGZsYXQocmVzdWx0KTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gW251bGxdO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoY29sLnJlbmRlclR5cGUgPT09IFwiYXJyYXlcIikge1xuICAgICAgaWYgKCFjb2wuZWxlbWVudCkgcmV0dXJuIFtudWxsXTtcbiAgICAgIHJldHVybiB0aGlzLnJlbmRlckNvbHVtbkltcG9ydChlbnRpdHlJZCwgY29sLmVsZW1lbnQsIG5hbWVzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gW251bGxdO1xuICB9XG5cbiAgcmVuZGVyRmlsdGVySW1wb3J0KGVudGl0eUlkOiBzdHJpbmcsIGNvbDogUmVuZGVyaW5nTm9kZSwgbmFtZXM6IEVudGl0eU5hbWVzUmVjb3JkKSB7XG4gICAgaWYgKGNvbC5uYW1lID09PSBcInNlYXJjaFwiKSB7XG4gICAgICByZXR1cm4gYGltcG9ydCB7ICR7bmFtZXMuY2FwaXRhbH1TZWFyY2hJbnB1dCB9IGZyb20gXCJAL2NvbXBvbmVudHMvJHtuYW1lcy5mc30vJHtuYW1lcy5jYXBpdGFsfVNlYXJjaElucHV0XCI7YDtcbiAgICB9IGVsc2UgaWYgKGNvbC5yZW5kZXJUeXBlID09PSBcImVudW1zXCIpIHtcbiAgICAgIGlmIChjb2wubmFtZSA9PT0gXCJvcmRlckJ5XCIpIHtcbiAgICAgICAgY29uc3QgY29tcG9uZW50SWQgPSBgJHtuYW1lcy5jYXBpdGFsfSR7aW5mbGVjdGlvbi5jYW1lbGl6ZShjb2wubmFtZSl9U2VsZWN0YDtcbiAgICAgICAgcmV0dXJuIGBpbXBvcnQgeyAke2NvbXBvbmVudElkfSB9IGZyb20gXCJAL2NvbXBvbmVudHMvJHtuYW1lcy5mc30vJHtjb21wb25lbnRJZH1cIjtgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB7IGlkLCB0YXJnZXRFbnRpdHlOYW1lczogdGFyZ2V0TUROYW1lcyB9ID0gZ2V0RW51bUluZm9Gcm9tQ29sTmFtZShcbiAgICAgICAgICAgIGVudGl0eUlkLFxuICAgICAgICAgICAgY29sLm5hbWUsXG4gICAgICAgICAgKTtcbiAgICAgICAgICBjb25zdCBjb21wb25lbnRJZCA9IGAke2lkfVNlbGVjdGA7XG4gICAgICAgICAgcmV0dXJuIGBpbXBvcnQgeyAke2NvbXBvbmVudElkfSB9IGZyb20gXCJAL2NvbXBvbmVudHMvJHt0YXJnZXRNRE5hbWVzLmZzfS8ke2NvbXBvbmVudElkfVwiO2A7XG4gICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgIHJldHVybiBcIlwiO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjb2wucmVuZGVyVHlwZSA9PT0gXCJudW1iZXItZmtfaWRcIikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVsUHJvcCA9IGdldFJlbGF0aW9uUHJvcEZyb21Db2xOYW1lKGVudGl0eUlkLCBjb2wubmFtZS5yZXBsYWNlKFwiX2lkXCIsIFwiXCIpKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0TmFtZXMgPSBFbnRpdHlNYW5hZ2VyLmdldE5hbWVzRnJvbUlkKHJlbFByb3Aud2l0aCk7XG4gICAgICAgIGNvbnN0IGNvbXBvbmVudElkID0gYCR7cmVsUHJvcC53aXRofUlkQXN5bmNTZWxlY3RgO1xuICAgICAgICByZXR1cm4gYGltcG9ydCB7ICR7Y29tcG9uZW50SWR9IH0gZnJvbSBcIkAvY29tcG9uZW50cy8ke3RhcmdldE5hbWVzLmZzfS8ke2NvbXBvbmVudElkfVwiO2A7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihg66CM642UIOu2iOqwgOuKpe2VnCDtlYTthLAg7J6E7Y+s7Yq4ICR7Y29sLm5hbWV9ICR7Y29sLnJlbmRlclR5cGV9YCk7XG4gICAgfVxuICB9XG5cbiAgcmVuZGVyRmlsdGVyKGVudGl0eUlkOiBzdHJpbmcsIGNvbDogUmVuZGVyaW5nTm9kZSwgbmFtZXM6IEVudGl0eU5hbWVzUmVjb3JkKSB7XG4gICAgaWYgKGNvbC5uYW1lID09PSBcInNlYXJjaFwiKSB7XG4gICAgICByZXR1cm4gXCJcIjtcbiAgICB9XG5cbiAgICBjb25zdCBpc0NsZWFyYWJsZSA9IGNvbC5vcHRpb25hbCA9PT0gdHJ1ZSAmJiBjb2wubmFtZSAhPT0gXCJvcmRlckJ5XCI7XG4gICAgbGV0IGNvbXBvbmVudElkOiBzdHJpbmc7XG4gICAgaWYgKGNvbC5yZW5kZXJUeXBlID09PSBcImVudW1zXCIpIHtcbiAgICAgIGlmIChjb2wubmFtZSA9PT0gXCJvcmRlckJ5XCIpIHtcbiAgICAgICAgY29tcG9uZW50SWQgPSBgJHtuYW1lcy5jYXBpdGFsfSR7aW5mbGVjdGlvbi5jYW1lbGl6ZShjb2wubmFtZSl9U2VsZWN0YDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgeyBpZCB9ID0gZ2V0RW51bUluZm9Gcm9tQ29sTmFtZShlbnRpdHlJZCwgY29sLm5hbWUpO1xuICAgICAgICAgIGNvbXBvbmVudElkID0gYCR7aWR9U2VsZWN0YDtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBgPCR7Y29tcG9uZW50SWR9IHsuLi5yZWdpc3RlcignJHtjb2wubmFtZX0nKX0gJHtpc0NsZWFyYWJsZSA/IFwiY2xlYXJhYmxlXCIgOiBcIlwifSAvPmA7XG4gICAgfSBlbHNlIGlmIChjb2wucmVuZGVyVHlwZSA9PT0gXCJudW1iZXItZmtfaWRcIikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVsUHJvcCA9IGdldFJlbGF0aW9uUHJvcEZyb21Db2xOYW1lKGVudGl0eUlkLCBjb2wubmFtZS5yZXBsYWNlKFwiX2lkXCIsIFwiXCIpKTtcbiAgICAgICAgY29tcG9uZW50SWQgPSBgJHtyZWxQcm9wLndpdGh9SWRBc3luY1NlbGVjdGA7XG4gICAgICAgIHJldHVybiBgPCR7Y29tcG9uZW50SWR9IHsuLi5yZWdpc3RlcignJHtjb2wubmFtZX0nKX0gJHtcbiAgICAgICAgICBpc0NsZWFyYWJsZSA/IFwiY2xlYXJhYmxlXCIgOiBcIlwiXG4gICAgICAgIH0gc3Vic2V0PVwiQVwiIC8+YDtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGDroIzrjZQg67aI6rCA64ql7ZWcIO2VhO2EsCDsnoTtj6ztirggJHtjb2wubmFtZX0gJHtjb2wucmVuZGVyVHlwZX1gKTtcbiAgICB9XG4gIH1cblxuICBnZXREZWZhdWx0KGNvbHVtbnM6IFJlbmRlcmluZ05vZGVbXSk6IHtcbiAgICBvcmRlckJ5OiBzdHJpbmc7XG4gICAgc2VhcmNoOiBzdHJpbmc7XG4gICAgaGFzU2VhcmNoOiBib29sZWFuO1xuICAgIGhhc09yZGVyQnk6IGJvb2xlYW47XG4gIH0ge1xuICAgIGNvbnN0IGRlZiA9IHtcbiAgICAgIG9yZGVyQnk6IFwiXCIsXG4gICAgICBzZWFyY2g6IFwiXCIsXG4gICAgICBoYXNTZWFyY2g6IGZhbHNlLFxuICAgICAgaGFzT3JkZXJCeTogZmFsc2UsXG4gICAgfTtcbiAgICBjb25zdCBvcmRlckJ5Wm9kVHlwZSA9IGNvbHVtbnMuZmluZCgoY29sKSA9PiBjb2wubmFtZSA9PT0gXCJvcmRlckJ5XCIpPy56b2RUeXBlO1xuICAgIGlmIChvcmRlckJ5Wm9kVHlwZSAmJiBvcmRlckJ5Wm9kVHlwZSBpbnN0YW5jZW9mIHouWm9kRW51bSkge1xuICAgICAgZGVmLm9yZGVyQnkgPSBPYmplY3Qua2V5cyhvcmRlckJ5Wm9kVHlwZS5lbnVtKVswXTtcbiAgICAgIGRlZi5oYXNPcmRlckJ5ID0gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3Qgc2VhcmNoWm9kVHlwZSA9IGNvbHVtbnMuZmluZCgoY29sKSA9PiBjb2wubmFtZSA9PT0gXCJzZWFyY2hcIik/LnpvZFR5cGU7XG4gICAgaWYgKHNlYXJjaFpvZFR5cGUgJiYgc2VhcmNoWm9kVHlwZSBpbnN0YW5jZW9mIHouWm9kRW51bSkge1xuICAgICAgZGVmLnNlYXJjaCA9IE9iamVjdC5rZXlzKHNlYXJjaFpvZFR5cGUuZW51bSlbMF07XG4gICAgICBkZWYuaGFzU2VhcmNoID0gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGRlZjtcbiAgfVxuXG4gIGFzeW5jIHJlbmRlcih7IGVudGl0eUlkIH06IFRlbXBsYXRlT3B0aW9uc1tcInZpZXdfbGlzdFwiXSkge1xuICAgIGNvbnN0IHsgZ2V0Q29sdW1uc05vZGUgfSA9IGF3YWl0IGltcG9ydChcIi4uL2VudGl0eS1jb252ZXJ0ZXJcIik7XG4gICAgY29uc3QgeyBnZXRab2RUeXBlQnlJZCwgem9kVHlwZVRvUmVuZGVyaW5nTm9kZSB9ID0gYXdhaXQgaW1wb3J0KFwiLi4vem9kLWNvbnZlcnRlclwiKTtcblxuICAgIGNvbnN0IGNvbHVtbnNOb2RlID0gYXdhaXQgZ2V0Q29sdW1uc05vZGUoZW50aXR5SWQsIFwiQVwiKTtcbiAgICBjb25zdCBsaXN0UGFyYW1zWm9kVHlwZSA9IGF3YWl0IGdldFpvZFR5cGVCeUlkKGAke2VudGl0eUlkfUxpc3RQYXJhbXNgKTtcbiAgICBjb25zdCBsaXN0UGFyYW1zTm9kZSA9IHpvZFR5cGVUb1JlbmRlcmluZ05vZGUobGlzdFBhcmFtc1pvZFR5cGUpO1xuXG4gICAgY29uc3QgbmFtZXMgPSBFbnRpdHlNYW5hZ2VyLmdldE5hbWVzRnJvbUlkKGVudGl0eUlkKTtcbiAgICBjb25zdCBlbnRpdHkgPSBFbnRpdHlNYW5hZ2VyLmdldChlbnRpdHlJZCk7XG5cbiAgICAvLyDsi6TsoJwg66as7Iqk7Yq4IOy7rOufvFxuICAgIGNvbnN0IGNvbHVtbnMgPSAoY29sdW1uc05vZGUuY2hpbGRyZW4gYXMgUmVuZGVyaW5nTm9kZVtdKVxuXG4gICAgICAuc29ydCgoYSwgYikgPT4gKGEubmFtZSA9PT0gXCJpZFwiID8gLTEgOiBiLm5hbWUgPT09IFwiaWRcIiA/IDEgOiAwKSlcbiAgICAgIC5tYXAoKGNvbCkgPT4ge1xuICAgICAgICBjb25zdCBwcm9wQ2FuZGlkYXRlID0gZW50aXR5LnByb3BzLmZpbmQoKHApID0+IHAubmFtZSA9PT0gY29sLm5hbWUpO1xuICAgICAgICBjb25zdCByZW5kZXJlZCA9IHRoaXMucmVuZGVyQ29sdW1uKGVudGl0eUlkLCBjb2wsIG5hbWVzKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBuYW1lOiBjb2wubmFtZSxcbiAgICAgICAgICBsYWJlbDogY29sLm5hbWUgPT09IFwiaWRcIiA/IFwiSURcIiA6IChwcm9wQ2FuZGlkYXRlPy5kZXNjID8/IGNvbC5sYWJlbCksXG4gICAgICAgICAgdGM6IGAocm93KSA9PiAke3JlbmRlcmVkfWAsXG4gICAgICAgICAgZml0OlxuICAgICAgICAgICAgY29sLnJlbmRlclR5cGUgPT09IFwibnVtYmVyLWlkXCIgfHxcbiAgICAgICAgICAgIGNvbC5yZW5kZXJUeXBlID09PSBcImRhdGV0aW1lXCIgfHxcbiAgICAgICAgICAgIGNvbC5yZW5kZXJUeXBlID09PSBcInN0cmluZy1kYXRldGltZVwiLFxuICAgICAgICAgIGFsaWduOiBjb2wucmVuZGVyVHlwZSA9PT0gXCJudW1iZXItaWRcIiA/IFwiY2VudGVyXCIgOiB1bmRlZmluZWQsXG4gICAgICAgIH07XG4gICAgICB9KTtcblxuICAgIC8vIO2VhO2EsCDsu6zrn7xcbiAgICBjb25zdCBmaWx0ZXJDb2x1bW5zID0gKGxpc3RQYXJhbXNOb2RlLmNoaWxkcmVuIGFzIFJlbmRlcmluZ05vZGVbXSlcbiAgICAgIC5maWx0ZXIoXG4gICAgICAgIChjb2wpID0+XG4gICAgICAgICAgY29sLm5hbWUgIT09IFwiaWRcIiAmJlxuICAgICAgICAgIGNvbC5uYW1lICE9PSBcInF1ZXJ5TW9kZVwiICYmXG4gICAgICAgICAgKFtcImVudW1zXCIsIFwibnVtYmVyLWlkXCJdLmluY2x1ZGVzKGNvbC5yZW5kZXJUeXBlKSB8fCBjb2wubmFtZS5lbmRzV2l0aChcIl9pZFwiKSksXG4gICAgICApXG4gICAgICAvLyBvcmRlckJ56rCAIOqwgOyepSDrkqTroZwg7Jik6rKMIOyInOyEnCDsobDsoJVcbiAgICAgIC5zb3J0KChhKSA9PiB7XG4gICAgICAgIHJldHVybiBhLm5hbWUgPT09IFwib3JkZXJCeVwiID8gMSA6IC0xO1xuICAgICAgfSk7XG5cbiAgICAvLyDtlYTthLAg7Lus65+87J2EIO2UhOumrCDthZztlIzrpr/snLzroZwg7ISk7KCVXG4gICAgY29uc3QgcHJlVGVtcGxhdGVzOiBSZW5kZXJlZFRlbXBsYXRlW1wicHJlVGVtcGxhdGVzXCJdID0gW107XG4gICAgZm9yIChjb25zdCBjb2wgb2YgZmlsdGVyQ29sdW1ucykge1xuICAgICAgbGV0IGtleTogVGVtcGxhdGVLZXk7XG4gICAgICBsZXQgdGFyZ2V0RW50aXR5SWQgPSBlbnRpdHlJZDtcbiAgICAgIGxldCBlbnVtSWQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICAgICAgaWYgKGNvbC5yZW5kZXJUeXBlID09PSBcImVudW1zXCIpIHtcbiAgICAgICAgaWYgKGNvbC5uYW1lID09PSBcInNlYXJjaFwiKSB7XG4gICAgICAgICAga2V5ID0gXCJ2aWV3X2VudW1zX3NlbGVjdFwiO1xuICAgICAgICAgIGVudW1JZCA9IGAke25hbWVzLmNhcGl0YWx9U2VhcmNoRmllbGRgO1xuICAgICAgICAgIHRhcmdldEVudGl0eUlkID0gbmFtZXMuY2FwaXRhbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBrZXkgPSBcInZpZXdfZW51bXNfc2VsZWN0XCI7XG4gICAgICAgICAgLy8gY29uZmlnLmVudW1JZCDsmrDshKAg7IKs7JqpXG4gICAgICAgICAgaWYgKGNvbC5jb25maWcgJiYgXCJlbnVtSWRcIiBpbiBjb2wuY29uZmlnKSB7XG4gICAgICAgICAgICBlbnVtSWQgPSAoY29sLmNvbmZpZyBhcyB7IGVudW1JZDogc3RyaW5nIH0pLmVudW1JZDtcbiAgICAgICAgICAgIHRhcmdldEVudGl0eUlkID0gZW50aXR5SWQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGNvbnN0IHsgdGFyZ2V0RW50aXR5TmFtZXMsIGlkIH0gPSBnZXRFbnVtSW5mb0Zyb21Db2xOYW1lKGVudGl0eUlkLCBjb2wubmFtZSk7XG4gICAgICAgICAgICAgIHRhcmdldEVudGl0eUlkID0gdGFyZ2V0RW50aXR5TmFtZXMuY2FwaXRhbDtcbiAgICAgICAgICAgICAgZW51bUlkID0gaWQ7XG4gICAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBrZXkgPSBcInZpZXdfaWRfYXN5bmNfc2VsZWN0XCI7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3QgcmVsUHJvcCA9IGdldFJlbGF0aW9uUHJvcEZyb21Db2xOYW1lKGVudGl0eUlkLCBjb2wubmFtZS5yZXBsYWNlKFwiX2lkXCIsIFwiXCIpKTtcbiAgICAgICAgICB0YXJnZXRFbnRpdHlJZCA9IHJlbFByb3Aud2l0aDtcbiAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcHJlVGVtcGxhdGVzLnB1c2goe1xuICAgICAgICBrZXksXG4gICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICBlbnRpdHlJZDogdGFyZ2V0RW50aXR5SWQsXG4gICAgICAgICAgZW51bUlkLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8g7Lus65+87JeQ7IScIOyCrOyaqe2VmOuKlCBlbnVt65OkIOyImOynkVxuICAgIGNvbnN0IGNvbHVtbkVudW1zOiBzdHJpbmdbXSA9IFtdO1xuICAgIChjb2x1bW5zTm9kZS5jaGlsZHJlbiA/PyBbXSkuZm9yRWFjaCgoY29sKSA9PiB7XG4gICAgICBpZiAoY29sLnJlbmRlclR5cGUgPT09IFwiZW51bXNcIikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHsgaWQ6IGVudW1JZCB9ID0gZ2V0RW51bUluZm9Gcm9tQ29sTmFtZShlbnRpdHlJZCwgY29sLm5hbWUpO1xuICAgICAgICAgIGNvbHVtbkVudW1zLnB1c2goZW51bUlkKTtcbiAgICAgICAgfSBjYXRjaCB7fVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gU2VhcmNoSW5wdXRcbiAgICBwcmVUZW1wbGF0ZXM/LnB1c2goe1xuICAgICAga2V5OiBcInZpZXdfc2VhcmNoX2lucHV0XCIsXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIGVudGl0eUlkLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIOuUlO2PtO2KuCDtjIzrnbzrr7jthLBcbiAgICAvLyBjb25zdCBkZWYgPSB0aGlzLmdldERlZmF1bHQoZmlsdGVyQ29sdW1ucyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4udGhpcy5nZXRUYXJnZXRBbmRQYXRoKG5hbWVzKSxcbiAgICAgIGJvZHk6IGBcbmltcG9ydCB7IHVzZVN0YXRlLCBGcmFnbWVudCB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgY3JlYXRlRmlsZVJvdXRlLCB1c2VOYXZpZ2F0ZSB9IGZyb20gXCJAdGFuc3RhY2svcmVhY3Qtcm91dGVyXCI7XG5cbmltcG9ydCB7IENhcmQsIENhcmRDb250ZW50LCBDYXJkSGVhZGVyIH0gZnJvbSBcIkBzb25hbXUta2l0L3JlYWN0LWNvbXBvbmVudHMvY29tcG9uZW50c1wiO1xuaW1wb3J0IHsgQmFkZ2UgfSBmcm9tIFwiQHNvbmFtdS1raXQvcmVhY3QtY29tcG9uZW50cy9jb21wb25lbnRzXCI7XG5pbXBvcnQgeyBCdXR0b24gfSBmcm9tIFwiQHNvbmFtdS1raXQvcmVhY3QtY29tcG9uZW50cy9jb21wb25lbnRzXCI7XG5pbXBvcnQgeyBQYWdpbmF0aW9uLCBUYWJsZSwgVGFibGVCb2R5LCBUYWJsZUNlbGwsIHR5cGUgVGFibGVDb2wsIFRhYmxlSGVhZCwgVGFibGVIZWFkZXIsIFRhYmxlUm93IH0gZnJvbSBcIkBzb25hbXUta2l0L3JlYWN0LWNvbXBvbmVudHMvY29tcG9uZW50c1wiO1xuaW1wb3J0IHsgU2VsZWN0LCBTZWxlY3RDb250ZW50LCBTZWxlY3RJdGVtLCBTZWxlY3RUcmlnZ2VyLCBTZWxlY3RWYWx1ZSB9IGZyb20gXCJAc29uYW11LWtpdC9yZWFjdC1jb21wb25lbnRzL2NvbXBvbmVudHNcIjtcbmltcG9ydCB7IEFsZXJ0RGlhbG9nLCBBbGVydERpYWxvZ0FjdGlvbiwgQWxlcnREaWFsb2dDYW5jZWwsIEFsZXJ0RGlhbG9nQ29udGVudCwgQWxlcnREaWFsb2dEZXNjcmlwdGlvbiwgQWxlcnREaWFsb2dGb290ZXIsIEFsZXJ0RGlhbG9nSGVhZGVyLCBBbGVydERpYWxvZ1RpdGxlIH0gZnJvbSBcIkBzb25hbXUta2l0L3JlYWN0LWNvbXBvbmVudHMvY29tcG9uZW50c1wiO1xuaW1wb3J0IHsgSW5wdXQgfSBmcm9tIFwiQHNvbmFtdS1raXQvcmVhY3QtY29tcG9uZW50cy9jb21wb25lbnRzXCI7XG5pbXBvcnQgeyBDaGVja2JveCB9IGZyb20gXCJAc29uYW11LWtpdC9yZWFjdC1jb21wb25lbnRzL2NvbXBvbmVudHNcIjtcblxuaW1wb3J0IHsgdXNlTGlzdFBhcmFtcywgbnVtRiwgZGF0ZUYsIGRhdGV0aW1lRiB9IGZyb20gXCJAc29uYW11LWtpdC9yZWFjdC1jb21wb25lbnRzL2xpYlwiO1xuaW1wb3J0IHsgJHtuYW1lcy5jYXBpdGFsfVN1YnNldEEgfSBmcm9tIFwiQC9zZXJ2aWNlcy9zb25hbXUuZ2VuZXJhdGVkXCI7XG5pbXBvcnQgeyAke25hbWVzLmNhcGl0YWx9U2VydmljZSB9IGZyb20gXCJAL3NlcnZpY2VzL3NlcnZpY2VzLmdlbmVyYXRlZFwiO1xuaW1wb3J0IHsgJHtuYW1lcy5jYXBpdGFsfUxpc3RQYXJhbXMgfSBmcm9tIFwiQC9zZXJ2aWNlcy8ke25hbWVzLmZzfS8ke25hbWVzLmZzfS50eXBlc1wiO1xuaW1wb3J0IHsgJHsoKCkgPT4ge1xuICAgICAgICAvLyDquLDrs7ggZW51bSDsiJjsp5EgKGZpbHRlckNvbHVtbnPsl5Ag7J6I64qUIOqyg+unjClcbiAgICAgICAgY29uc3QgYmFzZUVudW1zOiBzdHJpbmdbXSA9IFtdO1xuICAgICAgICBpZiAoZmlsdGVyQ29sdW1ucy5zb21lKChjb2wpID0+IGNvbC5uYW1lID09PSBcIm9yZGVyQnlcIikpIHtcbiAgICAgICAgICBiYXNlRW51bXMucHVzaChgJHtuYW1lcy5jYXBpdGFsfU9yZGVyQnlgLCBgJHtuYW1lcy5jYXBpdGFsfU9yZGVyQnlMYWJlbGApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmaWx0ZXJDb2x1bW5zLnNvbWUoKGNvbCkgPT4gY29sLm5hbWUgPT09IFwic2VhcmNoXCIpKSB7XG4gICAgICAgICAgYmFzZUVudW1zLnB1c2goYCR7bmFtZXMuY2FwaXRhbH1TZWFyY2hGaWVsZGAsIGAke25hbWVzLmNhcGl0YWx9U2VhcmNoRmllbGRMYWJlbGApO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8g7ZWE7YSwIGVudW0g7IiY7KeRIChjb25maWcuZW51bUlkIOyasOyEoCwg7JeG7Jy866m0IGdldEVudW1JbmZvRnJvbUNvbE5hbWUpXG4gICAgICAgIGNvbnN0IGZpbHRlckVudW1JZHMgPSBmaWx0ZXJDb2x1bW5zXG4gICAgICAgICAgLmZpbHRlcihcbiAgICAgICAgICAgIChjb2wpID0+IGNvbC5yZW5kZXJUeXBlID09PSBcImVudW1zXCIgJiYgY29sLm5hbWUgIT09IFwic2VhcmNoXCIgJiYgY29sLm5hbWUgIT09IFwib3JkZXJCeVwiLFxuICAgICAgICAgIClcbiAgICAgICAgICAubWFwKChjb2wpID0+IHtcbiAgICAgICAgICAgIGlmIChjb2wuY29uZmlnICYmIFwiZW51bUlkXCIgaW4gY29sLmNvbmZpZykge1xuICAgICAgICAgICAgICByZXR1cm4gKGNvbC5jb25maWcgYXMgeyBlbnVtSWQ6IHN0cmluZyB9KS5lbnVtSWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBjb25zdCB7IGlkOiBlbnVtSWQgfSA9IGdldEVudW1JbmZvRnJvbUNvbE5hbWUoZW50aXR5SWQsIGNvbC5uYW1lKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGVudW1JZDtcbiAgICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KVxuICAgICAgICAgIC5maWx0ZXIoQm9vbGVhbikgYXMgc3RyaW5nW107XG5cbiAgICAgICAgLy8g66qo65OgIGVudW0g7ZWp7LmY6rOgIOykkeuztSDsoJzqsbBcbiAgICAgICAgY29uc3QgYWxsRW51bXMgPSBbLi4ubmV3IFNldChbLi4uZmlsdGVyRW51bUlkcywgLi4uY29sdW1uRW51bXNdKV07XG4gICAgICAgIGNvbnN0IGVudW1JbXBvcnRzID0gYWxsRW51bXMuZmxhdE1hcCgoZW51bUlkKSA9PiBbYCR7ZW51bUlkfWAsIGAke2VudW1JZH1MYWJlbGBdKTtcblxuICAgICAgICByZXR1cm4gWy4uLmJhc2VFbnVtcywgLi4uZW51bUltcG9ydHNdLmpvaW4oXCIsIFwiKTtcbiAgICAgIH0pKCl9IH0gZnJvbSBcIkAvc2VydmljZXMvc29uYW11LmdlbmVyYXRlZFwiO1xuJHsoKCkgPT4ge1xuICAvLyBGSyDtlYTrk5zsnZggQXN5bmNTZWxlY3Qg7Lu07Y+s64SM7Yq4IGltcG9ydFxuICBjb25zdCBma0NvbHVtbnMgPSBmaWx0ZXJDb2x1bW5zLmZpbHRlcigoY29sKSA9PiBjb2wubmFtZS5lbmRzV2l0aChcIl9pZFwiKSAmJiBjb2wubmFtZSAhPT0gXCJpZFwiKTtcbiAgcmV0dXJuIGZrQ29sdW1uc1xuICAgIC5tYXAoKGNvbCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcmVsUHJvcCA9IGdldFJlbGF0aW9uUHJvcEZyb21Db2xOYW1lKGVudGl0eUlkLCBjb2wubmFtZS5yZXBsYWNlKFwiX2lkXCIsIFwiXCIpKTtcbiAgICAgICAgY29uc3QgdGFyZ2V0TmFtZXMgPSBFbnRpdHlNYW5hZ2VyLmdldE5hbWVzRnJvbUlkKHJlbFByb3Aud2l0aCk7XG4gICAgICAgIHJldHVybiBgaW1wb3J0IHsgJHtyZWxQcm9wLndpdGh9SWRBc3luY1NlbGVjdCB9IGZyb20gXCJAL2NvbXBvbmVudHMvJHt0YXJnZXROYW1lcy5mc30vJHtyZWxQcm9wLndpdGh9SWRBc3luY1NlbGVjdFwiO2A7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICB9XG4gICAgfSlcbiAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgLmpvaW4oXCJcXG5cIik7XG59KSgpfVxuJHtcbiAgZmlsdGVyQ29sdW1ucy5zb21lKChjb2wpID0+IGNvbC5uYW1lID09PSBcInNlYXJjaFwiKVxuICAgID8gYFxuaW1wb3J0IHsgJHtuYW1lcy5jYXBpdGFsfVNlYXJjaEZpZWxkU2VsZWN0IH0gZnJvbSBcIkAvY29tcG9uZW50cy8ke25hbWVzLmZzfS8ke25hbWVzLmNhcGl0YWx9U2VhcmNoRmllbGRTZWxlY3RcIjtgXG4gICAgOiBcIlwiXG59XG4ke1xuICBmaWx0ZXJDb2x1bW5zLnNvbWUoKGNvbCkgPT4gY29sLm5hbWUgPT09IFwib3JkZXJCeVwiKVxuICAgID8gYFxuaW1wb3J0IHsgJHtuYW1lcy5jYXBpdGFsfU9yZGVyQnlTZWxlY3QgfSBmcm9tIFwiQC9jb21wb25lbnRzLyR7bmFtZXMuZnN9LyR7bmFtZXMuY2FwaXRhbH1PcmRlckJ5U2VsZWN0XCI7YFxuICAgIDogXCJcIlxufVxuXG5pbXBvcnQgRWRpdEljb24gZnJvbSBcIn5pY29ucy9sdWNpZGUvc3F1YXJlLXBlblwiO1xuaW1wb3J0IFRyYXNoSWNvbiBmcm9tIFwifmljb25zL2x1Y2lkZS90cmFzaC0yXCI7XG5pbXBvcnQgTGlzdEljb24gZnJvbSBcIn5pY29ucy9tZGkvZm9ybWF0LWxpc3QtYnVsbGV0ZWRcIjtcbmltcG9ydCBTZWFyY2hJY29uIGZyb20gXCJ+aWNvbnMvbWRpL21hZ25pZnlcIjtcblxuZXhwb3J0IGNvbnN0IFJvdXRlID0gY3JlYXRlRmlsZVJvdXRlKFwiL2FkbWluLyR7bmFtZXMuZnNQbHVyYWx9L1wiKSh7XFxuICBoZWFkOiAoKSA9PiAoe1xcbiAgICBtZXRhOiBbXFxuICAgICAgeyB0aXRsZTogXCIke2VudGl0eS50aXRsZSA/PyBuYW1lcy5jYXBpdGFsfSBMaXN0XCIgfSxcXG4gICAgICB7IG5hbWU6IFwiZGVzY3JpcHRpb25cIiwgY29udGVudDogXCIke2VudGl0eS50aXRsZSA/PyBuYW1lcy5jYXBpdGFsfSDrqqnroZ0g6rSA66asXCIgfSxcXG4gICAgXSxcXG4gIH0pLFxcbiAgY29tcG9uZW50OiAke25hbWVzLmNhcGl0YWx9TGlzdCxcXG59KTtcXG5cXG50eXBlICR7bmFtZXMuY2FwaXRhbH1MaXN0UHJvcHMgPSB7fTtcblxuZnVuY3Rpb24gJHtuYW1lcy5jYXBpdGFsfUxpc3Qoe306ICR7bmFtZXMuY2FwaXRhbH1MaXN0UHJvcHMpIHtcbiAgY29uc3QgbmF2aWdhdGUgPSB1c2VOYXZpZ2F0ZSgpO1xuXG4gIC8vIOyDge2DnCDqtIDrpqxcbiAgY29uc3QgW3NlbGVjdGVkSXRlbXMsIHNldFNlbGVjdGVkSXRlbXNdID0gdXNlU3RhdGU8U2V0PG51bWJlcj4+KG5ldyBTZXQoKSk7XG4gIGNvbnN0IFtkZWxldGVEaWFsb2dPcGVuLCBzZXREZWxldGVEaWFsb2dPcGVuXSA9IHVzZVN0YXRlKGZhbHNlKTtcbiAgY29uc3QgW2l0ZW1Ub0RlbGV0ZSwgc2V0SXRlbVRvRGVsZXRlXSA9IHVzZVN0YXRlPHsgaWQ6IG51bWJlcjsgbmFtZT86IHN0cmluZyB9IHwgbnVsbD4obnVsbCk7XG5cbiAgLy8g66as7Iqk7Yq4IO2VhO2EsFxuICBjb25zdCB7IGxpc3RQYXJhbXMsIHJlZ2lzdGVyIH0gPSB1c2VMaXN0UGFyYW1zKCR7bmFtZXMuY2FwaXRhbH1MaXN0UGFyYW1zLCB7XG4gICAgbnVtOiAxMCxcbiAgICBwYWdlOiAxLFxuICAgIGtleXdvcmQ6IFwiXCIsJHtcbiAgICAgIGZpbHRlckNvbHVtbnMuc29tZSgoY29sKSA9PiBjb2wubmFtZSA9PT0gXCJzZWFyY2hcIilcbiAgICAgICAgPyBgXG4gICAgc2VhcmNoOiAke25hbWVzLmNhcGl0YWx9U2VhcmNoRmllbGQub3B0aW9uc1swXSxgXG4gICAgICAgIDogXCJcIlxuICAgIH0ke1xuICAgICAgZmlsdGVyQ29sdW1ucy5zb21lKChjb2wpID0+IGNvbC5uYW1lID09PSBcIm9yZGVyQnlcIilcbiAgICAgICAgPyBgXG4gICAgb3JkZXJCeTogJHtuYW1lcy5jYXBpdGFsfU9yZGVyQnkub3B0aW9uc1swXSxgXG4gICAgICAgIDogXCJcIlxuICAgIH1cbiAgfSk7XG5cbiAgLy8g66as7Iqk7Yq4IOy/vOumrFxuICBjb25zdCB7IGRhdGEsIHJlZmV0Y2gsIGlzTG9hZGluZyB9ID0gJHtuYW1lcy5jYXBpdGFsfVNlcnZpY2UudXNlJHtuYW1lcy5jYXBpdGFsUGx1cmFsfShcIkFcIiwgbGlzdFBhcmFtcyk7XG4gIGNvbnN0IHsgcm93cywgdG90YWwgfSA9IGRhdGEgPz8ge307XG5cbiAgLy8g7ZiE7J6sIOqyveuhnOyZgCDtg4DsnbTti4BcbiAgY29uc3QgUEFHRSA9IHtcbiAgICByb3V0ZTogXCIvYWRtaW4vJHtuYW1lcy5mc1BsdXJhbH1cIixcbiAgICB0aXRsZTogXCIke2VudGl0eS50aXRsZSA/PyBuYW1lcy5jYXBpdGFsfVwiLFxuICB9O1xuXG4gIC8vIOy7rOufvCDsoJXsnZhcbiAgdHlwZSAke25hbWVzLmNhcGl0YWx9Um93ID0gTm9uTnVsbGFibGU8dHlwZW9mIHJvd3M+W251bWJlcl07XG4gIGNvbnN0IGNvbHVtbnM6IFRhYmxlQ29sPCR7bmFtZXMuY2FwaXRhbH1Sb3c+W10gPSBbXG4ke2NvbHVtbnNcbiAgLm1hcChcbiAgICAoY29sKSA9PiBgICAgIHtcbiAgICAgIGxhYmVsOiBcIiR7Y29sLmxhYmVsfVwiLFxuICAgICAgdGM6ICR7Y29sLnRjfSwke1xuICAgICAgICBjb2wuZml0XG4gICAgICAgICAgPyBgXG4gICAgICBmaXQ6IHRydWUsYFxuICAgICAgICAgIDogXCJcIlxuICAgICAgfSR7XG4gICAgICAgIGNvbC5hbGlnblxuICAgICAgICAgID8gYFxuICAgICAgYWxpZ246IFwiJHtjb2wuYWxpZ259XCIsYFxuICAgICAgICAgIDogXCJcIlxuICAgICAgfVxuICAgIH1gLFxuICApXG4gIC5qb2luKFwiLFxcblwiKX0sXG4gICAge1xuICAgICAgbGFiZWw6IFwiTWFuYWdlXCIsXG4gICAgICBmaXQ6IHRydWUsXG4gICAgICBhbGlnbjogXCJjZW50ZXJcIixcbiAgICAgIHRjOiAocm93KSA9PiAoXG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgZ2FwLTFcIj5cbiAgICAgICAgICA8QnV0dG9uXG4gICAgICAgICAgICB2YXJpYW50PVwieWVsbG93XCJcbiAgICAgICAgICAgIHNpemU9XCJ4c1wiXG4gICAgICAgICAgICBpY29uPXs8RWRpdEljb24gLz59XG4gICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBuYXZpZ2F0ZSh7IHRvOiBcXGBcXCR7UEFHRS5yb3V0ZX0vZm9ybVxcYCwgc2VhcmNoOiB7IGlkOiByb3cuaWQgfSB9KX1cbiAgICAgICAgICAvPlxuICAgICAgICAgIDxCdXR0b25cbiAgICAgICAgICAgIHZhcmlhbnQ9XCJyZWRcIlxuICAgICAgICAgICAgc2l6ZT1cInhzXCJcbiAgICAgICAgICAgIGljb249ezxUcmFzaEljb24gLz59XG4gICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBoYW5kbGVEZWxldGVDbGljayhyb3cuaWQpfVxuICAgICAgICAgIC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgKSxcbiAgICB9LFxuICBdO1xuXG4gIC8vIOyEoO2DnSDtlbjrk6Trn6xcbiAgY29uc3QgaGFuZGxlVG9nZ2xlSXRlbSA9IChpZDogbnVtYmVyKSA9PiB7XG4gICAgY29uc3QgbmV3U2VsZWN0aW9uID0gbmV3IFNldChzZWxlY3RlZEl0ZW1zKTtcbiAgICBpZiAobmV3U2VsZWN0aW9uLmhhcyhpZCkpIHtcbiAgICAgIG5ld1NlbGVjdGlvbi5kZWxldGUoaWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXdTZWxlY3Rpb24uYWRkKGlkKTtcbiAgICB9XG4gICAgc2V0U2VsZWN0ZWRJdGVtcyhuZXdTZWxlY3Rpb24pO1xuICB9O1xuXG4gIGNvbnN0IGlzQWxsU2VsZWN0ZWQgPSAoKSA9PiB7XG4gICAgcmV0dXJuIChyb3dzPy5sZW5ndGggPz8gMCkgPiAwICYmIHJvd3MhLmV2ZXJ5KChyb3cpID0+IHNlbGVjdGVkSXRlbXMuaGFzKHJvdy5pZCkpO1xuICB9O1xuXG4gIGNvbnN0IGhhbmRsZVNlbGVjdEFsbCA9IChjaGVja2VkOiBib29sZWFuKSA9PiB7XG4gICAgaWYgKGNoZWNrZWQpIHtcbiAgICAgIHNldFNlbGVjdGVkSXRlbXMobmV3IFNldChyb3dzPy5tYXAoKHJvdykgPT4gcm93LmlkKSA/PyBbXSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZXRTZWxlY3RlZEl0ZW1zKG5ldyBTZXQoKSk7XG4gICAgfVxuICB9O1xuXG4gIC8vIOyCreygnCDtlbjrk6Trn6xcbiAgY29uc3QgaGFuZGxlRGVsZXRlQ2xpY2sgPSAoaWQ6IG51bWJlciwgbmFtZT86IHN0cmluZykgPT4ge1xuICAgIHNldEl0ZW1Ub0RlbGV0ZSh7IGlkLCBuYW1lIH0pO1xuICAgIHNldERlbGV0ZURpYWxvZ09wZW4odHJ1ZSk7XG4gIH07XG5cbiAgY29uc3QgaGFuZGxlQ29uZmlybURlbGV0ZSA9ICgpID0+IHtcbiAgICBpZiAoaXRlbVRvRGVsZXRlKSB7XG4gICAgICAke25hbWVzLmNhcGl0YWx9U2VydmljZS5kZWwoW2l0ZW1Ub0RlbGV0ZS5pZF0pLnRoZW4oKCkgPT4ge1xuICAgICAgICByZWZldGNoKCk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgc2V0RGVsZXRlRGlhbG9nT3BlbihmYWxzZSk7XG4gICAgc2V0SXRlbVRvRGVsZXRlKG51bGwpO1xuICB9O1xuXG4gIHJldHVybiAoXG4gICAgPGRpdiBjbGFzc05hbWU9XCJmbGV4LTEgb3ZlcmZsb3ctYXV0b1wiPlxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJtYXgtdy1bMTgwMHB4XSBteC1hdXRvIHAtOFwiPlxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cInNwYWNlLXktNiBtYi04XCI+XG4gICAgICAgICAgey8qIEhlYWRlciAqL31cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImZsZXggaXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gICAgICAgICAgICA8TGlzdEljb24gY2xhc3NOYW1lPVwiaC01IHctNVwiIC8+XG4gICAgICAgICAgICA8c3BhbiBjbGFzc05hbWU9XCJ0ZXh0LWxnIGZvbnQtc2VtaWJvbGQgaC01XCI+e1BBR0UudGl0bGV9PC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPENhcmQgY2xhc3NOYW1lPVwic2hhZG93LXNtIGJvcmRlci1ib3JkZXIvNDAgb3ZlcmZsb3ctaGlkZGVuXCI+XG4gICAgICAgICAgICA8Q2FyZEhlYWRlciBjbGFzc05hbWU9XCJwYi0wIHB4LTAgcHQtMFwiPlxuICAgICAgICAgICAgICB7LyogRmlsdGVycyAqL31cbiAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJiZy1ncmF5LTEwMCBweC02IHB5LTQgc3BhY2UteS0zXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJmbGV4IGl0ZW1zLWNlbnRlciBnYXAtMyBmbGV4LXdyYXBcIj5cbiR7XG4gIGZpbHRlckNvbHVtbnMuc29tZSgoY29sKSA9PiBjb2wubmFtZSA9PT0gXCJzZWFyY2hcIilcbiAgICA/IGAgICAgICAgICAgICAgICAgICA8JHtuYW1lcy5jYXBpdGFsfVNlYXJjaEZpZWxkU2VsZWN0XG4gICAgICAgICAgICAgICAgICAgIHsuLi5yZWdpc3RlcihcInNlYXJjaFwiKX1cbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWFyY2ggVHlwZVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cInctWzIwMHB4XSBoLTggYmctd2hpdGUgYm9yZGVyLWdyYXktMzAwIHRleHQteHNcIlxuICAgICAgICAgICAgICAgICAgLz5gXG4gICAgOiBcIlwiXG59XG5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwicmVsYXRpdmUgZmxleC0xIG1heC13LXhzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxJbnB1dFxuICAgICAgICAgICAgICAgICAgICAgIHsuLi5yZWdpc3RlcihcImtleXdvcmRcIil9XG4gICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWFyY2guLi5cIlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cImgtOCBwci04IHRleHQteHMgYmctd2hpdGUgYm9yZGVyLWdyYXktMzAwXCJcbiAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPEJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgIHZhcmlhbnQ9XCJnaG9zdFwiXG4gICAgICAgICAgICAgICAgICAgICAgc2l6ZT1cInNtXCJcbiAgICAgICAgICAgICAgICAgICAgICBpY29uPXs8U2VhcmNoSWNvbiAvPn1cbiAgICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJhYnNvbHV0ZSByaWdodC0wIHRvcC0wIGgtOCB3LTggaG92ZXI6YmctdHJhbnNwYXJlbnRcIlxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwibWwtYXV0b1wiPlxuICAgICAgICAgICAgICAgICAgICA8QnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwiaC04IHB4LTQgYmctcHJpbWFyeSBob3ZlcjpiZy1wcmltYXJ5LzkwIHRleHQtd2hpdGVcIlxuICAgICAgICAgICAgICAgICAgICAgIG9uQ2xpY2s9eygpID0+IG5hdmlnYXRlKHsgdG86IFxcYFxcJHtQQUdFLnJvdXRlfS9mb3JtXFxgIH0pfVxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3NOYW1lPVwidGV4dC14c1wiPkNyZWF0ZTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9CdXR0b24+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZmxleCBpdGVtcy1jZW50ZXIgZ2FwLTMgZmxleC13cmFwXCI+XG4ke2ZpbHRlckNvbHVtbnNcbiAgLmZpbHRlcigoY29sKSA9PiBjb2wubmFtZSAhPT0gXCJzZWFyY2hcIiAmJiBjb2wubmFtZSAhPT0gXCJvcmRlckJ5XCIpXG4gIC5tYXAoKGNvbCkgPT4ge1xuICAgIGlmIChjb2wucmVuZGVyVHlwZSA9PT0gXCJlbnVtc1wiKSB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBjb25maWcuZW51bUlk6rCAIOyeiOycvOuptCDsmrDshKAg7IKs7JqpLCDsl4bsnLzrqbQgZ2V0RW51bUluZm9Gcm9tQ29sTmFtZSDsi5zrj4RcbiAgICAgICAgY29uc3QgZW51bUlkID1cbiAgICAgICAgICBjb2wuY29uZmlnICYmIFwiZW51bUlkXCIgaW4gY29sLmNvbmZpZ1xuICAgICAgICAgICAgPyAoY29sLmNvbmZpZyBhcyB7IGVudW1JZDogc3RyaW5nIH0pLmVudW1JZFxuICAgICAgICAgICAgOiBnZXRFbnVtSW5mb0Zyb21Db2xOYW1lKGVudGl0eUlkLCBjb2wubmFtZSkuaWQ7XG4gICAgICAgIHJldHVybiBgICAgICAgICAgICAgICAgICAgPFNlbGVjdCBrZXk9e1xcYCR7Y29sLm5hbWV9LVxcJHtsaXN0UGFyYW1zLiR7Y29sLm5hbWV9fVxcYH0gey4uLnJlZ2lzdGVyKFwiJHtjb2wubmFtZX1cIil9IGNsZWFyYWJsZT5cbiAgICAgICAgICAgICAgICAgICAgPFNlbGVjdFRyaWdnZXIgY2xhc3NOYW1lPVwidy1bMjAwcHhdIGgtOCBiZy13aGl0ZSBib3JkZXItZ3JheS0zMDAgdGV4dC14c1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxTZWxlY3RWYWx1ZSBwbGFjZWhvbGRlcj1cIiR7Y29sLmxhYmVsfVwiIGNsYXNzTmFtZT1cInRydW5jYXRlXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9TZWxlY3RUcmlnZ2VyPlxuICAgICAgICAgICAgICAgICAgICA8U2VsZWN0Q29udGVudD5cbiAgICAgICAgICAgICAgICAgICAgICB7JHtlbnVtSWR9Lm9wdGlvbnMubWFwKChrZXkpID0+IChcbiAgICAgICAgICAgICAgICAgICAgICAgIDxTZWxlY3RJdGVtIGtleT17a2V5fSB2YWx1ZT17a2V5fT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgeyR7ZW51bUlkfUxhYmVsW2tleV19XG4gICAgICAgICAgICAgICAgICAgICAgICA8L1NlbGVjdEl0ZW0+XG4gICAgICAgICAgICAgICAgICAgICAgKSl9XG4gICAgICAgICAgICAgICAgICAgIDwvU2VsZWN0Q29udGVudD5cbiAgICAgICAgICAgICAgICAgIDwvU2VsZWN0PmA7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgcmV0dXJuIFwiXCI7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEZLIO2VhOuTnCAoQXN5bmNTZWxlY3QpXG4gICAgaWYgKGNvbC5uYW1lLmVuZHNXaXRoKFwiX2lkXCIpICYmIGNvbC5uYW1lICE9PSBcImlkXCIpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlbFByb3AgPSBnZXRSZWxhdGlvblByb3BGcm9tQ29sTmFtZShlbnRpdHlJZCwgY29sLm5hbWUucmVwbGFjZShcIl9pZFwiLCBcIlwiKSk7XG4gICAgICAgIHJldHVybiBgICAgICAgICAgICAgICAgICAgPCR7cmVsUHJvcC53aXRofUlkQXN5bmNTZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgc3Vic2V0PVwiQVwiXG4gICAgICAgICAgICAgICAgICAgIHsuLi5yZWdpc3RlcihcIiR7Y29sLm5hbWV9XCIpfVxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIiR7Y29sLmxhYmVsID8/IHJlbFByb3Aud2l0aH1cIlxuICAgICAgICAgICAgICAgICAgICBjbGVhcmFibGVcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwidy1bMjAwcHhdIGgtOCB0ZXh0LXhzXCJcbiAgICAgICAgICAgICAgICAgIC8+YDtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gXCJcIjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIFwiXCI7XG4gIH0pXG4gIC5maWx0ZXIoQm9vbGVhbilcbiAgLmpvaW4oXCJcXG5cIil9XG4ke1xuICBmaWx0ZXJDb2x1bW5zLnNvbWUoKGNvbCkgPT4gY29sLm5hbWUgPT09IFwib3JkZXJCeVwiKVxuICAgID8gYCAgICAgICAgICAgICAgICAgIDwke25hbWVzLmNhcGl0YWx9T3JkZXJCeVNlbGVjdFxuICAgICAgICAgICAgICAgICAgICB7Li4ucmVnaXN0ZXIoXCJvcmRlckJ5XCIpfVxuICAgICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlNvcnRcIlxuICAgICAgICAgICAgICAgICAgICB0ZXh0UHJlZml4PVwiU29ydDogXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwidy1bMjAwcHhdIGgtOCBiZy13aGl0ZSBib3JkZXItZ3JheS0zMDAgdGV4dC14c1wiXG4gICAgICAgICAgICAgICAgICAvPmBcbiAgICA6IFwiXCJcbn1cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzTmFtZT1cInRleHQteHMgdGV4dC1tdXRlZC1mb3JlZ3JvdW5kXCI+e3RvdGFsID8/IDB9IHJlc3VsdHM8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9DYXJkSGVhZGVyPlxuXG4gICAgICAgICAgICA8Q2FyZENvbnRlbnQgY2xhc3NOYW1lPVwicHgtNiBwYi02IHB0LTYgYmctd2hpdGVcIj5cbiAgICAgICAgICAgICAgey8qIFRhYmxlICovfVxuICAgICAgICAgICAgICA8VGFibGU+XG4gICAgICAgICAgICAgICAgPFRhYmxlSGVhZGVyPlxuICAgICAgICAgICAgICAgICAgPFRhYmxlUm93IGNsYXNzTmFtZT1cImhvdmVyOmJnLXRyYW5zcGFyZW50IGJnLWdyYXktMTAwXCI+XG4gICAgICAgICAgICAgICAgICAgIDxUYWJsZUhlYWQgY2xhc3NOYW1lPVwiaC05IHRleHQteHMgdy1bNDBweF1cIj5cbiAgICAgICAgICAgICAgICAgICAgICA8Q2hlY2tib3hcbiAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrZWQ9e2lzQWxsU2VsZWN0ZWQoKX1cbiAgICAgICAgICAgICAgICAgICAgICAgIG9uVmFsdWVDaGFuZ2U9e2hhbmRsZVNlbGVjdEFsbH1cbiAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICA8L1RhYmxlSGVhZD5cbiAgICAgICAgICAgICAgICAgICAge2NvbHVtbnMubWFwKChjb2wsIGlkeCkgPT4gKFxuICAgICAgICAgICAgICAgICAgICAgIDxUYWJsZUhlYWQga2V5PXtpZHh9IGZpdD17Y29sLmZpdH0gYWxpZ249e2NvbC5hbGlnbn0+XG4gICAgICAgICAgICAgICAgICAgICAgICB7Y29sLmxhYmVsfVxuICAgICAgICAgICAgICAgICAgICAgIDwvVGFibGVIZWFkPlxuICAgICAgICAgICAgICAgICAgICApKX1cbiAgICAgICAgICAgICAgICAgIDwvVGFibGVSb3c+XG4gICAgICAgICAgICAgICAgPC9UYWJsZUhlYWRlcj5cbiAgICAgICAgICAgICAgICA8VGFibGVCb2R5PlxuICAgICAgICAgICAgICAgICAgeyFpc0xvYWRpbmcgJiYgcm93cyAmJiByb3dzLm1hcCgocm93KSA9PiAoXG4gICAgICAgICAgICAgICAgICAgIDxGcmFnbWVudCBrZXk9e3Jvdy5pZH0+XG4gICAgICAgICAgICAgICAgICAgICAgPFRhYmxlUm93PlxuICAgICAgICAgICAgICAgICAgICAgICAgPFRhYmxlQ2VsbCBjbGFzc05hbWU9XCJweS0zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxDaGVja2JveFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoZWNrZWQ9e3NlbGVjdGVkSXRlbXMuaGFzKHJvdy5pZCl9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb25WYWx1ZUNoYW5nZT17KCkgPT4gaGFuZGxlVG9nZ2xlSXRlbShyb3cuaWQpfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9UYWJsZUNlbGw+XG4gICAgICAgICAgICAgICAgICAgICAgICB7Y29sdW1ucy5tYXAoKGNvbCwgaWR4KSA9PiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxUYWJsZUNlbGwga2V5PXtpZHh9IGZpdD17Y29sLmZpdH0gYWxpZ249e2NvbC5hbGlnbn0gY2xhc3NOYW1lPVwicHktM1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtjb2wudGMocm93KX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9UYWJsZUNlbGw+XG4gICAgICAgICAgICAgICAgICAgICAgICApKX1cbiAgICAgICAgICAgICAgICAgICAgICA8L1RhYmxlUm93PlxuICAgICAgICAgICAgICAgICAgICA8L0ZyYWdtZW50PlxuICAgICAgICAgICAgICAgICAgKSl9XG4gICAgICAgICAgICAgICAgPC9UYWJsZUJvZHk+XG4gICAgICAgICAgICAgIDwvVGFibGU+XG5cbiAgICAgICAgICAgICAgey8qIFBhZ2luYXRpb24gKi99XG4gICAgICAgICAgICAgIDxQYWdpbmF0aW9uXG4gICAgICAgICAgICAgICAgey4uLnJlZ2lzdGVyKFwicGFnZVwiKX1cbiAgICAgICAgICAgICAgICB0b3RhbD17dG90YWwgPz8gMH1cbiAgICAgICAgICAgICAgICBpdGVtc1BlclBhZ2U9e2xpc3RQYXJhbXMubnVtID8/IDEwfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgPC9DYXJkQ29udGVudD5cbiAgICAgICAgICA8L0NhcmQ+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIHsvKiBEZWxldGUgRGlhbG9nICovfVxuICAgICAgPEFsZXJ0RGlhbG9nIG9wZW49e2RlbGV0ZURpYWxvZ09wZW59IG9uT3BlbkNoYW5nZT17c2V0RGVsZXRlRGlhbG9nT3Blbn0+XG4gICAgICAgIDxBbGVydERpYWxvZ0NvbnRlbnQ+XG4gICAgICAgICAgPEFsZXJ0RGlhbG9nSGVhZGVyPlxuICAgICAgICAgICAgPEFsZXJ0RGlhbG9nVGl0bGU+QXJlIHlvdSBzdXJlPzwvQWxlcnREaWFsb2dUaXRsZT5cbiAgICAgICAgICAgIDxBbGVydERpYWxvZ0Rlc2NyaXB0aW9uPlxuICAgICAgICAgICAgICBUaGlzIGFjdGlvbiBjYW5ub3QgYmUgdW5kb25lLiBUaGlzIHdpbGwgcGVybWFuZW50bHkgZGVsZXRlIHRoaXMgaXRlbS5cbiAgICAgICAgICAgIDwvQWxlcnREaWFsb2dEZXNjcmlwdGlvbj5cbiAgICAgICAgICA8L0FsZXJ0RGlhbG9nSGVhZGVyPlxuICAgICAgICAgIDxBbGVydERpYWxvZ0Zvb3Rlcj5cbiAgICAgICAgICAgIDxBbGVydERpYWxvZ0NhbmNlbD5DYW5jZWw8L0FsZXJ0RGlhbG9nQ2FuY2VsPlxuICAgICAgICAgICAgPEFsZXJ0RGlhbG9nQWN0aW9uIG9uQ2xpY2s9e2hhbmRsZUNvbmZpcm1EZWxldGV9PkRlbGV0ZTwvQWxlcnREaWFsb2dBY3Rpb24+XG4gICAgICAgICAgPC9BbGVydERpYWxvZ0Zvb3Rlcj5cbiAgICAgICAgPC9BbGVydERpYWxvZ0NvbnRlbnQ+XG4gICAgICA8L0FsZXJ0RGlhbG9nPlxuICAgIDwvZGl2PlxuICApO1xufVxuICAgICAgYC50cmltKCksXG4gICAgICBpbXBvcnRLZXlzOiBbXSxcbiAgICAgIHByZVRlbXBsYXRlcyxcbiAgICB9O1xuICB9XG59XG4iXSwibmFtZXMiOlsiaW5mbGVjdGlvbiIsImZsYXQiLCJ6IiwiRW50aXR5TWFuYWdlciIsImdldEVudW1JbmZvRnJvbUNvbE5hbWUiLCJnZXRSZWxhdGlvblByb3BGcm9tQ29sTmFtZSIsIlRlbXBsYXRlIiwiVGVtcGxhdGVfX3ZpZXdfbGlzdCIsImdldFRhcmdldEFuZFBhdGgiLCJuYW1lcyIsInRhcmdldCIsInBhdGgiLCJmc1BsdXJhbCIsIndyYXBUYyIsImJvZHkiLCJrZXkiLCJjb2xsYXBzaW5nIiwiY2xhc3NOYW1lIiwicmVuZGVyQ29sdW1uIiwiZW50aXR5SWQiLCJjb2wiLCJwYXJlbnRPYmoiLCJ3aXRob3V0TmFtZSIsImNvbE5hbWUiLCJuYW1lIiwiaW5jbHVkZXMiLCJwYXJ0cyIsInNwbGl0Iiwiam9pbiIsInJlbmRlclR5cGUiLCJiYXNlTmFtZSIsInBvcCIsInJlcGxhY2UiLCJyZWxQcm9wRmsiLCJ3aXRoIiwibnVsbGFibGUiLCJsYWJlbCIsImlkIiwiZW51bUlkIiwicGlja2VkQ2hpbGQiLCJjaGlsZHJlbiIsImZpbmQiLCJjaGlsZCIsImNvbmZpZyIsInBpY2tlZCIsIkVycm9yIiwicmVuZGVyQ29sdW1uSW1wb3J0IiwiY2FwaXRhbCIsInJlbFByb3AiLCJyZXN1bHQiLCJtYXAiLCJnZXROYW1lc0Zyb21JZCIsImVsZW1lbnQiLCJyZW5kZXJGaWx0ZXJJbXBvcnQiLCJmcyIsImNvbXBvbmVudElkIiwiY2FtZWxpemUiLCJ0YXJnZXRFbnRpdHlOYW1lcyIsInRhcmdldE1ETmFtZXMiLCJ0YXJnZXROYW1lcyIsInJlbmRlckZpbHRlciIsImlzQ2xlYXJhYmxlIiwib3B0aW9uYWwiLCJnZXREZWZhdWx0IiwiY29sdW1ucyIsImRlZiIsIm9yZGVyQnkiLCJzZWFyY2giLCJoYXNTZWFyY2giLCJoYXNPcmRlckJ5Iiwib3JkZXJCeVpvZFR5cGUiLCJ6b2RUeXBlIiwiWm9kRW51bSIsIk9iamVjdCIsImtleXMiLCJlbnVtIiwic2VhcmNoWm9kVHlwZSIsInJlbmRlciIsImdldENvbHVtbnNOb2RlIiwiZ2V0Wm9kVHlwZUJ5SWQiLCJ6b2RUeXBlVG9SZW5kZXJpbmdOb2RlIiwiY29sdW1uc05vZGUiLCJsaXN0UGFyYW1zWm9kVHlwZSIsImxpc3RQYXJhbXNOb2RlIiwiZW50aXR5IiwiZ2V0Iiwic29ydCIsImEiLCJiIiwicHJvcENhbmRpZGF0ZSIsInByb3BzIiwicCIsInJlbmRlcmVkIiwiZGVzYyIsInRjIiwiZml0IiwiYWxpZ24iLCJ1bmRlZmluZWQiLCJmaWx0ZXJDb2x1bW5zIiwiZmlsdGVyIiwiZW5kc1dpdGgiLCJwcmVUZW1wbGF0ZXMiLCJ0YXJnZXRFbnRpdHlJZCIsInB1c2giLCJvcHRpb25zIiwiY29sdW1uRW51bXMiLCJmb3JFYWNoIiwiYmFzZUVudW1zIiwic29tZSIsImZpbHRlckVudW1JZHMiLCJCb29sZWFuIiwiYWxsRW51bXMiLCJTZXQiLCJlbnVtSW1wb3J0cyIsImZsYXRNYXAiLCJma0NvbHVtbnMiLCJ0aXRsZSIsImNhcGl0YWxQbHVyYWwiLCJ0cmltIiwiaW1wb3J0S2V5cyJdLCJtYXBwaW5ncyI6IkFBQUEsT0FBT0EsZ0JBQWdCLGFBQWE7QUFDcEMsU0FBU0MsSUFBSSxRQUFRLFVBQVU7QUFDL0IsU0FBU0MsQ0FBQyxRQUFRLE1BQU07QUFDeEIsU0FBU0MsYUFBYSxRQUFnQyxpQ0FBOEI7QUFFcEYsU0FBU0Msc0JBQXNCLEVBQUVDLDBCQUEwQixRQUFRLGdCQUFhO0FBRWhGLFNBQVNDLFFB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
|