breeze-client 2.1.5 → 2.1.6-mjs

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 (384) hide show
  1. package/adapter-ajax-angularjs/{breeze-client-adapter-ajax-angularjs.d.ts → index.d.ts} +1 -0
  2. package/adapter-ajax-fetch/{breeze-client-adapter-ajax-fetch.d.ts → index.d.ts} +1 -0
  3. package/adapter-ajax-httpclient/{breeze-client-adapter-ajax-httpclient.d.ts → index.d.ts} +1 -0
  4. package/adapter-ajax-jquery/{breeze-client-adapter-ajax-jquery.d.ts → index.d.ts} +1 -0
  5. package/adapter-ajax-post/{breeze-client-adapter-ajax-post.d.ts → index.d.ts} +1 -0
  6. package/adapter-data-service-odata/adapter-data-service-odata.d.ts +0 -1
  7. package/adapter-data-service-odata/{breeze-client-adapter-data-service-odata.d.ts → index.d.ts} +1 -0
  8. package/adapter-data-service-webapi/{breeze-client-adapter-data-service-webapi.d.ts → index.d.ts} +1 -0
  9. package/adapter-model-library-backing-store/{breeze-client-adapter-model-library-backing-store.d.ts → index.d.ts} +1 -0
  10. package/adapter-model-library-ko/{breeze-client-adapter-model-library-ko.d.ts → index.d.ts} +1 -0
  11. package/adapter-uri-builder-json/{breeze-client-adapter-uri-builder-json.d.ts → index.d.ts} +1 -0
  12. package/adapter-uri-builder-odata/{breeze-client-adapter-uri-builder-odata.d.ts → index.d.ts} +1 -0
  13. package/esm2022/adapter-ajax-angularjs/adapter-ajax-angularjs.mjs +135 -0
  14. package/esm2022/adapter-ajax-angularjs/adapter-core.mjs +49 -0
  15. package/esm2022/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.mjs +5 -0
  16. package/esm2022/adapter-ajax-fetch/adapter-ajax-fetch.mjs +135 -0
  17. package/esm2022/adapter-ajax-fetch/adapter-core.mjs +49 -0
  18. package/esm2022/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.mjs +5 -0
  19. package/esm2022/adapter-ajax-httpclient/adapter-ajax-httpclient.mjs +139 -0
  20. package/esm2022/adapter-ajax-httpclient/adapter-core.mjs +49 -0
  21. package/esm2022/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.mjs +5 -0
  22. package/esm2022/adapter-ajax-jquery/adapter-ajax-jquery.mjs +107 -0
  23. package/esm2022/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.mjs +5 -0
  24. package/esm2022/adapter-ajax-post/adapter-ajax-post.mjs +77 -0
  25. package/esm2022/adapter-ajax-post/breeze-client-adapter-ajax-post.mjs +5 -0
  26. package/esm2022/adapter-data-service-odata/adapter-core.mjs +49 -0
  27. package/esm2022/adapter-data-service-odata/adapter-data-service-odata.mjs +461 -0
  28. package/esm2022/adapter-data-service-odata/breeze-client-adapter-data-service-odata.mjs +5 -0
  29. package/esm2022/adapter-data-service-webapi/adapter-data-service-webapi.mjs +100 -0
  30. package/esm2022/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.mjs +5 -0
  31. package/esm2022/adapter-model-library-backing-store/adapter-model-library-backing-store.mjs +269 -0
  32. package/esm2022/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.mjs +5 -0
  33. package/esm2022/adapter-model-library-ko/adapter-model-library-ko.mjs +241 -0
  34. package/esm2022/adapter-model-library-ko/breeze-client-adapter-model-library-ko.mjs +5 -0
  35. package/esm2022/adapter-uri-builder-json/adapter-core.mjs +49 -0
  36. package/esm2022/adapter-uri-builder-json/adapter-uri-builder-json.mjs +37 -0
  37. package/esm2022/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.mjs +5 -0
  38. package/esm2022/adapter-uri-builder-odata/adapter-core.mjs +49 -0
  39. package/esm2022/adapter-uri-builder-odata/adapter-uri-builder-odata.mjs +191 -0
  40. package/esm2022/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.mjs +5 -0
  41. package/esm2022/breeze-client.mjs +5 -0
  42. package/esm2022/index.mjs +2 -0
  43. package/esm2022/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.mjs +5 -0
  44. package/esm2022/mixin-get-entity-graph/mixin-get-entity-graph.mjs +269 -0
  45. package/esm2022/mixin-save-queuing/breeze-client-mixin-save-queuing.mjs +5 -0
  46. package/esm2022/mixin-save-queuing/mixin-save-queuing.mjs +421 -0
  47. package/esm2022/src/abstract-data-service-adapter.mjs +294 -0
  48. package/esm2022/src/array.mjs +4 -0
  49. package/esm2022/src/assert-param.mjs +330 -0
  50. package/esm2022/src/breeze.mjs +85 -0
  51. package/esm2022/src/complex-array.mjs +117 -0
  52. package/esm2022/src/config.mjs +232 -0
  53. package/esm2022/src/core.mjs +712 -0
  54. package/esm2022/src/csdl-metadata-parser.mjs +385 -0
  55. package/esm2022/src/data-service.mjs +239 -0
  56. package/esm2022/src/data-type.mjs +507 -0
  57. package/esm2022/src/default-property-interceptor.mjs +460 -0
  58. package/esm2022/src/entity-action.mjs +45 -0
  59. package/esm2022/src/entity-aspect.mjs +897 -0
  60. package/esm2022/src/entity-group.mjs +192 -0
  61. package/esm2022/src/entity-key.mjs +127 -0
  62. package/esm2022/src/entity-manager.mjs +2183 -0
  63. package/esm2022/src/entity-metadata.mjs +2242 -0
  64. package/esm2022/src/entity-query.mjs +1005 -0
  65. package/esm2022/src/entity-state.mjs +107 -0
  66. package/{esm2015/src/enum.js → esm2022/src/enum.mjs} +3 -1
  67. package/esm2022/src/event.mjs +264 -0
  68. package/esm2022/src/interface-registry.mjs +39 -0
  69. package/esm2022/src/key-generator.mjs +110 -0
  70. package/esm2022/src/local-query-comparison-options.mjs +75 -0
  71. package/esm2022/src/mapping-context.mjs +422 -0
  72. package/{esm5/src/naming-convention.js → esm2022/src/naming-convention.mjs} +35 -29
  73. package/esm2022/src/observable-array.mjs +183 -0
  74. package/esm2022/src/predicate.mjs +1259 -0
  75. package/esm2022/src/primitive-array.mjs +85 -0
  76. package/esm2022/src/query-options.mjs +160 -0
  77. package/esm2022/src/relation-array.mjs +173 -0
  78. package/esm2022/src/save-options.mjs +51 -0
  79. package/esm2022/src/unattached-children-map.mjs +56 -0
  80. package/{esm5/src/validate.js → esm2022/src/validate.mjs} +116 -110
  81. package/esm2022/src/validation-options.mjs +78 -0
  82. package/{fesm2015/breeze-client-adapter-ajax-angularjs.js → fesm2022/breeze-client-adapter-ajax-angularjs.mjs} +6 -1
  83. package/fesm2022/breeze-client-adapter-ajax-angularjs.mjs.map +1 -0
  84. package/{fesm2015/breeze-client-adapter-ajax-fetch.js → fesm2022/breeze-client-adapter-ajax-fetch.mjs} +9 -4
  85. package/fesm2022/breeze-client-adapter-ajax-fetch.mjs.map +1 -0
  86. package/{fesm2015/breeze-client-adapter-ajax-httpclient.js → fesm2022/breeze-client-adapter-ajax-httpclient.mjs} +6 -4
  87. package/fesm2022/breeze-client-adapter-ajax-httpclient.mjs.map +1 -0
  88. package/{fesm2015/breeze-client-adapter-ajax-jquery.js → fesm2022/breeze-client-adapter-ajax-jquery.mjs} +6 -2
  89. package/fesm2022/breeze-client-adapter-ajax-jquery.mjs.map +1 -0
  90. package/{fesm2015/breeze-client-adapter-ajax-post.js → fesm2022/breeze-client-adapter-ajax-post.mjs} +1 -1
  91. package/fesm2022/breeze-client-adapter-ajax-post.mjs.map +1 -0
  92. package/{fesm2015/breeze-client-adapter-data-service-odata.js → fesm2022/breeze-client-adapter-data-service-odata.mjs} +70 -67
  93. package/fesm2022/breeze-client-adapter-data-service-odata.mjs.map +1 -0
  94. package/{fesm2015/breeze-client-adapter-data-service-webapi.js → fesm2022/breeze-client-adapter-data-service-webapi.mjs} +36 -29
  95. package/fesm2022/breeze-client-adapter-data-service-webapi.mjs.map +1 -0
  96. package/{fesm2015/breeze-client-adapter-model-library-backing-store.js → fesm2022/breeze-client-adapter-model-library-backing-store.mjs} +14 -13
  97. package/fesm2022/breeze-client-adapter-model-library-backing-store.mjs.map +1 -0
  98. package/{fesm2015/breeze-client-adapter-model-library-ko.js → fesm2022/breeze-client-adapter-model-library-ko.mjs} +14 -13
  99. package/fesm2022/breeze-client-adapter-model-library-ko.mjs.map +1 -0
  100. package/{fesm2015/breeze-client-adapter-uri-builder-json.js → fesm2022/breeze-client-adapter-uri-builder-json.mjs} +9 -8
  101. package/fesm2022/breeze-client-adapter-uri-builder-json.mjs.map +1 -0
  102. package/{fesm2015/breeze-client-adapter-uri-builder-odata.js → fesm2022/breeze-client-adapter-uri-builder-odata.mjs} +86 -86
  103. package/fesm2022/breeze-client-adapter-uri-builder-odata.mjs.map +1 -0
  104. package/{fesm2015/breeze-client-mixin-get-entity-graph.js → fesm2022/breeze-client-mixin-get-entity-graph.mjs} +1 -1
  105. package/fesm2022/breeze-client-mixin-get-entity-graph.mjs.map +1 -0
  106. package/{fesm2015/breeze-client-mixin-save-queuing.js → fesm2022/breeze-client-mixin-save-queuing.mjs} +23 -2
  107. package/fesm2022/breeze-client-mixin-save-queuing.mjs.map +1 -0
  108. package/{fesm2015/breeze-client.js → fesm2022/breeze-client.mjs} +2122 -1540
  109. package/fesm2022/breeze-client.mjs.map +1 -0
  110. package/mixin-get-entity-graph/{breeze-client-mixin-get-entity-graph.d.ts → index.d.ts} +1 -0
  111. package/mixin-save-queuing/{breeze-client-mixin-save-queuing.d.ts → index.d.ts} +1 -0
  112. package/package.json +93 -11
  113. package/src/abstract-data-service-adapter.d.ts +0 -1
  114. package/src/config.d.ts +1 -1
  115. package/src/core.d.ts +1 -1
  116. package/src/data-type.d.ts +5 -0
  117. package/src/entity-aspect.d.ts +6 -6
  118. package/src/entity-manager.d.ts +4 -4
  119. package/src/entity-metadata.d.ts +45 -33
  120. package/src/entity-query.d.ts +1 -1
  121. package/src/entity-state.d.ts +4 -0
  122. package/src/mapping-context.d.ts +1 -1
  123. package/src/predicate.d.ts +4 -7
  124. package/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.metadata.json +0 -1
  125. package/adapter-ajax-angularjs/package.json +0 -13
  126. package/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.metadata.json +0 -1
  127. package/adapter-ajax-fetch/package.json +0 -13
  128. package/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.metadata.json +0 -1
  129. package/adapter-ajax-httpclient/package.json +0 -13
  130. package/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.metadata.json +0 -1
  131. package/adapter-ajax-jquery/package.json +0 -13
  132. package/adapter-ajax-post/breeze-client-adapter-ajax-post.metadata.json +0 -1
  133. package/adapter-ajax-post/package.json +0 -13
  134. package/adapter-data-service-odata/breeze-client-adapter-data-service-odata.metadata.json +0 -1
  135. package/adapter-data-service-odata/package.json +0 -13
  136. package/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.metadata.json +0 -1
  137. package/adapter-data-service-webapi/package.json +0 -13
  138. package/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.metadata.json +0 -1
  139. package/adapter-model-library-backing-store/package.json +0 -13
  140. package/adapter-model-library-ko/breeze-client-adapter-model-library-ko.metadata.json +0 -1
  141. package/adapter-model-library-ko/package.json +0 -13
  142. package/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.metadata.json +0 -1
  143. package/adapter-uri-builder-json/package.json +0 -13
  144. package/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.metadata.json +0 -1
  145. package/adapter-uri-builder-odata/package.json +0 -13
  146. package/breeze-client.d.ts +0 -8
  147. package/breeze-client.metadata.json +0 -1
  148. package/bundles/breeze-client-adapter-ajax-angularjs.umd.js +0 -190
  149. package/bundles/breeze-client-adapter-ajax-angularjs.umd.js.map +0 -1
  150. package/bundles/breeze-client-adapter-ajax-angularjs.umd.min.js +0 -2
  151. package/bundles/breeze-client-adapter-ajax-angularjs.umd.min.js.map +0 -1
  152. package/bundles/breeze-client-adapter-ajax-fetch.umd.js +0 -190
  153. package/bundles/breeze-client-adapter-ajax-fetch.umd.js.map +0 -1
  154. package/bundles/breeze-client-adapter-ajax-fetch.umd.min.js +0 -2
  155. package/bundles/breeze-client-adapter-ajax-fetch.umd.min.js.map +0 -1
  156. package/bundles/breeze-client-adapter-ajax-httpclient.umd.js +0 -195
  157. package/bundles/breeze-client-adapter-ajax-httpclient.umd.js.map +0 -1
  158. package/bundles/breeze-client-adapter-ajax-httpclient.umd.min.js +0 -2
  159. package/bundles/breeze-client-adapter-ajax-httpclient.umd.min.js.map +0 -1
  160. package/bundles/breeze-client-adapter-ajax-jquery.umd.js +0 -115
  161. package/bundles/breeze-client-adapter-ajax-jquery.umd.js.map +0 -1
  162. package/bundles/breeze-client-adapter-ajax-jquery.umd.min.js +0 -2
  163. package/bundles/breeze-client-adapter-ajax-jquery.umd.min.js.map +0 -1
  164. package/bundles/breeze-client-adapter-ajax-post.umd.js +0 -92
  165. package/bundles/breeze-client-adapter-ajax-post.umd.js.map +0 -1
  166. package/bundles/breeze-client-adapter-ajax-post.umd.min.js +0 -2
  167. package/bundles/breeze-client-adapter-ajax-post.umd.min.js.map +0 -1
  168. package/bundles/breeze-client-adapter-data-service-odata.umd.js +0 -743
  169. package/bundles/breeze-client-adapter-data-service-odata.umd.js.map +0 -1
  170. package/bundles/breeze-client-adapter-data-service-odata.umd.min.js +0 -16
  171. package/bundles/breeze-client-adapter-data-service-odata.umd.min.js.map +0 -1
  172. package/bundles/breeze-client-adapter-data-service-webapi.umd.js +0 -326
  173. package/bundles/breeze-client-adapter-data-service-webapi.umd.js.map +0 -1
  174. package/bundles/breeze-client-adapter-data-service-webapi.umd.min.js +0 -16
  175. package/bundles/breeze-client-adapter-data-service-webapi.umd.min.js.map +0 -1
  176. package/bundles/breeze-client-adapter-model-library-backing-store.umd.js +0 -280
  177. package/bundles/breeze-client-adapter-model-library-backing-store.umd.js.map +0 -1
  178. package/bundles/breeze-client-adapter-model-library-backing-store.umd.min.js +0 -2
  179. package/bundles/breeze-client-adapter-model-library-backing-store.umd.min.js.map +0 -1
  180. package/bundles/breeze-client-adapter-model-library-ko.umd.js +0 -252
  181. package/bundles/breeze-client-adapter-model-library-ko.umd.js.map +0 -1
  182. package/bundles/breeze-client-adapter-model-library-ko.umd.min.js +0 -2
  183. package/bundles/breeze-client-adapter-model-library-ko.umd.min.js.map +0 -1
  184. package/bundles/breeze-client-adapter-uri-builder-json.umd.js +0 -96
  185. package/bundles/breeze-client-adapter-uri-builder-json.umd.js.map +0 -1
  186. package/bundles/breeze-client-adapter-uri-builder-json.umd.min.js +0 -2
  187. package/bundles/breeze-client-adapter-uri-builder-json.umd.min.js.map +0 -1
  188. package/bundles/breeze-client-adapter-uri-builder-odata.umd.js +0 -262
  189. package/bundles/breeze-client-adapter-uri-builder-odata.umd.js.map +0 -1
  190. package/bundles/breeze-client-adapter-uri-builder-odata.umd.min.js +0 -2
  191. package/bundles/breeze-client-adapter-uri-builder-odata.umd.min.js.map +0 -1
  192. package/bundles/breeze-client-mixin-get-entity-graph.umd.js +0 -258
  193. package/bundles/breeze-client-mixin-get-entity-graph.umd.js.map +0 -1
  194. package/bundles/breeze-client-mixin-get-entity-graph.umd.min.js +0 -2
  195. package/bundles/breeze-client-mixin-get-entity-graph.umd.min.js.map +0 -1
  196. package/bundles/breeze-client-mixin-save-queuing.umd.js +0 -579
  197. package/bundles/breeze-client-mixin-save-queuing.umd.js.map +0 -1
  198. package/bundles/breeze-client-mixin-save-queuing.umd.min.js +0 -16
  199. package/bundles/breeze-client-mixin-save-queuing.umd.min.js.map +0 -1
  200. package/bundles/breeze-client.umd.js +0 -14098
  201. package/bundles/breeze-client.umd.js.map +0 -1
  202. package/bundles/breeze-client.umd.min.js +0 -16
  203. package/bundles/breeze-client.umd.min.js.map +0 -1
  204. package/esm2015/adapter-ajax-angularjs/adapter-ajax-angularjs.js +0 -130
  205. package/esm2015/adapter-ajax-angularjs/adapter-core.js +0 -49
  206. package/esm2015/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.js +0 -5
  207. package/esm2015/adapter-ajax-fetch/adapter-ajax-fetch.js +0 -130
  208. package/esm2015/adapter-ajax-fetch/adapter-core.js +0 -49
  209. package/esm2015/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.js +0 -5
  210. package/esm2015/adapter-ajax-httpclient/adapter-ajax-httpclient.js +0 -137
  211. package/esm2015/adapter-ajax-httpclient/adapter-core.js +0 -49
  212. package/esm2015/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.js +0 -5
  213. package/esm2015/adapter-ajax-jquery/adapter-ajax-jquery.js +0 -103
  214. package/esm2015/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.js +0 -5
  215. package/esm2015/adapter-ajax-post/adapter-ajax-post.js +0 -77
  216. package/esm2015/adapter-ajax-post/breeze-client-adapter-ajax-post.js +0 -5
  217. package/esm2015/adapter-data-service-odata/adapter-core.js +0 -49
  218. package/esm2015/adapter-data-service-odata/adapter-data-service-odata.js +0 -459
  219. package/esm2015/adapter-data-service-odata/breeze-client-adapter-data-service-odata.js +0 -5
  220. package/esm2015/adapter-data-service-webapi/adapter-data-service-webapi.js +0 -93
  221. package/esm2015/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.js +0 -5
  222. package/esm2015/adapter-model-library-backing-store/adapter-model-library-backing-store.js +0 -268
  223. package/esm2015/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.js +0 -5
  224. package/esm2015/adapter-model-library-ko/adapter-model-library-ko.js +0 -240
  225. package/esm2015/adapter-model-library-ko/breeze-client-adapter-model-library-ko.js +0 -5
  226. package/esm2015/adapter-uri-builder-json/adapter-core.js +0 -49
  227. package/esm2015/adapter-uri-builder-json/adapter-uri-builder-json.js +0 -36
  228. package/esm2015/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.js +0 -5
  229. package/esm2015/adapter-uri-builder-odata/adapter-core.js +0 -49
  230. package/esm2015/adapter-uri-builder-odata/adapter-uri-builder-odata.js +0 -192
  231. package/esm2015/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.js +0 -5
  232. package/esm2015/breeze-client.js +0 -9
  233. package/esm2015/index.js +0 -2
  234. package/esm2015/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.js +0 -5
  235. package/esm2015/mixin-get-entity-graph/mixin-get-entity-graph.js +0 -269
  236. package/esm2015/mixin-save-queuing/breeze-client-mixin-save-queuing.js +0 -5
  237. package/esm2015/mixin-save-queuing/mixin-save-queuing.js +0 -400
  238. package/esm2015/src/abstract-data-service-adapter.js +0 -296
  239. package/esm2015/src/array.js +0 -4
  240. package/esm2015/src/assert-param.js +0 -312
  241. package/esm2015/src/breeze.js +0 -85
  242. package/esm2015/src/complex-array.js +0 -119
  243. package/esm2015/src/config.js +0 -223
  244. package/esm2015/src/core.js +0 -709
  245. package/esm2015/src/csdl-metadata-parser.js +0 -385
  246. package/esm2015/src/data-service.js +0 -203
  247. package/esm2015/src/data-type.js +0 -444
  248. package/esm2015/src/default-property-interceptor.js +0 -460
  249. package/esm2015/src/entity-action.js +0 -45
  250. package/esm2015/src/entity-aspect.js +0 -806
  251. package/esm2015/src/entity-group.js +0 -187
  252. package/esm2015/src/entity-key.js +0 -116
  253. package/esm2015/src/entity-manager.js +0 -2094
  254. package/esm2015/src/entity-metadata.js +0 -2109
  255. package/esm2015/src/entity-query.js +0 -996
  256. package/esm2015/src/entity-state.js +0 -99
  257. package/esm2015/src/event.js +0 -256
  258. package/esm2015/src/interface-registry.js +0 -41
  259. package/esm2015/src/key-generator.js +0 -108
  260. package/esm2015/src/local-query-comparison-options.js +0 -65
  261. package/esm2015/src/mapping-context.js +0 -405
  262. package/esm2015/src/naming-convention.js +0 -88
  263. package/esm2015/src/observable-array.js +0 -185
  264. package/esm2015/src/predicate.js +0 -1235
  265. package/esm2015/src/primitive-array.js +0 -87
  266. package/esm2015/src/query-options.js +0 -152
  267. package/esm2015/src/relation-array.js +0 -175
  268. package/esm2015/src/save-options.js +0 -41
  269. package/esm2015/src/unattached-children-map.js +0 -58
  270. package/esm2015/src/validate.js +0 -991
  271. package/esm2015/src/validation-options.js +0 -64
  272. package/esm5/adapter-ajax-angularjs/adapter-ajax-angularjs.js +0 -132
  273. package/esm5/adapter-ajax-angularjs/adapter-core.js +0 -49
  274. package/esm5/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.js +0 -5
  275. package/esm5/adapter-ajax-fetch/adapter-ajax-fetch.js +0 -132
  276. package/esm5/adapter-ajax-fetch/adapter-core.js +0 -49
  277. package/esm5/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.js +0 -5
  278. package/esm5/adapter-ajax-httpclient/adapter-ajax-httpclient.js +0 -139
  279. package/esm5/adapter-ajax-httpclient/adapter-core.js +0 -49
  280. package/esm5/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.js +0 -5
  281. package/esm5/adapter-ajax-jquery/adapter-ajax-jquery.js +0 -105
  282. package/esm5/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.js +0 -5
  283. package/esm5/adapter-ajax-post/adapter-ajax-post.js +0 -81
  284. package/esm5/adapter-ajax-post/breeze-client-adapter-ajax-post.js +0 -5
  285. package/esm5/adapter-data-service-odata/adapter-core.js +0 -49
  286. package/esm5/adapter-data-service-odata/adapter-data-service-odata.js +0 -466
  287. package/esm5/adapter-data-service-odata/breeze-client-adapter-data-service-odata.js +0 -5
  288. package/esm5/adapter-data-service-webapi/adapter-data-service-webapi.js +0 -98
  289. package/esm5/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.js +0 -5
  290. package/esm5/adapter-model-library-backing-store/adapter-model-library-backing-store.js +0 -270
  291. package/esm5/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.js +0 -5
  292. package/esm5/adapter-model-library-ko/adapter-model-library-ko.js +0 -242
  293. package/esm5/adapter-model-library-ko/breeze-client-adapter-model-library-ko.js +0 -5
  294. package/esm5/adapter-uri-builder-json/adapter-core.js +0 -49
  295. package/esm5/adapter-uri-builder-json/adapter-uri-builder-json.js +0 -38
  296. package/esm5/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.js +0 -5
  297. package/esm5/adapter-uri-builder-odata/adapter-core.js +0 -49
  298. package/esm5/adapter-uri-builder-odata/adapter-uri-builder-odata.js +0 -197
  299. package/esm5/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.js +0 -5
  300. package/esm5/breeze-client.js +0 -9
  301. package/esm5/index.js +0 -2
  302. package/esm5/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.js +0 -5
  303. package/esm5/mixin-get-entity-graph/mixin-get-entity-graph.js +0 -269
  304. package/esm5/mixin-save-queuing/breeze-client-mixin-save-queuing.js +0 -5
  305. package/esm5/mixin-save-queuing/mixin-save-queuing.js +0 -412
  306. package/esm5/src/abstract-data-service-adapter.js +0 -302
  307. package/esm5/src/array.js +0 -4
  308. package/esm5/src/assert-param.js +0 -317
  309. package/esm5/src/breeze.js +0 -85
  310. package/esm5/src/complex-array.js +0 -119
  311. package/esm5/src/config.js +0 -228
  312. package/esm5/src/core.js +0 -717
  313. package/esm5/src/csdl-metadata-parser.js +0 -385
  314. package/esm5/src/data-service.js +0 -207
  315. package/esm5/src/data-type.js +0 -451
  316. package/esm5/src/default-property-interceptor.js +0 -460
  317. package/esm5/src/entity-action.js +0 -52
  318. package/esm5/src/entity-aspect.js +0 -812
  319. package/esm5/src/entity-group.js +0 -189
  320. package/esm5/src/entity-key.js +0 -118
  321. package/esm5/src/entity-manager.js +0 -2112
  322. package/esm5/src/entity-metadata.js +0 -2144
  323. package/esm5/src/entity-query.js +0 -1023
  324. package/esm5/src/entity-state.js +0 -106
  325. package/esm5/src/enum.js +0 -144
  326. package/esm5/src/event.js +0 -259
  327. package/esm5/src/interface-registry.js +0 -43
  328. package/esm5/src/key-generator.js +0 -111
  329. package/esm5/src/local-query-comparison-options.js +0 -67
  330. package/esm5/src/mapping-context.js +0 -407
  331. package/esm5/src/observable-array.js +0 -201
  332. package/esm5/src/predicate.js +0 -1300
  333. package/esm5/src/primitive-array.js +0 -87
  334. package/esm5/src/query-options.js +0 -167
  335. package/esm5/src/relation-array.js +0 -175
  336. package/esm5/src/save-options.js +0 -43
  337. package/esm5/src/unattached-children-map.js +0 -60
  338. package/esm5/src/validation-options.js +0 -66
  339. package/fesm2015/breeze-client-adapter-ajax-angularjs.js.map +0 -1
  340. package/fesm2015/breeze-client-adapter-ajax-fetch.js.map +0 -1
  341. package/fesm2015/breeze-client-adapter-ajax-httpclient.js.map +0 -1
  342. package/fesm2015/breeze-client-adapter-ajax-jquery.js.map +0 -1
  343. package/fesm2015/breeze-client-adapter-ajax-post.js.map +0 -1
  344. package/fesm2015/breeze-client-adapter-data-service-odata.js.map +0 -1
  345. package/fesm2015/breeze-client-adapter-data-service-webapi.js.map +0 -1
  346. package/fesm2015/breeze-client-adapter-model-library-backing-store.js.map +0 -1
  347. package/fesm2015/breeze-client-adapter-model-library-ko.js.map +0 -1
  348. package/fesm2015/breeze-client-adapter-uri-builder-json.js.map +0 -1
  349. package/fesm2015/breeze-client-adapter-uri-builder-odata.js.map +0 -1
  350. package/fesm2015/breeze-client-mixin-get-entity-graph.js.map +0 -1
  351. package/fesm2015/breeze-client-mixin-save-queuing.js.map +0 -1
  352. package/fesm2015/breeze-client.js.map +0 -1
  353. package/fesm5/breeze-client-adapter-ajax-angularjs.js +0 -186
  354. package/fesm5/breeze-client-adapter-ajax-angularjs.js.map +0 -1
  355. package/fesm5/breeze-client-adapter-ajax-fetch.js +0 -186
  356. package/fesm5/breeze-client-adapter-ajax-fetch.js.map +0 -1
  357. package/fesm5/breeze-client-adapter-ajax-httpclient.js +0 -193
  358. package/fesm5/breeze-client-adapter-ajax-httpclient.js.map +0 -1
  359. package/fesm5/breeze-client-adapter-ajax-jquery.js +0 -111
  360. package/fesm5/breeze-client-adapter-ajax-jquery.js.map +0 -1
  361. package/fesm5/breeze-client-adapter-ajax-post.js +0 -86
  362. package/fesm5/breeze-client-adapter-ajax-post.js.map +0 -1
  363. package/fesm5/breeze-client-adapter-data-service-odata.js +0 -519
  364. package/fesm5/breeze-client-adapter-data-service-odata.js.map +0 -1
  365. package/fesm5/breeze-client-adapter-data-service-webapi.js +0 -104
  366. package/fesm5/breeze-client-adapter-data-service-webapi.js.map +0 -1
  367. package/fesm5/breeze-client-adapter-model-library-backing-store.js +0 -276
  368. package/fesm5/breeze-client-adapter-model-library-backing-store.js.map +0 -1
  369. package/fesm5/breeze-client-adapter-model-library-ko.js +0 -248
  370. package/fesm5/breeze-client-adapter-model-library-ko.js.map +0 -1
  371. package/fesm5/breeze-client-adapter-uri-builder-json.js +0 -92
  372. package/fesm5/breeze-client-adapter-uri-builder-json.js.map +0 -1
  373. package/fesm5/breeze-client-adapter-uri-builder-odata.js +0 -250
  374. package/fesm5/breeze-client-adapter-uri-builder-odata.js.map +0 -1
  375. package/fesm5/breeze-client-mixin-get-entity-graph.js +0 -254
  376. package/fesm5/breeze-client-mixin-get-entity-graph.js.map +0 -1
  377. package/fesm5/breeze-client-mixin-save-queuing.js +0 -356
  378. package/fesm5/breeze-client-mixin-save-queuing.js.map +0 -1
  379. package/fesm5/breeze-client.js +0 -13820
  380. package/fesm5/breeze-client.js.map +0 -1
  381. package/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.metadata.json +0 -1
  382. package/mixin-get-entity-graph/package.json +0 -13
  383. package/mixin-save-queuing/breeze-client-mixin-save-queuing.metadata.json +0 -1
  384. package/mixin-save-queuing/package.json +0 -13
