@ultipa-graph/ultipa-driver 5.1.5-s5.2 → 6.0.4

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 (260) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +65 -0
  3. package/dist/client.d.ts +196 -0
  4. package/dist/client.js +394 -0
  5. package/dist/config.d.ts +65 -0
  6. package/dist/config.js +135 -0
  7. package/dist/connection.d.ts +30 -0
  8. package/dist/connection.js +190 -0
  9. package/dist/errors.d.ts +99 -0
  10. package/dist/errors.js +237 -0
  11. package/dist/index.d.ts +14 -5
  12. package/dist/index.js +88 -39
  13. package/dist/printers.d.ts +33 -0
  14. package/dist/printers.js +312 -0
  15. package/dist/proto/gqldb.proto +689 -0
  16. package/dist/response.d.ts +256 -0
  17. package/dist/response.js +723 -0
  18. package/dist/services/admin-service.d.ts +44 -0
  19. package/dist/services/admin-service.js +168 -0
  20. package/dist/services/bulk-import-service.d.ts +35 -0
  21. package/dist/services/bulk-import-service.js +105 -0
  22. package/dist/services/converters.d.ts +57 -0
  23. package/dist/services/converters.js +254 -0
  24. package/dist/services/data-service.d.ts +44 -0
  25. package/dist/services/data-service.js +206 -0
  26. package/dist/services/graph-service.d.ts +32 -0
  27. package/dist/services/graph-service.js +127 -0
  28. package/dist/services/health-service.d.ts +50 -0
  29. package/dist/services/health-service.js +78 -0
  30. package/dist/services/index.d.ts +13 -0
  31. package/dist/services/index.js +30 -0
  32. package/dist/services/query-service.d.ts +39 -0
  33. package/dist/services/query-service.js +112 -0
  34. package/dist/services/service-context.d.ts +39 -0
  35. package/dist/services/service-context.js +73 -0
  36. package/dist/services/session-service.d.ts +24 -0
  37. package/dist/services/session-service.js +66 -0
  38. package/dist/services/transaction-service.d.ts +33 -0
  39. package/dist/services/transaction-service.js +100 -0
  40. package/dist/services.d.ts +28 -0
  41. package/dist/services.js +122 -0
  42. package/dist/session.d.ts +45 -0
  43. package/dist/session.js +75 -0
  44. package/dist/transaction.d.ts +42 -0
  45. package/dist/transaction.js +89 -0
  46. package/dist/types/bulk_import.d.ts +53 -0
  47. package/dist/types/bulk_import.js +6 -0
  48. package/dist/types/data_types.d.ts +116 -0
  49. package/dist/types/data_types.js +122 -0
  50. package/dist/types/enums.d.ts +59 -0
  51. package/dist/types/enums.js +67 -0
  52. package/dist/types/graph_models.d.ts +54 -0
  53. package/dist/types/graph_models.js +6 -0
  54. package/dist/types/index.d.ts +11 -5
  55. package/dist/types/index.js +36 -37
  56. package/dist/types/metadata.d.ts +107 -0
  57. package/dist/types/metadata.js +6 -0
  58. package/dist/types/schema.d.ts +31 -0
  59. package/dist/types/schema.js +6 -0
  60. package/dist/types/typed_value.d.ts +25 -0
  61. package/dist/types/typed_value.js +1176 -0
  62. package/dist/types/wrappers.d.ts +23 -0
  63. package/dist/types/wrappers.js +39 -0
  64. package/dist/types.d.ts +7 -0
  65. package/dist/types.js +24 -0
  66. package/package.json +50 -63
  67. package/dist/connection/connection.final.d.ts +0 -14
  68. package/dist/connection/connection.final.js +0 -94
  69. package/dist/connection/connection.final.js.map +0 -1
  70. package/dist/connection/connection.pool.d.ts +0 -21
  71. package/dist/connection/connection.pool.js +0 -103
  72. package/dist/connection/connection.pool.js.map +0 -1
  73. package/dist/connection/extra/algos/algo.extra.d.ts +0 -34
  74. package/dist/connection/extra/algos/algo.extra.js +0 -69
  75. package/dist/connection/extra/algos/algo.extra.js.map +0 -1
  76. package/dist/connection/extra/algos/algo.utils.d.ts +0 -3
  77. package/dist/connection/extra/algos/algo.utils.js +0 -54
  78. package/dist/connection/extra/algos/algo.utils.js.map +0 -1
  79. package/dist/connection/extra/algos/community.d.ts +0 -27
  80. package/dist/connection/extra/algos/community.js +0 -76
  81. package/dist/connection/extra/algos/community.js.map +0 -1
  82. package/dist/connection/extra/algos/degrees.d.ts +0 -10
  83. package/dist/connection/extra/algos/degrees.js +0 -24
  84. package/dist/connection/extra/algos/degrees.js.map +0 -1
  85. package/dist/connection/extra/algos/embedding.d.ts +0 -13
  86. package/dist/connection/extra/algos/embedding.js +0 -33
  87. package/dist/connection/extra/algos/embedding.js.map +0 -1
  88. package/dist/connection/extra/algos/index.d.ts +0 -5
  89. package/dist/connection/extra/algos/index.js +0 -14
  90. package/dist/connection/extra/algos/index.js.map +0 -1
  91. package/dist/connection/extra/base.extra.d.ts +0 -18
  92. package/dist/connection/extra/base.extra.js +0 -111
  93. package/dist/connection/extra/base.extra.js.map +0 -1
  94. package/dist/connection/extra/batch.insert.extra.d.ts +0 -58
  95. package/dist/connection/extra/batch.insert.extra.js +0 -354
  96. package/dist/connection/extra/batch.insert.extra.js.map +0 -1
  97. package/dist/connection/extra/connection.base.d.ts +0 -112
  98. package/dist/connection/extra/connection.base.js +0 -530
  99. package/dist/connection/extra/connection.base.js.map +0 -1
  100. package/dist/connection/extra/connection.d.ts +0 -17
  101. package/dist/connection/extra/connection.js +0 -44
  102. package/dist/connection/extra/connection.js.map +0 -1
  103. package/dist/connection/extra/graph.extra.d.ts +0 -54
  104. package/dist/connection/extra/graph.extra.js +0 -151
  105. package/dist/connection/extra/graph.extra.js.map +0 -1
  106. package/dist/connection/extra/hdc.extra.d.ts +0 -89
  107. package/dist/connection/extra/hdc.extra.js +0 -322
  108. package/dist/connection/extra/hdc.extra.js.map +0 -1
  109. package/dist/connection/extra/index.extra.d.ts +0 -102
  110. package/dist/connection/extra/index.extra.js +0 -210
  111. package/dist/connection/extra/index.extra.js.map +0 -1
  112. package/dist/connection/extra/job.extra.d.ts +0 -32
  113. package/dist/connection/extra/job.extra.js +0 -122
  114. package/dist/connection/extra/job.extra.js.map +0 -1
  115. package/dist/connection/extra/meta.extra.d.ts +0 -36
  116. package/dist/connection/extra/meta.extra.js +0 -123
  117. package/dist/connection/extra/meta.extra.js.map +0 -1
  118. package/dist/connection/extra/policy.extra.d.ts +0 -32
  119. package/dist/connection/extra/policy.extra.js +0 -114
  120. package/dist/connection/extra/policy.extra.js.map +0 -1
  121. package/dist/connection/extra/privilege.extra.d.ts +0 -8
  122. package/dist/connection/extra/privilege.extra.js +0 -20
  123. package/dist/connection/extra/privilege.extra.js.map +0 -1
  124. package/dist/connection/extra/property.extra.d.ts +0 -66
  125. package/dist/connection/extra/property.extra.js +0 -190
  126. package/dist/connection/extra/property.extra.js.map +0 -1
  127. package/dist/connection/extra/schema.extra.d.ts +0 -108
  128. package/dist/connection/extra/schema.extra.js +0 -253
  129. package/dist/connection/extra/schema.extra.js.map +0 -1
  130. package/dist/connection/extra/search.extra.d.ts +0 -12
  131. package/dist/connection/extra/search.extra.js +0 -117
  132. package/dist/connection/extra/search.extra.js.map +0 -1
  133. package/dist/connection/extra/task.extra.d.ts +0 -24
  134. package/dist/connection/extra/task.extra.js +0 -107
  135. package/dist/connection/extra/task.extra.js.map +0 -1
  136. package/dist/connection/extra/user.extra.d.ts +0 -28
  137. package/dist/connection/extra/user.extra.js +0 -91
  138. package/dist/connection/extra/user.extra.js.map +0 -1
  139. package/dist/connection/extra/user.privilege.extra.d.ts +0 -64
  140. package/dist/connection/extra/user.privilege.extra.js +0 -273
  141. package/dist/connection/extra/user.privilege.extra.js.map +0 -1
  142. package/dist/connection/index.d.ts +0 -5
  143. package/dist/connection/index.js +0 -13
  144. package/dist/connection/index.js.map +0 -1
  145. package/dist/connection/network.manager.d.ts +0 -28
  146. package/dist/connection/network.manager.js +0 -179
  147. package/dist/connection/network.manager.js.map +0 -1
  148. package/dist/index.js.map +0 -1
  149. package/dist/printers/alias.d.ts +0 -2
  150. package/dist/printers/alias.js +0 -39
  151. package/dist/printers/alias.js.map +0 -1
  152. package/dist/printers/any.d.ts +0 -2
  153. package/dist/printers/any.js +0 -63
  154. package/dist/printers/any.js.map +0 -1
  155. package/dist/printers/array.aio.d.ts +0 -3
  156. package/dist/printers/array.aio.js +0 -259
  157. package/dist/printers/array.aio.js.map +0 -1
  158. package/dist/printers/common.d.ts +0 -0
  159. package/dist/printers/common.js +0 -1
  160. package/dist/printers/common.js.map +0 -1
  161. package/dist/printers/edge.d.ts +0 -5
  162. package/dist/printers/edge.js +0 -78
  163. package/dist/printers/edge.js.map +0 -1
  164. package/dist/printers/explain.plan.d.ts +0 -2
  165. package/dist/printers/explain.plan.js +0 -46
  166. package/dist/printers/explain.plan.js.map +0 -1
  167. package/dist/printers/index.d.ts +0 -24
  168. package/dist/printers/index.js +0 -43
  169. package/dist/printers/index.js.map +0 -1
  170. package/dist/printers/node.d.ts +0 -5
  171. package/dist/printers/node.js +0 -77
  172. package/dist/printers/node.js.map +0 -1
  173. package/dist/printers/path.d.ts +0 -3
  174. package/dist/printers/path.js +0 -62
  175. package/dist/printers/path.js.map +0 -1
  176. package/dist/printers/status.d.ts +0 -3
  177. package/dist/printers/status.js +0 -68
  178. package/dist/printers/status.js.map +0 -1
  179. package/dist/printers/table.d.ts +0 -2
  180. package/dist/printers/table.js +0 -56
  181. package/dist/printers/table.js.map +0 -1
  182. package/dist/proto/tmp.js +0 -366
  183. package/dist/proto/ultipa_grpc_pb.d.ts +0 -258
  184. package/dist/proto/ultipa_grpc_pb.js +0 -366
  185. package/dist/proto/ultipa_grpc_pb.js.map +0 -1
  186. package/dist/proto/ultipa_pb.d.ts +0 -1
  187. package/dist/proto/ultipa_pb.js +0 -12119
  188. package/dist/proto/ultipa_pb.js.map +0 -1
  189. package/dist/types/index.js.map +0 -1
  190. package/dist/types/types.algos.params.d.ts +0 -545
  191. package/dist/types/types.algos.params.js +0 -16
  192. package/dist/types/types.algos.params.js.map +0 -1
  193. package/dist/types/types.d.ts +0 -1214
  194. package/dist/types/types.extra.d.ts +0 -146
  195. package/dist/types/types.extra.js +0 -27
  196. package/dist/types/types.extra.js.map +0 -1
  197. package/dist/types/types.js +0 -1606
  198. package/dist/types/types.js.map +0 -1
  199. package/dist/types/util.d.ts +0 -15
  200. package/dist/types/util.js +0 -136
  201. package/dist/types/util.js.map +0 -1
  202. package/dist/utils/common.d.ts +0 -3
  203. package/dist/utils/common.js +0 -22
  204. package/dist/utils/common.js.map +0 -1
  205. package/dist/utils/config.d.ts +0 -3
  206. package/dist/utils/config.js +0 -7
  207. package/dist/utils/config.js.map +0 -1
  208. package/dist/utils/format.d.ts +0 -45
  209. package/dist/utils/format.js +0 -879
  210. package/dist/utils/format.js.map +0 -1
  211. package/dist/utils/index.d.ts +0 -10
  212. package/dist/utils/index.js +0 -30
  213. package/dist/utils/index.js.map +0 -1
  214. package/dist/utils/params.validate.d.ts +0 -4
  215. package/dist/utils/params.validate.js +0 -14
  216. package/dist/utils/params.validate.js.map +0 -1
  217. package/dist/utils/property.d.ts +0 -24
  218. package/dist/utils/property.js +0 -203
  219. package/dist/utils/property.js.map +0 -1
  220. package/dist/utils/raft.retry.d.ts +0 -0
  221. package/dist/utils/raft.retry.js +0 -1
  222. package/dist/utils/raft.retry.js.map +0 -1
  223. package/dist/utils/serialize/commont.d.ts +0 -12
  224. package/dist/utils/serialize/commont.js +0 -46
  225. package/dist/utils/serialize/commont.js.map +0 -1
  226. package/dist/utils/serialize/deserialize.d.ts +0 -10
  227. package/dist/utils/serialize/deserialize.js +0 -288
  228. package/dist/utils/serialize/deserialize.js.map +0 -1
  229. package/dist/utils/serialize/null.d.ts +0 -32
  230. package/dist/utils/serialize/null.js +0 -178
  231. package/dist/utils/serialize/null.js.map +0 -1
  232. package/dist/utils/serialize/serialize.d.ts +0 -10
  233. package/dist/utils/serialize/serialize.js +0 -146
  234. package/dist/utils/serialize/serialize.js.map +0 -1
  235. package/dist/utils/stream.helper.d.ts +0 -10
  236. package/dist/utils/stream.helper.js +0 -71
  237. package/dist/utils/stream.helper.js.map +0 -1
  238. package/dist/utils/time.record.d.ts +0 -15
  239. package/dist/utils/time.record.js +0 -52
  240. package/dist/utils/time.record.js.map +0 -1
  241. package/dist/utils/timezone.d.ts +0 -7
  242. package/dist/utils/timezone.js +0 -21
  243. package/dist/utils/timezone.js.map +0 -1
  244. package/dist/utils/ultipa.datetime.d.ts +0 -14
  245. package/dist/utils/ultipa.datetime.js +0 -160
  246. package/dist/utils/ultipa.datetime.js.map +0 -1
  247. package/dist/utils/uql-maker.d.ts +0 -165
  248. package/dist/utils/uql-maker.js +0 -402
  249. package/dist/utils/uql-maker.js.map +0 -1
  250. package/dist/utils/uql.parse.d.ts +0 -27
  251. package/dist/utils/uql.parse.js +0 -205
  252. package/dist/utils/uql.parse.js.map +0 -1
  253. package/readme.md +0 -65
  254. package/src/proto/build.sh +0 -41
  255. package/src/proto/build_windows.sh +0 -40
  256. package/src/proto/ultipa.proto +0 -531
  257. package/src/proto/ultipa_grpc_pb.d.ts +0 -92
  258. package/src/proto/ultipa_grpc_pb.js +0 -414
  259. package/src/proto/ultipa_pb.d.ts +0 -1983
  260. package/src/proto/ultipa_pb.js +0 -14852
