angular-odata 0.128.0 → 0.131.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 (246) hide show
  1. package/README.md +27 -244
  2. package/fesm2022/angular-odata.mjs +2320 -1118
  3. package/fesm2022/angular-odata.mjs.map +1 -1
  4. package/lib/api.d.ts +10 -11
  5. package/lib/cache/cache.d.ts +2 -2
  6. package/lib/cache/memory.d.ts +2 -2
  7. package/lib/cache/storage.d.ts +2 -2
  8. package/lib/index.d.ts +1 -0
  9. package/lib/loaders.d.ts +8 -8
  10. package/lib/metadata/csdl/csdl-annotation.d.ts +62 -26
  11. package/lib/metadata/csdl/csdl-entity-container.d.ts +8 -3
  12. package/lib/metadata/csdl/csdl-entity-set.d.ts +7 -2
  13. package/lib/metadata/csdl/csdl-enum-type.d.ts +11 -3
  14. package/lib/metadata/csdl/csdl-function-action.d.ts +54 -11
  15. package/lib/metadata/csdl/csdl-navigation-property-binding.d.ts +4 -0
  16. package/lib/metadata/csdl/csdl-reference.d.ts +26 -3
  17. package/lib/metadata/csdl/csdl-schema.d.ts +5 -2
  18. package/lib/metadata/csdl/csdl-singleton.d.ts +5 -0
  19. package/lib/metadata/csdl/csdl-structural-property.d.ts +19 -3
  20. package/lib/metadata/csdl/csdl-structured-type.d.ts +28 -7
  21. package/lib/metadata/csdl/csdl-type-definition.d.ts +3 -0
  22. package/lib/metadata/metadata.d.ts +16 -3
  23. package/lib/models/collection.d.ts +2 -1
  24. package/lib/models/model.d.ts +6 -5
  25. package/lib/models/options.d.ts +11 -4
  26. package/lib/module.d.ts +3 -3
  27. package/lib/options.d.ts +3 -3
  28. package/lib/resources/path/segments.d.ts +3 -3
  29. package/lib/resources/query/builder.d.ts +3 -2
  30. package/lib/resources/query/expressions/apply.d.ts +1 -1
  31. package/lib/resources/query/expressions/compute.d.ts +1 -1
  32. package/lib/resources/query/expressions/count.d.ts +1 -1
  33. package/lib/resources/query/expressions/expand.d.ts +5 -2
  34. package/lib/resources/query/expressions/filter.d.ts +2 -1
  35. package/lib/resources/query/expressions/orderby.d.ts +2 -1
  36. package/lib/resources/query/expressions/search.d.ts +2 -1
  37. package/lib/resources/query/expressions/select.d.ts +2 -1
  38. package/lib/resources/query/expressions/syntax.d.ts +2 -2
  39. package/lib/resources/query/handlers.d.ts +17 -5
  40. package/lib/resources/query/options.d.ts +3 -3
  41. package/lib/resources/resource.d.ts +36 -8
  42. package/lib/resources/types/action.d.ts +4 -4
  43. package/lib/resources/types/entity-set.d.ts +15 -8
  44. package/lib/resources/types/entity.d.ts +5 -1
  45. package/lib/resources/types/function.d.ts +4 -4
  46. package/lib/resources/types/navigation-property.d.ts +12 -3
  47. package/lib/resources/types/property.d.ts +14 -3
  48. package/lib/resources/types/singleton.d.ts +5 -1
  49. package/lib/schema/annotation.d.ts +3 -3
  50. package/lib/schema/callable.d.ts +3 -3
  51. package/lib/schema/element.d.ts +3 -3
  52. package/lib/schema/entity-container.d.ts +2 -2
  53. package/lib/schema/entity-set.d.ts +2 -2
  54. package/lib/schema/enum-type.d.ts +10 -10
  55. package/lib/schema/parsers/callable.d.ts +4 -4
  56. package/lib/schema/parsers/enum-type.d.ts +15 -15
  57. package/lib/schema/parsers/structured-type.d.ts +8 -5
  58. package/lib/schema/schema.d.ts +3 -3
  59. package/lib/schema/singleton.d.ts +2 -2
  60. package/lib/schema/structured-type.d.ts +7 -4
  61. package/lib/services/entity-set.d.ts +9 -6
  62. package/lib/services/entity.d.ts +1 -1
  63. package/lib/services/singleton.d.ts +1 -1
  64. package/lib/settings.d.ts +2 -2
  65. package/lib/types.d.ts +82 -69
  66. package/lib/utils/enums.d.ts +12 -12
  67. package/lib/utils/http.d.ts +1 -1
  68. package/lib/utils/objects.d.ts +1 -1
  69. package/lib/utils/odata.d.ts +2 -2
  70. package/lib/utils/strings.d.ts +2 -2
  71. package/package.json +3 -5
  72. package/schematics/apigen/angular/api-config.js +7 -1
  73. package/schematics/apigen/angular/api-config.js.map +1 -1
  74. package/schematics/apigen/angular/base.d.ts +22 -2
  75. package/schematics/apigen/angular/base.js +82 -42
  76. package/schematics/apigen/angular/base.js.map +1 -1
  77. package/schematics/apigen/angular/entity.js +7 -1
  78. package/schematics/apigen/angular/entity.js.map +1 -1
  79. package/schematics/apigen/angular/enum.js +1 -0
  80. package/schematics/apigen/angular/enum.js.map +1 -1
  81. package/schematics/apigen/angular/module.js.map +1 -1
  82. package/schematics/apigen/angular/service.js +3 -2
  83. package/schematics/apigen/angular/service.js.map +1 -1
  84. package/schematics/apigen/files/api-config/__fileName__.ts +8 -6
  85. package/schematics/apigen/files/entity/__fileName__.ts +2 -2
  86. package/schematics/apigen/files/entitycontainer-service/__fileName__.ts +1 -1
  87. package/schematics/apigen/files/entityset-service/__fileName__.ts +1 -1
  88. package/schematics/apigen/files/enum/__fileName__.ts +1 -1
  89. package/schematics/apigen/files/metadata/metadata.json +1 -0
  90. package/schematics/apigen/files/singleton-service/__fileName__.ts +1 -1
  91. package/schematics/apigen/index.js +56 -12
  92. package/schematics/apigen/index.js.map +1 -1
  93. package/schematics/apigen/metadata/csdl/csdl-annotation.d.ts +56 -23
  94. package/schematics/apigen/metadata/csdl/csdl-annotation.js +143 -13
  95. package/schematics/apigen/metadata/csdl/csdl-annotation.js.map +1 -1
  96. package/schematics/apigen/metadata/csdl/csdl-entity-container.d.ts +3 -0
  97. package/schematics/apigen/metadata/csdl/csdl-entity-container.js +19 -0
  98. package/schematics/apigen/metadata/csdl/csdl-entity-container.js.map +1 -1
  99. package/schematics/apigen/metadata/csdl/csdl-entity-set.d.ts +3 -0
  100. package/schematics/apigen/metadata/csdl/csdl-entity-set.js +11 -0
  101. package/schematics/apigen/metadata/csdl/csdl-entity-set.js.map +1 -1
  102. package/schematics/apigen/metadata/csdl/csdl-enum-type.d.ts +6 -0
  103. package/schematics/apigen/metadata/csdl/csdl-enum-type.js +17 -0
  104. package/schematics/apigen/metadata/csdl/csdl-enum-type.js.map +1 -1
  105. package/schematics/apigen/metadata/csdl/csdl-function-action.d.ts +37 -0
  106. package/schematics/apigen/metadata/csdl/csdl-function-action.js +52 -0
  107. package/schematics/apigen/metadata/csdl/csdl-function-action.js.map +1 -1
  108. package/schematics/apigen/metadata/csdl/csdl-navigation-property-binding.d.ts +4 -0
  109. package/schematics/apigen/metadata/csdl/csdl-navigation-property-binding.js +6 -0
  110. package/schematics/apigen/metadata/csdl/csdl-navigation-property-binding.js.map +1 -1
  111. package/schematics/apigen/metadata/csdl/csdl-reference.d.ts +15 -3
  112. package/schematics/apigen/metadata/csdl/csdl-reference.js +26 -2
  113. package/schematics/apigen/metadata/csdl/csdl-reference.js.map +1 -1
  114. package/schematics/apigen/metadata/csdl/csdl-schema.d.ts +3 -0
  115. package/schematics/apigen/metadata/csdl/csdl-schema.js +37 -0
  116. package/schematics/apigen/metadata/csdl/csdl-schema.js.map +1 -1
  117. package/schematics/apigen/metadata/csdl/csdl-singleton.d.ts +3 -0
  118. package/schematics/apigen/metadata/csdl/csdl-singleton.js +8 -0
  119. package/schematics/apigen/metadata/csdl/csdl-singleton.js.map +1 -1
  120. package/schematics/apigen/metadata/csdl/csdl-structural-property.d.ts +16 -0
  121. package/schematics/apigen/metadata/csdl/csdl-structural-property.js +53 -0
  122. package/schematics/apigen/metadata/csdl/csdl-structural-property.js.map +1 -1
  123. package/schematics/apigen/metadata/csdl/csdl-structured-type.d.ts +22 -3
  124. package/schematics/apigen/metadata/csdl/csdl-structured-type.js +47 -2
  125. package/schematics/apigen/metadata/csdl/csdl-structured-type.js.map +1 -1
  126. package/schematics/apigen/metadata/csdl/csdl-type-definition.d.ts +3 -0
  127. package/schematics/apigen/metadata/csdl/csdl-type-definition.js +19 -0
  128. package/schematics/apigen/metadata/csdl/csdl-type-definition.js.map +1 -1
  129. package/schematics/apigen/metadata/metadata.d.ts +10 -0
  130. package/schematics/apigen/metadata/metadata.js +12 -6
  131. package/schematics/apigen/metadata/metadata.js.map +1 -1
  132. package/schematics/apigen/metadata/parser.js.map +1 -1
  133. package/schematics/apigen/schema.d.ts +2 -1
  134. package/schematics/apigen/schema.json +15 -14
  135. package/schematics/apigen/utils.d.ts +1 -0
  136. package/schematics/apigen/utils.js +25 -1
  137. package/schematics/apigen/utils.js.map +1 -1
  138. package/schematics/ng-add/index.js +1 -2
  139. package/schematics/ng-add/index.js.map +1 -1
  140. package/esm2022/angular-odata.mjs +0 -5
  141. package/esm2022/lib/annotations.mjs +0 -140
  142. package/esm2022/lib/api.mjs +0 -419
  143. package/esm2022/lib/cache/cache.mjs +0 -175
  144. package/esm2022/lib/cache/index.mjs +0 -4
  145. package/esm2022/lib/cache/memory.mjs +0 -30
  146. package/esm2022/lib/cache/storage.mjs +0 -55
  147. package/esm2022/lib/client.mjs +0 -212
  148. package/esm2022/lib/constants.mjs +0 -95
  149. package/esm2022/lib/helper.mjs +0 -280
  150. package/esm2022/lib/index.mjs +0 -21
  151. package/esm2022/lib/loaders.mjs +0 -39
  152. package/esm2022/lib/metadata/csdl/csdl-annotation.mjs +0 -95
  153. package/esm2022/lib/metadata/csdl/csdl-entity-container.mjs +0 -27
  154. package/esm2022/lib/metadata/csdl/csdl-entity-set.mjs +0 -24
  155. package/esm2022/lib/metadata/csdl/csdl-enum-type.mjs +0 -37
  156. package/esm2022/lib/metadata/csdl/csdl-function-action.mjs +0 -94
  157. package/esm2022/lib/metadata/csdl/csdl-navigation-property-binding.mjs +0 -7
  158. package/esm2022/lib/metadata/csdl/csdl-reference.mjs +0 -23
  159. package/esm2022/lib/metadata/csdl/csdl-schema.mjs +0 -39
  160. package/esm2022/lib/metadata/csdl/csdl-singleton.mjs +0 -15
  161. package/esm2022/lib/metadata/csdl/csdl-structural-property.mjs +0 -70
  162. package/esm2022/lib/metadata/csdl/csdl-structured-type.mjs +0 -92
  163. package/esm2022/lib/metadata/csdl/csdl-type-definition.mjs +0 -15
  164. package/esm2022/lib/metadata/index.mjs +0 -3
  165. package/esm2022/lib/metadata/metadata.mjs +0 -14
  166. package/esm2022/lib/metadata/parser.mjs +0 -563
  167. package/esm2022/lib/models/collection.mjs +0 -814
  168. package/esm2022/lib/models/index.mjs +0 -4
  169. package/esm2022/lib/models/model.mjs +0 -553
  170. package/esm2022/lib/models/options.mjs +0 -1179
  171. package/esm2022/lib/module.mjs +0 -55
  172. package/esm2022/lib/options.mjs +0 -36
  173. package/esm2022/lib/resources/index.mjs +0 -7
  174. package/esm2022/lib/resources/options.mjs +0 -56
  175. package/esm2022/lib/resources/path/handlers.mjs +0 -79
  176. package/esm2022/lib/resources/path/index.mjs +0 -3
  177. package/esm2022/lib/resources/path/segments.mjs +0 -148
  178. package/esm2022/lib/resources/query/builder.mjs +0 -636
  179. package/esm2022/lib/resources/query/expressions/apply.mjs +0 -236
  180. package/esm2022/lib/resources/query/expressions/base.mjs +0 -25
  181. package/esm2022/lib/resources/query/expressions/compute.mjs +0 -54
  182. package/esm2022/lib/resources/query/expressions/count.mjs +0 -116
  183. package/esm2022/lib/resources/query/expressions/expand.mjs +0 -147
  184. package/esm2022/lib/resources/query/expressions/filter.mjs +0 -178
  185. package/esm2022/lib/resources/query/expressions/index.mjs +0 -10
  186. package/esm2022/lib/resources/query/expressions/orderby.mjs +0 -79
  187. package/esm2022/lib/resources/query/expressions/search.mjs +0 -141
  188. package/esm2022/lib/resources/query/expressions/select.mjs +0 -47
  189. package/esm2022/lib/resources/query/expressions/syntax.mjs +0 -751
  190. package/esm2022/lib/resources/query/handlers.mjs +0 -420
  191. package/esm2022/lib/resources/query/index.mjs +0 -5
  192. package/esm2022/lib/resources/query/options.mjs +0 -139
  193. package/esm2022/lib/resources/request.mjs +0 -196
  194. package/esm2022/lib/resources/resource.mjs +0 -311
  195. package/esm2022/lib/resources/response.mjs +0 -174
  196. package/esm2022/lib/resources/types/action.mjs +0 -116
  197. package/esm2022/lib/resources/types/batch.mjs +0 -428
  198. package/esm2022/lib/resources/types/count.mjs +0 -33
  199. package/esm2022/lib/resources/types/entity-set.mjs +0 -131
  200. package/esm2022/lib/resources/types/entity.mjs +0 -112
  201. package/esm2022/lib/resources/types/function.mjs +0 -146
  202. package/esm2022/lib/resources/types/index.mjs +0 -15
  203. package/esm2022/lib/resources/types/media.mjs +0 -44
  204. package/esm2022/lib/resources/types/metadata.mjs +0 -35
  205. package/esm2022/lib/resources/types/navigation-property.mjs +0 -256
  206. package/esm2022/lib/resources/types/options.mjs +0 -2
  207. package/esm2022/lib/resources/types/property.mjs +0 -197
  208. package/esm2022/lib/resources/types/reference.mjs +0 -87
  209. package/esm2022/lib/resources/types/singleton.mjs +0 -130
  210. package/esm2022/lib/resources/types/value.mjs +0 -48
  211. package/esm2022/lib/schema/annotation.mjs +0 -37
  212. package/esm2022/lib/schema/callable.mjs +0 -66
  213. package/esm2022/lib/schema/element.mjs +0 -67
  214. package/esm2022/lib/schema/entity-container.mjs +0 -11
  215. package/esm2022/lib/schema/entity-set.mjs +0 -9
  216. package/esm2022/lib/schema/enum-type.mjs +0 -68
  217. package/esm2022/lib/schema/index.mjs +0 -9
  218. package/esm2022/lib/schema/parsers/callable.mjs +0 -110
  219. package/esm2022/lib/schema/parsers/edm.mjs +0 -101
  220. package/esm2022/lib/schema/parsers/enum-type.mjs +0 -130
  221. package/esm2022/lib/schema/parsers/index.mjs +0 -5
  222. package/esm2022/lib/schema/parsers/structured-type.mjs +0 -514
  223. package/esm2022/lib/schema/schema.mjs +0 -45
  224. package/esm2022/lib/schema/singleton.mjs +0 -9
  225. package/esm2022/lib/schema/structured-type.mjs +0 -213
  226. package/esm2022/lib/services/base.mjs +0 -29
  227. package/esm2022/lib/services/entity-set.mjs +0 -155
  228. package/esm2022/lib/services/entity.mjs +0 -12
  229. package/esm2022/lib/services/factory.mjs +0 -44
  230. package/esm2022/lib/services/index.mjs +0 -5
  231. package/esm2022/lib/services/singleton.mjs +0 -54
  232. package/esm2022/lib/settings.mjs +0 -112
  233. package/esm2022/lib/types.mjs +0 -118
  234. package/esm2022/lib/utils/arraybuffers.mjs +0 -46
  235. package/esm2022/lib/utils/arrays.mjs +0 -10
  236. package/esm2022/lib/utils/dates.mjs +0 -18
  237. package/esm2022/lib/utils/durations.mjs +0 -40
  238. package/esm2022/lib/utils/enums.mjs +0 -61
  239. package/esm2022/lib/utils/http.mjs +0 -95
  240. package/esm2022/lib/utils/index.mjs +0 -10
  241. package/esm2022/lib/utils/objects.mjs +0 -204
  242. package/esm2022/lib/utils/odata.mjs +0 -22
  243. package/esm2022/lib/utils/strings.mjs +0 -20
  244. package/esm2022/lib/utils/types.mjs +0 -136
  245. package/esm2022/lib/utils/urls.mjs +0 -24
  246. package/esm2022/public-api.mjs +0 -5