@@ -1,806 +0,0 @@
1
- import { core } from './core';
2
- import { config } from './config';
3
- import { BreezeEvent } from './event';
4
- import { assertParam } from './assert-param';
5
- import { EntityState } from './entity-state';
6
- import { EntityAction } from './entity-action';
7
- import { EntityType } from './entity-metadata';
8
- import { EntityKey } from './entity-key';
9
- import { Validator, ValidationError } from './validate';
10
- import { EntityQuery } from './entity-query';
11
- /**
12
- An EntityAspect instance is associated with every attached entity and is accessed via the entity's 'entityAspect' property.
13
-
14
- The EntityAspect itself provides properties to determine and modify the EntityState of the entity and has methods
15
- that provide a variety of services including validation and change tracking.
16
-
17
- An EntityAspect will almost never need to be constructed directly. You will usually get an EntityAspect by accessing
18
- an entities 'entityAspect' property. This property will be automatically attached when an entity is created via either
19
- a query, import or [[EntityManager.createEntity]] call.
20
- > // assume order is an order entity attached to an EntityManager.
21
- > var aspect = order.entityAspect;
22
- > var currentState = aspect.entityState;
23
-
24
- **/
25
- export class EntityAspect {
26
- /** @hidden @internal */
27
- constructor(entity) {
28
- // if called without new
29
- // if (!(this instanceof EntityAspect)) {
30
- // return new EntityAspect(entity);
31
- // }
32
- /**
33
- Sets the entity to an EntityState of 'Unchanged'. This is also the equivalent of calling [[EntityAspect.acceptChanges]].
34
- The same operation can be performed by calling [[EntityAspect.setEntityState]].
35
- > // assume order is an order entity attached to an EntityManager.
36
- > order.entityAspect.setUnchanged();
37
- > // The 'order' entity will now be in an 'Unchanged' state with any changes committed.
38
- **/
39
- this.setUnchanged = function () {
40
- return this.setEntityState(EntityState.Unchanged);
41
- };
42
- /**
43
- Sets the entity to an EntityState of 'Modified'. This can also be achieved by changing the value of any property on an 'Unchanged' entity.
44
- The same operation can be performed by calling [[EntityAspect.setEntityState]].
45
- > // assume order is an order entity attached to an EntityManager.
46
- > order.entityAspect.setModified();
47
- > // The 'order' entity will now be in a 'Modified' state.
48
- **/
49
- this.setModified = function () {
50
- return this.setEntityState(EntityState.Modified);
51
- };
52
- /**
53
- Sets the entity to an EntityState of 'Deleted'. This both marks the entity as being scheduled for deletion during the next 'Save' call
54
- but also removes the entity from all of its related entities.
55
- The same operation can be performed by calling [[EntityAspect.setEntityState]].
56
- > // assume order is an order entity attached to an EntityManager.
57
- > order.entityAspect.setDeleted();
58
- > // The 'order' entity will now be in a 'Deleted' state and it will no longer have any 'related' entities.
59
- **/
60
- this.setDeleted = function () {
61
- return this.setEntityState(EntityState.Deleted);
62
- };
63
- /**
64
- Sets the entity to an EntityState of 'Detached'. This removes the entity from all of its related entities, but does NOT change the EntityState of any existing entities.
65
- The same operation can be performed by calling [[EntityAspect.setEntityState]].
66
- > // assume order is an order entity attached to an EntityManager.
67
- > order.entityAspect.setDetached();
68
- > // The 'order' entity will now be in a 'Detached' state and it will no longer have any 'related' entities.
69
- **/
70
- this.setDetached = function () {
71
- return this.setEntityState(EntityState.Detached);
72
- };
73
- this.entity = entity;
74
- // TODO: keep public or not?
75
- this.entityGroup = undefined;
76
- this.entityManager = undefined;
77
- this.entityState = EntityState.Detached;
78
- this.isBeingSaved = false;
79
- this.originalValues = {};
80
- this.hasValidationErrors = false;
81
- this._validationErrors = {};
82
- // Uncomment when we implement entityAspect.isNavigationPropertyLoaded method
83
- // this._loadedNavPropMap = {};
84
- this.validationErrorsChanged = new BreezeEvent("validationErrorsChanged", this);
85
- this.propertyChanged = new BreezeEvent("propertyChanged", this);
86
- // in case this is the NULL entityAspect. - used with ComplexAspects that have no parent.
87
- if (entity != null) {
88
- // remove properties that should be on prototype but placed on class by Babel
89
- if (!entity.entityType) {
90
- delete (entity.entityType);
91
- }
92
- if (!entity.entityAspect) {
93
- delete (entity.entityAspect);
94
- }
95
- entity.entityAspect = this;
96
- // entityType should already be on the entity from 'watch'
97
- let entityType = entity.entityType || entity._$entityType;
98
- if (!entityType) {
99
- let typeName = entity.prototype._$typeName;
100
- if (!typeName) {
101
- throw new Error("This entity is not registered as a valid EntityType");
102
- }
103
- else {
104
- throw new Error("Metadata for this entityType has not yet been resolved: " + typeName);
105
- }
106
- }
107
- let entityCtor = entityType.getEntityCtor();
108
- config.interfaceRegistry.modelLibrary.getDefaultInstance().startTracking(entity, entityCtor.prototype);
109
- }
110
- }
111
- /** @hidden */
112
- // type-guard
113
- static isEntity(obj) {
114
- return obj.entityAspect != null;
115
- }
116
- // No longer used
117
- // static createFrom(entity: Entity): EntityAspect {
118
- // if (entity == null) {
119
- // return EntityAspect._nullInstance;
120
- // } else if (entity.entityAspect) {
121
- // return entity.entityAspect;
122
- // }
123
- // return new EntityAspect(entity);
124
- // }
125
- // TODO: refactor this and the instance getPropertyValue method.
126
- /**
127
- Returns the value of a specified 'property path' for a specified entity.
128
-
129
- The propertyPath can be either a string delimited with '.' or a string array.
130
- **/
131
- // used by EntityQuery and Predicate
132
- static getPropertyPathValue(obj, propertyPath) {
133
- let properties = Array.isArray(propertyPath) ? propertyPath : propertyPath.split(".");
134
- if (properties.length === 1) {
135
- return obj.getProperty(propertyPath);
136
- }
137
- else {
138
- let nextValue = obj;
139
- // hack use of some to perform mapFirst operation.
140
- properties.some((prop) => {
141
- nextValue = nextValue.getProperty(prop);
142
- return nextValue == null;
143
- });
144
- return nextValue;
145
- }
146
- }
147
- /**
148
- Returns the [[EntityKey]] for this Entity.
149
- > // assume order is an order entity attached to an EntityManager.
150
- > var entityKey = order.entityAspect.getKey();
151
- @param forceRefresh - (boolean=false) Forces the recalculation of the key. This should normally be unnecessary.
152
- @return The [[EntityKey]] associated with this Entity.
153
- **/
154
- getKey(forceRefresh = false) {
155
- forceRefresh = assertParam(forceRefresh, "forceRefresh").isBoolean().isOptional().check(false);
156
- if (forceRefresh || !this._entityKey) {
157
- let entityType = this.entity.entityType;
158
- let keyProps = entityType.keyProperties;
159
- let values = keyProps.map(function (p) {
160
- return this.entity.getProperty(p.name);
161
- }, this);
162
- this._entityKey = new EntityKey(entityType, values);
163
- }
164
- return this._entityKey;
165
- }
166
- /**
167
- Returns the entity to an [[EntityState]] of 'Unchanged' by committing all changes made since the entity was last queried
168
- had 'acceptChanges' called on it.
169
- > // assume order is an order entity attached to an EntityManager.
170
- > order.entityAspect.acceptChanges();
171
- > // The 'order' entity will now be in an 'Unchanged' state with any changes committed.
172
- **/
173
- acceptChanges() {
174
- if (!this.entity)
175
- return;
176
- this._checkOperation("acceptChanges");
177
- let em = this.entityManager;
178
- if (this.entityState.isDeleted()) {
179
- em.detachEntity(this.entity);
180
- }
181
- else {
182
- this.setUnchanged();
183
- }
184
- em.entityChanged.publish({ entityAction: EntityAction.AcceptChanges, entity: this.entity });
185
- }
186
- /**
187
- Returns the entity to an [[EntityState]] of 'Unchanged' by rejecting all changes made to it since the entity was last queried
188
- had 'rejectChanges' called on it.
189
- > // assume order is an order entity attached to an EntityManager.
190
- > order.entityAspect.rejectChanges();
191
- > // The 'order' entity will now be in an 'Unchanged' state with any changes rejected.
192
- **/
193
- rejectChanges() {
194
- this._checkOperation("rejectChanges");
195
- let entity = this.entity;
196
- let entityManager = this.entityManager;
197
- // we do not want PropertyChange or EntityChange events to occur here
198
- core.using(entityManager, "isRejectingChanges", true, function () {
199
- rejectChangesCore(entity);
200
- });
201
- if (this.entityState.isAdded()) {
202
- // next line is needed because the following line will cause this.entityManager -> null;
203
- entityManager.detachEntity(entity);
204
- // need to tell em that an entity that needed to be saved no longer does.
205
- entityManager._notifyStateChange(entity, false);
206
- }
207
- else {
208
- if (this.entityState.isDeleted()) {
209
- entityManager._linkRelatedEntities(entity);
210
- }
211
- this.setUnchanged();
212
- // propertyChanged propertyName is not specified because more than one property may have changed.
213
- this.propertyChanged.publish({ entity: entity, propertyName: null });
214
- entityManager.entityChanged.publish({ entityAction: EntityAction.RejectChanges, entity: entity });
215
- }
216
- }
217
- /** @hidden @internal */
218
- // TODO: rename - and use '_'; used on both EntityAspect and ComplexAspect for polymorphic reasons.
219
- getPropertyPath(propName) {
220
- return propName;
221
- }
222
- /**
223
- Sets the entity to an EntityState of 'Added'. This is NOT the equivalent of calling [[EntityManager.addEntity]]
224
- because no key generation will occur for autogenerated keys as a result of this operation. As a result this operation can be problematic
225
- unless you are certain that the entity being marked 'Added' does not already exist in the database and does not have an autogenerated key.
226
- The same operation can be performed by calling [[EntityAspect.setEntityState]].
227
- > // assume order is an order entity attached to an EntityManager.
228
- > order.entityAspect.setAdded();
229
- > // The 'order' entity will now be in an 'Added' state.
230
- **/
231
- setAdded() {
232
- return this.setEntityState(EntityState.Added);
233
- }
234
- /**
235
- Sets the entity to the specified EntityState. See also 'setUnchanged', 'setModified', 'setDetached', etc.
236
- > // assume order is an order entity attached to an EntityManager.
237
- > order.entityAspect.setEntityState(EntityState.Unchanged);
238
- > // The 'order' entity will now be in a 'Unchanged' state.
239
- **/
240
- setEntityState(entityState) {
241
- if (this.entityState === entityState)
242
- return false;
243
- this._checkOperation("setEntityState");
244
- if (this.entityState.isDetached()) {
245
- throw new Error("You cannot set the 'entityState' of an entity when it is detached - except by first attaching it to an EntityManager");
246
- }
247
- let entity = this.entity;
248
- let em = this.entityManager;
249
- let needsSave = true;
250
- if (entityState === EntityState.Unchanged) {
251
- clearOriginalValues(entity);
252
- delete this.hasTempKey;
253
- needsSave = false;
254
- }
255
- else if (entityState === EntityState.Added) {
256
- clearOriginalValues(entity);
257
- // TODO: more to do here... like regenerating key ???
258
- }
259
- else if (entityState === EntityState.Deleted) {
260
- if (this.entityState.isAdded()) {
261
- // turn it into a detach and exit early
262
- this.setEntityState(EntityState.Detached);
263
- return true;
264
- }
265
- else {
266
- // TODO: think about cascade deletes
267
- // entityState needs to be set it early in this one case to insure that fk's are not cleared.
268
- this.entityState = EntityState.Deleted;
269
- removeFromRelations(entity, EntityState.Deleted);
270
- }
271
- }
272
- else if (entityState === EntityState.Modified) {
273
- // nothing extra needed
274
- }
275
- else if (entityState === EntityState.Detached) {
276
- let group = this.entityGroup;
277
- // no group === already detached.
278
- if (!group)
279
- return false;
280
- group.detachEntity(entity);
281
- // needs to occur early here - so this IS deliberately redundent with the same code later in this method.
282
- this.entityState = entityState;
283
- removeFromRelations(entity, EntityState.Detached);
284
- this._detach();
285
- em.entityChanged.publish({ entityAction: EntityAction.Detach, entity: entity });
286
- needsSave = false;
287
- }
288
- this.entityState = entityState;
289
- em._notifyStateChange(entity, needsSave);
290
- return true;
291
- }
292
- /**
293
- Performs a query for the value of a specified [[NavigationProperty]]. __Async__
294
- > emp.entityAspect.loadNavigationProperty("Orders").then(function (data) {
295
- > var orders = data.results;
296
- > }).catch(function (exception) {
297
- > // handle exception here;
298
- > });
299
- @param navigationProperty - The NavigationProperty or the name of the NavigationProperty to 'load'.
300
- @param callback - Function to call on success.
301
- @param errorCallback - Function to call on failure.
302
- @return Promise with shape
303
- - results {Array of Entity}
304
- - query {EntityQuery} The original query
305
- - httpResponse {httpResponse} The HttpResponse returned from the server.
306
- **/
307
- loadNavigationProperty(navigationProperty, callback, errorCallback) {
308
- let entity = this.entity;
309
- let navProperty = entity.entityType._checkNavProperty(navigationProperty);
310
- let query = EntityQuery.fromEntityNavigation(entity, navProperty);
311
- // return entity.entityAspect.entityManager.executeQuery(query, callback, errorCallback);
312
- let promise = entity.entityAspect.entityManager.executeQuery(query);
313
- return promise.then((data) => {
314
- this._markAsLoaded(navProperty.name);
315
- if (callback)
316
- callback(data);
317
- return Promise.resolve(data);
318
- }, (error) => {
319
- if (errorCallback)
320
- errorCallback(error);
321
- return Promise.reject(error);
322
- });
323
- }
324
- /**
325
- Marks this navigationProperty on this entity as already having been loaded.
326
- > emp.entityAspect.markNavigationPropertyAsLoaded("Orders");
327
- @param navigationProperty - The NavigationProperty or name of NavigationProperty to 'load'.
328
- **/
329
- markNavigationPropertyAsLoaded(navigationProperty) {
330
- if (!this.entity)
331
- return;
332
- let navProperty = this.entity.entityType._checkNavProperty(navigationProperty);
333
- this._markAsLoaded(navProperty.name);
334
- }
335
- /**
336
- Determines whether a navigationProperty on this entity has already been loaded.
337
-
338
- A navigation property is considered loaded when any of the following three conditions applies:
339
-
340
- 1. It was fetched from the backend server.
341
- <br/> This can be the result of an expand query or a call to the [[EntityAspect.loadNavigationProperty]] method.
342
- <br/> Note that even if the fetch returns nothing the property is still marked as loaded in this case.
343
- 1. The property is scalar and has been set to a nonnull value.
344
- 1. The [[EntityAspect.markNavigationPropertyAsLoaded]] was called.
345
-
346
- > var wasLoaded = emp.entityAspect.isNavigationPropertyLoaded("Orders");
347
- @param navigationProperty - The NavigationProperty or name of NavigationProperty to 'load'.
348
- **/
349
- isNavigationPropertyLoaded(navigationProperty) {
350
- if (!this.entity)
351
- return;
352
- let navProperty = this.entity.entityType._checkNavProperty(navigationProperty);
353
- if (navProperty.isScalar && this.entity.getProperty(navProperty.name) != null) {
354
- return true;
355
- }
356
- return this._loadedNps && this._loadedNps.indexOf(navProperty.name) >= 0;
357
- }
358
- /** @hidden @internal */
359
- _markAsLoaded(navPropName) {
360
- this._loadedNps = this._loadedNps || [];
361
- core.arrayAddItemUnique(this._loadedNps, navPropName);
362
- }
363
- /**
364
- Performs validation on the entity, any errors encountered during the validation are available via the
365
- [[EntityAspect.getValidationErrors]] method. Validating an entity means executing
366
- all of the validators on both the entity itself as well as those on each of its properties.
367
- > // assume order is an order entity attached to an EntityManager.
368
- > var isOk = order.entityAspect.validateEntity();
369
- > // isOk will be 'true' if there are no errors on the entity.
370
- > if (!isOk) {
371
- > var errors = order.entityAspect.getValidationErrors();
372
- > }
373
- @return Whether the entity passed validation.
374
- **/
375
- validateEntity() {
376
- let ok = true;
377
- this._processValidationOpAndPublish(function (that) {
378
- ok = validateTarget(that.entity);
379
- });
380
- return ok;
381
- }
382
- /**
383
- Performs validation on a specific property of this entity, any errors encountered during the validation are available via the
384
- [[EntityAspect.getValidationErrors]] method. Validating a property means executing
385
- all of the validators on the specified property. This call is also made automatically anytime a property
386
- of an entity is changed.
387
- > // assume order is an order entity attached to an EntityManager.
388
- > var isOk = order.entityAspect.validateProperty("Order");
389
-
390
- or
391
- > var orderDateProperty = order.entityType.getProperty("OrderDate");
392
- > var isOk = order.entityAspect.validateProperty(OrderDateProperty);
393
- @param property - The [[DataProperty]] or [[NavigationProperty]] to validate or a string
394
- with the name of the property or a property path with the path to a property of a complex object.
395
- @param context - A context object used to pass additional information to each [[Validator]].
396
- @return Whether the entity passed validation.
397
- **/
398
- validateProperty(property, context) {
399
- let value = this.getPropertyValue(property); // performs validations
400
- if (value && value.complexAspect) {
401
- return validateTarget(value);
402
- }
403
- context = context || {};
404
- context.entity = this.entity;
405
- if (typeof property === "string") {
406
- context.property = this.entity.entityType.getProperty(property, true);
407
- context.propertyName = property;
408
- }
409
- else {
410
- context.property = property;
411
- context.propertyName = property.name;
412
- }
413
- return this._validateProperty(value, context);
414
- }
415
- /**
416
- Returns the validation errors associated with either the entire entity or any specified property.
417
-
418
- This method can return all of the errors for an Entity
419
- > // assume order is an order entity attached to an EntityManager.
420
- > var valErrors = order.entityAspect.getValidationErrors();
421
-
422
- as well as those for just a specific property.
423
- > // assume order is an order entity attached to an EntityManager.
424
- > var orderDateErrors = order.entityAspect.getValidationErrors("OrderDate");
425
-
426
- which can also be expressed as
427
- > // assume order is an order entity attached to an EntityManager.
428
- > var orderDateProperty = order.entityType.getProperty("OrderDate");
429
- > var orderDateErrors = order.entityAspect.getValidationErrors(orderDateProperty);
430
- @param property - The property for which validation errors should be retrieved.
431
- If omitted, all of the validation errors for this entity will be returned.
432
- @return A array of validation errors.
433
- **/
434
- getValidationErrors(property) {
435
- assertParam(property, "property").isOptional().isEntityProperty().or().isString().check();
436
- let result = core.getOwnPropertyValues(this._validationErrors);
437
- if (property) {
438
- let propertyName = typeof (property) === 'string' ? property : property.name;
439
- result = result.filter(function (ve) {
440
- return ve.property && (ve.property.name === propertyName || (propertyName.indexOf(".") !== -1 && ve.propertyName === propertyName));
441
- });
442
- }
443
- return result;
444
- }
445
- /**
446
- Adds a validation error.
447
- **/
448
- addValidationError(validationError) {
449
- assertParam(validationError, "validationError").isInstanceOf(ValidationError).check();
450
- this._processValidationOpAndPublish(function (that) {
451
- that._addValidationError(validationError);
452
- });
453
- }
454
- /**
455
- Removes a validation error.
456
- @param validationErrorOrKey - Either a ValidationError or a ValidationError 'key' value
457
- **/
458
- removeValidationError(validationErrorOrKey) {
459
- assertParam(validationErrorOrKey, "validationErrorOrKey").isString().or().isInstanceOf(ValidationError).or().isInstanceOf(Validator).check();
460
- let key = (typeof (validationErrorOrKey) === "string") ? validationErrorOrKey : validationErrorOrKey.key;
461
- this._processValidationOpAndPublish(function (that) {
462
- that._removeValidationError(key);
463
- });
464
- }
465
- /**
466
- Removes all of the validation errors for a specified entity
467
- **/
468
- clearValidationErrors() {
469
- this._processValidationOpAndPublish(function (that) {
470
- core.objectForEach(that._validationErrors, function (key, valError) {
471
- if (valError) {
472
- delete that._validationErrors[key];
473
- that._pendingValidationResult.removed.push(valError);
474
- }
475
- });
476
- that.hasValidationErrors = !core.isEmpty(that._validationErrors);
477
- });
478
- }
479
- /**
480
- Returns an [[EntityKey]] for the entity pointed to by the specified scalar NavigationProperty.
481
- This only returns an EntityKey if the current entity is a 'child' entity along the specified NavigationProperty.
482
- i.e. has a single parent.
483
-
484
- @param navigationProperty - The [[NavigationProperty]] ( pointing to a parent).
485
- @returns Either a parent EntityKey if this is a 'child' entity or null;
486
- */
487
- getParentKey(navigationProperty) {
488
- if (!this.entity)
489
- return null;
490
- // TODO: review this - not sure about the comment.
491
- // NavigationProperty doesn't yet exist
492
- // assertParam(navigationProperty, "navigationProperty").isInstanceOf(NavigationProperty).check();
493
- let fkNames = navigationProperty.foreignKeyNames;
494
- if (fkNames.length === 0)
495
- return null;
496
- let that = this;
497
- let fkValues = fkNames.map(function (fkn) {
498
- return that.entity.getProperty(fkn);
499
- });
500
- return new EntityKey(navigationProperty.entityType, fkValues);
501
- }
502
- // TODO: refactor this and the static getPropertyPathValue.
503
- /**
504
- Returns the value of a specified DataProperty or NavigationProperty or 'property path'.
505
- **/
506
- getPropertyValue(property) {
507
- assertParam(property, "property").isString().or().isEntityProperty().check();
508
- let value;
509
- if (typeof (property) === 'string') {
510
- let propNames = property.trim().split(".");
511
- let propName = propNames.shift();
512
- value = this.entity;
513
- value = value.getProperty(propName);
514
- while (propNames.length > 0) {
515
- propName = propNames.shift();
516
- value = value.getProperty(propName);
517
- }
518
- }
519
- else {
520
- if (!(property.parentType instanceof EntityType)) {
521
- throw new Error("The validateProperty method does not accept a 'property' parameter whose parentType is a ComplexType; " +
522
- "Pass a 'property path' string as the 'property' parameter instead ");
523
- }
524
- value = this.entity.getProperty(property.name);
525
- }
526
- return value;
527
- }
528
- // internal methods
529
- /** @hidden @internal */
530
- _checkOperation(operationName) {
531
- if (this.isBeingSaved) {
532
- throw new Error("Cannot perform a '" + operationName + "' on an entity that is in the process of being saved");
533
- }
534
- // allows chaining
535
- return this;
536
- }
537
- /** @hidden @internal */
538
- _detach() {
539
- this.entityGroup = undefined;
540
- this.entityManager = undefined;
541
- this.entityState = EntityState.Detached;
542
- this.originalValues = {};
543
- this._validationErrors = {};
544
- this.hasValidationErrors = false;
545
- this.validationErrorsChanged.clear();
546
- this.propertyChanged.clear();
547
- }
548
- // called from defaultInterceptor.
549
- /** @hidden @internal */
550
- _validateProperty(value, context) {
551
- let ok = true;
552
- this._processValidationOpAndPublish(function (that) {
553
- context.property.getAllValidators().forEach(function (validator) {
554
- ok = validate(that, validator, value, context) && ok;
555
- });
556
- });
557
- return ok;
558
- }
559
- /** @hidden @internal */
560
- _processValidationOpAndPublish(validationFn) {
561
- if (this._pendingValidationResult) {
562
- // only top level processValidations call publishes
563
- validationFn(this);
564
- }
565
- else {
566
- try {
567
- this._pendingValidationResult = { entity: this.entity, added: [], removed: [] };
568
- validationFn(this);
569
- if (this._pendingValidationResult.added.length > 0 || this._pendingValidationResult.removed.length > 0) {
570
- this.validationErrorsChanged.publish(this._pendingValidationResult);
571
- // this might be a detached entity hence the guard below.
572
- this.entityManager && this.entityManager.validationErrorsChanged.publish(this._pendingValidationResult);
573
- }
574
- }
575
- finally {
576
- this._pendingValidationResult = undefined;
577
- }
578
- }
579
- }
580
- /** @hidden @internal */
581
- // TODO: add/use a ValidationError type
582
- _addValidationError(validationError) {
583
- this._validationErrors[validationError.key] = validationError;
584
- this.hasValidationErrors = true;
585
- this._pendingValidationResult.added.push(validationError);
586
- }
587
- /** @hidden @internal */
588
- _removeValidationError(key) {
589
- let valError = this._validationErrors[key];
590
- if (valError) {
591
- delete this._validationErrors[key];
592
- this.hasValidationErrors = !core.isEmpty(this._validationErrors);
593
- this._pendingValidationResult.removed.push(valError);
594
- }
595
- }
596
- }
597
- /** @hidden @internal */
598
- EntityAspect._nullInstance = new EntityAspect(); // TODO: determine if this works
599
- BreezeEvent.bubbleEvent(EntityAspect.prototype, function () {
600
- return this.entityManager;
601
- });
602
- function rejectChangesCore(target) {
603
- let aspect = target.entityAspect || target.complexAspect;
604
- let stype = target.entityType || target.complexType;
605
- let originalValues = aspect.originalValues;
606
- for (let propName in originalValues) {
607
- target.setProperty(propName, originalValues[propName]);
608
- }
609
- stype.complexProperties.forEach(function (cp) {
610
- let cos = target.getProperty(cp.name);
611
- if (cp.isScalar) {
612
- rejectChangesCore(cos);
613
- }
614
- else {
615
- cos._rejectChanges();
616
- cos.forEach(rejectChangesCore);
617
- }
618
- });
619
- }
620
- function removeFromRelations(entity, entityState) {
621
- // remove this entity from any collections.
622
- // mark the entity deleted or detached
623
- let isDeleted = entityState.isDeleted();
624
- if (isDeleted) {
625
- removeFromRelationsCore(entity);
626
- }
627
- else {
628
- core.using(entity.entityAspect.entityManager, "isLoading", true, function () {
629
- removeFromRelationsCore(entity);
630
- });
631
- }
632
- }
633
- function removeFromRelationsCore(entity) {
634
- entity.entityType.navigationProperties.forEach(function (np) {
635
- let inverseNp = np.inverse;
636
- let npValue = entity.getProperty(np.name);
637
- if (np.isScalar) {
638
- if (npValue) {
639
- if (inverseNp) {
640
- if (inverseNp.isScalar) {
641
- npValue.setProperty(inverseNp.name, null);
642
- }
643
- else {
644
- let collection = npValue.getProperty(inverseNp.name);
645
- if (collection.length) {
646
- core.arrayRemoveItem(collection, entity);
647
- }
648
- }
649
- }
650
- entity.setProperty(np.name, null);
651
- }
652
- }
653
- else {
654
- if (inverseNp != null) {
655
- // npValue is a live list so we need to copy it first.
656
- npValue.slice(0).forEach((v) => {
657
- if (inverseNp.isScalar) {
658
- v.setProperty(inverseNp.name, null);
659
- }
660
- else {
661
- // TODO: many to many - not yet handled.
662
- }
663
- });
664
- }
665
- // now clear it.
666
- npValue.length = 0;
667
- }
668
- });
669
- }
670
- // note entityAspect only - ( no complex aspect allowed on the call).
671
- function validate(entityAspect, validator, value, context) {
672
- let ve = validator.validate(value, context);
673
- if (ve) {
674
- entityAspect._addValidationError(ve);
675
- return false;
676
- }
677
- else {
678
- let key = ValidationError.getKey(validator, context ? context.propertyName : null);
679
- entityAspect._removeValidationError(key);
680
- return true;
681
- }
682
- }
683
- // coIndex is only used where target is a complex object that is part of an array of complex objects
684
- // in which case ctIndex is the index of the target within the array.
685
- function validateTarget(target, coIndex) {
686
- let ok = true;
687
- let stype = target.entityType || target.complexType;
688
- let aspect = target.entityAspect || target.complexAspect;
689
- let entityAspect = target.entityAspect || target.complexAspect.getEntityAspect();
690
- let context = { entity: entityAspect.entity };
691
- if (coIndex !== undefined) {
692
- context.index = coIndex;
693
- }
694
- stype.getProperties().forEach(function (p) {
695
- let value = target.getProperty(p.name);
696
- let validators = p.getAllValidators();
697
- if (validators.length > 0) {
698
- context.property = p;
699
- context.propertyName = aspect.getPropertyPath(p.name);
700
- ok = entityAspect._validateProperty(value, context) && ok;
701
- }
702
- if (p.isComplexProperty) {
703
- if (p.isScalar) {
704
- ok = validateTarget(value) && ok;
705
- }
706
- else {
707
- ok = value.reduce(function (pv, cv, ix) {
708
- return validateTarget(cv, ix) && pv;
709
- }, ok);
710
- }
711
- }
712
- });
713
- // then target level
714
- stype.getAllValidators().forEach(function (validator) {
715
- ok = validate(entityAspect, validator, target) && ok;
716
- });
717
- return ok;
718
- }
719
- /**
720
- An ComplexAspect instance is associated with every complex object instance and is accessed via the complex object's 'complexAspect' property.
721
-
722
- The ComplexAspect itself provides properties to determine the parent object, parent property and original values for the complex object.
723
-
724
- A ComplexAspect will almost never need to be constructed directly. You will usually get an ComplexAspect by accessing
725
- an entities 'complexAspect' property. This property will be automatically attached when an complex object is created as part of an
726
- entity via either a query, import or EntityManager.createEntity call.
727
- > // assume address is a complex property on the 'Customer' type
728
- > var aspect = aCustomer.address.complexAspect;
729
- > // aCustomer === aspect.parent;
730
- **/
731
- export class ComplexAspect {
732
- /** You will rarely, if ever, create a ComplexAspect directly. */
733
- constructor(complexObject, parent, parentProperty) {
734
- if (!complexObject) {
735
- throw new Error("The ComplexAspect ctor requires an entity as its only argument.");
736
- }
737
- if (complexObject.complexAspect) {
738
- return complexObject.complexAspect;
739
- }
740
- // if called without new
741
- if (!(this instanceof ComplexAspect)) {
742
- return new ComplexAspect(complexObject, parent, parentProperty);
743
- }
744
- // entityType should already be on the entity from 'watch'
745
- this.complexObject = complexObject;
746
- complexObject.complexAspect = this;
747
- // TODO: keep public or not?
748
- this.originalValues = {};
749
- // if a standalone complexObject
750
- if (parent != null) {
751
- this.parent = parent;
752
- this.parentProperty = parentProperty;
753
- }
754
- let complexType = complexObject.complexType;
755
- if (!complexType) {
756
- let typeName = complexObject.prototype._$typeName;
757
- if (!typeName) {
758
- throw new Error("This entity is not registered as a valid ComplexType");
759
- }
760
- else {
761
- throw new Error("Metadata for this complexType has not yet been resolved: " + typeName);
762
- }
763
- }
764
- let complexCtor = complexType.getCtor();
765
- config.interfaceRegistry.modelLibrary.getDefaultInstance().startTracking(complexObject, complexCtor.prototype);
766
- }
767
- /**
768
- Returns the EntityAspect for the top level entity that contains this complex object.
769
- **/
770
- getEntityAspect() {
771
- let parent = this.parent;
772
- if (!parent)
773
- return new EntityAspect();
774
- let entityAspect = parent.entityAspect;
775
- while (parent && !entityAspect) {
776
- parent = parent.complexAspect && parent.complexAspect.parent;
777
- entityAspect = parent && parent.entityAspect;
778
- }
779
- return entityAspect || new EntityAspect();
780
- }
781
- /** @hidden @internal */
782
- // TODO: rename - and use '_'; used on both EntityAspect and ComplexAspect for polymorphic reasons.
783
- getPropertyPath(propName) {
784
- let parent = this.parent;
785
- if (!parent)
786
- return null;
787
- let aspect = parent.complexAspect || parent.entityAspect;
788
- return aspect.getPropertyPath(this.parentProperty.name + "." + propName);
789
- }
790
- }
791
- function clearOriginalValues(target) {
792
- let aspect = target.entityAspect || target.complexAspect;
793
- aspect.originalValues = {};
794
- let stype = target.entityType || target.complexType;
795
- stype.complexProperties.forEach(function (cp) {
796
- let cos = target.getProperty(cp.name);
797
- if (cp.isScalar) {
798
- clearOriginalValues(cos);
799
- }
800
- else {
801
- cos._acceptChanges();
802
- cos.forEach(clearOriginalValues);
803
- }
804
- });
805
- }
806
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LWFzcGVjdC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2JyZWV6ZS1jbGllbnQvIiwic291cmNlcyI6WyJzcmMvZW50aXR5LWFzcGVjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQzlCLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDbEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLFdBQVcsRUFBRyxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsVUFBVSxFQUFpRSxNQUFNLG1CQUFtQixDQUFDO0FBQzlHLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFHekMsT0FBTyxFQUFFLFNBQVMsRUFBRSxlQUFlLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDeEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBeUM3Qzs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxPQUFPLFlBQVk7SUFzRnZCLHdCQUF3QjtJQUN4QixZQUFZLE1BQWU7UUFFekIsd0JBQXdCO1FBQ3hCLHlDQUF5QztRQUN6QyxxQ0FBcUM7UUFDckMsSUFBSTtRQXVLTjs7Ozs7O1dBTUc7UUFDSCxpQkFBWSxHQUFHO1lBQ2IsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNwRCxDQUFDLENBQUM7UUFHRjs7Ozs7O1dBTUc7UUFDSCxnQkFBVyxHQUFHO1lBQ1osT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNuRCxDQUFDLENBQUM7UUFFRjs7Ozs7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ZyB9IGZyb20gJy4vY29uZmlnJztcclxuaW1wb3J0IHsgQnJlZXplRXZlbnQgfSBmcm9tICcuL2V2ZW50JztcclxuaW1wb3J0IHsgYXNzZXJ0UGFyYW0gfSBmcm9tICcuL2Fzc2VydC1wYXJhbSc7XHJcbmltcG9ydCB7IEVudGl0eVN0YXRlICB9IGZyb20gJy4vZW50aXR5LXN0YXRlJztcclxuaW1wb3J0IHsgRW50aXR5QWN0aW9uIH0gZnJvbSAnLi9lbnRpdHktYWN0aW9uJztcclxuaW1wb3J0IHsgRW50aXR5VHlwZSwgQ29tcGxleFR5cGUsIERhdGFQcm9wZXJ0eSwgTmF2aWdhdGlvblByb3BlcnR5LCBFbnRpdHlQcm9wZXJ0eSB9IGZyb20gJy4vZW50aXR5LW1ldGFkYXRhJztcclxuaW1wb3J0IHsgRW50aXR5S2V5IH0gZnJvbSAnLi9lbnRpdHkta2V5JztcclxuaW1wb3J0IHsgRW50aXR5R3JvdXAgfSBmcm9tICcuL2VudGl0eS1ncm91cCc7XHJcbmltcG9ydCB7IEVudGl0eU1hbmFnZXIsIFF1ZXJ5UmVzdWx0LCBRdWVyeUVycm9yQ2FsbGJhY2ssIFF1ZXJ5U3VjY2Vzc0NhbGxiYWNrIH0gZnJvbSAnLi9lbnRpdHktbWFuYWdlcic7XHJcbmltcG9ydCB7IFZhbGlkYXRvciwgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSAnLi92YWxpZGF0ZSc7XHJcbmltcG9ydCB7IEVudGl0eVF1ZXJ5IH0gZnJvbSAnLi9lbnRpdHktcXVlcnknO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBFbnRpdHkge1xyXG4gIGVudGl0eUFzcGVjdDogRW50aXR5QXNwZWN0O1xyXG4gIGVudGl0eVR5cGU6IEVudGl0eVR5cGU7XHJcbiAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gIGdldFByb3BlcnR5Pyhwcm9wOiBzdHJpbmcpOiBhbnk7XHJcbiAgLyoqIEBpbnRlcm5hbCAqL1xyXG4gIHNldFByb3BlcnR5Pyhwcm9wOiBhbnksIHZhbHVlOiBhbnkpOiB2b2lkO1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIHByb3RvdHlwZT86IHsgXyR0eXBlTmFtZTogc3RyaW5nIH07XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgXyRlbnRpdHlUeXBlPzogRW50aXR5VHlwZTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBDb21wbGV4T2JqZWN0IHtcclxuICBjb21wbGV4QXNwZWN0OiBDb21wbGV4QXNwZWN0O1xyXG4gIGNvbXBsZXhUeXBlOiBDb21wbGV4VHlwZTtcclxuICBnZXRQcm9wZXJ0eT8ocHJvcDogc3RyaW5nKTogYW55O1xyXG4gIHNldFByb3BlcnR5Pyhwcm9wOiBhbnksIHZhbHVlOiBhbnkpOiB2b2lkO1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIHByb3RvdHlwZT86IHsgXyR0eXBlTmFtZTogc3RyaW5nIH07XHJcbn1cclxuXHJcbmV4cG9ydCB0eXBlIFN0cnVjdHVyYWxPYmplY3QgPSBFbnRpdHkgfCBDb21wbGV4T2JqZWN0O1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBQcm9wZXJ0eUNoYW5nZWRFdmVudEFyZ3Mge1xyXG4gIGVudGl0eTogRW50aXR5O1xyXG4gIHByb3BlcnR5TmFtZTogc3RyaW5nIHwgbnVsbDtcclxuICBwYXJlbnQ/OiBTdHJ1Y3R1cmFsT2JqZWN0O1xyXG4gIHByb3BlcnR5PzogRW50aXR5UHJvcGVydHk7XHJcbiAgb2xkVmFsdWU/OiBhbnk7XHJcbiAgbmV3VmFsdWU/OiBhbnk7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgVmFsaWRhdGlvbkVycm9yc0NoYW5nZWRFdmVudEFyZ3Mge1xyXG4gIGVudGl0eTogRW50aXR5O1xyXG4gIGFkZGVkOiBWYWxpZGF0aW9uRXJyb3JbXTtcclxuICByZW1vdmVkOiBWYWxpZGF0aW9uRXJyb3JbXTtcclxufVxyXG5cclxuLyoqXHJcbkFuIEVudGl0eUFzcGVjdCBpbnN0YW5jZSBpcyBhc3NvY2lhdGVkIHdpdGggZXZlcnkgYXR0YWNoZWQgZW50aXR5IGFuZCBpcyBhY2Nlc3NlZCB2aWEgdGhlIGVudGl0eSdzICdlbnRpdHlBc3BlY3QnIHByb3BlcnR5LlxyXG5cclxuVGhlIEVudGl0eUFzcGVjdCBpdHNlbGYgcHJvdmlkZXMgcHJvcGVydGllcyB0byBkZXRlcm1pbmUgYW5kIG1vZGlmeSB0aGUgRW50aXR5U3RhdGUgb2YgdGhlIGVudGl0eSBhbmQgaGFzIG1ldGhvZHNcclxudGhhdCBwcm92aWRlIGEgdmFyaWV0eSBvZiBzZXJ2aWNlcyBpbmNsdWRpbmcgdmFsaWRhdGlvbiBhbmQgY2hhbmdlIHRyYWNraW5nLlxyXG5cclxuQW4gRW50aXR5QXNwZWN0IHdpbGwgYWxtb3N0IG5ldmVyIG5lZWQgdG8gYmUgY29uc3RydWN0ZWQgZGlyZWN0bHkuIFlvdSB3aWxsIHVzdWFsbHkgZ2V0IGFuIEVudGl0eUFzcGVjdCBieSBhY2Nlc3NpbmdcclxuYW4gZW50aXRpZXMgJ2VudGl0eUFzcGVjdCcgcHJvcGVydHkuICBUaGlzIHByb3BlcnR5IHdpbGwgYmUgYXV0b21hdGljYWxseSBhdHRhY2hlZCB3aGVuIGFuIGVudGl0eSBpcyBjcmVhdGVkIHZpYSBlaXRoZXJcclxuYSBxdWVyeSwgaW1wb3J0IG9yIFtbRW50aXR5TWFuYWdlci5jcmVhdGVFbnRpdHldXSBjYWxsLlxyXG4+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4+ICAgICAgdmFyIGFzcGVjdCA9IG9yZGVyLmVudGl0eUFzcGVjdDtcclxuPiAgICAgIHZhciBjdXJyZW50U3RhdGUgPSBhc3BlY3QuZW50aXR5U3RhdGU7XHJcblxyXG4qKi9cclxuZXhwb3J0IGNsYXNzIEVudGl0eUFzcGVjdCB7XHJcbiAgLyoqIFRoZSBFbnRpdHkgdGhhdCB0aGlzIGFzcGVjdCBpcyBhc3NvY2lhdGVkIHdpdGguIF9fUmVhZCBPbmx5X18gICoqL1xyXG4gIGVudGl0eT86IEVudGl0eTtcclxuICAvKiogVGhlIFtbRW50aXR5TWFuYWdlcl1dIHRoYXQgY29udGFpbnMgdGhpcyBlbnRpdHkuIF9fUmVhZCBPbmx5X18gKiovXHJcbiAgZW50aXR5TWFuYWdlcj86IEVudGl0eU1hbmFnZXI7XHJcbiAgLyoqICBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIGVudGl0eUdyb3VwPzogRW50aXR5R3JvdXA7XHJcbiAgLyoqIFRoZSBbW0VudGl0eVN0YXRlXV0gb2YgdGhpcyBlbnRpdHkuIF9fUmVhZCBPbmx5X18gKiovXHJcbiAgZW50aXR5U3RhdGU6IEVudGl0eVN0YXRlO1xyXG4gIC8qKiAgIFdoZXRoZXIgdGhpcyBlbnRpdHkgaXMgaW4gdGhlIHByb2Nlc3Mgb2YgYmVpbmcgc2F2ZWQuIF9fUmVhZCBPbmx5X18gKi9cclxuICBpc0JlaW5nU2F2ZWQ6IGJvb2xlYW47XHJcbiAgLyoqIFRoZSAnb3JpZ2luYWwgdmFsdWVzJyBvZiB0aGlzIGVudGl0eSB3aGVyZSB0aGV5IGFyZSBkaWZmZXJlbnQgZnJvbSB0aGUgJ2N1cnJlbnQgdmFsdWVzJy5cclxuICBUaGlzIGlzIGEgbWFwIHdoZXJlIHRoZSBrZXkgaXMgYSBwcm9wZXJ0eSBuYW1lIGFuZCB0aGUgdmFsdWUgaXMgdGhlICdvcmlnaW5hbCB2YWx1ZScgb2YgdGhlIHByb3BlcnR5LiAqL1xyXG4gIG9yaWdpbmFsVmFsdWVzOiB7fTtcclxuICAvKiogIFdoZXRoZXIgdGhpcyBlbnRpdHkgaGFzIGFueSB2YWxpZGF0aW9uIGVycm9ycy4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGhhc1ZhbGlkYXRpb25FcnJvcnM6IGJvb2xlYW47XHJcbiAgLyoqIFdoZXRoZXIgdGhpcyBlbnRpdHkgaGFzIGEgdGVtcG9yYXJ5IFtbRW50aXR5S2V5XV0uICovXHJcbiAgaGFzVGVtcEtleTogYm9vbGVhbjtcclxuICAvKiogV2hldGhlciB0aGlzIGVudGl0eSB3YXMgY3JlYXRlZCBieSBiZWluZyBsb2FkZWQgZnJvbSB0aGUgZGF0YWJhc2UgKi9cclxuICB3YXNMb2FkZWQ/OiBib29sZWFuO1xyXG4gIC8qKiBFeHRyYSBtZXRhZGF0YSBhYm91dCB0aGlzIGVudGl0eSBzdWNoIGFzIHRoZSBlbnRpdHkncyBldGFnLlxyXG4gIFlvdSBtYXkgZXh0ZW5kIHRoaXMgb2JqZWN0IHdpdGggeW91ciBvd24gbWV0YWRhdGEgaW5mb3JtYXRpb24uXHJcbiAgQnJlZXplIChkZSlzZXJpYWxpemVzIHRoaXMgb2JqZWN0IHdoZW4gaW1wb3J0aW5nL2V4cG9ydGluZyB0aGUgZW50aXR5LiAqKi9cclxuICBleHRyYU1ldGFkYXRhPzogYW55O1xyXG4gIC8qKlxyXG4gIEEgW1tCcmVlemVFdmVudF1dIHRoYXQgZmlyZXMgd2hlbmV2ZXIgYW55IG9mIHRoZSB2YWxpZGF0aW9uIGVycm9ycyBvbiB0aGlzIGVudGl0eSBjaGFuZ2UuXHJcbiAgTm90ZSB0aGF0IHRoaXMgbWlnaHQgYmUgdGhlIHJlbW92YWwgb2YgYW4gZXJyb3Igd2hlbiBzb21lIGRhdGEgb24gdGhlIGVudGl0eSBpcyBmaXhlZC5cclxuICBAZXZlbnRBcmdzIC0gXHJcbiAgICAtIGVudGl0eSAtIFRoZSBlbnRpdHkgb24gd2hpY2ggdGhlIHZhbGlkYXRpb24gZXJyb3JzIGFyZSBiZWluZyBhZGRlZCBvciByZW1vdmVkLlxyXG4gICAgLSBhZGRlZCAtIEFuIGFycmF5IGNvbnRhaW5pbmcgYW55IG5ld2x5IGFkZGVkIFtbVmFsaWRhdGlvbkVycm9yXV1zXHJcbiAgICAtIHJlbW92ZWQgLSBBbiBhcnJheSBjb250YWluaW5nIGFueSBuZXdseSByZW1vdmVkIFtbVmFsaWRhdGlvbkVycm9yXV1zLiBUaGlzIGlzIHRob3NlXHJcbiAgICAgIGVycm9ycyB0aGF0IGhhdmUgYmVlbiAnZml4ZWQnLlxyXG5cclxuPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuPiAgICAgIG9yZGVyLmVudGl0eUFzcGVjdC52YWxpZGF0aW9uRXJyb3JzQ2hhbmdlZC5zdWJzY3JpYmUoXHJcbj4gICAgICBmdW5jdGlvbiAodmFsaWRhdGlvbkNoYW5nZUFyZ3MpIHtcclxuPiAgICAgICAgICAvLyB0aGlzIGNvZGUgd2lsbCBiZSBleGVjdXRlZCBhbnl0aW1lIGEgcHJvcGVydHkgdmFsdWUgY2hhbmdlcyBvbiB0aGUgJ29yZGVyJyBlbnRpdHkuXHJcbj4gICAgICAgICAgdmFyIGVudGl0eSA9PSB2YWxpZGF0aW9uQ2hhbmdlQXJncy5lbnRpdHk7IC8vIE5vdGU6IGVudGl0eSA9PT0gb3JkZXJcclxuPiAgICAgICAgICB2YXIgZXJyb3JzQWRkZWQgPSB2YWxpZGF0aW9uQ2hhbmdlQXJncy5hZGRlZDtcclxuPiAgICAgICAgICB2YXIgZXJyb3JzQ2xlYXJlZCA9IHZhbGlkYXRpb25DaGFuZ2VBcmdzLnJlbW92ZWQ7XHJcbj4gICAgICB9KTtcclxuICBAZXZlbnRcclxuICAqKi9cclxuICB2YWxpZGF0aW9uRXJyb3JzQ2hhbmdlZDogQnJlZXplRXZlbnQ8VmFsaWRhdGlvbkVycm9yc0NoYW5nZWRFdmVudEFyZ3M+O1xyXG4gIC8qKlxyXG4gIEEgW1tCcmVlemVFdmVudF1dIHRoYXQgZmlyZXMgd2hlbmV2ZXIgYSB2YWx1ZSBvZiBvbmUgb2YgdGhpcyBlbnRpdHkncyBwcm9wZXJ0aWVzIGNoYW5nZS5cclxuICBAZXZlbnRBcmdzIC1cclxuICAgIC0gZW50aXR5IC0gVGhlIGVudGl0eSB3aG9zZSBwcm9wZXJ0eSBoYXMgY2hhbmdlZC5cclxuICAgIC0gcHJvcGVydHkgLSBUaGUgW1tEYXRhUHJvcGVydHldXSB0aGF0IGNoYW5nZWQuXHJcbiAgICAtIHByb3BlcnR5TmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSB0aGF0IGNoYW5nZWQuIFRoaXMgdmFsdWUgd2lsbCBiZSAnbnVsbCcgZm9yIG9wZXJhdGlvbnMgdGhhdCByZXBsYWNlIHRoZSBlbnRpcmUgZW50aXR5LiAgVGhpcyBpbmNsdWRlc1xyXG4gICAgICBxdWVyaWVzLCBpbXBvcnRzIGFuZCBzYXZlcyB0aGF0IHJlcXVpcmUgYSBtZXJnZS4gVGhlIHJlbWFpbmluZyBwYXJhbWV0ZXJzIHdpbGwgbm90IGV4aXN0IGluIHRoaXMgY2FzZSBlaXRoZXIuIFRoaXMgd2lsbCBhY3R1YWxseSBiZSBhIFwicHJvcGVydHkgcGF0aFwiXHJcbiAgICAgIGZvciBhbnkgcHJvcGVydGllcyBvZiBhIGNvbXBsZXggdHlwZS5cclxuICAgIC0gb2xkVmFsdWUgLSBUaGUgb2xkIHZhbHVlIG9mIHRoaXMgcHJvcGVydHkgYmVmb3JlIHRoZSBjaGFuZ2UuXHJcbiAgICAtIG5ld1ZhbHVlIC0gVGhlIG5ldyB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5IGFmdGVyIHRoZSBjaGFuZ2UuXHJcbiAgICAtIHBhcmVudCAtIFRoZSBpbW1lZGlhdGUgcGFyZW50IG9iamVjdCBmb3IgdGhlIGNoYW5nZWQgcHJvcGVydHkuICBUaGlzIHdpbGwgYmUgYSBDb21wbGV4VHlwZSBpbnN0YW5jZSBhcyBvcHBvc2VkIHRvIGFuIEVudGl0eSBcclxuICAgICAgZm9yIGFueSBjb21wbGV4IHR5cGUgb3IgbmVzdGVkIGNvbXBsZXggdHlwZSBwcm9wZXJ0aWVzLlxyXG5cclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICBvcmRlci5lbnRpdHlBc3BlY3QucHJvcGVydHlDaGFuZ2VkLnN1YnNjcmliZShcclxuICA+ICAgICAgZnVuY3Rpb24gKHByb3BlcnR5Q2hhbmdlZEFyZ3MpIHtcclxuICA+ICAgICAgICAgIC8vIHRoaXMgY29kZSB3aWxsIGJlIGV4ZWN1dGVkIGFueXRpbWUgYSBwcm9wZXJ0eSB2YWx1ZSBjaGFuZ2VzIG9uIHRoZSAnb3JkZXInIGVudGl0eS5cclxuICA+ICAgICAgICAgIHZhciBlbnRpdHkgPSBwcm9wZXJ0eUNoYW5nZWRBcmdzLmVudGl0eTsgLy8gTm90ZTogZW50aXR5ID09PSBvcmRlclxyXG4gID4gICAgICAgICAgdmFyIHByb3BlcnR5TmFtZUNoYW5nZWQgPSBwcm9wZXJ0eUNoYW5nZWRBcmdzLnByb3BlcnR5TmFtZTtcclxuICA+ICAgICAgICAgIHZhciBvbGRWYWx1ZSA9IHByb3BlcnR5Q2hhbmdlZEFyZ3Mub2xkVmFsdWU7XHJcbiAgPiAgICAgICAgICB2YXIgbmV3VmFsdWUgPSBwcm9wZXJ0eUNoYW5nZWRBcmdzLm5ld1ZhbHVlO1xyXG4gID4gICAgICB9KTtcclxuICBAZXZlbnRcclxuICAqKi9cclxuICBwcm9wZXJ0eUNoYW5nZWQ6IEJyZWV6ZUV2ZW50PFByb3BlcnR5Q2hhbmdlZEV2ZW50QXJncz47XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF92YWxpZGF0aW9uRXJyb3JzOiB7IFtpbmRleDogc3RyaW5nXTogVmFsaWRhdGlvbkVycm9yIH07XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3BlbmRpbmdWYWxpZGF0aW9uUmVzdWx0OiBhbnk7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2VudGl0eUtleTogRW50aXR5S2V5O1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9sb2FkZWROcHM6IGFueVtdO1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9pbml0aWFsaXplZD86IGJvb2xlYW47XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2luUHJvY2VzczogYW55W107IC8vIHVzZWQgaW4gZGVmYXVsdFByb3BlcnR5SW50ZXJjZXB0b3IgZm9yIHRlbXAgc3RvcmFnZS5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfaW5Qcm9jZXNzRW50aXR5PzogRW50aXR5OyAvLyB1c2VkIGluIEVudGl0eU1hbmFnZXJcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBzdGF0aWMgX251bGxJbnN0YW5jZSA9IG5ldyBFbnRpdHlBc3BlY3QoKTsgLy8gVE9ETzogZGV0ZXJtaW5lIGlmIHRoaXMgd29ya3NcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBjb25zdHJ1Y3RvcihlbnRpdHk/OiBFbnRpdHkpIHtcclxuXHJcbiAgICAvLyBpZiBjYWxsZWQgd2l0aG91dCBuZXdcclxuICAgIC8vIGlmICghKHRoaXMgaW5zdGFuY2VvZiBFbnRpdHlBc3BlY3QpKSB7XHJcbiAgICAvLyAgIHJldHVybiBuZXcgRW50aXR5QXNwZWN0KGVudGl0eSk7XHJcbiAgICAvLyB9XHJcblxyXG4gICAgdGhpcy5lbnRpdHkgPSBlbnRpdHk7XHJcbiAgICAvLyBUT0RPOiBrZWVwIHB1YmxpYyBvciBub3Q/XHJcbiAgICB0aGlzLmVudGl0eUdyb3VwID0gdW5kZWZpbmVkO1xyXG4gICAgdGhpcy5lbnRpdHlNYW5hZ2VyID0gdW5kZWZpbmVkO1xyXG4gICAgdGhpcy5lbnRpdHlTdGF0ZSA9IEVudGl0eVN0YXRlLkRldGFjaGVkO1xyXG4gICAgdGhpcy5pc0JlaW5nU2F2ZWQgPSBmYWxzZTtcclxuICAgIHRoaXMub3JpZ2luYWxWYWx1ZXMgPSB7fTtcclxuICAgIHRoaXMuaGFzVmFsaWRhdGlvbkVycm9ycyA9IGZhbHNlO1xyXG4gICAgdGhpcy5fdmFsaWRhdGlvbkVycm9ycyA9IHt9O1xyXG5cclxuICAgIC8vIFVuY29tbWVudCB3aGVuIHdlIGltcGxlbWVudCBlbnRpdHlBc3BlY3QuaXNOYXZpZ2F0aW9uUHJvcGVydHlMb2FkZWQgbWV0aG9kXHJcbiAgICAvLyB0aGlzLl9sb2FkZWROYXZQcm9wTWFwID0ge307XHJcblxyXG4gICAgdGhpcy52YWxpZGF0aW9uRXJyb3JzQ2hhbmdlZCA9IG5ldyBCcmVlemVFdmVudChcInZhbGlkYXRpb25FcnJvcnNDaGFuZ2VkXCIsIHRoaXMpO1xyXG4gICAgdGhpcy5wcm9wZXJ0eUNoYW5nZWQgPSBuZXcgQnJlZXplRXZlbnQoXCJwcm9wZXJ0eUNoYW5nZWRcIiwgdGhpcyk7XHJcbiAgICAvLyBpbiBjYXNlIHRoaXMgaXMgdGhlIE5VTEwgZW50aXR5QXNwZWN0LiAtIHVzZWQgd2l0aCBDb21wbGV4QXNwZWN0cyB0aGF0IGhhdmUgbm8gcGFyZW50LlxyXG5cclxuICAgIGlmIChlbnRpdHkgIT0gbnVsbCkge1xyXG4gICAgICAvLyByZW1vdmUgcHJvcGVydGllcyB0aGF0IHNob3VsZCBiZSBvbiBwcm90b3R5cGUgYnV0IHBsYWNlZCBvbiBjbGFzcyBieSBCYWJlbFxyXG4gICAgICBpZiAoIWVudGl0eS5lbnRpdHlUeXBlKSB7IGRlbGV0ZShlbnRpdHkuZW50aXR5VHlwZSk7IH1cclxuICAgICAgaWYgKCFlbnRpdHkuZW50aXR5QXNwZWN0KSB7IGRlbGV0ZShlbnRpdHkuZW50aXR5QXNwZWN0KTsgfVxyXG4gICAgICBlbnRpdHkuZW50aXR5QXNwZWN0ID0gdGhpcztcclxuXHJcbiAgICAgIC8vIGVudGl0eVR5cGUgc2hvdWxkIGFscmVhZHkgYmUgb24gdGhlIGVudGl0eSBmcm9tICd3YXRjaCdcclxuICAgICAgbGV0IGVudGl0eVR5cGUgPSBlbnRpdHkuZW50aXR5VHlwZSB8fCBlbnRpdHkuXyRlbnRpdHlUeXBlO1xyXG4gICAgICBpZiAoIWVudGl0eVR5cGUpIHtcclxuICAgICAgICBsZXQgdHlwZU5hbWUgPSBlbnRpdHkucHJvdG90eXBlLl8kdHlwZU5hbWU7XHJcbiAgICAgICAgaWYgKCF0eXBlTmFtZSkge1xyXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbnRpdHkgaXMgbm90IHJlZ2lzdGVyZWQgYXMgYSB2YWxpZCBFbnRpdHlUeXBlXCIpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNZXRhZGF0YSBmb3IgdGhpcyBlbnRpdHlUeXBlIGhhcyBub3QgeWV0IGJlZW4gcmVzb2x2ZWQ6IFwiICsgdHlwZU5hbWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBsZXQgZW50aXR5Q3RvciA9IGVudGl0eVR5cGUuZ2V0RW50aXR5Q3RvcigpO1xyXG4gICAgICBjb25maWcuaW50ZXJmYWNlUmVnaXN0cnkubW9kZWxMaWJyYXJ5LmdldERlZmF1bHRJbnN0YW5jZSgpLnN0YXJ0VHJhY2tpbmcoZW50aXR5LCBlbnRpdHlDdG9yLnByb3RvdHlwZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiAqL1xyXG4gIC8vIHR5cGUtZ3VhcmRcclxuICBzdGF0aWMgaXNFbnRpdHkob2JqOiBTdHJ1Y3R1cmFsT2JqZWN0KTogb2JqIGlzIEVudGl0eSB7XHJcbiAgICByZXR1cm4gKG9iaiBhcyBhbnkpLmVudGl0eUFzcGVjdCAhPSBudWxsO1xyXG4gIH1cclxuXHJcbiAgLy8gTm8gbG9uZ2VyIHVzZWRcclxuICAvLyBzdGF0aWMgY3JlYXRlRnJvbShlbnRpdHk6IEVudGl0eSk6IEVudGl0eUFzcGVjdCB7XHJcbiAgLy8gICBpZiAoZW50aXR5ID09IG51bGwpIHtcclxuICAvLyAgICAgcmV0dXJuIEVudGl0eUFzcGVjdC5fbnVsbEluc3RhbmNlO1xyXG4gIC8vICAgfSBlbHNlIGlmIChlbnRpdHkuZW50aXR5QXNwZWN0KSB7XHJcbiAgLy8gICAgIHJldHVybiBlbnRpdHkuZW50aXR5QXNwZWN0O1xyXG4gIC8vICAgfVxyXG4gIC8vICAgcmV0dXJuIG5ldyBFbnRpdHlBc3BlY3QoZW50aXR5KTtcclxuICAvLyB9XHJcblxyXG4gIC8vIFRPRE86IHJlZmFjdG9yIHRoaXMgYW5kIHRoZSBpbnN0YW5jZSBnZXRQcm9wZXJ0eVZhbHVlIG1ldGhvZC5cclxuICAvKipcclxuICBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCAncHJvcGVydHkgcGF0aCcgZm9yIGEgc3BlY2lmaWVkIGVudGl0eS5cclxuXHJcbiAgVGhlIHByb3BlcnR5UGF0aCBjYW4gYmUgZWl0aGVyIGEgc3RyaW5nIGRlbGltaXRlZCB3aXRoICcuJyBvciBhIHN0cmluZyBhcnJheS4gIFxyXG4gICoqL1xyXG4gIC8vIHVzZWQgYnkgRW50aXR5UXVlcnkgYW5kIFByZWRpY2F0ZVxyXG4gIHN0YXRpYyBnZXRQcm9wZXJ0eVBhdGhWYWx1ZShvYmo6IEVudGl0eSwgcHJvcGVydHlQYXRoOiBzdHJpbmcgfCBzdHJpbmdbXSkge1xyXG4gICAgbGV0IHByb3BlcnRpZXMgPSBBcnJheS5pc0FycmF5KHByb3BlcnR5UGF0aCkgPyBwcm9wZXJ0eVBhdGggOiBwcm9wZXJ0eVBhdGguc3BsaXQoXCIuXCIpO1xyXG4gICAgaWYgKHByb3BlcnRpZXMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgIHJldHVybiBvYmouZ2V0UHJvcGVydHkocHJvcGVydHlQYXRoIGFzIHN0cmluZyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBsZXQgbmV4dFZhbHVlID0gb2JqO1xyXG4gICAgICAvLyBoYWNrIHVzZSBvZiBzb21lIHRvIHBlcmZvcm0gbWFwRmlyc3Qgb3BlcmF0aW9uLlxyXG4gICAgICBwcm9wZXJ0aWVzLnNvbWUoKHByb3ApID0+IHtcclxuICAgICAgICBuZXh0VmFsdWUgPSBuZXh0VmFsdWUuZ2V0UHJvcGVydHkocHJvcCk7XHJcbiAgICAgICAgcmV0dXJuIG5leHRWYWx1ZSA9PSBudWxsO1xyXG4gICAgICB9KTtcclxuICAgICAgcmV0dXJuIG5leHRWYWx1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgdGhlIFtbRW50aXR5S2V5XV0gZm9yIHRoaXMgRW50aXR5LlxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIHZhciBlbnRpdHlLZXkgPSBvcmRlci5lbnRpdHlBc3BlY3QuZ2V0S2V5KCk7XHJcbiAgQHBhcmFtIGZvcmNlUmVmcmVzaCAtIChib29sZWFuPWZhbHNlKSBGb3JjZXMgdGhlIHJlY2FsY3VsYXRpb24gb2YgdGhlIGtleS4gIFRoaXMgc2hvdWxkIG5vcm1hbGx5IGJlIHVubmVjZXNzYXJ5LlxyXG4gIEByZXR1cm4gVGhlIFtbRW50aXR5S2V5XV0gYXNzb2NpYXRlZCB3aXRoIHRoaXMgRW50aXR5LlxyXG4gICoqL1xyXG4gIGdldEtleShmb3JjZVJlZnJlc2g6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG4gICAgZm9yY2VSZWZyZXNoID0gYXNzZXJ0UGFyYW0oZm9yY2VSZWZyZXNoLCBcImZvcmNlUmVmcmVzaFwiKS5pc0Jvb2xlYW4oKS5pc09wdGlvbmFsKCkuY2hlY2soZmFsc2UpO1xyXG4gICAgaWYgKGZvcmNlUmVmcmVzaCB8fCAhdGhpcy5fZW50aXR5S2V5KSB7XHJcbiAgICAgIGxldCBlbnRpdHlUeXBlID0gdGhpcy5lbnRpdHkhLmVudGl0eVR5cGU7XHJcbiAgICAgIGxldCBrZXlQcm9wcyA9IGVudGl0eVR5cGUua2V5UHJvcGVydGllcztcclxuICAgICAgbGV0IHZhbHVlcyA9IGtleVByb3BzLm1hcChmdW5jdGlvbiAocCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmVudGl0eS5nZXRQcm9wZXJ0eShwLm5hbWUpO1xyXG4gICAgICB9LCB0aGlzKTtcclxuICAgICAgdGhpcy5fZW50aXR5S2V5ID0gbmV3IEVudGl0eUtleShlbnRpdHlUeXBlLCB2YWx1ZXMpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuX2VudGl0eUtleTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgdGhlIGVudGl0eSB0byBhbiBbW0VudGl0eVN0YXRlXV0gb2YgJ1VuY2hhbmdlZCcgYnkgY29tbWl0dGluZyBhbGwgY2hhbmdlcyBtYWRlIHNpbmNlIHRoZSBlbnRpdHkgd2FzIGxhc3QgcXVlcmllZFxyXG4gIGhhZCAnYWNjZXB0Q2hhbmdlcycgY2FsbGVkIG9uIGl0LlxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIG9yZGVyLmVudGl0eUFzcGVjdC5hY2NlcHRDaGFuZ2VzKCk7XHJcbiAgPiAgICAgIC8vIFRoZSAnb3JkZXInIGVudGl0eSB3aWxsIG5vdyBiZSBpbiBhbiAnVW5jaGFuZ2VkJyBzdGF0ZSB3aXRoIGFueSBjaGFuZ2VzIGNvbW1pdHRlZC5cclxuICAqKi9cclxuICBhY2NlcHRDaGFuZ2VzKCkge1xyXG4gICAgaWYgKCF0aGlzLmVudGl0eSkgcmV0dXJuO1xyXG4gICAgdGhpcy5fY2hlY2tPcGVyYXRpb24oXCJhY2NlcHRDaGFuZ2VzXCIpO1xyXG4gICAgbGV0IGVtID0gdGhpcy5lbnRpdHlNYW5hZ2VyITtcclxuICAgIGlmICh0aGlzLmVudGl0eVN0YXRlLmlzRGVsZXRlZCgpKSB7XHJcbiAgICAgIGVtLmRldGFjaEVudGl0eSh0aGlzLmVudGl0eSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnNldFVuY2hhbmdlZCgpO1xyXG4gICAgfVxyXG4gICAgZW0uZW50aXR5Q2hhbmdlZC5wdWJsaXNoKHsgZW50aXR5QWN0aW9uOiBFbnRpdHlBY3Rpb24uQWNjZXB0Q2hhbmdlcywgZW50aXR5OiB0aGlzLmVudGl0eSB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgdGhlIGVudGl0eSB0byBhbiBbW0VudGl0eVN0YXRlXV0gb2YgJ1VuY2hhbmdlZCcgYnkgcmVqZWN0aW5nIGFsbCBjaGFuZ2VzIG1hZGUgdG8gaXQgc2luY2UgdGhlIGVudGl0eSB3YXMgbGFzdCBxdWVyaWVkXHJcbiAgaGFkICdyZWplY3RDaGFuZ2VzJyBjYWxsZWQgb24gaXQuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgb3JkZXIuZW50aXR5QXNwZWN0LnJlamVjdENoYW5nZXMoKTtcclxuICA+ICAgICAgLy8gVGhlICdvcmRlcicgZW50aXR5IHdpbGwgbm93IGJlIGluIGFuICdVbmNoYW5nZWQnIHN0YXRlIHdpdGggYW55IGNoYW5nZXMgcmVqZWN0ZWQuXHJcbiAgKiovXHJcbiAgcmVqZWN0Q2hhbmdlcygpIHtcclxuICAgIHRoaXMuX2NoZWNrT3BlcmF0aW9uKFwicmVqZWN0Q2hhbmdlc1wiKTtcclxuICAgIGxldCBlbnRpdHkgPSB0aGlzLmVudGl0eSE7XHJcbiAgICBsZXQgZW50aXR5TWFuYWdlciA9IHRoaXMuZW50aXR5TWFuYWdlciE7XHJcbiAgICAvLyB3ZSBkbyBub3Qgd2FudCBQcm9wZXJ0eUNoYW5nZSBvciBFbnRpdHlDaGFuZ2UgZXZlbnRzIHRvIG9jY3VyIGhlcmVcclxuICAgIGNvcmUudXNpbmcoZW50aXR5TWFuYWdlciwgXCJpc1JlamVjdGluZ0NoYW5nZXNcIiwgdHJ1ZSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICByZWplY3RDaGFuZ2VzQ29yZShlbnRpdHkpO1xyXG4gICAgfSk7XHJcbiAgICBpZiAodGhpcy5lbnRpdHlTdGF0ZS5pc0FkZGVkKCkpIHtcclxuICAgICAgLy8gbmV4dCBsaW5lIGlzIG5lZWRlZCBiZWNhdXNlIHRoZSBmb2xsb3dpbmcgbGluZSB3aWxsIGNhdXNlIHRoaXMuZW50aXR5TWFuYWdlciAtPiBudWxsO1xyXG4gICAgICBlbnRpdHlNYW5hZ2VyLmRldGFjaEVudGl0eShlbnRpdHkpO1xyXG4gICAgICAvLyBuZWVkIHRvIHRlbGwgZW0gdGhhdCBhbiBlbnRpdHkgdGhhdCBuZWVkZWQgdG8gYmUgc2F2ZWQgbm8gbG9uZ2VyIGRvZXMuXHJcbiAgICAgIGVudGl0eU1hbmFnZXIuX25vdGlmeVN0YXRlQ2hhbmdlKGVudGl0eSwgZmFsc2UpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKHRoaXMuZW50aXR5U3RhdGUuaXNEZWxldGVkKCkpIHtcclxuICAgICAgICBlbnRpdHlNYW5hZ2VyLl9saW5rUmVsYXRlZEVudGl0aWVzKGVudGl0eSk7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5zZXRVbmNoYW5nZWQoKTtcclxuICAgICAgLy8gcHJvcGVydHlDaGFuZ2VkIHByb3BlcnR5TmFtZSBpcyBub3Qgc3BlY2lmaWVkIGJlY2F1c2UgbW9yZSB0aGFuIG9uZSBwcm9wZXJ0eSBtYXkgaGF2ZSBjaGFuZ2VkLlxyXG4gICAgICB0aGlzLnByb3BlcnR5Q2hhbmdlZC5wdWJsaXNoKHsgZW50aXR5OiBlbnRpdHksIHByb3BlcnR5TmFtZTogbnVsbCB9KTtcclxuICAgICAgZW50aXR5TWFuYWdlci5lbnRpdHlDaGFuZ2VkLnB1Ymxpc2goeyBlbnRpdHlBY3Rpb246IEVudGl0eUFjdGlvbi5SZWplY3RDaGFuZ2VzLCBlbnRpdHk6IGVudGl0eSB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiAgQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICAvLyBUT0RPOiByZW5hbWUgLSBhbmQgdXNlICdfJzsgdXNlZCBvbiBib3RoIEVudGl0eUFzcGVjdCBhbmQgQ29tcGxleEFzcGVjdCBmb3IgcG9seW1vcnBoaWMgcmVhc29ucy5cclxuICBnZXRQcm9wZXJ0eVBhdGgocHJvcE5hbWU6IHN0cmluZykge1xyXG4gICAgcmV0dXJuIHByb3BOYW1lO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgU2V0cyB0aGUgZW50aXR5IHRvIGFuIEVudGl0eVN0YXRlIG9mICdBZGRlZCcuICBUaGlzIGlzIE5PVCB0aGUgZXF1aXZhbGVudCBvZiBjYWxsaW5nIFtbRW50aXR5TWFuYWdlci5hZGRFbnRpdHldXVxyXG4gIGJlY2F1c2Ugbm8ga2V5IGdlbmVyYXRpb24gd2lsbCBvY2N1ciBmb3IgYXV0b2dlbmVyYXRlZCBrZXlzIGFzIGEgcmVzdWx0IG9mIHRoaXMgb3BlcmF0aW9uLiBBcyBhIHJlc3VsdCB0aGlzIG9wZXJhdGlvbiBjYW4gYmUgcHJvYmxlbWF0aWNcclxuICB1bmxlc3MgeW91IGFyZSBjZXJ0YWluIHRoYXQgdGhlIGVudGl0eSBiZWluZyBtYXJrZWQgJ0FkZGVkJyBkb2VzIG5vdCBhbHJlYWR5IGV4aXN0IGluIHRoZSBkYXRhYmFzZSBhbmQgZG9lcyBub3QgaGF2ZSBhbiBhdXRvZ2VuZXJhdGVkIGtleS5cclxuICBUaGUgc2FtZSBvcGVyYXRpb24gY2FuIGJlIHBlcmZvcm1lZCBieSBjYWxsaW5nIFtbRW50aXR5QXNwZWN0LnNldEVudGl0eVN0YXRlXV0uXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgb3JkZXIuZW50aXR5QXNwZWN0LnNldEFkZGVkKCk7XHJcbiAgPiAgICAgIC8vIFRoZSAnb3JkZXInIGVudGl0eSB3aWxsIG5vdyBiZSBpbiBhbiAnQWRkZWQnIHN0YXRlLlxyXG4gICoqL1xyXG4gIHNldEFkZGVkKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc2V0RW50aXR5U3RhdGUoRW50aXR5U3RhdGUuQWRkZWQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgU2V0cyB0aGUgZW50aXR5IHRvIGFuIEVudGl0eVN0YXRlIG9mICdVbmNoYW5nZWQnLiAgVGhpcyBpcyBhbHNvIHRoZSBlcXVpdmFsZW50IG9mIGNhbGxpbmcgW1tFbnRpdHlBc3BlY3QuYWNjZXB0Q2hhbmdlc11dLlxyXG4gIFRoZSBzYW1lIG9wZXJhdGlvbiBjYW4gYmUgcGVyZm9ybWVkIGJ5IGNhbGxpbmcgW1tFbnRpdHlBc3BlY3Quc2V0RW50aXR5U3RhdGVdXS5cclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICBvcmRlci5lbnRpdHlBc3BlY3Quc2V0VW5jaGFuZ2VkKCk7XHJcbiAgPiAgICAgIC8vIFRoZSAnb3JkZXInIGVudGl0eSB3aWxsIG5vdyBiZSBpbiBhbiAnVW5jaGFuZ2VkJyBzdGF0ZSB3aXRoIGFueSBjaGFuZ2VzIGNvbW1pdHRlZC5cclxuICAqKi9cclxuICBzZXRVbmNoYW5nZWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zZXRFbnRpdHlTdGF0ZShFbnRpdHlTdGF0ZS5VbmNoYW5nZWQpO1xyXG4gIH07XHJcblxyXG5cclxuICAvKipcclxuICBTZXRzIHRoZSBlbnRpdHkgdG8gYW4gRW50aXR5U3RhdGUgb2YgJ01vZGlmaWVkJy4gIFRoaXMgY2FuIGFsc28gYmUgYWNoaWV2ZWQgYnkgY2hhbmdpbmcgdGhlIHZhbHVlIG9mIGFueSBwcm9wZXJ0eSBvbiBhbiAnVW5jaGFuZ2VkJyBlbnRpdHkuXHJcbiAgVGhlIHNhbWUgb3BlcmF0aW9uIGNhbiBiZSBwZXJmb3JtZWQgYnkgY2FsbGluZyBbW0VudGl0eUFzcGVjdC5zZXRFbnRpdHlTdGF0ZV1dLlxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIG9yZGVyLmVudGl0eUFzcGVjdC5zZXRNb2RpZmllZCgpO1xyXG4gID4gICAgICAvLyBUaGUgJ29yZGVyJyBlbnRpdHkgd2lsbCBub3cgYmUgaW4gYSAnTW9kaWZpZWQnIHN0YXRlLlxyXG4gICoqL1xyXG4gIHNldE1vZGlmaWVkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc2V0RW50aXR5U3RhdGUoRW50aXR5U3RhdGUuTW9kaWZpZWQpO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gIFNldHMgdGhlIGVudGl0eSB0byBhbiBFbnRpdHlTdGF0ZSBvZiAnRGVsZXRlZCcuICBUaGlzIGJvdGggbWFya3MgdGhlIGVudGl0eSBhcyBiZWluZyBzY2hlZHVsZWQgZm9yIGRlbGV0aW9uIGR1cmluZyB0aGUgbmV4dCAnU2F2ZScgY2FsbFxyXG4gIGJ1dCBhbHNvIHJlbW92ZXMgdGhlIGVudGl0eSBmcm9tIGFsbCBvZiBpdHMgcmVsYXRlZCBlbnRpdGllcy5cclxuICBUaGUgc2FtZSBvcGVyYXRpb24gY2FuIGJlIHBlcmZvcm1lZCBieSBjYWxsaW5nIFtbRW50aXR5QXNwZWN0LnNldEVudGl0eVN0YXRlXV0uXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgb3JkZXIuZW50aXR5QXNwZWN0LnNldERlbGV0ZWQoKTtcclxuICA+ICAgICAgLy8gVGhlICdvcmRlcicgZW50aXR5IHdpbGwgbm93IGJlIGluIGEgJ0RlbGV0ZWQnIHN0YXRlIGFuZCBpdCB3aWxsIG5vIGxvbmdlciBoYXZlIGFueSAncmVsYXRlZCcgZW50aXRpZXMuXHJcbiAgKiovXHJcbiAgc2V0RGVsZXRlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHJldHVybiB0aGlzLnNldEVudGl0eVN0YXRlKEVudGl0eVN0YXRlLkRlbGV0ZWQpO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gIFNldHMgdGhlIGVudGl0eSB0byBhbiBFbnRpdHlTdGF0ZSBvZiAnRGV0YWNoZWQnLiAgVGhpcyByZW1vdmVzIHRoZSBlbnRpdHkgZnJvbSBhbGwgb2YgaXRzIHJlbGF0ZWQgZW50aXRpZXMsIGJ1dCBkb2VzIE5PVCBjaGFuZ2UgdGhlIEVudGl0eVN0YXRlIG9mIGFueSBleGlzdGluZyBlbnRpdGllcy5cclxuICBUaGUgc2FtZSBvcGVyYXRpb24gY2FuIGJlIHBlcmZvcm1lZCBieSBjYWxsaW5nIFtbRW50aXR5QXNwZWN0LnNldEVudGl0eVN0YXRlXV0uXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgb3JkZXIuZW50aXR5QXNwZWN0LnNldERldGFjaGVkKCk7XHJcbiAgPiAgICAgIC8vIFRoZSAnb3JkZXInIGVudGl0eSB3aWxsIG5vdyBiZSBpbiBhICdEZXRhY2hlZCcgc3RhdGUgYW5kIGl0IHdpbGwgbm8gbG9uZ2VyIGhhdmUgYW55ICdyZWxhdGVkJyBlbnRpdGllcy5cclxuICAqKi9cclxuICBzZXREZXRhY2hlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHJldHVybiB0aGlzLnNldEVudGl0eVN0YXRlKEVudGl0eVN0YXRlLkRldGFjaGVkKTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICBTZXRzIHRoZSBlbnRpdHkgdG8gdGhlIHNwZWNpZmllZCBFbnRpdHlTdGF0ZS4gU2VlIGFsc28gJ3NldFVuY2hhbmdlZCcsICdzZXRNb2RpZmllZCcsICdzZXREZXRhY2hlZCcsIGV0Yy5cclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICBvcmRlci5lbnRpdHlBc3BlY3Quc2V0RW50aXR5U3RhdGUoRW50aXR5U3RhdGUuVW5jaGFuZ2VkKTtcclxuICA+ICAgICAgLy8gVGhlICdvcmRlcicgZW50aXR5IHdpbGwgbm93IGJlIGluIGEgJ1VuY2hhbmdlZCcgc3RhdGUuXHJcbiAgKiovXHJcbiAgc2V0RW50aXR5U3RhdGUoZW50aXR5U3RhdGU6IEVudGl0eVN0YXRlKSB7XHJcbiAgICBpZiAodGhpcy5lbnRpdHlTdGF0ZSA9PT0gZW50aXR5U3RhdGUpIHJldHVybiBmYWxzZTtcclxuICAgIHRoaXMuX2NoZWNrT3BlcmF0aW9uKFwic2V0RW50aXR5U3RhdGVcIik7XHJcbiAgICBpZiAodGhpcy5lbnRpdHlTdGF0ZS5pc0RldGFjaGVkKCkpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiWW91IGNhbm5vdCBzZXQgdGhlICdlbnRpdHlTdGF0ZScgb2YgYW4gZW50aXR5IHdoZW4gaXQgaXMgZGV0YWNoZWQgLSBleGNlcHQgYnkgZmlyc3QgYXR0YWNoaW5nIGl0IHRvIGFuIEVudGl0eU1hbmFnZXJcIik7XHJcbiAgICB9XHJcbiAgICBsZXQgZW50aXR5ID0gdGhpcy5lbnRpdHkhO1xyXG4gICAgbGV0IGVtID0gdGhpcy5lbnRpdHlNYW5hZ2VyITtcclxuICAgIGxldCBuZWVkc1NhdmUgPSB0cnVlO1xyXG4gICAgaWYgKGVudGl0eVN0YXRlID09PSBFbnRpdHlTdGF0ZS5VbmNoYW5nZWQpIHtcclxuICAgICAgY2xlYXJPcmlnaW5hbFZhbHVlcyhlbnRpdHkpO1xyXG4gICAgICBkZWxldGUgdGhpcy5oYXNUZW1wS2V5O1xyXG4gICAgICBuZWVkc1NhdmUgPSBmYWxzZTtcclxuICAgIH0gZWxzZSBpZiAoZW50aXR5U3RhdGUgPT09IEVudGl0eVN0YXRlLkFkZGVkKSB7XHJcbiAgICAgIGNsZWFyT3JpZ2luYWxWYWx1ZXMoZW50aXR5KTtcclxuICAgICAgLy8gVE9ETzogbW9yZSB0byBkbyBoZXJlLi4uIGxpa2UgcmVnZW5lcmF0aW5nIGtleSA/Pz9cclxuICAgIH0gZWxzZSBpZiAoZW50aXR5U3RhdGUgPT09IEVudGl0eVN0YXRlLkRlbGV0ZWQpIHtcclxuICAgICAgaWYgKHRoaXMuZW50aXR5U3RhdGUuaXNBZGRlZCgpKSB7XHJcbiAgICAgICAgLy8gdHVybiBpdCBpbnRvIGEgZGV0YWNoIGFuZCBleGl0IGVhcmx5XHJcbiAgICAgICAgdGhpcy5zZXRFbnRpdHlTdGF0ZShFbnRpdHlTdGF0ZS5EZXRhY2hlZCk7XHJcbiAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gVE9ETzogdGhpbmsgYWJvdXQgY2FzY2FkZSBkZWxldGVzXHJcbiAgICAgICAgLy8gZW50aXR5U3RhdGUgbmVlZHMgdG8gYmUgc2V0IGl0IGVhcmx5IGluIHRoaXMgb25lIGNhc2UgdG8gaW5zdXJlIHRoYXQgZmsncyBhcmUgbm90IGNsZWFyZWQuXHJcbiAgICAgICAgdGhpcy5lbnRpdHlTdGF0ZSA9IEVudGl0eVN0YXRlLkRlbGV0ZWQ7XHJcbiAgICAgICAgcmVtb3ZlRnJvbVJlbGF0aW9ucyhlbnRpdHksIEVudGl0eVN0YXRlLkRlbGV0ZWQpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2UgaWYgKGVudGl0eVN0YXRlID09PSBFbnRpdHlTdGF0ZS5Nb2RpZmllZCkge1xyXG4gICAgICAvLyBub3RoaW5nIGV4dHJhIG5lZWRlZFxyXG4gICAgfSBlbHNlIGlmIChlbnRpdHlTdGF0ZSA9PT0gRW50aXR5U3RhdGUuRGV0YWNoZWQpIHtcclxuICAgICAgbGV0IGdyb3VwID0gdGhpcy5lbnRpdHlHcm91cDtcclxuICAgICAgLy8gbm8gZ3JvdXAgPT09IGFscmVhZHkgZGV0YWNoZWQuXHJcbiAgICAgIGlmICghZ3JvdXApIHJldHVybiBmYWxzZTtcclxuICAgICAgZ3JvdXAuZGV0YWNoRW50aXR5KGVudGl0eSk7XHJcbiAgICAgIC8vIG5lZWRzIHRvIG9jY3VyIGVhcmx5IGhlcmUgLSBzbyB0aGlzIElTIGRlbGliZXJhdGVseSByZWR1bmRlbnQgd2l0aCB0aGUgc2FtZSBjb2RlIGxhdGVyIGluIHRoaXMgbWV0aG9kLlxyXG4gICAgICB0aGlzLmVudGl0eVN0YXRlID0gZW50aXR5U3RhdGU7XHJcbiAgICAgIHJlbW92ZUZyb21SZWxhdGlvbnMoZW50aXR5LCBFbnRpdHlTdGF0ZS5EZXRhY2hlZCk7XHJcbiAgICAgIHRoaXMuX2RldGFjaCgpO1xyXG4gICAgICBlbS5lbnRpdHlDaGFuZ2VkLnB1Ymxpc2goeyBlbnRpdHlBY3Rpb246IEVudGl0eUFjdGlvbi5EZXRhY2gsIGVudGl0eTogZW50aXR5IH0pO1xyXG4gICAgICBuZWVkc1NhdmUgPSBmYWxzZTtcclxuICAgIH1cclxuICAgIHRoaXMuZW50aXR5U3RhdGUgPSBlbnRpdHlTdGF0ZTtcclxuICAgIGVtLl9ub3RpZnlTdGF0ZUNoYW5nZShlbnRpdHksIG5lZWRzU2F2ZSk7XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcblxyXG4gIGxvYWROYXZpZ2F0aW9uUHJvcGVydHkobmF2aWdhdGlvblByb3BlcnR5OiBzdHJpbmcsIGNhbGxiYWNrPzogUXVlcnlTdWNjZXNzQ2FsbGJhY2ssIGVycm9yQ2FsbGJhY2s/OiBRdWVyeUVycm9yQ2FsbGJhY2spOiBQcm9taXNlPFF1ZXJ5UmVzdWx0PjtcclxuICBsb2FkTmF2aWdhdGlvblByb3BlcnR5KG5hdmlnYXRpb25Qcm9wZXJ0eTogTmF2aWdhdGlvblByb3BlcnR5LCBjYWxsYmFjaz86IFF1ZXJ5U3VjY2Vzc0NhbGxiYWNrLCBlcnJvckNhbGxiYWNrPzogUXVlcnlFcnJvckNhbGxiYWNrKTogUHJvbWlzZTxRdWVyeVJlc3VsdD47XHJcbiAgLyoqXHJcbiAgUGVyZm9ybXMgYSBxdWVyeSBmb3IgdGhlIHZhbHVlIG9mIGEgc3BlY2lmaWVkIFtbTmF2aWdhdGlvblByb3BlcnR5XV0uIF9fQXN5bmNfX1xyXG4gID4gICAgICBlbXAuZW50aXR5QXNwZWN0LmxvYWROYXZpZ2F0aW9uUHJvcGVydHkoXCJPcmRlcnNcIikudGhlbihmdW5jdGlvbiAoZGF0YSkge1xyXG4gID4gICAgICAgICAgdmFyIG9yZGVycyA9IGRhdGEucmVzdWx0cztcclxuICA+ICAgICAgfSkuY2F0Y2goZnVuY3Rpb24gKGV4Y2VwdGlvbikge1xyXG4gID4gICAgICAgICAgLy8gaGFuZGxlIGV4Y2VwdGlvbiBoZXJlO1xyXG4gID4gICAgICB9KTtcclxuICBAcGFyYW0gbmF2aWdhdGlvblByb3BlcnR5IC0gVGhlIE5hdmlnYXRpb25Qcm9wZXJ0eSBvciB0aGUgbmFtZSBvZiB0aGUgTmF2aWdhdGlvblByb3BlcnR5IHRvICdsb2FkJy5cclxuICBAcGFyYW0gY2FsbGJhY2sgLSBGdW5jdGlvbiB0byBjYWxsIG9uIHN1Y2Nlc3MuXHJcbiAgQHBhcmFtIGVycm9yQ2FsbGJhY2sgLSBGdW5jdGlvbiB0byBjYWxsIG9uIGZhaWx1cmUuXHJcbiAgQHJldHVybiBQcm9taXNlIHdpdGggc2hhcGVcclxuICAgIC0gcmVzdWx0cyB7QXJyYXkgb2YgRW50aXR5fVxyXG4gICAgLSBxdWVyeSB7RW50aXR5UXVlcnl9IFRoZSBvcmlnaW5hbCBxdWVyeVxyXG4gICAgLSBodHRwUmVzcG9uc2Uge2h0dHBSZXNwb25zZX0gVGhlIEh0dHBSZXNwb25zZSByZXR1cm5lZCBmcm9tIHRoZSBzZXJ2ZXIuXHJcbiAgKiovXHJcbiAgbG9hZE5hdmlnYXRpb25Qcm9wZXJ0eShuYXZpZ2F0aW9uUHJvcGVydHk6IE5hdmlnYXRpb25Qcm9wZXJ0eSB8IHN0cmluZywgY2FsbGJhY2s6IFF1ZXJ5U3VjY2Vzc0NhbGxiYWNrLCBlcnJvckNhbGxiYWNrOiBRdWVyeUVycm9yQ2FsbGJhY2spIHtcclxuICAgIGxldCBlbnRpdHkgPSB0aGlzLmVudGl0eSE7XHJcbiAgICBsZXQgbmF2UHJvcGVydHkgPSBlbnRpdHkuZW50aXR5VHlwZS5fY2hlY2tOYXZQcm9wZXJ0eShuYXZpZ2F0aW9uUHJvcGVydHkpO1xyXG4gICAgbGV0IHF1ZXJ5ID0gRW50aXR5UXVlcnkuZnJvbUVudGl0eU5hdmlnYXRpb24oZW50aXR5LCBuYXZQcm9wZXJ0eSk7XHJcbiAgICAvLyByZXR1cm4gZW50aXR5LmVudGl0eUFzcGVjdC5lbnRpdHlNYW5hZ2VyLmV4ZWN1dGVRdWVyeShxdWVyeSwgY2FsbGJhY2ssIGVycm9yQ2FsbGJhY2spO1xyXG4gICAgbGV0IHByb21pc2UgPSBlbnRpdHkuZW50aXR5QXNwZWN0LmVudGl0eU1hbmFnZXIhLmV4ZWN1dGVRdWVyeShxdWVyeSk7XHJcblxyXG4gICAgcmV0dXJuIHByb21pc2UudGhlbigoZGF0YSkgPT4ge1xyXG4gICAgICB0aGlzLl9tYXJrQXNMb2FkZWQobmF2UHJvcGVydHkubmFtZSk7XHJcbiAgICAgIGlmIChjYWxsYmFjaykgY2FsbGJhY2soZGF0YSk7XHJcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZGF0YSk7XHJcbiAgICB9LCAoZXJyb3IpID0+IHtcclxuICAgICAgaWYgKGVycm9yQ2FsbGJhY2spIGVycm9yQ2FsbGJhY2soZXJyb3IpO1xyXG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QoZXJyb3IpO1xyXG4gICAgfSk7XHJcblxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgTWFya3MgdGhpcyBuYXZpZ2F0aW9uUHJvcGVydHkgb24gdGhpcyBlbnRpdHkgYXMgYWxyZWFkeSBoYXZpbmcgYmVlbiBsb2FkZWQuXHJcbiAgPiAgICAgIGVtcC5lbnRpdHlBc3BlY3QubWFya05hdmlnYXRpb25Qcm9wZXJ0eUFzTG9hZGVkKFwiT3JkZXJzXCIpO1xyXG4gIEBwYXJhbSBuYXZpZ2F0aW9uUHJvcGVydHkgLSBUaGUgTmF2aWdhdGlvblByb3BlcnR5IG9yIG5hbWUgb2YgTmF2aWdhdGlvblByb3BlcnR5IHRvICdsb2FkJy5cclxuICAqKi9cclxuICBtYXJrTmF2aWdhdGlvblByb3BlcnR5QXNMb2FkZWQobmF2aWdhdGlvblByb3BlcnR5OiBOYXZpZ2F0aW9uUHJvcGVydHkgfCBzdHJpbmcpIHtcclxuICAgIGlmICghdGhpcy5lbnRpdHkpIHJldHVybjtcclxuICAgIGxldCBuYXZQcm9wZXJ0eSA9IHRoaXMuZW50aXR5LmVudGl0eVR5cGUuX2NoZWNrTmF2UHJvcGVydHkobmF2aWdhdGlvblByb3BlcnR5KTtcclxuICAgIHRoaXMuX21hcmtBc0xvYWRlZChuYXZQcm9wZXJ0eS5uYW1lKTtcclxuICB9XHJcblxyXG4gIGlzTmF2aWdhdGlvblByb3BlcnR5TG9hZGVkKG5hdmlnYXRpb25Qcm9wZXJ0eTogc3RyaW5nKTogYm9vbGVhbjtcclxuICBpc05hdmlnYXRpb25Qcm9wZXJ0eUxvYWRlZChuYXZpZ2F0aW9uUHJvcGVydHk6IE5hdmlnYXRpb25Qcm9wZXJ0eSk6IGJvb2xlYW47XHJcbiAgLyoqXHJcbiAgRGV0ZXJtaW5lcyB3aGV0aGVyIGEgbmF2aWdhdGlvblByb3BlcnR5IG9uIHRoaXMgZW50aXR5IGhhcyBhbHJlYWR5IGJlZW4gbG9hZGVkLlxyXG5cclxuICBBIG5hdmlnYXRpb24gcHJvcGVydHkgaXMgY29uc2lkZXJlZCBsb2FkZWQgd2hlbiBhbnkgb2YgdGhlIGZvbGxvd2luZyB0aHJlZSBjb25kaXRpb25zIGFwcGxpZXM6XHJcblxyXG4gICAgMS4gSXQgd2FzIGZldGNoZWQgZnJvbSB0aGUgYmFja2VuZCBzZXJ2ZXIuXHJcbiAgICAgICAgPGJyLz4gICBUaGlzIGNhbiBiZSB0aGUgcmVzdWx0IG9mIGFuIGV4cGFuZCBxdWVyeSBvciBhIGNhbGwgdG8gdGhlIFtbRW50aXR5QXNwZWN0LmxvYWROYXZpZ2F0aW9uUHJvcGVydHldXSBtZXRob2QuXHJcbiAgICAgICAgPGJyLz4gICBOb3RlIHRoYXQgZXZlbiBpZiB0aGUgZmV0Y2ggcmV0dXJucyBub3RoaW5nIHRoZSBwcm9wZXJ0eSBpcyBzdGlsbCBtYXJrZWQgYXMgbG9hZGVkIGluIHRoaXMgY2FzZS5cclxuICAgIDEuIFRoZSBwcm9wZXJ0eSBpcyBzY2FsYXIgYW5kIGhhcyBiZWVuIHNldCB0byBhIG5vbm51bGwgdmFsdWUuXHJcbiAgICAxLiBUaGUgW1tFbnRpdHlBc3BlY3QubWFya05hdmlnYXRpb25Qcm9wZXJ0eUFzTG9hZGVkXV0gd2FzIGNhbGxlZC5cclxuICBcclxuICA+ICAgICB2YXIgd2FzTG9hZGVkID0gZW1wLmVudGl0eUFzcGVjdC5pc05hdmlnYXRpb25Qcm9wZXJ0eUxvYWRlZChcIk9yZGVyc1wiKTtcclxuICBAcGFyYW0gbmF2aWdhdGlvblByb3BlcnR5IC0gVGhlIE5hdmlnYXRpb25Qcm9wZXJ0eSBvciBuYW1lIG9mIE5hdmlnYXRpb25Qcm9wZXJ0eSB0byAnbG9hZCcuXHJcbiAgKiovXHJcbiAgaXNOYXZpZ2F0aW9uUHJvcGVydHlMb2FkZWQobmF2aWdhdGlvblByb3BlcnR5OiBOYXZpZ2F0aW9uUHJvcGVydHkgfCBzdHJpbmcpIHtcclxuICAgIGlmICghdGhpcy5lbnRpdHkpIHJldHVybjtcclxuICAgIGxldCBuYXZQcm9wZXJ0eSA9IHRoaXMuZW50aXR5LmVudGl0eVR5cGUuX2NoZWNrTmF2UHJvcGVydHkobmF2aWdhdGlvblByb3BlcnR5KTtcclxuICAgIGlmIChuYXZQcm9wZXJ0eS5pc1NjYWxhciAmJiB0aGlzLmVudGl0eS5nZXRQcm9wZXJ0eShuYXZQcm9wZXJ0eS5uYW1lKSAhPSBudWxsKSB7XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMuX2xvYWRlZE5wcyAmJiB0aGlzLl9sb2FkZWROcHMuaW5kZXhPZihuYXZQcm9wZXJ0eS5uYW1lKSA+PSAwO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX21hcmtBc0xvYWRlZChuYXZQcm9wTmFtZTogc3RyaW5nKSB7XHJcbiAgICB0aGlzLl9sb2FkZWROcHMgPSB0aGlzLl9sb2FkZWROcHMgfHwgW107XHJcbiAgICBjb3JlLmFycmF5QWRkSXRlbVVuaXF1ZSh0aGlzLl9sb2FkZWROcHMsIG5hdlByb3BOYW1lKTtcclxuICB9XHJcblxyXG5cclxuICAvKipcclxuICBQZXJmb3JtcyB2YWxpZGF0aW9uIG9uIHRoZSBlbnRpdHksIGFueSBlcnJvcnMgZW5jb3VudGVyZWQgZHVyaW5nIHRoZSB2YWxpZGF0aW9uIGFyZSBhdmFpbGFibGUgdmlhIHRoZVxyXG4gIFtbRW50aXR5QXNwZWN0LmdldFZhbGlkYXRpb25FcnJvcnNdXSBtZXRob2QuIFZhbGlkYXRpbmcgYW4gZW50aXR5IG1lYW5zIGV4ZWN1dGluZ1xyXG4gIGFsbCBvZiB0aGUgdmFsaWRhdG9ycyBvbiBib3RoIHRoZSBlbnRpdHkgaXRzZWxmIGFzIHdlbGwgYXMgdGhvc2Ugb24gZWFjaCBvZiBpdHMgcHJvcGVydGllcy5cclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICB2YXIgaXNPayA9IG9yZGVyLmVudGl0eUFzcGVjdC52YWxpZGF0ZUVudGl0eSgpO1xyXG4gID4gICAgICAvLyBpc09rIHdpbGwgYmUgJ3RydWUnIGlmIHRoZXJlIGFyZSBubyBlcnJvcnMgb24gdGhlIGVudGl0eS5cclxuICA+ICAgICAgaWYgKCFpc09rKSB7XHJcbiAgPiAgICAgICAgICB2YXIgZXJyb3JzID0gb3JkZXIuZW50aXR5QXNwZWN0LmdldFZhbGlkYXRpb25FcnJvcnMoKTtcclxuICA+ICAgICAgfVxyXG4gIEByZXR1cm4gV2hldGhlciB0aGUgZW50aXR5IHBhc3NlZCB2YWxpZGF0aW9uLlxyXG4gICoqL1xyXG4gIHZhbGlkYXRlRW50aXR5KCkge1xyXG4gICAgbGV0IG9rID0gdHJ1ZTtcclxuICAgIHRoaXMuX3Byb2Nlc3NWYWxpZGF0aW9uT3BBbmRQdWJsaXNoKGZ1bmN0aW9uICh0aGF0OiBhbnkpIHtcclxuICAgICAgb2sgPSB2YWxpZGF0ZVRhcmdldCh0aGF0LmVudGl0eSk7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBvaztcclxuICB9XHJcblxyXG4gIHZhbGlkYXRlUHJvcGVydHkocHJvcGVydHk6IHN0cmluZywgY29udGV4dD86IGFueSk6IGJvb2xlYW47XHJcbiAgdmFsaWRhdGVQcm9wZXJ0eShwcm9wZXJ0eTogRGF0YVByb3BlcnR5LCBjb250ZXh0PzogYW55KTogYm9vbGVhbjtcclxuICB2YWxpZGF0ZVByb3BlcnR5KHByb3BlcnR5OiBOYXZpZ2F0aW9uUHJvcGVydHksIGNvbnRleHQ/OiBhbnkpOiBib29sZWFuO1xyXG4gIC8qKlxyXG4gIFBlcmZvcm1zIHZhbGlkYXRpb24gb24gYSBzcGVjaWZpYyBwcm9wZXJ0eSBvZiB0aGlzIGVudGl0eSwgYW55IGVycm9ycyBlbmNvdW50ZXJlZCBkdXJpbmcgdGhlIHZhbGlkYXRpb24gYXJlIGF2YWlsYWJsZSB2aWEgdGhlXHJcbiAgW1tFbnRpdHlBc3BlY3QuZ2V0VmFsaWRhdGlvbkVycm9yc11dIG1ldGhvZC4gVmFsaWRhdGluZyBhIHByb3BlcnR5IG1lYW5zIGV4ZWN1dGluZ1xyXG4gIGFsbCBvZiB0aGUgdmFsaWRhdG9ycyBvbiB0aGUgc3BlY2lmaWVkIHByb3BlcnR5LiAgVGhpcyBjYWxsIGlzIGFsc28gbWFkZSBhdXRvbWF0aWNhbGx5IGFueXRpbWUgYSBwcm9wZXJ0eVxyXG4gIG9mIGFuIGVudGl0eSBpcyBjaGFuZ2VkLlxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIHZhciBpc09rID0gb3JkZXIuZW50aXR5QXNwZWN0LnZhbGlkYXRlUHJvcGVydHkoXCJPcmRlclwiKTtcclxuXHJcbiAgb3JcclxuICA+ICAgICAgdmFyIG9yZGVyRGF0ZVByb3BlcnR5ID0gb3JkZXIuZW50aXR5VHlwZS5nZXRQcm9wZXJ0eShcIk9yZGVyRGF0ZVwiKTtcclxuICA+ICAgICAgdmFyIGlzT2sgPSBvcmRlci5lbnRpdHlBc3BlY3QudmFsaWRhdGVQcm9wZXJ0eShPcmRlckRhdGVQcm9wZXJ0eSk7XHJcbiAgQHBhcmFtIHByb3BlcnR5IC0gVGhlIFtbRGF0YVByb3BlcnR5XV0gb3IgW1tOYXZpZ2F0aW9uUHJvcGVydHldXSB0byB2YWxpZGF0ZSBvciBhIHN0cmluZyBcclxuICB3aXRoIHRoZSBuYW1lIG9mIHRoZSBwcm9wZXJ0eSBvciBhIHByb3BlcnR5IHBhdGggd2l0aCB0aGUgcGF0aCB0byBhIHByb3BlcnR5IG9mIGEgY29tcGxleCBvYmplY3QuXHJcbiAgQHBhcmFtIGNvbnRleHQgLSAgQSBjb250ZXh0IG9iamVjdCB1c2VkIHRvIHBhc3MgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiB0byBlYWNoIFtbVmFsaWRhdG9yXV0uXHJcbiAgQHJldHVybiBXaGV0aGVyIHRoZSBlbnRpdHkgcGFzc2VkIHZhbGlkYXRpb24uXHJcbiAgKiovXHJcbiAgdmFsaWRhdGVQcm9wZXJ0eShwcm9wZXJ0eTogRW50aXR5UHJvcGVydHkgfCBzdHJpbmcsIGNvbnRleHQ6IGFueSkge1xyXG4gICAgbGV0IHZhbHVlID0gdGhpcy5nZXRQcm9wZXJ0eVZhbHVlKHByb3BlcnR5KTsgLy8gcGVyZm9ybXMgdmFsaWRhdGlvbnNcclxuICAgIGlmICh2YWx1ZSAmJiB2YWx1ZS5jb21wbGV4QXNwZWN0KSB7XHJcbiAgICAgIHJldHVybiB2YWxpZGF0ZVRhcmdldCh2YWx1ZSk7XHJcbiAgICB9XHJcbiAgICBjb250ZXh0ID0gY29udGV4dCB8fCB7fTtcclxuICAgIGNvbnRleHQuZW50aXR5ID0gdGhpcy5lbnRpdHk7XHJcbiAgICBpZiAodHlwZW9mIHByb3BlcnR5ID09PSBcInN0cmluZ1wiKSB7XHJcbiAgICAgIGNvbnRleHQucHJvcGVydHkgPSB0aGlzLmVudGl0eSEuZW50aXR5VHlwZS5nZXRQcm9wZXJ0eShwcm9wZXJ0eSwgdHJ1ZSk7XHJcbiAgICAgIGNvbnRleHQucHJvcGVydHlOYW1lID0gcHJvcGVydHk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb250ZXh0LnByb3BlcnR5ID0gcHJvcGVydHk7XHJcbiAgICAgIGNvbnRleHQucHJvcGVydHlOYW1lID0gcHJvcGVydHkubmFtZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5fdmFsaWRhdGVQcm9wZXJ0eSh2YWx1ZSwgY29udGV4dCk7XHJcbiAgfVxyXG5cclxuICBnZXRWYWxpZGF0aW9uRXJyb3JzKCk6IFZhbGlkYXRpb25FcnJvcltdO1xyXG4gIGdldFZhbGlkYXRpb25FcnJvcnMocHJvcGVydHk6IHN0cmluZyk6IFZhbGlkYXRpb25FcnJvcltdO1xyXG4gIGdldFZhbGlkYXRpb25FcnJvcnMocHJvcGVydHk6IEVudGl0eVByb3BlcnR5KTogVmFsaWRhdGlvbkVycm9yW107XHJcbiAgLyoqXHJcbiAgUmV0dXJucyB0aGUgdmFsaWRhdGlvbiBlcnJvcnMgYXNzb2NpYXRlZCB3aXRoIGVpdGhlciB0aGUgZW50aXJlIGVudGl0eSBvciBhbnkgc3BlY2lmaWVkIHByb3BlcnR5LlxyXG4gIFxyXG4gIFRoaXMgbWV0aG9kIGNhbiByZXR1cm4gYWxsIG9mIHRoZSBlcnJvcnMgZm9yIGFuIEVudGl0eVxyXG4gID4gICAgICAvLyBhc3N1bWUgb3JkZXIgaXMgYW4gb3JkZXIgZW50aXR5IGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIHZhciB2YWxFcnJvcnMgPSBvcmRlci5lbnRpdHlBc3BlY3QuZ2V0VmFsaWRhdGlvbkVycm9ycygpO1xyXG5cclxuICBhcyB3ZWxsIGFzIHRob3NlIGZvciBqdXN0IGEgc3BlY2lmaWMgcHJvcGVydHkuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBvcmRlciBpcyBhbiBvcmRlciBlbnRpdHkgYXR0YWNoZWQgdG8gYW4gRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgdmFyIG9yZGVyRGF0ZUVycm9ycyA9IG9yZGVyLmVudGl0eUFzcGVjdC5nZXRWYWxpZGF0aW9uRXJyb3JzKFwiT3JkZXJEYXRlXCIpO1xyXG5cclxuICB3aGljaCBjYW4gYWxzbyBiZSBleHByZXNzZWQgYXNcclxuICA+ICAgICAgLy8gYXNzdW1lIG9yZGVyIGlzIGFuIG9yZGVyIGVudGl0eSBhdHRhY2hlZCB0byBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICB2YXIgb3JkZXJEYXRlUHJvcGVydHkgPSBvcmRlci5lbnRpdHlUeXBlLmdldFByb3BlcnR5KFwiT3JkZXJEYXRlXCIpO1xyXG4gID4gICAgICB2YXIgb3JkZXJEYXRlRXJyb3JzID0gb3JkZXIuZW50aXR5QXNwZWN0LmdldFZhbGlkYXRpb25FcnJvcnMob3JkZXJEYXRlUHJvcGVydHkpO1xyXG4gIEBwYXJhbSBwcm9wZXJ0eSAtIFRoZSBwcm9wZXJ0eSBmb3Igd2hpY2ggdmFsaWRhdGlvbiBlcnJvcnMgc2hvdWxkIGJlIHJldHJpZXZlZC5cclxuICBJZiBvbWl0dGVkLCBhbGwgb2YgdGhlIHZhbGlkYXRpb24gZXJyb3JzIGZvciB0aGlzIGVudGl0eSB3aWxsIGJlIHJldHVybmVkLlxyXG4gIEByZXR1cm4gQSBhcnJheSBvZiB2YWxpZGF0aW9uIGVycm9ycy5cclxuICAqKi9cclxuICBnZXRWYWxpZGF0aW9uRXJyb3JzKHByb3BlcnR5PzogRGF0YVByb3BlcnR5IHwgTmF2aWdhdGlvblByb3BlcnR5IHwgc3RyaW5nKSB7XHJcbiAgICBhc3NlcnRQYXJhbShwcm9wZXJ0eSwgXCJwcm9wZXJ0eVwiKS5pc09wdGlvbmFsKCkuaXNFbnRpdHlQcm9wZXJ0eSgpLm9yKCkuaXNTdHJpbmcoKS5jaGVjaygpO1xyXG4gICAgbGV0IHJlc3VsdCA9IGNvcmUuZ2V0T3duUHJvcGVydHlWYWx1ZXModGhpcy5fdmFsaWRhdGlvbkVycm9ycyk7XHJcbiAgICBpZiAocHJvcGVydHkpIHtcclxuICAgICAgbGV0IHByb3BlcnR5TmFtZSA9IHR5cGVvZiAocHJvcGVydHkpID09PSAnc3RyaW5nJyA/IHByb3BlcnR5IDogcHJvcGVydHkubmFtZTtcclxuICAgICAgcmVzdWx0ID0gcmVzdWx0LmZpbHRlcihmdW5jdGlvbiAodmU6IFZhbGlkYXRpb25FcnJvcikge1xyXG4gICAgICAgIHJldHVybiB2ZS5wcm9wZXJ0eSAmJiAodmUucHJvcGVydHkubmFtZSA9PT0gcHJvcGVydHlOYW1lIHx8IChwcm9wZXJ0eU5hbWUuaW5kZXhPZihcIi5cIikgIT09IC0xICYmIHZlLnByb3BlcnR5TmFtZSA9PT0gcHJvcGVydHlOYW1lKSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIEFkZHMgYSB2YWxpZGF0aW9uIGVycm9yLlxyXG4gICoqL1xyXG4gIGFkZFZhbGlkYXRpb25FcnJvcih2YWxpZGF0aW9uRXJyb3I6IFZhbGlkYXRpb25FcnJvcikge1xyXG4gICAgYXNzZXJ0UGFyYW0odmFsaWRhdGlvbkVycm9yLCBcInZhbGlkYXRpb25FcnJvclwiKS5pc0luc3RhbmNlT2YoVmFsaWRhdGlvbkVycm9yKS5jaGVjaygpO1xyXG4gICAgdGhpcy5fcHJvY2Vzc1ZhbGlkYXRpb25PcEFuZFB1Ymxpc2goZnVuY3Rpb24gKHRoYXQ6IGFueSkge1xyXG4gICAgICB0aGF0Ll9hZGRWYWxpZGF0aW9uRXJyb3IodmFsaWRhdGlvbkVycm9yKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcmVtb3ZlVmFsaWRhdGlvbkVycm9yKHZhbGlkYXRpb25FcnJvcjogVmFsaWRhdGlvbkVycm9yKTogdm9pZDtcclxuICByZW1vdmVWYWxpZGF0aW9uRXJyb3IodmFsaWRhdGlvbktleTogc3RyaW5nKTogdm9pZDtcclxuICAvKipcclxuICBSZW1vdmVzIGEgdmFsaWRhdGlvbiBlcnJvci5cclxuICBAcGFyYW0gdmFsaWRhdGlvbkVycm9yT3JLZXkgLSBFaXRoZXIgYSBWYWxpZGF0aW9uRXJyb3Igb3IgYSBWYWxpZGF0aW9uRXJyb3IgJ2tleScgdmFsdWVcclxuICAqKi9cclxuICByZW1vdmVWYWxpZGF0aW9uRXJyb3IodmFsaWRhdGlvbkVycm9yT3JLZXk6IFZhbGlkYXRpb25FcnJvciB8IHN0cmluZykge1xyXG4gICAgYXNzZXJ0UGFyYW0odmFsaWRhdGlvbkVycm9yT3JLZXksIFwidmFsaWRhdGlvbkVycm9yT3JLZXlcIikuaXNTdHJpbmcoKS5vcigpLmlzSW5zdGFuY2VPZihWYWxpZGF0aW9uRXJyb3IpLm9yKCkuaXNJbnN0YW5jZU9mKFZhbGlkYXRvcikuY2hlY2soKTtcclxuXHJcbiAgICBsZXQga2V5ID0gKHR5cGVvZiAodmFsaWRhdGlvbkVycm9yT3JLZXkpID09PSBcInN0cmluZ1wiKSA/IHZhbGlkYXRpb25FcnJvck9yS2V5IDogdmFsaWRhdGlvbkVycm9yT3JLZXkua2V5O1xyXG4gICAgdGhpcy5fcHJvY2Vzc1ZhbGlkYXRpb25PcEFuZFB1Ymxpc2goZnVuY3Rpb24gKHRoYXQ6IGFueSkge1xyXG4gICAgICB0aGF0Ll9yZW1vdmVWYWxpZGF0aW9uRXJyb3Ioa2V5KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmVtb3ZlcyBhbGwgb2YgdGhlIHZhbGlkYXRpb24gZXJyb3JzIGZvciBhIHNwZWNpZmllZCBlbnRpdHlcclxuICAqKi9cclxuICBjbGVhclZhbGlkYXRpb25FcnJvcnMoKSB7XHJcbiAgICB0aGlzLl9wcm9jZXNzVmFsaWRhdGlvbk9wQW5kUHVibGlzaChmdW5jdGlvbiAodGhhdDogYW55KSB7XHJcbiAgICAgIGNvcmUub2JqZWN0Rm9yRWFjaCh0aGF0Ll92YWxpZGF0aW9uRXJyb3JzLCBmdW5jdGlvbiAoa2V5OiBzdHJpbmcsIHZhbEVycm9yOiBWYWxpZGF0aW9uRXJyb3IpIHtcclxuICAgICAgICBpZiAodmFsRXJyb3IpIHtcclxuICAgICAgICAgIGRlbGV0ZSB0aGF0Ll92YWxpZGF0aW9uRXJyb3JzW2tleV07XHJcbiAgICAgICAgICB0aGF0Ll9wZW5kaW5nVmFsaWRhdGlvblJlc3VsdC5yZW1vdmVkLnB1c2godmFsRXJyb3IpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICAgIHRoYXQuaGFzVmFsaWRhdGlvbkVycm9ycyA9ICFjb3JlLmlzRW1wdHkodGhhdC5fdmFsaWRhdGlvbkVycm9ycyk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgYW4gW1tFbnRpdHlLZXldXSBmb3IgdGhlIGVudGl0eSBwb2ludGVkIHRvIGJ5IHRoZSBzcGVjaWZpZWQgc2NhbGFyIE5hdmlnYXRpb25Qcm9wZXJ0eS5cclxuICBUaGlzIG9ubHkgcmV0dXJucyBhbiBFbnRpdHlLZXkgaWYgdGhlIGN1cnJlbnQgZW50aXR5IGlzIGEgJ2NoaWxkJyBlbnRpdHkgYWxvbmcgdGhlIHNwZWNpZmllZCBOYXZpZ2F0aW9uUHJvcGVydHkuIFxyXG4gIGkuZS4gaGFzIGEgc2luZ2xlIHBhcmVudC5cclxuXHJcbiAgQHBhcmFtIG5hdmlnYXRpb25Qcm9wZXJ0eSAtIFRoZSBbW05hdmlnYXRpb25Qcm9wZXJ0eV1dICggcG9pbnRpbmcgdG8gYSBwYXJlbnQpLiBcclxuICBAcmV0dXJucyBFaXRoZXIgYSBwYXJlbnQgRW50aXR5S2V5IGlmIHRoaXMgaXMgYSAnY2hpbGQnIGVudGl0eSBvciBudWxsOyAgXHJcbiAgKi9cclxuICBnZXRQYXJlbnRLZXkobmF2aWdhdGlvblByb3BlcnR5OiBOYXZpZ2F0aW9uUHJvcGVydHkpIHtcclxuICAgIGlmICghdGhpcy5lbnRpdHkpIHJldHVybiBudWxsO1xyXG4gICAgLy8gVE9ETzogcmV2aWV3IHRoaXMgLSBub3Qgc3VyZSBhYm91dCB0aGUgY29tbWVudC5cclxuICAgIC8vIE5hdmlnYXRpb25Qcm9wZXJ0eSBkb2Vzbid0IHlldCBleGlzdFxyXG4gICAgLy8gYXNzZXJ0UGFyYW0obmF2aWdhdGlvblByb3BlcnR5LCBcIm5hdmlnYXRpb25Qcm9wZXJ0eVwiKS5pc0luc3RhbmNlT2YoTmF2aWdhdGlvblByb3BlcnR5KS5jaGVjaygpO1xyXG4gICAgbGV0IGZrTmFtZXMgPSBuYXZpZ2F0aW9uUHJvcGVydHkuZm9yZWlnbktleU5hbWVzO1xyXG4gICAgaWYgKGZrTmFtZXMubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcclxuICAgIGxldCB0aGF0ID0gdGhpcztcclxuICAgIGxldCBma1ZhbHVlcyA9IGZrTmFtZXMubWFwKGZ1bmN0aW9uIChma24pIHtcclxuICAgICAgcmV0dXJuIHRoYXQuZW50aXR5IS5nZXRQcm9wZXJ0eShma24pO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gbmV3IEVudGl0eUtleShuYXZpZ2F0aW9uUHJvcGVydHkuZW50aXR5VHlwZSwgZmtWYWx1ZXMpO1xyXG4gIH1cclxuXHJcbiAgLy8gVE9ETzogcmVmYWN0b3IgdGhpcyBhbmQgdGhlIHN0YXRpYyBnZXRQcm9wZXJ0eVBhdGhWYWx1ZS5cclxuICAvKipcclxuICBSZXR1cm5zIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBEYXRhUHJvcGVydHkgb3IgTmF2aWdhdGlvblByb3BlcnR5IG9yICdwcm9wZXJ0eSBwYXRoJy4gIFxyXG4gICoqL1xyXG4gIGdldFByb3BlcnR5VmFsdWUocHJvcGVydHk6IHN0cmluZyB8IERhdGFQcm9wZXJ0eSB8IE5hdmlnYXRpb25Qcm9wZXJ0eSkge1xyXG4gICAgYXNzZXJ0UGFyYW0ocHJvcGVydHksIFwicHJvcGVydHlcIikuaXNTdHJpbmcoKS5vcigpLmlzRW50aXR5UHJvcGVydHkoKS5jaGVjaygpO1xyXG4gICAgbGV0IHZhbHVlOiBhbnk7XHJcbiAgICBpZiAodHlwZW9mIChwcm9wZXJ0eSkgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgIGxldCBwcm9wTmFtZXMgPSBwcm9wZXJ0eS50cmltKCkuc3BsaXQoXCIuXCIpO1xyXG4gICAgICBsZXQgcHJvcE5hbWUgPSBwcm9wTmFtZXMuc2hpZnQoKTtcclxuICAgICAgdmFsdWUgPSB0aGlzLmVudGl0eTtcclxuICAgICAgdmFsdWUgPSB2YWx1ZS5nZXRQcm9wZXJ0eShwcm9wTmFtZSk7XHJcbiAgICAgIHdoaWxlIChwcm9wTmFtZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIHByb3BOYW1lID0gcHJvcE5hbWVzLnNoaWZ0KCk7XHJcbiAgICAgICAgdmFsdWUgPSB2YWx1ZS5nZXRQcm9wZXJ0eShwcm9wTmFtZSk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmICghKHByb3BlcnR5LnBhcmVudFR5cGUgaW5zdGFuY2VvZiBFbnRpdHlUeXBlKSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSB2YWxpZGF0ZVByb3BlcnR5IG1ldGhvZCBkb2VzIG5vdCBhY2NlcHQgYSAncHJvcGVydHknIHBhcmFtZXRlciB3aG9zZSBwYXJlbnRUeXBlIGlzIGEgQ29tcGxleFR5cGU7IFwiICtcclxuICAgICAgICAgIFwiUGFzcyBhICdwcm9wZXJ0eSBwYXRoJyBzdHJpbmcgYXMgdGhlICdwcm9wZXJ0eScgcGFyYW1ldGVyIGluc3RlYWQgXCIpO1xyXG4gICAgICB9XHJcbiAgICAgIHZhbHVlID0gdGhpcy5lbnRpdHkhLmdldFByb3BlcnR5KHByb3BlcnR5Lm5hbWUpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHZhbHVlO1xyXG4gIH1cclxuXHJcbiAgLy8gaW50ZXJuYWwgbWV0aG9kc1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9jaGVja09wZXJhdGlvbihvcGVyYXRpb25OYW1lOiBzdHJpbmcpIHtcclxuICAgIGlmICh0aGlzLmlzQmVpbmdTYXZlZCkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgcGVyZm9ybSBhICdcIiArIG9wZXJhdGlvbk5hbWUgKyBcIicgb24gYW4gZW50aXR5IHRoYXQgaXMgaW4gdGhlIHByb2Nlc3Mgb2YgYmVpbmcgc2F2ZWRcIik7XHJcbiAgICB9XHJcbiAgICAvLyBhbGxvd3MgY2hhaW5pbmdcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2RldGFjaCgpIHtcclxuICAgIHRoaXMuZW50aXR5R3JvdXAgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLmVudGl0eU1hbmFnZXIgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLmVudGl0eVN0YXRlID0gRW50aXR5U3RhdGUuRGV0YWNoZWQ7XHJcbiAgICB0aGlzLm9yaWdpbmFsVmFsdWVzID0ge307XHJcbiAgICB0aGlzLl92YWxpZGF0aW9uRXJyb3JzID0ge307XHJcbiAgICB0aGlzLmhhc1ZhbGlkYXRpb25FcnJvcnMgPSBmYWxzZTtcclxuICAgIHRoaXMudmFsaWRhdGlvbkVycm9yc0NoYW5nZWQuY2xlYXIoKTtcclxuICAgIHRoaXMucHJvcGVydHlDaGFuZ2VkLmNsZWFyKCk7XHJcblxyXG4gIH1cclxuXHJcblxyXG4gIC8vIGNhbGxlZCBmcm9tIGRlZmF1bHRJbnRlcmNlcHRvci5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfdmFsaWRhdGVQcm9wZXJ0eSh2YWx1ZTogYW55LCBjb250ZXh0OiBhbnkpIHtcclxuICAgIGxldCBvayA9IHRydWU7XHJcbiAgICB0aGlzLl9wcm9jZXNzVmFsaWRhdGlvbk9wQW5kUHVibGlzaChmdW5jdGlvbiAodGhhdDogYW55KSB7XHJcbiAgICAgIGNvbnRleHQucHJvcGVydHkuZ2V0QWxsVmFsaWRhdG9ycygpLmZvckVhY2goZnVuY3Rpb24gKHZhbGlkYXRvcjogVmFsaWRhdG9yKSB7XHJcbiAgICAgICAgb2sgPSB2YWxpZGF0ZSh0aGF0LCB2YWxpZGF0b3IsIHZhbHVlLCBjb250ZXh0KSAmJiBvaztcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBvaztcclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9wcm9jZXNzVmFsaWRhdGlvbk9wQW5kUHVibGlzaCh2YWxpZGF0aW9uRm46IGFueSkge1xyXG4gICAgaWYgKHRoaXMuX3BlbmRpbmdWYWxpZGF0aW9uUmVzdWx0KSB7XHJcbiAgICAgIC8vIG9ubHkgdG9wIGxldmVsIHByb2Nlc3NWYWxpZGF0aW9ucyBjYWxsIHB1Ymxpc2hlc1xyXG4gICAgICB2YWxpZGF0aW9uRm4odGhpcyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIHRoaXMuX3BlbmRpbmdWYWxpZGF0aW9uUmVzdWx0ID0geyBlbnRpdHk6IHRoaXMuZW50aXR5LCBhZGRlZDogW10sIHJlbW92ZWQ6IFtdIH07XHJcbiAgICAgICAgdmFsaWRhdGlvbkZuKHRoaXMpO1xyXG4gICAgICAgIGlmICh0aGlzLl9wZW5kaW5nVmFsaWRhdGlvblJlc3VsdC5hZGRlZC5sZW5ndGggPiAwIHx8IHRoaXMuX3BlbmRpbmdWYWxpZGF0aW9uUmVzdWx0LnJlbW92ZWQubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgdGhpcy52YWxpZGF0aW9uRXJyb3JzQ2hhbmdlZC5wdWJsaXNoKHRoaXMuX3BlbmRpbmdWYWxpZGF0aW9uUmVzdWx0KTtcclxuICAgICAgICAgIC8vIHRoaXMgbWlnaHQgYmUgYSBkZXRhY2hlZCBlbnRpdHkgaGVuY2UgdGhlIGd1YXJkIGJlbG93LlxyXG4gICAgICAgICAgdGhpcy5lbnRpdHlNYW5hZ2VyICYmIHRoaXMuZW50aXR5TWFuYWdlci52YWxpZGF0aW9uRXJyb3JzQ2hhbmdlZC5wdWJsaXNoKHRoaXMuX3BlbmRpbmdWYWxpZGF0aW9uUmVzdWx0KTtcclxuXHJcbiAgICAgICAgfVxyXG4gICAgICB9IGZpbmFsbHkge1xyXG4gICAgICAgIHRoaXMuX3BlbmRpbmdWYWxpZGF0aW9uUmVzdWx0ID0gdW5kZWZpbmVkO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICAvLyBUT0RPOiBhZGQvdXNlIGEgVmFsaWRhdGlvbkVycm9yIHR5cGVcclxuICBfYWRkVmFsaWRhdGlvbkVycm9yKHZhbGlkYXRpb25FcnJvcjogYW55KSB7XHJcbiAgICB0aGlzLl92YWxpZGF0aW9uRXJyb3JzW3ZhbGlkYXRpb25FcnJvci5rZXldID0gdmFsaWRhdGlvbkVycm9yO1xyXG4gICAgdGhpcy5oYXNWYWxpZGF0aW9uRXJyb3JzID0gdHJ1ZTtcclxuICAgIHRoaXMuX3BlbmRpbmdWYWxpZGF0aW9uUmVzdWx0LmFkZGVkLnB1c2godmFsaWRhdGlvbkVycm9yKTtcclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9yZW1vdmVWYWxpZGF0aW9uRXJyb3Ioa2V5OiBzdHJpbmcpIHtcclxuICAgIGxldCB2YWxFcnJvciA9IHRoaXMuX3ZhbGlkYXRpb25FcnJvcnNba2V5XTtcclxuICAgIGlmICh2YWxFcnJvcikge1xyXG4gICAgICBkZWxldGUgdGhpcy5fdmFsaWRhdGlvbkVycm9yc1trZXldO1xyXG4gICAgICB0aGlzLmhhc1ZhbGlkYXRpb25FcnJvcnMgPSAhY29yZS5pc0VtcHR5KHRoaXMuX3ZhbGlkYXRpb25FcnJvcnMpO1xyXG4gICAgICB0aGlzLl9wZW5kaW5nVmFsaWRhdGlvblJlc3VsdC5yZW1vdmVkLnB1c2godmFsRXJyb3IpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbn1cclxuXHJcbkJyZWV6ZUV2ZW50LmJ1YmJsZUV2ZW50KEVudGl0eUFzcGVjdC5wcm90b3R5cGUsIGZ1bmN0aW9uICgpIHtcclxuICByZXR1cm4gdGhpcy5lbnRpdHlNYW5hZ2VyO1xyXG59KTtcclxuXHJcbmZ1bmN0aW9uIHJlamVjdENoYW5nZXNDb3JlKHRhcmdldDogYW55KSB7XHJcbiAgbGV0IGFzcGVjdCA9IHRhcmdldC5lbnRpdHlBc3BlY3QgfHwgdGFyZ2V0LmNvbXBsZXhBc3BlY3Q7XHJcbiAgbGV0IHN0eXBlID0gdGFyZ2V0LmVudGl0eVR5cGUgfHwgdGFyZ2V0LmNvbXBsZXhUeXBlO1xyXG4gIGxldCBvcmlnaW5hbFZhbHVlcyA9IGFzcGVjdC5vcmlnaW5hbFZhbHVlcztcclxuICBmb3IgKGxldCBwcm9wTmFtZSBpbiBvcmlnaW5hbFZhbHVlcykge1xyXG4gICAgdGFyZ2V0LnNldFByb3BlcnR5KHByb3BOYW1lLCBvcmlnaW5hbFZhbHVlc1twcm9wTmFtZV0pO1xyXG4gIH1cclxuICBzdHlwZS5jb21wbGV4UHJvcGVydGllcy5mb3JFYWNoKGZ1bmN0aW9uIChjcDogYW55KSB7XHJcbiAgICBsZXQgY29zID0gdGFyZ2V0LmdldFByb3BlcnR5KGNwLm5hbWUpO1xyXG4gICAgaWYgKGNwLmlzU2NhbGFyKSB7XHJcbiAgICAgIHJlamVjdENoYW5nZXNDb3JlKGNvcyk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb3MuX3JlamVjdENoYW5nZXMoKTtcclxuICAgICAgY29zLmZvckVhY2gocmVqZWN0Q2hhbmdlc0NvcmUpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiByZW1vdmVGcm9tUmVsYXRpb25zKGVudGl0eTogRW50aXR5LCBlbnRpdHlTdGF0ZTogRW50aXR5U3RhdGUpIHtcclxuICAvLyByZW1vdmUgdGhpcyBlbnRpdHkgZnJvbSBhbnkgY29sbGVjdGlvbnMuXHJcbiAgLy8gbWFyayB0aGUgZW50aXR5IGRlbGV0ZWQgb3IgZGV0YWNoZWRcclxuXHJcbiAgbGV0IGlzRGVsZXRlZCA9IGVudGl0eVN0YXRlLmlzRGVsZXRlZCgpO1xyXG4gIGlmIChpc0RlbGV0ZWQpIHtcclxuICAgIHJlbW92ZUZyb21SZWxhdGlvbnNDb3JlKGVudGl0eSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIGNvcmUudXNpbmcoZW50aXR5LmVudGl0eUFzcGVjdC5lbnRpdHlNYW5hZ2VyISwgXCJpc0xvYWRpbmdcIiwgdHJ1ZSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICByZW1vdmVGcm9tUmVsYXRpb25zQ29yZShlbnRpdHkpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiByZW1vdmVGcm9tUmVsYXRpb25zQ29yZShlbnRpdHk6IEVudGl0eSkge1xyXG4gIGVudGl0eS5lbnRpdHlUeXBlLm5hdmlnYXRpb25Qcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24gKG5wKSB7XHJcbiAgICBsZXQgaW52ZXJzZU5wID0gbnAuaW52ZXJzZTtcclxuICAgIGxldCBucFZhbHVlID0gZW50aXR5LmdldFByb3BlcnR5KG5wLm5hbWUpO1xyXG4gICAgaWYgKG5wLmlzU2NhbGFyKSB7XHJcbiAgICAgIGlmIChucFZhbHVlKSB7XHJcbiAgICAgICAgaWYgKGludmVyc2VOcCkge1xyXG4gICAgICAgICAgaWYgKGludmVyc2VOcC5pc1NjYWxhcikge1xyXG4gICAgICAgICAgICBucFZhbHVlLnNldFByb3BlcnR5KGludmVyc2VOcC5uYW1lLCBudWxsKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGxldCBjb2xsZWN0aW9uID0gbnBWYWx1ZS5nZXRQcm9wZXJ0eShpbnZlcnNlTnAubmFtZSk7XHJcbiAgICAgICAgICAgIGlmIChjb2xsZWN0aW9uLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgIGNvcmUuYXJyYXlSZW1vdmVJdGVtKGNvbGxlY3Rpb24sIGVudGl0eSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZW50aXR5LnNldFByb3BlcnR5KG5wLm5hbWUsIG51bGwpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAoaW52ZXJzZU5wICE9IG51bGwpIHtcclxuICAgICAgICAvLyBucFZhbHVlIGlzIGEgbGl2ZSBsaXN0IHNvIHdlIG5lZWQgdG8gY29weSBpdCBmaXJzdC5cclxuICAgICAgICBucFZhbHVlLnNsaWNlKDApLmZvckVhY2goKHY6IGFueSkgPT4ge1xyXG4gICAgICAgICAgaWYgKGludmVyc2VOcCEuaXNTY2FsYXIpIHtcclxuICAgICAgICAgICAgdi5zZXRQcm9wZXJ0eShpbnZlcnNlTnAhLm5hbWUsIG51bGwpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gVE9ETzogbWFueSB0byBtYW55IC0gbm90IHlldCBoYW5kbGVkLlxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICAgIC8vIG5vdyBjbGVhciBpdC5cclxuICAgICAgbnBWYWx1ZS5sZW5ndGggPSAwO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxufVxyXG5cclxuLy8gbm90ZSBlbnRpdHlBc3BlY3Qgb25seSAtICggbm8gY29tcGxleCBhc3BlY3QgYWxsb3dlZCBvbiB0aGUgY2FsbCkuXHJcbmZ1bmN0aW9uIHZhbGlkYXRlKGVudGl0eUFzcGVjdDogRW50aXR5QXNwZWN0LCB2YWxpZGF0b3I6IFZhbGlkYXRvciwgdmFsdWU6IGFueSwgY29udGV4dD86IGFueSkge1xyXG4gIGxldCB2ZSA9IHZhbGlkYXRvci52YWxpZGF0ZSh2YWx1ZSwgY29udGV4dCk7XHJcbiAgaWYgKHZlKSB7XHJcbiAgICBlbnRpdHlBc3BlY3QuX2FkZFZhbGlkYXRpb25FcnJvcih2ZSk7XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfSBlbHNlIHtcclxuICAgIGxldCBrZXkgPSBWYWxpZGF0aW9uRXJyb3IuZ2V0S2V5KHZhbGlkYXRvciwgY29udGV4dCA/IGNvbnRleHQucHJvcGVydHlOYW1lIDogbnVsbCk7XHJcbiAgICBlbnRpdHlBc3BlY3QuX3JlbW92ZVZhbGlkYXRpb25FcnJvcihrZXkpO1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG59XHJcblxyXG4vLyBjb0luZGV4IGlzIG9ubHkgdXNlZCB3aGVyZSB0YXJnZXQgaXMgYSBjb21wbGV4IG9iamVjdCB0aGF0IGlzIHBhcnQgb2YgYW4gYXJyYXkgb2YgY29tcGxleCBvYmplY3RzXHJcbi8vIGluIHdoaWNoIGNhc2UgY3RJbmRleCBpcyB0aGUgaW5kZXggb2YgdGhlIHRhcmdldCB3aXRoaW4gdGhlIGFycmF5LlxyXG5mdW5jdGlvbiB2YWxpZGF0ZVRhcmdldCh0YXJnZXQ6IGFueSwgY29JbmRleD86IG51bWJlcikge1xyXG4gIGxldCBvayA9IHRydWU7XHJcbiAgbGV0IHN0eXBlID0gdGFyZ2V0LmVudGl0eVR5cGUgfHwgdGFyZ2V0LmNvbXBsZXhUeXBlO1xyXG4gIGxldCBhc3BlY3QgPSB0YXJnZXQuZW50aXR5QXNwZWN0IHx8IHRhcmdldC5jb21wbGV4QXNwZWN0O1xyXG4gIGxldCBlbnRpdHlBc3BlY3QgPSB0YXJnZXQuZW50aXR5QXNwZWN0IHx8IHRhcmdldC5jb21wbGV4QXNwZWN0LmdldEVudGl0eUFzcGVjdCgpO1xyXG4gIGxldCBjb250ZXh0ID0gPGFueT57IGVudGl0eTogZW50aXR5QXNwZWN0LmVudGl0eSB9O1xyXG4gIGlmIChjb0luZGV4ICE9PSB1bmRlZmluZWQpIHtcclxuICAgIGNvbnRleHQuaW5kZXggPSBjb0luZGV4O1xyXG4gIH1cclxuXHJcbiAgc3R5cGUuZ2V0UHJvcGVydGllcygpLmZvckVhY2goZnVuY3Rpb24gKHA6IGFueSkge1xyXG4gICAgbGV0IHZhbHVlID0gdGFyZ2V0LmdldFByb3BlcnR5KHAubmFtZSk7XHJcbiAgICBsZXQgdmFsaWRhdG9ycyA9IHAuZ2V0QWxsVmFsaWRhdG9ycygpO1xyXG4gICAgaWYgKHZhbGlkYXRvcnMubGVuZ3RoID4gMCkge1xyXG4gICAgICBjb250ZXh0LnByb3BlcnR5ID0gcDtcclxuICAgICAgY29udGV4dC5wcm9wZXJ0eU5hbWUgPSBhc3BlY3QuZ2V0UHJvcGVydHlQYXRoKHAubmFtZSk7XHJcbiAgICAgIG9rID0gZW50aXR5QXNwZWN0Ll92YWxpZGF0ZVByb3BlcnR5KHZhbHVlLCBjb250ZXh0KSAmJiBvaztcclxuICAgIH1cclxuICAgIGlmIChwLmlzQ29tcGxleFByb3BlcnR5KSB7XHJcbiAgICAgIGlmIChwLmlzU2NhbGFyKSB7XHJcbiAgICAgICAgb2sgPSB2YWxpZGF0ZVRhcmdldCh2YWx1ZSkgJiYgb2s7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgb2sgPSB2YWx1ZS5yZWR1Y2UoZnVuY3Rpb24gKHB2OiBhbnksIGN2OiBhbnksIGl4OiBudW1iZXIpIHtcclxuICAgICAgICAgIHJldHVybiB2YWxpZGF0ZVRhcmdldChjdiwgaXgpICYmIHB2O1xyXG4gICAgICAgIH0sIG9rKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgLy8gdGhlbiB0YXJnZXQgbGV2ZWxcclxuICBzdHlwZS5nZXRBbGxWYWxpZGF0b3JzKCkuZm9yRWFjaChmdW5jdGlvbiAodmFsaWRhdG9yOiBWYWxpZGF0b3IpIHtcclxuICAgIG9rID0gdmFsaWRhdGUoZW50aXR5QXNwZWN0LCB2YWxpZGF0b3IsIHRhcmdldCkgJiYgb2s7XHJcbiAgfSk7XHJcbiAgcmV0dXJuIG9rO1xyXG59XHJcblxyXG4vKipcclxuQW4gQ29tcGxleEFzcGVjdCBpbnN0YW5jZSBpcyBhc3NvY2lhdGVkIHdpdGggZXZlcnkgY29tcGxleCBvYmplY3QgaW5zdGFuY2UgYW5kIGlzIGFjY2Vzc2VkIHZpYSB0aGUgY29tcGxleCBvYmplY3QncyAnY29tcGxleEFzcGVjdCcgcHJvcGVydHkuXHJcblxyXG5UaGUgQ29tcGxleEFzcGVjdCBpdHNlbGYgcHJvdmlkZXMgcHJvcGVydGllcyB0byBkZXRlcm1pbmUgdGhlIHBhcmVudCBvYmplY3QsIHBhcmVudCBwcm9wZXJ0eSBhbmQgb3JpZ2luYWwgdmFsdWVzIGZvciB0aGUgY29tcGxleCBvYmplY3QuXHJcblxyXG5BIENvbXBsZXhBc3BlY3Qgd2lsbCBhbG1vc3QgbmV2ZXIgbmVlZCB0byBiZSBjb25zdHJ1Y3RlZCBkaXJlY3RseS4gWW91IHdpbGwgdXN1YWxseSBnZXQgYW4gQ29tcGxleEFzcGVjdCBieSBhY2Nlc3NpbmdcclxuYW4gZW50aXRpZXMgJ2NvbXBsZXhBc3BlY3QnIHByb3BlcnR5LiAgVGhpcyBwcm9wZXJ0eSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgYXR0YWNoZWQgd2hlbiBhbiBjb21wbGV4IG9iamVjdCBpcyBjcmVhdGVkIGFzIHBhcnQgb2YgYW5cclxuZW50aXR5IHZpYSBlaXRoZXIgYSBxdWVyeSwgaW1wb3J0IG9yIEVudGl0eU1hbmFnZXIuY3JlYXRlRW50aXR5IGNhbGwuXHJcbj4gICAgICAvLyBhc3N1bWUgYWRkcmVzcyBpcyBhIGNvbXBsZXggcHJvcGVydHkgb24gdGhlICdDdXN0b21lcicgdHlwZVxyXG4+ICAgICAgdmFyIGFzcGVjdCA9IGFDdXN0b21lci5hZGRyZXNzLmNvbXBsZXhBc3BlY3Q7XHJcbj4gICAgICAvLyBhQ3VzdG9tZXIgPT09IGFzcGVjdC5wYXJlbnQ7XHJcbioqL1xyXG5leHBvcnQgY2xhc3MgQ29tcGxleEFzcGVjdCB7XHJcblxyXG4gIC8qKiBUaGUgY29tcGxleCBvYmplY3QgdGhhdCB0aGlzIGFzcGVjdCBpcyBhc3NvY2lhdGVkIHdpdGguIF9fUmVhZCBPbmx5X18gKi9cclxuICBjb21wbGV4T2JqZWN0OiBDb21wbGV4T2JqZWN0O1xyXG4gIC8qKiBUaGUgJ29yaWdpbmFsIHZhbHVlcycgb2YgdGhpcyBjb21wbGV4IG9iamVjdCB3aGVyZSB0aGV5IGFyZSBkaWZmZXJlbnQgZnJvbSB0aGUgJ2N1cnJlbnQgdmFsdWVzJy5cclxuICBUaGlzIGlzIGEgbWFwIHdoZXJlIHRoZSBrZXkgaXMgYSBwcm9wZXJ0eSBuYW1lIGFuZCB0aGUgdmFsdWUgaXMgdGhlICdvcmlnaW5hbCB2YWx1ZScgb2YgdGhlIHByb3BlcnR5LlxyXG4gIF9fUmVhZCBPbmx5X18gKi9cclxuICBvcmlnaW5hbFZhbHVlczoge307XHJcbiAgLyoqIFRoZSBwYXJlbnQgb2JqZWN0IHRoYXQgdG8gd2hpY2ggdGhpcyBhc3BlY3QgYmVsb25nczsgdGhpcyB3aWxsIGVpdGhlciBiZSBhbiBlbnRpdHkgb3IgYW5vdGhlciBjb21wbGV4IG9iamVjdC4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIHBhcmVudD86IFN0cnVjdHVyYWxPYmplY3Q7XHJcbiAgLyoqIFRoZSBbW0RhdGFQcm9wZXJ0eV1dIG9uIHRoZSAncGFyZW50JyB0aGF0IGNvbnRhaW5zIHRoaXMgY29tcGxleCBvYmplY3QuIF9fUmVhZCBPbmx5X18gKi9cclxuICBwYXJlbnRQcm9wZXJ0eT86IERhdGFQcm9wZXJ0eTtcclxuICBleHRyYU1ldGFkYXRhPzogYW55O1xyXG5cclxuICAvKiogWW91IHdpbGwgcmFyZWx5LCBpZiBldmVyLCBjcmVhdGUgYSBDb21wbGV4QXNwZWN0IGRpcmVjdGx5LiAqL1xyXG4gIGNvbnN0cnVjdG9yKGNvbXBsZXhPYmplY3Q6IENvbXBsZXhPYmplY3QsIHBhcmVudDogU3RydWN0dXJhbE9iamVjdCwgcGFyZW50UHJvcGVydHk6IERhdGFQcm9wZXJ0eSkge1xyXG4gICAgaWYgKCFjb21wbGV4T2JqZWN0KSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSAgQ29tcGxleEFzcGVjdCBjdG9yIHJlcXVpcmVzIGFuIGVudGl0eSBhcyBpdHMgb25seSBhcmd1bWVudC5cIik7XHJcbiAgICB9XHJcbiAgICBpZiAoY29tcGxleE9iamVjdC5jb21wbGV4QXNwZWN0KSB7XHJcbiAgICAgIHJldHVybiBjb21wbGV4T2JqZWN0LmNvbXBsZXhBc3BlY3Q7XHJcbiAgICB9XHJcbiAgICAvLyBpZiBjYWxsZWQgd2l0aG91dCBuZXdcclxuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDb21wbGV4QXNwZWN0KSkge1xyXG4gICAgICByZXR1cm4gbmV3IENvbXBsZXhBc3BlY3QoY29tcGxleE9iamVjdCwgcGFyZW50LCBwYXJlbnRQcm9wZXJ0eSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gZW50aXR5VHlwZSBzaG91bGQgYWxyZWFkeSBiZSBvbiB0aGUgZW50aXR5IGZyb20gJ3dhdGNoJ1xyXG4gICAgdGhpcy5jb21wbGV4T2JqZWN0ID0gY29tcGxleE9iamVjdDtcclxuICAgIGNvbXBsZXhPYmplY3QuY29tcGxleEFzcGVjdCA9IHRoaXM7XHJcblxyXG4gICAgLy8gVE9ETzoga2VlcCBwdWJsaWMgb3Igbm90P1xyXG4gICAgdGhpcy5vcmlnaW5hbFZhbHVlcyA9IHt9O1xyXG5cclxuICAgIC8vIGlmIGEgc3RhbmRhbG9uZSBjb21wbGV4T2JqZWN0XHJcbiAgICBpZiAocGFyZW50ICE9IG51bGwpIHtcclxuICAgICAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XHJcbiAgICAgIHRoaXMucGFyZW50UHJvcGVydHkgPSBwYXJlbnRQcm9wZXJ0eTtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgY29tcGxleFR5cGUgPSBjb21wbGV4T2JqZWN0LmNvbXBsZXhUeXBlO1xyXG4gICAgaWYgKCFjb21wbGV4VHlwZSkge1xyXG4gICAgICBsZXQgdHlwZU5hbWUgPSBjb21wbGV4T2JqZWN0LnByb3RvdHlwZS5fJHR5cGVOYW1lO1xyXG4gICAgICBpZiAoIXR5cGVOYW1lKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbnRpdHkgaXMgbm90IHJlZ2lzdGVyZWQgYXMgYSB2YWxpZCBDb21wbGV4VHlwZVwiKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNZXRhZGF0YSBmb3IgdGhpcyBjb21wbGV4VHlwZSBoYXMgbm90IHlldCBiZWVuIHJlc29sdmVkOiBcIiArIHR5cGVOYW1lKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgbGV0IGNvbXBsZXhDdG9yID0gY29tcGxleFR5cGUuZ2V0Q3RvcigpO1xyXG4gICAgY29uZmlnLmludGVyZmFjZVJlZ2lzdHJ5Lm1vZGVsTGlicmFyeS5nZXREZWZhdWx0SW5zdGFuY2UoKS5zdGFydFRyYWNraW5nKGNvbXBsZXhPYmplY3QsIGNvbXBsZXhDdG9yLnByb3RvdHlwZSk7XHJcblxyXG4gIH1cclxuXHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgdGhlIEVudGl0eUFzcGVjdCBmb3IgdGhlIHRvcCBsZXZlbCBlbnRpdHkgdGhhdCBjb250YWlucyB0aGlzIGNvbXBsZXggb2JqZWN0LlxyXG4gICoqL1xyXG4gIGdldEVudGl0eUFzcGVjdCgpIHtcclxuICAgIGxldCBwYXJlbnQgPSA8YW55PnRoaXMucGFyZW50O1xyXG4gICAgaWYgKCFwYXJlbnQpIHJldHVybiBuZXcgRW50aXR5QXNwZWN0KCk7XHJcbiAgICBsZXQgZW50aXR5QXNwZWN0ID0gcGFyZW50LmVudGl0eUFzcGVjdDtcclxuICAgIHdoaWxlIChwYXJlbnQgJiYgIWVudGl0eUFzcGVjdCkge1xyXG4gICAgICBwYXJlbnQgPSBwYXJlbnQuY29tcGxleEFzcGVjdCAmJiBwYXJlbnQuY29tcGxleEFzcGVjdC5wYXJlbnQ7XHJcbiAgICAgIGVudGl0eUFzcGVjdCA9IHBhcmVudCAmJiBwYXJlbnQuZW50aXR5QXNwZWN0O1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGVudGl0eUFzcGVjdCB8fCBuZXcgRW50aXR5QXNwZWN0KCk7XHJcbiAgfVxyXG5cclxuICAvKiogIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgLy8gVE9ETzogcmVuYW1lIC0gYW5kIHVzZSAnXyc7IHVzZWQgb24gYm90aCBFbnRpdHlBc3BlY3QgYW5kIENvbXBsZXhBc3BlY3QgZm9yIHBvbHltb3JwaGljIHJlYXNvbnMuXHJcbiAgZ2V0UHJvcGVydHlQYXRoKHByb3BOYW1lOiBzdHJpbmcpIHtcclxuICAgIGxldCBwYXJlbnQgPSA8YW55PnRoaXMucGFyZW50O1xyXG4gICAgaWYgKCFwYXJlbnQpIHJldHVybiBudWxsO1xyXG4gICAgbGV0IGFzcGVjdCA9IHBhcmVudC5jb21wbGV4QXNwZWN0IHx8IHBhcmVudC5lbnRpdHlBc3BlY3Q7XHJcbiAgICByZXR1cm4gYXNwZWN0LmdldFByb3BlcnR5UGF0aCh0aGlzLnBhcmVudFByb3BlcnR5IS5uYW1lICsgXCIuXCIgKyBwcm9wTmFtZSk7XHJcbiAgfVxyXG5cclxufVxyXG5cclxuZnVuY3Rpb24gY2xlYXJPcmlnaW5hbFZhbHVlcyh0YXJnZXQ6IGFueSkge1xyXG4gIGxldCBhc3BlY3QgPSB0YXJnZXQuZW50aXR5QXNwZWN0IHx8IHRhcmdldC5jb21wbGV4QXNwZWN0O1xyXG4gIGFzcGVjdC5vcmlnaW5hbFZhbHVlcyA9IHt9O1xyXG4gIGxldCBzdHlwZSA9IHRhcmdldC5lbnRpdHlUeXBlIHx8IHRhcmdldC5jb21wbGV4VHlwZTtcclxuICBzdHlwZS5jb21wbGV4UHJvcGVydGllcy5mb3JFYWNoKGZ1bmN0aW9uIChjcDogYW55KSB7XHJcbiAgICBsZXQgY29zID0gdGFyZ2V0LmdldFByb3BlcnR5KGNwLm5hbWUpO1xyXG4gICAgaWYgKGNwLmlzU2NhbGFyKSB7XHJcbiAgICAgIGNsZWFyT3JpZ2luYWxWYWx1ZXMoY29zKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGNvcy5fYWNjZXB0Q2hhbmdlcygpO1xyXG4gICAgICBjb3MuZm9yRWFjaChjbGVhck9yaWdpbmFsVmFsdWVzKTtcclxuICAgIH1cclxuICB9KTtcclxufVxyXG5cclxuXHJcbiJdfQ==