@@ -0,0 +1,723 @@
1
+ "use strict";
2
+ /**
3
+ * Response handling for GQLDB Node.js driver.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Response = exports.AliasResult = exports.Row = void 0;
7
+ const types_1 = require("./types");
8
+ /** Represents a single row in the query result */
9
+ class Row {
10
+ values;
11
+ types;
12
+ constructor(values, types = []) {
13
+ this.values = values;
14
+ this.types = types;
15
+ }
16
+ /** Get the value at the given column index */
17
+ get(index) {
18
+ if (index < 0 || index >= this.values.length) {
19
+ throw new Error(`Column index out of range: ${index}`);
20
+ }
21
+ const value = this.values[index];
22
+ // If value is a TypedValue object, convert it
23
+ if (value && typeof value === 'object' && 'type' in value && 'data' in value && 'isNull' in value) {
24
+ return (0, types_1.typedValueToJS)(value);
25
+ }
26
+ return value;
27
+ }
28
+ /** Get the PropertyType at the given column index */
29
+ getType(index) {
30
+ if (index < 0 || index >= this.types.length) {
31
+ return types_1.PropertyType.UNSET;
32
+ }
33
+ return this.types[index];
34
+ }
35
+ /** Get the value at the given column index as a string */
36
+ getString(index) {
37
+ const val = this.get(index);
38
+ if (val === null || val === undefined)
39
+ return '';
40
+ if (typeof val === 'string')
41
+ return val;
42
+ return String(val);
43
+ }
44
+ /** Get the value at the given column index as a number */
45
+ getNumber(index) {
46
+ const val = this.get(index);
47
+ if (val === null || val === undefined)
48
+ return 0;
49
+ if (typeof val === 'number')
50
+ return val;
51
+ const num = Number(val);
52
+ if (isNaN(num))
53
+ throw new Error(`Cannot convert ${typeof val} to number`);
54
+ return num;
55
+ }
56
+ /** Get the value at the given column index as a boolean */
57
+ getBoolean(index) {
58
+ const val = this.get(index);
59
+ if (val === null || val === undefined)
60
+ return false;
61
+ if (typeof val === 'boolean')
62
+ return val;
63
+ throw new Error(`Cannot convert ${typeof val} to boolean`);
64
+ }
65
+ }
66
+ exports.Row = Row;
67
+ /**
68
+ * Represents a single column's data from the response.
69
+ * Allows chaining operations like resp.alias("n").asNodes() or resp.get(0).asNodes().
70
+ */
71
+ class AliasResult {
72
+ aliasName;
73
+ columnIdx;
74
+ response;
75
+ constructor(aliasName, columnIdx, response) {
76
+ this.aliasName = aliasName;
77
+ this.columnIdx = columnIdx;
78
+ this.response = response;
79
+ }
80
+ /** Get the alias name */
81
+ get alias() {
82
+ return this.aliasName;
83
+ }
84
+ /** Get the column index */
85
+ get columnIndex() {
86
+ return this.columnIdx;
87
+ }
88
+ /**
89
+ * Extract nodes from the aliased column with schema info.
90
+ * Throws TypeError if the column contains non-NODE types.
91
+ */
92
+ collectNode(val, nodes, schemas) {
93
+ if (val && typeof val.id === 'string' && 'labels' in val) {
94
+ const node = {
95
+ id: val.id,
96
+ labels: val.labels || [],
97
+ properties: val.properties || {},
98
+ };
99
+ nodes.push(node);
100
+ for (const label of node.labels) {
101
+ if (!schemas.has(label)) {
102
+ schemas.set(label, this.buildSchemaFromNode(label, node));
103
+ }
104
+ }
105
+ }
106
+ }
107
+ collectEdge(val, edges, schemas) {
108
+ if (val && typeof val.id === 'string' && 'label' in val) {
109
+ const edge = {
110
+ id: val.id,
111
+ label: val.label || '',
112
+ fromNodeId: val.fromNodeId || '',
113
+ toNodeId: val.toNodeId || '',
114
+ properties: val.properties || {},
115
+ };
116
+ edges.push(edge);
117
+ if (edge.label && !schemas.has(edge.label)) {
118
+ schemas.set(edge.label, this.buildSchemaFromEdge(edge.label, edge));
119
+ }
120
+ }
121
+ }
122
+ /**
123
+ * Extract nodes from the aliased column with schema info.
124
+ * Supports both direct NODE columns and LIST of NODE columns
125
+ * (e.g., group variables from quantified patterns).
126
+ */
127
+ asNodes() {
128
+ const nodes = [];
129
+ const schemas = new Map();
130
+ for (const row of this.response.rows) {
131
+ if (this.columnIdx >= row.values.length) {
132
+ continue;
133
+ }
134
+ let itemType = row.getType(this.columnIdx);
135
+ const rawValue = row.values[this.columnIdx];
136
+ if (itemType === types_1.PropertyType.UNSET && rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
137
+ itemType = rawValue.type;
138
+ }
139
+ if (!rawValue || (typeof rawValue === 'object' && 'isNull' in rawValue && rawValue.isNull)) {
140
+ continue;
141
+ }
142
+ if (itemType === types_1.PropertyType.NODE) {
143
+ this.collectNode(row.get(this.columnIdx), nodes, schemas);
144
+ }
145
+ else if (itemType === types_1.PropertyType.LIST) {
146
+ // LIST of NODE (group variable from quantified pattern)
147
+ const list = row.get(this.columnIdx);
148
+ if (Array.isArray(list)) {
149
+ for (const item of list) {
150
+ this.collectNode(item, nodes, schemas);
151
+ }
152
+ }
153
+ }
154
+ else {
155
+ throw new TypeError(`Type mismatch: column '${this.aliasName}' (index ${this.columnIdx}) contains ${types_1.PropertyType[itemType]}, expected NODE or LIST of NODE`);
156
+ }
157
+ }
158
+ return { nodes, schemas };
159
+ }
160
+ /**
161
+ * Extract edges from the aliased column with schema info.
162
+ * Supports both direct EDGE columns and LIST of EDGE columns
163
+ * (e.g., group variables from quantified patterns).
164
+ */
165
+ asEdges() {
166
+ const edges = [];
167
+ const schemas = new Map();
168
+ for (const row of this.response.rows) {
169
+ if (this.columnIdx >= row.values.length) {
170
+ continue;
171
+ }
172
+ let itemType = row.getType(this.columnIdx);
173
+ const rawValue = row.values[this.columnIdx];
174
+ if (itemType === types_1.PropertyType.UNSET && rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
175
+ itemType = rawValue.type;
176
+ }
177
+ if (!rawValue || (typeof rawValue === 'object' && 'isNull' in rawValue && rawValue.isNull)) {
178
+ continue;
179
+ }
180
+ if (itemType === types_1.PropertyType.EDGE) {
181
+ this.collectEdge(row.get(this.columnIdx), edges, schemas);
182
+ }
183
+ else if (itemType === types_1.PropertyType.LIST) {
184
+ // LIST of EDGE (group variable from quantified pattern)
185
+ const list = row.get(this.columnIdx);
186
+ if (Array.isArray(list)) {
187
+ for (const item of list) {
188
+ this.collectEdge(item, edges, schemas);
189
+ }
190
+ }
191
+ }
192
+ else {
193
+ throw new TypeError(`Type mismatch: column '${this.aliasName}' (index ${this.columnIdx}) contains ${types_1.PropertyType[itemType]}, expected EDGE or LIST of EDGE`);
194
+ }
195
+ }
196
+ return { edges, schemas };
197
+ }
198
+ /**
199
+ * Extract paths from the aliased column.
200
+ * Throws TypeError if the column contains non-PATH types.
201
+ */
202
+ asPaths() {
203
+ const paths = [];
204
+ for (const row of this.response.rows) {
205
+ if (this.columnIdx >= row.values.length) {
206
+ continue;
207
+ }
208
+ // Check type from types array or from TypedValue object
209
+ let itemType = row.getType(this.columnIdx);
210
+ const rawValue = row.values[this.columnIdx];
211
+ if (itemType === types_1.PropertyType.UNSET && rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
212
+ itemType = rawValue.type;
213
+ }
214
+ // Skip null values
215
+ if (!rawValue || (typeof rawValue === 'object' && 'isNull' in rawValue && rawValue.isNull)) {
216
+ continue;
217
+ }
218
+ // Type checking: must be PATH type
219
+ if (itemType !== types_1.PropertyType.PATH) {
220
+ throw new TypeError(`Type mismatch: column '${this.aliasName}' (index ${this.columnIdx}) contains ${types_1.PropertyType[itemType]}, expected PATH`);
221
+ }
222
+ // Convert TypedValue to GqldbPath
223
+ const val = row.get(this.columnIdx);
224
+ if (val && Array.isArray(val.nodes)) {
225
+ // Convert GqldbNode/GqldbEdge to Node/Edge
226
+ const nodes = (val.nodes || []).map((n) => ({
227
+ id: n.id || '',
228
+ labels: n.labels || [],
229
+ properties: n.properties || {},
230
+ }));
231
+ const edges = (val.edges || []).map((e) => ({
232
+ id: e.id || '',
233
+ label: e.label || '',
234
+ fromNodeId: e.fromNodeId || '',
235
+ toNodeId: e.toNodeId || '',
236
+ properties: e.properties || {},
237
+ }));
238
+ paths.push({ nodes, edges });
239
+ }
240
+ }
241
+ return paths;
242
+ }
243
+ /** Convert the aliased column to a single-column table */
244
+ asTable() {
245
+ // Check if first non-null value is a GqldbTable — if so, unwrap it
246
+ for (const row of this.response.rows) {
247
+ if (this.columnIdx < row.values.length) {
248
+ const itemType = row.getType(this.columnIdx);
249
+ if (itemType === types_1.PropertyType.TABLE) {
250
+ const val = row.get(this.columnIdx);
251
+ if (val && 'columns' in val && 'rows' in val) {
252
+ return this.unwrapGqldbTable(val);
253
+ }
254
+ }
255
+ }
256
+ break; // only check first row
257
+ }
258
+ // Fallback: generic single-column table
259
+ const headers = [{
260
+ name: this.aliasName,
261
+ type: types_1.PropertyType.UNSET,
262
+ }];
263
+ if (this.response.rows.length > 0) {
264
+ for (const row of this.response.rows) {
265
+ if (this.columnIdx < row.values.length) {
266
+ const type = row.getType(this.columnIdx);
267
+ if (type !== types_1.PropertyType.UNSET) {
268
+ headers[0].type = type;
269
+ break;
270
+ }
271
+ }
272
+ }
273
+ }
274
+ const tableRows = this.response.rows.map(row => {
275
+ if (this.columnIdx < row.values.length) {
276
+ return [row.get(this.columnIdx)];
277
+ }
278
+ return [null];
279
+ });
280
+ return { name: '', headers, rows: tableRows };
281
+ }
282
+ unwrapGqldbTable(gt) {
283
+ const headers = gt.columns.map((col, i) => {
284
+ let colType = types_1.PropertyType.UNSET;
285
+ if (gt.rows.length > 0 && i < gt.rows[0].length) {
286
+ const v = gt.rows[0][i];
287
+ if (typeof v === 'number')
288
+ colType = Number.isInteger(v) ? types_1.PropertyType.INT64 : types_1.PropertyType.DOUBLE;
289
+ else if (typeof v === 'string')
290
+ colType = types_1.PropertyType.STRING;
291
+ else if (typeof v === 'boolean')
292
+ colType = types_1.PropertyType.BOOL;
293
+ }
294
+ return { name: col, type: colType };
295
+ });
296
+ return { name: this.aliasName, headers, rows: gt.rows };
297
+ }
298
+ /** Extract scalar or list attribute values from the aliased column */
299
+ asAttr() {
300
+ const values = [];
301
+ let attrType = types_1.PropertyType.UNSET;
302
+ for (const row of this.response.rows) {
303
+ if (this.columnIdx < row.values.length) {
304
+ // Try to get type from row.types first, then from TypedValue object
305
+ if (attrType === types_1.PropertyType.UNSET) {
306
+ attrType = row.getType(this.columnIdx);
307
+ if (attrType === types_1.PropertyType.UNSET) {
308
+ const rawValue = row.values[this.columnIdx];
309
+ if (rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
310
+ attrType = rawValue.type;
311
+ }
312
+ }
313
+ }
314
+ const value = row.get(this.columnIdx); // Use get() to convert TypedValue
315
+ values.push(value);
316
+ }
317
+ }
318
+ return { name: this.aliasName, type: attrType, values };
319
+ }
320
+ /** Extract raw JavaScript values from the aliased column */
321
+ asValues() {
322
+ const values = [];
323
+ for (const row of this.response.rows) {
324
+ if (this.columnIdx < row.values.length) {
325
+ values.push(row.get(this.columnIdx));
326
+ }
327
+ }
328
+ return values;
329
+ }
330
+ // Helper methods
331
+ buildSchemaFromNode(label, node) {
332
+ const properties = Object.entries(node.properties).map(([name, value]) => ({
333
+ name,
334
+ type: this.inferPropertyType(value),
335
+ }));
336
+ return { name: label, properties };
337
+ }
338
+ buildSchemaFromEdge(label, edge) {
339
+ const properties = Object.entries(edge.properties).map(([name, value]) => ({
340
+ name,
341
+ type: this.inferPropertyType(value),
342
+ }));
343
+ return { name: label, properties };
344
+ }
345
+ inferPropertyType(value) {
346
+ if (value === null || value === undefined)
347
+ return types_1.PropertyType.NULL;
348
+ if (typeof value === 'boolean')
349
+ return types_1.PropertyType.BOOL;
350
+ if (typeof value === 'number') {
351
+ return Number.isInteger(value) ? types_1.PropertyType.INT64 : types_1.PropertyType.DOUBLE;
352
+ }
353
+ if (typeof value === 'string')
354
+ return types_1.PropertyType.STRING;
355
+ if (Buffer.isBuffer(value))
356
+ return types_1.PropertyType.BLOB;
357
+ if (Array.isArray(value))
358
+ return types_1.PropertyType.LIST;
359
+ if (typeof value === 'object')
360
+ return types_1.PropertyType.MAP;
361
+ return types_1.PropertyType.UNSET;
362
+ }
363
+ }
364
+ exports.AliasResult = AliasResult;
365
+ /** Represents the result of a GQL query */
366
+ class Response {
367
+ columns;
368
+ rows;
369
+ rowCount;
370
+ hasMore;
371
+ warnings;
372
+ rowsAffected;
373
+ constructor(columns, rows, rowCount, hasMore, warnings, rowsAffected = 0) {
374
+ this.columns = columns;
375
+ this.rows = rows;
376
+ this.rowCount = rowCount;
377
+ this.hasMore = hasMore;
378
+ this.warnings = warnings;
379
+ this.rowsAffected = rowsAffected;
380
+ }
381
+ /** Check if the response has no rows */
382
+ isEmpty() {
383
+ return this.rows.length === 0;
384
+ }
385
+ /** Get the first row */
386
+ first() {
387
+ return this.rows[0];
388
+ }
389
+ /** Get the last row */
390
+ last() {
391
+ return this.rows[this.rows.length - 1];
392
+ }
393
+ /** Get the value for a column by name */
394
+ getByName(row, columnName) {
395
+ const index = this.columns.indexOf(columnName);
396
+ if (index === -1) {
397
+ throw new Error(`Column not found: ${columnName}`);
398
+ }
399
+ return row.get(index);
400
+ }
401
+ /** Iterate over all rows with a callback */
402
+ forEach(fn) {
403
+ this.rows.forEach(fn);
404
+ }
405
+ /** Transform each row using a callback */
406
+ map(fn) {
407
+ return this.rows.map(fn);
408
+ }
409
+ /** Convert the response to an array of objects */
410
+ toObjects() {
411
+ return this.rows.map(row => {
412
+ const obj = {};
413
+ this.columns.forEach((col, i) => {
414
+ // Add boundary check to handle mismatched columns/values
415
+ obj[col] = i < row.values.length ? row.get(i) : null;
416
+ });
417
+ return obj;
418
+ });
419
+ }
420
+ /** Convert the response to JSON */
421
+ toJSON() {
422
+ return JSON.stringify(this.toObjects());
423
+ }
424
+ /** Get the single value from a single-row, single-column response */
425
+ singleValue() {
426
+ if (this.rows.length === 0)
427
+ return null;
428
+ if (this.rows.length > 1) {
429
+ throw new Error(`Expected single row, got ${this.rows.length}`);
430
+ }
431
+ if (this.rows[0].values.length === 0)
432
+ return null;
433
+ if (this.rows[0].values.length > 1) {
434
+ throw new Error(`Expected single column, got ${this.rows[0].values.length}`);
435
+ }
436
+ return this.rows[0].get(0);
437
+ }
438
+ /** Get the single number value */
439
+ singleNumber() {
440
+ const val = this.singleValue();
441
+ if (val === null || val === undefined)
442
+ return 0;
443
+ if (typeof val === 'number')
444
+ return val;
445
+ const num = Number(val);
446
+ if (isNaN(num))
447
+ throw new Error(`Cannot convert ${typeof val} to number`);
448
+ return num;
449
+ }
450
+ /** Get the single string value */
451
+ singleString() {
452
+ const val = this.singleValue();
453
+ if (val === null || val === undefined)
454
+ return '';
455
+ if (typeof val === 'string')
456
+ return val;
457
+ return String(val);
458
+ }
459
+ /** Iterator support */
460
+ [Symbol.iterator]() {
461
+ return this.rows[Symbol.iterator]();
462
+ }
463
+ /** Get the number of rows */
464
+ get length() {
465
+ return this.rows.length;
466
+ }
467
+ /**
468
+ * Get an AliasResult for the specified column name.
469
+ * Use this to extract data from a specific column by name.
470
+ * Example: resp.alias("n").asNodes()
471
+ */
472
+ alias(columnName) {
473
+ const colIdx = this.columns.indexOf(columnName);
474
+ if (colIdx === -1) {
475
+ throw new Error(`Column alias not found: ${columnName}`);
476
+ }
477
+ return new AliasResult(columnName, colIdx, this);
478
+ }
479
+ /**
480
+ * Get an AliasResult for the column at the specified index.
481
+ * Use this to extract data from a specific column by index.
482
+ * Example: resp.get(0).asNodes()
483
+ */
484
+ get(index) {
485
+ if (index < 0 || index >= this.columns.length) {
486
+ throw new Error(`Column index out of range: ${index} (total: ${this.columns.length})`);
487
+ }
488
+ return new AliasResult(this.columns[index], index, this);
489
+ }
490
+ /**
491
+ * @deprecated Use alias() or get() instead. This method will be removed in a future version.
492
+ * Extract nodes from response with schema info.
493
+ * Supports both NODE and LIST of NODE columns.
494
+ */
495
+ asNodes() {
496
+ const nodes = [];
497
+ const schemas = new Map();
498
+ const collectNode = (val) => {
499
+ if (val && typeof val.id === 'string' && 'labels' in val) {
500
+ const node = {
501
+ id: val.id,
502
+ labels: val.labels || [],
503
+ properties: val.properties || {},
504
+ };
505
+ nodes.push(node);
506
+ for (const label of node.labels) {
507
+ if (!schemas.has(label)) {
508
+ schemas.set(label, this.buildSchemaFromNode(label, node));
509
+ }
510
+ }
511
+ }
512
+ };
513
+ for (const row of this.rows) {
514
+ for (let i = 0; i < row.values.length; i++) {
515
+ let itemType = row.getType(i);
516
+ const rawValue = row.values[i];
517
+ if (itemType === types_1.PropertyType.UNSET && rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
518
+ itemType = rawValue.type;
519
+ }
520
+ if (itemType === types_1.PropertyType.NODE) {
521
+ collectNode(row.get(i));
522
+ }
523
+ else if (itemType === types_1.PropertyType.LIST) {
524
+ const list = row.get(i);
525
+ if (Array.isArray(list)) {
526
+ for (const item of list) {
527
+ collectNode(item);
528
+ }
529
+ }
530
+ }
531
+ }
532
+ }
533
+ return { nodes, schemas };
534
+ }
535
+ /**
536
+ * @deprecated Use alias() or get() instead. This method will be removed in a future version.
537
+ * Extract edges from response with schema info.
538
+ * Supports both EDGE and LIST of EDGE columns.
539
+ */
540
+ asEdges() {
541
+ const edges = [];
542
+ const schemas = new Map();
543
+ const collectEdge = (val) => {
544
+ if (val && typeof val.id === 'string' && 'label' in val) {
545
+ const edge = {
546
+ id: val.id,
547
+ label: val.label || '',
548
+ fromNodeId: val.fromNodeId || '',
549
+ toNodeId: val.toNodeId || '',
550
+ properties: val.properties || {},
551
+ };
552
+ edges.push(edge);
553
+ if (edge.label && !schemas.has(edge.label)) {
554
+ schemas.set(edge.label, this.buildSchemaFromEdge(edge.label, edge));
555
+ }
556
+ }
557
+ };
558
+ for (const row of this.rows) {
559
+ for (let i = 0; i < row.values.length; i++) {
560
+ let itemType = row.getType(i);
561
+ const rawValue = row.values[i];
562
+ if (itemType === types_1.PropertyType.UNSET && rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
563
+ itemType = rawValue.type;
564
+ }
565
+ if (itemType === types_1.PropertyType.EDGE) {
566
+ collectEdge(row.get(i));
567
+ }
568
+ else if (itemType === types_1.PropertyType.LIST) {
569
+ const list = row.get(i);
570
+ if (Array.isArray(list)) {
571
+ for (const item of list) {
572
+ collectEdge(item);
573
+ }
574
+ }
575
+ }
576
+ }
577
+ }
578
+ return { edges, schemas };
579
+ }
580
+ /**
581
+ * @deprecated Use alias() or get() instead. This method will be removed in a future version.
582
+ * Extract paths from response.
583
+ * Paths are identified by PropertyType.PATH type in the TypedValue.
584
+ */
585
+ asPaths() {
586
+ const paths = [];
587
+ for (const row of this.rows) {
588
+ for (let i = 0; i < row.values.length; i++) {
589
+ // Check type from types array or from TypedValue object
590
+ let itemType = row.getType(i);
591
+ const rawValue = row.values[i];
592
+ if (itemType === types_1.PropertyType.UNSET && rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
593
+ itemType = rawValue.type;
594
+ }
595
+ if (itemType === types_1.PropertyType.PATH) {
596
+ // Convert TypedValue to GqldbPath
597
+ const val = row.get(i);
598
+ if (val && Array.isArray(val.nodes)) {
599
+ // Convert GqldbNode/GqldbEdge to Node/Edge
600
+ const nodes = (val.nodes || []).map((n) => ({
601
+ id: n.id || '',
602
+ labels: n.labels || [],
603
+ properties: n.properties || {},
604
+ }));
605
+ const edges = (val.edges || []).map((e) => ({
606
+ id: e.id || '',
607
+ label: e.label || '',
608
+ fromNodeId: e.fromNodeId || '',
609
+ toNodeId: e.toNodeId || '',
610
+ properties: e.properties || {},
611
+ }));
612
+ paths.push({ nodes, edges });
613
+ }
614
+ }
615
+ }
616
+ }
617
+ return paths;
618
+ }
619
+ /**
620
+ * @deprecated Use alias() or get() instead. This method will be removed in a future version.
621
+ * Return response as generic table.
622
+ * If response is a single TABLE column, unwraps the GqldbTable into proper headers/rows.
623
+ */
624
+ asTable() {
625
+ // If single column of TABLE type, unwrap GqldbTable
626
+ if (this.columns.length === 1 && this.rows.length > 0) {
627
+ const itemType = this.rows[0].getType(0);
628
+ if (itemType === types_1.PropertyType.TABLE) {
629
+ const val = this.rows[0].get(0);
630
+ if (val && 'columns' in val && 'rows' in val) {
631
+ const gt = val;
632
+ const headers = gt.columns.map((col, i) => {
633
+ let colType = types_1.PropertyType.UNSET;
634
+ if (gt.rows.length > 0 && i < gt.rows[0].length) {
635
+ const v = gt.rows[0][i];
636
+ if (typeof v === 'number')
637
+ colType = Number.isInteger(v) ? types_1.PropertyType.INT64 : types_1.PropertyType.DOUBLE;
638
+ else if (typeof v === 'string')
639
+ colType = types_1.PropertyType.STRING;
640
+ else if (typeof v === 'boolean')
641
+ colType = types_1.PropertyType.BOOL;
642
+ }
643
+ return { name: col, type: colType };
644
+ });
645
+ return { name: this.columns[0], headers, rows: gt.rows };
646
+ }
647
+ }
648
+ }
649
+ // Fallback: generic multi-column table
650
+ const headers = this.columns.map(col => ({
651
+ name: col,
652
+ type: types_1.PropertyType.UNSET,
653
+ }));
654
+ const tableRows = this.rows.map(row => {
655
+ return this.columns.map((_, i) => (i < row.values.length ? row.get(i) : null));
656
+ });
657
+ return { name: '', headers, rows: tableRows };
658
+ }
659
+ /**
660
+ * @deprecated Use alias() or get() instead. This method will be removed in a future version.
661
+ * Extract scalar or list attribute values
662
+ */
663
+ asAttr(columnName) {
664
+ const colIndex = this.columns.indexOf(columnName);
665
+ if (colIndex === -1) {
666
+ throw new Error(`Column not found: ${columnName}`);
667
+ }
668
+ const values = [];
669
+ let attrType = types_1.PropertyType.UNSET;
670
+ for (const row of this.rows) {
671
+ if (colIndex < row.values.length) {
672
+ // Try to get type from row.types first, then from TypedValue object
673
+ if (attrType === types_1.PropertyType.UNSET) {
674
+ attrType = row.getType(colIndex);
675
+ if (attrType === types_1.PropertyType.UNSET) {
676
+ const rawValue = row.values[colIndex];
677
+ if (rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
678
+ attrType = rawValue.type;
679
+ }
680
+ }
681
+ }
682
+ const value = row.get(colIndex); // Use get() to convert TypedValue
683
+ values.push(value);
684
+ }
685
+ }
686
+ return { name: columnName, type: attrType, values };
687
+ }
688
+ // Helper methods
689
+ buildSchemaFromNode(label, node) {
690
+ const properties = Object.entries(node.properties).map(([name, value]) => ({
691
+ name,
692
+ type: this.inferPropertyType(value),
693
+ }));
694
+ return { name: label, properties };
695
+ }
696
+ buildSchemaFromEdge(label, edge) {
697
+ const properties = Object.entries(edge.properties).map(([name, value]) => ({
698
+ name,
699
+ type: this.inferPropertyType(value),
700
+ }));
701
+ return { name: label, properties };
702
+ }
703
+ inferPropertyType(value) {
704
+ if (value === null || value === undefined)
705
+ return types_1.PropertyType.NULL;
706
+ if (typeof value === 'boolean')
707
+ return types_1.PropertyType.BOOL;
708
+ if (typeof value === 'number') {
709
+ return Number.isInteger(value) ? types_1.PropertyType.INT64 : types_1.PropertyType.DOUBLE;
710
+ }
711
+ if (typeof value === 'string')
712
+ return types_1.PropertyType.STRING;
713
+ if (Buffer.isBuffer(value))
714
+ return types_1.PropertyType.BLOB;
715
+ if (Array.isArray(value))
716
+ return types_1.PropertyType.LIST;
717
+ if (typeof value === 'object')
718
+ return types_1.PropertyType.MAP;
719
+ return types_1.PropertyType.UNSET;
720
+ }
721
+ }
722
+ exports.Response = Response;
723
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzcG9uc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcmVzcG9uc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOztHQUVHOzs7QUFFSCxtQ0FBOEk7QUFFOUksa0RBQWtEO0FBQ2xELE1BQWEsR0FBRztJQUVJO0lBQ0E7SUFGbEIsWUFDa0IsTUFBYSxFQUNiLFFBQXdCLEVBQUU7UUFEMUIsV0FBTSxHQUFOLE1BQU0sQ0FBTztRQUNiLFVBQUssR0FBTCxLQUFLLENBQXFCO0lBQ3pDLENBQUM7SUFFSiw4Q0FBOEM7SUFDOUMsR0FBRyxDQUFDLEtBQWE7UUFDZixJQUFJLEtBQUssR0FBRyxDQUFDLElBQUksS0FBSyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDN0MsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN6RCxDQUFDO1FBQ0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqQyw4Q0FBOEM7UUFDOUMsSUFBSSxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLE1BQU0sSUFBSSxLQUFLLElBQUksTUFBTSxJQUFJLEtBQUssSUFBSSxRQUFRLElBQUksS0FBSyxFQUFFLENBQUM7WUFDbEcsT0FBTyxJQUFBLHNCQUFjLEVBQUMsS0FBbUIsQ0FBQyxDQUFDO1FBQzdDLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxxREFBcUQ7SUFDckQsT0FBTyxDQUFDLEtBQWE7UUFDbkIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxJQUFJLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzVDLE9BQU8sb0JBQVksQ0FBQyxLQUFLLENBQUM7UUFDNUIsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJ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LElBQUksRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN4RixJQUFJO1lBQ0osSUFBSSxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUM7U0FDcEMsQ0FBQyxDQUFDLENBQUM7UUFDSixPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsQ0FBQztJQUNyQyxDQUFDO0lBRU8saUJBQWlCLENBQUMsS0FBVTtRQUNsQyxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxLQUFLLFNBQVM7WUFBRSxPQUFPLG9CQUFZLENBQUMsSUFBSSxDQUFDO1FBQ3BFLElBQUksT0FBTyxLQUFLLEtBQUssU0FBUztZQUFFLE9BQU8sb0JBQVksQ0FBQyxJQUFJLENBQUM7UUFDekQsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUM5QixPQUFPLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLG9CQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxvQkFBWSxDQUFDLE1BQU0sQ0FBQztRQUM1RSxDQUFDO1FBQ0QsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1lBQUUsT0FBTyxvQkFBWSxDQUFDLE1BQU0sQ0FBQztRQUMxRCxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1lBQUUsT0FBTyxvQkFBWSxDQUFDLElBQUksQ0FBQztRQUNyRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1lBQUUsT0FBTyxvQkFBWSxDQUFDLElBQUksQ0FBQztRQUNuRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7WUFBRSxPQUFPLG9CQUFZLENBQUMsR0FBRyxDQUFDO1FBQ3ZELE9BQU8sb0JBQVksQ0FBQyxLQUFLLENBQUM7SUFDNUIsQ0FBQztDQUNGO0FBcFhELDRCQW9YQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUmVzcG9uc2UgaGFuZGxpbmcgZm9yIEdRTERCIE5vZGUuanMgZHJpdmVyLlxuICovXG5cbmltcG9ydCB7IFR5cGVkVmFsdWUsIHR5cGVkVmFsdWVUb0pTLCBQcm9wZXJ0eVR5cGUsIFNjaGVtYSwgUHJvcGVydHlEZWYsIFRhYmxlLCBIZWFkZXIsIEF0dHIsIEdxbGRiTm9kZSwgR3FsZGJFZGdlLCBHcWxkYlBhdGggfSBmcm9tICcuL3R5cGVzJztcblxuLyoqIFJlcHJlc2VudHMgYSBzaW5nbGUgcm93IGluIHRoZSBxdWVyeSByZXN1bHQgKi9cbmV4cG9ydCBjbGFzcyBSb3cge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgcmVhZG9ubHkgdmFsdWVzOiBhbnlbXSxcbiAgICBwdWJsaWMgcmVhZG9ubHkgdHlwZXM6IFByb3BlcnR5VHlwZVtdID0gW11cbiAgKSB7fVxuXG4gIC8qKiBHZXQgdGhlIHZhbHVlIGF0IHRoZSBnaXZlbiBjb2x1bW4gaW5kZXggKi9cbiAgZ2V0KGluZGV4OiBudW1iZXIpOiBhbnkge1xuICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gdGhpcy52YWx1ZXMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbHVtbiBpbmRleCBvdXQgb2YgcmFuZ2U6ICR7aW5kZXh9YCk7XG4gICAgfVxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy52YWx1ZXNbaW5kZXhdO1xuICAgIC8vIElmIHZhbHVlIGlzIGEgVHlwZWRWYWx1ZSBvYmplY3QsIGNvbnZlcnQgaXRcbiAgICBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiAndHlwZScgaW4gdmFsdWUgJiYgJ2RhdGEnIGluIHZhbHVlICYmICdpc051bGwnIGluIHZhbHVlKSB7XG4gICAgICByZXR1cm4gdHlwZWRWYWx1ZVRvSlModmFsdWUgYXMgVHlwZWRWYWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8qKiBHZXQgdGhlIFByb3BlcnR5VHlwZSBhdCB0aGUgZ2l2ZW4gY29sdW1uIGluZGV4ICovXG4gIGdldFR5cGUoaW5kZXg6IG51bWJlcik6IFByb3BlcnR5VHlwZSB7XG4gICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSB0aGlzLnR5cGVzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIFByb3BlcnR5VHlwZS5VTlNFVDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudHlwZXNbaW5kZXhdO1xuICB9XG5cbiAgLyoqIEdldCB0aGUgdmFsdWUgYXQgdGhlIGdpdmVuIGNvbHVtbiBpbmRleCBhcyBhIHN0cmluZyAqL1xuICBnZXRTdHJpbmcoaW5kZXg6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgdmFsID0gdGhpcy5nZXQoaW5kZXgpO1xuICAgIGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQpIHJldHVybiAnJztcbiAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHJldHVybiB2YWw7XG4gICAgcmV0dXJuIFN0cmluZyh2YWwpO1xuICB9XG5cbiAgLyoqIEdldCB0aGUgdmFsdWUgYXQgdGhlIGdpdmVuIGNvbHVtbiBpbmRleCBhcyBhIG51bWJlciAqL1xuICBnZXROdW1iZXIoaW5kZXg6IG51bWJlcik6IG51bWJlciB7XG4gICAgY29uc3QgdmFsID0gdGhpcy5nZXQoaW5kZXgpO1xuICAgIGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQpIHJldHVybiAwO1xuICAgIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykgcmV0dXJuIHZhbDtcbiAgICBjb25zdCBudW0gPSBOdW1iZXIodmFsKTtcbiAgICBpZiAoaXNOYU4obnVtKSkgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgY29udmVydCAke3R5cGVvZiB2YWx9IHRvIG51bWJlcmApO1xuICAgIHJldHVybiBudW07XG4gIH1cblxuICAvKiogR2V0IHRoZSB2YWx1ZSBhdCB0aGUgZ2l2ZW4gY29sdW1uIGluZGV4IGFzIGEgYm9vbGVhbiAqL1xuICBnZXRCb29sZWFuKGluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBjb25zdCB2YWwgPSB0aGlzLmdldChpbmRleCk7XG4gICAgaWYgKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGZhbHNlO1xuICAgIGlmICh0eXBlb2YgdmFsID09PSAnYm9vbGVhbicpIHJldHVybiB2YWw7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgY29udmVydCAke3R5cGVvZiB2YWx9IHRvIGJvb2xlYW5gKTtcbiAgfVxufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgYSBzaW5nbGUgY29sdW1uJ3MgZGF0YSBmcm9tIHRoZSByZXNwb25zZS5cbiAqIEFsbG93cyBjaGFpbmluZyBvcGVyYXRpb25zIGxpa2UgcmVzcC5hbGlhcyhcIm5cIikuYXNOb2RlcygpIG9yIHJlc3AuZ2V0KDApLmFzTm9kZXMoKS5cbiAqL1xuZXhwb3J0IGNsYXNzIEFsaWFzUmVzdWx0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBhbGlhc05hbWU6IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbHVtbklkeDogbnVtYmVyLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVzcG9uc2U6IFJlc3BvbnNlXG4gICkge31cblxuICAvKiogR2V0IHRoZSBhbGlhcyBuYW1lICovXG4gIGdldCBhbGlhcygpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmFsaWFzTmFtZTtcbiAgfVxuXG4gIC8qKiBHZXQgdGhlIGNvbHVtbiBpbmRleCAqL1xuICBnZXQgY29sdW1uSW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5jb2x1bW5JZHg7XG4gIH1cblxuICAvKipcbiAgICogRXh0cmFjdCBub2RlcyBmcm9tIHRoZSBhbGlhc2VkIGNvbHVtbiB3aXRoIHNjaGVtYSBpbmZvLlxuICAgKiBUaHJvd3MgVHlwZUVycm9yIGlmIHRoZSBjb2x1bW4gY29udGFpbnMgbm9uLU5PREUgdHlwZXMuXG4gICAqL1xuICBwcml2YXRlIGNvbGxlY3ROb2RlKHZhbDogYW55LCBub2RlczogTm9kZVtdLCBzY2hlbWFzOiBNYXA8c3RyaW5nLCBTY2hlbWE+KTogdm9pZCB7XG4gICAgaWYgKHZhbCAmJiB0eXBlb2YgdmFsLmlkID09PSAnc3RyaW5nJyAmJiAnbGFiZWxzJyBpbiB2YWwpIHtcbiAgICAgIGNvbnN0IG5vZGU6IE5vZGUgPSB7XG4gICAgICAgIGlkOiB2YWwuaWQsXG4gICAgICAgIGxhYmVsczogdmFsLmxhYmVscyB8fCBbXSxcbiAgICAgICAgcHJvcGVydGllczogdmFsLnByb3BlcnRpZXMgfHwge30sXG4gICAgICB9O1xuICAgICAgbm9kZXMucHVzaChub2RlKTtcbiAgICAgIGZvciAoY29uc3QgbGFiZWwgb2Ygbm9kZS5sYWJlbHMpIHtcbiAgICAgICAgaWYgKCFzY2hlbWFzLmhhcyhsYWJlbCkpIHtcbiAgICAgICAgICBzY2hlbWFzLnNldChsYWJlbCwgdGhpcy5idWlsZFNjaGVtYUZyb21Ob2RlKGxhYmVsLCBub2RlKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNvbGxlY3RFZGdlKHZhbDogYW55LCBlZGdlczogRWRnZVtdLCBzY2hlbWFzOiBNYXA8c3RyaW5nLCBTY2hlbWE+KTogdm9pZCB7XG4gICAgaWYgKHZhbCAmJiB0eXBlb2YgdmFsLmlkID09PSAnc3RyaW5nJyAmJiAnbGFiZWwnIGluIHZhbCkge1xuICAgICAgY29uc3QgZWRnZTogRWRnZSA9IHtcbiAgICAgICAgaWQ6IHZhbC5pZCxcbiAgICAgICAgbGFiZWw6IHZhbC5sYWJlbCB8fCAnJyxcbiAgICAgICAgZnJvbU5vZGVJZDogdmFsLmZyb21Ob2RlSWQgfHwgJycsXG4gICAgICAgIHRvTm9kZUlkOiB2YWwudG9Ob2RlSWQgfHwgJycsXG4gICAgICAgIHByb3BlcnRpZXM6IHZhbC5wcm9wZXJ0aWVzIHx8IHt9LFxuICAgICAgfTtcbiAgICAgIGVkZ2VzLnB1c2goZWRnZSk7XG4gICAgICBpZiAoZWRnZS5sYWJlbCAmJiAhc2NoZW1hcy5oYXMoZWRnZS5sYWJlbCkpIHtcbiAgICAgICAgc2NoZW1hcy5zZXQoZWRnZS5sYWJlbCwgdGhpcy5idWlsZFNjaGVtYUZyb21FZGdlKGVkZ2UubGFiZWwsIGVkZ2UpKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXh0cmFjdCBub2RlcyBmcm9tIHRoZSBhbGlhc2VkIGNvbHVtbiB3aXRoIHNjaGVtYSBpbmZvLlxuICAgKiBTdXBwb3J0cyBib3RoIGRpcmVjdCBOT0RFIGNvbHVtbnMgYW5kIExJU1Qgb2YgTk9ERSBjb2x1bW5zXG4gICAqIChlLmcuLCBncm91cCB2YXJpYWJsZXMgZnJvbSBxdWFudGlmaWVkIHBhdHRlcm5zKS5cbiAgICovXG4gIGFzTm9kZXMoKTogTm9kZVJlc3VsdCB7XG4gICAgY29uc3Qgbm9kZXM6IE5vZGVbXSA9IFtdO1xuICAgIGNvbnN0IHNjaGVtYXMgPSBuZXcgTWFwPHN0cmluZywgU2NoZW1hPigpO1xuXG4gICAgZm9yIChjb25zdCByb3cgb2YgdGhpcy5yZXNwb25zZS5yb3dzKSB7XG4gICAgICBpZiAodGhpcy5jb2x1bW5JZHggPj0gcm93LnZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGxldCBpdGVtVHlwZSA9IHJvdy5nZXRUeXBlKHRoaXMuY29sdW1uSWR4KTtcbiAgICAgIGNvbnN0IHJhd1ZhbHVlID0gcm93LnZhbHVlc1t0aGlzLmNvbHVtbklkeF07XG4gICAgICBpZiAoaXRlbVR5cGUgPT09IFByb3BlcnR5VHlwZS5VTlNFVCAmJiByYXdWYWx1ZSAmJiB0eXBlb2YgcmF3VmFsdWUgPT09ICdvYmplY3QnICYmICd0eXBlJyBpbiByYXdWYWx1ZSkge1xuICAgICAgICBpdGVtVHlwZSA9IHJhd1ZhbHVlLnR5cGU7XG4gICAgICB9XG5cbiAgICAgIGlmICghcmF3VmFsdWUgfHwgKHR5cGVvZiByYXdWYWx1ZSA9PT0gJ29iamVjdCcgJiYgJ2lzTnVsbCcgaW4gcmF3VmFsdWUgJiYgcmF3VmFsdWUuaXNOdWxsKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGl0ZW1UeXBlID09PSBQcm9wZXJ0eVR5cGUuTk9ERSkge1xuICAgICAgICB0aGlzLmNvbGxlY3ROb2RlKHJvdy5nZXQodGhpcy5jb2x1bW5JZHgpLCBub2Rlcywgc2NoZW1hcyk7XG4gICAgICB9IGVsc2UgaWYgKGl0ZW1UeXBlID09PSBQcm9wZXJ0eVR5cGUuTElTVCkge1xuICAgICAgICAvLyBMSVNUIG9mIE5PREUgKGdyb3VwIHZhcmlhYmxlIGZyb20gcXVhbnRpZmllZCBwYXR0ZXJuKVxuICAgICAgICBjb25zdCBsaXN0ID0gcm93LmdldCh0aGlzLmNvbHVtbklkeCk7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGxpc3QpKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGxpc3QpIHtcbiAgICAgICAgICAgIHRoaXMuY29sbGVjdE5vZGUoaXRlbSwgbm9kZXMsIHNjaGVtYXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcbiAgICAgICAgICBgVHlwZSBtaXNtYXRjaDogY29sdW1uICcke3RoaXMuYWxpYXNOYW1lfScgKGluZGV4ICR7dGhpcy5jb2x1bW5JZHh9KSBjb250YWlucyAke1Byb3BlcnR5VHlwZVtpdGVtVHlwZV19LCBleHBlY3RlZCBOT0RFIG9yIExJU1Qgb2YgTk9ERWBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4geyBub2Rlcywgc2NoZW1hcyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEV4dHJhY3QgZWRnZXMgZnJvbSB0aGUgYWxpYXNlZCBjb2x1bW4gd2l0aCBzY2hlbWEgaW5mby5cbiAgICogU3VwcG9ydHMgYm90aCBkaXJlY3QgRURHRSBjb2x1bW5zIGFuZCBMSVNUIG9mIEVER0UgY29sdW1uc1xuICAgKiAoZS5nLiwgZ3JvdXAgdmFyaWFibGVzIGZyb20gcXVhbnRpZmllZCBwYXR0ZXJucykuXG4gICAqL1xuICBhc0VkZ2VzKCk6IEVkZ2VSZXN1bHQge1xuICAgIGNvbnN0IGVkZ2VzOiBFZGdlW10gPSBbXTtcbiAgICBjb25zdCBzY2hlbWFzID0gbmV3IE1hcDxzdHJpbmcsIFNjaGVtYT4oKTtcblxuICAgIGZvciAoY29uc3Qgcm93IG9mIHRoaXMucmVzcG9uc2Uucm93cykge1xuICAgICAgaWYgKHRoaXMuY29sdW1uSWR4ID49IHJvdy52YWx1ZXMubGVuZ3RoKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBsZXQgaXRlbVR5cGUgPSByb3cuZ2V0VHlwZSh0aGlzLmNvbHVtbklkeCk7XG4gICAgICBjb25zdCByYXdWYWx1ZSA9IHJvdy52YWx1ZXNbdGhpcy5jb2x1bW5JZHhdO1xuICAgICAgaWYgKGl0ZW1UeXBlID09PSBQcm9wZXJ0eVR5cGUuVU5TRVQgJiYgcmF3VmFsdWUgJiYgdHlwZW9mIHJhd1ZhbHVlID09PSAnb2JqZWN0JyAmJiAndHlwZScgaW4gcmF3VmFsdWUpIHtcbiAgICAgICAgaXRlbVR5cGUgPSByYXdWYWx1ZS50eXBlO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXJhd1ZhbHVlIHx8ICh0eXBlb2YgcmF3VmFsdWUgPT09ICdvYmplY3QnICYmICdpc051bGwnIGluIHJhd1ZhbHVlICYmIHJhd1ZhbHVlLmlzTnVsbCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGlmIChpdGVtVHlwZSA9PT0gUHJvcGVydHlUeXBlLkVER0UpIHtcbiAgICAgICAgdGhpcy5jb2xsZWN0RWRnZShyb3cuZ2V0KHRoaXMuY29sdW1uSWR4KSwgZWRnZXMsIHNjaGVtYXMpO1xuICAgICAgfSBlbHNlIGlmIChpdGVtVHlwZSA9PT0gUHJvcGVydHlUeXBlLkxJU1QpIHtcbiAgICAgICAgLy8gTElTVCBvZiBFREdFIChncm91cCB2YXJpYWJsZSBmcm9tIHF1YW50aWZpZWQgcGF0dGVybilcbiAgICAgICAgY29uc3QgbGlzdCA9IHJvdy5nZXQodGhpcy5jb2x1bW5JZHgpO1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShsaXN0KSkge1xuICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBsaXN0KSB7XG4gICAgICAgICAgICB0aGlzLmNvbGxlY3RFZGdlKGl0ZW0sIGVkZ2VzLCBzY2hlbWFzKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgYFR5cGUgbWlzbWF0Y2g6IGNvbHVtbiAnJHt0aGlzLmFsaWFzTmFtZX0nIChpbmRleCAke3RoaXMuY29sdW1uSWR4fSkgY29udGFpbnMgJHtQcm9wZXJ0eVR5cGVbaXRlbVR5cGVdfSwgZXhwZWN0ZWQgRURHRSBvciBMSVNUIG9mIEVER0VgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgZWRnZXMsIHNjaGVtYXMgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHRyYWN0IHBhdGhzIGZyb20gdGhlIGFsaWFzZWQgY29sdW1uLlxuICAgKiBUaHJvd3MgVHlwZUVycm9yIGlmIHRoZSBjb2x1bW4gY29udGFpbnMgbm9uLVBBVEggdHlwZXMuXG4gICAqL1xuICBhc1BhdGhzKCk6IFBhdGhbXSB7XG4gICAgY29uc3QgcGF0aHM6IFBhdGhbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCByb3cgb2YgdGhpcy5yZXNwb25zZS5yb3dzKSB7XG4gICAgICBpZiAodGhpcy5jb2x1bW5JZHggPj0gcm93LnZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIHR5cGUgZnJvbSB0eXBlcyBhcnJheSBvciBmcm9tIFR5cGVkVmFsdWUgb2JqZWN0XG4gICAgICBsZXQgaXRlbVR5cGUgPSByb3cuZ2V0VHlwZSh0aGlzLmNvbHVtbklkeCk7XG4gICAgICBjb25zdCByYXdWYWx1ZSA9IHJvdy52YWx1ZXNbdGhpcy5jb2x1bW5JZHhdO1xuICAgICAgaWYgKGl0ZW1UeXBlID09PSBQcm9wZXJ0eVR5cGUuVU5TRVQgJiYgcmF3VmFsdWUgJiYgdHlwZW9mIHJhd1ZhbHVlID09PSAnb2JqZWN0JyAmJiAndHlwZScgaW4gcmF3VmFsdWUpIHtcbiAgICAgICAgaXRlbVR5cGUgPSByYXdWYWx1ZS50eXBlO1xuICAgICAgfVxuXG4gICAgICAvLyBTa2lwIG51bGwgdmFsdWVzXG4gICAgICBpZiAoIXJhd1ZhbHVlIHx8ICh0eXBlb2YgcmF3VmFsdWUgPT09ICdvYmplY3QnICYmICdpc051bGwnIGluIHJhd1ZhbHVlICYmIHJhd1ZhbHVlLmlzTnVsbCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIFR5cGUgY2hlY2tpbmc6IG11c3QgYmUgUEFUSCB0eXBlXG4gICAgICBpZiAoaXRlbVR5cGUgIT09IFByb3BlcnR5VHlwZS5QQVRIKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG4gICAgICAgICAgYFR5cGUgbWlzbWF0Y2g6IGNvbHVtbiAnJHt0aGlzLmFsaWFzTmFtZX0nIChpbmRleCAke3RoaXMuY29sdW1uSWR4fSkgY29udGFpbnMgJHtQcm9wZXJ0eVR5cGVbaXRlbVR5cGVdfSwgZXhwZWN0ZWQgUEFUSGBcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gQ29udmVydCBUeXBlZFZhbHVlIHRvIEdxbGRiUGF0aFxuICAgICAgY29uc3QgdmFsID0gcm93LmdldCh0aGlzLmNvbHVtbklkeCkgYXMgR3FsZGJQYXRoO1xuICAgICAgaWYgKHZhbCAmJiBBcnJheS5pc0FycmF5KHZhbC5ub2RlcykpIHtcbiAgICAgICAgLy8gQ29udmVydCBHcWxkYk5vZGUvR3FsZGJFZGdlIHRvIE5vZGUvRWRnZVxuICAgICAgICBjb25zdCBub2RlczogTm9kZVtdID0gKHZhbC5ub2RlcyB8fCBbXSkubWFwKChuOiBHcWxkYk5vZGUpID0+ICh7XG4gICAgICAgICAgaWQ6IG4uaWQgfHwgJycsXG4gICAgICAgICAgbGFiZWxzOiBuLmxhYmVscyB8fCBbXSxcbiAgICAgICAgICBwcm9wZXJ0aWVzOiBuLnByb3BlcnRpZXMgfHwge30sXG4gICAgICAgIH0pKTtcbiAgICAgICAgY29uc3QgZWRnZXM6IEVkZ2VbXSA9ICh2YWwuZWRnZXMgfHwgW10pLm1hcCgoZTogR3FsZGJFZGdlKSA9PiAoe1xuICAgICAgICAgIGlkOiBlLmlkIHx8ICcnLFxuICAgICAgICAgIGxhYmVsOiBlLmxhYmVsIHx8ICcnLFxuICAgICAgICAgIGZyb21Ob2RlSWQ6IGUuZnJvbU5vZGVJZCB8fCAnJyxcbiAgICAgICAgICB0b05vZGVJZDogZS50b05vZGVJZCB8fCAnJyxcbiAgICAgICAgICBwcm9wZXJ0aWVzOiBlLnByb3BlcnRpZXMgfHwge30sXG4gICAgICAgIH0pKTtcbiAgICAgICAgcGF0aHMucHVzaCh7IG5vZGVzLCBlZGdlcyB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcGF0aHM7XG4gIH1cblxuICAvKiogQ29udmVydCB0aGUgYWxpYXNlZCBjb2x1bW4gdG8gYSBzaW5nbGUtY29sdW1uIHRhYmxlICovXG4gIGFzVGFibGUoKTogVGFibGUge1xuICAgIC8vIENoZWNrIGlmIGZpcnN0IG5vbi1udWxsIHZhbHVlIGlzIGEgR3FsZGJUYWJsZSDigJQgaWYgc28sIHVud3JhcCBpdFxuICAgIGZvciAoY29uc3Qgcm93IG9mIHRoaXMucmVzcG9uc2Uucm93cykge1xuICAgICAgaWYgKHRoaXMuY29sdW1uSWR4IDwgcm93LnZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgaXRlbVR5cGUgPSByb3cuZ2V0VHlwZSh0aGlzLmNvbHVtbklkeCk7XG4gICAgICAgIGlmIChpdGVtVHlwZSA9PT0gUHJvcGVydHlUeXBlLlRBQkxFKSB7XG4gICAgICAgICAgY29uc3QgdmFsID0gcm93LmdldCh0aGlzLmNvbHVtbklkeCkgYXMgYW55O1xuICAgICAgICAgIGlmICh2YWwgJiYgJ2NvbHVtbnMnIGluIHZhbCAmJiAncm93cycgaW4gdmFsKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy51bndyYXBHcWxkYlRhYmxlKHZhbCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBicmVhazsgLy8gb25seSBjaGVjayBmaXJzdCByb3dcbiAgICB9XG5cbiAgICAvLyBGYWxsYmFjazogZ2VuZXJpYyBzaW5nbGUtY29sdW1uIHRhYmxlXG4gICAgY29uc3QgaGVhZGVyczogSGVhZGVyW10gPSBbe1xuICAgICAgbmFtZTogdGhpcy5hbGlhc05hbWUsXG4gICAgICB0eXBlOiBQcm9wZXJ0eVR5cGUuVU5TRVQsXG4gICAgfV07XG5cbiAgICBpZiAodGhpcy5yZXNwb25zZS5yb3dzLmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAoY29uc3Qgcm93IG9mIHRoaXMucmVzcG9uc2Uucm93cykge1xuICAgICAgICBpZiAodGhpcy5jb2x1bW5JZHggPCByb3cudmFsdWVzLmxlbmd0aCkge1xuICAgICAgICAgIGNvbnN0IHR5cGUgPSByb3cuZ2V0VHlwZSh0aGlzLmNvbHVtbklkeCk7XG4gICAgICAgICAgaWYgKHR5cGUgIT09IFByb3BlcnR5VHlwZS5VTlNFVCkge1xuICAgICAgICAgICAgaGVhZGVyc1swXS50eXBlID0gdHlwZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHRhYmxlUm93czogYW55W11bXSA9IHRoaXMucmVzcG9uc2Uucm93cy5tYXAocm93ID0+IHtcbiAgICAgIGlmICh0aGlzLmNvbHVtbklkeCA8IHJvdy52YWx1ZXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBbcm93LmdldCh0aGlzLmNvbHVtbklkeCldO1xuICAgICAgfVxuICAgICAgcmV0dXJuIFtudWxsXTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7IG5hbWU6ICcnLCBoZWFkZXJzLCByb3dzOiB0YWJsZVJvd3MgfTtcbiAgfVxuXG4gIHByaXZhdGUgdW53cmFwR3FsZGJUYWJsZShndDogeyBjb2x1bW5zOiBzdHJpbmdbXTsgcm93czogYW55W11bXSB9KTogVGFibGUge1xuICAgIGNvbnN0IGhlYWRlcnM6IEhlYWRlcltdID0gZ3QuY29sdW1ucy5tYXAoKGNvbCwgaSkgPT4ge1xuICAgICAgbGV0IGNvbFR5cGUgPSBQcm9wZXJ0eVR5cGUuVU5TRVQ7XG4gICAgICBpZiAoZ3Qucm93cy5sZW5ndGggPiAwICYmIGkgPCBndC5yb3dzWzBdLmxlbmd0aCkge1xuICAgICAgICBjb25zdCB2ID0gZ3Qucm93c1swXVtpXTtcbiAgICAgICAgaWYgKHR5cGVvZiB2ID09PSAnbnVtYmVyJykgY29sVHlwZSA9IE51bWJlci5pc0ludGVnZXIodikgPyBQcm9wZXJ0eVR5cGUuSU5UNjQgOiBQcm9wZXJ0eVR5cGUuRE9VQkxFO1xuICAgICAgICBlbHNlIGlmICh0eXBlb2YgdiA9PT0gJ3N0cmluZycpIGNvbFR5cGUgPSBQcm9wZXJ0eVR5cGUuU1RSSU5HO1xuICAgICAgICBlbHNlIGlmICh0eXBlb2YgdiA9PT0gJ2Jvb2xlYW4nKSBjb2xUeXBlID0gUHJvcGVydHlUeXBlLkJPT0w7XG4gICAgICB9XG4gICAgICByZXR1cm4geyBuYW1lOiBjb2wsIHR5cGU6IGNvbFR5cGUgfTtcbiAgICB9KTtcbiAgICByZXR1cm4geyBuYW1lOiB0aGlzLmFsaWFzTmFtZSwgaGVhZGVycywgcm93czogZ3Qucm93cyB9O1xuICB9XG5cbiAgLyoqIEV4dHJhY3Qgc2NhbGFyIG9yIGxpc3QgYXR0cmlidXRlIHZhbHVlcyBmcm9tIHRoZSBhbGlhc2VkIGNvbHVtbiAqL1xuICBhc0F0dHIoKTogQXR0ciB7XG4gICAgY29uc3QgdmFsdWVzOiBhbnlbXSA9IFtdO1xuICAgIGxldCBhdHRyVHlwZSA9IFByb3BlcnR5VHlwZS5VTlNFVDtcblxuICAgIGZvciAoY29uc3Qgcm93IG9mIHRoaXMucmVzcG9uc2Uucm93cykge1xuICAgICAgaWYgKHRoaXMuY29sdW1uSWR4IDwgcm93LnZhbHVlcy5sZW5ndGgpIHtcbiAgICAgICAgLy8gVHJ5IHRvIGdldCB0eXBlIGZyb20gcm93LnR5cGVzIGZpcnN0LCB0aGVuIGZyb20gVHlwZWRWYWx1ZSBvYmplY3RcbiAgICAgICAgaWYgKGF0dHJUeXBlID09PSBQcm9wZXJ0eVR5cGUuVU5TRVQpIHtcbiAgICAgICAgICBhdHRyVHlwZSA9IHJvdy5nZXRUeXBlKHRoaXMuY29sdW1uSWR4KTtcbiAgICAgICAgICBpZiAoYXR0clR5cGUgPT09IFByb3BlcnR5VHlwZS5VTlNFVCkge1xuICAgICAgICAgICAgY29uc3QgcmF3VmFsdWUgPSByb3cudmFsdWVzW3RoaXMuY29sdW1uSWR4XTtcbiAgICAgICAgICAgIGlmIChyYXdWYWx1ZSAmJiB0eXBlb2YgcmF3VmFsdWUgPT09ICdvYmplY3QnICYmICd0eXBlJyBpbiByYXdWYWx1ZSkge1xuICAgICAgICAgICAgICBhdHRyVHlwZSA9IHJhd1ZhbHVlLnR5cGU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHZhbHVlID0gcm93LmdldCh0aGlzLmNvbHVtbklkeCk7ICAvLyBVc2UgZ2V0KCkgdG8gY29udmVydCBUeXBlZFZhbHVlXG4gICAgICAgIHZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4geyBuYW1lOiB0aGlzLmFsaWFzTmFtZSwgdHlwZTogYXR0clR5cGUsIHZhbHVlcyB9O1xuICB9XG5cbiAgLyoqIEV4dHJhY3QgcmF3IEphdmFTY3JpcHQgdmFsdWVzIGZyb20gdGhlIGFsaWFzZWQgY29sdW1uICovXG4gIGFzVmFsdWVzKCk6IGFueVtdIHtcbiAgICBjb25zdCB2YWx1ZXM6IGFueVtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHJvdyBvZiB0aGlzLnJlc3BvbnNlLnJvd3MpIHtcbiAgICAgIGlmICh0aGlzLmNvbHVtbklkeCA8IHJvdy52YWx1ZXMubGVuZ3RoKSB7XG4gICAgICAgIHZhbHVlcy5wdXNoKHJvdy5nZXQodGhpcy5jb2x1bW5JZHgpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdmFsdWVzO1xuICB9XG5cbiAgLy8gSGVscGVyIG1ldGhvZHNcblxuICBwcml2YXRlIGJ1aWxkU2NoZW1hRnJvbU5vZGUobGFiZWw6IHN0cmluZywgbm9kZTogTm9kZSk6IFNjaGVtYSB7XG4gICAgY29uc3QgcHJvcGVydGllczogUHJvcGVydHlEZWZbXSA9IE9iamVjdC5lbnRyaWVzKG5vZGUucHJvcGVydGllcykubWFwKChbbmFtZSwgdmFsdWVdKSA9PiAoe1xuICAgICAgbmFtZSxcbiAgICAgIHR5cGU6IHRoaXMuaW5mZXJQcm9wZXJ0eVR5cGUodmFsdWUpLFxuICAgIH0pKTtcbiAgICByZXR1cm4geyBuYW1lOiBsYWJlbCwgcHJvcGVydGllcyB9O1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFNjaGVtYUZyb21FZGdlKGxhYmVsOiBzdHJpbmcsIGVkZ2U6IEVkZ2UpOiBTY2hlbWEge1xuICAgIGNvbnN0IHByb3BlcnRpZXM6IFByb3BlcnR5RGVmW10gPSBPYmplY3QuZW50cmllcyhlZGdlLnByb3BlcnRpZXMpLm1hcCgoW25hbWUsIHZhbHVlXSkgPT4gKHtcbiAgICAgIG5hbWUsXG4gICAgICB0eXBlOiB0aGlzLmluZmVyUHJvcGVydHlUeXBlKHZhbHVlKSxcbiAgICB9KSk7XG4gICAgcmV0dXJuIHsgbmFtZTogbGFiZWwsIHByb3BlcnRpZXMgfTtcbiAgfVxuXG4gIHByaXZhdGUgaW5mZXJQcm9wZXJ0eVR5cGUodmFsdWU6IGFueSk6IFByb3BlcnR5VHlwZSB7XG4gICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybiBQcm9wZXJ0eVR5cGUuTlVMTDtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHJldHVybiBQcm9wZXJ0eVR5cGUuQk9PTDtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgcmV0dXJuIE51bWJlci5pc0ludGVnZXIodmFsdWUpID8gUHJvcGVydHlUeXBlLklOVDY0IDogUHJvcGVydHlUeXBlLkRPVUJMRTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHJldHVybiBQcm9wZXJ0eVR5cGUuU1RSSU5HO1xuICAgIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsdWUpKSByZXR1cm4gUHJvcGVydHlUeXBlLkJMT0I7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSByZXR1cm4gUHJvcGVydHlUeXBlLkxJU1Q7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHJldHVybiBQcm9wZXJ0eVR5cGUuTUFQO1xuICAgIHJldHVybiBQcm9wZXJ0eVR5cGUuVU5TRVQ7XG4gIH1cbn1cblxuLyoqIFJlcHJlc2VudHMgdGhlIHJlc3VsdCBvZiBhIEdRTCBxdWVyeSAqL1xuZXhwb3J0IGNsYXNzIFJlc3BvbnNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IGNvbHVtbnM6IHN0cmluZ1tdLFxuICAgIHB1YmxpYyByZWFkb25seSByb3dzOiBSb3dbXSxcbiAgICBwdWJsaWMgcmVhZG9ubHkgcm93Q291bnQ6IG51bWJlcixcbiAgICBwdWJsaWMgcmVhZG9ubHkgaGFzTW9yZTogYm9vbGVhbixcbiAgICBwdWJsaWMgcmVhZG9ubHkgd2FybmluZ3M6IHN0cmluZ1tdLFxuICAgIHB1YmxpYyByZWFkb25seSByb3dzQWZmZWN0ZWQ6IG51bWJlciA9IDBcbiAgKSB7fVxuXG4gIC8qKiBDaGVjayBpZiB0aGUgcmVzcG9uc2UgaGFzIG5vIHJvd3MgKi9cbiAgaXNFbXB0eSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yb3dzLmxlbmd0aCA9PT0gMDtcbiAgfVxuXG4gIC8qKiBHZXQgdGhlIGZpcnN0IHJvdyAqL1xuICBmaXJzdCgpOiBSb3cgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnJvd3NbMF07XG4gIH1cblxuICAvKiogR2V0IHRoZSBsYXN0IHJvdyAqL1xuICBsYXN0KCk6IFJvdyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMucm93c1t0aGlzLnJvd3MubGVuZ3RoIC0gMV07XG4gIH1cblxuICAvKiogR2V0IHRoZSB2YWx1ZSBmb3IgYSBjb2x1bW4gYnkgbmFtZSAqL1xuICBnZXRCeU5hbWUocm93OiBSb3csIGNvbHVtbk5hbWU6IHN0cmluZyk6IGFueSB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLmNvbHVtbnMuaW5kZXhPZihjb2x1bW5OYW1lKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbHVtbiBub3QgZm91bmQ6ICR7Y29sdW1uTmFtZX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHJvdy5nZXQoaW5kZXgpO1xuICB9XG5cbiAgLyoqIEl0ZXJhdGUgb3ZlciBhbGwgcm93cyB3aXRoIGEgY2FsbGJhY2sgKi9cbiAgZm9yRWFjaChmbjogKHJvdzogUm93LCBpbmRleDogbnVtYmVyKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5yb3dzLmZvckVhY2goZm4pO1xuICB9XG5cbiAgLyoqIFRyYW5zZm9ybSBlYWNoIHJvdyB1c2luZyBhIGNhbGxiYWNrICovXG4gIG1hcDxUPihmbjogKHJvdzogUm93KSA9PiBUKTogVFtdIHtcbiAgICByZXR1cm4gdGhpcy5yb3dzLm1hcChmbik7XG4gIH1cblxuICAvKiogQ29udmVydCB0aGUgcmVzcG9uc2UgdG8gYW4gYXJyYXkgb2Ygb2JqZWN0cyAqL1xuICB0b09iamVjdHMoKTogUmVjb3JkPHN0cmluZywgYW55PltdIHtcbiAgICByZXR1cm4gdGhpcy5yb3dzLm1hcChyb3cgPT4ge1xuICAgICAgY29uc3Qgb2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgICB0aGlzLmNvbHVtbnMuZm9yRWFjaCgoY29sLCBpKSA9PiB7XG4gICAgICAgIC8vIEFkZCBib3VuZGFyeSBjaGVjayB0byBoYW5kbGUgbWlzbWF0Y2hlZCBjb2x1bW5zL3ZhbHVlc1xuICAgICAgICBvYmpbY29sXSA9IGkgPCByb3cudmFsdWVzLmxlbmd0aCA/IHJvdy5nZXQoaSkgOiBudWxsO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gb2JqO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIENvbnZlcnQgdGhlIHJlc3BvbnNlIHRvIEpTT04gKi9cbiAgdG9KU09OKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMudG9PYmplY3RzKCkpO1xuICB9XG5cbiAgLyoqIEdldCB0aGUgc2luZ2xlIHZhbHVlIGZyb20gYSBzaW5nbGUtcm93LCBzaW5nbGUtY29sdW1uIHJlc3BvbnNlICovXG4gIHNpbmdsZVZhbHVlKCk6IGFueSB7XG4gICAgaWYgKHRoaXMucm93cy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuICAgIGlmICh0aGlzLnJvd3MubGVuZ3RoID4gMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBzaW5nbGUgcm93LCBnb3QgJHt0aGlzLnJvd3MubGVuZ3RofWApO1xuICAgIH1cbiAgICBpZiAodGhpcy5yb3dzWzBdLnZhbHVlcy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuICAgIGlmICh0aGlzLnJvd3NbMF0udmFsdWVzLmxlbmd0aCA+IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgc2luZ2xlIGNvbHVtbiwgZ290ICR7dGhpcy5yb3dzWzBdLnZhbHVlcy5sZW5ndGh9YCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnJvd3NbMF0uZ2V0KDApO1xuICB9XG5cbiAgLyoqIEdldCB0aGUgc2luZ2xlIG51bWJlciB2YWx1ZSAqL1xuICBzaW5nbGVOdW1iZXIoKTogbnVtYmVyIHtcbiAgICBjb25zdCB2YWwgPSB0aGlzLnNpbmdsZVZhbHVlKCk7XG4gICAgaWYgKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09IHVuZGVmaW5lZCkgcmV0dXJuIDA7XG4gICAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSByZXR1cm4gdmFsO1xuICAgIGNvbnN0IG51bSA9IE51bWJlcih2YWwpO1xuICAgIGlmIChpc05hTihudW0pKSB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBjb252ZXJ0ICR7dHlwZW9mIHZhbH0gdG8gbnVtYmVyYCk7XG4gICAgcmV0dXJuIG51bTtcbiAgfVxuXG4gIC8qKiBHZXQgdGhlIHNpbmdsZSBzdHJpbmcgdmFsdWUgKi9cbiAgc2luZ2xlU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgY29uc3QgdmFsID0gdGhpcy5zaW5nbGVWYWx1ZSgpO1xuICAgIGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQpIHJldHVybiAnJztcbiAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHJldHVybiB2YWw7XG4gICAgcmV0dXJuIFN0cmluZyh2YWwpO1xuICB9XG5cbiAgLyoqIEl0ZXJhdG9yIHN1cHBvcnQgKi9cbiAgW1N5bWJvbC5pdGVyYXRvcl0oKTogSXRlcmF0b3I8Um93PiB7XG4gICAgcmV0dXJuIHRoaXMucm93c1tTeW1ib2wuaXRlcmF0b3JdKCk7XG4gIH1cblxuICAvKiogR2V0IHRoZSBudW1iZXIgb2Ygcm93cyAqL1xuICBnZXQgbGVuZ3RoKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucm93cy5sZW5ndGg7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFuIEFsaWFzUmVzdWx0IGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbiBuYW1lLlxuICAgKiBVc2UgdGhpcyB0byBleHRyYWN0IGRhdGEgZnJvbSBhIHNwZWNpZmljIGNvbHVtbiBieSBuYW1lLlxuICAgKiBFeGFtcGxlOiByZXNwLmFsaWFzKFwiblwiKS5hc05vZGVzKClcbiAgICovXG4gIGFsaWFzKGNvbHVtbk5hbWU6IHN0cmluZyk6IEFsaWFzUmVzdWx0IHtcbiAgICBjb25zdCBjb2xJZHggPSB0aGlzLmNvbHVtbnMuaW5kZXhPZihjb2x1bW5OYW1lKTtcbiAgICBpZiAoY29sSWR4ID09PSAtMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb2x1bW4gYWxpYXMgbm90IGZvdW5kOiAke2NvbHVtbk5hbWV9YCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgQWxpYXNSZXN1bHQoY29sdW1uTmFtZSwgY29sSWR4LCB0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYW4gQWxpYXNSZXN1bHQgZm9yIHRoZSBjb2x1bW4gYXQgdGhlIHNwZWNpZmllZCBpbmRleC5cbiAgICogVXNlIHRoaXMgdG8gZXh0cmFjdCBkYXRhIGZyb20gYSBzcGVjaWZpYyBjb2x1bW4gYnkgaW5kZXguXG4gICAqIEV4YW1wbGU6IHJlc3AuZ2V0KDApLmFzTm9kZXMoKVxuICAgKi9cbiAgZ2V0KGluZGV4OiBudW1iZXIpOiBBbGlhc1Jlc3VsdCB7XG4gICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSB0aGlzLmNvbHVtbnMubGVuZ3RoKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbHVtbiBpbmRleCBvdXQgb2YgcmFuZ2U6ICR7aW5kZXh9ICh0b3RhbDogJHt0aGlzLmNvbHVtbnMubGVuZ3RofSlgKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBBbGlhc1Jlc3VsdCh0aGlzLmNvbHVtbnNbaW5kZXhdLCBpbmRleCwgdGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgVXNlIGFsaWFzKCkgb3IgZ2V0KCkgaW5zdGVhZC4gVGhpcyBtZXRob2Qgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHZlcnNpb24uXG4gICAqIEV4dHJhY3Qgbm9kZXMgZnJvbSByZXNwb25zZSB3aXRoIHNjaGVtYSBpbmZvLlxuICAgKiBTdXBwb3J0cyBib3RoIE5PREUgYW5kIExJU1Qgb2YgTk9ERSBjb2x1bW5zLlxuICAgKi9cbiAgYXNOb2RlcygpOiBOb2RlUmVzdWx0IHtcbiAgICBjb25zdCBub2RlczogTm9kZVtdID0gW107XG4gICAgY29uc3Qgc2NoZW1hcyA9IG5ldyBNYXA8c3RyaW5nLCBTY2hlbWE+KCk7XG5cbiAgICBjb25zdCBjb2xsZWN0Tm9kZSA9ICh2YWw6IGFueSkgPT4ge1xuICAgICAgaWYgKHZhbCAmJiB0eXBlb2YgdmFsLmlkID09PSAnc3RyaW5nJyAmJiAnbGFiZWxzJyBpbiB2YWwpIHtcbiAgICAgICAgY29uc3Qgbm9kZTogTm9kZSA9IHtcbiAgICAgICAgICBpZDogdmFsLmlkLFxuICAgICAgICAgIGxhYmVsczogdmFsLmxhYmVscyB8fCBbXSxcbiAgICAgICAgICBwcm9wZXJ0aWVzOiB2YWwucHJvcGVydGllcyB8fCB7fSxcbiAgICAgICAgfTtcbiAgICAgICAgbm9kZXMucHVzaChub2RlKTtcbiAgICAgICAgZm9yIChjb25zdCBsYWJlbCBvZiBub2RlLmxhYmVscykge1xuICAgICAgICAgIGlmICghc2NoZW1hcy5oYXMobGFiZWwpKSB7XG4gICAgICAgICAgICBzY2hlbWFzLnNldChsYWJlbCwgdGhpcy5idWlsZFNjaGVtYUZyb21Ob2RlKGxhYmVsLCBub2RlKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZvciAoY29uc3Qgcm93IG9mIHRoaXMucm93cykge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3cudmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGxldCBpdGVtVHlwZSA9IHJvdy5nZXRUeXBlKGkpO1xuICAgICAgICBjb25zdCByYXdWYWx1ZSA9IHJvdy52YWx1ZXNbaV07XG4gICAgICAgIGlmIChpdGVtVHlwZSA9PT0gUHJvcGVydHlUeXBlLlVOU0VUICYmIHJhd1ZhbHVlICYmIHR5cGVvZiByYXdWYWx1ZSA9PT0gJ29iamVjdCcgJiYgJ3R5cGUnIGluIHJhd1ZhbHVlKSB7XG4gICAgICAgICAgaXRlbVR5cGUgPSByYXdWYWx1ZS50eXBlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGl0ZW1UeXBlID09PSBQcm9wZXJ0eVR5cGUuTk9ERSkge1xuICAgICAgICAgIGNvbGxlY3ROb2RlKHJvdy5nZXQoaSkpO1xuICAgICAgICB9IGVsc2UgaWYgKGl0ZW1UeXBlID09PSBQcm9wZXJ0eVR5cGUuTElTVCkge1xuICAgICAgICAgIGNvbnN0IGxpc3QgPSByb3cuZ2V0KGkpO1xuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGxpc3QpKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgbGlzdCkge1xuICAgICAgICAgICAgICBjb2xsZWN0Tm9kZShpdGVtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4geyBub2Rlcywgc2NoZW1hcyB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIFVzZSBhbGlhcygpIG9yIGdldCgpIGluc3RlYWQuIFRoaXMgbWV0aG9kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSB2ZXJzaW9uLlxuICAgKiBFeHRyYWN0IGVkZ2VzIGZyb20gcmVzcG9uc2Ugd2l0aCBzY2hlbWEgaW5mby5cbiAgICogU3VwcG9ydHMgYm90aCBFREdFIGFuZCBMSVNUIG9mIEVER0UgY29sdW1ucy5cbiAgICovXG4gIGFzRWRnZXMoKTogRWRnZVJlc3VsdCB7XG4gICAgY29uc3QgZWRnZXM6IEVkZ2VbXSA9IFtdO1xuICAgIGNvbnN0IHNjaGVtYXMgPSBuZXcgTWFwPHN0cmluZywgU2NoZW1hPigpO1xuXG4gICAgY29uc3QgY29sbGVjdEVkZ2UgPSAodmFsOiBhbnkpID0+IHtcbiAgICAgIGlmICh2YWwgJiYgdHlwZW9mIHZhbC5pZCA9PT0gJ3N0cmluZycgJiYgJ2xhYmVsJyBpbiB2YWwpIHtcbiAgICAgICAgY29uc3QgZWRnZTogRWRnZSA9IHtcbiAgICAgICAgICBpZDogdmFsLmlkLFxuICAgICAgICAgIGxhYmVsOiB2YWwubGFiZWwgfHwgJycsXG4gICAgICAgICAgZnJvbU5vZGVJZDogdmFsLmZyb21Ob2RlSWQgfHwgJycsXG4gICAgICAgICAgdG9Ob2RlSWQ6IHZhbC50b05vZGVJZCB8fCAnJyxcbiAgICAgICAgICBwcm9wZXJ0aWVzOiB2YWwucHJvcGVydGllcyB8fCB7fSxcbiAgICAgICAgfTtcbiAgICAgICAgZWRnZXMucHVzaChlZGdlKTtcbiAgICAgICAgaWYgKGVkZ2UubGFiZWwgJiYgIXNjaGVtYXMuaGFzKGVkZ2UubGFiZWwpKSB7XG4gICAgICAgICAgc2NoZW1hcy5zZXQoZWRnZS5sYWJlbCwgdGhpcy5idWlsZFNjaGVtYUZyb21FZGdlKGVkZ2UubGFiZWwsIGVkZ2UpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBmb3IgKGNvbnN0IHJvdyBvZiB0aGlzLnJvd3MpIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93LnZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBsZXQgaXRlbVR5cGUgPSByb3cuZ2V0VHlwZShpKTtcbiAgICAgICAgY29uc3QgcmF3VmFsdWUgPSByb3cudmFsdWVzW2ldO1xuICAgICAgICBpZiAoaXRlbVR5cGUgPT09IFByb3BlcnR5VHlwZS5VTlNFVCAmJiByYXdWYWx1ZSAmJiB0eXBlb2YgcmF3VmFsdWUgPT09ICdvYmplY3QnICYmICd0eXBlJyBpbiByYXdWYWx1ZSkge1xuICAgICAgICAgIGl0ZW1UeXBlID0gcmF3VmFsdWUudHlwZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChpdGVtVHlwZSA9PT0gUHJvcGVydHlUeXBlLkVER0UpIHtcbiAgICAgICAgICBjb2xsZWN0RWRnZShyb3cuZ2V0KGkpKTtcbiAgICAgICAgfSBlbHNlIGlmIChpdGVtVHlwZSA9PT0gUHJvcGVydHlUeXBlLkxJU1QpIHtcbiAgICAgICAgICBjb25zdCBsaXN0ID0gcm93LmdldChpKTtcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShsaXN0KSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGxpc3QpIHtcbiAgICAgICAgICAgICAgY29sbGVjdEVkZ2UoaXRlbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgZWRnZXMsIHNjaGVtYXMgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBVc2UgYWxpYXMoKSBvciBnZXQoKSBpbnN0ZWFkLiBUaGlzIG1ldGhvZCB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgdmVyc2lvbi5cbiAgICogRXh0cmFjdCBwYXRocyBmcm9tIHJlc3BvbnNlLlxuICAgKiBQYXRocyBhcmUgaWRlbnRpZmllZCBieSBQcm9wZXJ0eVR5cGUuUEFUSCB0eXBlIGluIHRoZSBUeXBlZFZhbHVlLlxuICAgKi9cbiAgYXNQYXRocygpOiBQYXRoW10ge1xuICAgIGNvbnN0IHBhdGhzOiBQYXRoW10gPSBbXTtcblxuICAgIGZvciAoY29uc3Qgcm93IG9mIHRoaXMucm93cykge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3cudmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIC8vIENoZWNrIHR5cGUgZnJvbSB0eXBlcyBhcnJheSBvciBmcm9tIFR5cGVkVmFsdWUgb2JqZWN0XG4gICAgICAgIGxldCBpdGVtVHlwZSA9IHJvdy5nZXRUeXBlKGkpO1xuICAgICAgICBjb25zdCByYXdWYWx1ZSA9IHJvdy52YWx1ZXNbaV07XG4gICAgICAgIGlmIChpdGVtVHlwZSA9PT0gUHJvcGVydHlUeXBlLlVOU0VUICYmIHJhd1ZhbHVlICYmIHR5cGVvZiByYXdWYWx1ZSA9PT0gJ29iamVjdCcgJiYgJ3R5cGUnIGluIHJhd1ZhbHVlKSB7XG4gICAgICAgICAgaXRlbVR5cGUgPSByYXdWYWx1ZS50eXBlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGl0ZW1UeXBlID09PSBQcm9wZXJ0eVR5cGUuUEFUSCkge1xuICAgICAgICAgIC8vIENvbnZlcnQgVHlwZWRWYWx1ZSB0byBHcWxkYlBhdGhcbiAgICAgICAgICBjb25zdCB2YWwgPSByb3cuZ2V0KGkpIGFzIEdxbGRiUGF0aDtcbiAgICAgICAgICBpZiAodmFsICYmIEFycmF5LmlzQXJyYXkodmFsLm5vZGVzKSkge1xuICAgICAgICAgICAgLy8gQ29udmVydCBHcWxkYk5vZGUvR3FsZGJFZGdlIHRvIE5vZGUvRWRnZVxuICAgICAgICAgICAgY29uc3Qgbm9kZXM6IE5vZGVbXSA9ICh2YWwubm9kZXMgfHwgW10pLm1hcCgobjogR3FsZGJOb2RlKSA9PiAoe1xuICAgICAgICAgICAgICBpZDogbi5pZCB8fCAnJyxcbiAgICAgICAgICAgICAgbGFiZWxzOiBuLmxhYmVscyB8fCBbXSxcbiAgICAgICAgICAgICAgcHJvcGVydGllczogbi5wcm9wZXJ0aWVzIHx8IHt9LFxuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgICAgY29uc3QgZWRnZXM6IEVkZ2VbXSA9ICh2YWwuZWRnZXMgfHwgW10pLm1hcCgoZTogR3FsZGJFZGdlKSA9PiAoe1xuICAgICAgICAgICAgICBpZDogZS5pZCB8fCAnJyxcbiAgICAgICAgICAgICAgbGFiZWw6IGUubGFiZWwgfHwgJycsXG4gICAgICAgICAgICAgIGZyb21Ob2RlSWQ6IGUuZnJvbU5vZGVJZCB8fCAnJyxcbiAgICAgICAgICAgICAgdG9Ob2RlSWQ6IGUudG9Ob2RlSWQgfHwgJycsXG4gICAgICAgICAgICAgIHByb3BlcnRpZXM6IGUucHJvcGVydGllcyB8fCB7fSxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIHBhdGhzLnB1c2goeyBub2RlcywgZWRnZXMgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhdGhzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIFVzZSBhbGlhcygpIG9yIGdldCgpIGluc3RlYWQuIFRoaXMgbWV0aG9kIHdpbGwgYmUgcmVtb3ZlZCBpbiBhIGZ1dHVyZSB2ZXJzaW9uLlxuICAgKiBSZXR1cm4gcmVzcG9uc2UgYXMgZ2VuZXJpYyB0YWJsZS5cbiAgICogSWYgcmVzcG9uc2UgaXMgYSBzaW5nbGUgVEFCTEUgY29sdW1uLCB1bndyYXBzIHRoZSBHcWxkYlRhYmxlIGludG8gcHJvcGVyIGhlYWRlcnMvcm93cy5cbiAgICovXG4gIGFzVGFibGUoKTogVGFibGUge1xuICAgIC8vIElmIHNpbmdsZSBjb2x1bW4gb2YgVEFCTEUgdHlwZSwgdW53cmFwIEdxbGRiVGFibGVcbiAgICBpZiAodGhpcy5jb2x1bW5zLmxlbmd0aCA9PT0gMSAmJiB0aGlzLnJvd3MubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgaXRlbVR5cGUgPSB0aGlzLnJvd3NbMF0uZ2V0VHlwZSgwKTtcbiAgICAgIGlmIChpdGVtVHlwZSA9PT0gUHJvcGVydHlUeXBlLlRBQkxFKSB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHRoaXMucm93c1swXS5nZXQoMCkgYXMgYW55O1xuICAgICAgICBpZiAodmFsICYmICdjb2x1bW5zJyBpbiB2YWwgJiYgJ3Jvd3MnIGluIHZhbCkge1xuICAgICAgICAgIGNvbnN0IGd0ID0gdmFsIGFzIHsgY29sdW1uczogc3RyaW5nW107IHJvd3M6IGFueVtdW10gfTtcbiAgICAgICAgICBjb25zdCBoZWFkZXJzOiBIZWFkZXJbXSA9IGd0LmNvbHVtbnMubWFwKChjb2w6IHN0cmluZywgaTogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgICBsZXQgY29sVHlwZSA9IFByb3BlcnR5VHlwZS5VTlNFVDtcbiAgICAgICAgICAgIGlmIChndC5yb3dzLmxlbmd0aCA+IDAgJiYgaSA8IGd0LnJvd3NbMF0ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIGNvbnN0IHYgPSBndC5yb3dzWzBdW2ldO1xuICAgICAgICAgICAgICBpZiAodHlwZW9mIHYgPT09ICdudW1iZXInKSBjb2xUeXBlID0gTnVtYmVyLmlzSW50ZWdlcih2KSA/IFByb3BlcnR5VHlwZS5JTlQ2NCA6IFByb3BlcnR5VHlwZS5ET1VCTEU7XG4gICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2ID09PSAnc3RyaW5nJykgY29sVHlwZSA9IFByb3BlcnR5VHlwZS5TVFJJTkc7XG4gICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2ID09PSAnYm9vbGVhbicpIGNvbFR5cGUgPSBQcm9wZXJ0eVR5cGUuQk9PTDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7IG5hbWU6IGNvbCwgdHlwZTogY29sVHlwZSB9O1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybiB7IG5hbWU6IHRoaXMuY29sdW1uc1swXSwgaGVhZGVycywgcm93czogZ3Qucm93cyB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRmFsbGJhY2s6IGdlbmVyaWMgbXVsdGktY29sdW1uIHRhYmxlXG4gICAgY29uc3QgaGVhZGVyczogSGVhZGVyW10gPSB0aGlzLmNvbHVtbnMubWFwKGNvbCA9PiAoe1xuICAgICAgbmFtZTogY29sLFxuICAgICAgdHlwZTogUHJvcGVydHlUeXBlLlVOU0VULFxuICAgIH0pKTtcblxuICAgIGNvbnN0IHRhYmxlUm93czogYW55W11bXSA9IHRoaXMucm93cy5tYXAocm93ID0+IHtcbiAgICAgIHJldHVybiB0aGlzLmNvbHVtbnMubWFwKChfLCBpKSA9PiAoaSA8IHJvdy52YWx1ZXMubGVuZ3RoID8gcm93LmdldChpKSA6IG51bGwpKTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7IG5hbWU6ICcnLCBoZWFkZXJzLCByb3dzOiB0YWJsZVJvd3MgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVwcmVjYXRlZCBVc2UgYWxpYXMoKSBvciBnZXQoKSBpbnN0ZWFkLiBUaGlzIG1ldGhvZCB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgdmVyc2lvbi5cbiAgICogRXh0cmFjdCBzY2FsYXIgb3IgbGlzdCBhdHRyaWJ1dGUgdmFsdWVzXG4gICAqL1xuICBhc0F0dHIoY29sdW1uTmFtZTogc3RyaW5nKTogQXR0ciB7XG4gICAgY29uc3QgY29sSW5kZXggPSB0aGlzLmNvbHVtbnMuaW5kZXhPZihjb2x1bW5OYW1lKTtcbiAgICBpZiAoY29sSW5kZXggPT09IC0xKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbHVtbiBub3QgZm91bmQ6ICR7Y29sdW1uTmFtZX1gKTtcbiAgICB9XG5cbiAgICBjb25zdCB2YWx1ZXM6IGFueVtdID0gW107XG4gICAgbGV0IGF0dHJUeXBlID0gUHJvcGVydHlUeXBlLlVOU0VUO1xuXG4gICAgZm9yIChjb25zdCByb3cgb2YgdGhpcy5yb3dzKSB7XG4gICAgICBpZiAoY29sSW5kZXggPCByb3cudmFsdWVzLmxlbmd0aCkge1xuICAgICAgICAvLyBUcnkgdG8gZ2V0IHR5cGUgZnJvbSByb3cudHlwZXMgZmlyc3QsIHRoZW4gZnJvbSBUeXBlZFZhbHVlIG9iamVjdFxuICAgICAgICBpZiAoYXR0clR5cGUgPT09IFByb3BlcnR5VHlwZS5VTlNFVCkge1xuICAgICAgICAgIGF0dHJUeXBlID0gcm93LmdldFR5cGUoY29sSW5kZXgpO1xuICAgICAgICAgIGlmIChhdHRyVHlwZSA9PT0gUHJvcGVydHlUeXBlLlVOU0VUKSB7XG4gICAgICAgICAgICBjb25zdCByYXdWYWx1ZSA9IHJvdy52YWx1ZXNbY29sSW5kZXhdO1xuICAgICAgICAgICAgaWYgKHJhd1ZhbHVlICYmIHR5cGVvZiByYXdWYWx1ZSA9PT0gJ29iamVjdCcgJiYgJ3R5cGUnIGluIHJhd1ZhbHVlKSB7XG4gICAgICAgICAgICAgIGF0dHJUeXBlID0gcmF3VmFsdWUudHlwZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdmFsdWUgPSByb3cuZ2V0KGNvbEluZGV4KTsgIC8vIFVzZSBnZXQoKSB0byBjb252ZXJ0IFR5cGVkVmFsdWVcbiAgICAgICAgdmFsdWVzLnB1c2godmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IG5hbWU6IGNvbHVtbk5hbWUsIHR5cGU6IGF0dHJUeXBlLCB2YWx1ZXMgfTtcbiAgfVxuXG4gIC8vIEhlbHBlciBtZXRob2RzXG5cbiAgcHJpdmF0ZSBidWlsZFNjaGVtYUZyb21Ob2RlKGxhYmVsOiBzdHJpbmcsIG5vZGU6IE5vZGUpOiBTY2hlbWEge1xuICAgIGNvbnN0IHByb3BlcnRpZXM6IFByb3BlcnR5RGVmW10gPSBPYmplY3QuZW50cmllcyhub2RlLnByb3BlcnRpZXMpLm1hcCgoW25hbWUsIHZhbHVlXSkgPT4gKHtcbiAgICAgIG5hbWUsXG4gICAgICB0eXBlOiB0aGlzLmluZmVyUHJvcGVydHlUeXBlKHZhbHVlKSxcbiAgICB9KSk7XG4gICAgcmV0dXJuIHsgbmFtZTogbGFiZWwsIHByb3BlcnRpZXMgfTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRTY2hlbWFGcm9tRWRnZShsYWJlbDogc3RyaW5nLCBlZGdlOiBFZGdlKTogU2NoZW1hIHtcbiAgICBjb25zdCBwcm9wZXJ0aWVzOiBQcm9wZXJ0eURlZltdID0gT2JqZWN0LmVudHJpZXMoZWRnZS5wcm9wZXJ0aWVzKS5tYXAoKFtuYW1lLCB2YWx1ZV0pID0+ICh7XG4gICAgICBuYW1lLFxuICAgICAgdHlwZTogdGhpcy5pbmZlclByb3BlcnR5VHlwZSh2YWx1ZSksXG4gICAgfSkpO1xuICAgIHJldHVybiB7IG5hbWU6IGxhYmVsLCBwcm9wZXJ0aWVzIH07XG4gIH1cblxuICBwcml2YXRlIGluZmVyUHJvcGVydHlUeXBlKHZhbHVlOiBhbnkpOiBQcm9wZXJ0eVR5cGUge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gUHJvcGVydHlUeXBlLk5VTEw7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSByZXR1cm4gUHJvcGVydHlUeXBlLkJPT0w7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcbiAgICAgIHJldHVybiBOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSA/IFByb3BlcnR5VHlwZS5JTlQ2NCA6IFByb3BlcnR5VHlwZS5ET1VCTEU7XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSByZXR1cm4gUHJvcGVydHlUeXBlLlNUUklORztcbiAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbHVlKSkgcmV0dXJuIFByb3BlcnR5VHlwZS5CTE9CO1xuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgcmV0dXJuIFByb3BlcnR5VHlwZS5MSVNUO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSByZXR1cm4gUHJvcGVydHlUeXBlLk1BUDtcbiAgICByZXR1cm4gUHJvcGVydHlUeXBlLlVOU0VUO1xuICB9XG59XG5cbi8qKiBSZXN1bHQgb2YgYW4gaW5zZXJ0IG5vZGVzIG9wZXJhdGlvbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbnNlcnROb2Rlc1Jlc3VsdCB7XG4gIHN1Y2Nlc3M6IGJvb2xlYW47XG4gIG5vZGVJZHM6IHN0cmluZ1tdO1xuICBub2RlQ291bnQ6IG51bWJlcjtcbiAgbWVzc2FnZTogc3RyaW5nO1xufVxuXG4vKiogUmVzdWx0IG9mIGFuIGluc2VydCBlZGdlcyBvcGVyYXRpb24gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW5zZXJ0RWRnZXNSZXN1bHQge1xuICBzdWNjZXNzOiBib29sZWFuO1xuICBlZGdlSWRzOiBzdHJpbmdbXTtcbiAgZWRnZUNvdW50OiBudW1iZXI7XG4gIG1lc3NhZ2U6IHN0cmluZztcbiAgc2tpcHBlZENvdW50OiBudW1iZXI7XG59XG5cbi8qKiBSZXN1bHQgb2YgYSBkZWxldGUgb3BlcmF0aW9uICovXG5leHBvcnQgaW50ZXJmYWNlIERlbGV0ZVJlc3VsdCB7XG4gIHN1Y2Nlc3M6IGJvb2xlYW47XG4gIGRlbGV0ZWRDb3VudDogbnVtYmVyO1xuICBtZXNzYWdlOiBzdHJpbmc7XG59XG5cbi8qKiBDb25maWd1cmF0aW9uIGZvciB0aGUgdW5pZmllZCBFeHBvcnQgb3BlcmF0aW9uICovXG5leHBvcnQgaW50ZXJmYWNlIEV4cG9ydENvbmZpZyB7XG4gIGdyYXBoTmFtZTogc3RyaW5nO1xuICBiYXRjaFNpemU/OiBudW1iZXI7XG4gIGV4cG9ydE5vZGVzPzogYm9vbGVhbjtcbiAgZXhwb3J0RWRnZXM/OiBib29sZWFuO1xuICBub2RlTGFiZWxzPzogc3RyaW5nW107XG4gIGVkZ2VMYWJlbHM/OiBzdHJpbmdbXTtcbiAgaW5jbHVkZU1ldGFkYXRhPzogYm9vbGVhbjtcbn1cblxuLyoqIFN0YXRpc3RpY3MgZm9yIGFuIGV4cG9ydCBvcGVyYXRpb24gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRXhwb3J0U3RhdHMge1xuICBub2Rlc0V4cG9ydGVkOiBudW1iZXI7XG4gIGVkZ2VzRXhwb3J0ZWQ6IG51bWJlcjtcbiAgYnl0ZXNXcml0dGVuOiBudW1iZXI7XG4gIGR1cmF0aW9uTXM6IG51bWJlcjtcbn1cblxuLyoqIEEgY2h1bmsgb2YgZXhwb3J0ZWQgZGF0YSBpbiBKU09OIExpbmVzIGZvcm1hdCAqL1xuZXhwb3J0IGludGVyZmFjZSBFeHBvcnRDaHVuayB7XG4gIGRhdGE6IEJ1ZmZlcjtcbiAgaXNGaW5hbDogYm9vbGVhbjtcbiAgc3RhdHM/OiBFeHBvcnRTdGF0cztcbn1cblxuLyoqXG4gKiBBIGJhdGNoIG9mIGV4cG9ydGVkIG5vZGVzXG4gKiBAZGVwcmVjYXRlZCBVc2UgZXhwb3J0KCkgd2l0aCBFeHBvcnRDb25maWcgaW5zdGVhZFxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4cG9ydE5vZGVzUmVzdWx0IHtcbiAgbm9kZXM6IEV4cG9ydGVkTm9kZVtdO1xuICBoYXNNb3JlOiBib29sZWFuO1xufVxuXG4vKipcbiAqIEEgYmF0Y2ggb2YgZXhwb3J0ZWQgZWRnZXNcbiAqIEBkZXByZWNhdGVkIFVzZSBleHBvcnQoKSB3aXRoIEV4cG9ydENvbmZpZyBpbnN0ZWFkXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRXhwb3J0RWRnZXNSZXN1bHQge1xuICBlZGdlczogRXhwb3J0ZWRFZGdlW107XG4gIGhhc01vcmU6IGJvb2xlYW47XG59XG5cbi8qKlxuICogQSBub2RlIGV4cG9ydGVkIGZyb20gdGhlIGRhdGFiYXNlXG4gKiBAZGVwcmVjYXRlZCBVc2UgZXhwb3J0KCkgd2l0aCBFeHBvcnRDb25maWcgaW5zdGVhZFxuICovXG5leHBvcnQgaW50ZXJmYWNlIEV4cG9ydGVkTm9kZSB7XG4gIGlkOiBzdHJpbmc7XG4gIGxhYmVsczogc3RyaW5nW107XG4gIHByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIGFueT47XG59XG5cbi8qKlxuICogQW4gZWRnZSBleHBvcnRlZCBmcm9tIHRoZSBkYXRhYmFzZVxuICogQGRlcHJlY2F0ZWQgVXNlIGV4cG9ydCgpIHdpdGggRXhwb3J0Q29uZmlnIGluc3RlYWRcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBFeHBvcnRlZEVkZ2Uge1xuICBpZDogc3RyaW5nO1xuICBsYWJlbDogc3RyaW5nO1xuICBmcm9tTm9kZUlkOiBzdHJpbmc7XG4gIHRvTm9kZUlkOiBzdHJpbmc7XG4gIHByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIGFueT47XG59XG5cbi8qKiBSZXByZXNlbnRzIGEgbm9kZSBpbiB0aGUgZ3JhcGggZGF0YWJhc2UgKi9cbmV4cG9ydCBpbnRlcmZhY2UgTm9kZSB7XG4gIGlkOiBzdHJpbmc7XG4gIGxhYmVsczogc3RyaW5nW107XG4gIHByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIGFueT47XG59XG5cbi8qKiBSZXByZXNlbnRzIGFuIGVkZ2UgaW4gdGhlIGdyYXBoIGRhdGFiYXNlICovXG5leHBvcnQgaW50ZXJmYWNlIEVkZ2Uge1xuICBpZDogc3RyaW5nO1xuICBsYWJlbDogc3RyaW5nO1xuICBmcm9tTm9kZUlkOiBzdHJpbmc7XG4gIHRvTm9kZUlkOiBzdHJpbmc7XG4gIHByb3BlcnRpZXM6IFJlY29yZDxzdHJpbmcsIGFueT47XG59XG5cbi8qKiBSZXByZXNlbnRzIGEgcGF0aCBpbiB0aGUgZ3JhcGggZGF0YWJhc2UgKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGF0aCB7XG4gIG5vZGVzOiBOb2RlW107XG4gIGVkZ2VzOiBFZGdlW107XG59XG5cbi8qKiBSZXN1bHQgd3JhcHBlciBmb3Igbm9kZXMgd2l0aCBzY2hlbWEgaW5mb3JtYXRpb24gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTm9kZVJlc3VsdCB7XG4gIG5vZGVzOiBOb2RlW107XG4gIHNjaGVtYXM6IE1hcDxzdHJpbmcsIFNjaGVtYT47XG59XG5cbi8qKiBSZXN1bHQgd3JhcHBlciBmb3IgZWRnZXMgd2l0aCBzY2hlbWEgaW5mb3JtYXRpb24gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRWRnZVJlc3VsdCB7XG4gIGVkZ2VzOiBFZGdlW107XG4gIHNjaGVtYXM6IE1hcDxzdHJpbmcsIFNjaGVtYT47XG59XG4iXX0=