@fairspec/agent 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +3 -0
  3. package/build/actions/tableSchema/asHtml.d.ts +4 -0
  4. package/build/actions/tableSchema/asHtml.js +82 -0
  5. package/build/actions/tableSchema/asHtml.spec.d.ts +1 -0
  6. package/build/actions/tableSchema/asHtml.spec.js +356 -0
  7. package/build/actions/tableSchema/asMarkdown.d.ts +4 -0
  8. package/build/actions/tableSchema/asMarkdown.js +65 -0
  9. package/build/actions/tableSchema/asMarkdown.spec.d.ts +1 -0
  10. package/build/actions/tableSchema/asMarkdown.spec.js +133 -0
  11. package/build/document/Document.d.ts +2 -0
  12. package/build/document/Document.js +2 -0
  13. package/build/document/index.d.ts +3 -0
  14. package/build/document/index.js +3 -0
  15. package/build/document/types/Base.d.ts +3 -0
  16. package/build/document/types/Base.js +2 -0
  17. package/build/document/types/Json.d.ts +5 -0
  18. package/build/document/types/Json.js +2 -0
  19. package/build/document/validate.d.ts +5 -0
  20. package/build/document/validate.js +23 -0
  21. package/build/document/validate.spec.d.ts +1 -0
  22. package/build/document/validate.spec.js +71 -0
  23. package/build/index.d.ts +1 -0
  24. package/build/index.js +2 -0
  25. package/build/package.json +39 -0
  26. package/build/plugin.d.ts +6 -0
  27. package/build/plugin.js +15 -0
  28. package/build/schema/convert/toHtml.d.ts +4 -0
  29. package/build/schema/convert/toHtml.js +107 -0
  30. package/build/schema/convert/toHtml.spec.d.ts +1 -0
  31. package/build/schema/convert/toHtml.spec.js +432 -0
  32. package/build/schema/convert/toMarkdown.d.ts +4 -0
  33. package/build/schema/convert/toMarkdown.js +75 -0
  34. package/build/schema/convert/toMarkdown.spec.d.ts +1 -0
  35. package/build/schema/convert/toMarkdown.spec.js +137 -0
  36. package/build/schema/index.d.ts +2 -0
  37. package/build/schema/index.js +3 -0
  38. package/build/server.d.ts +2 -0
  39. package/build/server.js +29 -0
  40. package/build/tableSchema/convert/toHtml.d.ts +4 -0
  41. package/build/tableSchema/convert/toHtml.js +80 -0
  42. package/build/tableSchema/convert/toHtml.spec.d.ts +1 -0
  43. package/build/tableSchema/convert/toHtml.spec.js +375 -0
  44. package/build/tableSchema/convert/toMarkdown.d.ts +4 -0
  45. package/build/tableSchema/convert/toMarkdown.js +57 -0
  46. package/build/tableSchema/convert/toMarkdown.spec.d.ts +1 -0
  47. package/build/tableSchema/convert/toMarkdown.spec.js +141 -0
  48. package/build/tableSchema/index.d.ts +2 -0
  49. package/build/tableSchema/index.js +3 -0
  50. package/build/tools/data/validate.d.ts +971 -0
  51. package/build/tools/data/validate.js +15 -0
  52. package/build/tools/data/validate.spec.d.ts +1 -0
  53. package/build/tools/data/validate.spec.js +228 -0
  54. package/build/tools/dataSchema/infer.d.ts +797 -0
  55. package/build/tools/dataSchema/infer.js +15 -0
  56. package/build/tools/dataSchema/infer.spec.d.ts +1 -0
  57. package/build/tools/dataSchema/infer.spec.js +215 -0
  58. package/build/tools/dataSchema/validate.d.ts +177 -0
  59. package/build/tools/dataSchema/validate.js +17 -0
  60. package/build/tools/dataSchema/validate.spec.d.ts +1 -0
  61. package/build/tools/dataSchema/validate.spec.js +148 -0
  62. package/build/tools/dataset/infer.d.ts +1985 -0
  63. package/build/tools/dataset/infer.js +15 -0
  64. package/build/tools/dataset/infer.spec.d.ts +1 -0
  65. package/build/tools/dataset/infer.spec.js +181 -0
  66. package/build/tools/dataset/validate.d.ts +1168 -0
  67. package/build/tools/dataset/validate.js +17 -0
  68. package/build/tools/dataset/validate.spec.d.ts +1 -0
  69. package/build/tools/dataset/validate.spec.js +212 -0
  70. package/build/tools/dialect/infer.d.ts +889 -0
  71. package/build/tools/dialect/infer.js +16 -0
  72. package/build/tools/dialect/infer.spec.d.ts +1 -0
  73. package/build/tools/dialect/infer.spec.js +138 -0
  74. package/build/tools/table/query.d.ts +798 -0
  75. package/build/tools/table/query.js +24 -0
  76. package/build/tools/table/query.spec.d.ts +1 -0
  77. package/build/tools/table/query.spec.js +138 -0
  78. package/build/tools/table/validate.d.ts +999 -0
  79. package/build/tools/table/validate.js +16 -0
  80. package/build/tools/table/validate.spec.d.ts +1 -0
  81. package/build/tools/table/validate.spec.js +106 -0
  82. package/build/tools/tableSchema/infer.d.ts +1316 -0
  83. package/build/tools/tableSchema/infer.js +16 -0
  84. package/build/tools/tableSchema/infer.spec.d.ts +1 -0
  85. package/build/tools/tableSchema/infer.spec.js +152 -0
  86. package/build/tools/tableSchema/validate.d.ts +177 -0
  87. package/build/tools/tableSchema/validate.js +17 -0
  88. package/build/tools/tableSchema/validate.spec.d.ts +1 -0
  89. package/build/tools/tableSchema/validate.spec.js +121 -0
  90. package/package.json +39 -0