@@ -1,636 +0,0 @@
1
- const COMPARISON_OPERATORS = ['eq', 'ne', 'gt', 'ge', 'lt', 'le'];
2
- const LOGICAL_OPERATORS = ['and', 'or', 'not'];
3
- const COLLECTION_OPERATORS = ['any', 'all'];
4
- const BOOLEAN_FUNCTIONS = ['startswith', 'endswith', 'contains'];
5
- const SUPPORTED_EXPAND_PROPERTIES = [
6
- 'expand',
7
- 'levels',
8
- 'select',
9
- 'top',
10
- 'count',
11
- 'orderby',
12
- 'filter',
13
- ];
14
- const FUNCTION_REGEX = /\((.*)\)/;
15
- const INDEXOF_REGEX = /(?!indexof)\((\w+)\)/;
16
- export var StandardAggregateMethods;
17
- (function (StandardAggregateMethods) {
18
- StandardAggregateMethods["sum"] = "sum";
19
- StandardAggregateMethods["min"] = "min";
20
- StandardAggregateMethods["max"] = "max";
21
- StandardAggregateMethods["average"] = "average";
22
- StandardAggregateMethods["countdistinct"] = "countdistinct";
23
- })(StandardAggregateMethods || (StandardAggregateMethods = {}));
24
- export var QueryCustomTypes;
25
- (function (QueryCustomTypes) {
26
- QueryCustomTypes[QueryCustomTypes["Raw"] = 0] = "Raw";
27
- QueryCustomTypes[QueryCustomTypes["Alias"] = 1] = "Alias";
28
- QueryCustomTypes[QueryCustomTypes["Duration"] = 2] = "Duration";
29
- QueryCustomTypes[QueryCustomTypes["Binary"] = 3] = "Binary";
30
- })(QueryCustomTypes || (QueryCustomTypes = {}));
31
- //https://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_QueryOptions
32
- export const raw = (value) => ({
33
- type: QueryCustomTypes.Raw,
34
- value,
35
- });
36
- export const alias = (value, name) => ({
37
- type: QueryCustomTypes.Alias,
38
- value,
39
- name,
40
- });
41
- export const duration = (value) => ({
42
- type: QueryCustomTypes.Duration,
43
- value,
44
- });
45
- export const binary = (value) => ({
46
- type: QueryCustomTypes.Binary,
47
- value,
48
- });
49
- export const isQueryCustomType = (value) => typeof value === 'object' &&
50
- 'type' in value &&
51
- value.type in QueryCustomTypes;
52
- export const isRawType = (value) => isQueryCustomType(value) &&
53
- value.type === QueryCustomTypes.Raw;
54
- export const ITEM_ROOT = '';
55
- export default function ({ select, search, skiptoken, format, top, skip, filter, transform, orderBy, key, count, expand, action, func, aliases, escape, } = {}) {
56
- const [path, params] = buildPathAndQuery({
57
- select,
58
- search,
59
- skiptoken,
60
- format,
61
- top,
62
- skip,
63
- filter,
64
- transform,
65
- orderBy,
66
- key,
67
- count,
68
- expand,
69
- action,
70
- func,
71
- aliases,
72
- escape,
73
- });
74
- return buildUrl(path, params);
75
- }
76
- export function buildPathAndQuery({ select, search, skiptoken, format, top, skip, filter, apply, transform, orderBy, key, count, expand, action, func, aliases, escape, } = {}) {
77
- let path = '';
78
- aliases = aliases || [];
79
- const query = {};
80
- // key is not (null, undefined)
81
- if (key != undefined) {
82
- path += `(${normalizeValue(key, { aliases, escape })})`;
83
- }
84
- // Select
85
- if (select) {
86
- query.$select = isRawType(select)
87
- ? select.value
88
- : Array.isArray(select)
89
- ? select.join(',')
90
- : select;
91
- }
92
- // Search
93
- if (search) {
94
- query.$search = search;
95
- }
96
- // Skiptoken
97
- if (skiptoken) {
98
- query.$skiptoken = skiptoken;
99
- }
100
- // Format
101
- if (format) {
102
- query.$format = format;
103
- }
104
- // Filter
105
- if (filter || typeof count === 'object') {
106
- query.$filter = buildFilter(typeof count === 'object' ? count : filter, {
107
- aliases,
108
- escape,
109
- });
110
- }
111
- // Transform
112
- if (transform) {
113
- query.$apply = buildTransforms(transform, { aliases, escape });
114
- }
115
- // Apply
116
- if (apply) {
117
- query.$apply = query.$apply
118
- ? query.$apply + '/' + buildApply(apply, { aliases, escape })
119
- : buildApply(apply, { aliases, escape });
120
- }
121
- // Expand
122
- if (expand) {
123
- query.$expand = buildExpand(expand, { aliases, escape });
124
- }
125
- // OrderBy
126
- if (orderBy) {
127
- query.$orderby = buildOrderBy(orderBy);
128
- }
129
- // Count
130
- if (isRawType(count)) {
131
- query.$count = count.value;
132
- }
133
- else if (typeof count === 'boolean') {
134
- query.$count = true;
135
- }
136
- else if (count) {
137
- path += '/$count';
138
- }
139
- // Top
140
- if (isRawType(top)) {
141
- query.$top = top.value;
142
- }
143
- else if (typeof top === 'number') {
144
- query.$top = top;
145
- }
146
- // Skip
147
- if (isRawType(skip)) {
148
- query.$top = skip.value;
149
- }
150
- else if (typeof skip === 'number') {
151
- query.$skip = skip;
152
- }
153
- if (action) {
154
- path += `/${action}`;
155
- }
156
- if (func) {
157
- if (typeof func === 'string') {
158
- path += `/${func}()`;
159
- }
160
- else if (typeof func === 'object') {
161
- const [funcName] = Object.keys(func);
162
- const funcArgs = normalizeValue(func[funcName], {
163
- aliases,
164
- escape,
165
- });
166
- path += `/${funcName}(${funcArgs})`;
167
- }
168
- }
169
- if (aliases.length > 0) {
170
- Object.assign(query, aliases.reduce((acc, alias) => Object.assign(acc, {
171
- [`@${alias.name}`]: normalizeValue(alias.value, {
172
- escape,
173
- }),
174
- }), {}));
175
- }
176
- // Filter empty values
177
- const params = Object.entries(query)
178
- .filter(([, value]) => value !== undefined && value !== '')
179
- .reduce((acc, [key, value]) => Object.assign(acc, { [key]: value }), {});
180
- return [path, params];
181
- }
182
- function renderPrimitiveValue(key, val, { aliases, escape, }) {
183
- return `${key} eq ${normalizeValue(val, { aliases, escape })}`;
184
- }
185
- function buildFilter(filters = {}, { aliases, propPrefix, escape, }) {
186
- return (Array.isArray(filters) ? filters : [filters]).reduce((acc, filter) => {
187
- if (filter) {
188
- const builtFilter = buildFilterCore(filter, {
189
- aliases,
190
- propPrefix,
191
- escape,
192
- });
193
- if (builtFilter) {
194
- acc.push(builtFilter);
195
- }
196
- }
197
- return acc;
198
- }, []).join(' and ');
199
- function buildFilterCore(filter = {}, { aliases, propPrefix, escape, }) {
200
- let filterExpr = '';
201
- if (isRawType(filter)) {
202
- // Use raw query custom filter string
203
- filterExpr = filter.value;
204
- }
205
- else if (typeof filter === 'string') {
206
- // Use raw filter string
207
- filterExpr = filter;
208
- }
209
- else if (filter && typeof filter === 'object') {
210
- const filtersArray = Object.keys(filter).reduce((result, filterKey) => {
211
- const value = filter[filterKey];
212
- let propName = '';
213
- if (propPrefix) {
214
- if (filterKey === ITEM_ROOT) {
215
- propName = propPrefix;
216
- }
217
- else if (INDEXOF_REGEX.test(filterKey)) {
218
- propName = filterKey.replace(INDEXOF_REGEX, (_, $1) => $1.trim() === ITEM_ROOT
219
- ? `(${propPrefix})`
220
- : `(${propPrefix}/${$1.trim()})`);
221
- }
222
- else if (FUNCTION_REGEX.test(filterKey)) {
223
- propName = filterKey.replace(FUNCTION_REGEX, (_, $1) => $1.trim() === ITEM_ROOT
224
- ? `(${propPrefix})`
225
- : `(${propPrefix}/${$1.trim()})`);
226
- }
227
- else {
228
- propName = `${propPrefix}/${filterKey}`;
229
- }
230
- }
231
- else {
232
- propName = filterKey;
233
- }
234
- if (filterKey === ITEM_ROOT && Array.isArray(value)) {
235
- return result.concat(value.map((arrayValue) => renderPrimitiveValue(propName, arrayValue, { escape, aliases })));
236
- }
237
- if (['number', 'string', 'boolean'].indexOf(typeof value) !== -1 ||
238
- value instanceof Date ||
239
- value === null) {
240
- // Simple key/value handled as equals operator
241
- result.push(renderPrimitiveValue(propName, value, { aliases, escape }));
242
- }
243
- else if (Array.isArray(value)) {
244
- const op = filterKey;
245
- const builtFilters = value
246
- .map((v) => buildFilter(v, { aliases, propPrefix, escape }))
247
- .filter((f) => f)
248
- .map((f) => LOGICAL_OPERATORS.indexOf(op) !== -1 ? `(${f})` : f);
249
- if (builtFilters.length) {
250
- if (LOGICAL_OPERATORS.indexOf(op) !== -1) {
251
- if (builtFilters.length) {
252
- if (op === 'not') {
253
- result.push(parseNot(builtFilters));
254
- }
255
- else {
256
- result.push(`(${builtFilters.join(` ${op} `)})`);
257
- }
258
- }
259
- }
260
- else {
261
- result.push(builtFilters.join(` ${op} `));
262
- }
263
- }
264
- }
265
- else if (LOGICAL_OPERATORS.indexOf(propName) !== -1) {
266
- const op = propName;
267
- const builtFilters = Object.keys(value).map((valueKey) => buildFilterCore({ [valueKey]: value[valueKey] }, { aliases, escape }));
268
- if (builtFilters.length) {
269
- if (op === 'not') {
270
- result.push(parseNot(builtFilters));
271
- }
272
- else {
273
- result.push(`${builtFilters.join(` ${op} `)}`);
274
- }
275
- }
276
- }
277
- else if (typeof value === 'object') {
278
- if ('type' in value) {
279
- result.push(renderPrimitiveValue(propName, value, { aliases, escape }));
280
- }
281
- else {
282
- const operators = Object.keys(value);
283
- operators.forEach((op) => {
284
- if (COMPARISON_OPERATORS.indexOf(op) !== -1) {
285
- result.push(`${propName} ${op} ${normalizeValue(value[op], {
286
- aliases,
287
- escape,
288
- })}`);
289
- }
290
- else if (LOGICAL_OPERATORS.indexOf(op) !== -1) {
291
- if (Array.isArray(value[op])) {
292
- result.push(value[op]
293
- .map((v) => '(' +
294
- buildFilterCore(v, {
295
- aliases,
296
- propPrefix: propName,
297
- escape,
298
- }) +
299
- ')')
300
- .join(` ${op} `));
301
- }
302
- else {
303
- result.push('(' +
304
- buildFilterCore(value[op], {
305
- aliases,
306
- propPrefix: propName,
307
- escape,
308
- }) +
309
- ')');
310
- }
311
- }
312
- else if (COLLECTION_OPERATORS.indexOf(op) !== -1) {
313
- const collectionClause = buildCollectionClause(filterKey.toLowerCase(), value[op], op, propName);
314
- if (collectionClause) {
315
- result.push(collectionClause);
316
- }
317
- }
318
- else if (op === 'has') {
319
- result.push(`${propName} ${op} ${normalizeValue(value[op], {
320
- aliases,
321
- escape,
322
- })}`);
323
- }
324
- else if (op === 'in') {
325
- const resultingValues = Array.isArray(value[op])
326
- ? value[op]
327
- : value[op].value.map((typedValue) => ({
328
- type: value[op].type,
329
- value: typedValue,
330
- }));
331
- result.push(propName +
332
- ' in (' +
333
- resultingValues
334
- .map((v) => normalizeValue(v, { aliases, escape }))
335
- .join(',') +
336
- ')');
337
- }
338
- else if (BOOLEAN_FUNCTIONS.indexOf(op) !== -1) {
339
- // Simple boolean functions (startswith, endswith, contains)
340
- result.push(`${op}(${propName},${normalizeValue(value[op], {
341
- aliases,
342
- escape,
343
- })})`);
344
- }
345
- else {
346
- // Nested property
347
- const filter = buildFilterCore(value, {
348
- aliases,
349
- propPrefix: propName,
350
- escape,
351
- });
352
- if (filter) {
353
- result.push(filter);
354
- }
355
- }
356
- });
357
- }
358
- }
359
- else if (value === undefined) {
360
- // Ignore/omit filter if value is `undefined`
361
- }
362
- else {
363
- throw new Error(`Unexpected value type: ${value}`);
364
- }
365
- return result;
366
- }, []);
367
- filterExpr = filtersArray.join(' and ');
368
- } /* else {
369
- throw new Error(`Unexpected filters type: ${filter}`);
370
- } */
371
- return filterExpr;
372
- }
373
- function buildCollectionClause(lambdaParameter, value, op, propName) {
374
- let clause = '';
375
- if (typeof value === 'string' || value instanceof String) {
376
- clause = getStringCollectionClause(lambdaParameter, value, op, propName);
377
- }
378
- else if (value) {
379
- // normalize {any:[{prop1: 1}, {prop2: 1}]} --> {any:{prop1: 1, prop2: 1}}; same for 'all',
380
- // simple values collection: {any:[{'': 'simpleVal1'}, {'': 'simpleVal2'}]} --> {any:{'': ['simpleVal1', 'simpleVal2']}}; same for 'all',
381
- const filterValue = Array.isArray(value)
382
- ? value.reduce((acc, item) => {
383
- if (item.hasOwnProperty(ITEM_ROOT)) {
384
- if (!acc.hasOwnProperty(ITEM_ROOT)) {
385
- acc[ITEM_ROOT] = [];
386
- }
387
- acc[ITEM_ROOT].push(item[ITEM_ROOT]);
388
- return acc;
389
- }
390
- return { ...acc, ...item };
391
- }, {})
392
- : value;
393
- const filter = buildFilterCore(filterValue, {
394
- aliases,
395
- propPrefix: lambdaParameter,
396
- escape,
397
- });
398
- clause = `${propName}/${op}(${filter ? `${lambdaParameter}:${filter}` : ''})`;
399
- }
400
- return clause;
401
- }
402
- }
403
- function getStringCollectionClause(lambdaParameter, value, collectionOperator, propName) {
404
- let clause = '';
405
- const conditionOperator = collectionOperator == 'all' ? 'ne' : 'eq';
406
- clause = `${propName}/${collectionOperator}(${lambdaParameter}: ${lambdaParameter} ${conditionOperator} '${value}')`;
407
- return clause;
408
- }
409
- function escapeIllegalChars(string) {
410
- string = string.replace(/%/g, '%25');
411
- string = string.replace(/\+/g, '%2B');
412
- string = string.replace(/\//g, '%2F');
413
- string = string.replace(/\?/g, '%3F');
414
- string = string.replace(/#/g, '%23');
415
- string = string.replace(/&/g, '%26');
416
- string = string.replace(/'/g, "''");
417
- return string;
418
- }
419
- export function normalizeValue(value, { aliases, escape = false, } = {}) {
420
- if (typeof value === 'string') {
421
- return escape ? `'${escapeIllegalChars(value)}'` : `'${value}'`;
422
- }
423
- else if (value instanceof Date) {
424
- return value.toISOString();
425
- }
426
- else if (typeof value === 'number') {
427
- return value;
428
- }
429
- else if (Array.isArray(value)) {
430
- return `[${value
431
- .map((d) => normalizeValue(d, { aliases, escape }))
432
- .join(',')}]`;
433
- }
434
- else if (value === null) {
435
- return value;
436
- }
437
- else if (typeof value === 'object') {
438
- switch (value.type) {
439
- case QueryCustomTypes.Raw:
440
- return value.value;
441
- case QueryCustomTypes.Duration:
442
- return `duration'${value.value}'`;
443
- case QueryCustomTypes.Binary:
444
- return `binary'${value.value}'`;
445
- case QueryCustomTypes.Alias:
446
- // Store
447
- if (Array.isArray(aliases)) {
448
- if (value.name === undefined) {
449
- value.name = `a${aliases.length + 1}`;
450
- }
451
- aliases.push(value);
452
- }
453
- return `@${value.name}`;
454
- default:
455
- return Object.entries(value)
456
- .filter(([, v]) => v !== undefined)
457
- .map(([k, v]) => `${k}=${normalizeValue(v, { aliases, escape })}`)
458
- .join(',');
459
- }
460
- }
461
- return value;
462
- }
463
- function buildExpand(expands, { aliases, escape = false, }) {
464
- if (isRawType(expands)) {
465
- return expands.value;
466
- }
467
- else if (typeof expands === 'number') {
468
- return expands;
469
- }
470
- else if (typeof expands === 'string') {
471
- if (expands.indexOf('/') === -1) {
472
- return expands;
473
- }
474
- // Change `Foo/Bar/Baz` to `Foo($expand=Bar($expand=Baz))`
475
- return expands
476
- .split('/')
477
- .reverse()
478
- .reduce((results, item, index, arr) => {
479
- if (index === 0) {
480
- // Inner-most item
481
- return `$expand=${item}`;
482
- }
483
- else if (index === arr.length - 1) {
484
- // Outer-most item, don't add `$expand=` prefix (added above)
485
- return `${item}(${results})`;
486
- }
487
- else {
488
- // Other items
489
- return `$expand=${item}(${results})`;
490
- }
491
- }, '');
492
- }
493
- else if (Array.isArray(expands)) {
494
- return `${expands
495
- .map((e) => buildExpand(e, { aliases, escape }))
496
- .join(',')}`;
497
- }
498
- else if (typeof expands === 'object') {
499
- const expandKeys = Object.keys(expands);
500
- if (expandKeys.some((key) => SUPPORTED_EXPAND_PROPERTIES.indexOf(key.toLowerCase()) !== -1)) {
501
- return expandKeys
502
- .map((key) => {
503
- let value;
504
- switch (key) {
505
- case 'filter':
506
- value = buildFilter(expands[key], {
507
- aliases,
508
- escape,
509
- });
510
- break;
511
- case 'orderBy':
512
- value = buildOrderBy(expands[key]);
513
- break;
514
- case 'levels':
515
- case 'count':
516
- case 'top':
517
- case 'skip':
518
- value = `${expands[key]}`;
519
- if (isRawType(value))
520
- value = value.value;
521
- break;
522
- default:
523
- value = buildExpand(expands[key], { aliases, escape });
524
- }
525
- return `$${key.toLowerCase()}=${value}`;
526
- })
527
- .join(';');
528
- }
529
- else {
530
- return expandKeys
531
- .map((key) => {
532
- const builtExpand = buildExpand(expands[key], { aliases, escape });
533
- return builtExpand ? `${key}(${builtExpand})` : key;
534
- })
535
- .join(',');
536
- }
537
- }
538
- return '';
539
- }
540
- function buildTransforms(transforms, { aliases, escape = false, }) {
541
- // Wrap single object an array for simplified processing
542
- const transformsArray = Array.isArray(transforms) ? transforms : [transforms];
543
- const transformsResult = transformsArray.reduce((result, transform) => {
544
- const { aggregate, filter, groupBy, ...rest } = transform;
545
- // TODO: support as many of the following:
546
- // topcount, topsum, toppercent,
547
- // bottomsum, bottomcount, bottompercent,
548
- // identity, concat, expand, search, compute, isdefined
549
- const unsupportedKeys = Object.keys(rest);
550
- if (unsupportedKeys.length) {
551
- throw new Error(`Unsupported transform(s): ${unsupportedKeys}`);
552
- }
553
- if (aggregate) {
554
- result.push(`aggregate(${buildAggregate(aggregate)})`);
555
- }
556
- if (filter) {
557
- const builtFilter = buildFilter(filter, { aliases, escape });
558
- if (builtFilter) {
559
- result.push(`filter(${buildFilter(builtFilter, { aliases, escape })})`);
560
- }
561
- }
562
- if (groupBy) {
563
- result.push(`groupby(${buildGroupBy(groupBy, { aliases, escape })})`);
564
- }
565
- return result;
566
- }, []);
567
- return transformsResult.join('/') || undefined;
568
- }
569
- function buildAggregate(aggregate) {
570
- // Wrap single object in an array for simplified processing
571
- const aggregateArray = Array.isArray(aggregate) ? aggregate : [aggregate];
572
- return aggregateArray
573
- .map((aggregateItem) => {
574
- return typeof aggregateItem === 'string'
575
- ? aggregateItem
576
- : Object.keys(aggregateItem).map((aggregateKey) => {
577
- const aggregateValue = aggregateItem[aggregateKey];
578
- // TODO: Are these always required? Can/should we default them if so?
579
- if (!aggregateValue.with) {
580
- throw new Error(`'with' property required for '${aggregateKey}'`);
581
- }
582
- if (!aggregateValue.as) {
583
- throw new Error(`'as' property required for '${aggregateKey}'`);
584
- }
585
- return `${aggregateKey} with ${aggregateValue.with} as ${aggregateValue.as}`;
586
- });
587
- })
588
- .join(',');
589
- }
590
- function buildGroupBy(groupBy, { aliases, escape = false, }) {
591
- if (!groupBy.properties) {
592
- throw new Error(`'properties' property required for groupBy`);
593
- }
594
- let result = `(${groupBy.properties.join(',')})`;
595
- if (groupBy.transform) {
596
- result += `,${buildTransforms(groupBy.transform, { aliases, escape })}`;
597
- }
598
- return result;
599
- }
600
- function buildOrderBy(orderBy, prefix = '') {
601
- if (isRawType(orderBy)) {
602
- return orderBy.value;
603
- }
604
- else if (Array.isArray(orderBy)) {
605
- return orderBy
606
- .map((value) => Array.isArray(value) &&
607
- value.length === 2 &&
608
- ['asc', 'desc'].indexOf(value[1]) !== -1
609
- ? value.join(' ')
610
- : value)
611
- .map((v) => `${prefix}${v}`)
612
- .join(',');
613
- }
614
- else if (typeof orderBy === 'object') {
615
- return Object.entries(orderBy)
616
- .map(([k, v]) => buildOrderBy(v, `${k}/`))
617
- .map((v) => `${prefix}${v}`)
618
- .join(',');
619
- }
620
- return `${prefix}${orderBy}`;
621
- }
622
- function buildApply(apply, { aliases, escape = false, }) {
623
- const applyArray = Array.isArray(apply) ? apply : [apply];
624
- return applyArray
625
- .map((v) => normalizeValue(v, { aliases, escape }))
626
- .join('/');
627
- }
628
- function buildUrl(path, params) {
629
- // This can be refactored using URL API. But IE does not support it.
630
- const queries = Object.entries(params).map(([key, value]) => `${key}=${value}`);
631
- return queries.length ? `${path}?${queries.join('&')}` : path;
632
- }
633
- function parseNot(builtFilters) {
634
- return `not(${builtFilters.join(' and ')})`;
635
- }
636
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItb2RhdGEvc3JjL2xpYi9yZXNvdXJjZXMvcXVlcnkvYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLG9CQUFvQixHQUFHLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNsRSxNQUFNLGlCQUFpQixHQUFHLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztBQUMvQyxNQUFNLG9CQUFvQixHQUFHLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQzVDLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxZQUFZLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ2pFLE1BQU0sMkJBQTJCLEdBQUc7SUFDbEMsUUFBUTtJQUNSLFFBQVE7SUFDUixRQUFRO0lBQ1IsS0FBSztJQUNMLE9BQU87SUFDUCxTQUFTO0lBQ1QsUUFBUTtDQUNULENBQUM7QUFFRixNQUFNLGNBQWMsR0FBRyxVQUFVLENBQUM7QUFDbEMsTUFBTSxhQUFhLEdBQUcsc0JBQXNCLENBQUM7QUFRN0MsTUFBTSxDQUFOLElBQVksd0JBTVg7QUFORCxXQUFZLHdCQUF3QjtJQUNsQyx1Q0FBVyxDQUFBO0lBQ1gsdUNBQVcsQ0FBQTtJQUNYLHVDQUFXLENBQUE7SUFDWCwrQ0FBbUIsQ0FBQTtJQUNuQiwyREFBK0IsQ0FBQTtBQUNqQyxDQUFDLEVBTlcsd0JBQXdCLEtBQXhCLHdCQUF3QixRQU1uQztBQTZDRCxNQUFNLENBQU4sSUFBWSxnQkFLWDtBQUxELFdBQVksZ0JBQWdCO0lBQzFCLHFEQUFHLENBQUE7SUFDSCx5REFBSyxDQUFBO0lBQ0wsK0RBQVEsQ0FBQTtJQUNSLDJEQUFNLENBQUE7QUFDUixDQUFDLEVBTFcsZ0JBQWdC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QUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxRCxPQUFPLFVBQVU7U0FDZCxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLGNBQWMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQztTQUNsRCxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDZixDQUFDO0FBRUQsU0FBUyxRQUFRLENBQUMsSUFBWSxFQUFFLE1BQStCO0lBQzdELG9FQUFvRTtJQUNwRSxNQUFNLE9BQU8sR0FBYSxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FDbEQsQ0FBQyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxHQUFHLElBQUksS0FBSyxFQUFFLENBQ3BDLENBQUM7SUFDRixPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0FBQ2hFLENBQUM7QUFFRCxTQUFTLFFBQVEsQ0FBQyxZQUFzQjtJQUN0QyxPQUFPLE9BQU8sWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDO0FBQzlDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBDT01QQVJJU09OX09QRVJBVE9SUyA9IFsnZXEnLCAnbmUnLCAnZ3QnLCAnZ2UnLCAnbHQnLCAnbGUnXTtcbmNvbnN0IExPR0lDQUxfT1BFUkFUT1JTID0gWydhbmQnLCAnb3InLCAnbm90J107XG5jb25zdCBDT0xMRUNUSU9OX09QRVJBVE9SUyA9IFsnYW55JywgJ2FsbCddO1xuY29uc3QgQk9PTEVBTl9GVU5DVElPTlMgPSBbJ3N0YXJ0c3dpdGgnLCAnZW5kc3dpdGgnLCAnY29udGFpbnMnXTtcbmNvbnN0IFNVUFBPUlRFRF9FWFBBTkRfUFJPUEVSVElFUyA9IFtcbiAgJ2V4cGFuZCcsXG4gICdsZXZlbHMnLFxuICAnc2VsZWN0JyxcbiAgJ3RvcCcsXG4gICdjb3VudCcsXG4gICdvcmRlcmJ5JyxcbiAgJ2ZpbHRlcicsXG5dO1xuXG5jb25zdCBGVU5DVElPTl9SRUdFWCA9IC9cXCgoLiopXFwpLztcbmNvbnN0IElOREVYT0ZfUkVHRVggPSAvKD8haW5kZXhvZilcXCgoXFx3KylcXCkvO1xuXG5leHBvcnQgdHlwZSBVbnBhY2tlZDxUPiA9IFQgZXh0ZW5kcyAoaW5mZXIgVSlbXSA/IFUgOiBUO1xuZXhwb3J0IHR5cGUgU2VsZWN0PFQ+ID0gU2VsZWN0VHlwZTxUPiB8IFNlbGVjdFR5cGU8VD5bXTtcbmV4cG9ydCB0eXBlIFNlbGVjdFR5cGU8VD4gPSBzdHJpbmcgfCBrZXlvZiBUO1xuZXhwb3J0IHR5cGUgRmlsdGVyPFQ+ID0gRmlsdGVyVHlwZSB8IEZpbHRlclR5cGVbXTtcbmV4cG9ydCB0eXBlIEZpbHRlclR5cGUgPSBzdHJpbmcgfCB7IFtuYW1lOiBzdHJpbmddOiBhbnkgfTtcblxuZXhwb3J0IGVudW0gU3RhbmRhcmRBZ2dyZWdhdGVNZXRob2RzIHtcbiAgc3VtID0gJ3N1bScsXG4gIG1pbiA9ICdtaW4nLFxuICBtYXggPSAnbWF4JyxcbiAgYXZlcmFnZSA9ICdhdmVyYWdlJyxcbiAgY291bnRkaXN0aW5jdCA9ICdjb3VudGRpc3RpbmN0Jyxcbn1cbmV4cG9ydCB0eXBlIEFnZ3JlZ2F0ZVR5cGUgPVxuICB8IHN0cmluZ1xuICB8IHsgW3Byb3BlcnR5TmFtZTogc3RyaW5nXTogeyB3aXRoOiBTdGFuZGFyZEFnZ3JlZ2F0ZU1ldGhvZHM7IGFzOiBzdHJpbmcgfSB9O1xuXG4vLyBPcmRlckJ5XG5cbmV4cG9ydCB0eXBlIE9yZGVyQnk8VD4gPSBPcmRlckJ5VHlwZTxUPiB8IE9yZGVyQnlUeXBlPFQ+W107XG5leHBvcnQgdHlwZSBPcmRlckJ5VHlwZTxUPiA9IHN0cmluZyB8IE9yZGVyQnlPYmplY3Q8VD47XG5leHBvcnQgdHlwZSBPcmRlckJ5T2JqZWN0PFQ+ID1cbiAgfCBrZXlvZiBUXG4gIHwgW2tleW9mIFQgfCBzdHJpbmcsICdhc2MnIHwgJ2Rlc2MnXVxuICB8IE5lc3RlZE9yZGVyQnk8VD47XG5leHBvcnQgdHlwZSBOZXN0ZWRPcmRlckJ5PFQ+ID0ge1xuICBbUCBpbiBrZXlvZiBUXT86IFRbUF0gZXh0ZW5kcyBBcnJheTxpbmZlciBFPiA/IE9yZGVyQnk8RT4gOiBPcmRlckJ5PFRbUF0+O1xufTtcblxuLy8gRXhwYW5kXG5leHBvcnQgdHlwZSBFeHBhbmQ8VD4gPSBFeHBhbmRUeXBlPFQ+IHwgRXhwYW5kVHlwZTxUPltdO1xuZXhwb3J0IHR5cGUgRXhwYW5kVHlwZTxUPiA9IHN0cmluZyB8IEV4cGFuZE9iamVjdDxUPjtcbmV4cG9ydCB0eXBlIEV4cGFuZE9iamVjdDxUPiA9IGtleW9mIFQgfCBOZXN0ZWRFeHBhbmRPcHRpb25zPFQ+O1xuZXhwb3J0IHR5cGUgTmVzdGVkRXhwYW5kT3B0aW9uczxUPiA9IHtcbiAgW1AgaW4ga2V5b2YgVF0/OiBFeHBhbmRPcHRpb25zPFVucGFja2VkPFRbUF0+Pjtcbn07XG5leHBvcnQgdHlwZSBFeHBhbmRPcHRpb25zPFQ+ID0ge1xuICBzZWxlY3Q/OiBTZWxlY3Q8VD47XG4gIGZpbHRlcj86IEZpbHRlcjxUPjtcbiAgb3JkZXJCeT86IE9yZGVyQnk8VD47XG4gIHRvcD86IG51bWJlcjtcbiAgc2tpcD86IG51bWJlcjtcbiAgbGV2ZWxzPzogbnVtYmVyIHwgJ21heCc7XG4gIGNvdW50PzogYm9vbGVhbiB8IEZpbHRlcjxUPjtcbiAgZXhwYW5kPzogRXhwYW5kPFQ+O1xufTtcblxuZXhwb3J0IHR5cGUgVHJhbnNmb3JtPFQ+ID0ge1xuICBhZ2dyZWdhdGU/OiBBZ2dyZWdhdGVUeXBlIHwgQXJyYXk8QWdncmVnYXRlVHlwZT47XG4gIGZpbHRlcj86IEZpbHRlcjxUPjtcbiAgZ3JvdXBCeT86IEdyb3VwQnlUeXBlPFQ+O1xufTtcbmV4cG9ydCB0eXBlIEdyb3VwQnlUeXBlPFQ+ID0ge1xuICBwcm9wZXJ0aWVzOiBBcnJheTxrZXlvZiBUPjtcbiAgdHJhbnNmb3JtPzogVHJhbnNmb3JtPFQ+O1xufTtcblxuZXhwb3J0IGVudW0gUXVlcnlDdXN0b21UeXBlcyB7XG4gIFJhdyxcbiAgQWxpYXMsXG4gIER1cmF0aW9uLFxuICBCaW5hcnksXG59XG5cbmV4cG9ydCB0eXBlIFF1ZXJ5Q3VzdG9tVHlwZSA9IHtcbiAgdHlwZTogUXVlcnlDdXN0b21UeXBlcztcbiAgdmFsdWU6IGFueTtcbiAgbmFtZT86IHN0cmluZztcbn07XG5leHBvcnQgdHlwZSBWYWx1ZSA9IHN0cmluZyB8IERhdGUgfCBudW1iZXIgfCBib29sZWFuIHwgUXVlcnlDdXN0b21UeXBlO1xuXG4vL2h0dHBzOi8vZG9jcy5vYXNpcy1vcGVuLm9yZy9vZGF0YS9vZGF0YS92NC4wMS9vZGF0YS12NC4wMS1wYXJ0Mi11cmwtY29udmVudGlvbnMuaHRtbCNzZWNfUXVlcnlPcHRpb25zXG5leHBvcnQgY29uc3QgcmF3ID0gKHZhbHVlOiBzdHJpbmcpOiBRdWVyeUN1c3RvbVR5cGUgPT4gKHtcbiAgdHlwZTogUXVlcnlDdXN0b21UeXBlcy5SYXcsXG4gIHZhbHVlLFxufSk7XG5leHBvcnQgY29uc3QgYWxpYXMgPSAodmFsdWU6IGFueSwgbmFtZT86IHN0cmluZyk6IFF1ZXJ5Q3VzdG9tVHlwZSA9PiAoe1xuICB0eXBlOiBRdWVyeUN1c3RvbVR5cGVzLkFsaWFzLFxuICB2YWx1ZSxcbiAgbmFtZSxcbn0pO1xuZXhwb3J0IGNvbnN0IGR1cmF0aW9uID0gKHZhbHVlOiBzdHJpbmcpOiBRdWVyeUN1c3RvbVR5cGUgPT4gKHtcbiAgdHlwZTogUXVlcnlDdXN0b21UeXBlcy5EdXJhdGlvbixcbiAgdmFsdWUsXG59KTtcbmV4cG9ydCBjb25zdCBiaW5hcnkgPSAodmFsdWU6IHN0cmluZyk6IFF1ZXJ5Q3VzdG9tVHlwZSA9PiAoe1xuICB0eXBlOiBRdWVyeUN1c3RvbVR5cGVzLkJpbmFyeSxcbiAgdmFsdWUsXG59KTtcbmV4cG9ydCBjb25zdCBpc1F1ZXJ5Q3VzdG9tVHlwZSA9ICh2YWx1ZTogYW55KSA9PlxuICB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmXG4gICd0eXBlJyBpbiB2YWx1ZSAmJlxuICB2YWx1ZS50eXBlIGluIFF1ZXJ5Q3VzdG9tVHlwZXM7XG5cbmV4cG9ydCBjb25zdCBpc1Jhd1R5cGUgPSAodmFsdWU6IGFueSkgPT5cbiAgaXNRdWVyeUN1c3RvbVR5cGUodmFsdWUpICYmXG4gICh2YWx1ZSBhcyBRdWVyeUN1c3RvbVR5cGUpLnR5cGUgPT09IFF1ZXJ5Q3VzdG9tVHlwZXMuUmF3O1xuXG5leHBvcnQgdHlwZSBRdWVyeU9wdGlvbnM8VD4gPSBFeHBhbmRPcHRpb25zPFQ+ICYge1xuICBzZWFyY2g6IHN0cmluZztcbiAgYXBwbHk6IHN0cmluZztcbiAgdHJhbnNmb3JtOiB7IFtuYW1lOiBzdHJpbmddOiBhbnkgfSB8IHsgW25hbWU6IHN0cmluZ106IGFueSB9W107XG4gIHNraXA6IG51bWJlcjtcbiAgc2tpcHRva2VuOiBzdHJpbmc7XG4gIGtleTogc3RyaW5nIHwgbnVtYmVyIHwgeyBbbmFtZTogc3RyaW5nXTogYW55IH07XG4gIGNvdW50OiBib29sZWFuIHwgRmlsdGVyPFQ+O1xuICBhY3Rpb246IHN0cmluZztcbiAgZnVuYzogc3RyaW5nIHwgeyBbZnVuY3Rpb25OYW1lOiBzdHJpbmddOiB7IFtwYXJhbWV0ZXJOYW1lOiBzdHJpbmddOiBhbnkgfSB9O1xuICBmb3JtYXQ6IHN0cmluZztcbiAgYWxpYXNlczogUXVlcnlDdXN0b21UeXBlW107XG4gIGVzY2FwZTogYm9vbGVhbjtcbn07XG5cbmV4cG9ydCBjb25zdCBJVEVNX1JPT1QgPSAnJztcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gPFQ+KHtcbiAgc2VsZWN0LFxuICBzZWFyY2gsXG4gIHNraXB0b2tlbixcbiAgZm9ybWF0LFxuICB0b3AsXG4gIHNraXAsXG4gIGZpbHRlcixcbiAgdHJhbnNmb3JtLFxuICBvcmRlckJ5LFxuICBrZXksXG4gIGNvdW50LFxuICBleHBhbmQsXG4gIGFjdGlvbixcbiAgZnVuYyxcbiAgYWxpYXNlcyxcbiAgZXNjYXBlLFxufTogUGFydGlhbDxRdWVyeU9wdGlvbnM8VD4+ID0ge30pIHtcbiAgY29uc3QgW3BhdGgsIHBhcmFtc10gPSBidWlsZFBhdGhBbmRRdWVyeSh7XG4gICAgc2VsZWN0LFxuICAgIHNlYXJjaCxcbiAgICBza2lwdG9rZW4sXG4gICAgZm9ybWF0LFxuICAgIHRvcCxcbiAgICBza2lwLFxuICAgIGZpbHRlcixcbiAgICB0cmFuc2Zvcm0sXG4gICAgb3JkZXJCeSxcbiAgICBrZXksXG4gICAgY291bnQsXG4gICAgZXhwYW5kLFxuICAgIGFjdGlvbixcbiAgICBmdW5jLFxuICAgIGFsaWFzZXMsXG4gICAgZXNjYXBlLFxuICB9KTtcblxuICByZXR1cm4gYnVpbGRVcmwocGF0aCwgcGFyYW1zKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUGF0aEFuZFF1ZXJ5PFQ+KHtcbiAgc2VsZWN0LFxuICBzZWFyY2gsXG4gIHNraXB0b2tlbixcbiAgZm9ybWF0LFxuICB0b3AsXG4gIHNraXAsXG4gIGZpbHRlcixcbiAgYXBwbHksXG4gIHRyYW5zZm9ybSxcbiAgb3JkZXJCeSxcbiAga2V5LFxuICBjb3VudCxcbiAgZXhwYW5kLFxuICBhY3Rpb24sXG4gIGZ1bmMsXG4gIGFsaWFzZXMsXG4gIGVzY2FwZSxcbn06IFBhcnRpYWw8UXVlcnlPcHRpb25zPFQ+PiA9IHt9KTogW3N0cmluZywgeyBbbmFtZTogc3RyaW5nXTogYW55IH1dIHtcbiAgbGV0IHBhdGg6IHN0cmluZyA9ICcnO1xuICBhbGlhc2VzID0gYWxpYXNlcyB8fCBbXTtcblxuICBjb25zdCBxdWVyeTogYW55ID0ge307XG5cbiAgLy8ga2V5IGlzIG5vdCAobnVsbCwgdW5kZWZpbmVkKVxuICBpZiAoa2V5ICE9IHVuZGVmaW5lZCkge1xuICAgIHBhdGggKz0gYCgke25vcm1hbGl6ZVZhbHVlKGtleSBhcyBWYWx1ZSwgeyBhbGlhc2VzLCBlc2NhcGUgfSl9KWA7XG4gIH1cblxuICAvLyBTZWxlY3RcbiAgaWYgKHNlbGVjdCkge1xuICAgIHF1ZXJ5LiRzZWxlY3QgPSBpc1Jhd1R5cGUoc2VsZWN0KVxuICAgICAgPyAoc2VsZWN0IGFzIHVua25vd24gYXMgUXVlcnlDdXN0b21UeXBlKS52YWx1ZVxuICAgICAgOiBBcnJheS5pc0FycmF5KHNlbGVjdClcbiAgICAgICAgPyBzZWxlY3Quam9pbignLCcpXG4gICAgICAgIDogc2VsZWN0O1xuICB9XG5cbiAgLy8gU2VhcmNoXG4gIGlmIChzZWFyY2gpIHtcbiAgICBxdWVyeS4kc2VhcmNoID0gc2VhcmNoO1xuICB9XG5cbiAgLy8gU2tpcHRva2VuXG4gIGlmIChza2lwdG9rZW4pIHtcbiAgICBxdWVyeS4kc2tpcHRva2VuID0gc2tpcHRva2VuO1xuICB9XG5cbiAgLy8gRm9ybWF0XG4gIGlmIChmb3JtYXQpIHtcbiAgICBxdWVyeS4kZm9ybWF0ID0gZm9ybWF0O1xuICB9XG5cbiAgLy8gRmlsdGVyXG4gIGlmIChmaWx0ZXIgfHwgdHlwZW9mIGNvdW50ID09PSAnb2JqZWN0Jykge1xuICAgIHF1ZXJ5LiRmaWx0ZXIgPSBidWlsZEZpbHRlcih0eXBlb2YgY291bnQgPT09ICdvYmplY3QnID8gY291bnQgOiBmaWx0ZXIsIHtcbiAgICAgIGFsaWFzZXMsXG4gICAgICBlc2NhcGUsXG4gICAgfSk7XG4gIH1cblxuICAvLyBUcmFuc2Zvcm1cbiAgaWYgKHRyYW5zZm9ybSkge1xuICAgIHF1ZXJ5LiRhcHBseSA9IGJ1aWxkVHJhbnNmb3Jtcyh0cmFuc2Zvcm0sIHsgYWxpYXNlcywgZXNjYXBlIH0pO1xuICB9XG5cbiAgLy8gQXBwbHlcbiAgaWYgKGFwcGx5KSB7XG4gICAgcXVlcnkuJGFwcGx5ID0gcXVlcnkuJGFwcGx5XG4gICAgICA/IHF1ZXJ5LiRhcHBseSArICcvJyArIGJ1aWxkQXBwbHkoYXBwbHksIHsgYWxpYXNlcywgZXNjYXBlIH0pXG4gICAgICA6IGJ1aWxkQXBwbHkoYXBwbHksIHsgYWxpYXNlcywgZXNjYXBlIH0pO1xuICB9XG5cbiAgLy8gRXhwYW5kXG4gIGlmIChleHBhbmQpIHtcbiAgICBxdWVyeS4kZXhwYW5kID0gYnVpbGRFeHBhbmQoZXhwYW5kLCB7IGFsaWFzZXMsIGVzY2FwZSB9KTtcbiAgfVxuXG4gIC8vIE9yZGVyQnlcbiAgaWYgKG9yZGVyQnkpIHtcbiAgICBxdWVyeS4kb3JkZXJieSA9IGJ1aWxkT3JkZXJCeShvcmRlckJ5KTtcbiAgfVxuXG4gIC8vIENvdW50XG4gIGlmIChpc1Jhd1R5cGUoY291bnQpKSB7XG4gICAgcXVlcnkuJGNvdW50ID0gKGNvdW50IGFzIFF1ZXJ5Q3VzdG9tVHlwZSkudmFsdWU7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGNvdW50ID09PSAnYm9vbGVhbicpIHtcbiAgICBxdWVyeS4kY291bnQgPSB0cnVlO1xuICB9IGVsc2UgaWYgKGNvdW50KSB7XG4gICAgcGF0aCArPSAnLyRjb3VudCc7XG4gIH1cblxuICAvLyBUb3BcbiAgaWYgKGlzUmF3VHlwZSh0b3ApKSB7XG4gICAgcXVlcnkuJHRvcCA9ICh0b3AgYXMgdW5rbm93biBhcyBRdWVyeUN1c3RvbVR5cGUpLnZhbHVlO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB0b3AgPT09ICdudW1iZXInKSB7XG4gICAgcXVlcnkuJHRvcCA9IHRvcDtcbiAgfVxuXG4gIC8vIFNraXBcbiAgaWYgKGlzUmF3VHlwZShza2lwKSkge1xuICAgIHF1ZXJ5LiR0b3AgPSAoc2tpcCBhcyB1bmtub3duIGFzIFF1ZXJ5Q3VzdG9tVHlwZSkudmFsdWU7XG4gIH0gZWxzZSBpZiAodHlwZW9mIHNraXAgPT09ICdudW1iZXInKSB7XG4gICAgcXVlcnkuJHNraXAgPSBza2lwO1xuICB9XG5cbiAgaWYgKGFjdGlvbikge1xuICAgIHBhdGggKz0gYC8ke2FjdGlvbn1gO1xuICB9XG5cbiAgaWYgKGZ1bmMpIHtcbiAgICBpZiAodHlwZW9mIGZ1bmMgPT09ICdzdHJpbmcnKSB7XG4gICAgICBwYXRoICs9IGAvJHtmdW5jfSgpYDtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBmdW5jID09PSAnb2JqZWN0Jykge1xuICAgICAgY29uc3QgW2Z1bmNOYW1lXSA9IE9iamVjdC5rZXlzKGZ1bmMpO1xuICAgICAgY29uc3QgZnVuY0FyZ3MgPSBub3JtYWxpemVWYWx1ZShmdW5jW2Z1bmNOYW1lXSBhcyBWYWx1ZSwge1xuICAgICAgICBhbGlhc2VzLFxuICAgICAgICBlc2NhcGUsXG4gICAgICB9KTtcblxuICAgICAgcGF0aCArPSBgLyR7ZnVuY05hbWV9KCR7ZnVuY0FyZ3N9KWA7XG4gICAgfVxuICB9XG5cbiAgaWYgKGFsaWFzZXMubGVuZ3RoID4gMCkge1xuICAgIE9iamVjdC5hc3NpZ24oXG4gICAgICBxdWVyeSxcbiAgICAgIGFsaWFzZXMucmVkdWNlKFxuICAgICAgICAoYWNjLCBhbGlhcykgPT5cbiAgICAgICAgICBPYmplY3QuYXNzaWduKGFjYywge1xuICAgICAgICAgICAgW2BAJHthbGlhcy5uYW1lfWBdOiBub3JtYWxpemVWYWx1ZShhbGlhcy52YWx1ZSwge1xuICAgICAgICAgICAgICBlc2NhcGUsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB9KSxcbiAgICAgICAge30sXG4gICAgICApLFxuICAgICk7XG4gIH1cblxuICAvLyBGaWx0ZXIgZW1wdHkgdmFsdWVzXG4gIGNvbnN0IHBhcmFtcyA9IE9iamVjdC5lbnRyaWVzKHF1ZXJ5KVxuICAgIC5maWx0ZXIoKFssIHZhbHVlXSkgPT4gdmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gJycpXG4gICAgLnJlZHVjZSgoYWNjLCBba2V5LCB2YWx1ZV0pID0+IE9iamVjdC5hc3NpZ24oYWNjLCB7IFtrZXldOiB2YWx1ZSB9KSwge30pO1xuXG4gIHJldHVybiBbcGF0aCwgcGFyYW1zXTtcbn1cblxuZnVuY3Rpb24gcmVuZGVyUHJpbWl0aXZlVmFsdWUoXG4gIGtleTogc3RyaW5nLFxuICB2YWw6IGFueSxcbiAge1xuICAgIGFsaWFzZXMsXG4gICAgZXNjYXBlLFxuICB9OiB7XG4gICAgYWxpYXNlcz86IFF1ZXJ5Q3VzdG9tVHlwZVtdO1xuICAgIGVzY2FwZT86IGJvb2xlYW47XG4gIH0sXG4pIHtcbiAgcmV0dXJuIGAke2tleX0gZXEgJHtub3JtYWxpemVWYWx1ZSh2YWwsIHsgYWxpYXNlcywgZXNjYXBlIH0pfWA7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkRmlsdGVyKFxuICBmaWx0ZXJzOiBGaWx0ZXI8YW55PiA9IHt9LFxuICB7XG4gICAgYWxpYXNlcyxcbiAgICBwcm9wUHJlZml4LFxuICAgIGVzY2FwZSxcbiAgfTogeyBhbGlhc2VzPzogUXVlcnlDdXN0b21UeXBlW107IHByb3BQcmVmaXg/OiBzdHJpbmc7IGVzY2FwZT86IGJvb2xlYW4gfSxcbik6IHN0cmluZyB7XG4gIHJldHVybiAoXG4gICAgKEFycmF5LmlzQXJyYXkoZmlsdGVycykgPyBmaWx0ZXJzIDogW2ZpbHRlcnNdKS5yZWR1Y2UoXG4gICAgICAoYWNjOiBzdHJpbmdbXSwgZmlsdGVyKSA9PiB7XG4gICAgICAgIGlmIChmaWx0ZXIpIHtcbiAgICAgICAgICBjb25zdCBidWlsdEZpbHRlciA9IGJ1aWxkRmlsdGVyQ29yZShmaWx0ZXIsIHtcbiAgICAgICAgICAgIGFsaWFzZXMsXG4gICAgICAgICAgICBwcm9wUHJlZml4LFxuICAgICAgICAgICAgZXNjYXBlLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGlmIChidWlsdEZpbHRlcikge1xuICAgICAgICAgICAgYWNjLnB1c2goYnVpbHRGaWx0ZXIpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSxcbiAgICAgIFtdLFxuICAgICkgYXMgc3RyaW5nW11cbiAgKS5qb2luKCcgYW5kICcpO1xuXG4gIGZ1bmN0aW9uIGJ1aWxkRmlsdGVyQ29yZShcbiAgICBmaWx0ZXI6IEZpbHRlcjxhbnk+ID0ge30sXG4gICAge1xuICAgICAgYWxpYXNlcyxcbiAgICAgIHByb3BQcmVmaXgsXG4gICAgICBlc2NhcGUsXG4gICAgfTogeyBhbGlhc2VzPzogUXVlcnlDdXN0b21UeXBlW107IHByb3BQcmVmaXg/OiBzdHJpbmc7IGVzY2FwZT86IGJvb2xlYW4gfSxcbiAgKSB7XG4gICAgbGV0IGZpbHRlckV4cHIgPSAnJztcbiAgICBpZiAoaXNSYXdUeXBlKGZpbHRlcikpIHtcbiAgICAgIC8vIFVzZSByYXcgcXVlcnkgY3VzdG9tIGZpbHRlciBzdHJpbmdcbiAgICAgIGZpbHRlckV4cHIgPSAoZmlsdGVyIGFzIFF1ZXJ5Q3VzdG9tVHlwZSkudmFsdWU7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgZmlsdGVyID09PSAnc3RyaW5nJykge1xuICAgICAgLy8gVXNlIHJhdyBmaWx0ZXIgc3RyaW5nXG4gICAgICBmaWx0ZXJFeHByID0gZmlsdGVyO1xuICAgIH0gZWxzZSBpZiAoZmlsdGVyICYmIHR5cGVvZiBmaWx0ZXIgPT09ICdvYmplY3QnKSB7XG4gICAgICBjb25zdCBmaWx0ZXJzQXJyYXkgPSBPYmplY3Qua2V5cyhmaWx0ZXIpLnJlZHVjZShcbiAgICAgICAgKHJlc3VsdDogYW55W10sIGZpbHRlcktleSkgPT4ge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gKGZpbHRlciBhcyBhbnkpW2ZpbHRlcktleV07XG4gICAgICAgICAgbGV0IHByb3BOYW1lID0gJyc7XG4gICAgICAgICAgaWYgKHByb3BQcmVmaXgpIHtcbiAgICAgICAgICAgIGlmIChmaWx0ZXJLZXkgPT09IElURU1fUk9PVCkge1xuICAgICAgICAgICAgICBwcm9wTmFtZSA9IHByb3BQcmVmaXg7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKElOREVYT0ZfUkVHRVgudGVzdChmaWx0ZXJLZXkpKSB7XG4gICAgICAgICAgICAgIHByb3BOYW1lID0gZmlsdGVyS2V5LnJlcGxhY2UoSU5ERVhPRl9SRUdFWCwgKF8sICQxKSA9PlxuICAgICAgICAgICAgICAgICQxLnRyaW0oKSA9PT0gSVRFTV9ST09UXG4gICAgICAgICAgICAgICAgICA/IGAoJHtwcm9wUHJlZml4fSlgXG4gICAgICAgICAgICAgICAgICA6IGAoJHtwcm9wUHJlZml4fS8keyQxLnRyaW0oKX0pYCxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoRlVOQ1RJT05fUkVHRVgudGVzdChmaWx0ZXJLZXkpKSB7XG4gICAgICAgICAgICAgIHByb3BOYW1lID0gZmlsdGVyS2V5LnJlcGxhY2UoRlVOQ1RJT05fUkVHRVgsIChfLCAkMSkgPT5cbiAgICAgICAgICAgICAgICAkMS50cmltKCkgPT09IElURU1fUk9PVFxuICAgICAgICAgICAgICAgICAgPyBgKCR7cHJvcFByZWZpeH0pYFxuICAgICAgICAgICAgICAgICAgOiBgKCR7cHJvcFByZWZpeH0vJHskMS50cmltKCl9KWAsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBwcm9wTmFtZSA9IGAke3Byb3BQcmVmaXh9LyR7ZmlsdGVyS2V5fWA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHByb3BOYW1lID0gZmlsdGVyS2V5O1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChmaWx0ZXJLZXkgPT09IElURU1fUk9PVCAmJiBBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5jb25jYXQoXG4gICAgICAgICAgICAgIHZhbHVlLm1hcCgoYXJyYXlWYWx1ZTogYW55KSA9PlxuICAgICAgICAgICAgICAgIHJlbmRlclByaW1pdGl2ZVZhbHVlKHByb3BOYW1lLCBhcnJheVZhbHVlLCB7IGVzY2FwZSwgYWxpYXNlcyB9KSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgWydudW1iZXInLCAnc3RyaW5nJywgJ2Jvb2xlYW4nXS5pbmRleE9mKHR5cGVvZiB2YWx1ZSkgIT09IC0xIHx8XG4gICAgICAgICAgICB2YWx1ZSBpbnN0YW5jZW9mIERhdGUgfHxcbiAgICAgICAgICAgIHZhbHVlID09PSBudWxsXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICAvLyBTaW1wbGUga2V5L3ZhbHVlIGhhbmRsZWQgYXMgZXF1YWxzIG9wZXJhdG9yXG4gICAgICAgICAgICByZXN1bHQucHVzaChcbiAgICAgICAgICAgICAgcmVuZGVyUHJpbWl0aXZlVmFsdWUocHJvcE5hbWUsIHZhbHVlLCB7IGFsaWFzZXMsIGVzY2FwZSB9KSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICAgICAgY29uc3Qgb3AgPSBmaWx0ZXJLZXk7XG4gICAgICAgICAgICBjb25zdCBidWlsdEZpbHRlcnMgPSB2YWx1ZVxuICAgICAgICAgICAgICAubWFwKCh2KSA9PiBidWlsZEZpbHRlcih2LCB7IGFsaWFzZXMsIHByb3BQcmVmaXgsIGVzY2FwZSB9KSlcbiAgICAgICAgICAgICAgLmZpbHRlcigoZikgPT4gZilcbiAgICAgICAgICAgICAgLm1hcCgoZikgPT5cbiAgICAgICAgICAgICAgICBMT0dJQ0FMX09QRVJBVE9SUy5pbmRleE9mKG9wKSAhPT0gLTEgPyBgKCR7Zn0pYCA6IGYsXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoYnVpbHRGaWx0ZXJzLmxlbmd0aCkge1xuICAgICAgICAgICAgICBpZiAoTE9HSUNBTF9PUEVSQVRPUlMuaW5kZXhPZihvcCkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgaWYgKGJ1aWx0RmlsdGVycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgIGlmIChvcCA9PT0gJ25vdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1c2gocGFyc2VOb3QoYnVpbHRGaWx0ZXJzIGFzIHN0cmluZ1tdKSk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChgKCR7YnVpbHRGaWx0ZXJzLmpvaW4oYCAke29wfSBgKX0pYCk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGJ1aWx0RmlsdGVycy5qb2luKGAgJHtvcH0gYCkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChMT0dJQ0FMX09QRVJBVE9SUy5pbmRleE9mKHByb3BOYW1lKSAhPT0gLTEpIHtcbiAgICAgICAgICAgIGNvbnN0IG9wID0gcHJvcE5hbWU7XG4gICAgICAgICAgICBjb25zdCBidWlsdEZpbHRlcnMgPSBPYmplY3Qua2V5cyh2YWx1ZSkubWFwKCh2YWx1ZUtleSkgPT5cbiAgICAgICAgICAgICAgYnVpbGRGaWx0ZXJDb3JlKFxuICAgICAgICAgICAgICAgIHsgW3ZhbHVlS2V5XTogdmFsdWVbdmFsdWVLZXldIH0sXG4gICAgICAgICAgICAgICAgeyBhbGlhc2VzLCBlc2NhcGUgfSxcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBpZiAoYnVpbHRGaWx0ZXJzLmxlbmd0aCkge1xuICAgICAgICAgICAgICBpZiAob3AgPT09ICdub3QnKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2gocGFyc2VOb3QoYnVpbHRGaWx0ZXJzIGFzIHN0cmluZ1tdKSk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goYCR7YnVpbHRGaWx0ZXJzLmpvaW4oYCAke29wfSBgKX1gKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgaWYgKCd0eXBlJyBpbiB2YWx1ZSkge1xuICAgICAgICAgICAgICByZXN1bHQucHVzaChcbiAgICAgICAgICAgICAgICByZW5kZXJQcmltaXRpdmVWYWx1ZShwcm9wTmFtZSwgdmFsdWUsIHsgYWxpYXNlcywgZXNjYXBlIH0pLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgY29uc3Qgb3BlcmF0b3JzID0gT2JqZWN0LmtleXModmFsdWUpO1xuICAgICAgICAgICAgICBvcGVyYXRvcnMuZm9yRWFjaCgob3ApID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoQ09NUEFSSVNPTl9PUEVSQVRPUlMuaW5kZXhPZihvcCkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChcbiAgICAgICAgICAgICAgICAgICAgYCR7cHJvcE5hbWV9ICR7b3B9ICR7bm9ybWFsaXplVmFsdWUodmFsdWVbb3BdLCB7XG4gICAgICAgICAgICAgICAgICAgICAgYWxpYXNlcyxcbiAgICAgICAgICAgICAgICAgICAgICBlc2NhcGUsXG4gICAgICAgICAgICAgICAgICAgIH0pfWAsXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoTE9HSUNBTF9PUEVSQVRPUlMuaW5kZXhPZihvcCkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZVtvcF0pKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKFxuICAgICAgICAgICAgICAgICAgICAgIHZhbHVlW29wXVxuICAgICAgICAgICAgICAgICAgICAgICAgLm1hcChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKHY6IGFueSkgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnKCcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1aWxkRmlsdGVyQ29yZSh2LCB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGlhc2VzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcFByZWZpeDogcHJvcE5hbWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlc2NhcGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICcpJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgIC5qb2luKGAgJHtvcH0gYCksXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChcbiAgICAgICAgICAgICAgICAgICAgICAnKCcgK1xuICAgICAgICAgICAgICAgICAgICAgICAgYnVpbGRGaWx0ZXJDb3JlKHZhbHVlW29wXSwge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBhbGlhc2VzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wUHJlZml4OiBwcm9wTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZXNjYXBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgfSkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgJyknLFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoQ09MTEVDVElPTl9PUEVSQVRPUlMuaW5kZXhPZihvcCkgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBjb2xsZWN0aW9uQ2xhdXNlID0gYnVpbGRDb2xsZWN0aW9uQ2xhdXNlKFxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXJLZXkudG9Mb3dlckNhc2UoKSxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVbb3BdLFxuICAgICAgICAgICAgICAgICAgICBvcCxcbiAgICAgICAgICAgICAgICAgICAgcHJvcE5hbWUsXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgaWYgKGNvbGxlY3Rpb25DbGF1c2UpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0LnB1c2goY29sbGVjdGlvbkNsYXVzZSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvcCA9PT0gJ2hhcycpIHtcbiAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKFxuICAgICAgICAgICAgICAgICAgICBgJHtwcm9wTmFtZX0gJHtvcH0gJHtub3JtYWxpemVWYWx1ZSh2YWx1ZVtvcF0sIHtcbiAgICAgICAgICAgICAgICAgICAgICBhbGlhc2VzLFxuICAgICAgICAgICAgICAgICAgICAgIGVzY2FwZSxcbiAgICAgICAgICAgICAgICAgICAgfSl9YCxcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvcCA9PT0gJ2luJykge1xuICAgICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0aW5nVmFsdWVzID0gQXJyYXkuaXNBcnJheSh2YWx1ZVtvcF0pXG4gICAgICAgICAgICAgICAgICAgID8gdmFsdWVbb3BdXG4gICAgICAgICAgICAgICAgICAgIDogdmFsdWVbb3BdLnZhbHVlLm1hcCgodHlwZWRWYWx1ZTogYW55KSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogdmFsdWVbb3BdLnR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogdHlwZWRWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgICB9KSk7XG5cbiAgICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKFxuICAgICAgICAgICAgICAgICAgICBwcm9wTmFtZSArXG4gICAgICAgICAgICAgICAgICAgICAgJyBpbiAoJyArXG4gICAgICAgICAgICAgICAgICAgICAgcmVzdWx0aW5nVmFsdWVzXG4gICAgICAgICAgICAgICAgICAgICAgICAubWFwKCh2OiBhbnkpID0+IG5vcm1hbGl6ZVZhbHVlKHYsIHsgYWxpYXNlcywgZXNjYXBlIH0pKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmpvaW4oJywnKSArXG4gICAgICAgICAgICAgICAgICAgICAgJyknLFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKEJPT0xFQU5fRlVOQ1RJT05TLmluZGV4T2Yob3ApICE9PSAtMSkge1xuICAgICAgICAgICAgICAgICAgLy8gU2ltcGxlIGJvb2xlYW4gZnVuY3Rpb25zIChzdGFydHN3aXRoLCBlbmRzd2l0aCwgY29udGFpbnMpXG4gICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChcbiAgICAgICAgICAgICAgICAgICAgYCR7b3B9KCR7cHJvcE5hbWV9LCR7bm9ybWFsaXplVmFsdWUodmFsdWVbb3BdLCB7XG4gICAgICAgICAgICAgICAgICAgICAgYWxpYXNlcyxcbiAgICAgICAgICAgICAgICAgICAgICBlc2NhcGUsXG4gICAgICAgICAgICAgICAgICAgIH0pfSlgLFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgLy8gTmVzdGVkIHByb3BlcnR5XG4gICAgICAgICAgICAgICAgICBjb25zdCBmaWx0ZXIgPSBidWlsZEZpbHRlckNvcmUodmFsdWUsIHtcbiAgICAgICAgICAgICAgICAgICAgYWxpYXNlcyxcbiAgICAgICAgICAgICAgICAgICAgcHJvcFByZWZpeDogcHJvcE5hbWUsXG4gICAgICAgICAgICAgICAgICAgIGVzY2FwZSxcbiAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlcikge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQucHVzaChmaWx0ZXIpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAvLyBJZ25vcmUvb21pdCBmaWx0ZXIgaWYgdmFsdWUgaXMgYHVuZGVmaW5lZGBcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkIHZhbHVlIHR5cGU6ICR7dmFsdWV9YCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSxcbiAgICAgICAgW10sXG4gICAgICApO1xuXG4gICAgICBmaWx0ZXJFeHByID0gZmlsdGVyc0FycmF5LmpvaW4oJyBhbmQgJyk7XG4gICAgfSAvKiBlbHNlIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkIGZpbHRlcnMgdHlwZTogJHtmaWx0ZXJ9YCk7XG4gICAgICB9ICovXG4gICAgcmV0dXJuIGZpbHRlckV4cHI7XG4gIH1cblxuICBmdW5jdGlvbiBidWlsZENvbGxlY3Rpb25DbGF1c2UoXG4gICAgbGFtYmRhUGFyYW1ldGVyOiBzdHJpbmcsXG4gICAgdmFsdWU6IGFueSxcbiAgICBvcDogc3RyaW5nLFxuICAgIHByb3BOYW1lOiBzdHJpbmcsXG4gICkge1xuICAgIGxldCBjbGF1c2UgPSAnJztcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnIHx8IHZhbHVlIGluc3RhbmNlb2YgU3RyaW5nKSB7XG4gICAgICBjbGF1c2UgPSBnZXRTdHJpbmdDb2xsZWN0aW9uQ2xhdXNlKGxhbWJkYVBhcmFtZXRlciwgdmFsdWUsIG9wLCBwcm9wTmFtZSk7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSkge1xuICAgICAgLy8gbm9ybWFsaXplIHthbnk6W3twcm9wMTogMX0sIHtwcm9wMjogMX1dfSAtLT4ge2FueTp7cHJvcDE6IDEsIHByb3AyOiAxfX07IHNhbWUgZm9yICdhbGwnLFxuICAgICAgLy8gc2ltcGxlIHZhbHVlcyBjb2xsZWN0aW9uOiB7YW55Olt7Jyc6ICdzaW1wbGVWYWwxJ30sIHsnJzogJ3NpbXBsZVZhbDInfV19IC0tPiB7YW55OnsnJzogWydzaW1wbGVWYWwxJywgJ3NpbXBsZVZhbDInXX19OyBzYW1lIGZvciAnYWxsJyxcbiAgICAgIGNvbnN0IGZpbHRlclZhbHVlID0gQXJyYXkuaXNBcnJheSh2YWx1ZSlcbiAgICAgICAgPyB2YWx1ZS5yZWR1Y2UoKGFjYywgaXRlbSkgPT4ge1xuICAgICAgICAgICAgaWYgKGl0ZW0uaGFzT3duUHJvcGVydHkoSVRFTV9ST09UKSkge1xuICAgICAgICAgICAgICBpZiAoIWFjYy5oYXNPd25Qcm9wZXJ0eShJVEVNX1JPT1QpKSB7XG4gICAgICAgICAgICAgICAgYWNjW0lURU1fUk9PVF0gPSBbXTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBhY2NbSVRFTV9ST09UXS5wdXNoKGl0ZW1bSVRFTV9ST09UXSk7XG4gICAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4geyAuLi5hY2MsIC4uLml0ZW0gfTtcbiAgICAgICAgICB9LCB7fSlcbiAgICAgICAgOiB2YWx1ZTtcblxuICAgICAgY29uc3QgZmlsdGVyID0gYnVpbGRGaWx0ZXJDb3JlKGZpbHRlclZhbHVlLCB7XG4gICAgICAgIGFsaWFzZXMsXG4gICAgICAgIHByb3BQcmVmaXg6IGxhbWJkYVBhcmFtZXRlcixcbiAgICAgICAgZXNjYXBlLFxuICAgICAgfSk7XG4gICAgICBjbGF1c2UgPSBgJHtwcm9wTmFtZX0vJHtvcH0oJHtcbiAgICAgICAgZmlsdGVyID8gYCR7bGFtYmRhUGFyYW1ldGVyfToke2ZpbHRlcn1gIDogJydcbiAgICAgIH0pYDtcbiAgICB9XG4gICAgcmV0dXJuIGNsYXVzZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRTdHJpbmdDb2xsZWN0aW9uQ2xhdXNlKFxuICBsYW1iZGFQYXJhbWV0ZXI6IHN0cmluZyxcbiAgdmFsdWU6IGFueSxcbiAgY29sbGVjdGlvbk9wZXJhdG9yOiBzdHJpbmcsXG4gIHByb3BOYW1lOiBzdHJpbmcsXG4pIHtcbiAgbGV0IGNsYXVzZSA9ICcnO1xuICBjb25zdCBjb25kaXRpb25PcGVyYXRvciA9IGNvbGxlY3Rpb25PcGVyYXRvciA9PSAnYWxsJyA/ICduZScgOiAnZXEnO1xuICBjbGF1c2UgPSBgJHtwcm9wTmFtZX0vJHtjb2xsZWN0aW9uT3BlcmF0b3J9KCR7bGFtYmRhUGFyYW1ldGVyfTogJHtsYW1iZGFQYXJhbWV0ZXJ9ICR7Y29uZGl0aW9uT3BlcmF0b3J9ICcke3ZhbHVlfScpYDtcblxuICByZXR1cm4gY2xhdXNlO1xufVxuXG5mdW5jdGlvbiBlc2NhcGVJbGxlZ2FsQ2hhcnMoc3RyaW5nOiBzdHJpbmcpIHtcbiAgc3RyaW5nID0gc3RyaW5nLnJlcGxhY2UoLyUvZywgJyUyNScpO1xuICBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZSgvXFwrL2csICclMkInKTtcbiAgc3RyaW5nID0gc3RyaW5nLnJlcGxhY2UoL1xcLy9nLCAnJTJGJyk7XG4gIHN0cmluZyA9IHN0cmluZy5yZXBsYWNlKC9cXD8vZywgJyUzRicpO1xuICBzdHJpbmcgPSBzdHJpbmcucmVwbGFjZSgvIy9nLCAnJTIzJyk7XG4gIHN0cmluZyA9IHN0cmluZy5yZXBsYWNlKC8mL2csICclMjYnKTtcbiAgc3RyaW5nID0gc3RyaW5nLnJlcGxhY2UoLycvZywgXCInJ1wiKTtcbiAgcmV0dXJuIHN0cmluZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZVZhbHVlKFxuICB2YWx1ZTogVmFsdWUsXG4gIHtcbiAgICBhbGlhc2VzLFxuICAgIGVzY2FwZSA9IGZhbHNlLFxuICB9OiB7IGFsaWFzZXM/OiBRdWVyeUN1c3RvbVR5cGVbXTsgZXNjYXBlPzogYm9vbGVhbiB9ID0ge30sXG4pOiBhbnkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBlc2NhcGUgPyBgJyR7ZXNjYXBlSWxsZWdhbENoYXJzKHZhbHVlKX0nYCA6IGAnJHt2YWx1ZX0nYDtcbiAgfSBlbHNlIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICByZXR1cm4gdmFsdWUudG9JU09TdHJpbmcoKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIGBbJHt2YWx1ZVxuICAgICAgLm1hcCgoZCkgPT4gbm9ybWFsaXplVmFsdWUoZCwgeyBhbGlhc2VzLCBlc2NhcGUgfSkpXG4gICAgICAuam9pbignLCcpfV1gO1xuICB9IGVsc2UgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcpIHtcbiAgICBzd2l0Y2ggKHZhbHVlLnR5cGUpIHtcbiAgICAgIGNhc2UgUXVlcnlDdXN0b21UeXBlcy5SYXc6XG4gICAgICAgIHJldHVybiB2YWx1ZS52YWx1ZTtcbiAgICAgIGNhc2UgUXVlcnlDdXN0b21UeXBlcy5EdXJhdGlvbjpcbiAgICAgICAgcmV0dXJuIGBkdXJhdGlvbicke3ZhbHVlLnZhbHVlfSdgO1xuICAgICAgY2FzZSBRdWVyeUN1c3RvbVR5cGVzLkJpbmFyeTpcbiAgICAgICAgcmV0dXJuIGBiaW5hcnknJHt2YWx1ZS52YWx1ZX0nYDtcbiAgICAgIGNhc2UgUXVlcnlDdXN0b21UeXBlcy5BbGlhczpcbiAgICAgICAgLy8gU3RvcmVcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoYWxpYXNlcykpIHtcbiAgICAgICAgICBpZiAodmFsdWUubmFtZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICB2YWx1ZS5uYW1lID0gYGEke2FsaWFzZXMubGVuZ3RoICsgMX1gO1xuICAgICAgICAgIH1cbiAgICAgICAgICBhbGlhc2VzLnB1c2godmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBgQCR7dmFsdWUubmFtZX1gO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKHZhbHVlKVxuICAgICAgICAgIC5maWx0ZXIoKFssIHZdKSA9PiB2ICE9PSB1bmRlZmluZWQpXG4gICAgICAgICAgLm1hcChcbiAgICAgICAgICAgIChbaywgdl0pID0+XG4gICAgICAgICAgICAgIGAke2t9PSR7bm9ybWFsaXplVmFsdWUodiBhcyBWYWx1ZSwgeyBhbGlhc2VzLCBlc2NhcGUgfSl9YCxcbiAgICAgICAgICApXG4gICAgICAgICAgLmpvaW4oJywnKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5mdW5jdGlvbiBidWlsZEV4cGFuZDxUPihcbiAgZXhwYW5kczogRXhwYW5kPFQ+LFxuICB7XG4gICAgYWxpYXNlcyxcbiAgICBlc2NhcGUgPSBmYWxzZSxcbiAgfTogeyBhbGlhc2VzPzogUXVlcnlDdXN0b21UeXBlW107IGVzY2FwZT86IGJvb2xlYW4gfSxcbik6IHN0cmluZyB7XG4gIGlmIChpc1Jhd1R5cGUoZXhwYW5kcykpIHtcbiAgICByZXR1cm4gKGV4cGFuZHMgYXMgUXVlcnlDdXN0b21UeXBlKS52YWx1ZTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZXhwYW5kcyA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gZXhwYW5kcyBhcyBhbnk7XG4gIH0gZWxzZSBpZiAodHlwZW9mIGV4cGFuZHMgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKGV4cGFuZHMuaW5kZXhPZignLycpID09PSAtMSkge1xuICAgICAgcmV0dXJuIGV4cGFuZHM7XG4gICAgfVxuXG4gICAgLy8gQ2hhbmdlIGBGb28vQmFyL0JhemAgdG8gYEZvbygkZXhwYW5kPUJhcigkZXhwYW5kPUJheikpYFxuICAgIHJldHVybiBleHBhbmRzXG4gICAgICAuc3BsaXQoJy8nKVxuICAgICAgLnJldmVyc2UoKVxuICAgICAgLnJlZHVjZSgocmVzdWx0cywgaXRlbSwgaW5kZXgsIGFycikgPT4ge1xuICAgICAgICBpZiAoaW5kZXggPT09IDApIHtcbiAgICAgICAgICAvLyBJbm5lci1tb3N0IGl0ZW1cbiAgICAgICAgICByZXR1cm4gYCRleHBhbmQ9JHtpdGVtfWA7XG4gICAgICAgIH0gZWxzZSBpZiAoaW5kZXggPT09IGFyci5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgLy8gT3V0ZXItbW9zdCBpdGVtLCBkb24ndCBhZGQgYCRleHBhbmQ9YCBwcmVmaXggKGFkZGVkIGFib3ZlKVxuICAgICAgICAgIHJldHVybiBgJHtpdGVtfSgke3Jlc3VsdHN9KWA7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gT3RoZXIgaXRlbXNcbiAgICAgICAgICByZXR1cm4gYCRleHBhbmQ9JHtpdGVtfSgke3Jlc3VsdHN9KWA7XG4gICAgICAgIH1cbiAgICAgIH0sICcnKTtcbiAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KGV4cGFuZHMpKSB7XG4gICAgcmV0dXJuIGAkeyhleHBhbmRzIGFzIEFycmF5PE5lc3RlZEV4cGFuZE9wdGlvbnM8YW55Pj4pXG4gICAgICAubWFwKChlKSA9PiBidWlsZEV4cGFuZChlLCB7IGFsaWFzZXMsIGVzY2FwZSB9KSlcbiAgICAgIC5qb2luKCcsJyl9YDtcbiAgfSBlbHNlIGlmICh0eXBlb2YgZXhwYW5kcyA9PT0gJ29iamVjdCcpIHtcbiAgICBjb25zdCBleHBhbmRLZXlzID0gT2JqZWN0LmtleXMoZXhwYW5kcyk7XG5cbiAgICBpZiAoXG4gICAgICBleHBhbmRLZXlzLnNvbWUoXG4gICAgICAgIChrZXkpID0+IFNVUFBPUlRFRF9FWFBBTkRfUFJPUEVSVElFUy5pbmRleE9mKGtleS50b0xvd2VyQ2FzZSgpKSAhPT0gLTEsXG4gICAgICApXG4gICAgKSB7XG4gICAgICByZXR1cm4gZXhwYW5kS2V5c1xuICAgICAgICAubWFwKChrZXkpID0+IHtcbiAgICAgICAgICBsZXQgdmFsdWU7XG4gICAgICAgICAgc3dpdGNoIChrZXkpIHtcbiAgICAgICAgICAgIGNhc2UgJ2ZpbHRlcic6XG4gICAgICAgICAgICAgIHZhbHVlID0gYnVpbGRGaWx0ZXIoKGV4cGFuZHMgYXMgTmVzdGVkRXhwYW5kT3B0aW9uczxhbnk+KVtrZXldLCB7XG4gICAgICAgICAgICAgICAgYWxpYXNlcyxcbiAgICAgICAgICAgICAgICBlc2NhcGUsXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ29yZGVyQnknOlxuICAgICAgICAgICAgICB2YWx1ZSA9IGJ1aWxkT3JkZXJCeShcbiAgICAgICAgICAgICAgICAoZXhwYW5kcyBhcyBOZXN0ZWRFeHBhbmRPcHRpb25zPGFueT4pW2tleV0gYXMgT3JkZXJCeTxUPixcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdsZXZlbHMnOlxuICAgICAgICAgICAgY2FzZSAnY291bnQnOlxuICAgICAgICAgICAgY2FzZSAndG9wJzpcbiAgICAgICAgICAgIGNhc2UgJ3NraXAnOlxuICAgICAgICAgICAgICB2YWx1ZSA9IGAkeyhleHBhbmRzIGFzIE5lc3RlZEV4cGFuZE9wdGlvbnM8YW55Pilba2V5XX1gO1xuICAgICAgICAgICAgICBpZiAoaXNSYXdUeXBlKHZhbHVlKSlcbiAgICAgICAgICAgICAgICB2YWx1ZSA9ICh2YWx1ZSBhcyB1bmtub3duIGFzIFF1ZXJ5Q3VzdG9tVHlwZSkudmFsdWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgdmFsdWUgPSBidWlsZEV4cGFuZChcbiAgICAgICAgICAgICAgICAoZXhwYW5kcyBhcyBOZXN0ZWRFeHBhbmRPcHRpb25zPGFueT4pW2tleV0gYXMgRXhwYW5kPFQ+LFxuICAgICAgICAgICAgICAgIHsgYWxpYXNlcywgZXNjYXBlIH0sXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBgJCR7a2V5LnRvTG93ZXJDYXNlKCl9PSR7dmFsdWV9YDtcbiAgICAgICAgfSlcbiAgICAgICAgLmpvaW4oJzsnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGV4cGFuZEtleXNcbiAgICAgICAgLm1hcCgoa2V5KSA9PiB7XG4gICAgICAgICAgY29uc3QgYnVpbHRFeHBhbmQgPSBidWlsZEV4cGFuZChcbiAgICAgICAgICAgIChleHBhbmRzIGFzIE5lc3RlZEV4cGFuZE9wdGlvbnM8YW55PilbXG4gICAgICAgICAgICAgIGtleVxuICAgICAgICAgICAgXSBhcyBOZXN0ZWRFeHBhbmRPcHRpb25zPGFueT4sXG4gICAgICAgICAgICB7IGFsaWFzZXMsIGVzY2FwZSB9LFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIGJ1aWx0RXhwYW5kID8gYCR7a2V5fSgke2J1aWx0RXhwYW5kfSlgIDoga2V5O1xuICAgICAgICB9KVxuICAgICAgICAuam9pbignLCcpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gJyc7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkVHJhbnNmb3JtczxUPihcbiAgdHJhbnNmb3JtczogVHJhbnNmb3JtPFQ+IHwgVHJhbnNmb3JtPFQ+W10sXG4gIHtcbiAgICBhbGlhc2VzLFxuICAgIGVzY2FwZSA9IGZhbHNlLFxuICB9OiB7IGFsaWFzZXM/OiBRdWVyeUN1c3RvbVR5cGVbXTsgZXNjYXBlPzogYm9vbGVhbiB9LFxuKSB7XG4gIC8vIFdyYXAgc2luZ2xlIG9iamVjdCBhbiBhcnJheSBmb3Igc2ltcGxpZmllZCBwcm9jZXNzaW5nXG4gIGNvbnN0IHRyYW5zZm9ybXNBcnJheSA9IEFycmF5LmlzQXJyYXkodHJhbnNmb3JtcykgPyB0cmFuc2Zvcm1zIDogW3RyYW5zZm9ybXNdO1xuXG4gIGNvbnN0IHRyYW5zZm9ybXNSZXN1bHQgPSB0cmFuc2Zvcm1zQXJyYXkucmVkdWNlKFxuICAgIChyZXN1bHQ6IHN0cmluZ1tdLCB0cmFuc2Zvcm0pID0+IHtcbiAgICAgIGNvbnN0IHsgYWdncmVnYXRlLCBmaWx0ZXIsIGdyb3VwQnksIC4uLnJlc3QgfSA9IHRyYW5zZm9ybTtcblxuICAgICAgLy8gVE9ETzogc3VwcG9ydCBhcyBtYW55IG9mIHRoZSBmb2xsb3dpbmc6XG4gICAgICAvLyAgIHRvcGNvdW50LCB0b3BzdW0sIHRvcHBlcmNlbnQsXG4gICAgICAvLyAgIGJvdHRvbXN1bSwgYm90dG9tY291bnQsIGJvdHRvbXBlcmNlbnQsXG4gICAgICAvLyAgIGlkZW50aXR5LCBjb25jYXQsIGV4cGFuZCwgc2VhcmNoLCBjb21wdXRlLCBpc2RlZmluZWRcbiAgICAgIGNvbnN0IHVuc3VwcG9ydGVkS2V5cyA9IE9iamVjdC5rZXlzKHJlc3QpO1xuICAgICAgaWYgKHVuc3VwcG9ydGVkS2V5cy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCB0cmFuc2Zvcm0ocyk6ICR7dW5zdXBwb3J0ZWRLZXlzfWApO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWdncmVnYXRlKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKGBhZ2dyZWdhdGUoJHtidWlsZEFnZ3JlZ2F0ZShhZ2dyZWdhdGUpfSlgKTtcbiAgICAgIH1cbiAgICAgIGlmIChmaWx0ZXIpIHtcbiAgICAgICAgY29uc3QgYnVpbHRGaWx0ZXIgPSBidWlsZEZpbHRlcihmaWx0ZXIsIHsgYWxpYXNlcywgZXNjYXBlIH0pO1xuICAgICAgICBpZiAoYnVpbHRGaWx0ZXIpIHtcbiAgICAgICAgICByZXN1bHQucHVzaChcbiAgICAgICAgICAgIGBmaWx0ZXIoJHtidWlsZEZpbHRlcihidWlsdEZpbHRlciwgeyBhbGlhc2VzLCBlc2NhcGUgfSl9KWAsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGdyb3VwQnkpIHtcbiAgICAgICAgcmVzdWx0LnB1c2goYGdyb3VwYnkoJHtidWlsZEdyb3VwQnkoZ3JvdXBCeSwgeyBhbGlhc2VzLCBlc2NhcGUgfSl9KWApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0sXG4gICAgW10sXG4gICk7XG5cbiAgcmV0dXJuIHRyYW5zZm9ybXNSZXN1bHQuam9pbignLycpIHx8IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gYnVpbGRBZ2dyZWdhdGUoYWdncmVnYXRlOiBBZ2dyZWdhdGVUeXBlIHwgQWdncmVnYXRlVHlwZVtdKSB7XG4gIC8vIFdyYXAgc2luZ2xlIG9iamVjdCBpbiBhbiBhcnJheSBmb3Igc2ltcGxpZmllZCBwcm9jZXNzaW5nXG4gIGNvbnN0IGFnZ3JlZ2F0ZUFycmF5ID0gQXJyYXkuaXNBcnJheShhZ2dyZWdhdGUpID8gYWdncmVnYXRlIDogW2FnZ3JlZ2F0ZV07XG5cbiAgcmV0dXJuIGFnZ3JlZ2F0ZUFycmF5XG4gICAgLm1hcCgoYWdncmVnYXRlSXRlbSkgPT4ge1xuICAgICAgcmV0dXJuIHR5cGVvZiBhZ2dyZWdhdGVJdGVtID09PSAnc3RyaW5nJ1xuICAgICAgICA/IGFnZ3JlZ2F0ZUl0ZW1cbiAgICAgICAgOiBPYmplY3Qua2V5cyhhZ2dyZWdhdGVJdGVtKS5tYXAoKGFnZ3JlZ2F0ZUtleSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYWdncmVnYXRlVmFsdWUgPSBhZ2dyZWdhdGVJdGVtW2FnZ3JlZ2F0ZUtleV07XG5cbiAgICAgICAgICAgIC8vIFRPRE86IEFyZSB0aGVzZSBhbHdheXMgcmVxdWlyZWQ/ICBDYW4vc2hvdWxkIHdlIGRlZmF1bHQgdGhlbSBpZiBzbz9cbiAgICAgICAgICAgIGlmICghYWdncmVnYXRlVmFsdWUud2l0aCkge1xuICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCd3aXRoJyBwcm9wZXJ0eSByZXF1aXJlZCBmb3IgJyR7YWdncmVnYXRlS2V5fSdgKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICghYWdncmVnYXRlVmFsdWUuYXMpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAnYXMnIHByb3BlcnR5IHJlcXVpcmVkIGZvciAnJHthZ2dyZWdhdGVLZXl9J2ApO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gYCR7YWdncmVnYXRlS2V5fSB3aXRoICR7YWdncmVnYXRlVmFsdWUud2l0aH0gYXMgJHthZ2dyZWdhdGVWYWx1ZS5hc31gO1xuICAgICAgICAgIH0pO1xuICAgIH0pXG4gICAgLmpvaW4oJywnKTtcbn1cblxuZnVuY3Rpb24gYnVpbGRHcm91cEJ5PFQ+KFxuICBncm91cEJ5OiBHcm91cEJ5VHlwZTxUPixcbiAge1xuICAgIGFsaWFzZXMsXG4gICAgZXNjYXBlID0gZmFsc2UsXG4gIH06IHsgYWxpYXNlcz86IFF1ZXJ5Q3VzdG9tVHlwZVtdOyBlc2NhcGU/OiBib29sZWFuIH0sXG4pIHtcbiAgaWYgKCFncm91cEJ5LnByb3BlcnRpZXMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCdwcm9wZXJ0aWVzJyBwcm9wZXJ0eSByZXF1aXJlZCBmb3IgZ3JvdXBCeWApO1xuICB9XG5cbiAgbGV0IHJlc3VsdCA9IGAoJHtncm91cEJ5LnByb3BlcnRpZXMuam9pbignLCcpfSlgO1xuXG4gIGlmIChncm91cEJ5LnRyYW5zZm9ybSkge1xuICAgIHJlc3VsdCArPSBgLCR7YnVpbGRUcmFuc2Zvcm1zKGdyb3VwQnkudHJhbnNmb3JtLCB7IGFsaWFzZXMsIGVzY2FwZSB9KX1gO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gYnVpbGRPcmRlckJ5PFQ+KG9yZGVyQnk6IE9yZGVyQnk8VD4sIHByZWZpeDogc3RyaW5nID0gJycpOiBzdHJpbmcge1xuICBpZiAoaXNSYXdUeXBlKG9yZGVyQnkpKSB7XG4gICAgcmV0dXJuIChvcmRlckJ5IGFzIFF1ZXJ5Q3VzdG9tVHlwZSkudmFsdWU7XG4gIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShvcmRlckJ5KSkge1xuICAgIHJldHVybiAob3JkZXJCeSBhcyBPcmRlckJ5T2JqZWN0PFQ+W10pXG4gICAgICAubWFwKCh2YWx1ZSkgPT5cbiAgICAgICAgQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiZcbiAgICAgICAgdmFsdWUubGVuZ3RoID09PSAyICYmXG4gICAgICAgIFsnYXNjJywgJ2Rlc2MnXS5pbmRleE9mKHZhbHVlWzFdKSAhPT0gLTFcbiAgICAgICAgICA/IHZhbHVlLmpvaW4oJyAnKVxuICAgICAgICAgIDogdmFsdWUsXG4gICAgICApXG4gICAgICAubWFwKCh2KSA9PiBgJHtwcmVmaXh9JHt2IGFzIHN0cmluZ31gKVxuICAgICAgLmpvaW4oJywnKTtcbiAgfSBlbHNlIGlmICh0eXBlb2Ygb3JkZXJCeSA9PT0gJ29iamVjdCcpIHtcbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXMob3JkZXJCeSlcbiAgICAgIC5tYXAoKFtrLCB2XSkgPT4gYnVpbGRPcmRlckJ5KHYgYXMgT3JkZXJCeTxhbnk+LCBgJHtrfS9gKSlcbiAgICAgIC5tYXAoKHYpID0+IGAke3ByZWZpeH0ke3Z9YClcbiAgICAgIC5qb2luKCcsJyk7XG4gIH1cbiAgcmV0dXJuIGAke3ByZWZpeH0ke29yZGVyQnkgYXMgc3RyaW5nfWA7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkQXBwbHkoXG4gIGFwcGx5OiBhbnksXG4gIHtcbiAgICBhbGlhc2VzLFxuICAgIGVzY2FwZSA9IGZhbHNlLFxuICB9OiB7IGFsaWFzZXM/OiBRdWVyeUN1c3RvbVR5cGVbXTsgZXNjYXBlPzogYm9vbGVhbiB9LFxuKSB7XG4gIGNvbnN0IGFwcGx5QXJyYXkgPSBBcnJheS5pc0FycmF5KGFwcGx5KSA/IGFwcGx5IDogW2FwcGx5XTtcbiAgcmV0dXJuIGFwcGx5QXJyYXlcbiAgICAubWFwKCh2KSA9PiBub3JtYWxpemVWYWx1ZSh2LCB7IGFsaWFzZXMsIGVzY2FwZSB9KSlcbiAgICAuam9pbignLycpO1xufVxuXG5mdW5jdGlvbiBidWlsZFVybChwYXRoOiBzdHJpbmcsIHBhcmFtczogeyBbbmFtZTogc3RyaW5nXTogYW55IH0pOiBzdHJpbmcge1xuICAvLyBUaGlzIGNhbiBiZSByZWZhY3RvcmVkIHVzaW5nIFVSTCBBUEkuIEJ1dCBJRSBkb2VzIG5vdCBzdXBwb3J0IGl0LlxuICBjb25zdCBxdWVyaWVzOiBzdHJpbmdbXSA9IE9iamVjdC5lbnRyaWVzKHBhcmFtcykubWFwKFxuICAgIChba2V5LCB2YWx1ZV0pID0+IGAke2tleX09JHt2YWx1ZX1gLFxuICApO1xuICByZXR1cm4gcXVlcmllcy5sZW5ndGggPyBgJHtwYXRofT8ke3F1ZXJpZXMuam9pbignJicpfWAgOiBwYXRoO1xufVxuXG5mdW5jdGlvbiBwYXJzZU5vdChidWlsdEZpbHRlcnM6IHN0cmluZ1tdKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBub3QoJHtidWlsdEZpbHRlcnMuam9pbignIGFuZCAnKX0pYDtcbn1cbiJdfQ==