@@ -0,0 +1,15 @@
1
+ import { Report, Resource, validateData } from "@fairspec/library";
2
+ import { createTool } from "@mastra/core/tools";
3
+ import { z } from "zod";
4
+ export const validateDataTool = createTool({
5
+ id: "validate-data",
6
+ description: "Validate data against a data schema (JSON Schema). Returns a validation report with errors if any.",
7
+ inputSchema: z.object({
8
+ resource: Resource.describe("The data resource to validate"),
9
+ }),
10
+ outputSchema: Report,
11
+ execute: async (input) => {
12
+ return await validateData(input.resource);
13
+ },
14
+ });
15
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90b29scy9kYXRhL3ZhbGlkYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQ2xFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQTtBQUMvQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFBO0FBRXZCLE1BQU0sQ0FBQyxNQUFNLGdCQUFnQixHQUFHLFVBQVUsQ0FBQztJQUN6QyxFQUFFLEVBQUUsZUFBZTtJQUNuQixXQUFXLEVBQ1Qsb0dBQW9HO0lBQ3RHLFdBQVcsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQ3BCLFFBQVEsRUFBRSxRQUFRLENBQUMsUUFBUSxDQUFDLCtCQUErQixDQUFDO0tBQzdELENBQUM7SUFDRixZQUFZLEVBQUUsTUFBTTtJQUNwQixPQUFPLEVBQUUsS0FBSyxFQUFDLEtBQUssRUFBQyxFQUFFO1FBQ3JCLE9BQU8sTUFBTSxZQUFZLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQzNDLENBQUM7Q0FDRixDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBSZXBvcnQsIFJlc291cmNlLCB2YWxpZGF0ZURhdGEgfSBmcm9tIFwiQGZhaXJzcGVjL2xpYnJhcnlcIlxuaW1wb3J0IHsgY3JlYXRlVG9vbCB9IGZyb20gXCJAbWFzdHJhL2NvcmUvdG9vbHNcIlxuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIlxuXG5leHBvcnQgY29uc3QgdmFsaWRhdGVEYXRhVG9vbCA9IGNyZWF0ZVRvb2woe1xuICBpZDogXCJ2YWxpZGF0ZS1kYXRhXCIsXG4gIGRlc2NyaXB0aW9uOlxuICAgIFwiVmFsaWRhdGUgZGF0YSBhZ2FpbnN0IGEgZGF0YSBzY2hlbWEgKEpTT04gU2NoZW1hKS4gUmV0dXJucyBhIHZhbGlkYXRpb24gcmVwb3J0IHdpdGggZXJyb3JzIGlmIGFueS5cIixcbiAgaW5wdXRTY2hlbWE6IHoub2JqZWN0KHtcbiAgICByZXNvdXJjZTogUmVzb3VyY2UuZGVzY3JpYmUoXCJUaGUgZGF0YSByZXNvdXJjZSB0byB2YWxpZGF0ZVwiKSxcbiAgfSksXG4gIG91dHB1dFNjaGVtYTogUmVwb3J0LFxuICBleGVjdXRlOiBhc3luYyBpbnB1dCA9PiB7XG4gICAgcmV0dXJuIGF3YWl0IHZhbGlkYXRlRGF0YShpbnB1dC5yZXNvdXJjZSlcbiAgfSxcbn0pXG4iXX0=
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,228 @@
1
+ import { writeTempFile } from "@fairspec/library";
2
+ import { describe, expect, it } from "vitest";
3
+ import { validateDataTool } from "./validate.js";
4
+ describe("validateDataTool", () => {
5
+ it("validates tool structure", () => {
6
+ expect(validateDataTool.id).toBe("validate-data");
7
+ expect(validateDataTool.description).toBeTruthy();
8
+ expect(validateDataTool.inputSchema).toBeTruthy();
9
+ expect(validateDataTool.outputSchema).toBeTruthy();
10
+ expect(validateDataTool.execute).toBeTypeOf("function");
11
+ });
12
+ it("validates data against schema", async () => {
13
+ const resource = {
14
+ data: { name: "test", count: 5 },
15
+ dataSchema: {
16
+ type: "object",
17
+ properties: {
18
+ name: { type: "string" },
19
+ count: { type: "integer" },
20
+ },
21
+ },
22
+ };
23
+ const result = await validateDataTool.execute?.({
24
+ resource,
25
+ }, {});
26
+ expect.assert(result);
27
+ expect.assert(!("error" in result));
28
+ expect(result.valid).toBe(true);
29
+ expect(result.errors).toHaveLength(0);
30
+ });
31
+ it("detects invalid data", async () => {
32
+ const resource = {
33
+ data: { name: 123, count: "invalid" },
34
+ dataSchema: {
35
+ type: "object",
36
+ properties: {
37
+ name: { type: "string" },
38
+ count: { type: "integer" },
39
+ },
40
+ },
41
+ };
42
+ const result = await validateDataTool.execute?.({
43
+ resource,
44
+ }, {});
45
+ expect.assert(result);
46
+ expect.assert(!("error" in result));
47
+ expect(result.valid).toBe(false);
48
+ expect(result.errors.length).toBeGreaterThan(0);
49
+ expect(result.errors).toContainEqual({
50
+ type: "data",
51
+ jsonPointer: "/name",
52
+ message: "must be string",
53
+ });
54
+ expect(result.errors).toContainEqual({
55
+ type: "data",
56
+ jsonPointer: "/count",
57
+ message: "must be integer",
58
+ });
59
+ });
60
+ it("validates data from file path", async () => {
61
+ const jsonData = { name: "alice", age: 25, active: true };
62
+ const dataPath = await writeTempFile(JSON.stringify(jsonData), {
63
+ format: "json",
64
+ });
65
+ const resource = {
66
+ data: dataPath,
67
+ dataSchema: {
68
+ type: "object",
69
+ properties: {
70
+ name: { type: "string" },
71
+ age: { type: "number" },
72
+ active: { type: "boolean" },
73
+ },
74
+ required: ["name", "age"],
75
+ },
76
+ };
77
+ const result = await validateDataTool.execute?.({
78
+ resource,
79
+ }, {});
80
+ expect.assert(result);
81
+ expect.assert(!("error" in result));
82
+ expect(result.valid).toBe(true);
83
+ expect(result.errors).toHaveLength(0);
84
+ });
85
+ it("detects invalid data from file path", async () => {
86
+ const jsonData = { name: "alice", age: "not a number" };
87
+ const dataPath = await writeTempFile(JSON.stringify(jsonData), {
88
+ format: "json",
89
+ });
90
+ const resource = {
91
+ data: dataPath,
92
+ dataSchema: {
93
+ type: "object",
94
+ properties: {
95
+ name: { type: "string" },
96
+ age: { type: "number" },
97
+ },
98
+ required: ["name", "age"],
99
+ },
100
+ };
101
+ const result = await validateDataTool.execute?.({
102
+ resource,
103
+ }, {});
104
+ expect.assert(result);
105
+ expect.assert(!("error" in result));
106
+ expect(result.valid).toBe(false);
107
+ expect(result.errors.length).toBeGreaterThan(0);
108
+ });
109
+ it("validates data with nested objects", async () => {
110
+ const resource = {
111
+ data: {
112
+ name: "alice",
113
+ address: { city: "New York", zip: "10001" },
114
+ },
115
+ dataSchema: {
116
+ type: "object",
117
+ properties: {
118
+ name: { type: "string" },
119
+ address: {
120
+ type: "object",
121
+ properties: {
122
+ city: { type: "string" },
123
+ zip: { type: "string" },
124
+ },
125
+ },
126
+ },
127
+ },
128
+ };
129
+ const result = await validateDataTool.execute?.({
130
+ resource,
131
+ }, {});
132
+ expect.assert(result);
133
+ expect.assert(!("error" in result));
134
+ expect(result.valid).toBe(true);
135
+ expect(result.errors).toHaveLength(0);
136
+ });
137
+ it("validates data with array types", async () => {
138
+ const resource = {
139
+ data: {
140
+ tags: ["admin", "user"],
141
+ scores: [95, 87, 92],
142
+ },
143
+ dataSchema: {
144
+ type: "object",
145
+ properties: {
146
+ tags: {
147
+ type: "array",
148
+ items: { type: "string" },
149
+ },
150
+ scores: {
151
+ type: "array",
152
+ items: { type: "number" },
153
+ },
154
+ },
155
+ },
156
+ };
157
+ const result = await validateDataTool.execute?.({
158
+ resource,
159
+ }, {});
160
+ expect.assert(result);
161
+ expect.assert(!("error" in result));
162
+ expect(result.valid).toBe(true);
163
+ expect(result.errors).toHaveLength(0);
164
+ });
165
+ it("returns error when no data but schema expected", async () => {
166
+ const resource = {
167
+ name: "empty",
168
+ dataSchema: { type: "object" },
169
+ };
170
+ const result = await validateDataTool.execute?.({
171
+ resource,
172
+ }, {});
173
+ expect.assert(result);
174
+ expect.assert(!("error" in result));
175
+ expect(result.valid).toBe(false);
176
+ expect(result.errors).toHaveLength(1);
177
+ expect(result.errors).toContainEqual({
178
+ type: "resource/type",
179
+ expectedResourceType: "data",
180
+ });
181
+ });
182
+ it("validates data with required fields", async () => {
183
+ const resource = {
184
+ data: { name: "alice" },
185
+ dataSchema: {
186
+ type: "object",
187
+ properties: {
188
+ name: { type: "string" },
189
+ age: { type: "number" },
190
+ },
191
+ required: ["name", "age"],
192
+ },
193
+ };
194
+ const result = await validateDataTool.execute?.({
195
+ resource,
196
+ }, {});
197
+ expect.assert(result);
198
+ expect.assert(!("error" in result));
199
+ expect(result.valid).toBe(false);
200
+ expect(result.errors.length).toBeGreaterThan(0);
201
+ });
202
+ it("validates array data against schema", async () => {
203
+ const resource = {
204
+ data: [
205
+ { id: 1, name: "alice" },
206
+ { id: 2, name: "bob" },
207
+ ],
208
+ dataSchema: {
209
+ type: "array",
210
+ items: {
211
+ type: "object",
212
+ properties: {
213
+ id: { type: "integer" },
214
+ name: { type: "string" },
215
+ },
216
+ },
217
+ },
218
+ };
219
+ const result = await validateDataTool.execute?.({
220
+ resource,
221
+ }, {});
222
+ expect.assert(result);
223
+ expect.assert(!("error" in result));
224
+ expect(result.valid).toBe(true);
225
+ expect(result.errors).toHaveLength(0);
226
+ });
227
+ });
228
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGUuc3BlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rvb2xzL2RhdGEvdmFsaWRhdGUuc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUJBQW1CLENBQUE7QUFDakQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLE1BQU0sUUFBUSxDQUFBO0FBQzdDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUVoRCxRQUFRLENBQUMsa0JBQWtCLEVBQUUsR0FBRyxFQUFFO0lBQ2hDLEVBQUUsQ0FBQywwQkFBMEIsRUFBRSxHQUFHLEVBQUU7UUFDbEMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQTtRQUNqRCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxDQUFDLENBQUMsVUFBVSxFQUFFLENBQUE7UUFDakQsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsQ0FBQyxDQUFDLFVBQVUsRUFBRSxDQUFBO1FBQ2pELE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsQ0FBQyxVQUFVLEVBQUUsQ0FBQTtRQUNsRCxNQUFNLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQ3pELENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLCtCQUErQixFQUFFLEtBQUssSUFBSSxFQUFFO1FBQzdDLE1BQU0sUUFBUSxHQUFhO1lBQ3pCLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRTtZQUNoQyxVQUFVLEVBQUU7Z0JBQ1YsSUFBSSxFQUFFLFFBQVE7Z0JBQ2QsVUFBVSxFQUFFO29CQUNWLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7b0JBQ3hCLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUU7aUJBQzNCO2FBQ0Y7U0FDRixDQUFBO1FBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FDN0M7WUFDRSxRQUFRO1NBQ1QsRUFDRCxFQUFFLENBQ0gsQ0FBQTtRQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDckIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUE7UUFFbkMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDL0IsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDdkMsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsc0JBQXNCLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDcEMsTUFBTSxRQUFRLEdBQWE7WUFDekIsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFO1lBQ3JDLFVBQVUsRUFBRTtnQkFDVixJQUFJLEVBQUUsUUFBUTtnQkFDZCxVQUFVLEVBQUU7b0JBQ1YsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtvQkFDeEIsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRTtpQkFDM0I7YUFDRjtTQUNGLENBQUE7UUFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxDQUM3QztZQUNFLFFBQVE7U0FDVCxFQUNELEVBQUUsQ0FDSCxDQUFBO1FBRUQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNyQixNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQTtRQUVuQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNoQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDL0MsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxjQUFjLENBQUM7WUFDbkMsSUFBSSxFQUFFLE1BQU07WUFDWixXQUFXLEVBQUUsT0FBTztZQUNwQixPQUFPLEVBQUUsZ0JBQWdCO1NBQzFCLENBQUMsQ0FBQTtRQUNGLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsY0FBYyxDQUFDO1lBQ25DLElBQUksRUFBRSxNQUFNO1lBQ1osV0FBVyxFQUFFLFFBQVE7WUFDckIsT0FBTyxFQUFFLGlCQUFpQjtTQUMzQixDQUFDLENBQUE7SUFDSixDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQywrQkFBK0IsRUFBRSxLQUFLLElBQUksRUFBRTtRQUM3QyxNQUFNLFFBQVEsR0FBRyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLENBQUE7UUFDekQsTUFBTSxRQUFRLEdBQUcsTUFBTSxhQUFhLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUM3RCxNQUFNLEVBQUUsTUFBTTtTQUNmLENBQUMsQ0FBQTtRQUVGLE1BQU0sUUFBUSxHQUFhO1lBQ3pCLElBQUksRUFBRSxRQUFRO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLElBQUksRUFBRSxRQUFRO2dCQUNkLFVBQVUsRUFBRTtvQkFDVixJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO29CQUN4QixHQUFHLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO29CQUN2QixNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFO2lCQUM1QjtnQkFDRCxRQUFRLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDO2FBQzFCO1NBQ0YsQ0FBQTtRQUVELE1BQU0sTUFBTSxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQzdDO1lBQ0UsUUFBUTtTQUNULEVBQ0QsRUFBRSxDQUNILENBQUE7UUFFRCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ3JCLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFBO1FBRW5DLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQy9CLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ3ZDLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLHFDQUFxQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ25ELE1BQU0sUUFBUSxHQUFHLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsY0FBYyxFQUFFLENBQUE7UUFDdkQsTUFBTSxRQUFRLEdBQUcsTUFBTSxhQUFhLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUM3RCxNQUFNLEVBQUUsTUFBTTtTQUNmLENBQUMsQ0FBQTtRQUVGLE1BQU0sUUFBUSxHQUFhO1lBQ3pCLElBQUksRUFBRSxRQUFRO1lBQ2QsVUFBVSxFQUFFO2dCQUNWLElBQUksRUFBRSxRQUFRO2dCQUNkLFVBQVUsRUFBRTtvQkFDVixJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO29CQUN4QixHQUFHLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO2lCQUN4QjtnQkFDRCxRQUFRLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDO2FBQzFCO1NBQ0YsQ0FBQTtRQUVELE1BQU0sTUFBTSxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQzdDO1lBQ0UsUUFBUTtTQUNULEVBQ0QsRUFBRSxDQUNILENBQUE7UUFFRCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ3JCLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFBO1FBRW5DLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ2hDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNqRCxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyxvQ0FBb0MsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNsRCxNQUFNLFFBQVEsR0FBYTtZQUN6QixJQUFJLEVBQUU7Z0JBQ0osSUFBSSxFQUFFLE9BQU87Z0JBQ2IsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFO2FBQzVDO1lBQ0QsVUFBVSxFQUFFO2dCQUNWLElBQUksRUFBRSxRQUFRO2dCQUNkLFVBQVUsRUFBRTtvQkFDVixJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO29CQUN4QixPQUFPLEVBQUU7d0JBQ1AsSUFBSSxFQUFFLFFBQVE7d0JBQ2QsVUFBVSxFQUFFOzRCQUNWLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7NEJBQ3hCLEdBQUcsRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7eUJBQ3hCO3FCQUNGO2lCQUNGO2FBQ0Y7U0FDRixDQUFBO1FBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FDN0M7WUFDRSxRQUFRO1NBQ1QsRUFDRCxFQUFFLENBQ0gsQ0FBQTtRQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDckIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUE7UUFFbkMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDL0IsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDdkMsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsaUNBQWlDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDL0MsTUFBTSxRQUFRLEdBQWE7WUFDekIsSUFBSSxFQUFFO2dCQUNKLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUM7Z0JBQ3ZCLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO2FBQ3JCO1lBQ0QsVUFBVSxFQUFFO2dCQUNWLElBQUksRUFBRSxRQUFRO2dCQUNkLFVBQVUsRUFBRTtvQkFDVixJQUFJLEVBQUU7d0JBQ0osSUFBSSxFQUFFLE9BQU87d0JBQ2IsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtxQkFDMUI7b0JBQ0QsTUFBTSxFQUFFO3dCQUNOLElBQUksRUFBRSxPQUFPO3dCQUNiLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7cUJBQzFCO2lCQUNGO2FBQ0Y7U0FDRixDQUFBO1FBRUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsQ0FDN0M7WUFDRSxRQUFRO1NBQ1QsRUFDRCxFQUFFLENBQ0gsQ0FBQTtRQUVELE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDckIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUE7UUFFbkMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDL0IsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDdkMsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsZ0RBQWdELEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDOUQsTUFBTSxRQUFRLEdBQWE7WUFDekIsSUFBSSxFQUFFLE9BQU87WUFDYixVQUFVLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO1NBQy9CLENBQUE7UUFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxDQUM3QztZQUNFLFFBQVE7U0FDVCxFQUNELEVBQUUsQ0FDSCxDQUFBO1FBRUQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNyQixNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQTtRQUVuQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNoQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNyQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLGNBQWMsQ0FBQztZQUNuQyxJQUFJLEVBQUUsZUFBZTtZQUNyQixvQkFBb0IsRUFBRSxNQUFNO1NBQzdCLENBQUMsQ0FBQTtJQUNKLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLHFDQUFxQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ25ELE1BQU0sUUFBUSxHQUFhO1lBQ3pCLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUU7WUFDdkIsVUFBVSxFQUFFO2dCQUNWLElBQUksRUFBRSxRQUFRO2dCQUNkLFVBQVUsRUFBRTtvQkFDVixJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO29CQUN4QixHQUFHLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO2lCQUN4QjtnQkFDRCxRQUFRLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDO2FBQzFCO1NBQ0YsQ0FBQTtRQUVELE1BQU0sTUFBTSxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsT0FBTyxFQUFFLENBQzdDO1lBQ0UsUUFBUTtTQUNULEVBQ0QsRUFBRSxDQUNILENBQUE7UUFFRCxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQ3JCLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFBO1FBRW5DLE1BQU0sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ2hDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNqRCxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyxxQ0FBcUMsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNuRCxNQUFNLFFBQVEsR0FBYTtZQUN6QixJQUFJLEVBQUU7Z0JBQ0osRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUU7Z0JBQ3hCLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFO2FBQ3ZCO1lBQ0QsVUFBVSxFQUFFO2dCQUNWLElBQUksRUFBRSxPQUFPO2dCQUNiLEtBQUssRUFBRTtvQkFDTCxJQUFJLEVBQUUsUUFBUTtvQkFDZCxVQUFVLEVBQUU7d0JBQ1YsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRTt3QkFDdkIsSUFBSSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtxQkFDekI7aUJBQ0Y7YUFDRjtTQUNGLENBQUE7UUFFRCxNQUFNLE1BQU0sR0FBRyxNQUFNLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxDQUM3QztZQUNFLFFBQVE7U0FDVCxFQUNELEVBQUUsQ0FDSCxDQUFBO1FBRUQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUNyQixNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQTtRQUVuQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUMvQixNQUFNLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUN2QyxDQUFDLENBQUMsQ0FBQTtBQUNKLENBQUMsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBSZXNvdXJjZSB9IGZyb20gXCJAZmFpcnNwZWMvbGlicmFyeVwiXG5pbXBvcnQgeyB3cml0ZVRlbXBGaWxlIH0gZnJvbSBcIkBmYWlyc3BlYy9saWJyYXJ5XCJcbmltcG9ydCB7IGRlc2NyaWJlLCBleHBlY3QsIGl0IH0gZnJvbSBcInZpdGVzdFwiXG5pbXBvcnQgeyB2YWxpZGF0ZURhdGFUb29sIH0gZnJvbSBcIi4vdmFsaWRhdGUudHNcIlxuXG5kZXNjcmliZShcInZhbGlkYXRlRGF0YVRvb2xcIiwgKCkgPT4ge1xuICBpdChcInZhbGlkYXRlcyB0b29sIHN0cnVjdHVyZVwiLCAoKSA9PiB7XG4gICAgZXhwZWN0KHZhbGlkYXRlRGF0YVRvb2wuaWQpLnRvQmUoXCJ2YWxpZGF0ZS1kYXRhXCIpXG4gICAgZXhwZWN0KHZhbGlkYXRlRGF0YVRvb2wuZGVzY3JpcHRpb24pLnRvQmVUcnV0aHkoKVxuICAgIGV4cGVjdCh2YWxpZGF0ZURhdGFUb29sLmlucHV0U2NoZW1hKS50b0JlVHJ1dGh5KClcbiAgICBleHBlY3QodmFsaWRhdGVEYXRhVG9vbC5vdXRwdXRTY2hlbWEpLnRvQmVUcnV0aHkoKVxuICAgIGV4cGVjdCh2YWxpZGF0ZURhdGFUb29sLmV4ZWN1dGUpLnRvQmVUeXBlT2YoXCJmdW5jdGlvblwiKVxuICB9KVxuXG4gIGl0KFwidmFsaWRhdGVzIGRhdGEgYWdhaW5zdCBzY2hlbWFcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlc291cmNlOiBSZXNvdXJjZSA9IHtcbiAgICAgIGRhdGE6IHsgbmFtZTogXCJ0ZXN0XCIsIGNvdW50OiA1IH0sXG4gICAgICBkYXRhU2NoZW1hOiB7XG4gICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICBuYW1lOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICBjb3VudDogeyB0eXBlOiBcImludGVnZXJcIiB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2YWxpZGF0ZURhdGFUb29sLmV4ZWN1dGU/LihcbiAgICAgIHtcbiAgICAgICAgcmVzb3VyY2UsXG4gICAgICB9LFxuICAgICAge30sXG4gICAgKVxuXG4gICAgZXhwZWN0LmFzc2VydChyZXN1bHQpXG4gICAgZXhwZWN0LmFzc2VydCghKFwiZXJyb3JcIiBpbiByZXN1bHQpKVxuXG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKVxuICAgIGV4cGVjdChyZXN1bHQuZXJyb3JzKS50b0hhdmVMZW5ndGgoMClcbiAgfSlcblxuICBpdChcImRldGVjdHMgaW52YWxpZCBkYXRhXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXNvdXJjZTogUmVzb3VyY2UgPSB7XG4gICAgICBkYXRhOiB7IG5hbWU6IDEyMywgY291bnQ6IFwiaW52YWxpZFwiIH0sXG4gICAgICBkYXRhU2NoZW1hOiB7XG4gICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICBuYW1lOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICBjb3VudDogeyB0eXBlOiBcImludGVnZXJcIiB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2YWxpZGF0ZURhdGFUb29sLmV4ZWN1dGU/LihcbiAgICAgIHtcbiAgICAgICAgcmVzb3VyY2UsXG4gICAgICB9LFxuICAgICAge30sXG4gICAgKVxuXG4gICAgZXhwZWN0LmFzc2VydChyZXN1bHQpXG4gICAgZXhwZWN0LmFzc2VydCghKFwiZXJyb3JcIiBpbiByZXN1bHQpKVxuXG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZShmYWxzZSlcbiAgICBleHBlY3QocmVzdWx0LmVycm9ycy5sZW5ndGgpLnRvQmVHcmVhdGVyVGhhbigwKVxuICAgIGV4cGVjdChyZXN1bHQuZXJyb3JzKS50b0NvbnRhaW5FcXVhbCh7XG4gICAgICB0eXBlOiBcImRhdGFcIixcbiAgICAgIGpzb25Qb2ludGVyOiBcIi9uYW1lXCIsXG4gICAgICBtZXNzYWdlOiBcIm11c3QgYmUgc3RyaW5nXCIsXG4gICAgfSlcbiAgICBleHBlY3QocmVzdWx0LmVycm9ycykudG9Db250YWluRXF1YWwoe1xuICAgICAgdHlwZTogXCJkYXRhXCIsXG4gICAgICBqc29uUG9pbnRlcjogXCIvY291bnRcIixcbiAgICAgIG1lc3NhZ2U6IFwibXVzdCBiZSBpbnRlZ2VyXCIsXG4gICAgfSlcbiAgfSlcblxuICBpdChcInZhbGlkYXRlcyBkYXRhIGZyb20gZmlsZSBwYXRoXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBqc29uRGF0YSA9IHsgbmFtZTogXCJhbGljZVwiLCBhZ2U6IDI1LCBhY3RpdmU6IHRydWUgfVxuICAgIGNvbnN0IGRhdGFQYXRoID0gYXdhaXQgd3JpdGVUZW1wRmlsZShKU09OLnN0cmluZ2lmeShqc29uRGF0YSksIHtcbiAgICAgIGZvcm1hdDogXCJqc29uXCIsXG4gICAgfSlcblxuICAgIGNvbnN0IHJlc291cmNlOiBSZXNvdXJjZSA9IHtcbiAgICAgIGRhdGE6IGRhdGFQYXRoLFxuICAgICAgZGF0YVNjaGVtYToge1xuICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgbmFtZTogeyB0eXBlOiBcInN0cmluZ1wiIH0sXG4gICAgICAgICAgYWdlOiB7IHR5cGU6IFwibnVtYmVyXCIgfSxcbiAgICAgICAgICBhY3RpdmU6IHsgdHlwZTogXCJib29sZWFuXCIgfSxcbiAgICAgICAgfSxcbiAgICAgICAgcmVxdWlyZWQ6IFtcIm5hbWVcIiwgXCJhZ2VcIl0sXG4gICAgICB9LFxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHZhbGlkYXRlRGF0YVRvb2wuZXhlY3V0ZT8uKFxuICAgICAge1xuICAgICAgICByZXNvdXJjZSxcbiAgICAgIH0sXG4gICAgICB7fSxcbiAgICApXG5cbiAgICBleHBlY3QuYXNzZXJ0KHJlc3VsdClcbiAgICBleHBlY3QuYXNzZXJ0KCEoXCJlcnJvclwiIGluIHJlc3VsdCkpXG5cbiAgICBleHBlY3QocmVzdWx0LnZhbGlkKS50b0JlKHRydWUpXG4gICAgZXhwZWN0KHJlc3VsdC5lcnJvcnMpLnRvSGF2ZUxlbmd0aCgwKVxuICB9KVxuXG4gIGl0KFwiZGV0ZWN0cyBpbnZhbGlkIGRhdGEgZnJvbSBmaWxlIHBhdGhcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGpzb25EYXRhID0geyBuYW1lOiBcImFsaWNlXCIsIGFnZTogXCJub3QgYSBudW1iZXJcIiB9XG4gICAgY29uc3QgZGF0YVBhdGggPSBhd2FpdCB3cml0ZVRlbXBGaWxlKEpTT04uc3RyaW5naWZ5KGpzb25EYXRhKSwge1xuICAgICAgZm9ybWF0OiBcImpzb25cIixcbiAgICB9KVxuXG4gICAgY29uc3QgcmVzb3VyY2U6IFJlc291cmNlID0ge1xuICAgICAgZGF0YTogZGF0YVBhdGgsXG4gICAgICBkYXRhU2NoZW1hOiB7XG4gICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICBuYW1lOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICBhZ2U6IHsgdHlwZTogXCJudW1iZXJcIiB9LFxuICAgICAgICB9LFxuICAgICAgICByZXF1aXJlZDogW1wibmFtZVwiLCBcImFnZVwiXSxcbiAgICAgIH0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmFsaWRhdGVEYXRhVG9vbC5leGVjdXRlPy4oXG4gICAgICB7XG4gICAgICAgIHJlc291cmNlLFxuICAgICAgfSxcbiAgICAgIHt9LFxuICAgIClcblxuICAgIGV4cGVjdC5hc3NlcnQocmVzdWx0KVxuICAgIGV4cGVjdC5hc3NlcnQoIShcImVycm9yXCIgaW4gcmVzdWx0KSlcblxuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUoZmFsc2UpXG4gICAgZXhwZWN0KHJlc3VsdC5lcnJvcnMubGVuZ3RoKS50b0JlR3JlYXRlclRoYW4oMClcbiAgfSlcblxuICBpdChcInZhbGlkYXRlcyBkYXRhIHdpdGggbmVzdGVkIG9iamVjdHNcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlc291cmNlOiBSZXNvdXJjZSA9IHtcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgbmFtZTogXCJhbGljZVwiLFxuICAgICAgICBhZGRyZXNzOiB7IGNpdHk6IFwiTmV3IFlvcmtcIiwgemlwOiBcIjEwMDAxXCIgfSxcbiAgICAgIH0sXG4gICAgICBkYXRhU2NoZW1hOiB7XG4gICAgICAgIHR5cGU6IFwib2JqZWN0XCIsXG4gICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICBuYW1lOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICBhZGRyZXNzOiB7XG4gICAgICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICBjaXR5OiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICAgICAgemlwOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmFsaWRhdGVEYXRhVG9vbC5leGVjdXRlPy4oXG4gICAgICB7XG4gICAgICAgIHJlc291cmNlLFxuICAgICAgfSxcbiAgICAgIHt9LFxuICAgIClcblxuICAgIGV4cGVjdC5hc3NlcnQocmVzdWx0KVxuICAgIGV4cGVjdC5hc3NlcnQoIShcImVycm9yXCIgaW4gcmVzdWx0KSlcblxuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUodHJ1ZSlcbiAgICBleHBlY3QocmVzdWx0LmVycm9ycykudG9IYXZlTGVuZ3RoKDApXG4gIH0pXG5cbiAgaXQoXCJ2YWxpZGF0ZXMgZGF0YSB3aXRoIGFycmF5IHR5cGVzXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXNvdXJjZTogUmVzb3VyY2UgPSB7XG4gICAgICBkYXRhOiB7XG4gICAgICAgIHRhZ3M6IFtcImFkbWluXCIsIFwidXNlclwiXSxcbiAgICAgICAgc2NvcmVzOiBbOTUsIDg3LCA5Ml0sXG4gICAgICB9LFxuICAgICAgZGF0YVNjaGVtYToge1xuICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgdGFnczoge1xuICAgICAgICAgICAgdHlwZTogXCJhcnJheVwiLFxuICAgICAgICAgICAgaXRlbXM6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgc2NvcmVzOiB7XG4gICAgICAgICAgICB0eXBlOiBcImFycmF5XCIsXG4gICAgICAgICAgICBpdGVtczogeyB0eXBlOiBcIm51bWJlclwiIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdmFsaWRhdGVEYXRhVG9vbC5leGVjdXRlPy4oXG4gICAgICB7XG4gICAgICAgIHJlc291cmNlLFxuICAgICAgfSxcbiAgICAgIHt9LFxuICAgIClcblxuICAgIGV4cGVjdC5hc3NlcnQocmVzdWx0KVxuICAgIGV4cGVjdC5hc3NlcnQoIShcImVycm9yXCIgaW4gcmVzdWx0KSlcblxuICAgIGV4cGVjdChyZXN1bHQudmFsaWQpLnRvQmUodHJ1ZSlcbiAgICBleHBlY3QocmVzdWx0LmVycm9ycykudG9IYXZlTGVuZ3RoKDApXG4gIH0pXG5cbiAgaXQoXCJyZXR1cm5zIGVycm9yIHdoZW4gbm8gZGF0YSBidXQgc2NoZW1hIGV4cGVjdGVkXCIsIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCByZXNvdXJjZTogUmVzb3VyY2UgPSB7XG4gICAgICBuYW1lOiBcImVtcHR5XCIsXG4gICAgICBkYXRhU2NoZW1hOiB7IHR5cGU6IFwib2JqZWN0XCIgfSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2YWxpZGF0ZURhdGFUb29sLmV4ZWN1dGU/LihcbiAgICAgIHtcbiAgICAgICAgcmVzb3VyY2UsXG4gICAgICB9LFxuICAgICAge30sXG4gICAgKVxuXG4gICAgZXhwZWN0LmFzc2VydChyZXN1bHQpXG4gICAgZXhwZWN0LmFzc2VydCghKFwiZXJyb3JcIiBpbiByZXN1bHQpKVxuXG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZShmYWxzZSlcbiAgICBleHBlY3QocmVzdWx0LmVycm9ycykudG9IYXZlTGVuZ3RoKDEpXG4gICAgZXhwZWN0KHJlc3VsdC5lcnJvcnMpLnRvQ29udGFpbkVxdWFsKHtcbiAgICAgIHR5cGU6IFwicmVzb3VyY2UvdHlwZVwiLFxuICAgICAgZXhwZWN0ZWRSZXNvdXJjZVR5cGU6IFwiZGF0YVwiLFxuICAgIH0pXG4gIH0pXG5cbiAgaXQoXCJ2YWxpZGF0ZXMgZGF0YSB3aXRoIHJlcXVpcmVkIGZpZWxkc1wiLCBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcmVzb3VyY2U6IFJlc291cmNlID0ge1xuICAgICAgZGF0YTogeyBuYW1lOiBcImFsaWNlXCIgfSxcbiAgICAgIGRhdGFTY2hlbWE6IHtcbiAgICAgICAgdHlwZTogXCJvYmplY3RcIixcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIG5hbWU6IHsgdHlwZTogXCJzdHJpbmdcIiB9LFxuICAgICAgICAgIGFnZTogeyB0eXBlOiBcIm51bWJlclwiIH0sXG4gICAgICAgIH0sXG4gICAgICAgIHJlcXVpcmVkOiBbXCJuYW1lXCIsIFwiYWdlXCJdLFxuICAgICAgfSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2YWxpZGF0ZURhdGFUb29sLmV4ZWN1dGU/LihcbiAgICAgIHtcbiAgICAgICAgcmVzb3VyY2UsXG4gICAgICB9LFxuICAgICAge30sXG4gICAgKVxuXG4gICAgZXhwZWN0LmFzc2VydChyZXN1bHQpXG4gICAgZXhwZWN0LmFzc2VydCghKFwiZXJyb3JcIiBpbiByZXN1bHQpKVxuXG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZShmYWxzZSlcbiAgICBleHBlY3QocmVzdWx0LmVycm9ycy5sZW5ndGgpLnRvQmVHcmVhdGVyVGhhbigwKVxuICB9KVxuXG4gIGl0KFwidmFsaWRhdGVzIGFycmF5IGRhdGEgYWdhaW5zdCBzY2hlbWFcIiwgYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IHJlc291cmNlOiBSZXNvdXJjZSA9IHtcbiAgICAgIGRhdGE6IFtcbiAgICAgICAgeyBpZDogMSwgbmFtZTogXCJhbGljZVwiIH0sXG4gICAgICAgIHsgaWQ6IDIsIG5hbWU6IFwiYm9iXCIgfSxcbiAgICAgIF0sXG4gICAgICBkYXRhU2NoZW1hOiB7XG4gICAgICAgIHR5cGU6IFwiYXJyYXlcIixcbiAgICAgICAgaXRlbXM6IHtcbiAgICAgICAgICB0eXBlOiBcIm9iamVjdFwiLFxuICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgIGlkOiB7IHR5cGU6IFwiaW50ZWdlclwiIH0sXG4gICAgICAgICAgICBuYW1lOiB7IHR5cGU6IFwic3RyaW5nXCIgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB2YWxpZGF0ZURhdGFUb29sLmV4ZWN1dGU/LihcbiAgICAgIHtcbiAgICAgICAgcmVzb3VyY2UsXG4gICAgICB9LFxuICAgICAge30sXG4gICAgKVxuXG4gICAgZXhwZWN0LmFzc2VydChyZXN1bHQpXG4gICAgZXhwZWN0LmFzc2VydCghKFwiZXJyb3JcIiBpbiByZXN1bHQpKVxuXG4gICAgZXhwZWN0KHJlc3VsdC52YWxpZCkudG9CZSh0cnVlKVxuICAgIGV4cGVjdChyZXN1bHQuZXJyb3JzKS50b0hhdmVMZW5ndGgoMClcbiAgfSlcbn0pXG4iXX0=