breeze-client 2.1.7 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (376) hide show
  1. package/README.md +8 -4
  2. package/adapter-ajax-angularjs/{breeze-client-adapter-ajax-angularjs.d.ts → index.d.ts} +1 -0
  3. package/adapter-ajax-fetch/{breeze-client-adapter-ajax-fetch.d.ts → index.d.ts} +1 -0
  4. package/adapter-ajax-httpclient/{breeze-client-adapter-ajax-httpclient.d.ts → index.d.ts} +1 -0
  5. package/adapter-ajax-jquery/{breeze-client-adapter-ajax-jquery.d.ts → index.d.ts} +1 -0
  6. package/adapter-ajax-post/{breeze-client-adapter-ajax-post.d.ts → index.d.ts} +1 -0
  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/{esm5/adapter-data-service-odata/adapter-data-service-odata.js → esm2022/adapter-data-service-odata/adapter-data-service-odata.mjs} +138 -147
  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 +325 -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/{esm2015/src/data-type.js → esm2022/src/data-type.mjs} +131 -124
  57. package/esm2022/src/default-property-interceptor.mjs +460 -0
  58. package/{esm2015/src/entity-action.js → esm2022/src/entity-action.mjs} +25 -25
  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 +1024 -0
  65. package/esm2022/src/entity-state.mjs +107 -0
  66. package/esm2022/src/enum.mjs +143 -0
  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} +68 -69
  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} +30 -30
  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} +2039 -1537
  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 +94 -12
  113. package/src/config.d.ts +1 -1
  114. package/src/core.d.ts +1 -1
  115. package/src/entity-aspect.d.ts +1 -1
  116. package/src/entity-metadata.d.ts +8 -6
  117. package/src/entity-query.d.ts +1 -1
  118. package/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.metadata.json +0 -1
  119. package/adapter-ajax-angularjs/package.json +0 -13
  120. package/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.metadata.json +0 -1
  121. package/adapter-ajax-fetch/package.json +0 -13
  122. package/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.metadata.json +0 -1
  123. package/adapter-ajax-httpclient/package.json +0 -13
  124. package/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.metadata.json +0 -1
  125. package/adapter-ajax-jquery/package.json +0 -13
  126. package/adapter-ajax-post/breeze-client-adapter-ajax-post.metadata.json +0 -1
  127. package/adapter-ajax-post/package.json +0 -13
  128. package/adapter-data-service-odata/breeze-client-adapter-data-service-odata.metadata.json +0 -1
  129. package/adapter-data-service-odata/package.json +0 -13
  130. package/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.metadata.json +0 -1
  131. package/adapter-data-service-webapi/package.json +0 -13
  132. package/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.metadata.json +0 -1
  133. package/adapter-model-library-backing-store/package.json +0 -13
  134. package/adapter-model-library-ko/breeze-client-adapter-model-library-ko.metadata.json +0 -1
  135. package/adapter-model-library-ko/package.json +0 -13
  136. package/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.metadata.json +0 -1
  137. package/adapter-uri-builder-json/package.json +0 -13
  138. package/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.metadata.json +0 -1
  139. package/adapter-uri-builder-odata/package.json +0 -13
  140. package/breeze-client.d.ts +0 -8
  141. package/breeze-client.metadata.json +0 -1
  142. package/bundles/breeze-client-adapter-ajax-angularjs.umd.js +0 -190
  143. package/bundles/breeze-client-adapter-ajax-angularjs.umd.js.map +0 -1
  144. package/bundles/breeze-client-adapter-ajax-angularjs.umd.min.js +0 -2
  145. package/bundles/breeze-client-adapter-ajax-angularjs.umd.min.js.map +0 -1
  146. package/bundles/breeze-client-adapter-ajax-fetch.umd.js +0 -190
  147. package/bundles/breeze-client-adapter-ajax-fetch.umd.js.map +0 -1
  148. package/bundles/breeze-client-adapter-ajax-fetch.umd.min.js +0 -2
  149. package/bundles/breeze-client-adapter-ajax-fetch.umd.min.js.map +0 -1
  150. package/bundles/breeze-client-adapter-ajax-httpclient.umd.js +0 -195
  151. package/bundles/breeze-client-adapter-ajax-httpclient.umd.js.map +0 -1
  152. package/bundles/breeze-client-adapter-ajax-httpclient.umd.min.js +0 -2
  153. package/bundles/breeze-client-adapter-ajax-httpclient.umd.min.js.map +0 -1
  154. package/bundles/breeze-client-adapter-ajax-jquery.umd.js +0 -115
  155. package/bundles/breeze-client-adapter-ajax-jquery.umd.js.map +0 -1
  156. package/bundles/breeze-client-adapter-ajax-jquery.umd.min.js +0 -2
  157. package/bundles/breeze-client-adapter-ajax-jquery.umd.min.js.map +0 -1
  158. package/bundles/breeze-client-adapter-ajax-post.umd.js +0 -92
  159. package/bundles/breeze-client-adapter-ajax-post.umd.js.map +0 -1
  160. package/bundles/breeze-client-adapter-ajax-post.umd.min.js +0 -2
  161. package/bundles/breeze-client-adapter-ajax-post.umd.min.js.map +0 -1
  162. package/bundles/breeze-client-adapter-data-service-odata.umd.js +0 -747
  163. package/bundles/breeze-client-adapter-data-service-odata.umd.js.map +0 -1
  164. package/bundles/breeze-client-adapter-data-service-odata.umd.min.js +0 -16
  165. package/bundles/breeze-client-adapter-data-service-odata.umd.min.js.map +0 -1
  166. package/bundles/breeze-client-adapter-data-service-webapi.umd.js +0 -333
  167. package/bundles/breeze-client-adapter-data-service-webapi.umd.js.map +0 -1
  168. package/bundles/breeze-client-adapter-data-service-webapi.umd.min.js +0 -16
  169. package/bundles/breeze-client-adapter-data-service-webapi.umd.min.js.map +0 -1
  170. package/bundles/breeze-client-adapter-model-library-backing-store.umd.js +0 -280
  171. package/bundles/breeze-client-adapter-model-library-backing-store.umd.js.map +0 -1
  172. package/bundles/breeze-client-adapter-model-library-backing-store.umd.min.js +0 -2
  173. package/bundles/breeze-client-adapter-model-library-backing-store.umd.min.js.map +0 -1
  174. package/bundles/breeze-client-adapter-model-library-ko.umd.js +0 -252
  175. package/bundles/breeze-client-adapter-model-library-ko.umd.js.map +0 -1
  176. package/bundles/breeze-client-adapter-model-library-ko.umd.min.js +0 -2
  177. package/bundles/breeze-client-adapter-model-library-ko.umd.min.js.map +0 -1
  178. package/bundles/breeze-client-adapter-uri-builder-json.umd.js +0 -96
  179. package/bundles/breeze-client-adapter-uri-builder-json.umd.js.map +0 -1
  180. package/bundles/breeze-client-adapter-uri-builder-json.umd.min.js +0 -2
  181. package/bundles/breeze-client-adapter-uri-builder-json.umd.min.js.map +0 -1
  182. package/bundles/breeze-client-adapter-uri-builder-odata.umd.js +0 -262
  183. package/bundles/breeze-client-adapter-uri-builder-odata.umd.js.map +0 -1
  184. package/bundles/breeze-client-adapter-uri-builder-odata.umd.min.js +0 -2
  185. package/bundles/breeze-client-adapter-uri-builder-odata.umd.min.js.map +0 -1
  186. package/bundles/breeze-client-mixin-get-entity-graph.umd.js +0 -258
  187. package/bundles/breeze-client-mixin-get-entity-graph.umd.js.map +0 -1
  188. package/bundles/breeze-client-mixin-get-entity-graph.umd.min.js +0 -2
  189. package/bundles/breeze-client-mixin-get-entity-graph.umd.min.js.map +0 -1
  190. package/bundles/breeze-client-mixin-save-queuing.umd.js +0 -579
  191. package/bundles/breeze-client-mixin-save-queuing.umd.js.map +0 -1
  192. package/bundles/breeze-client-mixin-save-queuing.umd.min.js +0 -16
  193. package/bundles/breeze-client-mixin-save-queuing.umd.min.js.map +0 -1
  194. package/bundles/breeze-client.umd.js +0 -14231
  195. package/bundles/breeze-client.umd.js.map +0 -1
  196. package/bundles/breeze-client.umd.min.js +0 -16
  197. package/bundles/breeze-client.umd.min.js.map +0 -1
  198. package/esm2015/adapter-ajax-angularjs/adapter-ajax-angularjs.js +0 -130
  199. package/esm2015/adapter-ajax-angularjs/adapter-core.js +0 -49
  200. package/esm2015/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.js +0 -5
  201. package/esm2015/adapter-ajax-fetch/adapter-ajax-fetch.js +0 -130
  202. package/esm2015/adapter-ajax-fetch/adapter-core.js +0 -49
  203. package/esm2015/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.js +0 -5
  204. package/esm2015/adapter-ajax-httpclient/adapter-ajax-httpclient.js +0 -137
  205. package/esm2015/adapter-ajax-httpclient/adapter-core.js +0 -49
  206. package/esm2015/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.js +0 -5
  207. package/esm2015/adapter-ajax-jquery/adapter-ajax-jquery.js +0 -103
  208. package/esm2015/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.js +0 -5
  209. package/esm2015/adapter-ajax-post/adapter-ajax-post.js +0 -77
  210. package/esm2015/adapter-ajax-post/breeze-client-adapter-ajax-post.js +0 -5
  211. package/esm2015/adapter-data-service-odata/adapter-core.js +0 -49
  212. package/esm2015/adapter-data-service-odata/adapter-data-service-odata.js +0 -463
  213. package/esm2015/adapter-data-service-odata/breeze-client-adapter-data-service-odata.js +0 -5
  214. package/esm2015/adapter-data-service-webapi/adapter-data-service-webapi.js +0 -100
  215. package/esm2015/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.js +0 -5
  216. package/esm2015/adapter-model-library-backing-store/adapter-model-library-backing-store.js +0 -268
  217. package/esm2015/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.js +0 -5
  218. package/esm2015/adapter-model-library-ko/adapter-model-library-ko.js +0 -240
  219. package/esm2015/adapter-model-library-ko/breeze-client-adapter-model-library-ko.js +0 -5
  220. package/esm2015/adapter-uri-builder-json/adapter-core.js +0 -49
  221. package/esm2015/adapter-uri-builder-json/adapter-uri-builder-json.js +0 -36
  222. package/esm2015/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.js +0 -5
  223. package/esm2015/adapter-uri-builder-odata/adapter-core.js +0 -49
  224. package/esm2015/adapter-uri-builder-odata/adapter-uri-builder-odata.js +0 -192
  225. package/esm2015/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.js +0 -5
  226. package/esm2015/breeze-client.js +0 -9
  227. package/esm2015/index.js +0 -2
  228. package/esm2015/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.js +0 -5
  229. package/esm2015/mixin-get-entity-graph/mixin-get-entity-graph.js +0 -269
  230. package/esm2015/mixin-save-queuing/breeze-client-mixin-save-queuing.js +0 -5
  231. package/esm2015/mixin-save-queuing/mixin-save-queuing.js +0 -400
  232. package/esm2015/src/abstract-data-service-adapter.js +0 -327
  233. package/esm2015/src/array.js +0 -4
  234. package/esm2015/src/assert-param.js +0 -312
  235. package/esm2015/src/breeze.js +0 -85
  236. package/esm2015/src/complex-array.js +0 -119
  237. package/esm2015/src/config.js +0 -223
  238. package/esm2015/src/core.js +0 -714
  239. package/esm2015/src/csdl-metadata-parser.js +0 -385
  240. package/esm2015/src/data-service.js +0 -203
  241. package/esm2015/src/default-property-interceptor.js +0 -460
  242. package/esm2015/src/entity-aspect.js +0 -804
  243. package/esm2015/src/entity-group.js +0 -187
  244. package/esm2015/src/entity-key.js +0 -116
  245. package/esm2015/src/entity-manager.js +0 -2094
  246. package/esm2015/src/entity-metadata.js +0 -2109
  247. package/esm2015/src/entity-query.js +0 -1015
  248. package/esm2015/src/entity-state.js +0 -107
  249. package/esm2015/src/enum.js +0 -141
  250. package/esm2015/src/event.js +0 -256
  251. package/esm2015/src/interface-registry.js +0 -41
  252. package/esm2015/src/key-generator.js +0 -108
  253. package/esm2015/src/local-query-comparison-options.js +0 -65
  254. package/esm2015/src/mapping-context.js +0 -411
  255. package/esm2015/src/naming-convention.js +0 -88
  256. package/esm2015/src/observable-array.js +0 -185
  257. package/esm2015/src/predicate.js +0 -1242
  258. package/esm2015/src/primitive-array.js +0 -87
  259. package/esm2015/src/query-options.js +0 -152
  260. package/esm2015/src/relation-array.js +0 -175
  261. package/esm2015/src/save-options.js +0 -41
  262. package/esm2015/src/unattached-children-map.js +0 -58
  263. package/esm2015/src/validate.js +0 -991
  264. package/esm2015/src/validation-options.js +0 -64
  265. package/esm5/adapter-ajax-angularjs/adapter-ajax-angularjs.js +0 -132
  266. package/esm5/adapter-ajax-angularjs/adapter-core.js +0 -49
  267. package/esm5/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.js +0 -5
  268. package/esm5/adapter-ajax-fetch/adapter-ajax-fetch.js +0 -132
  269. package/esm5/adapter-ajax-fetch/adapter-core.js +0 -49
  270. package/esm5/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.js +0 -5
  271. package/esm5/adapter-ajax-httpclient/adapter-ajax-httpclient.js +0 -139
  272. package/esm5/adapter-ajax-httpclient/adapter-core.js +0 -49
  273. package/esm5/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.js +0 -5
  274. package/esm5/adapter-ajax-jquery/adapter-ajax-jquery.js +0 -105
  275. package/esm5/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.js +0 -5
  276. package/esm5/adapter-ajax-post/adapter-ajax-post.js +0 -81
  277. package/esm5/adapter-ajax-post/breeze-client-adapter-ajax-post.js +0 -5
  278. package/esm5/adapter-data-service-odata/adapter-core.js +0 -49
  279. package/esm5/adapter-data-service-odata/breeze-client-adapter-data-service-odata.js +0 -5
  280. package/esm5/adapter-data-service-webapi/adapter-data-service-webapi.js +0 -105
  281. package/esm5/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.js +0 -5
  282. package/esm5/adapter-model-library-backing-store/adapter-model-library-backing-store.js +0 -270
  283. package/esm5/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.js +0 -5
  284. package/esm5/adapter-model-library-ko/adapter-model-library-ko.js +0 -242
  285. package/esm5/adapter-model-library-ko/breeze-client-adapter-model-library-ko.js +0 -5
  286. package/esm5/adapter-uri-builder-json/adapter-core.js +0 -49
  287. package/esm5/adapter-uri-builder-json/adapter-uri-builder-json.js +0 -38
  288. package/esm5/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.js +0 -5
  289. package/esm5/adapter-uri-builder-odata/adapter-core.js +0 -49
  290. package/esm5/adapter-uri-builder-odata/adapter-uri-builder-odata.js +0 -197
  291. package/esm5/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.js +0 -5
  292. package/esm5/breeze-client.js +0 -9
  293. package/esm5/index.js +0 -2
  294. package/esm5/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.js +0 -5
  295. package/esm5/mixin-get-entity-graph/mixin-get-entity-graph.js +0 -269
  296. package/esm5/mixin-save-queuing/breeze-client-mixin-save-queuing.js +0 -5
  297. package/esm5/mixin-save-queuing/mixin-save-queuing.js +0 -412
  298. package/esm5/src/abstract-data-service-adapter.js +0 -333
  299. package/esm5/src/array.js +0 -4
  300. package/esm5/src/assert-param.js +0 -317
  301. package/esm5/src/breeze.js +0 -85
  302. package/esm5/src/complex-array.js +0 -119
  303. package/esm5/src/config.js +0 -228
  304. package/esm5/src/core.js +0 -722
  305. package/esm5/src/csdl-metadata-parser.js +0 -385
  306. package/esm5/src/data-service.js +0 -207
  307. package/esm5/src/data-type.js +0 -510
  308. package/esm5/src/default-property-interceptor.js +0 -460
  309. package/esm5/src/entity-action.js +0 -52
  310. package/esm5/src/entity-aspect.js +0 -810
  311. package/esm5/src/entity-group.js +0 -189
  312. package/esm5/src/entity-key.js +0 -118
  313. package/esm5/src/entity-manager.js +0 -2112
  314. package/esm5/src/entity-metadata.js +0 -2144
  315. package/esm5/src/entity-query.js +0 -1042
  316. package/esm5/src/entity-state.js +0 -114
  317. package/esm5/src/enum.js +0 -144
  318. package/esm5/src/event.js +0 -259
  319. package/esm5/src/interface-registry.js +0 -43
  320. package/esm5/src/key-generator.js +0 -111
  321. package/esm5/src/local-query-comparison-options.js +0 -67
  322. package/esm5/src/mapping-context.js +0 -413
  323. package/esm5/src/observable-array.js +0 -201
  324. package/esm5/src/predicate.js +0 -1307
  325. package/esm5/src/primitive-array.js +0 -87
  326. package/esm5/src/query-options.js +0 -167
  327. package/esm5/src/relation-array.js +0 -175
  328. package/esm5/src/save-options.js +0 -43
  329. package/esm5/src/unattached-children-map.js +0 -60
  330. package/esm5/src/validation-options.js +0 -66
  331. package/fesm2015/breeze-client-adapter-ajax-angularjs.js.map +0 -1
  332. package/fesm2015/breeze-client-adapter-ajax-fetch.js.map +0 -1
  333. package/fesm2015/breeze-client-adapter-ajax-httpclient.js.map +0 -1
  334. package/fesm2015/breeze-client-adapter-ajax-jquery.js.map +0 -1
  335. package/fesm2015/breeze-client-adapter-ajax-post.js.map +0 -1
  336. package/fesm2015/breeze-client-adapter-data-service-odata.js.map +0 -1
  337. package/fesm2015/breeze-client-adapter-data-service-webapi.js.map +0 -1
  338. package/fesm2015/breeze-client-adapter-model-library-backing-store.js.map +0 -1
  339. package/fesm2015/breeze-client-adapter-model-library-ko.js.map +0 -1
  340. package/fesm2015/breeze-client-adapter-uri-builder-json.js.map +0 -1
  341. package/fesm2015/breeze-client-adapter-uri-builder-odata.js.map +0 -1
  342. package/fesm2015/breeze-client-mixin-get-entity-graph.js.map +0 -1
  343. package/fesm2015/breeze-client-mixin-save-queuing.js.map +0 -1
  344. package/fesm2015/breeze-client.js.map +0 -1
  345. package/fesm5/breeze-client-adapter-ajax-angularjs.js +0 -186
  346. package/fesm5/breeze-client-adapter-ajax-angularjs.js.map +0 -1
  347. package/fesm5/breeze-client-adapter-ajax-fetch.js +0 -186
  348. package/fesm5/breeze-client-adapter-ajax-fetch.js.map +0 -1
  349. package/fesm5/breeze-client-adapter-ajax-httpclient.js +0 -193
  350. package/fesm5/breeze-client-adapter-ajax-httpclient.js.map +0 -1
  351. package/fesm5/breeze-client-adapter-ajax-jquery.js +0 -111
  352. package/fesm5/breeze-client-adapter-ajax-jquery.js.map +0 -1
  353. package/fesm5/breeze-client-adapter-ajax-post.js +0 -86
  354. package/fesm5/breeze-client-adapter-ajax-post.js.map +0 -1
  355. package/fesm5/breeze-client-adapter-data-service-odata.js +0 -523
  356. package/fesm5/breeze-client-adapter-data-service-odata.js.map +0 -1
  357. package/fesm5/breeze-client-adapter-data-service-webapi.js +0 -111
  358. package/fesm5/breeze-client-adapter-data-service-webapi.js.map +0 -1
  359. package/fesm5/breeze-client-adapter-model-library-backing-store.js +0 -276
  360. package/fesm5/breeze-client-adapter-model-library-backing-store.js.map +0 -1
  361. package/fesm5/breeze-client-adapter-model-library-ko.js +0 -248
  362. package/fesm5/breeze-client-adapter-model-library-ko.js.map +0 -1
  363. package/fesm5/breeze-client-adapter-uri-builder-json.js +0 -92
  364. package/fesm5/breeze-client-adapter-uri-builder-json.js.map +0 -1
  365. package/fesm5/breeze-client-adapter-uri-builder-odata.js +0 -250
  366. package/fesm5/breeze-client-adapter-uri-builder-odata.js.map +0 -1
  367. package/fesm5/breeze-client-mixin-get-entity-graph.js +0 -254
  368. package/fesm5/breeze-client-mixin-get-entity-graph.js.map +0 -1
  369. package/fesm5/breeze-client-mixin-save-queuing.js +0 -356
  370. package/fesm5/breeze-client-mixin-save-queuing.js.map +0 -1
  371. package/fesm5/breeze-client.js +0 -13953
  372. package/fesm5/breeze-client.js.map +0 -1
  373. package/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.metadata.json +0 -1
  374. package/mixin-get-entity-graph/package.json +0 -13
  375. package/mixin-save-queuing/breeze-client-mixin-save-queuing.metadata.json +0 -1
  376. package/mixin-save-queuing/package.json +0 -13
@@ -1,2144 +0,0 @@
1
- import { __extends } from "tslib";
2
- import { core } from './core';
3
- import { config } from './config';
4
- import { BreezeEvent } from './event';
5
- import { assertParam, assertConfig, Param } from './assert-param';
6
- import { DataType } from './data-type';
7
- import { EntityAspect, ComplexAspect } from './entity-aspect';
8
- import { EntityKey } from './entity-key';
9
- import { Validator } from './validate';
10
- import { BreezeEnum } from './enum';
11
- import { DataService } from './data-service';
12
- import { NamingConvention } from './naming-convention';
13
- import { CsdlMetadataParser } from './csdl-metadata-parser'; // TODO isolate this later;
14
- import { LocalQueryComparisonOptions } from './local-query-comparison-options';
15
- import { defaultPropertyInterceptor } from './default-property-interceptor';
16
- /**
17
- An instance of the MetadataStore contains all of the metadata about a collection of [[EntityType]]'s.
18
- MetadataStores may be shared across [[EntityManager]]'s. If an EntityManager is created without an
19
- explicit MetadataStore, the MetadataStore from the MetadataStore.defaultInstance property will be used.
20
- @dynamic
21
- **/
22
- var MetadataStore = /** @class */ (function () {
23
- /**
24
- Constructs a new MetadataStore.
25
-
26
- > let ms = new MetadataStore();
27
-
28
- The store can then be associated with an EntityManager
29
- > let entityManager = new EntityManager( {
30
- > serviceName: "breeze/NorthwindIBModel",
31
- > metadataStore: ms
32
- > });
33
-
34
- or for an existing EntityManager
35
- > // Assume em1 is an existing EntityManager
36
- > em1.setProperties( { metadataStore: ms });
37
-
38
- @param config - Configuration settings .
39
- - namingConvention - (default=NamingConvention.defaultInstance) NamingConvention to be used in mapping property names
40
- between client and server. Uses the NamingConvention.defaultInstance if not specified.
41
- - localQueryComparisonOptions - (default=LocalQueryComparisonOptions.defaultInstance) The LocalQueryComparisonOptions to be
42
- used when performing "local queries" in order to match the semantics of queries against a remote service.
43
- - serializerFn - A function that is used to mediate the serialization of instances of this type.
44
- **/
45
- function MetadataStore(config) {
46
- config = config || {};
47
- assertConfig(config)
48
- .whereParam("namingConvention").isOptional().isInstanceOf(NamingConvention).withDefault(NamingConvention.defaultInstance)
49
- .whereParam("localQueryComparisonOptions").isOptional().isInstanceOf(LocalQueryComparisonOptions).withDefault(LocalQueryComparisonOptions.defaultInstance)
50
- .whereParam("serializerFn").isOptional().isFunction()
51
- .applyAll(this);
52
- this.dataServices = []; // array of dataServices;
53
- this._resourceEntityTypeMap = {}; // key is resource name - value is qualified entityType name
54
- this._structuralTypeMap = {}; // key is qualified structuraltype name - value is structuralType. ( structural = entityType or complexType).
55
- this._shortNameMap = {}; // key is shortName, value is qualified name - does not need to be serialized.
56
- this._ctorRegistry = {}; // key is either short or qual type name - value is ctor;
57
- this._incompleteTypeMap = {}; // key is entityTypeName; value is array of nav props
58
- this._incompleteComplexTypeMap = {}; // key is complexTypeName; value is array of complexType props
59
- this._id = MetadataStore.__id++;
60
- this.metadataFetched = new BreezeEvent("metadataFetched", this);
61
- }
62
- // for debugging use the line below instead.
63
- //ctor.normalizeTypeName = function (rawTypeName) { return parseTypeName(rawTypeName).typeName; };
64
- /**
65
- General purpose property set method
66
-
67
- > // assume em1 is an EntityManager containing a number of existing entities.
68
- > em1.metadataStore.setProperties( {
69
- > version: "6.1.3",
70
- > serializerFn: function(prop, value) {
71
- > return (prop.isUnmapped) ? undefined : value;
72
- > }
73
- > )};
74
- @param config - An object containing the selected properties and values to set.
75
- **/
76
- MetadataStore.prototype.setProperties = function (config) {
77
- assertConfig(config)
78
- .whereParam("name").isString().isOptional()
79
- .whereParam("serializerFn").isFunction().isOptional()
80
- .applyAll(this);
81
- };
82
- /**
83
- Adds a DataService to this MetadataStore. If a DataService with the same serviceName is already
84
- in the MetadataStore an exception will be thrown.
85
- @param dataService - The [[DataService]] to add
86
- @param shouldOverwrite - (default=false) Permit overwrite of existing DataService rather than throw exception
87
- **/
88
- MetadataStore.prototype.addDataService = function (dataService, shouldOverwrite) {
89
- assertParam(dataService, "dataService").isInstanceOf(DataService).check();
90
- assertParam(shouldOverwrite, "shouldOverwrite").isBoolean().isOptional().check();
91
- var ix = this._getDataServiceIndex(dataService.serviceName);
92
- if (ix >= 0) {
93
- if (!!shouldOverwrite) {
94
- this.dataServices[ix] = dataService;
95
- }
96
- else {
97
- throw new Error("A dataService with this name '" + dataService.serviceName + "' already exists in this MetadataStore");
98
- }
99
- }
100
- else {
101
- this.dataServices.push(dataService);
102
- }
103
- };
104
- /** @hidden @internal */
105
- MetadataStore.prototype._getDataServiceIndex = function (serviceName) {
106
- return core.arrayIndexOf(this.dataServices, function (ds) {
107
- return ds.serviceName === serviceName;
108
- });
109
- };
110
- /**
111
- Adds an EntityType to this MetadataStore. No additional properties may be added to the EntityType after its has
112
- been added to the MetadataStore.
113
- @param structuralType - The EntityType or ComplexType to add
114
- **/
115
- MetadataStore.prototype.addEntityType = function (stype) {
116
- var structuralType;
117
- if (stype instanceof EntityType || stype instanceof ComplexType) {
118
- structuralType = stype;
119
- }
120
- else {
121
- structuralType = stype.isComplexType ? new ComplexType(stype) : new EntityType(stype);
122
- }
123
- // if (!structuralType.isComplexType) { // same as below but isn't a 'type guard'
124
- if (structuralType instanceof EntityType) {
125
- if (structuralType.baseTypeName && !structuralType.baseEntityType) {
126
- var baseEntityType = this._getStructuralType(structuralType.baseTypeName, true);
127
- // safe cast because we know that baseEntityType must be an EntityType if the structuralType is an EntityType
128
- structuralType._updateFromBase(baseEntityType);
129
- }
130
- if (structuralType.keyProperties.length === 0 && !structuralType.isAbstract) {
131
- throw new Error("Unable to add " + structuralType.name +
132
- " to this MetadataStore. An EntityType must have at least one property designated as a key property - See the 'DataProperty.isPartOfKey' property.");
133
- }
134
- }
135
- structuralType.metadataStore = this;
136
- // don't register anon types
137
- if (!structuralType.isAnonymous) {
138
- if (this._structuralTypeMap[structuralType.name]) {
139
- throw new Error("Type " + structuralType.name + " already exists in this MetadataStore.");
140
- }
141
- this._structuralTypeMap[structuralType.name] = structuralType;
142
- this._shortNameMap[structuralType.shortName] = structuralType.name;
143
- }
144
- structuralType.getProperties().forEach(function (p) {
145
- structuralType._updateNames(p);
146
- if (!p.isUnmapped) {
147
- structuralType._mappedPropertiesCount++;
148
- }
149
- });
150
- structuralType._updateCps();
151
- // 'isEntityType' is a type guard
152
- if (structuralType instanceof EntityType) {
153
- structuralType._updateNps();
154
- // give the type it's base's resource name if it doesn't have its own.
155
- var defResourceName = structuralType.defaultResourceName || (structuralType.baseEntityType && structuralType.baseEntityType.defaultResourceName);
156
- if (defResourceName && !this.getEntityTypeNameForResourceName(defResourceName)) {
157
- this.setEntityTypeForResourceName(defResourceName, structuralType.name);
158
- }
159
- structuralType.defaultResourceName = defResourceName;
160
- // check if this structural type's name, short version or qualified version has a registered ctor.
161
- structuralType.getEntityCtor();
162
- }
163
- };
164
- /**
165
- Exports this MetadataStore to a serialized string appropriate for local storage. This operation is also called
166
- internally when exporting an EntityManager.
167
- > // assume ms is a previously created MetadataStore
168
- > let metadataAsString = ms.exportMetadata();
169
- > window.localStorage.setItem("metadata", metadataAsString);
170
- > // and later, usually in a different session imported
171
- > let metadataFromStorage = window.localStorage.getItem("metadata");
172
- > let newMetadataStore = new MetadataStore();
173
- > newMetadataStore.importMetadata(metadataFromStorage);
174
- @return A serialized version of this MetadataStore that may be stored locally and later restored.
175
- **/
176
- MetadataStore.prototype.exportMetadata = function () {
177
- var result = JSON.stringify({
178
- "metadataVersion": MetadataStore.metadataVersion,
179
- "name": this.name,
180
- "namingConvention": this.namingConvention.name,
181
- "localQueryComparisonOptions": this.localQueryComparisonOptions.name,
182
- "dataServices": this.dataServices,
183
- "structuralTypes": core.objectMap(this._structuralTypeMap),
184
- "resourceEntityTypeMap": this._resourceEntityTypeMap
185
- }, null, config.stringifyPad);
186
- return result;
187
- };
188
- /**
189
- Imports a previously exported serialized MetadataStore into this MetadataStore.
190
-
191
- > // assume ms is a previously created MetadataStore
192
- > let metadataAsString = ms.exportMetadata();
193
- > window.localStorage.setItem("metadata", metadataAsString);
194
- > // and later, usually in a different session
195
- > let metadataFromStorage = window.localStorage.getItem("metadata");
196
- > let newMetadataStore = new MetadataStore();
197
- > newMetadataStore.importMetadata(metadataFromStorage);
198
- @param exportedMetadata - A previously exported MetadataStore.
199
- @param allowMerge - Allows custom metadata to be merged into existing metadata types.
200
- @return This MetadataStore.
201
- @chainable
202
- **/
203
- MetadataStore.prototype.importMetadata = function (exportedMetadata, allowMerge) {
204
- var _this = this;
205
- if (allowMerge === void 0) { allowMerge = false; }
206
- assertParam(allowMerge, "allowMerge").isOptional().isBoolean().check();
207
- this._deferredTypes = {};
208
- // insure that we don't mutate incoming exportedMetadata ( if its an object)
209
- var metadataAsString = (typeof (exportedMetadata) === "string") ? exportedMetadata : JSON.stringify(exportedMetadata);
210
- var metadataJson = JSON.parse(metadataAsString);
211
- if (metadataJson.schema) {
212
- return CsdlMetadataParser.parse(this, metadataJson.schema, metadataJson.altMetadata);
213
- }
214
- var json = metadataJson;
215
- if (json.metadataVersion && json.metadataVersion !== MetadataStore.metadataVersion) {
216
- var msg = core.formatString("Cannot import metadata with a different 'metadataVersion' (%1) than the current 'MetadataStore.metadataVersion' (%2) ", json.metadataVersion, MetadataStore.metadataVersion);
217
- throw new Error(msg);
218
- }
219
- var ncName = json.namingConvention;
220
- var lqcoName = json.localQueryComparisonOptions;
221
- if (this.isEmpty()) {
222
- this.namingConvention = config._fetchObject(NamingConvention, ncName) || this.namingConvention;
223
- this.localQueryComparisonOptions = config._fetchObject(LocalQueryComparisonOptions, lqcoName) || this.localQueryComparisonOptions;
224
- }
225
- else {
226
- if (ncName && this.namingConvention.name !== ncName) {
227
- throw new Error("Cannot import metadata with a different 'namingConvention' from the current MetadataStore");
228
- }
229
- if (lqcoName && this.localQueryComparisonOptions.name !== lqcoName) {
230
- throw new Error("Cannot import metadata with different 'localQueryComparisonOptions' from the current MetadataStore");
231
- }
232
- }
233
- //noinspection JSHint
234
- json.dataServices && json.dataServices.forEach(function (ds) {
235
- var realDs = DataService.fromJSON(ds);
236
- _this.addDataService(realDs, true);
237
- });
238
- json.structuralTypes && json.structuralTypes.forEach(function (stype) {
239
- structuralTypeFromJson(_this, stype, allowMerge);
240
- });
241
- core.extend(this._resourceEntityTypeMap, json.resourceEntityTypeMap);
242
- core.extend(this._incompleteTypeMap, json.incompleteTypeMap);
243
- return this;
244
- };
245
- /**
246
- Creates a new MetadataStore from a previously exported serialized MetadataStore
247
- > // assume ms is a previously created MetadataStore
248
- > let metadataAsString = ms.exportMetadata();
249
- > window.localStorage.setItem("metadata", metadataAsString);
250
- > // and later, usually in a different session
251
- > let metadataFromStorage = window.localStorage.getItem("metadata");
252
- > let newMetadataStore = MetadataStore.importMetadata(metadataFromStorage);
253
- @param exportedString - A previously exported MetadataStore.
254
- @return A new MetadataStore.
255
- **/
256
- MetadataStore.importMetadata = function (exportedString) {
257
- var ms = new MetadataStore();
258
- ms.importMetadata(exportedString);
259
- return ms;
260
- };
261
- /**
262
- Returns whether Metadata has been retrieved for a specified service name.
263
- > // Assume em1 is an existing EntityManager.
264
- > if (!em1.metadataStore.hasMetadataFor("breeze/NorthwindIBModel"))) {
265
- > // do something interesting
266
- > }
267
- @param serviceName - The service name.
268
- @return Whether metadata has already been retrieved for the specified service name.
269
- **/
270
- MetadataStore.prototype.hasMetadataFor = function (serviceName) {
271
- return !!this.getDataService(serviceName);
272
- };
273
- /**
274
- Returns the DataService for a specified service name
275
- > // Assume em1 is an existing EntityManager.
276
- > let ds = em1.metadataStore.getDataService("breeze/NorthwindIBModel");
277
- > let adapterName = ds.adapterName; // may be null
278
- @param serviceName - The service name.
279
- @return The DataService with the specified name.
280
- **/
281
- MetadataStore.prototype.getDataService = function (serviceName) {
282
- assertParam(serviceName, "serviceName").isString().check();
283
- serviceName = DataService._normalizeServiceName(serviceName);
284
- return core.arrayFirst(this.dataServices, function (ds) {
285
- return ds.serviceName === serviceName;
286
- });
287
- };
288
- /**
289
- Fetches the metadata for a specified 'service'. This method is automatically called
290
- internally by an EntityManager before its first query against a new service. __Async__
291
-
292
- Usually you will not actually process the results of a fetchMetadata call directly, but will instead
293
- ask for the metadata from the EntityManager after the fetchMetadata call returns.
294
- > let ms = new MetadataStore();
295
- > // or more commonly
296
- > // let ms = anEntityManager.metadataStore;
297
- > ms.fetchMetadata("breeze/NorthwindIBModel").then(function(rawMetadata) {
298
- > // do something with the metadata
299
- > }).catch(function(exception) {
300
- > // handle exception here
301
- > });
302
- @param dataService - Either a DataService or just the name of the DataService to fetch metadata for.
303
- @param callback - Function called on success.
304
- @param errorCallback - Function called on failure.
305
- @return Promise
306
- **/
307
- MetadataStore.prototype.fetchMetadata = function (dataService, callback, errorCallback) {
308
- var _this = this;
309
- try {
310
- assertParam(dataService, "dataService").isString().or().isInstanceOf(DataService).check();
311
- assertParam(callback, "callback").isFunction().isOptional().check();
312
- assertParam(errorCallback, "errorCallback").isFunction().isOptional().check();
313
- if (typeof dataService === "string") {
314
- // use the dataService with a matching name or create a new one.
315
- dataService = this.getDataService(dataService) || new DataService({ serviceName: dataService });
316
- }
317
- dataService = DataService.resolve([dataService]);
318
- if (this.hasMetadataFor(dataService.serviceName)) {
319
- throw new Error("Metadata for a specific serviceName may only be fetched once per MetadataStore. ServiceName: " + dataService.serviceName);
320
- }
321
- return dataService.adapterInstance.fetchMetadata(this, dataService).then(function (rawMetadata) {
322
- _this.metadataFetched.publish({ metadataStore: _this, dataService: dataService, rawMetadata: rawMetadata });
323
- if (callback)
324
- callback(rawMetadata);
325
- return Promise.resolve(rawMetadata);
326
- }, function (error) {
327
- if (errorCallback)
328
- errorCallback(error);
329
- return Promise.reject(error);
330
- });
331
- }
332
- catch (e) {
333
- return Promise.reject(e);
334
- }
335
- };
336
- // TODO: strongly type interceptor below.
337
- /**
338
- Used to register a constructor for an EntityType that is not known via standard Metadata discovery;
339
- i.e. an unmapped type.
340
- @param entityCtor - The constructor function for the 'unmapped' type.
341
- @param interceptor - An interceptor function
342
- **/
343
- MetadataStore.prototype.trackUnmappedType = function (entityCtor, interceptor) {
344
- assertParam(entityCtor, "entityCtor").isFunction().check();
345
- assertParam(interceptor, "interceptor").isFunction().isOptional().check();
346
- // TODO: think about adding this to the MetadataStore.
347
- var entityType = new EntityType(this);
348
- entityType._setCtor(entityCtor, interceptor);
349
- };
350
- /**
351
- Provides a mechanism to register a 'custom' constructor to be used when creating new instances
352
- of the specified entity type. If this call is not made, a default constructor is created for
353
- the entity as needed.
354
- This call may be made before or after the corresponding EntityType has been discovered via
355
- Metadata discovery.
356
- > let Customer = function () {
357
- > this.miscData = "asdf";
358
- > };
359
- > Customer.prototype.doFoo() {
360
- > ...
361
- > }
362
- > // assume em1 is a preexisting EntityManager;
363
- > em1.metadataStore.registerEntityTypeCtor("Customer", Customer);
364
- > // any queries or EntityType.create calls from this point on will call the Customer constructor
365
- > // registered above.
366
- @param structuralTypeName - The name of the EntityType or ComplexType.
367
- @param aCtor - The constructor for this EntityType or ComplexType; may be null if all you want to do is set the next parameter.
368
- @param initFn - A function or the name of a function on the entity that is to be executed immediately after the entity has been created
369
- and populated with any initial values. Called with 'initFn(entity)'
370
- @param noTrackingFn - A function that is executed immediately after a noTracking entity has been created and whose return
371
- value will be used in place of the noTracking entity.
372
- **/
373
- MetadataStore.prototype.registerEntityTypeCtor = function (structuralTypeName, aCtor, initFn, noTrackingFn) {
374
- assertParam(structuralTypeName, "structuralTypeName").isString().check();
375
- assertParam(aCtor, "aCtor").isFunction().isOptional().check();
376
- assertParam(initFn, "initFn").isOptional().isFunction().or().isString().check();
377
- assertParam(noTrackingFn, "noTrackingFn").isOptional().isFunction().check();
378
- var qualifiedTypeName = getQualifiedTypeName(this, structuralTypeName, false);
379
- var typeName = qualifiedTypeName || structuralTypeName;
380
- if (aCtor) {
381
- if (aCtor._$typeName && aCtor._$typeName !== typeName) {
382
- // TODO: wrap this - console and especially console.warn does not exist in all browsers.
383
- console.warn("Registering a constructor for " + typeName + " that is already used for " + aCtor._$typeName + ".");
384
- }
385
- aCtor._$typeName = typeName;
386
- }
387
- this._ctorRegistry[typeName] = { ctor: aCtor, initFn: initFn, noTrackingFn: noTrackingFn };
388
- if (qualifiedTypeName) {
389
- var stype = this._structuralTypeMap[qualifiedTypeName];
390
- stype && stype.getCtor(true); // this will complete the registration if avail now.
391
- }
392
- };
393
- /**
394
- Returns whether this MetadataStore contains any metadata yet.
395
- > // assume em1 is a preexisting EntityManager;
396
- > if (em1.metadataStore.isEmpty()) {
397
- > // do something interesting
398
- > }
399
- **/
400
- MetadataStore.prototype.isEmpty = function () {
401
- return core.isEmpty(this._structuralTypeMap);
402
- };
403
- /**
404
- Returns an [[EntityType]] or null given its name.
405
- > // assume em1 is a preexisting EntityManager
406
- > let odType = em1.metadataStore.getAsEntityType("OrderDetail");
407
-
408
- or to throw an error if the type is not found
409
- > let badType = em1.metadataStore.getAsEntityType("Foo", false);
410
- > // badType will not get set and an exception will be thrown.
411
- @param structuralTypeName - Either the fully qualified name or a short name may be used. If a short name is specified and multiple types share
412
- that same short name an exception will be thrown.
413
- @param okIfNotFound - (default=false) Whether to throw an error if the specified EntityType is not found.
414
- @return The EntityType. ComplexType or 'null' if not not found.
415
- **/
416
- MetadataStore.prototype.getAsEntityType = function (typeName, okIfNotFound) {
417
- if (okIfNotFound === void 0) { okIfNotFound = false; }
418
- var st = this.getStructuralType(typeName, okIfNotFound);
419
- if (st instanceof EntityType) {
420
- return st;
421
- }
422
- else if (okIfNotFound) {
423
- return null;
424
- }
425
- else {
426
- var msg = core.formatString("Unable to locate an 'EntityType' by the name: '%1'. Be sure to execute a query or call fetchMetadata first.", typeName);
427
- throw new Error(msg);
428
- }
429
- };
430
- /**
431
- Returns an [[EntityType]] or null given its name.
432
- > // assume em1 is a preexisting EntityManager
433
- > let locType = em1.metadataStore.getAsComplexType("Location");
434
-
435
- or to throw an error if the type is not found
436
- > let badType = em1.metadataStore.getAsComplexType("Foo", false);
437
- > // badType will not get set and an exception will be thrown.
438
- @param structuralTypeName - Either the fully qualified name or a short name may be used. If a short name is specified and multiple types share
439
- that same short name an exception will be thrown.
440
- @param okIfNotFound - (default=false) Whether to throw an error if the specified EntityType is not found.
441
- @return The EntityType. ComplexType or 'null' if not not found.
442
- **/
443
- MetadataStore.prototype.getAsComplexType = function (typeName, okIfNotFound) {
444
- if (okIfNotFound === void 0) { okIfNotFound = false; }
445
- var st = this.getStructuralType(typeName, okIfNotFound);
446
- if (st instanceof ComplexType) {
447
- return st;
448
- }
449
- else if (okIfNotFound) {
450
- return null;
451
- }
452
- else {
453
- var msg = core.formatString("Unable to locate an 'ComplexType' by the name: '%1'. Be sure to execute a query or call fetchMetadata first.", typeName);
454
- throw new Error(msg);
455
- }
456
- };
457
- /**
458
- Returns an [[EntityType]] or a [[ComplexType]] given its name.
459
- @deprecated Replaced by getStructuralType but ... it is probably more usefull to call either getAsEntityType or getAsComplexType instead
460
- @param typeName - Either the fully qualified name or a short name may be used. If a short name is specified and multiple types share
461
- that same short name an exception will be thrown.
462
- @param okIfNotFound - (default=false) Whether to throw an error if the specified EntityType is not found.
463
- @return The EntityType. ComplexType or 'null' if not not found.
464
- **/
465
- MetadataStore.prototype.getEntityType = function (typeName, okIfNotFound) {
466
- if (okIfNotFound === void 0) { okIfNotFound = false; }
467
- return this.getStructuralType(typeName, okIfNotFound);
468
- };
469
- /**
470
- Returns an [[EntityType]] or a [[ComplexType]] given its name.
471
- > // assume em1 is a preexisting EntityManager
472
- > let odType = em1.metadataStore.getStructuralType("OrderDetail");
473
-
474
- or to throw an error if the type is not found
475
- > let badType = em1.metadataStore.getStructuralType("Foo", false);
476
- > // badType will not get set and an exception will be thrown.
477
- @deprecated Preferably use either getAsEntityType or getAsComplexType. Get
478
- @param typeName - Either the fully qualified name or a short name may be used. If a short name is specified and multiple types share
479
- that same short name an exception will be thrown.
480
- @param okIfNotFound - (default=false) Whether to throw an error if the specified EntityType is not found.
481
- @return The EntityType. ComplexType or 'null' if not not found.
482
- **/
483
- MetadataStore.prototype.getStructuralType = function (typeName, okIfNotFound) {
484
- if (okIfNotFound === void 0) { okIfNotFound = false; }
485
- assertParam(typeName, "typeName").isString().check();
486
- assertParam(okIfNotFound, "okIfNotFound").isBoolean().isOptional().check(false);
487
- return this._getStructuralType(typeName, okIfNotFound);
488
- };
489
- /** @hidden @internal */
490
- MetadataStore.prototype._getStructuralType = function (typeName, okIfNotFound) {
491
- if (okIfNotFound === void 0) { okIfNotFound = false; }
492
- var qualTypeName = getQualifiedTypeName(this, typeName, false);
493
- var type = this._structuralTypeMap[qualTypeName];
494
- if (!type) {
495
- if (okIfNotFound)
496
- return null;
497
- var msg = core.formatString("Unable to locate a 'Type' by the name: '%1'. Be sure to execute a query or call fetchMetadata first.", typeName);
498
- throw new Error(msg);
499
- }
500
- return type;
501
- };
502
- /**
503
- Returns an array containing all of the [[EntityType]]s or [[ComplexType]]s in this MetadataStore.
504
- > // assume em1 is a preexisting EntityManager
505
- > let allTypes = em1.metadataStore.getEntityTypes();
506
- **/
507
- MetadataStore.prototype.getEntityTypes = function () {
508
- return getTypesFromMap(this._structuralTypeMap);
509
- };
510
- MetadataStore.prototype.getIncompleteNavigationProperties = function () {
511
- return core.objectMap(this._incompleteTypeMap, function (key, value) {
512
- return value;
513
- });
514
- };
515
- /**
516
- Returns a fully qualified entityTypeName for a specified resource name. The reverse of this operation
517
- can be obtained via the [[EntityType.defaultResourceName]] property
518
- **/
519
- MetadataStore.prototype.getEntityTypeNameForResourceName = function (resourceName) {
520
- assertParam(resourceName, "resourceName").isString().check();
521
- return this._resourceEntityTypeMap[resourceName];
522
- };
523
- /**
524
- Associates a resourceName with an entityType.
525
-
526
- This method is only needed in those cases where multiple resources return the same
527
- entityType. In this case Metadata discovery will only determine a single resource name for
528
- each entityType.
529
- @param resourceName - The resource name
530
- @param entityTypeOrName - If passing a string either the fully qualified name or a short name may be used. If a short name is specified and multiple types share
531
- that same short name an exception will be thrown. If the entityType has not yet been discovered then a fully qualified name must be used.
532
- **/
533
- MetadataStore.prototype.setEntityTypeForResourceName = function (resourceName, entityTypeOrName) {
534
- assertParam(resourceName, "resourceName").isString().check();
535
- assertParam(entityTypeOrName, "entityTypeOrName").isInstanceOf(EntityType).or().isString().check();
536
- var entityTypeName;
537
- if (entityTypeOrName instanceof EntityType) {
538
- entityTypeName = entityTypeOrName.name;
539
- }
540
- else {
541
- entityTypeName = getQualifiedTypeName(this, entityTypeOrName, true);
542
- }
543
- this._resourceEntityTypeMap[resourceName] = entityTypeName;
544
- var entityType = this._getStructuralType(entityTypeName, true);
545
- if (entityType && entityType instanceof EntityType && !entityType.defaultResourceName) {
546
- entityType.defaultResourceName = resourceName;
547
- }
548
- };
549
- /** __Dev Only__ - for use when creating a new MetadataParserAdapter */
550
- MetadataStore.parseTypeName = function (entityTypeName) {
551
- // TODO: removed
552
- // if (!entityTypeName) {
553
- // return null;
554
- // }
555
- var typeParts = entityTypeName.split(":#");
556
- if (typeParts.length > 1) {
557
- return MetadataStore.makeTypeHash(typeParts[0], typeParts[1]);
558
- }
559
- if (core.stringStartsWith(entityTypeName, MetadataStore.ANONTYPE_PREFIX)) {
560
- var typeHash = MetadataStore.makeTypeHash(entityTypeName);
561
- typeHash.isAnonymous = true;
562
- return typeHash;
563
- }
564
- var entityTypeNameNoAssembly = entityTypeName.split(",")[0];
565
- typeParts = entityTypeNameNoAssembly.split(".");
566
- if (typeParts.length > 1) {
567
- var shortName = typeParts[typeParts.length - 1];
568
- var namespaceParts = typeParts.slice(0, typeParts.length - 1);
569
- var ns = namespaceParts.join(".");
570
- return MetadataStore.makeTypeHash(shortName, ns);
571
- }
572
- else {
573
- return MetadataStore.makeTypeHash(entityTypeName);
574
- }
575
- };
576
- /** __Dev Only__ - for use when creating a new MetadataParserAdapter */
577
- MetadataStore.makeTypeHash = function (shortName, ns) {
578
- return {
579
- shortTypeName: shortName,
580
- namespace: ns,
581
- typeName: qualifyTypeName(shortName, ns)
582
- };
583
- };
584
- // protected methods
585
- /** @hidden @internal */
586
- MetadataStore.prototype._checkEntityType = function (entity) {
587
- if (entity.entityType)
588
- return;
589
- var typeName = entity.prototype._$typeName;
590
- if (!typeName) {
591
- throw new Error("This entity has not been registered. See the MetadataStore.registerEntityTypeCtor method");
592
- }
593
- // we know that it is an EntityType ( as opposed to a ComplexType)
594
- var entityType = this._getStructuralType(typeName);
595
- if (entityType) {
596
- entity.entityType = entityType;
597
- }
598
- };
599
- /** @hidden @internal */
600
- MetadataStore.__id = 0;
601
- /** @hidden @internal */
602
- MetadataStore.ANONTYPE_PREFIX = "_IB_";
603
- /** The version of any MetadataStores created by this class */
604
- MetadataStore.metadataVersion = '1.0.5';
605
- // needs to be made avail to dataService.xxx files
606
- MetadataStore.normalizeTypeName = core.memoize(function (rawTypeName) {
607
- return rawTypeName && MetadataStore.parseTypeName(rawTypeName).typeName;
608
- });
609
- return MetadataStore;
610
- }());
611
- export { MetadataStore };
612
- MetadataStore.prototype._$typeName = "MetadataStore";
613
- BreezeEvent.bubbleEvent(MetadataStore.prototype);
614
- function getTypesFromMap(typeMap) {
615
- var types = [];
616
- for (var key in typeMap) {
617
- var value = typeMap[key];
618
- // skip 'shortName' entries
619
- if (key === value.name) {
620
- types.push(typeMap[key]);
621
- }
622
- }
623
- return types;
624
- }
625
- function structuralTypeFromJson(metadataStore, json, allowMerge) {
626
- var typeName = qualifyTypeName(json.shortName, json.namespace);
627
- var stype = metadataStore._getStructuralType(typeName, true);
628
- if (stype) {
629
- if (allowMerge) {
630
- return mergeStructuralType(stype, json);
631
- }
632
- else {
633
- // allow it but don't replace anything.
634
- return stype;
635
- }
636
- }
637
- var config = {
638
- shortName: json.shortName,
639
- namespace: json.namespace,
640
- isAbstract: json.isAbstract,
641
- autoGeneratedKeyType: AutoGeneratedKeyType.fromName(json.autoGeneratedKeyType),
642
- defaultResourceName: json.defaultResourceName,
643
- custom: json.custom
644
- };
645
- stype = json.isComplexType ? new ComplexType(config) : new EntityType(config);
646
- // baseType may not have been imported yet so we need to defer handling this type until later.
647
- if (json.baseTypeName && stype instanceof EntityType) {
648
- stype.baseTypeName = json.baseTypeName;
649
- var baseEntityType = metadataStore._getStructuralType(json.baseTypeName, true);
650
- if (baseEntityType) {
651
- completeStructuralTypeFromJson(metadataStore, json, stype);
652
- }
653
- else {
654
- core.getArray(metadataStore._deferredTypes, json.baseTypeName).push({ json: json, stype: stype });
655
- }
656
- }
657
- else {
658
- completeStructuralTypeFromJson(metadataStore, json, stype);
659
- }
660
- // stype may or may not have been added to the metadataStore at this point.
661
- return stype;
662
- }
663
- function mergeStructuralType(stype, json) {
664
- if (json.custom) {
665
- stype.custom = json.custom;
666
- }
667
- mergeProps(stype, json.dataProperties);
668
- mergeProps(stype, json.navigationProperties);
669
- return stype;
670
- }
671
- function mergeProps(stype, jsonProps) {
672
- if (!jsonProps)
673
- return;
674
- jsonProps.forEach(function (jsonProp) {
675
- var propName = jsonProp.name;
676
- if (!propName) {
677
- if (jsonProp.nameOnServer) {
678
- propName = stype.metadataStore.namingConvention.serverPropertyNameToClient(jsonProp.nameOnServer, {});
679
- }
680
- else {
681
- // backslash-quote works around compiler bug
682
- var msg = "Unable to complete \'importMetadata\' - cannot locate a \'name\' or \'nameOnServer\' for one of the imported property nodes";
683
- throw new Error(msg);
684
- }
685
- }
686
- if (jsonProp.custom) {
687
- var prop = stype.getProperty(propName, true);
688
- prop.custom = jsonProp.custom;
689
- }
690
- });
691
- }
692
- function completeStructuralTypeFromJson(metadataStore, json, stype) {
693
- // validators from baseType work because validation walks thru base types
694
- // so no need to copy down.
695
- if (json.validators) {
696
- stype.validators = json.validators.map(Validator.fromJSON);
697
- }
698
- json.dataProperties.forEach(function (dp) {
699
- stype._addPropertyCore(DataProperty.fromJSON(dp));
700
- });
701
- var isEntityType = !json.isComplexType;
702
- if (isEntityType) {
703
- //noinspection JSHint
704
- json.navigationProperties && json.navigationProperties.forEach(function (np) {
705
- stype._addPropertyCore(NavigationProperty.fromJSON(np));
706
- });
707
- }
708
- metadataStore.addEntityType(stype);
709
- var deferredTypes = metadataStore._deferredTypes;
710
- var deferrals = deferredTypes[stype.name];
711
- if (deferrals) {
712
- deferrals.forEach(function (d) {
713
- completeStructuralTypeFromJson(metadataStore, d.json, d.stype);
714
- });
715
- delete deferredTypes[stype.name];
716
- }
717
- }
718
- function getQualifiedTypeName(metadataStore, structTypeName, throwIfNotFound) {
719
- if (isQualifiedTypeName(structTypeName))
720
- return structTypeName;
721
- var result = metadataStore._shortNameMap[structTypeName];
722
- if (!result && throwIfNotFound) {
723
- throw new Error("Unable to locate 'entityTypeName' of: " + structTypeName);
724
- }
725
- return result;
726
- }
727
- /** Container for all of the metadata about a specific type of Entity.
728
- **/
729
- var EntityType = /** @class */ (function () {
730
- /** EntityType constructor
731
- > let entityType = new EntityType( {
732
- > shortName: "person",
733
- > namespace: "myAppNamespace"
734
- > });
735
- @param config - Configuration settings or a MetadataStore. If this parameter is just a MetadataStore
736
- then what will be created is an 'anonymous' type that will never be communicated to or from the server. It is purely for
737
- client side use and will be given an automatically generated name. Normally, however, you will use a configuration object.
738
- **/
739
- function EntityType(config) {
740
- /** Always false for an EntityType. **/
741
- this.isComplexType = false;
742
- /**
743
- @deprecated Use [[getCtor]] instead.
744
- */
745
- this.getEntityCtor = this.getCtor;
746
- if (arguments.length > 1) {
747
- throw new Error("The EntityType ctor has a single argument that is either a 'MetadataStore' or a configuration object.");
748
- }
749
- // let etConfig = <EntityTypeConfig> <any> undefined;
750
- var etConfig = undefined;
751
- if (config._$typeName === "MetadataStore") {
752
- this.metadataStore = config;
753
- this.shortName = "Anon_" + (++EntityType.__nextAnonIx);
754
- this.namespace = "";
755
- this.isAnonymous = true;
756
- // etConfig = undefined;
757
- }
758
- else {
759
- etConfig = config;
760
- assertConfig(config)
761
- .whereParam("shortName").isNonEmptyString()
762
- .whereParam("namespace").isString().isOptional().withDefault("")
763
- .whereParam("baseTypeName").isString().isOptional()
764
- .whereParam("isAbstract").isBoolean().isOptional().withDefault(false)
765
- .whereParam("autoGeneratedKeyType").isEnumOf(AutoGeneratedKeyType).isOptional().withDefault(AutoGeneratedKeyType.None)
766
- .whereParam("defaultResourceName").isNonEmptyString().isOptional().withDefault(null)
767
- .whereParam("dataProperties").isOptional()
768
- .whereParam("navigationProperties").isOptional()
769
- .whereParam("serializerFn").isOptional().isFunction()
770
- .whereParam("custom").isOptional()
771
- .applyAll(this);
772
- }
773
- this.name = qualifyTypeName(this.shortName, this.namespace);
774
- // the defaultResourceName may also be set up either via metadata lookup or first query or via the 'setProperties' method
775
- this.dataProperties = [];
776
- this.navigationProperties = [];
777
- this.complexProperties = [];
778
- this.keyProperties = [];
779
- this.foreignKeyProperties = [];
780
- this.inverseForeignKeyProperties = [];
781
- this.concurrencyProperties = [];
782
- this.unmappedProperties = []; // will be updated later.
783
- this.validators = [];
784
- this.warnings = [];
785
- this._mappedPropertiesCount = 0;
786
- this.subtypes = [];
787
- // now process any data/nav props
788
- if (etConfig && etConfig.dataProperties) {
789
- addProperties(this, etConfig.dataProperties, DataProperty);
790
- }
791
- if (etConfig && etConfig.navigationProperties) {
792
- addProperties(this, etConfig.navigationProperties, NavigationProperty);
793
- }
794
- }
795
- /**
796
- General purpose property set method
797
- > // assume em1 is an EntityManager containing a number of existing entities.
798
- > let custType = em1.metadataStore.getEntityType("Customer");
799
- > custType.setProperties( {
800
- > autoGeneratedKeyType: AutoGeneratedKeyType.Identity;
801
- > defaultResourceName: "CustomersAndIncludedOrders"
802
- > )};
803
- @param config - a configuration object
804
- **/
805
- EntityType.prototype.setProperties = function (config) {
806
- assertConfig(config)
807
- .whereParam("autoGeneratedKeyType").isEnumOf(AutoGeneratedKeyType).isOptional()
808
- .whereParam("defaultResourceName").isString().isOptional()
809
- .whereParam("serializerFn").isFunction().isOptional()
810
- .whereParam("custom").isOptional()
811
- .applyAll(this);
812
- if (config.defaultResourceName) {
813
- this.defaultResourceName = config.defaultResourceName;
814
- }
815
- };
816
- /**
817
- Returns whether this type is a subtype of a specified type.
818
- **/
819
- EntityType.prototype.isSubtypeOf = function (entityType) {
820
- assertParam(entityType, "entityType").isInstanceOf(EntityType).check();
821
- var baseType = this;
822
- do {
823
- if (baseType === entityType)
824
- return true;
825
- baseType = baseType.baseEntityType;
826
- } while (baseType);
827
- return false;
828
- };
829
- /**
830
- Returns an array containing this type and any/all subtypes of this type down thru the hierarchy.
831
- **/
832
- EntityType.prototype.getSelfAndSubtypes = function () {
833
- var result = [this];
834
- this.subtypes.forEach(function (st) {
835
- var subtypes = st.getSelfAndSubtypes();
836
- result.push.apply(result, subtypes);
837
- });
838
- return result;
839
- };
840
- EntityType.prototype.getAllValidators = function () {
841
- var result = this.validators.slice(0);
842
- var bt = this.baseEntityType;
843
- while (bt) {
844
- result.push.apply(result, bt.validators);
845
- bt = bt.baseEntityType;
846
- }
847
- return result;
848
- };
849
- /**
850
- Adds a [[DataProperty]] or a [[NavigationProperty]] to this EntityType.
851
- > // assume myEntityType is a newly constructed EntityType.
852
- > myEntityType.addProperty(dataProperty1);
853
- > myEntityType.addProperty(dataProperty2);
854
- > myEntityType.addProperty(navigationProperty1);
855
- **/
856
- EntityType.prototype.addProperty = function (property) {
857
- assertParam(property, "property").isInstanceOf(DataProperty).or().isInstanceOf(NavigationProperty).check();
858
- // true is 2nd arg to force resolve of any navigation properties.
859
- var newprop = this._addPropertyCore(property, true);
860
- if (this.subtypes && this.subtypes.length) {
861
- var stype_1 = this;
862
- stype_1.getSelfAndSubtypes().forEach(function (st) {
863
- if (st !== stype_1) {
864
- if (property.isNavigationProperty) {
865
- st._addPropertyCore(new NavigationProperty(property), true);
866
- }
867
- else {
868
- st._addPropertyCore(new DataProperty(property), true);
869
- }
870
- }
871
- });
872
- }
873
- return newprop;
874
- };
875
- /** @hidden @internal */
876
- EntityType.prototype._updateFromBase = function (baseEntityType) {
877
- var _this = this;
878
- this.baseEntityType = baseEntityType;
879
- if (this.autoGeneratedKeyType === AutoGeneratedKeyType.None) {
880
- this.autoGeneratedKeyType = baseEntityType.autoGeneratedKeyType;
881
- }
882
- baseEntityType.dataProperties.forEach(function (dp) {
883
- var newDp = new DataProperty(dp);
884
- // don't need to copy validators becaue we will walk the hierarchy to find them
885
- newDp.validators = [];
886
- newDp.baseProperty = dp;
887
- _this._addPropertyCore(newDp);
888
- }, this);
889
- baseEntityType.navigationProperties.forEach(function (np) {
890
- var newNp = new NavigationProperty(np);
891
- // don't need to copy validators becaue we will walk the hierarchy to find them
892
- newNp.validators = [];
893
- newNp.baseProperty = np;
894
- _this._addPropertyCore(newNp);
895
- }, this);
896
- baseEntityType.subtypes.push(this);
897
- };
898
- /** @hidden @internal */
899
- EntityType.prototype._addPropertyCore = function (property, shouldResolve) {
900
- if (shouldResolve === void 0) { shouldResolve = false; }
901
- if (this.isFrozen) {
902
- throw new Error("The '" + this.name + "' EntityType/ComplexType has been frozen. You can only add properties to an EntityType/ComplexType before any instances of that type have been created and attached to an entityManager.");
903
- }
904
- var parentType = property.parentType;
905
- if (parentType) {
906
- if (parentType !== this) {
907
- throw new Error("This property: " + property.name + " has already been added to " + property.parentType.name);
908
- }
909
- else {
910
- // adding the same property more than once to the same entityType is just ignored.
911
- return;
912
- }
913
- }
914
- property.parentType = this;
915
- var ms = this.metadataStore;
916
- // if (property.isDataProperty) { // modified because doesn't act as a type guard
917
- if (property instanceof DataProperty) {
918
- this._addDataProperty(property);
919
- }
920
- else {
921
- this._addNavigationProperty(property);
922
- // metadataStore can be undefined if this entityType has not yet been added to a MetadataStore.
923
- if (shouldResolve && ms) {
924
- tryResolveNp(property, ms);
925
- }
926
- }
927
- // unmapped properties can be added AFTER entityType has already resolved all property names.
928
- if (ms && !(property.name && property.nameOnServer)) {
929
- updateClientServerNames(ms.namingConvention, property, "name");
930
- }
931
- // props can be added after entity prototype has already been wrapped.
932
- if (ms && this._extra) {
933
- if (this._extra.alreadyWrappedProps) {
934
- var proto_1 = this._ctor.prototype;
935
- config.interfaceRegistry.modelLibrary.getDefaultInstance().initializeEntityPrototype(proto_1);
936
- }
937
- }
938
- };
939
- /**
940
- Create a new entity of this type.
941
- > // assume em1 is an EntityManager containing a number of existing entities.
942
- > let custType = em1.metadataStore.getAsEntityType("Customer");
943
- > let cust1 = custType.createEntity();
944
- > em1.addEntity(cust1);
945
- @param initialValues- Configuration object of the properties to set immediately after creation.
946
- @return The new entity.
947
- **/
948
- EntityType.prototype.createEntity = function (initialValues) {
949
- // ignore the _$eref once the entity is attached to an entityManager.
950
- if (initialValues && initialValues._$eref && !initialValues._$eref.entityAspect.entityManager)
951
- return initialValues._$eref;
952
- var instance = this._createInstanceCore();
953
- if (initialValues) {
954
- // only assign an _eref if the object is fully "keyed"
955
- if (this.keyProperties.every(function (kp) {
956
- return initialValues[kp.name] != null;
957
- })) {
958
- initialValues._$eref = instance;
959
- }
960
- this._updateTargetFromRaw(instance, initialValues, getRawValueFromConfig);
961
- this.navigationProperties.forEach(function (np) {
962
- var relatedEntity;
963
- var val = initialValues[np.name];
964
- if (val != undefined) {
965
- var navEntityType_1 = np.entityType;
966
- if (np.isScalar) {
967
- relatedEntity = val.entityAspect ? val : navEntityType_1.createEntity(val);
968
- instance.setProperty(np.name, relatedEntity);
969
- }
970
- else {
971
- var relatedEntities_1 = instance.getProperty(np.name);
972
- val.forEach(function (v) {
973
- relatedEntity = v.entityAspect ? v : navEntityType_1.createEntity(v);
974
- relatedEntities_1.push(relatedEntity);
975
- });
976
- }
977
- }
978
- });
979
- }
980
- this._initializeInstance(instance);
981
- return instance;
982
- };
983
- /** @hidden @internal */
984
- EntityType.prototype._createInstanceCore = function () {
985
- var aCtor = this.getCtor();
986
- var instance = new aCtor();
987
- new EntityAspect(instance);
988
- return instance;
989
- };
990
- /** @hidden @internal */
991
- EntityType.prototype._initializeInstance = function (instance) {
992
- if (this.baseEntityType) {
993
- this.baseEntityType._initializeInstance(instance);
994
- }
995
- var initFn = this.initFn;
996
- if (initFn) {
997
- var fn = (typeof initFn === "string") ? instance[initFn] : initFn;
998
- fn(instance);
999
- }
1000
- this.complexProperties && this.complexProperties.forEach(function (cp) {
1001
- var complexType = cp.dataType;
1002
- var ctInstance = instance.getProperty(cp.name);
1003
- if (Array.isArray(ctInstance)) {
1004
- ctInstance.forEach(function (ctInst) {
1005
- complexType._initializeInstance(ctInst);
1006
- });
1007
- }
1008
- else {
1009
- complexType._initializeInstance(ctInstance);
1010
- }
1011
- });
1012
- // not needed for complexObjects
1013
- if (instance.entityAspect) {
1014
- instance.entityAspect._initialized = true;
1015
- }
1016
- };
1017
- /**
1018
- Returns the constructor for this EntityType.
1019
- @param forceRefresh - Whether to ignore any cached version of this constructor. (default == false)
1020
- @return The constructor for this EntityType.
1021
- **/
1022
- EntityType.prototype.getCtor = function (forceRefresh) {
1023
- if (forceRefresh === void 0) { forceRefresh = false; }
1024
- if (this._ctor && !forceRefresh)
1025
- return this._ctor;
1026
- var ctorRegistry = this.metadataStore._ctorRegistry;
1027
- var r = ctorRegistry[this.name] || ctorRegistry[this.shortName] || {};
1028
- var aCtor = r.ctor || this._ctor;
1029
- var ctorType = aCtor && aCtor.prototype && (aCtor.prototype.entityType || aCtor.prototype.complexType);
1030
- if (ctorType && ctorType.metadataStore !== this.metadataStore) {
1031
- // We can't risk a mismatch between the ctor and the type info in a specific metadatastore
1032
- // because modelLibraries rely on type info to intercept ctor properties
1033
- throw new Error("Cannot register the same constructor for " + this.name + " in different metadata stores. Please define a separate constructor for each metadata store.");
1034
- }
1035
- if (r.ctor && forceRefresh) {
1036
- this._extra = undefined;
1037
- }
1038
- if (!aCtor) {
1039
- var createCtor = config.interfaceRegistry.modelLibrary.getDefaultInstance().createCtor;
1040
- aCtor = createCtor ? createCtor(this) : createEmptyCtor(this);
1041
- }
1042
- this.initFn = r.initFn;
1043
- this.noTrackingFn = r.noTrackingFn;
1044
- aCtor.prototype._$typeName = this.name;
1045
- this._setCtor(aCtor);
1046
- return aCtor;
1047
- };
1048
- /** @hidden @internal */
1049
- // May make public later.
1050
- EntityType.prototype._setCtor = function (aCtor, interceptor) {
1051
- var instanceProto = aCtor.prototype;
1052
- // place for extra breeze related data
1053
- this._extra = this._extra || {};
1054
- var instance = new aCtor();
1055
- calcUnmappedProperties(this, instance);
1056
- if (this._$typeName === "EntityType") {
1057
- // insure that all of the properties are on the 'template' instance before watching the class.
1058
- instanceProto.entityType = this;
1059
- }
1060
- else {
1061
- instanceProto.complexType = this;
1062
- }
1063
- // defaultPropertyInterceptor is a 'global' (but internal to breeze) function;
1064
- instanceProto._$interceptor = interceptor || defaultPropertyInterceptor;
1065
- config.interfaceRegistry.modelLibrary.getDefaultInstance().initializeEntityPrototype(instanceProto);
1066
- this._ctor = aCtor;
1067
- };
1068
- /**
1069
- Adds either an entity or property level validator to this EntityType.
1070
- > // assume em1 is an EntityManager containing a number of existing entities.
1071
- > let custType = em1.metadataStore.getEntityType("Customer");
1072
- > let countryProp = custType.getProperty("Country");
1073
- > let valFn = function (v) {
1074
- > if (v == null) return true;
1075
- > return (core.stringStartsWith(v, "US"));
1076
- > };
1077
- > let countryValidator = new Validator("countryIsUS", valFn,
1078
- > { displayName: "Country", messageTemplate: "'%displayName%' must start with 'US'" });
1079
- > custType.addValidator(countryValidator, countryProp);
1080
-
1081
- This is the same as adding an entity level validator via the 'validators' property of DataProperty or NavigationProperty
1082
- > countryProp.validators.push(countryValidator);
1083
-
1084
- Entity level validators can also be added by omitting the 'property' parameter.
1085
- > custType.addValidator(someEntityLevelValidator);
1086
-
1087
- or
1088
- > custType.validators.push(someEntityLevelValidator);
1089
- @param validator - Validator to add.
1090
- @param property - Property to add this validator to. If omitted, the validator is assumed to be an
1091
- entity level validator and is added to the EntityType's 'validators'.
1092
- **/
1093
- EntityType.prototype.addValidator = function (validator, property) {
1094
- assertParam(validator, "validator").isInstanceOf(Validator).check();
1095
- assertParam(property, "property").isOptional().isString().or().isEntityProperty().check();
1096
- if (property != null) {
1097
- var prop = (typeof property === 'string') ? this.getProperty(property, true) : property;
1098
- prop.validators.push(validator);
1099
- }
1100
- else {
1101
- this.validators.push(validator);
1102
- }
1103
- };
1104
- /**
1105
- Returns all of the properties ( dataProperties and navigationProperties) for this EntityType.
1106
- > // assume em1 is an EntityManager containing a number of existing entities.
1107
- > let custType = em1.metadataStore.getEntityType("Customer");
1108
- > let arrayOfProps = custType.getProperties();
1109
- @return An array of Data and Navigation properties.
1110
- **/
1111
- EntityType.prototype.getProperties = function () {
1112
- return this.dataProperties.concat(this.navigationProperties);
1113
- };
1114
- /**
1115
- Returns all of the property names ( for both dataProperties and navigationProperties) for this EntityType.
1116
- > // assume em1 is an EntityManager containing a number of existing entities.
1117
- > let custType = em1.metadataStore.getEntityType("Customer");
1118
- > let arrayOfPropNames = custType.getPropertyNames();
1119
- **/
1120
- EntityType.prototype.getPropertyNames = function () {
1121
- return this.getProperties().map(core.pluck('name'));
1122
- };
1123
- /**
1124
- Returns a data property with the specified name or null.
1125
- > // assume em1 is an EntityManager containing a number of existing entities.
1126
- > let custType = em1.metadataStore.getEntityType("Customer");
1127
- > let customerNameDataProp = custType.getDataProperty("CustomerName");
1128
- @return A DataProperty or null if not found.
1129
- **/
1130
- EntityType.prototype.getDataProperty = function (propertyName) {
1131
- return core.arrayFirst(this.dataProperties, core.propEq('name', propertyName));
1132
- };
1133
- /**
1134
- Returns a navigation property with the specified name or null.
1135
- > // assume em1 is an EntityManager containing a number of existing entities.
1136
- > let custType = em1.metadataStore.getEntityType("Customer");
1137
- > let customerOrdersNavProp = custType.getDataProperty("Orders");
1138
- @return A NavigationProperty or null if not found.
1139
- **/
1140
- EntityType.prototype.getNavigationProperty = function (propertyName) {
1141
- return core.arrayFirst(this.navigationProperties, core.propEq('name', propertyName));
1142
- };
1143
- /**
1144
- Returns either a DataProperty or a NavigationProperty with the specified name or null.
1145
-
1146
- This method also accepts a '.' delimited property path and will return the 'property' at the
1147
- end of the path.
1148
- > let custType = em1.metadataStore.getEntityType("Customer");
1149
- > let companyNameProp = custType.getProperty("CompanyName");
1150
-
1151
- This method can also walk a property path to return a property
1152
- > let orderDetailType = em1.metadataStore.getEntityType("OrderDetail");
1153
- > let companyNameProp2 = orderDetailType.getProperty("Order.Customer.CompanyName");
1154
- > // companyNameProp === companyNameProp2
1155
- @param [throwIfNotFound=false] {Boolean} Whether to throw an exception if not found.
1156
- @return A DataProperty or NavigationProperty or null if not found.
1157
- **/
1158
- EntityType.prototype.getProperty = function (propertyPath, throwIfNotFound) {
1159
- if (throwIfNotFound === void 0) { throwIfNotFound = false; }
1160
- var props = this.getPropertiesOnPath(propertyPath, false, throwIfNotFound);
1161
- return (props && props.length > 0) ? props[props.length - 1] : null;
1162
- };
1163
- /** @hidden @internal */
1164
- // TODO: have this return empty array instead of null and fix consumers.
1165
- // TODO: think about renaming with '_' prefix.
1166
- EntityType.prototype.getPropertiesOnPath = function (propertyPath, useServerName, throwIfNotFound) {
1167
- if (throwIfNotFound === void 0) { throwIfNotFound = false; }
1168
- var propertyNames = (Array.isArray(propertyPath)) ? propertyPath : propertyPath.trim().split('.');
1169
- var ok = true;
1170
- var key = useServerName === true ? "nameOnServer" : useServerName === false ? "name" : null;
1171
- var parentType = this;
1172
- var getProps = function (propName) {
1173
- var fn = key === null ? core.propsEq("name", "nameOnServer", propName) : core.propEq(key, propName);
1174
- var prop = core.arrayFirst(parentType.getProperties(), fn);
1175
- if (prop) {
1176
- parentType = (prop instanceof NavigationProperty) ? prop.entityType : prop.dataType;
1177
- // parentType = prop.isNavigationProperty ? prop.entityType : prop.dataType;
1178
- }
1179
- else if (throwIfNotFound) {
1180
- throw new Error("unable to locate property: " + propName + " on entityType: " + parentType.name);
1181
- }
1182
- else {
1183
- ok = false;
1184
- }
1185
- return prop;
1186
- };
1187
- var props = propertyNames.map(getProps);
1188
- return ok ? props : null;
1189
- };
1190
- /** For use in pluggable adapters. */
1191
- // TODO: document use
1192
- EntityType.prototype.clientPropertyPathToServer = function (propertyPath, delimiter) {
1193
- if (delimiter === void 0) { delimiter = '.'; }
1194
- var propNames;
1195
- if (this.isAnonymous) {
1196
- var fn_1 = this.metadataStore.namingConvention.clientPropertyNameToServer;
1197
- propNames = propertyPath.split(".").map(function (propName) {
1198
- return fn_1(propName);
1199
- });
1200
- }
1201
- else {
1202
- var props = this.getPropertiesOnPath(propertyPath, false, true);
1203
- propNames = props.map(function (prop) { return prop.nameOnServer; });
1204
- }
1205
- return propNames.join(delimiter);
1206
- };
1207
- /** For use in pluggable adapters. */
1208
- // TODO: document use
1209
- EntityType.prototype.getEntityKeyFromRawEntity = function (rawEntity, rawValueFn) {
1210
- var keyValues = this.keyProperties.map(function (dp) {
1211
- var val = rawValueFn(rawEntity, dp);
1212
- return DataType.parseRawValue(val, dp.dataType);
1213
- });
1214
- return new EntityKey(this, keyValues);
1215
- };
1216
- /** @hidden @internal */
1217
- EntityType.prototype._updateTargetFromRaw = function (target, raw, rawValueFn) {
1218
- // called recursively for complex properties
1219
- this.dataProperties.forEach(function (dp) {
1220
- if (!dp.isSettable)
1221
- return;
1222
- var rawVal = rawValueFn(raw, dp);
1223
- if (rawVal === undefined)
1224
- return;
1225
- var dataType = dp.dataType; // this will be a complexType when dp is a complexProperty
1226
- var oldVal;
1227
- if (dp.isComplexProperty) {
1228
- var complexType_1 = dp.dataType;
1229
- if (rawVal === null)
1230
- return; // rawVal may be null in nosql dbs where it was never defined for the given row.
1231
- oldVal = target.getProperty(dp.name);
1232
- if (dp.isScalar) {
1233
- complexType_1._updateTargetFromRaw(oldVal, rawVal, rawValueFn);
1234
- }
1235
- else {
1236
- if (Array.isArray(rawVal)) {
1237
- var newVal = rawVal.map(function (rawCo) {
1238
- var newCo = complexType_1._createInstanceCore(target, dp);
1239
- complexType_1._updateTargetFromRaw(newCo, rawCo, rawValueFn);
1240
- complexType_1._initializeInstance(newCo);
1241
- return newCo;
1242
- });
1243
- if (!core.arrayEquals(oldVal, newVal, coEquals)) {
1244
- // clear the old array and push new objects into it.
1245
- oldVal.length = 0;
1246
- newVal.forEach(function (nv) {
1247
- oldVal.push(nv);
1248
- });
1249
- }
1250
- }
1251
- else {
1252
- oldVal.length = 0;
1253
- }
1254
- }
1255
- }
1256
- else {
1257
- if (dp.isScalar) {
1258
- var newVal = DataType.parseRawValue(rawVal, dataType);
1259
- target.setProperty(dp.name, newVal);
1260
- }
1261
- else {
1262
- oldVal = target.getProperty(dp.name);
1263
- if (Array.isArray(rawVal)) {
1264
- // need to compare values
1265
- var newVal = rawVal.map(function (rv) {
1266
- return DataType.parseRawValue(rv, dataType);
1267
- });
1268
- if (!core.arrayEquals(oldVal, newVal)) {
1269
- // clear the old array and push new objects into it.
1270
- oldVal.length = 0;
1271
- newVal.forEach(function (nv) {
1272
- oldVal.push(nv);
1273
- });
1274
- }
1275
- }
1276
- else {
1277
- oldVal.length = 0;
1278
- }
1279
- }
1280
- }
1281
- });
1282
- // if merging from an import then raw will have an entityAspect or a complexAspect
1283
- var rawAspect = raw.entityAspect || raw.complexAspect;
1284
- if (rawAspect) {
1285
- var targetAspect = EntityAspect.isEntity(target) ? target.entityAspect : target.complexAspect;
1286
- if (rawAspect.originalValuesMap) {
1287
- targetAspect.originalValues = rawAspect.originalValuesMap;
1288
- }
1289
- if (rawAspect.extraMetadata) {
1290
- targetAspect.extraMetadata = rawAspect.extraMetadata;
1291
- }
1292
- }
1293
- };
1294
- /**
1295
- Returns a string representation of this EntityType.
1296
- **/
1297
- EntityType.prototype.toString = function () {
1298
- return this.name;
1299
- };
1300
- EntityType.prototype.toJSON = function () {
1301
- return core.toJson(this, {
1302
- shortName: null,
1303
- namespace: null,
1304
- baseTypeName: null,
1305
- isAbstract: false,
1306
- autoGeneratedKeyType: null,
1307
- defaultResourceName: null,
1308
- dataProperties: localPropsOnly,
1309
- navigationProperties: localPropsOnly,
1310
- validators: null,
1311
- custom: null
1312
- });
1313
- };
1314
- /** @hidden @internal */
1315
- EntityType.prototype._updateNames = function (property) {
1316
- var nc = this.metadataStore.namingConvention;
1317
- updateClientServerNames(nc, property, "name");
1318
- if (property.isNavigationProperty) {
1319
- updateClientServerNames(nc, property, "foreignKeyNames");
1320
- updateClientServerNames(nc, property, "invForeignKeyNames");
1321
- // these will get set later via _updateNps
1322
- // this.inverse
1323
- // this.entityType
1324
- // this.relatedDataProperties
1325
- // dataProperty.relatedNavigationProperty
1326
- // dataProperty.inverseNavigationProperty
1327
- }
1328
- };
1329
- /** @hidden @internal */
1330
- EntityType.prototype._checkNavProperty = function (navigationProperty) {
1331
- // if (navigationProperty.isNavigationProperty) {
1332
- if (navigationProperty instanceof NavigationProperty) {
1333
- if (navigationProperty.parentType !== this) {
1334
- throw new Error(core.formatString("The navigationProperty '%1' is not a property of entity type '%2'", navigationProperty.name, this.name));
1335
- }
1336
- return navigationProperty;
1337
- }
1338
- if (typeof (navigationProperty) === 'string') {
1339
- var np = this.getProperty(navigationProperty);
1340
- // if (np && np.isNavigationProperty) return np;
1341
- if (np && np instanceof NavigationProperty)
1342
- return np;
1343
- }
1344
- throw new Error("The 'navigationProperty' parameter must either be a NavigationProperty or the name of a NavigationProperty");
1345
- };
1346
- /** @hidden @internal */
1347
- EntityType.prototype._addDataProperty = function (dp) {
1348
- this.dataProperties.push(dp);
1349
- if (dp.isPartOfKey) {
1350
- this.keyProperties.push(dp);
1351
- }
1352
- if (dp.isComplexProperty) {
1353
- this.complexProperties.push(dp);
1354
- }
1355
- if (dp.concurrencyMode && dp.concurrencyMode !== "None") {
1356
- this.concurrencyProperties.push(dp);
1357
- }
1358
- if (dp.isUnmapped) {
1359
- this.unmappedProperties.push(dp);
1360
- }
1361
- };
1362
- /** @hidden @internal */
1363
- EntityType.prototype._addNavigationProperty = function (np) {
1364
- this.navigationProperties.push(np);
1365
- if (!isQualifiedTypeName(np.entityTypeName)) {
1366
- np.entityTypeName = qualifyTypeName(np.entityTypeName, this.namespace);
1367
- }
1368
- };
1369
- /** @hidden @internal */
1370
- EntityType.prototype._updateCps = function () {
1371
- var metadataStore = this.metadataStore;
1372
- var incompleteTypeMap = metadataStore._incompleteComplexTypeMap;
1373
- this.complexProperties.forEach(function (cp) {
1374
- if (cp.complexType)
1375
- return;
1376
- if (!resolveCp(cp, metadataStore)) {
1377
- core.getArray(incompleteTypeMap, cp.complexTypeName).push(cp);
1378
- }
1379
- });
1380
- if (this.isComplexType) {
1381
- (incompleteTypeMap[this.name] || []).forEach(function (cp) {
1382
- resolveCp(cp, metadataStore);
1383
- });
1384
- delete incompleteTypeMap[this.name];
1385
- }
1386
- };
1387
- /** @hidden @internal */
1388
- EntityType.prototype._updateNps = function () {
1389
- var metadataStore = this.metadataStore;
1390
- // resolve all navProps for this entityType
1391
- this.navigationProperties.forEach(function (np) {
1392
- tryResolveNp(np, metadataStore);
1393
- });
1394
- var incompleteTypeMap = metadataStore._incompleteTypeMap;
1395
- // next resolve all navProp that point to this entityType.
1396
- (incompleteTypeMap[this.name] || []).forEach(function (np) {
1397
- tryResolveNp(np, metadataStore);
1398
- });
1399
- // every navProp that pointed to this type should now be resolved
1400
- delete incompleteTypeMap[this.name];
1401
- };
1402
- /** @hidden @internal */
1403
- EntityType.__nextAnonIx = 0;
1404
- /** @hidden @internal */
1405
- EntityType.qualifyTypeName = qualifyTypeName;
1406
- return EntityType;
1407
- }());
1408
- export { EntityType };
1409
- EntityType.prototype._$typeName = "EntityType";
1410
- function getRawValueFromConfig(rawEntity, dp) {
1411
- // 'true' fork can happen if an initializer contains an actaul instance of an already created complex object.
1412
- return (rawEntity.entityAspect || rawEntity.complexAspect) ? rawEntity.getProperty(dp.name) : rawEntity[dp.name];
1413
- }
1414
- function updateClientServerNames(nc, parent, clientPropName) {
1415
- var serverPropName = clientPropName + "OnServer";
1416
- var clientName = parent[clientPropName];
1417
- if (clientName && clientName.length) {
1418
- // if (parent.isUnmapped) return;
1419
- var serverNames = core.toArray(clientName).map(function (cName) {
1420
- var sName = nc.clientPropertyNameToServer(cName, parent);
1421
- var testName = nc.serverPropertyNameToClient(sName, parent);
1422
- if (cName !== testName) {
1423
- throw new Error("NamingConvention for this client property name does not roundtrip properly:" + cName + "-->" + testName);
1424
- }
1425
- return sName;
1426
- });
1427
- parent[serverPropName] = Array.isArray(clientName) ? serverNames : serverNames[0];
1428
- }
1429
- else {
1430
- var serverName = parent[serverPropName];
1431
- if ((!serverName) || serverName.length === 0)
1432
- return;
1433
- var clientNames = core.toArray(serverName).map(function (sName) {
1434
- var cName = nc.serverPropertyNameToClient(sName, parent);
1435
- var testName = nc.clientPropertyNameToServer(cName, parent);
1436
- if (sName !== testName) {
1437
- throw new Error("NamingConvention for this server property name does not roundtrip properly:" + sName + "-->" + testName);
1438
- }
1439
- return cName;
1440
- });
1441
- parent[clientPropName] = Array.isArray(serverName) ? clientNames : clientNames[0];
1442
- }
1443
- }
1444
- function createEmptyCtor(type) {
1445
- if (config.noEval) {
1446
- var Entity = function () { };
1447
- return Entity;
1448
- }
1449
- else {
1450
- var name_1 = type.name.replace(/\W/g, '_');
1451
- return Function('return function ' + name_1 + '(){}')();
1452
- }
1453
- }
1454
- function coEquals(co1, co2) {
1455
- var complexType = co1.complexAspect.parentProperty.dataType;
1456
- var dataProps = complexType.dataProperties;
1457
- var areEqual = dataProps.every(function (dp) {
1458
- if (!dp.isSettable)
1459
- return true;
1460
- var v1 = co1.getProperty(dp.name);
1461
- var v2 = co2.getProperty(dp.name);
1462
- if (dp.isComplexProperty && dp.isScalar) {
1463
- return coEquals(v1, v2);
1464
- }
1465
- else if (dp.isComplexProperty && !dp.isScalar) {
1466
- return core.arrayEquals(v1, v2, coEquals);
1467
- }
1468
- else {
1469
- var dataType = dp.dataType; // this will be a complexType when dp is a complexProperty
1470
- return (v1 === v2 || (dataType && dataType.normalize && v1 && v2 && dataType.normalize(v1) === dataType.normalize(v2)));
1471
- }
1472
- });
1473
- return areEqual;
1474
- }
1475
- function localPropsOnly(props) {
1476
- return props.filter(function (prop) {
1477
- return prop.baseProperty == null;
1478
- });
1479
- }
1480
- function resolveCp(cp, metadataStore) {
1481
- var complexType = metadataStore._getStructuralType(cp.complexTypeName, true);
1482
- if (!complexType)
1483
- return false;
1484
- if (!(complexType instanceof ComplexType)) {
1485
- throw new Error("Unable to resolve ComplexType with the name: " + cp.complexTypeName + " for the property: " + cp.name);
1486
- }
1487
- cp.dataType = complexType;
1488
- cp.defaultValue = null;
1489
- return true;
1490
- }
1491
- function tryResolveNp(np, metadataStore) {
1492
- if (np.entityType)
1493
- return true;
1494
- var entityType = metadataStore._getStructuralType(np.entityTypeName, true);
1495
- if (entityType) {
1496
- np.entityType = entityType;
1497
- np._resolveNp();
1498
- // don't bother removing - _updateNps will do it later.
1499
- // __arrayRemoveItem(incompleteNps, np, false);
1500
- }
1501
- else {
1502
- var incompleteNps = core.getArray(metadataStore._incompleteTypeMap, np.entityTypeName);
1503
- core.arrayAddItemUnique(incompleteNps, np);
1504
- }
1505
- return !!entityType;
1506
- }
1507
- function calcUnmappedProperties(stype, instance) {
1508
- var metadataPropNames = stype.getPropertyNames();
1509
- var modelLib = config.interfaceRegistry.modelLibrary.getDefaultInstance();
1510
- var trackablePropNames = modelLib.getTrackablePropertyNames(instance);
1511
- trackablePropNames.forEach(function (pn) {
1512
- if (metadataPropNames.indexOf(pn) === -1) {
1513
- var val = instance[pn];
1514
- try {
1515
- if (typeof val === "function")
1516
- val = val();
1517
- }
1518
- catch (e) {
1519
- }
1520
- var dt = DataType.fromValue(val);
1521
- var newProp_1 = new DataProperty({
1522
- name: pn,
1523
- dataType: dt,
1524
- isNullable: true,
1525
- isUnmapped: true
1526
- });
1527
- newProp_1.isSettable = core.isSettable(instance, pn);
1528
- if (stype instanceof EntityType && stype.subtypes != null && stype.subtypes.length) {
1529
- stype.getSelfAndSubtypes().forEach(function (st) {
1530
- st._addPropertyCore(new DataProperty(newProp_1));
1531
- });
1532
- }
1533
- else {
1534
- stype._addPropertyCore(newProp_1);
1535
- }
1536
- }
1537
- });
1538
- }
1539
- /** Container for all of the metadata about a specific type of Complex object.
1540
- > let complexType = new ComplexType( {
1541
- > shortName: "address",
1542
- > namespace: "myAppNamespace"
1543
- > });
1544
- @param config - Configuration settings
1545
- **/
1546
- var ComplexType = /** @class */ (function () {
1547
- function ComplexType(config) {
1548
- /** For polymorphic purpose only - always true here */
1549
- this.isComplexType = true;
1550
- // copy entityType methods onto complexType
1551
- /** See [[EntityType.getCtor]] */
1552
- this.getCtor = EntityType.prototype.getCtor;
1553
- // note the name change.
1554
- this.createInstance = EntityType.prototype.createEntity;
1555
- /** See [EntityType.addValidator] */
1556
- this.addValidator = EntityType.prototype.addValidator;
1557
- this.getProperty = EntityType.prototype.getProperty;
1558
- this.getPropertiesOnPath = EntityType.prototype.getPropertiesOnPath;
1559
- this.getPropertyNames = EntityType.prototype.getPropertyNames;
1560
- /** @hidden @internal */
1561
- this._addPropertyCore = EntityType.prototype._addPropertyCore;
1562
- /** @hidden @internal */
1563
- this._addDataProperty = EntityType.prototype._addDataProperty;
1564
- /** @hidden @internal */
1565
- this._updateNames = EntityType.prototype._updateNames;
1566
- /** @hidden @internal */
1567
- this._updateCps = EntityType.prototype._updateCps;
1568
- /** @hidden @internal */
1569
- this._initializeInstance = EntityType.prototype._initializeInstance;
1570
- /** @hidden @internal */
1571
- this._updateTargetFromRaw = EntityType.prototype._updateTargetFromRaw;
1572
- /** @hidden @internal */
1573
- this._setCtor = EntityType.prototype._setCtor;
1574
- if (arguments.length > 1) {
1575
- throw new Error("The ComplexType ctor has a single argument that is a configuration object.");
1576
- }
1577
- assertConfig(config)
1578
- .whereParam("shortName").isNonEmptyString()
1579
- .whereParam("namespace").isString().isOptional().withDefault("")
1580
- .whereParam("dataProperties").isOptional()
1581
- .whereParam("isComplexType").isOptional().isBoolean() // needed because this ctor can get called from the addEntityType method which needs the isComplexType prop
1582
- .whereParam("custom").isOptional()
1583
- .applyAll(this);
1584
- this.name = qualifyTypeName(this.shortName, this.namespace);
1585
- this.isComplexType = true;
1586
- this.dataProperties = [];
1587
- this.complexProperties = [];
1588
- this.validators = [];
1589
- this.concurrencyProperties = [];
1590
- this.unmappedProperties = [];
1591
- this._mappedPropertiesCount = 0;
1592
- // keyProperties and navigationProperties are not used on complexTypes - but here to allow sharing of code between EntityType and ComplexType.
1593
- this.navigationProperties = [];
1594
- this.keyProperties = []; // may be used later to enforce uniqueness on arrays of complextypes.
1595
- if (config.dataProperties) {
1596
- addProperties(this, config.dataProperties, DataProperty);
1597
- }
1598
- }
1599
- /**
1600
- General purpose property set method
1601
- > // assume em1 is an EntityManager
1602
- > let addresstType = em1.metadataStore.getEntityType("Address");
1603
- > addressType.setProperties( {
1604
- > custom: { foo: 7, bar: "test" }
1605
- > });
1606
- @param config - Custom config object
1607
- @param config.custom - {Object}
1608
- **/
1609
- ComplexType.prototype.setProperties = function (config) {
1610
- assertConfig(config)
1611
- .whereParam("custom").isOptional()
1612
- .applyAll(this);
1613
- };
1614
- ComplexType.prototype.getAllValidators = function () {
1615
- // ComplexType inheritance is not YET supported.
1616
- return this.validators;
1617
- };
1618
- /** @hidden @internal */
1619
- ComplexType.prototype._createInstanceCore = function (parent, parentProperty) {
1620
- var aCtor = this.getCtor();
1621
- var instance = new aCtor();
1622
- new ComplexAspect(instance, parent, parentProperty);
1623
- // initialization occurs during either attach or in createInstance call.
1624
- return instance;
1625
- };
1626
- ComplexType.prototype.addProperty = function (dataProperty) {
1627
- assertParam(dataProperty, "dataProperty").isInstanceOf(DataProperty).check();
1628
- return this._addPropertyCore(dataProperty);
1629
- };
1630
- ComplexType.prototype.getProperties = function () {
1631
- return this.dataProperties;
1632
- };
1633
- ComplexType.prototype.toJSON = function () {
1634
- return core.toJson(this, {
1635
- shortName: null,
1636
- namespace: null,
1637
- isComplexType: null,
1638
- dataProperties: null,
1639
- validators: null,
1640
- custom: null
1641
- });
1642
- };
1643
- return ComplexType;
1644
- }());
1645
- export { ComplexType };
1646
- ComplexType.prototype._$typeName = "ComplexType";
1647
- /** Creates an instance of this complexType */
1648
- ComplexType.prototype.createInstance = EntityType.prototype.createEntity;
1649
- /**
1650
- A DataProperty describes the metadata for a single property of an [[EntityType]] that contains simple data.
1651
-
1652
- Instances of the DataProperty class are constructed automatically during Metadata retrieval. However it is also possible to construct them
1653
- directly via the constructor.
1654
- **/
1655
- var DataProperty = /** @class */ (function () {
1656
- /** DataProperty constructor
1657
- > let lastNameProp = new DataProperty( {
1658
- > name: "lastName",
1659
- > dataType: DataType.String,
1660
- > isNullable: true,
1661
- > maxLength: 20
1662
- > });
1663
- > // assuming personEntityType is a newly constructed EntityType
1664
- > personEntityType.addProperty(lastNameProperty);
1665
- @param config - A configuration Object or a DataProperty
1666
- */
1667
- function DataProperty(config) {
1668
- /** Is this a DataProperty? - always true here. Allows polymorphic treatment of DataProperties and NavigationProperties. __Read Only__ */
1669
- this.isDataProperty = true;
1670
- /** Is this a NavigationProperty? - always false here. Allows polymorphic treatment of DataProperties and NavigationProperties. __Read Only__ */
1671
- this.isNavigationProperty = false;
1672
- assertConfig(config)
1673
- .whereParam("name").isString().isOptional()
1674
- .whereParam("nameOnServer").isString().isOptional()
1675
- .whereParam("dataType").isEnumOf(DataType).isOptional().or().isString().or().isInstanceOf(ComplexType)
1676
- .whereParam("complexTypeName").isOptional()
1677
- .whereParam("isNullable").isBoolean().isOptional().withDefault(true)
1678
- .whereParam("isScalar").isOptional().withDefault(true) // will be false for some NoSQL databases.
1679
- .whereParam("defaultValue").isOptional()
1680
- .whereParam("isPartOfKey").isBoolean().isOptional()
1681
- .whereParam("isUnmapped").isBoolean().isOptional()
1682
- .whereParam("isSettable").isBoolean().isOptional().withDefault(true)
1683
- .whereParam("concurrencyMode").isString().isOptional()
1684
- .whereParam("maxLength").isNumber().isOptional()
1685
- .whereParam("validators").isInstanceOf(Validator).isArray().isOptional().withDefault([])
1686
- .whereParam("displayName").isOptional()
1687
- .whereParam("enumType").isOptional()
1688
- .whereParam("rawTypeName").isOptional() // occurs with undefined datatypes
1689
- .whereParam("custom").isOptional()
1690
- .applyAll(this);
1691
- var hasName = !!(this.name || this.nameOnServer);
1692
- if (!hasName) {
1693
- throw new Error("A DataProperty must be instantiated with either a 'name' or a 'nameOnServer' property");
1694
- }
1695
- // name/nameOnServer is resolved later when a metadataStore is available.
1696
- if (this.complexTypeName) {
1697
- this.isComplexProperty = true;
1698
- // this.dataType = null; // TODO: would like to remove this line because dataType will be set later.
1699
- }
1700
- else if (typeof (this.dataType) === "string") {
1701
- var dt = DataType.fromName(this.dataType);
1702
- if (!dt) {
1703
- throw new Error("Unable to find a DataType enumeration by the name of: " + this.dataType);
1704
- }
1705
- this.dataType = dt;
1706
- }
1707
- else if (!this.dataType) {
1708
- this.dataType = DataType.String;
1709
- }
1710
- // == as opposed to === is deliberate here.
1711
- if (this.defaultValue == null) {
1712
- if (this.isNullable) {
1713
- this.defaultValue = null;
1714
- }
1715
- else {
1716
- if (this.isComplexProperty) {
1717
- // what to do? - shouldn't happen from EF - but otherwise ???
1718
- }
1719
- else if (this.dataType === DataType.Binary) {
1720
- this.defaultValue = "AAAAAAAAJ3U="; // hack for all binary fields but value is specifically valid for timestamp fields - arbitrary valid 8 byte base64 value.
1721
- }
1722
- else {
1723
- this.defaultValue = this.dataType.defaultValue;
1724
- var msg = "A nonnullable DataProperty cannot have a null defaultValue. Name: " + (this.name || this.nameOnServer);
1725
- if (this.defaultValue === null) {
1726
- throw new Error(msg); // if defaultValue is explicity set to null, that's an error
1727
- }
1728
- else if (this.defaultValue == null) {
1729
- console.warn(msg); // if defaultValue is not set, that's a warning
1730
- }
1731
- }
1732
- }
1733
- }
1734
- else if (this.dataType.isNumeric) {
1735
- // in case the defaultValue comes in as a string ( which it does in EF6).
1736
- if (typeof (this.defaultValue) === "string") {
1737
- this.defaultValue = parseFloat(this.defaultValue);
1738
- }
1739
- }
1740
- if (this.isComplexProperty) {
1741
- this.isScalar = this.isScalar == null || this.isScalar === true;
1742
- }
1743
- }
1744
- DataProperty.getRawValueFromServer = function (rawEntity, dp) {
1745
- if (dp.isUnmapped) {
1746
- return rawEntity[dp.nameOnServer || dp.name];
1747
- }
1748
- else {
1749
- var val = rawEntity[dp.nameOnServer];
1750
- return val !== undefined ? val : dp.defaultValue;
1751
- }
1752
- };
1753
- DataProperty.getRawValueFromClient = function (rawEntity, dp) {
1754
- var val = rawEntity[dp.name];
1755
- return val !== undefined ? val : dp.defaultValue;
1756
- };
1757
- DataProperty.prototype.resolveProperty = function (propName) {
1758
- var result = this[propName];
1759
- var baseProp = this.baseProperty;
1760
- while (result == undefined && baseProp != null) {
1761
- result = baseProp[propName];
1762
- baseProp = baseProp.baseProperty;
1763
- }
1764
- return result;
1765
- };
1766
- DataProperty.prototype.formatName = function () {
1767
- return this.parentType.name + "--" + this.name;
1768
- };
1769
- /**
1770
- General purpose property set method
1771
- > // assume em1 is an EntityManager
1772
- > let prop = myEntityType.getProperty("myProperty");
1773
- > prop.setProperties( {
1774
- > custom: { foo: 7, bar: "test" }
1775
- > });
1776
- @param config - A configuration object.
1777
- **/
1778
- DataProperty.prototype.setProperties = function (config) {
1779
- assertConfig(config)
1780
- .whereParam("displayName").isOptional()
1781
- .whereParam("custom").isOptional()
1782
- .applyAll(this);
1783
- };
1784
- DataProperty.prototype.getAllValidators = function () {
1785
- var validators = this.validators.slice(0);
1786
- var baseProp = this.baseProperty;
1787
- while (baseProp) {
1788
- validators.push.apply(validators, baseProp.validators);
1789
- baseProp = baseProp.baseProperty;
1790
- }
1791
- return validators;
1792
- };
1793
- DataProperty.prototype.toJSON = function () {
1794
- // do not serialize dataTypes that are complexTypes
1795
- return core.toJson(this, {
1796
- name: null,
1797
- dataType: function (v) {
1798
- return (v && v instanceof DataType) ? v.name : undefined;
1799
- },
1800
- complexTypeName: null,
1801
- isNullable: true,
1802
- defaultValue: null,
1803
- isPartOfKey: false,
1804
- isUnmapped: false,
1805
- isSettable: true,
1806
- concurrencyMode: null,
1807
- maxLength: null,
1808
- validators: null,
1809
- displayName: null,
1810
- enumType: null,
1811
- rawTypeName: null,
1812
- isScalar: true,
1813
- custom: null
1814
- });
1815
- };
1816
- DataProperty.fromJSON = function (json) {
1817
- json.dataType = DataType.fromName(json.dataType);
1818
- // Parse default value into correct data type. (dateTime instances require extra work to deserialize properly.)
1819
- if (json.defaultValue && json.dataType && json.dataType.parse) {
1820
- json.defaultValue = json.dataType.parse(json.defaultValue, typeof json.defaultValue);
1821
- }
1822
- if (json.validators) {
1823
- json.validators = json.validators.map(Validator.fromJSON);
1824
- }
1825
- return new DataProperty(json);
1826
- };
1827
- return DataProperty;
1828
- }());
1829
- export { DataProperty };
1830
- DataProperty.prototype._$typeName = "DataProperty";
1831
- /** A NavigationProperty describes the metadata for a single property of an [[EntityType]] that return instances of other EntityTypes.
1832
-
1833
- Instances of the NavigationProperty class are constructed automatically during Metadata retrieval. However it is also possible to construct them
1834
- directly via the constructor.
1835
- **/
1836
- var NavigationProperty = /** @class */ (function () {
1837
- /** NavigationProperty constructor
1838
- > let homeAddressProp = new NavigationProperty( {
1839
- > name: "homeAddress",
1840
- > entityTypeName: "Address:#myNamespace",
1841
- > isScalar: true,
1842
- > associationName: "address_person",
1843
- > foreignKeyNames: ["homeAddressId"]
1844
- > });
1845
- > let homeAddressIdProp = new DataProperty( {
1846
- > name: "homeAddressId"
1847
- > dataType: DataType.Integer
1848
- > });
1849
- > // assuming personEntityType is a newly constructed EntityType
1850
- > personEntityType.addProperty(homeAddressProp);
1851
- > personEntityType.addProperty(homeAddressIdProp);
1852
- @param config - A configuration object.
1853
- **/
1854
- function NavigationProperty(config) {
1855
- /** Is this a DataProperty? - always false here
1856
- Allows polymorphic treatment of DataProperties and NavigationProperties. __Read Only__ */
1857
- this.isDataProperty = false;
1858
- /** Is this a NavigationProperty? - always true here
1859
- Allows polymorphic treatment of DataProperties and NavigationProperties. __Read Only__ */
1860
- this.isNavigationProperty = true;
1861
- this.formatName = DataProperty.prototype.formatName;
1862
- this.getAllValidators = DataProperty.prototype.getAllValidators;
1863
- this.resolveProperty = DataProperty.prototype.resolveProperty;
1864
- assertConfig(config)
1865
- .whereParam("name").isString().isOptional()
1866
- .whereParam("nameOnServer").isString().isOptional()
1867
- .whereParam("entityTypeName").isString()
1868
- .whereParam("isScalar").isBoolean().isOptional().withDefault(true)
1869
- .whereParam("associationName").isString().isOptional()
1870
- .whereParam("foreignKeyNames").isArray().isString().isOptional().withDefault([])
1871
- .whereParam("foreignKeyNamesOnServer").isArray().isString().isOptional().withDefault([])
1872
- .whereParam("invForeignKeyNames").isArray().isString().isOptional().withDefault([])
1873
- .whereParam("invForeignKeyNamesOnServer").isArray().isString().isOptional().withDefault([])
1874
- .whereParam("validators").isInstanceOf(Validator).isArray().isOptional().withDefault([])
1875
- .whereParam("displayName").isOptional()
1876
- .whereParam("custom").isOptional()
1877
- .applyAll(this);
1878
- var hasName = !!(this.name || this.nameOnServer);
1879
- if (!hasName) {
1880
- throw new Error("A Navigation property must be instantiated with either a 'name' or a 'nameOnServer' property");
1881
- }
1882
- }
1883
- /**
1884
- General purpose property set method
1885
- > // assume myEntityType is an EntityType
1886
- > let prop = myEntityType.getProperty("myProperty");
1887
- > prop.setProperties( {
1888
- > custom: { foo: 7, bar: "test" }
1889
- > });
1890
- @param config - A config object
1891
- **/
1892
- // TODO: create an interface for this.
1893
- NavigationProperty.prototype.setProperties = function (config) {
1894
- if (!this.parentType) {
1895
- throw new Error("Cannot call NavigationProperty.setProperties until the parent EntityType of the NavigationProperty has been set.");
1896
- }
1897
- var inverse = config.inverse;
1898
- if (inverse)
1899
- delete config.inverse;
1900
- assertConfig(config)
1901
- .whereParam("displayName").isOptional()
1902
- .whereParam("foreignKeyNames").isArray().isString().isOptional().withDefault([])
1903
- .whereParam("invForeignKeyNames").isArray().isString().isOptional().withDefault([])
1904
- .whereParam("custom").isOptional()
1905
- .applyAll(this);
1906
- this.parentType._updateNames(this);
1907
- this._resolveNp();
1908
- if (inverse) {
1909
- this.setInverse(inverse);
1910
- }
1911
- };
1912
- Object.defineProperty(NavigationProperty.prototype, "inverse", {
1913
- /** The inverse of this NavigationProperty. The NavigationProperty that represents a navigation in the opposite direction
1914
- to this NavigationProperty. May be undefined for a undirectional NavigationProperty. __Read Only__ */
1915
- get: function () {
1916
- return this.getInverse();
1917
- },
1918
- enumerable: true,
1919
- configurable: true
1920
- });
1921
- /** @hidden @internal */
1922
- NavigationProperty.prototype.getInverse = function () {
1923
- var np = this;
1924
- while (!np._inverse && np.baseProperty) {
1925
- np = np.baseProperty;
1926
- }
1927
- return np._inverse;
1928
- };
1929
- NavigationProperty.prototype.setInverse = function (inverseNp) {
1930
- // let invNp: NavigationProperty;
1931
- var invNp = (inverseNp instanceof NavigationProperty) ? inverseNp : this.entityType.getNavigationProperty(inverseNp);
1932
- if (!invNp) {
1933
- throw throwSetInverseError(this, "Unable to find inverse property: " + inverseNp);
1934
- }
1935
- if (this._inverse || invNp._inverse) {
1936
- throwSetInverseError(this, "It has already been set on one side or the other.");
1937
- }
1938
- if (invNp.entityType !== this.parentType) {
1939
- throwSetInverseError(this, invNp.formatName + " is not a valid inverse property for this.");
1940
- }
1941
- if (this.associationName) {
1942
- invNp.associationName = this.associationName;
1943
- }
1944
- else {
1945
- if (!invNp.associationName) {
1946
- invNp.associationName = this.formatName() + "_" + invNp.formatName();
1947
- }
1948
- this.associationName = invNp.associationName;
1949
- }
1950
- this._resolveNp();
1951
- invNp._resolveNp();
1952
- };
1953
- // // In progress - will be used for manual metadata config
1954
- // createInverse(config: any) {
1955
- // if (!this.entityType) {
1956
- // throwCreateInverseError(this, "has not yet been defined.");
1957
- // }
1958
- // if (this.entityType.isFrozen) {
1959
- // throwCreateInverseError(this, "is frozen.");
1960
- // }
1961
- // let metadataStore = this.entityType.metadataStore;
1962
- // if (metadataStore == null) {
1963
- // throwCreateInverseError(this, "has not yet been added to the metadataStore.");
1964
- // }
1965
- // config.entityTypeName = this.parentEntityType.name;
1966
- // config.associationName = this.associationName;
1967
- // let invNp = new NavigationProperty(config);
1968
- // this.parentEntityType.addNavigationProperty(invNp);
1969
- // return invNp;
1970
- // };
1971
- NavigationProperty.prototype.toJSON = function () {
1972
- return core.toJson(this, {
1973
- name: null,
1974
- entityTypeName: null,
1975
- isScalar: null,
1976
- associationName: null,
1977
- validators: null,
1978
- displayName: null,
1979
- foreignKeyNames: null,
1980
- invForeignKeyNames: null,
1981
- custom: null
1982
- });
1983
- };
1984
- NavigationProperty.fromJSON = function (json) {
1985
- if (json.validators) {
1986
- json.validators = json.validators.map(Validator.fromJSON);
1987
- }
1988
- return new NavigationProperty(json);
1989
- };
1990
- /** @hidden @internal */
1991
- NavigationProperty.prototype._resolveNp = function () {
1992
- var np = this;
1993
- var entityType = np.entityType;
1994
- var invNp = core.arrayFirst(entityType.navigationProperties, function (altNp) {
1995
- // Can't do this because of possibility of comparing a base class np with a subclass altNp.
1996
- // return altNp.associationName === np.associationName
1997
- // && altNp !== np;
1998
- // So use this instead.
1999
- return altNp.associationName === np.associationName &&
2000
- (altNp.name !== np.name || altNp.entityTypeName !== np.entityTypeName);
2001
- });
2002
- np._inverse = invNp || undefined;
2003
- //if (invNp && invNp.inverse == null) {
2004
- // invNp._resolveNp();
2005
- //}
2006
- if (!invNp) {
2007
- // unidirectional 1-n relationship
2008
- np.invForeignKeyNames.forEach(function (invFkName) {
2009
- var fkProp = entityType.getDataProperty(invFkName);
2010
- if (fkProp == null) {
2011
- throw new Error("EntityType '" + np.entityTypeName + "' has no foreign key matching '" + invFkName + "'");
2012
- }
2013
- var invEntityType = np.parentType;
2014
- invNp = core.arrayFirst(invEntityType.navigationProperties, function (np2) {
2015
- return np2.invForeignKeyNames && np2.invForeignKeyNames.indexOf(fkProp.name) >= 0 && np2.entityType === fkProp.parentType;
2016
- });
2017
- fkProp.inverseNavigationProperty = invNp || undefined;
2018
- core.arrayAddItemUnique(entityType.foreignKeyProperties, fkProp);
2019
- });
2020
- }
2021
- resolveRelated(np);
2022
- };
2023
- return NavigationProperty;
2024
- }());
2025
- export { NavigationProperty };
2026
- NavigationProperty.prototype._$typeName = "NavigationProperty";
2027
- function throwSetInverseError(np, message) {
2028
- throw new Error("Cannot set the inverse property for: " + np.formatName() + ". " + message);
2029
- }
2030
- // Not current used.
2031
- // function throwCreateInverseError(np: NavigationProperty, message: string) {
2032
- // throw new Error("Cannot create inverse for: " + np.formatName() + ". The entityType for this navigation property " + message);
2033
- // }
2034
- // sets navigation property: relatedDataProperties and dataProperty: relatedNavigationProperty
2035
- function resolveRelated(np) {
2036
- var fkNames = np.foreignKeyNames;
2037
- if (fkNames.length === 0)
2038
- return;
2039
- var parentEntityType = np.parentType;
2040
- var fkProps = fkNames.map(function (fkName) {
2041
- return parentEntityType.getDataProperty(fkName);
2042
- });
2043
- var fkPropCollection = parentEntityType.foreignKeyProperties;
2044
- fkProps.forEach(function (dp) {
2045
- core.arrayAddItemUnique(fkPropCollection, dp);
2046
- dp.relatedNavigationProperty = np;
2047
- // now update the inverse
2048
- core.arrayAddItemUnique(np.entityType.inverseForeignKeyProperties, dp);
2049
- if (np.relatedDataProperties) {
2050
- core.arrayAddItemUnique(np.relatedDataProperties, dp);
2051
- }
2052
- else {
2053
- np.relatedDataProperties = [dp];
2054
- }
2055
- });
2056
- }
2057
- /**
2058
- AutoGeneratedKeyType is an 'Enum' containing all of the valid states for an automatically generated key.
2059
- **/
2060
- var AutoGeneratedKeyType = /** @class */ (function (_super) {
2061
- __extends(AutoGeneratedKeyType, _super);
2062
- function AutoGeneratedKeyType() {
2063
- return _super !== null && _super.apply(this, arguments) || this;
2064
- }
2065
- /**
2066
- This entity does not have an autogenerated key.
2067
- The client must set the key before adding the entity to the EntityManager
2068
- **/
2069
- AutoGeneratedKeyType.None = new AutoGeneratedKeyType();
2070
- /**
2071
- This entity's key is an Identity column and is set by the backend database.
2072
- Keys for new entities will be temporary until the entities are saved at which point the keys will
2073
- be converted to their 'real' versions.
2074
- **/
2075
- AutoGeneratedKeyType.Identity = new AutoGeneratedKeyType();
2076
- /**
2077
- This entity's key is generated by a KeyGenerator and is set by the backend database.
2078
- Keys for new entities will be temporary until the entities are saved at which point the keys will
2079
- be converted to their 'real' versions.
2080
- **/
2081
- AutoGeneratedKeyType.KeyGenerator = new AutoGeneratedKeyType();
2082
- return AutoGeneratedKeyType;
2083
- }(BreezeEnum));
2084
- export { AutoGeneratedKeyType };
2085
- AutoGeneratedKeyType.prototype._$typeName = "AutoGeneratedKeyType";
2086
- Error['x'] = AutoGeneratedKeyType.resolveSymbols();
2087
- var proto = Param.prototype;
2088
- // 'this' below is TS annotation
2089
- proto.isEntity = function () {
2090
- return this._addContext({
2091
- fn: isEntity,
2092
- msg: " must be an entity"
2093
- });
2094
- };
2095
- function isEntity(context, v) {
2096
- if (v == null)
2097
- return false;
2098
- return (v.entityType !== undefined);
2099
- }
2100
- proto.isEntityProperty = function () {
2101
- return this._addContext({
2102
- fn: isEntityProperty,
2103
- msg: " must be either a DataProperty or a NavigationProperty"
2104
- });
2105
- };
2106
- function isEntityProperty(context, v) {
2107
- if (v == null)
2108
- return false;
2109
- return (v.isDataProperty || v.isNavigationProperty);
2110
- }
2111
- // functions shared between classes related to Metadata
2112
- function isQualifiedTypeName(entityTypeName) {
2113
- return entityTypeName.indexOf(":#") >= 0;
2114
- }
2115
- export function qualifyTypeName(shortName, ns) {
2116
- if (ns && ns.length > 0) {
2117
- return shortName + ":#" + ns;
2118
- }
2119
- else {
2120
- return shortName;
2121
- }
2122
- }
2123
- // Used by both ComplexType and EntityType
2124
- function addProperties(entityType, propObj, ctor) {
2125
- if (propObj == null)
2126
- return;
2127
- if (Array.isArray(propObj)) {
2128
- propObj.forEach(entityType._addPropertyCore.bind(entityType));
2129
- }
2130
- else if (typeof (propObj) === 'object') {
2131
- for (var key in propObj) {
2132
- if (core.hasOwnProperty(propObj, key)) {
2133
- var value = propObj[key];
2134
- value.name = key;
2135
- var prop = new ctor(value);
2136
- entityType._addPropertyCore(prop);
2137
- }
2138
- }
2139
- }
2140
- else {
2141
- throw new Error("The 'dataProperties' or 'navigationProperties' values must be either an array of data/nav properties or an object where each property defines a data/nav property");
2142
- }
2143
- }
2144
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LW1ldGFkYXRhLmpzIiwic291cmNlUm9vdCI6Im5nOi8vYnJlZXplLWNsaWVudC8iLCJzb3VyY2VzIjpbInNyYy9lbnRpdHktbWV0YWRhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxJQUFJLEVBQWlCLE1BQU0sUUFBUSxDQUFDO0FBQzdDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDbEMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN0QyxPQUFPLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNsRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxZQUFZLEVBQUUsYUFBYSxFQUEyQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDekMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN2QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQyxDQUFDLDJCQUEyQjtBQUN4RixPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUMvRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQTZDNUU7Ozs7O0dBS0c7QUFDSDtJQXFERTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BcUJHO0lBQ0gsdUJBQVksTUFBNEI7UUFDdEMsTUFBTSxHQUFHLE1BQU0sSUFBSSxFQUFFLENBQUM7UUFDdEIsWUFBWSxDQUFDLE1B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TSxHQUFHLENBQUMsRUFBRTtRQUN2QixPQUFPLFNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0tBQzlCO1NBQU07UUFDTCxPQUFPLFNBQVMsQ0FBQztLQUNsQjtBQUNILENBQUM7QUFFRCwwQ0FBMEM7QUFDMUMsU0FBUyxhQUFhLENBQUMsVUFBMEIsRUFBRSxPQUEyQixFQUFFLElBQVM7SUFDdkYsSUFBSSxPQUFPLElBQUksSUFBSTtRQUFFLE9BQU87SUFDNUIsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQzFCLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO0tBQy9EO1NBQU0sSUFBSSxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssUUFBUSxFQUFFO1FBQ3hDLEtBQUssSUFBSSxHQUFHLElBQUksT0FBTyxFQUFFO1lBQ3ZCLElBQUksSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDLEVBQUU7Z0JBQ3JDLElBQUksS0FBSyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztnQkFDekIsS0FBSyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUM7Z0JBQ2pCLElBQUksSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUMzQixVQUFVLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDbkM7U0FDRjtLQUNGO1NBQU07UUFDTCxNQUFNLElBQUksS0FBSyxDQUFDLG1LQUFtSyxDQUFDLENBQUM7S0FDdEw7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29yZSwgRXJyb3JDYWxsYmFjayB9IGZyb20gJy4vY29yZSc7XHJcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gJy4vY29uZmlnJztcclxuaW1wb3J0IHsgQnJlZXplRXZlbnQgfSBmcm9tICcuL2V2ZW50JztcclxuaW1wb3J0IHsgYXNzZXJ0UGFyYW0sIGFzc2VydENvbmZpZywgUGFyYW0gfSBmcm9tICcuL2Fzc2VydC1wYXJhbSc7XHJcbmltcG9ydCB7IERhdGFUeXBlIH0gZnJvbSAnLi9kYXRhLXR5cGUnO1xyXG5pbXBvcnQgeyBFbnRpdHlBc3BlY3QsIENvbXBsZXhBc3BlY3QsIEVudGl0eSwgQ29tcGxleE9iamVjdCwgU3RydWN0dXJhbE9iamVjdCB9IGZyb20gJy4vZW50aXR5LWFzcGVjdCc7XHJcbmltcG9ydCB7IEVudGl0eUtleSB9IGZyb20gJy4vZW50aXR5LWtleSc7XHJcbmltcG9ydCB7IFZhbGlkYXRvciB9IGZyb20gJy4vdmFsaWRhdGUnO1xyXG5pbXBvcnQgeyBCcmVlemVFbnVtIH0gZnJvbSAnLi9lbnVtJztcclxuaW1wb3J0IHsgRGF0YVNlcnZpY2UgfSBmcm9tICcuL2RhdGEtc2VydmljZSc7XHJcbmltcG9ydCB7IE5hbWluZ0NvbnZlbnRpb24gfSBmcm9tICcuL25hbWluZy1jb252ZW50aW9uJztcclxuaW1wb3J0IHsgQ3NkbE1ldGFkYXRhUGFyc2VyIH0gZnJvbSAnLi9jc2RsLW1ldGFkYXRhLXBhcnNlcic7IC8vIFRPRE8gaXNvbGF0ZSB0aGlzIGxhdGVyO1xyXG5pbXBvcnQgeyBMb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnMgfSBmcm9tICcuL2xvY2FsLXF1ZXJ5LWNvbXBhcmlzb24tb3B0aW9ucyc7XHJcbmltcG9ydCB7IGRlZmF1bHRQcm9wZXJ0eUludGVyY2VwdG9yIH0gZnJvbSAnLi9kZWZhdWx0LXByb3BlcnR5LWludGVyY2VwdG9yJztcclxuXHJcbmV4cG9ydCB0eXBlIEVudGl0eVByb3BlcnR5ID0gRGF0YVByb3BlcnR5IHwgTmF2aWdhdGlvblByb3BlcnR5O1xyXG5leHBvcnQgdHlwZSBTdHJ1Y3R1cmFsVHlwZSA9IEVudGl0eVR5cGUgfCBDb21wbGV4VHlwZTtcclxuXHJcbi8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElTdHJ1Y3R1cmFsVHlwZU1hcCB7XHJcbiAgW2luZGV4OiBzdHJpbmddOiBTdHJ1Y3R1cmFsVHlwZTtcclxufVxyXG4vKiogS2VlcCB0cmFjayBvZiBjb25zdHJ1Y3RvcnMgYW5kIGluaXRpYWxpemVycyBmb3IgU3RydWN0dXJhbFR5cGVzICovXHJcbmludGVyZmFjZSBDdG9yUmVjb3JkIHsgXHJcbiAgY3RvcjogeyBuZXcgKCk6IFN0cnVjdHVyYWxPYmplY3QgfTtcclxuICBpbml0Rm4/OiBGdW5jdGlvbiB8IHN0cmluZzsgXHJcbiAgbm9UcmFja2luZ0ZuPzogRnVuY3Rpb247XHJcbn1cclxuXHJcbi8vIFRPRE86IGNvbnNpZGVyIGV4cG9zaW5nIGxhdGVyXHJcbi8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIElNZXRhZGF0YUpzb24ge1xyXG4gIG1ldGFkYXRhVmVyc2lvbjogc3RyaW5nO1xyXG4gIG5hbWU6IHN0cmluZztcclxuICBuYW1pbmdDb252ZW50aW9uOiBzdHJpbmc7XHJcbiAgbG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zOiBzdHJpbmc7XHJcbiAgZGF0YVNlcnZpY2VzOiBPYmplY3RbXTsgLy8gSURhdGFTZXJ2aWNlSnNvbltdXHJcbiAgc3RydWN0dXJhbFR5cGVzOiBPYmplY3RbXTsgLy8gSVN0cnVjdHVyYWxUeXBlSnNvbltdOyBcclxuICByZXNvdXJjZUVudGl0eVR5cGVNYXA6IE9iamVjdFtdOyAvLyBJUmVzb3VyY2VFbnRpdHlUeXBlSnNvbltdXHJcbiAgaW5jb21wbGV0ZVR5cGVNYXA6IE9iamVjdFtdO1xyXG59XHJcblxyXG4vKiogQ29uZmlndXJhdGlvbiBpbmZvIHRvIGJlIHBhc3NlZCB0byB0aGUgW1tNZXRhZGF0YVN0b3JlXV0gY29uc3RydWN0b3IgKi9cclxuZXhwb3J0IGludGVyZmFjZSBNZXRhZGF0YVN0b3JlQ29uZmlnIHtcclxuICAvKiogVGhlICBbW05hbWluZ0NvbnZlbnRpb25dXSBhc3NvY2lhdGVkIHdpdGggdGhpcyBNZXRhZGF0YVN0b3JlLiAqL1xyXG4gIG5hbWluZ0NvbnZlbnRpb24/OiBOYW1pbmdDb252ZW50aW9uO1xyXG4gIC8qKiBUaGUgIFtbTG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zXV0gYXNzb2NpYXRlZCB3aXRoIHRoaXMgTWV0YWRhdGFTdG9yZS4gKi9cclxuICBsb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnM/OiBMb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnM7XHJcbiAgc2VyaWFsaXplckZuPzogKHByb3A6IEVudGl0eVByb3BlcnR5LCB2YWw6IGFueSkgPT4gYW55O1xyXG4gIG5hbWU/OiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTWV0YWRhdGFGZXRjaGVkRXZlbnRBcmdzIHtcclxuICBtZXRhZGF0YVN0b3JlOiBNZXRhZGF0YVN0b3JlO1xyXG4gIGRhdGFTZXJ2aWNlOiBEYXRhU2VydmljZSB8IHN0cmluZztcclxuICByYXdNZXRhZGF0YTogYW55O1xyXG59XHJcblxyXG4vKipcclxuQW4gaW5zdGFuY2Ugb2YgdGhlIE1ldGFkYXRhU3RvcmUgY29udGFpbnMgYWxsIG9mIHRoZSBtZXRhZGF0YSBhYm91dCBhIGNvbGxlY3Rpb24gb2YgW1tFbnRpdHlUeXBlXV0ncy5cclxuTWV0YWRhdGFTdG9yZXMgbWF5IGJlIHNoYXJlZCBhY3Jvc3MgW1tFbnRpdHlNYW5hZ2VyXV0ncy4gIElmIGFuIEVudGl0eU1hbmFnZXIgaXMgY3JlYXRlZCB3aXRob3V0IGFuXHJcbmV4cGxpY2l0IE1ldGFkYXRhU3RvcmUsIHRoZSBNZXRhZGF0YVN0b3JlIGZyb20gdGhlIE1ldGFkYXRhU3RvcmUuZGVmYXVsdEluc3RhbmNlIHByb3BlcnR5IHdpbGwgYmUgdXNlZC5cclxuQGR5bmFtaWNcclxuKiovXHJcbmV4cG9ydCBjbGFzcyBNZXRhZGF0YVN0b3JlIHtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBkZWNsYXJlIF8kdHlwZU5hbWU6IHN0cmluZzsgLy8gb24gcHJvdG9cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgc3RhdGljIF9faWQgPSAwO1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIHN0YXRpYyBBTk9OVFlQRV9QUkVGSVggPSBcIl9JQl9cIjtcclxuICAvKiogVGhlIHZlcnNpb24gb2YgYW55IE1ldGFkYXRhU3RvcmVzIGNyZWF0ZWQgYnkgdGhpcyBjbGFzcyAqL1xyXG4gIHN0YXRpYyBtZXRhZGF0YVZlcnNpb24gPSAnMS4wLjUnO1xyXG5cclxuICBuYW1lOiBzdHJpbmc7XHJcbiAgZGF0YVNlcnZpY2VzOiBEYXRhU2VydmljZVtdO1xyXG5cclxuICAvKiogVGhlICBbW05hbWluZ0NvbnZlbnRpb25dXSBhc3NvY2lhdGVkIHdpdGggdGhpcyBNZXRhZGF0YVN0b3JlLiBfX1JlYWQgT25seV9fICovXHJcbiAgbmFtaW5nQ29udmVudGlvbjogTmFtaW5nQ29udmVudGlvbjtcclxuICAvKiogVGhlICBbW0xvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9uc11dIGFzc29jaWF0ZWQgd2l0aCB0aGlzIE1ldGFkYXRhU3RvcmUuIF9fUmVhZCBPbmx5X18gKi9cclxuICBsb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnM6IExvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9ucztcclxuICBzZXJpYWxpemVyRm4/OiAocHJvcDogRW50aXR5UHJvcGVydHksIHZhbDogYW55KSA9PiBhbnk7XHJcbiAgLyoqXHJcbiAgQW4gW1tCcmVlemVFdmVudF1dIHRoYXQgZmlyZXMgYWZ0ZXIgYSBNZXRhZGF0YVN0b3JlIGhhcyBjb21wbGV0ZWQgZmV0Y2hpbmcgbWV0YWRhdGEgZnJvbSBhIHJlbW90ZSBzZXJ2aWNlLlxyXG4gIFxyXG4gIEBldmVudEFyZ3MgLVxyXG4gICAgLSBtZXRhZGF0YVN0b3JlIC0gVGhlIE1ldGFkYXRhU3RvcmUgaW50byB3aGljaCB0aGUgbWV0YWRhdGEgd2FzIGZldGNoZWQuXHJcbiAgICAtIGRhdGFTZXJ2aWNlIC0gVGhlIFtbRGF0YVNlcnZpY2VdXSB0aGF0IG1ldGFkYXRhIHdhcyBmZXRjaGVkIGZyb20uXHJcbiAgICAtIHJhd01ldGFkYXRhIC0ge09iamVjdH0gVGhlIHJhdyBtZXRhZGF0YSByZXR1cm5lZCBmcm9tIHRoZSBzZXJ2aWNlLiAoSXQgd2lsbCBoYXZlIGFscmVhZHkgYmVlbiBwcm9jZXNzZWQgYnkgdGhpcyBwb2ludCkuXHJcbiAgPiAgICAgIGxldCBtcyA9IG15RW50aXR5TWFuYWdlci5tZXRhZGF0YVN0b3JlO1xyXG4gID4gICAgICBtcy5tZXRhZGF0YUZldGNoZWQuc3Vic2NyaWJlKGZ1bmN0aW9uKGFyZ3MpIHtcclxuICA+ICAgICAgICAgIGxldCBtZXRhZGF0YVN0b3JlID0gYXJncy5tZXRhZGF0YVN0b3JlO1xyXG4gID4gICAgICAgICAgbGV0IGRhdGFTZXJ2aWNlID0gYXJncy5kYXRhU2VydmljZTtcclxuICA+ICAgICAgfSk7XHJcbiAgQGV2ZW50XHJcbiAgKiovXHJcbiAgbWV0YWRhdGFGZXRjaGVkOiBCcmVlemVFdmVudDxNZXRhZGF0YUZldGNoZWRFdmVudEFyZ3M+O1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9yZXNvdXJjZUVudGl0eVR5cGVNYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2VudGl0eVR5cGVSZXNvdXJjZU1hcDogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwga2V5IGlzIHF1YWxpZmllZCBzdHJ1Y3R1cmFsdHlwZSBuYW1lIC0gdmFsdWUgaXMgc3RydWN0dXJhbFR5cGUuICggc3RydWN0dXJhbCA9IGVudGl0eVR5cGUgb3IgY29tcGxleFR5cGUpLiAqL1xyXG4gIF9zdHJ1Y3R1cmFsVHlwZU1hcDogSVN0cnVjdHVyYWxUeXBlTWFwO1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCBrZXkgaXMgc2hvcnROYW1lLCB2YWx1ZSBpcyBxdWFsaWZpZWQgbmFtZSAtIGRvZXMgbm90IG5lZWQgdG8gYmUgc2VyaWFsaXplZC4gKiovXHJcbiAgX3Nob3J0TmFtZU1hcDogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwga2V5IGlzIGVpdGhlciBzaG9ydCBvciBxdWFsIHR5cGUgbmFtZSAtIHZhbHVlIGlzIGN0b3I7ICoqL1xyXG4gIF9jdG9yUmVnaXN0cnk6IFJlY29yZDxzdHJpbmcsIEN0b3JSZWNvcmQ+O1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCBrZXkgaXMgZW50aXR5VHlwZU5hbWU7IHZhbHVlIGlzIGFycmF5IG9mIG5hdiBwcm9wcyAqKi9cclxuICBfaW5jb21wbGV0ZVR5cGVNYXA6IFJlY29yZDxzdHJpbmcsIE5hdmlnYXRpb25Qcm9wZXJ0eVtdPjtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKiovXHJcbiAgX2luY29tcGxldGVDb21wbGV4VHlwZU1hcDogUmVjb3JkPHN0cmluZywgRGF0YVByb3BlcnR5W10+O1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCB7IGpzb246IGFueSwgc3R5cGU6IFN0cnVjdHVyYWxUeXBlIH1bXSB8IHsgZW50aXR5VHlwZTogRW50aXR5VHlwZSwgY3NkbEVudGl0eVR5cGU6IGFueSB9W10gKiovXHJcbiAgX2RlZmVycmVkVHlwZXM6IFJlY29yZDxzdHJpbmcsIGFueT47XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICoqL1xyXG4gIF9pZDogbnVtYmVyO1xyXG5cclxuICAvKipcclxuICBDb25zdHJ1Y3RzIGEgbmV3IE1ldGFkYXRhU3RvcmUuXHJcbiAgXHJcbiAgPiAgICAgbGV0IG1zID0gbmV3IE1ldGFkYXRhU3RvcmUoKTtcclxuXHJcbiAgVGhlIHN0b3JlIGNhbiB0aGVuIGJlIGFzc29jaWF0ZWQgd2l0aCBhbiBFbnRpdHlNYW5hZ2VyXHJcbiAgPiAgICAgbGV0IGVudGl0eU1hbmFnZXIgPSBuZXcgRW50aXR5TWFuYWdlcigge1xyXG4gID4gICAgICAgICBzZXJ2aWNlTmFtZTogXCJicmVlemUvTm9ydGh3aW5kSUJNb2RlbFwiLCBcclxuICA+ICAgICAgICAgbWV0YWRhdGFTdG9yZTogbXMgXHJcbiAgPiAgICAgfSk7XHJcblxyXG4gIG9yIGZvciBhbiBleGlzdGluZyBFbnRpdHlNYW5hZ2VyXHJcbiAgPiAgICAvLyBBc3N1bWUgZW0xIGlzIGFuIGV4aXN0aW5nIEVudGl0eU1hbmFnZXJcclxuICA+ICAgIGVtMS5zZXRQcm9wZXJ0aWVzKCB7IG1ldGFkYXRhU3RvcmU6IG1zIH0pO1xyXG4gIFxyXG4gIEBwYXJhbSBjb25maWcgLSBDb25maWd1cmF0aW9uIHNldHRpbmdzIC5cclxuICAgIC0gbmFtaW5nQ29udmVudGlvbiAtIChkZWZhdWx0PU5hbWluZ0NvbnZlbnRpb24uZGVmYXVsdEluc3RhbmNlKSBOYW1pbmdDb252ZW50aW9uIHRvIGJlIHVzZWQgaW4gbWFwcGluZyBwcm9wZXJ0eSBuYW1lc1xyXG4gIGJldHdlZW4gY2xpZW50IGFuZCBzZXJ2ZXIuIFVzZXMgdGhlIE5hbWluZ0NvbnZlbnRpb24uZGVmYXVsdEluc3RhbmNlIGlmIG5vdCBzcGVjaWZpZWQuXHJcbiAgICAtIGxvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9ucyAtIChkZWZhdWx0PUxvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9ucy5kZWZhdWx0SW5zdGFuY2UpIFRoZSBMb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnMgdG8gYmVcclxuICB1c2VkIHdoZW4gcGVyZm9ybWluZyBcImxvY2FsIHF1ZXJpZXNcIiBpbiBvcmRlciB0byBtYXRjaCB0aGUgc2VtYW50aWNzIG9mIHF1ZXJpZXMgYWdhaW5zdCBhIHJlbW90ZSBzZXJ2aWNlLlxyXG4gICAgLSBzZXJpYWxpemVyRm4gLSBBIGZ1bmN0aW9uIHRoYXQgaXMgdXNlZCB0byBtZWRpYXRlIHRoZSBzZXJpYWxpemF0aW9uIG9mIGluc3RhbmNlcyBvZiB0aGlzIHR5cGUuXHJcbiAgKiovXHJcbiAgY29uc3RydWN0b3IoY29uZmlnPzogTWV0YWRhdGFTdG9yZUNvbmZpZykge1xyXG4gICAgY29uZmlnID0gY29uZmlnIHx8IHt9O1xyXG4gICAgYXNzZXJ0Q29uZmlnKGNvbmZpZylcclxuICAgICAgLndoZXJlUGFyYW0oXCJuYW1pbmdDb252ZW50aW9uXCIpLmlzT3B0aW9uYWwoKS5pc0luc3RhbmNlT2YoTmFtaW5nQ29udmVudGlvbikud2l0aERlZmF1bHQoTmFtaW5nQ29udmVudGlvbi5kZWZhdWx0SW5zdGFuY2UpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwibG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zXCIpLmlzT3B0aW9uYWwoKS5pc0luc3RhbmNlT2YoTG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zKS53aXRoRGVmYXVsdChMb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnMuZGVmYXVsdEluc3RhbmNlKVxyXG4gICAgICAud2hlcmVQYXJhbShcInNlcmlhbGl6ZXJGblwiKS5pc09wdGlvbmFsKCkuaXNGdW5jdGlvbigpXHJcbiAgICAgIC5hcHBseUFsbCh0aGlzKTtcclxuICAgIHRoaXMuZGF0YVNlcnZpY2VzID0gW107IC8vIGFycmF5IG9mIGRhdGFTZXJ2aWNlcztcclxuICAgIHRoaXMuX3Jlc291cmNlRW50aXR5VHlwZU1hcCA9IHt9OyAvLyBrZXkgaXMgcmVzb3VyY2UgbmFtZSAtIHZhbHVlIGlzIHF1YWxpZmllZCBlbnRpdHlUeXBlIG5hbWVcclxuICAgIHRoaXMuX3N0cnVjdHVyYWxUeXBlTWFwID0ge307IC8vIGtleSBpcyBxdWFsaWZpZWQgc3RydWN0dXJhbHR5cGUgbmFtZSAtIHZhbHVlIGlzIHN0cnVjdHVyYWxUeXBlLiAoIHN0cnVjdHVyYWwgPSBlbnRpdHlUeXBlIG9yIGNvbXBsZXhUeXBlKS5cclxuICAgIHRoaXMuX3Nob3J0TmFtZU1hcCA9IHt9OyAvLyBrZXkgaXMgc2hvcnROYW1lLCB2YWx1ZSBpcyBxdWFsaWZpZWQgbmFtZSAtIGRvZXMgbm90IG5lZWQgdG8gYmUgc2VyaWFsaXplZC5cclxuICAgIHRoaXMuX2N0b3JSZWdpc3RyeSA9IHt9OyAvLyBrZXkgaXMgZWl0aGVyIHNob3J0IG9yIHF1YWwgdHlwZSBuYW1lIC0gdmFsdWUgaXMgY3RvcjtcclxuXHJcbiAgICB0aGlzLl9pbmNvbXBsZXRlVHlwZU1hcCA9IHt9OyAvLyBrZXkgaXMgZW50aXR5VHlwZU5hbWU7IHZhbHVlIGlzIGFycmF5IG9mIG5hdiBwcm9wc1xyXG4gICAgdGhpcy5faW5jb21wbGV0ZUNvbXBsZXhUeXBlTWFwID0ge307IC8vIGtleSBpcyBjb21wbGV4VHlwZU5hbWU7IHZhbHVlIGlzIGFycmF5IG9mIGNvbXBsZXhUeXBlIHByb3BzXHJcbiAgICB0aGlzLl9pZCA9IE1ldGFkYXRhU3RvcmUuX19pZCsrO1xyXG4gICAgdGhpcy5tZXRhZGF0YUZldGNoZWQgPSBuZXcgQnJlZXplRXZlbnQoXCJtZXRhZGF0YUZldGNoZWRcIiwgdGhpcyk7XHJcblxyXG4gIH1cclxuXHJcbiAgLy8gbmVlZHMgdG8gYmUgbWFkZSBhdmFpbCB0byBkYXRhU2VydmljZS54eHggZmlsZXNcclxuICBzdGF0aWMgbm9ybWFsaXplVHlwZU5hbWUgPSBjb3JlLm1lbW9pemUoZnVuY3Rpb24gKHJhd1R5cGVOYW1lOiBzdHJpbmcpIHtcclxuICAgIHJldHVybiByYXdUeXBlTmFtZSAmJiBNZXRhZGF0YVN0b3JlLnBhcnNlVHlwZU5hbWUocmF3VHlwZU5hbWUpLnR5cGVOYW1lO1xyXG4gIH0pO1xyXG4gIC8vIGZvciBkZWJ1Z2dpbmcgdXNlIHRoZSBsaW5lIGJlbG93IGluc3RlYWQuXHJcbiAgLy9jdG9yLm5vcm1hbGl6ZVR5cGVOYW1lID0gZnVuY3Rpb24gKHJhd1R5cGVOYW1lKSB7IHJldHVybiBwYXJzZVR5cGVOYW1lKHJhd1R5cGVOYW1lKS50eXBlTmFtZTsgfTtcclxuXHJcbiAgLyoqXHJcbiAgR2VuZXJhbCBwdXJwb3NlIHByb3BlcnR5IHNldCBtZXRob2RcclxuICBcclxuICA+ICAgICAvLyBhc3N1bWUgZW0xIGlzIGFuIEVudGl0eU1hbmFnZXIgY29udGFpbmluZyBhIG51bWJlciBvZiBleGlzdGluZyBlbnRpdGllcy5cclxuICA+ICAgICBlbTEubWV0YWRhdGFTdG9yZS5zZXRQcm9wZXJ0aWVzKCB7XHJcbiAgPiAgICAgICAgIHZlcnNpb246IFwiNi4xLjNcIixcclxuICA+ICAgICAgICAgc2VyaWFsaXplckZuOiBmdW5jdGlvbihwcm9wLCB2YWx1ZSkge1xyXG4gID4gICAgICAgICByZXR1cm4gKHByb3AuaXNVbm1hcHBlZCkgPyB1bmRlZmluZWQgOiB2YWx1ZTtcclxuICA+ICAgICAgICAgfVxyXG4gID4gICAgICl9O1xyXG4gIEBwYXJhbSBjb25maWcgLSAgQW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHNlbGVjdGVkIHByb3BlcnRpZXMgYW5kIHZhbHVlcyB0byBzZXQuXHJcbiAgKiovXHJcbiAgc2V0UHJvcGVydGllcyhjb25maWc6IE1ldGFkYXRhU3RvcmVDb25maWcpIHtcclxuICAgIGFzc2VydENvbmZpZyhjb25maWcpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwibmFtZVwiKS5pc1N0cmluZygpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAud2hlcmVQYXJhbShcInNlcmlhbGl6ZXJGblwiKS5pc0Z1bmN0aW9uKCkuaXNPcHRpb25hbCgpXHJcbiAgICAgIC5hcHBseUFsbCh0aGlzKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIEFkZHMgYSBEYXRhU2VydmljZSB0byB0aGlzIE1ldGFkYXRhU3RvcmUuIElmIGEgRGF0YVNlcnZpY2Ugd2l0aCB0aGUgc2FtZSBzZXJ2aWNlTmFtZSBpcyBhbHJlYWR5XHJcbiAgaW4gdGhlIE1ldGFkYXRhU3RvcmUgYW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLlxyXG4gIEBwYXJhbSBkYXRhU2VydmljZSAtIFRoZSBbW0RhdGFTZXJ2aWNlXV0gdG8gYWRkXHJcbiAgQHBhcmFtIHNob3VsZE92ZXJ3cml0ZSAtIChkZWZhdWx0PWZhbHNlKSBQZXJtaXQgb3ZlcndyaXRlIG9mIGV4aXN0aW5nIERhdGFTZXJ2aWNlIHJhdGhlciB0aGFuIHRocm93IGV4Y2VwdGlvblxyXG4gICoqL1xyXG4gIGFkZERhdGFTZXJ2aWNlKGRhdGFTZXJ2aWNlOiBEYXRhU2VydmljZSwgc2hvdWxkT3ZlcndyaXRlPzogYm9vbGVhbikge1xyXG4gICAgYXNzZXJ0UGFyYW0oZGF0YVNlcnZpY2UsIFwiZGF0YVNlcnZpY2VcIikuaXNJbnN0YW5jZU9mKERhdGFTZXJ2aWNlKS5jaGVjaygpO1xyXG4gICAgYXNzZXJ0UGFyYW0oc2hvdWxkT3ZlcndyaXRlLCBcInNob3VsZE92ZXJ3cml0ZVwiKS5pc0Jvb2xlYW4oKS5pc09wdGlvbmFsKCkuY2hlY2soKTtcclxuICAgIGxldCBpeCA9IHRoaXMuX2dldERhdGFTZXJ2aWNlSW5kZXgoZGF0YVNlcnZpY2Uuc2VydmljZU5hbWUpO1xyXG4gICAgaWYgKGl4ID49IDApIHtcclxuICAgICAgaWYgKCEhc2hvdWxkT3ZlcndyaXRlKSB7XHJcbiAgICAgICAgdGhpcy5kYXRhU2VydmljZXNbaXhdID0gZGF0YVNlcnZpY2U7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQSBkYXRhU2VydmljZSB3aXRoIHRoaXMgbmFtZSAnXCIgKyBkYXRhU2VydmljZS5zZXJ2aWNlTmFtZSArIFwiJyBhbHJlYWR5IGV4aXN0cyBpbiB0aGlzIE1ldGFkYXRhU3RvcmVcIik7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZGF0YVNlcnZpY2VzLnB1c2goZGF0YVNlcnZpY2UpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2dldERhdGFTZXJ2aWNlSW5kZXgoc2VydmljZU5hbWU6IHN0cmluZykge1xyXG4gICAgcmV0dXJuIGNvcmUuYXJyYXlJbmRleE9mKHRoaXMuZGF0YVNlcnZpY2VzLCBmdW5jdGlvbiAoZHMpIHtcclxuICAgICAgcmV0dXJuIGRzLnNlcnZpY2VOYW1lID09PSBzZXJ2aWNlTmFtZTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgQWRkcyBhbiBFbnRpdHlUeXBlIHRvIHRoaXMgTWV0YWRhdGFTdG9yZS4gIE5vIGFkZGl0aW9uYWwgcHJvcGVydGllcyBtYXkgYmUgYWRkZWQgdG8gdGhlIEVudGl0eVR5cGUgYWZ0ZXIgaXRzIGhhc1xyXG4gIGJlZW4gYWRkZWQgdG8gdGhlIE1ldGFkYXRhU3RvcmUuXHJcbiAgQHBhcmFtIHN0cnVjdHVyYWxUeXBlIC0gVGhlIEVudGl0eVR5cGUgb3IgQ29tcGxleFR5cGUgdG8gYWRkXHJcbiAgKiovXHJcbiAgYWRkRW50aXR5VHlwZShzdHlwZTogU3RydWN0dXJhbFR5cGUgfCBFbnRpdHlUeXBlQ29uZmlnIHwgQ29tcGxleFR5cGVDb25maWcpIHtcclxuICAgIGxldCBzdHJ1Y3R1cmFsVHlwZTogU3RydWN0dXJhbFR5cGU7XHJcbiAgICBpZiAoc3R5cGUgaW5zdGFuY2VvZiBFbnRpdHlUeXBlIHx8IHN0eXBlIGluc3RhbmNlb2YgQ29tcGxleFR5cGUpIHtcclxuICAgICAgc3RydWN0dXJhbFR5cGUgPSBzdHlwZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHN0cnVjdHVyYWxUeXBlID0gKHN0eXBlIGFzIGFueSkuaXNDb21wbGV4VHlwZSA/IG5ldyBDb21wbGV4VHlwZShzdHlwZSkgOiBuZXcgRW50aXR5VHlwZShzdHlwZSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaWYgKCFzdHJ1Y3R1cmFsVHlwZS5pc0NvbXBsZXhUeXBlKSB7IC8vIHNhbWUgYXMgYmVsb3cgYnV0IGlzbid0IGEgJ3R5cGUgZ3VhcmQnXHJcbiAgICBpZiAoc3RydWN0dXJhbFR5cGUgaW5zdGFuY2VvZiBFbnRpdHlUeXBlKSB7XHJcbiAgICAgIGlmIChzdHJ1Y3R1cmFsVHlwZS5iYXNlVHlwZU5hbWUgJiYgIXN0cnVjdHVyYWxUeXBlLmJhc2VFbnRpdHlUeXBlKSB7XHJcbiAgICAgICAgbGV0IGJhc2VFbnRpdHlUeXBlID0gdGhpcy5fZ2V0U3RydWN0dXJhbFR5cGUoc3RydWN0dXJhbFR5cGUuYmFzZVR5cGVOYW1lLCB0cnVlKTtcclxuICAgICAgICAvLyBzYWZlIGNhc3QgYmVjYXVzZSB3ZSBrbm93IHRoYXQgYmFzZUVudGl0eVR5cGUgbXVzdCBiZSBhbiBFbnRpdHlUeXBlIGlmIHRoZSBzdHJ1Y3R1cmFsVHlwZSBpcyBhbiBFbnRpdHlUeXBlXHJcbiAgICAgICAgc3RydWN0dXJhbFR5cGUuX3VwZGF0ZUZyb21CYXNlKGJhc2VFbnRpdHlUeXBlIGFzIEVudGl0eVR5cGUpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChzdHJ1Y3R1cmFsVHlwZS5rZXlQcm9wZXJ0aWVzLmxlbmd0aCA9PT0gMCAmJiAhc3RydWN0dXJhbFR5cGUuaXNBYnN0cmFjdCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVuYWJsZSB0byBhZGQgXCIgKyBzdHJ1Y3R1cmFsVHlwZS5uYW1lICtcclxuICAgICAgICAgIFwiIHRvIHRoaXMgTWV0YWRhdGFTdG9yZS4gIEFuIEVudGl0eVR5cGUgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBwcm9wZXJ0eSBkZXNpZ25hdGVkIGFzIGEga2V5IHByb3BlcnR5IC0gU2VlIHRoZSAnRGF0YVByb3BlcnR5LmlzUGFydE9mS2V5JyBwcm9wZXJ0eS5cIik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzdHJ1Y3R1cmFsVHlwZS5tZXRhZGF0YVN0b3JlID0gdGhpcztcclxuICAgIC8vIGRvbid0IHJlZ2lzdGVyIGFub24gdHlwZXNcclxuICAgIGlmICghKHN0cnVjdHVyYWxUeXBlIGFzIGFueSkuaXNBbm9ueW1vdXMpIHtcclxuICAgICAgaWYgKHRoaXMuX3N0cnVjdHVyYWxUeXBlTWFwW3N0cnVjdHVyYWxUeXBlLm5hbWVdKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVHlwZSBcIiArIHN0cnVjdHVyYWxUeXBlLm5hbWUgKyBcIiBhbHJlYWR5IGV4aXN0cyBpbiB0aGlzIE1ldGFkYXRhU3RvcmUuXCIpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLl9zdHJ1Y3R1cmFsVHlwZU1hcFtzdHJ1Y3R1cmFsVHlwZS5uYW1lXSA9IHN0cnVjdHVyYWxUeXBlO1xyXG4gICAgICB0aGlzLl9zaG9ydE5hbWVNYXBbc3RydWN0dXJhbFR5cGUuc2hvcnROYW1lXSA9IHN0cnVjdHVyYWxUeXBlLm5hbWU7XHJcbiAgICB9XHJcblxyXG4gICAgc3RydWN0dXJhbFR5cGUuZ2V0UHJvcGVydGllcygpLmZvckVhY2gocCA9PiB7XHJcbiAgICAgIHN0cnVjdHVyYWxUeXBlLl91cGRhdGVOYW1lcyhwKTtcclxuICAgICAgaWYgKCFwLmlzVW5tYXBwZWQpIHtcclxuICAgICAgICBzdHJ1Y3R1cmFsVHlwZS5fbWFwcGVkUHJvcGVydGllc0NvdW50Kys7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIHN0cnVjdHVyYWxUeXBlLl91cGRhdGVDcHMoKTtcclxuXHJcbiAgICAvLyAnaXNFbnRpdHlUeXBlJyBpcyBhIHR5cGUgZ3VhcmRcclxuICAgIGlmIChzdHJ1Y3R1cmFsVHlwZSBpbnN0YW5jZW9mIEVudGl0eVR5cGUpIHtcclxuICAgICAgc3RydWN0dXJhbFR5cGUuX3VwZGF0ZU5wcygpO1xyXG4gICAgICAvLyBnaXZlIHRoZSB0eXBlIGl0J3MgYmFzZSdzIHJlc291cmNlIG5hbWUgaWYgaXQgZG9lc24ndCBoYXZlIGl0cyBvd24uXHJcbiAgICAgIGxldCBkZWZSZXNvdXJjZU5hbWUgPSBzdHJ1Y3R1cmFsVHlwZS5kZWZhdWx0UmVzb3VyY2VOYW1lIHx8IChzdHJ1Y3R1cmFsVHlwZS5iYXNlRW50aXR5VHlwZSAmJiBzdHJ1Y3R1cmFsVHlwZS5iYXNlRW50aXR5VHlwZS5kZWZhdWx0UmVzb3VyY2VOYW1lKTtcclxuICAgICAgaWYgKGRlZlJlc291cmNlTmFtZSAmJiAhdGhpcy5nZXRFbnRpdHlUeXBlTmFtZUZvclJlc291cmNlTmFtZShkZWZSZXNvdXJjZU5hbWUpKSB7XHJcbiAgICAgICAgdGhpcy5zZXRFbnRpdHlUeXBlRm9yUmVzb3VyY2VOYW1lKGRlZlJlc291cmNlTmFtZSwgc3RydWN0dXJhbFR5cGUubmFtZSk7XHJcbiAgICAgIH1cclxuICAgICAgc3RydWN0dXJhbFR5cGUuZGVmYXVsdFJlc291cmNlTmFtZSA9IGRlZlJlc291cmNlTmFtZTtcclxuICAgICAgLy8gY2hlY2sgaWYgdGhpcyBzdHJ1Y3R1cmFsIHR5cGUncyBuYW1lLCBzaG9ydCB2ZXJzaW9uIG9yIHF1YWxpZmllZCB2ZXJzaW9uIGhhcyBhIHJlZ2lzdGVyZWQgY3Rvci5cclxuICAgICAgc3RydWN0dXJhbFR5cGUuZ2V0RW50aXR5Q3RvcigpO1xyXG4gICAgfVxyXG5cclxuICB9XHJcblxyXG5cclxuICAvKipcclxuICBFeHBvcnRzIHRoaXMgTWV0YWRhdGFTdG9yZSB0byBhIHNlcmlhbGl6ZWQgc3RyaW5nIGFwcHJvcHJpYXRlIGZvciBsb2NhbCBzdG9yYWdlLiAgIFRoaXMgb3BlcmF0aW9uIGlzIGFsc28gY2FsbGVkXHJcbiAgaW50ZXJuYWxseSB3aGVuIGV4cG9ydGluZyBhbiBFbnRpdHlNYW5hZ2VyLlxyXG4gID4gICAgICAvLyBhc3N1bWUgbXMgaXMgYSBwcmV2aW91c2x5IGNyZWF0ZWQgTWV0YWRhdGFTdG9yZVxyXG4gID4gICAgICBsZXQgbWV0YWRhdGFBc1N0cmluZyA9IG1zLmV4cG9ydE1ldGFkYXRhKCk7XHJcbiAgPiAgICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbShcIm1ldGFkYXRhXCIsIG1ldGFkYXRhQXNTdHJpbmcpO1xyXG4gID4gICAgICAvLyBhbmQgbGF0ZXIsIHVzdWFsbHkgaW4gYSBkaWZmZXJlbnQgc2Vzc2lvbiBpbXBvcnRlZFxyXG4gID4gICAgICBsZXQgbWV0YWRhdGFGcm9tU3RvcmFnZSA9IHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbShcIm1ldGFkYXRhXCIpO1xyXG4gID4gICAgICBsZXQgbmV3TWV0YWRhdGFTdG9yZSA9IG5ldyBNZXRhZGF0YVN0b3JlKCk7XHJcbiAgPiAgICAgIG5ld01ldGFkYXRhU3RvcmUuaW1wb3J0TWV0YWRhdGEobWV0YWRhdGFGcm9tU3RvcmFnZSk7XHJcbiAgQHJldHVybiBBIHNlcmlhbGl6ZWQgdmVyc2lvbiBvZiB0aGlzIE1ldGFkYXRhU3RvcmUgdGhhdCBtYXkgYmUgc3RvcmVkIGxvY2FsbHkgYW5kIGxhdGVyIHJlc3RvcmVkLlxyXG4gICoqL1xyXG4gIGV4cG9ydE1ldGFkYXRhKCkge1xyXG4gICAgbGV0IHJlc3VsdCA9IEpTT04uc3RyaW5naWZ5KHtcclxuICAgICAgXCJtZXRhZGF0YVZlcnNpb25cIjogTWV0YWRhdGFTdG9yZS5tZXRhZGF0YVZlcnNpb24sXHJcbiAgICAgIFwibmFtZVwiOiB0aGlzLm5hbWUsXHJcbiAgICAgIFwibmFtaW5nQ29udmVudGlvblwiOiB0aGlzLm5hbWluZ0NvbnZlbnRpb24ubmFtZSxcclxuICAgICAgXCJsb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnNcIjogdGhpcy5sb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnMubmFtZSxcclxuICAgICAgXCJkYXRhU2VydmljZXNcIjogdGhpcy5kYXRhU2VydmljZXMsXHJcbiAgICAgIFwic3RydWN0dXJhbFR5cGVzXCI6IGNvcmUub2JqZWN0TWFwKHRoaXMuX3N0cnVjdHVyYWxUeXBlTWFwKSxcclxuICAgICAgXCJyZXNvdXJjZUVudGl0eVR5cGVNYXBcIjogdGhpcy5fcmVzb3VyY2VFbnRpdHlUeXBlTWFwXHJcbiAgICB9LCBudWxsLCBjb25maWcuc3RyaW5naWZ5UGFkKTtcclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBJbXBvcnRzIGEgcHJldmlvdXNseSBleHBvcnRlZCBzZXJpYWxpemVkIE1ldGFkYXRhU3RvcmUgaW50byB0aGlzIE1ldGFkYXRhU3RvcmUuXHJcbiAgICBcclxuICA+ICAgICAgLy8gYXNzdW1lIG1zIGlzIGEgcHJldmlvdXNseSBjcmVhdGVkIE1ldGFkYXRhU3RvcmVcclxuICA+ICAgICAgbGV0IG1ldGFkYXRhQXNTdHJpbmcgPSBtcy5leHBvcnRNZXRhZGF0YSgpO1xyXG4gID4gICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnNldEl0ZW0oXCJtZXRhZGF0YVwiLCBtZXRhZGF0YUFzU3RyaW5nKTtcclxuICA+ICAgICAgLy8gYW5kIGxhdGVyLCB1c3VhbGx5IGluIGEgZGlmZmVyZW50IHNlc3Npb25cclxuICA+ICAgICAgbGV0IG1ldGFkYXRhRnJvbVN0b3JhZ2UgPSB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJtZXRhZGF0YVwiKTtcclxuICA+ICAgICAgbGV0IG5ld01ldGFkYXRhU3RvcmUgPSBuZXcgTWV0YWRhdGFTdG9yZSgpO1xyXG4gID4gICAgICBuZXdNZXRhZGF0YVN0b3JlLmltcG9ydE1ldGFkYXRhKG1ldGFkYXRhRnJvbVN0b3JhZ2UpO1xyXG4gIEBwYXJhbSBleHBvcnRlZE1ldGFkYXRhIC0gQSBwcmV2aW91c2x5IGV4cG9ydGVkIE1ldGFkYXRhU3RvcmUuXHJcbiAgQHBhcmFtIGFsbG93TWVyZ2UgLSAgQWxsb3dzIGN1c3RvbSBtZXRhZGF0YSB0byBiZSBtZXJnZWQgaW50byBleGlzdGluZyBtZXRhZGF0YSB0eXBlcy5cclxuICBAcmV0dXJuIFRoaXMgTWV0YWRhdGFTdG9yZS5cclxuICBAY2hhaW5hYmxlXHJcbiAgKiovXHJcbiAgaW1wb3J0TWV0YWRhdGEoZXhwb3J0ZWRNZXRhZGF0YTogc3RyaW5nIHwgT2JqZWN0LCBhbGxvd01lcmdlOiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgIGFzc2VydFBhcmFtKGFsbG93TWVyZ2UsIFwiYWxsb3dNZXJnZVwiKS5pc09wdGlvbmFsKCkuaXNCb29sZWFuKCkuY2hlY2soKTtcclxuICAgIHRoaXMuX2RlZmVycmVkVHlwZXMgPSB7fTtcclxuICAgIC8vIGluc3VyZSB0aGF0IHdlIGRvbid0IG11dGF0ZSBpbmNvbWluZyBleHBvcnRlZE1ldGFkYXRhICggaWYgaXRzIGFuIG9iamVjdClcclxuICAgIGxldCBtZXRhZGF0YUFzU3RyaW5nID0gKHR5cGVvZiAoZXhwb3J0ZWRNZXRhZGF0YSkgPT09IFwic3RyaW5nXCIpID8gZXhwb3J0ZWRNZXRhZGF0YSA6IEpTT04uc3RyaW5naWZ5KGV4cG9ydGVkTWV0YWRhdGEpO1xyXG4gICAgY29uc3QgbWV0YWRhdGFKc29uID0gSlNPTi5wYXJzZShtZXRhZGF0YUFzU3RyaW5nKTtcclxuXHJcbiAgICBpZiAobWV0YWRhdGFKc29uLnNjaGVtYSkge1xyXG4gICAgICByZXR1cm4gQ3NkbE1ldGFkYXRhUGFyc2VyLnBhcnNlKHRoaXMsIG1ldGFkYXRhSnNvbi5zY2hlbWEsIG1ldGFkYXRhSnNvbi5hbHRNZXRhZGF0YSk7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IGpzb24gPSBtZXRhZGF0YUpzb24gYXMgSU1ldGFkYXRhSnNvbjtcclxuICAgIGlmIChqc29uLm1ldGFkYXRhVmVyc2lvbiAmJiBqc29uLm1ldGFkYXRhVmVyc2lvbiAhPT0gTWV0YWRhdGFTdG9yZS5tZXRhZGF0YVZlcnNpb24pIHtcclxuICAgICAgbGV0IG1zZyA9IGNvcmUuZm9ybWF0U3RyaW5nKFwiQ2Fubm90IGltcG9ydCBtZXRhZGF0YSB3aXRoIGEgZGlmZmVyZW50ICdtZXRhZGF0YVZlcnNpb24nICglMSkgdGhhbiB0aGUgY3VycmVudCAnTWV0YWRhdGFTdG9yZS5tZXRhZGF0YVZlcnNpb24nICglMikgXCIsXHJcbiAgICAgICAganNvbi5tZXRhZGF0YVZlcnNpb24sIE1ldGFkYXRhU3RvcmUubWV0YWRhdGFWZXJzaW9uKTtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IG5jTmFtZSA9IGpzb24ubmFtaW5nQ29udmVudGlvbjtcclxuICAgIGxldCBscWNvTmFtZSA9IGpzb24ubG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zO1xyXG4gICAgaWYgKHRoaXMuaXNFbXB0eSgpKSB7XHJcbiAgICAgIHRoaXMubmFtaW5nQ29udmVudGlvbiA9IGNvbmZpZy5fZmV0Y2hPYmplY3QoTmFtaW5nQ29udmVudGlvbiwgbmNOYW1lKSB8fCB0aGlzLm5hbWluZ0NvbnZlbnRpb247XHJcbiAgICAgIHRoaXMubG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zID0gY29uZmlnLl9mZXRjaE9iamVjdChMb2NhbFF1ZXJ5Q29tcGFyaXNvbk9wdGlvbnMsIGxxY29OYW1lKSB8fCB0aGlzLmxvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9ucztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmIChuY05hbWUgJiYgdGhpcy5uYW1pbmdDb252ZW50aW9uLm5hbWUgIT09IG5jTmFtZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBpbXBvcnQgbWV0YWRhdGEgd2l0aCBhIGRpZmZlcmVudCAnbmFtaW5nQ29udmVudGlvbicgZnJvbSB0aGUgY3VycmVudCBNZXRhZGF0YVN0b3JlXCIpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChscWNvTmFtZSAmJiB0aGlzLmxvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9ucy5uYW1lICE9PSBscWNvTmFtZSkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBpbXBvcnQgbWV0YWRhdGEgd2l0aCBkaWZmZXJlbnQgJ2xvY2FsUXVlcnlDb21wYXJpc29uT3B0aW9ucycgZnJvbSB0aGUgY3VycmVudCBNZXRhZGF0YVN0b3JlXCIpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy9ub2luc3BlY3Rpb24gSlNIaW50XHJcbiAgICBqc29uLmRhdGFTZXJ2aWNlcyAmJiBqc29uLmRhdGFTZXJ2aWNlcy5mb3JFYWNoKChkcykgPT4ge1xyXG4gICAgICBsZXQgcmVhbERzID0gRGF0YVNlcnZpY2UuZnJvbUpTT04oZHMpO1xyXG4gICAgICB0aGlzLmFkZERhdGFTZXJ2aWNlKHJlYWxEcywgdHJ1ZSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICBqc29uLnN0cnVjdHVyYWxUeXBlcyAmJiBqc29uLnN0cnVjdHVyYWxUeXBlcy5mb3JFYWNoKChzdHlwZSkgPT4ge1xyXG4gICAgICBzdHJ1Y3R1cmFsVHlwZUZyb21Kc29uKHRoaXMsIHN0eXBlLCBhbGxvd01lcmdlKTtcclxuICAgIH0pO1xyXG4gICAgY29yZS5leHRlbmQodGhpcy5fcmVzb3VyY2VFbnRpdHlUeXBlTWFwLCBqc29uLnJlc291cmNlRW50aXR5VHlwZU1hcCk7XHJcbiAgICBjb3JlLmV4dGVuZCh0aGlzLl9pbmNvbXBsZXRlVHlwZU1hcCwganNvbi5pbmNvbXBsZXRlVHlwZU1hcCk7XHJcblxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBDcmVhdGVzIGEgbmV3IE1ldGFkYXRhU3RvcmUgZnJvbSBhIHByZXZpb3VzbHkgZXhwb3J0ZWQgc2VyaWFsaXplZCBNZXRhZGF0YVN0b3JlXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBtcyBpcyBhIHByZXZpb3VzbHkgY3JlYXRlZCBNZXRhZGF0YVN0b3JlXHJcbiAgPiAgICAgIGxldCBtZXRhZGF0YUFzU3RyaW5nID0gbXMuZXhwb3J0TWV0YWRhdGEoKTtcclxuICA+ICAgICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKFwibWV0YWRhdGFcIiwgbWV0YWRhdGFBc1N0cmluZyk7XHJcbiAgPiAgICAgIC8vIGFuZCBsYXRlciwgdXN1YWxseSBpbiBhIGRpZmZlcmVudCBzZXNzaW9uXHJcbiAgPiAgICAgIGxldCBtZXRhZGF0YUZyb21TdG9yYWdlID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKFwibWV0YWRhdGFcIik7XHJcbiAgPiAgICAgIGxldCBuZXdNZXRhZGF0YVN0b3JlID0gTWV0YWRhdGFTdG9yZS5pbXBvcnRNZXRhZGF0YShtZXRhZGF0YUZyb21TdG9yYWdlKTtcclxuICBAcGFyYW0gZXhwb3J0ZWRTdHJpbmcgLSBBIHByZXZpb3VzbHkgZXhwb3J0ZWQgTWV0YWRhdGFTdG9yZS5cclxuICBAcmV0dXJuIEEgbmV3IE1ldGFkYXRhU3RvcmUuXHJcbiAgKiovXHJcbiAgc3RhdGljIGltcG9ydE1ldGFkYXRhKGV4cG9ydGVkU3RyaW5nOiBzdHJpbmcpIHtcclxuICAgIGxldCBtcyA9IG5ldyBNZXRhZGF0YVN0b3JlKCk7XHJcbiAgICBtcy5pbXBvcnRNZXRhZGF0YShleHBvcnRlZFN0cmluZyk7XHJcbiAgICByZXR1cm4gbXM7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIHdoZXRoZXIgTWV0YWRhdGEgaGFzIGJlZW4gcmV0cmlldmVkIGZvciBhIHNwZWNpZmllZCBzZXJ2aWNlIG5hbWUuXHJcbiAgPiAgICAgIC8vIEFzc3VtZSBlbTEgaXMgYW4gZXhpc3RpbmcgRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgaWYgKCFlbTEubWV0YWRhdGFTdG9yZS5oYXNNZXRhZGF0YUZvcihcImJyZWV6ZS9Ob3J0aHdpbmRJQk1vZGVsXCIpKSkge1xyXG4gID4gICAgICAgICAgLy8gZG8gc29tZXRoaW5nIGludGVyZXN0aW5nXHJcbiAgPiAgICAgIH1cclxuICBAcGFyYW0gc2VydmljZU5hbWUgLSBUaGUgc2VydmljZSBuYW1lLlxyXG4gIEByZXR1cm4gV2hldGhlciBtZXRhZGF0YSBoYXMgYWxyZWFkeSBiZWVuIHJldHJpZXZlZCBmb3IgdGhlIHNwZWNpZmllZCBzZXJ2aWNlIG5hbWUuXHJcbiAgKiovXHJcbiAgaGFzTWV0YWRhdGFGb3Ioc2VydmljZU5hbWU6IHN0cmluZykge1xyXG4gICAgcmV0dXJuICEhdGhpcy5nZXREYXRhU2VydmljZShzZXJ2aWNlTmFtZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIHRoZSBEYXRhU2VydmljZSBmb3IgYSBzcGVjaWZpZWQgc2VydmljZSBuYW1lXHJcbiAgPiAgICAgIC8vIEFzc3VtZSBlbTEgaXMgYW4gZXhpc3RpbmcgRW50aXR5TWFuYWdlci5cclxuICA+ICAgICAgbGV0IGRzID0gZW0xLm1ldGFkYXRhU3RvcmUuZ2V0RGF0YVNlcnZpY2UoXCJicmVlemUvTm9ydGh3aW5kSUJNb2RlbFwiKTtcclxuICA+ICAgICAgbGV0IGFkYXB0ZXJOYW1lID0gZHMuYWRhcHRlck5hbWU7IC8vIG1heSBiZSBudWxsXHJcbiAgQHBhcmFtIHNlcnZpY2VOYW1lIC0gVGhlIHNlcnZpY2UgbmFtZS5cclxuICBAcmV0dXJuIFRoZSBEYXRhU2VydmljZSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZS5cclxuICAqKi9cclxuICBnZXREYXRhU2VydmljZShzZXJ2aWNlTmFtZTogc3RyaW5nKSB7XHJcbiAgICBhc3NlcnRQYXJhbShzZXJ2aWNlTmFtZSwgXCJzZXJ2aWNlTmFtZVwiKS5pc1N0cmluZygpLmNoZWNrKCk7XHJcblxyXG4gICAgc2VydmljZU5hbWUgPSBEYXRhU2VydmljZS5fbm9ybWFsaXplU2VydmljZU5hbWUoc2VydmljZU5hbWUpO1xyXG4gICAgcmV0dXJuIGNvcmUuYXJyYXlGaXJzdCh0aGlzLmRhdGFTZXJ2aWNlcywgZnVuY3Rpb24gKGRzOiBEYXRhU2VydmljZSkge1xyXG4gICAgICByZXR1cm4gZHMuc2VydmljZU5hbWUgPT09IHNlcnZpY2VOYW1lO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBGZXRjaGVzIHRoZSBtZXRhZGF0YSBmb3IgYSBzcGVjaWZpZWQgJ3NlcnZpY2UnLiBUaGlzIG1ldGhvZCBpcyBhdXRvbWF0aWNhbGx5IGNhbGxlZFxyXG4gIGludGVybmFsbHkgYnkgYW4gRW50aXR5TWFuYWdlciBiZWZvcmUgaXRzIGZpcnN0IHF1ZXJ5IGFnYWluc3QgYSBuZXcgc2VydmljZS4gX19Bc3luY19fXHJcblxyXG4gIFVzdWFsbHkgeW91IHdpbGwgbm90IGFjdHVhbGx5IHByb2Nlc3MgdGhlIHJlc3VsdHMgb2YgYSBmZXRjaE1ldGFkYXRhIGNhbGwgZGlyZWN0bHksIGJ1dCB3aWxsIGluc3RlYWRcclxuICBhc2sgZm9yIHRoZSBtZXRhZGF0YSBmcm9tIHRoZSBFbnRpdHlNYW5hZ2VyIGFmdGVyIHRoZSBmZXRjaE1ldGFkYXRhIGNhbGwgcmV0dXJucy5cclxuICA+ICAgICAgbGV0IG1zID0gbmV3IE1ldGFkYXRhU3RvcmUoKTtcclxuICA+ICAgICAgLy8gb3IgbW9yZSBjb21tb25seVxyXG4gID4gICAgICAvLyBsZXQgbXMgPSBhbkVudGl0eU1hbmFnZXIubWV0YWRhdGFTdG9yZTtcclxuICA+ICAgICAgbXMuZmV0Y2hNZXRhZGF0YShcImJyZWV6ZS9Ob3J0aHdpbmRJQk1vZGVsXCIpLnRoZW4oZnVuY3Rpb24ocmF3TWV0YWRhdGEpIHtcclxuICA+ICAgICAgICAgICAgLy8gZG8gc29tZXRoaW5nIHdpdGggdGhlIG1ldGFkYXRhXHJcbiAgPiAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uKGV4Y2VwdGlvbikge1xyXG4gID4gICAgICAgICAgLy8gaGFuZGxlIGV4Y2VwdGlvbiBoZXJlXHJcbiAgPiAgICAgIH0pO1xyXG4gIEBwYXJhbSBkYXRhU2VydmljZSAtICBFaXRoZXIgYSBEYXRhU2VydmljZSBvciBqdXN0IHRoZSBuYW1lIG9mIHRoZSBEYXRhU2VydmljZSB0byBmZXRjaCBtZXRhZGF0YSBmb3IuXHJcbiAgQHBhcmFtIGNhbGxiYWNrIC0gRnVuY3Rpb24gY2FsbGVkIG9uIHN1Y2Nlc3MuXHJcbiAgQHBhcmFtIGVycm9yQ2FsbGJhY2sgLSBGdW5jdGlvbiBjYWxsZWQgb24gZmFpbHVyZS5cclxuICBAcmV0dXJuIFByb21pc2VcclxuICAqKi9cclxuICBmZXRjaE1ldGFkYXRhKGRhdGFTZXJ2aWNlOiBzdHJpbmcgfCBEYXRhU2VydmljZSwgY2FsbGJhY2s/OiAoc2NoZW1hOiBhbnkpID0+IHZvaWQsIGVycm9yQ2FsbGJhY2s/OiBFcnJvckNhbGxiYWNrKSB7XHJcbiAgICB0cnkge1xyXG4gICAgICBhc3NlcnRQYXJhbShkYXRhU2VydmljZSwgXCJkYXRhU2VydmljZVwiKS5pc1N0cmluZygpLm9yKCkuaXNJbnN0YW5jZU9mKERhdGFTZXJ2aWNlKS5jaGVjaygpO1xyXG4gICAgICBhc3NlcnRQYXJhbShjYWxsYmFjaywgXCJjYWxsYmFja1wiKS5pc0Z1bmN0aW9uKCkuaXNPcHRpb25hbCgpLmNoZWNrKCk7XHJcbiAgICAgIGFzc2VydFBhcmFtKGVycm9yQ2FsbGJhY2ssIFwiZXJyb3JDYWxsYmFja1wiKS5pc0Z1bmN0aW9uKCkuaXNPcHRpb25hbCgpLmNoZWNrKCk7XHJcblxyXG4gICAgICBpZiAodHlwZW9mIGRhdGFTZXJ2aWNlID09PSBcInN0cmluZ1wiKSB7XHJcbiAgICAgICAgLy8gdXNlIHRoZSBkYXRhU2VydmljZSB3aXRoIGEgbWF0Y2hpbmcgbmFtZSBvciBjcmVhdGUgYSBuZXcgb25lLlxyXG4gICAgICAgIGRhdGFTZXJ2aWNlID0gdGhpcy5nZXREYXRhU2VydmljZShkYXRhU2VydmljZSkgfHwgbmV3IERhdGFTZXJ2aWNlKHsgc2VydmljZU5hbWU6IGRhdGFTZXJ2aWNlIH0pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBkYXRhU2VydmljZSA9IERhdGFTZXJ2aWNlLnJlc29sdmUoW2RhdGFTZXJ2aWNlXSk7XHJcblxyXG4gICAgICBpZiAodGhpcy5oYXNNZXRhZGF0YUZvcihkYXRhU2VydmljZS5zZXJ2aWNlTmFtZSkpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJNZXRhZGF0YSBmb3IgYSBzcGVjaWZpYyBzZXJ2aWNlTmFtZSBtYXkgb25seSBiZSBmZXRjaGVkIG9uY2UgcGVyIE1ldGFkYXRhU3RvcmUuIFNlcnZpY2VOYW1lOiBcIiArIGRhdGFTZXJ2aWNlLnNlcnZpY2VOYW1lKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGRhdGFTZXJ2aWNlLmFkYXB0ZXJJbnN0YW5jZSEuZmV0Y2hNZXRhZGF0YSh0aGlzLCBkYXRhU2VydmljZSkudGhlbigocmF3TWV0YWRhdGE6IGFueSkgPT4ge1xyXG4gICAgICAgIHRoaXMubWV0YWRhdGFGZXRjaGVkLnB1Ymxpc2goeyBtZXRhZGF0YVN0b3JlOiB0aGlzLCBkYXRhU2VydmljZTogZGF0YVNlcnZpY2UsIHJhd01ldGFkYXRhOiByYXdNZXRhZGF0YSB9KTtcclxuICAgICAgICBpZiAoY2FsbGJhY2spIGNhbGxiYWNrKHJhd01ldGFkYXRhKTtcclxuICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHJhd01ldGFkYXRhKTtcclxuICAgICAgfSwgZnVuY3Rpb24gKGVycm9yOiBhbnkpIHtcclxuICAgICAgICBpZiAoZXJyb3JDYWxsYmFjaykgZXJyb3JDYWxsYmFjayhlcnJvcik7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm9yKTtcclxuICAgICAgfSk7XHJcbiAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICAvLyBUT0RPOiBzdHJvbmdseSB0eXBlIGludGVyY2VwdG9yIGJlbG93LlxyXG4gIC8qKlxyXG4gIFVzZWQgdG8gcmVnaXN0ZXIgYSBjb25zdHJ1Y3RvciBmb3IgYW4gRW50aXR5VHlwZSB0aGF0IGlzIG5vdCBrbm93biB2aWEgc3RhbmRhcmQgTWV0YWRhdGEgZGlzY292ZXJ5O1xyXG4gIGkuZS4gYW4gdW5tYXBwZWQgdHlwZS5cclxuICBAcGFyYW0gZW50aXR5Q3RvciAtIFRoZSBjb25zdHJ1Y3RvciBmdW5jdGlvbiBmb3IgdGhlICd1bm1hcHBlZCcgdHlwZS5cclxuICBAcGFyYW0gaW50ZXJjZXB0b3IgLSBBbiBpbnRlcmNlcHRvciBmdW5jdGlvblxyXG4gICoqL1xyXG4gIHRyYWNrVW5tYXBwZWRUeXBlKGVudGl0eUN0b3I6IGFueSwgaW50ZXJjZXB0b3I6IGFueSkge1xyXG4gICAgYXNzZXJ0UGFyYW0oZW50aXR5Q3RvciwgXCJlbnRpdHlDdG9yXCIpLmlzRnVuY3Rpb24oKS5jaGVjaygpO1xyXG4gICAgYXNzZXJ0UGFyYW0oaW50ZXJjZXB0b3IsIFwiaW50ZXJjZXB0b3JcIikuaXNGdW5jdGlvbigpLmlzT3B0aW9uYWwoKS5jaGVjaygpO1xyXG4gICAgLy8gVE9ETzogdGhpbmsgYWJvdXQgYWRkaW5nIHRoaXMgdG8gdGhlIE1ldGFkYXRhU3RvcmUuXHJcbiAgICBsZXQgZW50aXR5VHlwZSA9IG5ldyBFbnRpdHlUeXBlKHRoaXMpO1xyXG4gICAgZW50aXR5VHlwZS5fc2V0Q3RvcihlbnRpdHlDdG9yLCBpbnRlcmNlcHRvcik7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBQcm92aWRlcyBhIG1lY2hhbmlzbSB0byByZWdpc3RlciBhICdjdXN0b20nIGNvbnN0cnVjdG9yIHRvIGJlIHVzZWQgd2hlbiBjcmVhdGluZyBuZXcgaW5zdGFuY2VzXHJcbiAgb2YgdGhlIHNwZWNpZmllZCBlbnRpdHkgdHlwZS4gIElmIHRoaXMgY2FsbCBpcyBub3QgbWFkZSwgYSBkZWZhdWx0IGNvbnN0cnVjdG9yIGlzIGNyZWF0ZWQgZm9yXHJcbiAgdGhlIGVudGl0eSBhcyBuZWVkZWQuXHJcbiAgVGhpcyBjYWxsIG1heSBiZSBtYWRlIGJlZm9yZSBvciBhZnRlciB0aGUgY29ycmVzcG9uZGluZyBFbnRpdHlUeXBlIGhhcyBiZWVuIGRpc2NvdmVyZWQgdmlhXHJcbiAgTWV0YWRhdGEgZGlzY292ZXJ5LlxyXG4gID4gICAgICBsZXQgQ3VzdG9tZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgPiAgICAgICAgICAgICAgdGhpcy5taXNjRGF0YSA9IFwiYXNkZlwiO1xyXG4gID4gICAgICAgICAgfTtcclxuICA+ICAgICAgQ3VzdG9tZXIucHJvdG90eXBlLmRvRm9vKCkge1xyXG4gID4gICAgICAgICAgICAgIC4uLlxyXG4gID4gICAgICAgICAgfVxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGEgcHJlZXhpc3RpbmcgRW50aXR5TWFuYWdlcjtcclxuICA+ICAgICAgZW0xLm1ldGFkYXRhU3RvcmUucmVnaXN0ZXJFbnRpdHlUeXBlQ3RvcihcIkN1c3RvbWVyXCIsIEN1c3RvbWVyKTtcclxuICA+ICAgICAgLy8gYW55IHF1ZXJpZXMgb3IgRW50aXR5VHlwZS5jcmVhdGUgY2FsbHMgZnJvbSB0aGlzIHBvaW50IG9uIHdpbGwgY2FsbCB0aGUgQ3VzdG9tZXIgY29uc3RydWN0b3JcclxuICA+ICAgICAgLy8gcmVnaXN0ZXJlZCBhYm92ZS5cclxuICBAcGFyYW0gc3RydWN0dXJhbFR5cGVOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIEVudGl0eVR5cGUgb3IgQ29tcGxleFR5cGUuXHJcbiAgQHBhcmFtIGFDdG9yIC0gVGhlIGNvbnN0cnVjdG9yIGZvciB0aGlzIEVudGl0eVR5cGUgb3IgQ29tcGxleFR5cGU7IG1heSBiZSBudWxsIGlmIGFsbCB5b3Ugd2FudCB0byBkbyBpcyBzZXQgdGhlIG5leHQgcGFyYW1ldGVyLlxyXG4gIEBwYXJhbSBpbml0Rm4gLSBBIGZ1bmN0aW9uIG9yIHRoZSBuYW1lIG9mIGEgZnVuY3Rpb24gb24gdGhlIGVudGl0eSB0aGF0IGlzIHRvIGJlIGV4ZWN1dGVkIGltbWVkaWF0ZWx5IGFmdGVyIHRoZSBlbnRpdHkgaGFzIGJlZW4gY3JlYXRlZFxyXG4gIGFuZCBwb3B1bGF0ZWQgd2l0aCBhbnkgaW5pdGlhbCB2YWx1ZXMuIENhbGxlZCB3aXRoICdpbml0Rm4oZW50aXR5KSdcclxuICBAcGFyYW0gbm9UcmFja2luZ0ZuIC0gQSBmdW5jdGlvbiB0aGF0IGlzIGV4ZWN1dGVkIGltbWVkaWF0ZWx5IGFmdGVyIGEgbm9UcmFja2luZyBlbnRpdHkgaGFzIGJlZW4gY3JlYXRlZCBhbmQgd2hvc2UgcmV0dXJuXHJcbiAgdmFsdWUgd2lsbCBiZSB1c2VkIGluIHBsYWNlIG9mIHRoZSBub1RyYWNraW5nIGVudGl0eS5cclxuICAqKi9cclxuICByZWdpc3RlckVudGl0eVR5cGVDdG9yKHN0cnVjdHVyYWxUeXBlTmFtZTogc3RyaW5nLCBhQ3Rvcj86IGFueSwgaW5pdEZuPzogRnVuY3Rpb24gfCBzdHJpbmcsIG5vVHJhY2tpbmdGbj86IEZ1bmN0aW9uKSB7XHJcbiAgICBhc3NlcnRQYXJhbShzdHJ1Y3R1cmFsVHlwZU5hbWUsIFwic3RydWN0dXJhbFR5cGVOYW1lXCIpLmlzU3RyaW5nKCkuY2hlY2soKTtcclxuICAgIGFzc2VydFBhcmFtKGFDdG9yLCBcImFDdG9yXCIpLmlzRnVuY3Rpb24oKS5pc09wdGlvbmFsKCkuY2hlY2soKTtcclxuICAgIGFzc2VydFBhcmFtKGluaXRGbiwgXCJpbml0Rm5cIikuaXNPcHRpb25hbCgpLmlzRnVuY3Rpb24oKS5vcigpLmlzU3RyaW5nKCkuY2hlY2soKTtcclxuICAgIGFzc2VydFBhcmFtKG5vVHJhY2tpbmdGbiwgXCJub1RyYWNraW5nRm5cIikuaXNPcHRpb25hbCgpLmlzRnVuY3Rpb24oKS5jaGVjaygpO1xyXG5cclxuICAgIGxldCBxdWFsaWZpZWRUeXBlTmFtZSA9IGdldFF1YWxpZmllZFR5cGVOYW1lKHRoaXMsIHN0cnVjdHVyYWxUeXBlTmFtZSwgZmFsc2UpO1xyXG4gICAgbGV0IHR5cGVOYW1lID0gcXVhbGlmaWVkVHlwZU5hbWUgfHwgc3RydWN0dXJhbFR5cGVOYW1lO1xyXG5cclxuICAgIGlmIChhQ3Rvcikge1xyXG4gICAgICBpZiAoYUN0b3IuXyR0eXBlTmFtZSAmJiBhQ3Rvci5fJHR5cGVOYW1lICE9PSB0eXBlTmFtZSkge1xyXG4gICAgICAgIC8vIFRPRE86IHdyYXAgdGhpcyAtIGNvbnNvbGUgYW5kIGVzcGVjaWFsbHkgY29uc29sZS53YXJuIGRvZXMgbm90IGV4aXN0IGluIGFsbCBicm93c2Vycy5cclxuICAgICAgICBjb25zb2xlLndhcm4oXCJSZWdpc3RlcmluZyBhIGNvbnN0cnVjdG9yIGZvciBcIiArIHR5cGVOYW1lICsgXCIgdGhhdCBpcyBhbHJlYWR5IHVzZWQgZm9yIFwiICsgYUN0b3IuXyR0eXBlTmFtZSArIFwiLlwiKTtcclxuICAgICAgfVxyXG4gICAgICBhQ3Rvci5fJHR5cGVOYW1lID0gdHlwZU5hbWU7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fY3RvclJlZ2lzdHJ5W3R5cGVOYW1lXSA9IHsgY3RvcjogYUN0b3IsIGluaXRGbjogaW5pdEZuLCBub1RyYWNraW5nRm46IG5vVHJhY2tpbmdGbiB9O1xyXG4gICAgaWYgKHF1YWxpZmllZFR5cGVOYW1lKSB7XHJcbiAgICAgIGxldCBzdHlwZSA9IHRoaXMuX3N0cnVjdHVyYWxUeXBlTWFwW3F1YWxpZmllZFR5cGVOYW1lXTtcclxuICAgICAgc3R5cGUgJiYgc3R5cGUuZ2V0Q3Rvcih0cnVlKTsgLy8gdGhpcyB3aWxsIGNvbXBsZXRlIHRoZSByZWdpc3RyYXRpb24gaWYgYXZhaWwgbm93LlxyXG4gICAgfVxyXG5cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgd2hldGhlciB0aGlzIE1ldGFkYXRhU3RvcmUgY29udGFpbnMgYW55IG1ldGFkYXRhIHlldC5cclxuICA+ICAgICAgLy8gYXNzdW1lIGVtMSBpcyBhIHByZWV4aXN0aW5nIEVudGl0eU1hbmFnZXI7XHJcbiAgPiAgICAgIGlmIChlbTEubWV0YWRhdGFTdG9yZS5pc0VtcHR5KCkpIHtcclxuICA+ICAgICAgICAgIC8vIGRvIHNvbWV0aGluZyBpbnRlcmVzdGluZ1xyXG4gID4gICAgICB9XHJcbiAgKiovXHJcbiAgaXNFbXB0eSgpIHtcclxuICAgIHJldHVybiBjb3JlLmlzRW1wdHkodGhpcy5fc3RydWN0dXJhbFR5cGVNYXApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhbiBbW0VudGl0eVR5cGVdXSBvciBudWxsIGdpdmVuIGl0cyBuYW1lLlxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGEgcHJlZXhpc3RpbmcgRW50aXR5TWFuYWdlclxyXG4gID4gICAgICBsZXQgb2RUeXBlID0gZW0xLm1ldGFkYXRhU3RvcmUuZ2V0QXNFbnRpdHlUeXBlKFwiT3JkZXJEZXRhaWxcIik7XHJcblxyXG4gIG9yIHRvIHRocm93IGFuIGVycm9yIGlmIHRoZSB0eXBlIGlzIG5vdCBmb3VuZFxyXG4gID4gICAgICBsZXQgYmFkVHlwZSA9IGVtMS5tZXRhZGF0YVN0b3JlLmdldEFzRW50aXR5VHlwZShcIkZvb1wiLCBmYWxzZSk7XHJcbiAgPiAgICAgIC8vIGJhZFR5cGUgd2lsbCBub3QgZ2V0IHNldCBhbmQgYW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLlxyXG4gIEBwYXJhbSBzdHJ1Y3R1cmFsVHlwZU5hbWUgLSBFaXRoZXIgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9yIGEgc2hvcnQgbmFtZSBtYXkgYmUgdXNlZC4gSWYgYSBzaG9ydCBuYW1lIGlzIHNwZWNpZmllZCBhbmQgbXVsdGlwbGUgdHlwZXMgc2hhcmVcclxuICB0aGF0IHNhbWUgc2hvcnQgbmFtZSBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uXHJcbiAgQHBhcmFtIG9rSWZOb3RGb3VuZCAtIChkZWZhdWx0PWZhbHNlKSBXaGV0aGVyIHRvIHRocm93IGFuIGVycm9yIGlmIHRoZSBzcGVjaWZpZWQgRW50aXR5VHlwZSBpcyBub3QgZm91bmQuXHJcbiAgQHJldHVybiBUaGUgRW50aXR5VHlwZS4gQ29tcGxleFR5cGUgb3IgJ251bGwnIGlmIG5vdCBub3QgZm91bmQuXHJcbiAgKiovXHJcbiAgZ2V0QXNFbnRpdHlUeXBlKHR5cGVOYW1lOiBzdHJpbmcsIG9rSWZOb3RGb3VuZDogYm9vbGVhbiA9IGZhbHNlKSB7XHJcbiAgICBjb25zdCBzdCA9IHRoaXMuZ2V0U3RydWN0dXJhbFR5cGUodHlwZU5hbWUsIG9rSWZOb3RGb3VuZCk7XHJcbiAgICBpZiAoc3QgaW5zdGFuY2VvZiBFbnRpdHlUeXBlKSB7XHJcbiAgICAgIHJldHVybiBzdCBhcyBFbnRpdHlUeXBlO1xyXG4gICAgfSBlbHNlIGlmIChva0lmTm90Rm91bmQpIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBsZXQgbXNnID0gY29yZS5mb3JtYXRTdHJpbmcoXCJVbmFibGUgdG8gbG9jYXRlIGFuICdFbnRpdHlUeXBlJyBieSB0aGUgbmFtZTogJyUxJy4gQmUgc3VyZSB0byBleGVjdXRlIGEgcXVlcnkgb3IgY2FsbCBmZXRjaE1ldGFkYXRhIGZpcnN0LlwiLCB0eXBlTmFtZSk7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhbiBbW0VudGl0eVR5cGVdXSBvciBudWxsIGdpdmVuIGl0cyBuYW1lLlxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGEgcHJlZXhpc3RpbmcgRW50aXR5TWFuYWdlclxyXG4gID4gICAgICBsZXQgbG9jVHlwZSA9IGVtMS5tZXRhZGF0YVN0b3JlLmdldEFzQ29tcGxleFR5cGUoXCJMb2NhdGlvblwiKTtcclxuXHJcbiAgb3IgdG8gdGhyb3cgYW4gZXJyb3IgaWYgdGhlIHR5cGUgaXMgbm90IGZvdW5kXHJcbiAgPiAgICAgIGxldCBiYWRUeXBlID0gZW0xLm1ldGFkYXRhU3RvcmUuZ2V0QXNDb21wbGV4VHlwZShcIkZvb1wiLCBmYWxzZSk7XHJcbiAgPiAgICAgIC8vIGJhZFR5cGUgd2lsbCBub3QgZ2V0IHNldCBhbmQgYW4gZXhjZXB0aW9uIHdpbGwgYmUgdGhyb3duLlxyXG4gIEBwYXJhbSBzdHJ1Y3R1cmFsVHlwZU5hbWUgLSBFaXRoZXIgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9yIGEgc2hvcnQgbmFtZSBtYXkgYmUgdXNlZC4gSWYgYSBzaG9ydCBuYW1lIGlzIHNwZWNpZmllZCBhbmQgbXVsdGlwbGUgdHlwZXMgc2hhcmVcclxuICB0aGF0IHNhbWUgc2hvcnQgbmFtZSBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uXHJcbiAgQHBhcmFtIG9rSWZOb3RGb3VuZCAtIChkZWZhdWx0PWZhbHNlKSBXaGV0aGVyIHRvIHRocm93IGFuIGVycm9yIGlmIHRoZSBzcGVjaWZpZWQgRW50aXR5VHlwZSBpcyBub3QgZm91bmQuXHJcbiAgQHJldHVybiBUaGUgRW50aXR5VHlwZS4gQ29tcGxleFR5cGUgb3IgJ251bGwnIGlmIG5vdCBub3QgZm91bmQuXHJcbiAgKiovXHJcbiBnZXRBc0NvbXBsZXhUeXBlKHR5cGVOYW1lOiBzdHJpbmcsIG9rSWZOb3RGb3VuZDogYm9vbGVhbiA9IGZhbHNlKSB7XHJcbiAgY29uc3Qgc3QgPSB0aGlzLmdldFN0cnVjdHVyYWxUeXBlKHR5cGVOYW1lLCBva0lmTm90Rm91bmQpO1xyXG4gIGlmIChzdCBpbnN0YW5jZW9mIENvbXBsZXhUeXBlKSB7XHJcbiAgICByZXR1cm4gc3QgYXMgQ29tcGxleFR5cGU7XHJcbiAgfSBlbHNlIGlmIChva0lmTm90Rm91bmQpIHtcclxuICAgIHJldHVybiBudWxsO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBsZXQgbXNnID0gY29yZS5mb3JtYXRTdHJpbmcoXCJVbmFibGUgdG8gbG9jYXRlIGFuICdDb21wbGV4VHlwZScgYnkgdGhlIG5hbWU6ICclMScuIEJlIHN1cmUgdG8gZXhlY3V0ZSBhIHF1ZXJ5IG9yIGNhbGwgZmV0Y2hNZXRhZGF0YSBmaXJzdC5cIiwgdHlwZU5hbWUpO1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XHJcbiAgfVxyXG59XHJcblxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIGFuIFtbRW50aXR5VHlwZV1dIG9yIGEgW1tDb21wbGV4VHlwZV1dIGdpdmVuIGl0cyBuYW1lLlxyXG4gIEBkZXByZWNhdGVkIFJlcGxhY2VkIGJ5IGdldFN0cnVjdHVyYWxUeXBlIGJ1dCAuLi4gaXQgaXMgcHJvYmFibHkgbW9yZSB1c2VmdWxsIHRvIGNhbGwgZWl0aGVyIGdldEFzRW50aXR5VHlwZSBvciBnZXRBc0NvbXBsZXhUeXBlIGluc3RlYWRcclxuICBAcGFyYW0gdHlwZU5hbWUgLSBFaXRoZXIgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9yIGEgc2hvcnQgbmFtZSBtYXkgYmUgdXNlZC4gSWYgYSBzaG9ydCBuYW1lIGlzIHNwZWNpZmllZCBhbmQgbXVsdGlwbGUgdHlwZXMgc2hhcmVcclxuICB0aGF0IHNhbWUgc2hvcnQgbmFtZSBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uXHJcbiAgQHBhcmFtIG9rSWZOb3RGb3VuZCAtIChkZWZhdWx0PWZhbHNlKSBXaGV0aGVyIHRvIHRocm93IGFuIGVycm9yIGlmIHRoZSBzcGVjaWZpZWQgRW50aXR5VHlwZSBpcyBub3QgZm91bmQuXHJcbiAgQHJldHVybiBUaGUgRW50aXR5VHlwZS4gQ29tcGxleFR5cGUgb3IgJ251bGwnIGlmIG5vdCBub3QgZm91bmQuXHJcbiAgKiovXHJcbiAgZ2V0RW50aXR5VHlwZSh0eXBlTmFtZTogc3RyaW5nLCBva0lmTm90Rm91bmQ6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG4gICAgcmV0dXJuIHRoaXMuZ2V0U3RydWN0dXJhbFR5cGUodHlwZU5hbWUsIG9rSWZOb3RGb3VuZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIGFuIFtbRW50aXR5VHlwZV1dIG9yIGEgW1tDb21wbGV4VHlwZV1dIGdpdmVuIGl0cyBuYW1lLlxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGEgcHJlZXhpc3RpbmcgRW50aXR5TWFuYWdlclxyXG4gID4gICAgICBsZXQgb2RUeXBlID0gZW0xLm1ldGFkYXRhU3RvcmUuZ2V0U3RydWN0dXJhbFR5cGUoXCJPcmRlckRldGFpbFwiKTtcclxuXHJcbiAgb3IgdG8gdGhyb3cgYW4gZXJyb3IgaWYgdGhlIHR5cGUgaXMgbm90IGZvdW5kXHJcbiAgPiAgICAgIGxldCBiYWRUeXBlID0gZW0xLm1ldGFkYXRhU3RvcmUuZ2V0U3RydWN0dXJhbFR5cGUoXCJGb29cIiwgZmFsc2UpO1xyXG4gID4gICAgICAvLyBiYWRUeXBlIHdpbGwgbm90IGdldCBzZXQgYW5kIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi5cclxuICBAZGVwcmVjYXRlZCBQcmVmZXJhYmx5IHVzZSBlaXRoZXIgZ2V0QXNFbnRpdHlUeXBlIG9yIGdldEFzQ29tcGxleFR5cGUuICBHZXRcclxuICBAcGFyYW0gdHlwZU5hbWUgLSBFaXRoZXIgdGhlIGZ1bGx5IHF1YWxpZmllZCBuYW1lIG9yIGEgc2hvcnQgbmFtZSBtYXkgYmUgdXNlZC4gSWYgYSBzaG9ydCBuYW1lIGlzIHNwZWNpZmllZCBhbmQgbXVsdGlwbGUgdHlwZXMgc2hhcmVcclxuICB0aGF0IHNhbWUgc2hvcnQgbmFtZSBhbiBleGNlcHRpb24gd2lsbCBiZSB0aHJvd24uXHJcbiAgQHBhcmFtIG9rSWZOb3RGb3VuZCAtIChkZWZhdWx0PWZhbHNlKSBXaGV0aGVyIHRvIHRocm93IGFuIGVycm9yIGlmIHRoZSBzcGVjaWZpZWQgRW50aXR5VHlwZSBpcyBub3QgZm91bmQuXHJcbiAgQHJldHVybiBUaGUgRW50aXR5VHlwZS4gQ29tcGxleFR5cGUgb3IgJ251bGwnIGlmIG5vdCBub3QgZm91bmQuXHJcbiAgKiovXHJcbiAgZ2V0U3RydWN0dXJhbFR5cGUodHlwZU5hbWU6IHN0cmluZywgb2tJZk5vdEZvdW5kOiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgIGFzc2VydFBhcmFtKHR5cGVOYW1lLCBcInR5cGVOYW1lXCIpLmlzU3RyaW5nKCkuY2hlY2soKTtcclxuICAgIGFzc2VydFBhcmFtKG9rSWZOb3RGb3VuZCwgXCJva0lmTm90Rm91bmRcIikuaXNCb29sZWFuKCkuaXNPcHRpb25hbCgpLmNoZWNrKGZhbHNlKTtcclxuICAgIHJldHVybiB0aGlzLl9nZXRTdHJ1Y3R1cmFsVHlwZSh0eXBlTmFtZSwgb2tJZk5vdEZvdW5kKTtcclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9nZXRTdHJ1Y3R1cmFsVHlwZSh0eXBlTmFtZTogc3RyaW5nLCBva0lmTm90Rm91bmQ6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG4gICAgbGV0IHF1YWxUeXBlTmFtZSA9IGdldFF1YWxpZmllZFR5cGVOYW1lKHRoaXMsIHR5cGVOYW1lLCBmYWxzZSk7XHJcbiAgICBsZXQgdHlwZSA9IHRoaXMuX3N0cnVjdHVyYWxUeXBlTWFwW3F1YWxUeXBlTmFtZV07XHJcbiAgICBpZiAoIXR5cGUpIHtcclxuICAgICAgaWYgKG9rSWZOb3RGb3VuZCkgcmV0dXJuIG51bGw7XHJcbiAgICAgIGxldCBtc2cgPSBjb3JlLmZvcm1hdFN0cmluZyhcIlVuYWJsZSB0byBsb2NhdGUgYSAnVHlwZScgYnkgdGhlIG5hbWU6ICclMScuIEJlIHN1cmUgdG8gZXhlY3V0ZSBhIHF1ZXJ5IG9yIGNhbGwgZmV0Y2hNZXRhZGF0YSBmaXJzdC5cIiwgdHlwZU5hbWUpO1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IobXNnKTtcclxuICAgIH1cclxuICAgIHJldHVybiB0eXBlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIGFsbCBvZiB0aGUgW1tFbnRpdHlUeXBlXV1zIG9yIFtbQ29tcGxleFR5cGVdXXMgaW4gdGhpcyBNZXRhZGF0YVN0b3JlLlxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGEgcHJlZXhpc3RpbmcgRW50aXR5TWFuYWdlclxyXG4gID4gICAgICBsZXQgYWxsVHlwZXMgPSBlbTEubWV0YWRhdGFTdG9yZS5nZXRFbnRpdHlUeXBlcygpO1xyXG4gICoqL1xyXG4gIGdldEVudGl0eVR5cGVzKCkge1xyXG4gICAgcmV0dXJuIGdldFR5cGVzRnJvbU1hcCh0aGlzLl9zdHJ1Y3R1cmFsVHlwZU1hcCk7XHJcbiAgfVxyXG5cclxuICBnZXRJbmNvbXBsZXRlTmF2aWdhdGlvblByb3BlcnRpZXMoKSB7XHJcbiAgICByZXR1cm4gY29yZS5vYmplY3RNYXAodGhpcy5faW5jb21wbGV0ZVR5cGVNYXAsIGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XHJcbiAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIGZ1bGx5IHF1YWxpZmllZCBlbnRpdHlUeXBlTmFtZSBmb3IgYSBzcGVjaWZpZWQgcmVzb3VyY2UgbmFtZS4gIFRoZSByZXZlcnNlIG9mIHRoaXMgb3BlcmF0aW9uXHJcbiAgY2FuIGJlIG9idGFpbmVkIHZpYSB0aGUgIFtbRW50aXR5VHlwZS5kZWZhdWx0UmVzb3VyY2VOYW1lXV0gcHJvcGVydHlcclxuICAqKi9cclxuICBnZXRFbnRpdHlUeXBlTmFtZUZvclJlc291cmNlTmFtZShyZXNvdXJjZU5hbWU6IHN0cmluZykge1xyXG4gICAgYXNzZXJ0UGFyYW0ocmVzb3VyY2VOYW1lLCBcInJlc291cmNlTmFtZVwiKS5pc1N0cmluZygpLmNoZWNrKCk7XHJcbiAgICByZXR1cm4gdGhpcy5fcmVzb3VyY2VFbnRpdHlUeXBlTWFwW3Jlc291cmNlTmFtZV07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBBc3NvY2lhdGVzIGEgcmVzb3VyY2VOYW1lIHdpdGggYW4gZW50aXR5VHlwZS5cclxuXHJcbiAgVGhpcyBtZXRob2QgaXMgb25seSBuZWVkZWQgaW4gdGhvc2UgY2FzZXMgd2hlcmUgbXVsdGlwbGUgcmVzb3VyY2VzIHJldHVybiB0aGUgc2FtZVxyXG4gIGVudGl0eVR5cGUuICBJbiB0aGlzIGNhc2UgTWV0YWRhdGEgZGlzY292ZXJ5IHdpbGwgb25seSBkZXRlcm1pbmUgYSBzaW5nbGUgcmVzb3VyY2UgbmFtZSBmb3JcclxuICBlYWNoIGVudGl0eVR5cGUuXHJcbiAgQHBhcmFtIHJlc291cmNlTmFtZSAtIFRoZSByZXNvdXJjZSBuYW1lXHJcbiAgQHBhcmFtIGVudGl0eVR5cGVPck5hbWUgLSBJZiBwYXNzaW5nIGEgc3RyaW5nIGVpdGhlciB0aGUgZnVsbHkgcXVhbGlmaWVkIG5hbWUgb3IgYSBzaG9ydCBuYW1lIG1heSBiZSB1c2VkLiBJZiBhIHNob3J0IG5hbWUgaXMgc3BlY2lmaWVkIGFuZCBtdWx0aXBsZSB0eXBlcyBzaGFyZVxyXG4gIHRoYXQgc2FtZSBzaG9ydCBuYW1lIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi4gSWYgdGhlIGVudGl0eVR5cGUgaGFzIG5vdCB5ZXQgYmVlbiBkaXNjb3ZlcmVkIHRoZW4gYSBmdWxseSBxdWFsaWZpZWQgbmFtZSBtdXN0IGJlIHVzZWQuXHJcbiAgKiovXHJcbiAgc2V0RW50aXR5VHlwZUZvclJlc291cmNlTmFtZShyZXNvdXJjZU5hbWU6IHN0cmluZywgZW50aXR5VHlwZU9yTmFtZTogRW50aXR5VHlwZSB8IHN0cmluZykge1xyXG4gICAgYXNzZXJ0UGFyYW0ocmVzb3VyY2VOYW1lLCBcInJlc291cmNlTmFtZVwiKS5pc1N0cmluZygpLmNoZWNrKCk7XHJcbiAgICBhc3NlcnRQYXJhbShlbnRpdHlUeXBlT3JOYW1lLCBcImVudGl0eVR5cGVPck5hbWVcIikuaXNJbnN0YW5jZU9mKEVudGl0eVR5cGUpLm9yKCkuaXNTdHJpbmcoKS5jaGVjaygpO1xyXG5cclxuICAgIGxldCBlbnRpdHlUeXBlTmFtZTogc3RyaW5nO1xyXG4gICAgaWYgKGVudGl0eVR5cGVPck5hbWUgaW5zdGFuY2VvZiBFbnRpdHlUeXBlKSB7XHJcbiAgICAgIGVudGl0eVR5cGVOYW1lID0gZW50aXR5VHlwZU9yTmFtZS5uYW1lO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgZW50aXR5VHlwZU5hbWUgPSBnZXRRdWFsaWZpZWRUeXBlTmFtZSh0aGlzLCBlbnRpdHlUeXBlT3JOYW1lLCB0cnVlKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9yZXNvdXJjZUVudGl0eVR5cGVNYXBbcmVzb3VyY2VOYW1lXSA9IGVudGl0eVR5cGVOYW1lO1xyXG4gICAgbGV0IGVudGl0eVR5cGUgPSB0aGlzLl9nZXRTdHJ1Y3R1cmFsVHlwZShlbnRpdHlUeXBlTmFtZSwgdHJ1ZSk7XHJcbiAgICBpZiAoZW50aXR5VHlwZSAmJiBlbnRpdHlUeXBlIGluc3RhbmNlb2YgRW50aXR5VHlwZSAmJiAhZW50aXR5VHlwZS5kZWZhdWx0UmVzb3VyY2VOYW1lKSB7XHJcbiAgICAgIGVudGl0eVR5cGUuZGVmYXVsdFJlc291cmNlTmFtZSA9IHJlc291cmNlTmFtZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBfX0RldiBPbmx5X18gLSBmb3IgdXNlIHdoZW4gY3JlYXRpbmcgYSBuZXcgTWV0YWRhdGFQYXJzZXJBZGFwdGVyICAqL1xyXG4gIHN0YXRpYyBwYXJzZVR5cGVOYW1lKGVudGl0eVR5cGVOYW1lOiBzdHJpbmcpIHtcclxuICAgIC8vIFRPRE86IHJlbW92ZWQgXHJcbiAgICAvLyBpZiAoIWVudGl0eVR5cGVOYW1lKSB7XHJcbiAgICAvLyAgIHJldHVybiBudWxsO1xyXG4gICAgLy8gfVxyXG5cclxuICAgIGxldCB0eXBlUGFydHMgPSBlbnRpdHlUeXBlTmFtZS5zcGxpdChcIjojXCIpO1xyXG4gICAgaWYgKHR5cGVQYXJ0cy5sZW5ndGggPiAxKSB7XHJcbiAgICAgIHJldHVybiBNZXRhZGF0YVN0b3JlLm1ha2VUeXBlSGFzaCh0eXBlUGFydHNbMF0sIHR5cGVQYXJ0c1sxXSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGNvcmUuc3RyaW5nU3RhcnRzV2l0aChlbnRpdHlUeXBlTmFtZSwgTWV0YWRhdGFTdG9yZS5BTk9OVFlQRV9QUkVGSVgpKSB7XHJcbiAgICAgIGxldCB0eXBlSGFzaCA9IE1ldGFkYXRhU3RvcmUubWFrZVR5cGVIYXNoKGVudGl0eVR5cGVOYW1lKTtcclxuICAgICAgKHR5cGVIYXNoIGFzIGFueSkuaXNBbm9ueW1vdXMgPSB0cnVlO1xyXG4gICAgICByZXR1cm4gdHlwZUhhc2g7XHJcbiAgICB9XHJcbiAgICBsZXQgZW50aXR5VHlwZU5hbWVOb0Fzc2VtYmx5ID0gZW50aXR5VHlwZU5hbWUuc3BsaXQoXCIsXCIpWzBdO1xyXG4gICAgdHlwZVBhcnRzID0gZW50aXR5VHlwZU5hbWVOb0Fzc2VtYmx5LnNwbGl0KFwiLlwiKTtcclxuICAgIGlmICh0eXBlUGFydHMubGVuZ3RoID4gMSkge1xyXG4gICAgICBsZXQgc2hvcnROYW1lID0gdHlwZVBhcnRzW3R5cGVQYXJ0cy5sZW5ndGggLSAxXTtcclxuICAgICAgbGV0IG5hbWVzcGFjZVBhcnRzID0gdHlwZVBhcnRzLnNsaWNlKDAsIHR5cGVQYXJ0cy5sZW5ndGggLSAxKTtcclxuICAgICAgbGV0IG5zID0gbmFtZXNwYWNlUGFydHMuam9pbihcIi5cIik7XHJcbiAgICAgIHJldHVybiBNZXRhZGF0YVN0b3JlLm1ha2VUeXBlSGFzaChzaG9ydE5hbWUsIG5zKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBNZXRhZGF0YVN0b3JlLm1ha2VUeXBlSGFzaChlbnRpdHlUeXBlTmFtZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogX19EZXYgT25seV9fIC0gZm9yIHVzZSB3aGVuIGNyZWF0aW5nIGEgbmV3IE1ldGFkYXRhUGFyc2VyQWRhcHRlciAgKi9cclxuICBzdGF0aWMgbWFrZVR5cGVIYXNoKHNob3J0TmFtZTogc3RyaW5nLCBucz86IHN0cmluZykge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgc2hvcnRUeXBlTmFtZTogc2hvcnROYW1lLFxyXG4gICAgICBuYW1lc3BhY2U6IG5zLFxyXG4gICAgICB0eXBlTmFtZTogcXVhbGlmeVR5cGVOYW1lKHNob3J0TmFtZSwgbnMpXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLy8gcHJvdGVjdGVkIG1ldGhvZHNcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfY2hlY2tFbnRpdHlUeXBlKGVudGl0eTogRW50aXR5KSB7XHJcbiAgICBpZiAoZW50aXR5LmVudGl0eVR5cGUpIHJldHVybjtcclxuICAgIGxldCB0eXBlTmFtZSA9IGVudGl0eS5wcm90b3R5cGUuXyR0eXBlTmFtZTtcclxuICAgIGlmICghdHlwZU5hbWUpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcyBlbnRpdHkgaGFzIG5vdCBiZWVuIHJlZ2lzdGVyZWQuIFNlZSB0aGUgTWV0YWRhdGFTdG9yZS5yZWdpc3RlckVudGl0eVR5cGVDdG9yIG1ldGhvZFwiKTtcclxuICAgIH1cclxuICAgIC8vIHdlIGtub3cgdGhhdCBpdCBpcyBhbiBFbnRpdHlUeXBlICggYXMgb3Bwb3NlZCB0byBhIENvbXBsZXhUeXBlKVxyXG4gICAgbGV0IGVudGl0eVR5cGUgPSB0aGlzLl9nZXRTdHJ1Y3R1cmFsVHlwZSh0eXBlTmFtZSkgYXMgRW50aXR5VHlwZTtcclxuICAgIGlmIChlbnRpdHlUeXBlKSB7XHJcbiAgICAgIGVudGl0eS5lbnRpdHlUeXBlID0gZW50aXR5VHlwZTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxufVxyXG5NZXRhZGF0YVN0b3JlLnByb3RvdHlwZS5fJHR5cGVOYW1lID0gXCJNZXRhZGF0YVN0b3JlXCI7XHJcblxyXG5CcmVlemVFdmVudC5idWJibGVFdmVudChNZXRhZGF0YVN0b3JlLnByb3RvdHlwZSk7XHJcblxyXG5mdW5jdGlvbiBnZXRUeXBlc0Zyb21NYXAodHlwZU1hcDogSVN0cnVjdHVyYWxUeXBlTWFwKSB7XHJcbiAgbGV0IHR5cGVzOiAoU3RydWN0dXJhbFR5cGUpW10gPSBbXTtcclxuICBmb3IgKGxldCBrZXkgaW4gdHlwZU1hcCkge1xyXG4gICAgbGV0IHZhbHVlID0gdHlwZU1hcFtrZXldO1xyXG4gICAgLy8gc2tpcCAnc2hvcnROYW1lJyBlbnRyaWVzXHJcbiAgICBpZiAoa2V5ID09PSB2YWx1ZS5uYW1lKSB7XHJcbiAgICAgIHR5cGVzLnB1c2godHlwZU1hcFtrZXldKTtcclxuICAgIH1cclxuICB9XHJcbiAgcmV0dXJuIHR5cGVzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzdHJ1Y3R1cmFsVHlwZUZyb21Kc29uKG1ldGFkYXRhU3RvcmU6IE1ldGFkYXRhU3RvcmUsIGpzb246IGFueSwgYWxsb3dNZXJnZTogYm9vbGVhbikge1xyXG4gIGxldCB0eXBlTmFtZSA9IHF1YWxpZnlUeXBlTmFtZShqc29uLnNob3J0TmFtZSwganNvbi5uYW1lc3BhY2UpO1xyXG4gIGxldCBzdHlwZSA9IG1ldGFkYXRhU3RvcmUuX2dldFN0cnVjdHVyYWxUeXBlKHR5cGVOYW1lLCB0cnVlKTtcclxuICBpZiAoc3R5cGUpIHtcclxuICAgIGlmIChhbGxvd01lcmdlKSB7XHJcbiAgICAgIHJldHVybiBtZXJnZVN0cnVjdHVyYWxUeXBlKHN0eXBlLCBqc29uKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIGFsbG93IGl0IGJ1dCBkb24ndCByZXBsYWNlIGFueXRoaW5nLlxyXG4gICAgICByZXR1cm4gc3R5cGU7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGxldCBjb25maWcgPSB7XHJcbiAgICBzaG9ydE5hbWU6IGpzb24uc2hvcnROYW1lLFxyXG4gICAgbmFtZXNwYWNlOiBqc29uLm5hbWVzcGFjZSxcclxuICAgIGlzQWJzdHJhY3Q6IGpzb24uaXNBYnN0cmFjdCxcclxuICAgIGF1dG9HZW5lcmF0ZWRLZXlUeXBlOiBBdXRvR2VuZXJhdGVkS2V5VHlwZS5mcm9tTmFtZShqc29uLmF1dG9HZW5lcmF0ZWRLZXlUeXBlKSxcclxuICAgIGRlZmF1bHRSZXNvdXJjZU5hbWU6IGpzb24uZGVmYXVsdFJlc291cmNlTmFtZSxcclxuICAgIGN1c3RvbToganNvbi5jdXN0b21cclxuICB9O1xyXG5cclxuICBzdHlwZSA9IGpzb24uaXNDb21wbGV4VHlwZSA/IG5ldyBDb21wbGV4VHlwZShjb25maWcpIDogbmV3IEVudGl0eVR5cGUoY29uZmlnKTtcclxuXHJcbiAgLy8gYmFzZVR5cGUgbWF5IG5vdCBoYXZlIGJlZW4gaW1wb3J0ZWQgeWV0IHNvIHdlIG5lZWQgdG8gZGVmZXIgaGFuZGxpbmcgdGhpcyB0eXBlIHVudGlsIGxhdGVyLlxyXG4gIGlmIChqc29uLmJhc2VUeXBlTmFtZSAmJiBzdHlwZSBpbnN0YW5jZW9mIEVudGl0eVR5cGUpIHtcclxuICAgIHN0eXBlLmJhc2VUeXBlTmFtZSA9IGpzb24uYmFzZVR5cGVOYW1lO1xyXG4gICAgbGV0IGJhc2VFbnRpdHlUeXBlID0gbWV0YWRhdGFTdG9yZS5fZ2V0U3RydWN0dXJhbFR5cGUoanNvbi5iYXNlVHlwZU5hbWUsIHRydWUpO1xyXG4gICAgaWYgKGJhc2VFbnRpdHlUeXBlKSB7XHJcbiAgICAgIGNvbXBsZXRlU3RydWN0dXJhbFR5cGVGcm9tSnNvbihtZXRhZGF0YVN0b3JlLCBqc29uLCBzdHlwZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb3JlLmdldEFycmF5KG1ldGFkYXRhU3RvcmUuX2RlZmVycmVkVHlwZXMsIGpzb24uYmFzZVR5cGVOYW1lKS5wdXNoKHsganNvbjoganNvbiwgc3R5cGU6IHN0eXBlIH0pO1xyXG5cclxuICAgIH1cclxuICB9IGVsc2Uge1xyXG4gICAgY29tcGxldGVTdHJ1Y3R1cmFsVHlwZUZyb21Kc29uKG1ldGFkYXRhU3RvcmUsIGpzb24sIHN0eXBlKTtcclxuICB9XHJcblxyXG4gIC8vIHN0eXBlIG1heSBvciBtYXkgbm90IGhhdmUgYmVlbiBhZGRlZCB0byB0aGUgbWV0YWRhdGFTdG9yZSBhdCB0aGlzIHBvaW50LlxyXG4gIHJldHVybiBzdHlwZTtcclxufVxyXG5cclxuZnVuY3Rpb24gbWVyZ2VTdHJ1Y3R1cmFsVHlwZShzdHlwZTogU3RydWN0dXJhbFR5cGUsIGpzb246IGFueSkge1xyXG4gIGlmIChqc29uLmN1c3RvbSkge1xyXG4gICAgc3R5cGUuY3VzdG9tID0ganNvbi5jdXN0b207XHJcbiAgfVxyXG5cclxuICBtZXJnZVByb3BzKHN0eXBlLCBqc29uLmRhdGFQcm9wZXJ0aWVzKTtcclxuICBtZXJnZVByb3BzKHN0eXBlLCBqc29uLm5hdmlnYXRpb25Qcm9wZXJ0aWVzKTtcclxuICByZXR1cm4gc3R5cGU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIG1lcmdlUHJvcHMoc3R5cGU6IFN0cnVjdHVyYWxUeXBlLCBqc29uUHJvcHM6IGFueVtdKSB7XHJcbiAgaWYgKCFqc29uUHJvcHMpIHJldHVybjtcclxuICBqc29uUHJvcHMuZm9yRWFjaCgoanNvblByb3ApID0+IHtcclxuICAgIGxldCBwcm9wTmFtZSA9IGpzb25Qcm9wLm5hbWU7XHJcbiAgICBpZiAoIXByb3BOYW1lKSB7XHJcbiAgICAgIGlmIChqc29uUHJvcC5uYW1lT25TZXJ2ZXIpIHtcclxuICAgICAgICBwcm9wTmFtZSA9IHN0eXBlLm1ldGFkYXRhU3RvcmUubmFtaW5nQ29udmVudGlvbi5zZXJ2ZXJQcm9wZXJ0eU5hbWVUb0NsaWVudChqc29uUHJvcC5uYW1lT25TZXJ2ZXIsIHt9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBiYWNrc2xhc2gtcXVvdGUgd29ya3MgYXJvdW5kIGNvbXBpbGVyIGJ1Z1xyXG4gICAgICAgIGNvbnN0IG1zZyA9IFwiVW5hYmxlIHRvIGNvbXBsZXRlIFxcJ2ltcG9ydE1ldGFkYXRhXFwnIC0gY2Fubm90IGxvY2F0ZSBhIFxcJ25hbWVcXCcgb3IgXFwnbmFtZU9uU2VydmVyXFwnIGZvciBvbmUgb2YgdGhlIGltcG9ydGVkIHByb3BlcnR5IG5vZGVzXCI7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChqc29uUHJvcC5jdXN0b20pIHtcclxuICAgICAgbGV0IHByb3AgPSBzdHlwZS5nZXRQcm9wZXJ0eShwcm9wTmFtZSwgdHJ1ZSk7XHJcbiAgICAgIHByb3AhLmN1c3RvbSA9IGpzb25Qcm9wLmN1c3RvbTtcclxuICAgIH1cclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gY29tcGxldGVTdHJ1Y3R1cmFsVHlwZUZyb21Kc29uKG1ldGFkYXRhU3RvcmU6IE1ldGFkYXRhU3RvcmUsIGpzb246IGFueSwgc3R5cGU6IGFueSkge1xyXG5cclxuICAvLyB2YWxpZGF0b3JzIGZyb20gYmFzZVR5cGUgd29yayBiZWNhdXNlIHZhbGlkYXRpb24gd2Fsa3MgdGhydSBiYXNlIHR5cGVzXHJcbiAgLy8gc28gbm8gbmVlZCB0byBjb3B5IGRvd24uXHJcbiAgaWYgKGpzb24udmFsaWRhdG9ycykge1xyXG4gICAgc3R5cGUudmFsaWRhdG9ycyA9IGpzb24udmFsaWRhdG9ycy5tYXAoVmFsaWRhdG9yLmZyb21KU09OKTtcclxuICB9XHJcblxyXG4gIGpzb24uZGF0YVByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbiAoZHA6IE9iamVjdCkge1xyXG4gICAgc3R5cGUuX2FkZFByb3BlcnR5Q29yZShEYXRhUHJvcGVydHkuZnJvbUpTT04oZHApKTtcclxuICB9KTtcclxuXHJcblxyXG4gIGxldCBpc0VudGl0eVR5cGUgPSAhanNvbi5pc0NvbXBsZXhUeXBlO1xyXG4gIGlmIChpc0VudGl0eVR5cGUpIHtcclxuICAgIC8vbm9pbnNwZWN0aW9uIEpTSGludFxyXG4gICAganNvbi5uYXZpZ2F0aW9uUHJvcGVydGllcyAmJiBqc29uLm5hdmlnYXRpb25Qcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24gKG5wOiBPYmplY3QpIHtcclxuICAgICAgc3R5cGUuX2FkZFByb3BlcnR5Q29yZShOYXZpZ2F0aW9uUHJvcGVydHkuZnJvbUpTT04obnApKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbWV0YWRhdGFTdG9yZS5hZGRFbnRpdHlUeXBlKHN0eXBlKTtcclxuXHJcbiAgbGV0IGRlZmVycmVkVHlwZXMgPSBtZXRhZGF0YVN0b3JlLl9kZWZlcnJlZFR5cGVzO1xyXG4gIGxldCBkZWZlcnJhbHMgPSBkZWZlcnJlZFR5cGVzW3N0eXBlLm5hbWVdO1xyXG4gIGlmIChkZWZlcnJhbHMpIHtcclxuICAgIGRlZmVycmFscy5mb3JFYWNoKGZ1bmN0aW9uIChkOiBhbnkpIHtcclxuICAgICAgY29tcGxldGVTdHJ1Y3R1cmFsVHlwZUZyb21Kc29uKG1ldGFkYXRhU3RvcmUsIGQuanNvbiwgZC5zdHlwZSk7XHJcbiAgICB9KTtcclxuICAgIGRlbGV0ZSBkZWZlcnJlZFR5cGVzW3N0eXBlLm5hbWVdO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0UXVhbGlmaWVkVHlwZU5hbWUobWV0YWRhdGFTdG9yZTogTWV0YWRhdGFTdG9yZSwgc3RydWN0VHlwZU5hbWU6IHN0cmluZywgdGhyb3dJZk5vdEZvdW5kPzogYm9vbGVhbikge1xyXG4gIGlmIChpc1F1YWxpZmllZFR5cGVOYW1lKHN0cnVjdFR5cGVOYW1lKSkgcmV0dXJuIHN0cnVjdFR5cGVOYW1lO1xyXG4gIGxldCByZXN1bHQgPSBtZXRhZGF0YVN0b3JlLl9zaG9ydE5hbWVNYXBbc3RydWN0VHlwZU5hbWVdO1xyXG4gIGlmICghcmVzdWx0ICYmIHRocm93SWZOb3RGb3VuZCkge1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVW5hYmxlIHRvIGxvY2F0ZSAnZW50aXR5VHlwZU5hbWUnIG9mOiBcIiArIHN0cnVjdFR5cGVOYW1lKTtcclxuICB9XHJcbiAgcmV0dXJuIHJlc3VsdDtcclxufVxyXG5cclxuLyoqIENvbmZpZ3VyYXRpb24gaW5mbyB0byBiZSBwYXNzZWQgdG8gdGhlIFtbRW50aXR5VHlwZV1dIGNvbnN0cnVjdG9yICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRW50aXR5VHlwZUNvbmZpZyB7XHJcbiAgc2hvcnROYW1lPzogc3RyaW5nO1xyXG4gIG5hbWVzcGFjZT86IHN0cmluZztcclxuICBiYXNlVHlwZU5hbWU/OiBzdHJpbmc7XHJcbiAgaXNBYnN0cmFjdD86IGJvb2xlYW47XHJcbiAgYXV0b0dlbmVyYXRlZEtleVR5cGU/OiBBdXRvR2VuZXJhdGVkS2V5VHlwZTtcclxuICBkZWZhdWx0UmVzb3VyY2VOYW1lPzogc3RyaW5nO1xyXG4gIGRhdGFQcm9wZXJ0aWVzPzogRGF0YVByb3BlcnR5W10gfCBPYmplY3RbXSB8IE9iamVjdDsgIC8vIFRPRE86IHNlZSBpZiB3ZSBjYW4ndCBxdWFsaWZ5IE9iamVjdFtdIGEgbGl0dGxlIGJldHRlci5cclxuICBuYXZpZ2F0aW9uUHJvcGVydGllcz86IE5hdmlnYXRpb25Qcm9wZXJ0eVtdIHwgT2JqZWN0W10gfCBPYmplY3Q7XHJcbiAgc2VyaWFsaXplckZuPzogKHByb3A6IEVudGl0eVByb3BlcnR5LCB2YWw6IGFueSkgPT4gYW55O1xyXG4gIGN1c3RvbT86IGFueTtcclxufVxyXG5cclxuLyoqIENvbmZpZ3VyYXRpb24gaW5mbyB0byBiZSBwYXNzZWQgdG8gdGhlIFtbRW50aXR5VHlwZS5zZXRQcm9wZXJ0aWVzXV0gbWV0aG9kICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRW50aXR5VHlwZVNldENvbmZpZyB7XHJcbiAgYXV0b0dlbmVyYXRlZEtleVR5cGU/OiBBdXRvR2VuZXJhdGVkS2V5VHlwZTtcclxuICBkZWZhdWx0UmVzb3VyY2VOYW1lPzogc3RyaW5nO1xyXG4gIHNlcmlhbGl6ZXJGbj86IChwcm9wOiBFbnRpdHlQcm9wZXJ0eSwgdmFsOiBhbnkpID0+IGFueTtcclxuICBjdXN0b20/OiBhbnk7XHJcbn1cclxuXHJcbi8qKiBDb250YWluZXIgZm9yIGFsbCBvZiB0aGUgbWV0YWRhdGEgYWJvdXQgYSBzcGVjaWZpYyB0eXBlIG9mIEVudGl0eS5cclxuKiovXHJcbmV4cG9ydCBjbGFzcyBFbnRpdHlUeXBlIHtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBkZWNsYXJlIF8kdHlwZU5hbWU6IHN0cmluZzsgLy8gb24gcHJvdG9cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBzdGF0aWMgX19uZXh0QW5vbkl4ID0gMDtcclxuICAvKiogQWx3YXlzIGZhbHNlIGZvciBhbiBFbnRpdHlUeXBlLiAqKi9cclxuICBpc0NvbXBsZXhUeXBlID0gZmFsc2U7XHJcbiAgLyoqIFRoZSBbW01ldGFkYXRhU3RvcmVdXSB0aGF0IGNvbnRhaW5zIHRoaXMgRW50aXR5VHlwZS4gX19SZWFkIE9ubHlfXyAqKi9cclxuICBtZXRhZGF0YVN0b3JlOiBNZXRhZGF0YVN0b3JlO1xyXG4gIC8qKiBUaGUgRGF0YVByb3BlcnRpZXMgKHNlZSBbW0RhdGFQcm9wZXJ0eV1dIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEVudGl0eVR5cGUuIF9fUmVhZCBPbmx5X18gICoqL1xyXG4gIGRhdGFQcm9wZXJ0aWVzOiBEYXRhUHJvcGVydHlbXTtcclxuICAvKiogIFRoZSBOYXZpZ2F0aW9uUHJvcGVydGllcyAoc2VlIFtbTmF2aWdhdGlvblByb3BlcnR5XV0gYXNzb2NpYXRlZCB3aXRoIHRoaXMgRW50aXR5VHlwZS4gX19SZWFkIE9ubHlfXyAgKiovXHJcbiAgbmF2aWdhdGlvblByb3BlcnRpZXM6IE5hdmlnYXRpb25Qcm9wZXJ0eVtdO1xyXG4gIC8qKlxyXG4gIFRoZSBEYXRhUHJvcGVydGllcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBFbnRpdHlUeXBlIHRoYXQgbWFrZSB1cCBpdCdzIFtbRW50aXR5S2V5XV0uIF9fUmVhZCBPbmx5X18gKiovXHJcbiAga2V5UHJvcGVydGllczogRGF0YVByb3BlcnR5W107XHJcbiAgLyoqIFRoZSBEYXRhUHJvcGVydGllcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBFbnRpdHlUeXBlIHRoYXQgYXJlIGZvcmVpZ24ga2V5IHByb3BlcnRpZXMuIF9fUmVhZCBPbmx5X18gKiovXHJcbiAgZm9yZWlnbktleVByb3BlcnRpZXM6IERhdGFQcm9wZXJ0eVtdO1xyXG4gIGludmVyc2VGb3JlaWduS2V5UHJvcGVydGllczogRGF0YVByb3BlcnR5W107XHJcbiAgLyoqICBUaGUgRGF0YVByb3BlcnRpZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgRW50aXR5VHlwZSB0aGF0IGFyZSBjb25jdXJyZW5jeSBwcm9wZXJ0aWVzLiBfX1JlYWQgT25seV9fICoqL1xyXG4gIGNvbmN1cnJlbmN5UHJvcGVydGllczogRGF0YVByb3BlcnR5W107XHJcbiAgLyoqIFRoZSBEYXRhUHJvcGVydGllcyBmb3IgdGhpcyBFbnRpdHlUeXBlIHRoYXQgY29udGFpbiBpbnN0YW5jZXMgb2YgYSBbW0NvbXBsZXhUeXBlXV0uIF9fUmVhZCBPbmx5X18gICAqKi9cclxuICBjb21wbGV4UHJvcGVydGllczogRGF0YVByb3BlcnR5W107XHJcbiAgLyoqIFRoZSBEYXRhUHJvcGVydGllcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBFbnRpdHlUeXBlIHRoYXQgYXJlIG5vdCBtYXBwZWQgdG8gYW55IGJhY2tlbmQgZGF0YXN0b3JlLiBUaGVzZSBhcmUgZWZmZWN0aXZlbHkgZnJlZSBzdGFuZGluZ1xyXG4gIHByb3BlcnRpZXMuIF9fUmVhZCBPbmx5X18gKiovXHJcbiAgdW5tYXBwZWRQcm9wZXJ0aWVzOiBEYXRhUHJvcGVydHlbXTtcclxuXHJcbiAgLyoqIFRoZSBmdWxseSBxdWFsaWZpZWQgbmFtZSBvZiB0aGlzIEVudGl0eVR5cGUuIF9fUmVhZCBPbmx5X18gICoqL1xyXG4gIG5hbWU6IHN0cmluZztcclxuICAvKiogVGhlIHNob3J0LCB1bnF1YWxpZmllZCwgbmFtZSBmb3IgdGhpcyBFbnRpdHlUeXBlLiBfX1JlYWQgT25seV9fICAqKi9cclxuICBzaG9ydE5hbWU6IHN0cmluZztcclxuICAvKiogVGhlIG5hbWVzcGFjZSBmb3IgdGhpcyBFbnRpdHlUeXBlLiBfX1JlYWQgT25seV9fICAqKi9cclxuICBuYW1lc3BhY2U6IHN0cmluZztcclxuICAvKiogVGhlIG5hbWUgb2YgdGhpcyBFbnRpdHlUeXBlJ3MgYmFzZSBFbnRpdHlUeXBlICAoaWYgYW55KSAqL1xyXG4gIGJhc2VUeXBlTmFtZT86IHN0cmluZztcclxuICAvKiogVGhlIGJhc2UgRW50aXR5VHlwZSAoaWYgYW55KSBmb3IgdGhpcyBFbnRpdHlUeXBlLiBfX1JlYWQgT25seV9fICAgKiovXHJcbiAgYmFzZUVudGl0eVR5cGU6IEVudGl0eVR5cGU7XHJcbiAgc3VidHlwZXM6IEVudGl0eVR5cGVbXTtcclxuXHJcbiAgLyoqICBXaGV0aGVyIHRoaXMgRW50aXR5VHlwZSBpcyBhYnN0cmFjdC4gX19SZWFkIE9ubHlfXyAqKi9cclxuICBpc0Fic3RyYWN0OiBib29sZWFuO1xyXG4gIC8qKiAgV2hldGhlciB0aGlzIEVudGl0eVR5cGUgaXMgYW5vbnltb3VzLiBBbm9ueW1vdXMgdHlwZXMgd2lsbCBuZXZlciBiZSBjb21tdW5pY2F0ZWQgdG8gb3IgZnJvbSB0aGUgc2VydmVyLiBUaGV5IGFyZSBwdXJlbHkgZm9yXHJcbiAgY2xpZW50IHNpZGUgdXNlIGFuZCBhcmUgZ2l2ZW4gYW4gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgbmFtZS4gIF9fUmVhZCBPbmx5X18gKiovXHJcbiAgaXNBbm9ueW1vdXM6IGJvb2xlYW47XHJcbiAgLyoqIFdoZXRoZXIgdGhpcyBFbnRpdHlUeXBlIGhhcyBiZWVuICdmcm96ZW4nLiAgRW50aXR5VHlwZXMgYmVjb21lIGZyb3plbiBhZnRlciB0aGUgZmlyc3QgaW5zdGFuY2UgXHJcbiAgb2YgdGhhdCB0eXBlIGhhcyBiZWVuIGNyZWF0ZWQgYW5kIGF0dGFjaGVkIHRvIGFuIEVudGl0eU1hbmFnZXIuICovXHJcbiAgaXNGcm96ZW46IGJvb2xlYW47XHJcblxyXG4gIC8qKiBUaGUgW1tBdXRvR2VuZXJhdGVkS2V5VHlwZV1dIGZvciB0aGlzIEVudGl0eVR5cGUuIF9fUmVhZCBPbmx5X18gKiovXHJcbiAgYXV0b0dlbmVyYXRlZEtleVR5cGU6IEF1dG9HZW5lcmF0ZWRLZXlUeXBlO1xyXG4gIC8qKiAgIFRoZSBkZWZhdWx0IHJlc291cmNlIG5hbWUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgRW50aXR5VHlwZS4gIEFuIEVudGl0eVR5cGUgbWF5IGJlIHF1ZXJpZWQgdmlhIGEgdmFyaWV0eSBvZiAncmVzb3VyY2UgbmFtZXMnIGJ1dCB0aGlzIG9uZVxyXG4gIGlzIHVzZWQgYXMgdGhlIGRlZmF1bHQgd2hlbiBubyByZXNvdXJjZSBuYW1lIGlzIHByb3ZpZGVkLiAgVGhpcyB3aWxsIG9jY3VyIHdoZW4gY2FsbGluZyBbW0VudGl0eUFzcGVjdC5sb2FkTmF2aWdhdGlvblByb3BlcnR5XV1cclxuICBvciB3aGVuIGV4ZWN1dGluZyBhbnkgW1tFbnRpdHlRdWVyeV1dIHRoYXQgd2FzIGNyZWF0ZWQgdmlhIGFuIFtbRW50aXR5S2V5XV0uIF9fUmVhZCBPbmx5X18gKiovXHJcbiAgZGVmYXVsdFJlc291cmNlTmFtZTogc3RyaW5nO1xyXG4gIC8qKiBBIGZ1bmN0aW9uIHRoYXQgaXMgdXNlZCB0byBjdXN0b21pemUgdGhlIHNlcmlhbGl6YXRpb24gb2YgYW55IEVudGl0eVByb3BlcnRpZXMgb2YgdGhpcyB0eXBlLiAqL1xyXG4gIHNlcmlhbGl6ZXJGbj86IChwcm9wOiBFbnRpdHlQcm9wZXJ0eSwgdmFsOiBhbnkpID0+IGFueTtcclxuICAvKiogIEEgZnJlZSBmb3JtIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIGRlZmluZSBhbnkgY3VzdG9tIG1ldGFkYXRhIGZvciB0aGlzIEVudGl0eVR5cGUuIF9fUmVhZCBPbmx5X18gICoqL1xyXG4gIGN1c3RvbT86IGFueTtcclxuICAvKiogVGhlIGVudGl0eSBsZXZlbCB2YWxpZGF0b3JzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIEVudGl0eVR5cGUuIFZhbGlkYXRvcnMgY2FuIGJlIGFkZGVkIGFuZFxyXG4gIHJlbW92ZWQgZnJvbSB0aGlzIGNvbGxlY3Rpb24uIF9fUmVhZCBPbmx5X18uICAgKiovXHJcbiAgdmFsaWRhdG9yczogVmFsaWRhdG9yW107XHJcblxyXG4gIHdhcm5pbmdzOiBhbnlbXTtcclxuICBpbml0Rm46IEZ1bmN0aW9uIHwgc3RyaW5nO1xyXG4gIG5vVHJhY2tpbmdGbjogRnVuY3Rpb247XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9leHRyYTogYW55O1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9jdG9yOiB7IG5ldyAoKTogU3RydWN0dXJhbE9iamVjdCB9O1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9tYXBwZWRQcm9wZXJ0aWVzQ291bnQ6IG51bWJlcjtcclxuXHJcbiAgLyoqIFxyXG4gIEBkZXByZWNhdGVkIFVzZSBbW2dldEN0b3JdXSBpbnN0ZWFkLiAgIFxyXG4gICovXHJcbiAgZ2V0RW50aXR5Q3RvciA9IHRoaXMuZ2V0Q3RvcjtcclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgc3RhdGljIHF1YWxpZnlUeXBlTmFtZSA9IHF1YWxpZnlUeXBlTmFtZTtcclxuXHJcblxyXG4gIC8qKiBFbnRpdHlUeXBlIGNvbnN0cnVjdG9yICBcclxuICA+ICAgICAgbGV0IGVudGl0eVR5cGUgPSBuZXcgRW50aXR5VHlwZSgge1xyXG4gID4gICAgICAgICAgc2hvcnROYW1lOiBcInBlcnNvblwiLFxyXG4gID4gICAgICAgICAgbmFtZXNwYWNlOiBcIm15QXBwTmFtZXNwYWNlXCJcclxuICA+ICAgICAgfSk7XHJcbiAgQHBhcmFtIGNvbmZpZyAtIENvbmZpZ3VyYXRpb24gc2V0dGluZ3Mgb3IgYSBNZXRhZGF0YVN0b3JlLiAgSWYgdGhpcyBwYXJhbWV0ZXIgaXMganVzdCBhIE1ldGFkYXRhU3RvcmVcclxuICB0aGVuIHdoYXQgd2lsbCBiZSBjcmVhdGVkIGlzIGFuICdhbm9ueW1vdXMnIHR5cGUgdGhhdCB3aWxsIG5ldmVyIGJlIGNvbW11bmljYXRlZCB0byBvciBmcm9tIHRoZSBzZXJ2ZXIuIEl0IGlzIHB1cmVseSBmb3JcclxuICBjbGllbnQgc2lkZSB1c2UgYW5kIHdpbGwgYmUgZ2l2ZW4gYW4gYXV0b21hdGljYWxseSBnZW5lcmF0ZWQgbmFtZS4gTm9ybWFsbHksIGhvd2V2ZXIsIHlvdSB3aWxsIHVzZSBhIGNvbmZpZ3VyYXRpb24gb2JqZWN0LlxyXG4gICoqL1xyXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogTWV0YWRhdGFTdG9yZSB8IEVudGl0eVR5cGVDb25maWcpIHtcclxuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgRW50aXR5VHlwZSBjdG9yIGhhcyBhIHNpbmdsZSBhcmd1bWVudCB0aGF0IGlzIGVpdGhlciBhICdNZXRhZGF0YVN0b3JlJyBvciBhIGNvbmZpZ3VyYXRpb24gb2JqZWN0LlwiKTtcclxuICAgIH1cclxuICAgIC8vIGxldCBldENvbmZpZyA9ICA8RW50aXR5VHlwZUNvbmZpZz4gPGFueT4gdW5kZWZpbmVkO1xyXG4gICAgbGV0IGV0Q29uZmlnOiBFbnRpdHlUeXBlQ29uZmlnIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xyXG5cclxuICAgIGlmICgoY29uZmlnIGFzIGFueSkuXyR0eXBlTmFtZSA9PT0gXCJNZXRhZGF0YVN0b3JlXCIpIHtcclxuICAgICAgdGhpcy5tZXRhZGF0YVN0b3JlID0gY29uZmlnIGFzIE1ldGFkYXRhU3RvcmU7XHJcbiAgICAgIHRoaXMuc2hvcnROYW1lID0gXCJBbm9uX1wiICsgKCsrRW50aXR5VHlwZS5fX25leHRBbm9uSXgpO1xyXG4gICAgICB0aGlzLm5hbWVzcGFjZSA9IFwiXCI7XHJcbiAgICAgIHRoaXMuaXNBbm9ueW1vdXMgPSB0cnVlO1xyXG4gICAgICAvLyBldENvbmZpZyA9IHVuZGVmaW5lZDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGV0Q29uZmlnID0gY29uZmlnIGFzIEVudGl0eVR5cGVDb25maWc7XHJcbiAgICAgIGFzc2VydENvbmZpZyhjb25maWcpXHJcbiAgICAgICAgLndoZXJlUGFyYW0oXCJzaG9ydE5hbWVcIikuaXNOb25FbXB0eVN0cmluZygpXHJcbiAgICAgICAgLndoZXJlUGFyYW0oXCJuYW1lc3BhY2VcIikuaXNTdHJpbmcoKS5pc09wdGlvbmFsKCkud2l0aERlZmF1bHQoXCJcIilcclxuICAgICAgICAud2hlcmVQYXJhbShcImJhc2VUeXBlTmFtZVwiKS5pc1N0cmluZygpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAgIC53aGVyZVBhcmFtKFwiaXNBYnN0cmFjdFwiKS5pc0Jvb2xlYW4oKS5pc09wdGlvbmFsKCkud2l0aERlZmF1bHQoZmFsc2UpXHJcbiAgICAgICAgLndoZXJlUGFyYW0oXCJhdXRvR2VuZXJhdGVkS2V5VHlwZVwiKS5pc0VudW1PZihBdXRvR2VuZXJhdGVkS2V5VHlwZSkuaXNPcHRpb25hbCgpLndpdGhEZWZhdWx0KEF1dG9HZW5lcmF0ZWRLZXlUeXBlLk5vbmUpXHJcbiAgICAgICAgLndoZXJlUGFyYW0oXCJkZWZhdWx0UmVzb3VyY2VOYW1lXCIpLmlzTm9uRW1wdHlTdHJpbmcoKS5pc09wdGlvbmFsKCkud2l0aERlZmF1bHQobnVsbClcclxuICAgICAgICAud2hlcmVQYXJhbShcImRhdGFQcm9wZXJ0aWVzXCIpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAgIC53aGVyZVBhcmFtKFwibmF2aWdhdGlvblByb3BlcnRpZXNcIikuaXNPcHRpb25hbCgpXHJcbiAgICAgICAgLndoZXJlUGFyYW0oXCJzZXJpYWxpemVyRm5cIikuaXNPcHRpb25hbCgpLmlzRnVuY3Rpb24oKVxyXG4gICAgICAgIC53aGVyZVBhcmFtKFwiY3VzdG9tXCIpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAgIC5hcHBseUFsbCh0aGlzKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLm5hbWUgPSBxdWFsaWZ5VHlwZU5hbWUodGhpcy5zaG9ydE5hbWUsIHRoaXMubmFtZXNwYWNlKTtcclxuXHJcbiAgICAvLyB0aGUgZGVmYXVsdFJlc291cmNlTmFtZSBtYXkgYWxzbyBiZSBzZXQgdXAgZWl0aGVyIHZpYSBtZXRhZGF0YSBsb29rdXAgb3IgZmlyc3QgcXVlcnkgb3IgdmlhIHRoZSAnc2V0UHJvcGVydGllcycgbWV0aG9kXHJcbiAgICB0aGlzLmRhdGFQcm9wZXJ0aWVzID0gW107XHJcbiAgICB0aGlzLm5hdmlnYXRpb25Qcm9wZXJ0aWVzID0gW107XHJcbiAgICB0aGlzLmNvbXBsZXhQcm9wZXJ0aWVzID0gW107XHJcbiAgICB0aGlzLmtleVByb3BlcnRpZXMgPSBbXTtcclxuICAgIHRoaXMuZm9yZWlnbktleVByb3BlcnRpZXMgPSBbXTtcclxuICAgIHRoaXMuaW52ZXJzZUZvcmVpZ25LZXlQcm9wZXJ0aWVzID0gW107XHJcbiAgICB0aGlzLmNvbmN1cnJlbmN5UHJvcGVydGllcyA9IFtdO1xyXG4gICAgdGhpcy51bm1hcHBlZFByb3BlcnRpZXMgPSBbXTsgLy8gd2lsbCBiZSB1cGRhdGVkIGxhdGVyLlxyXG4gICAgdGhpcy52YWxpZGF0b3JzID0gW107XHJcbiAgICB0aGlzLndhcm5pbmdzID0gW107XHJcbiAgICB0aGlzLl9tYXBwZWRQcm9wZXJ0aWVzQ291bnQgPSAwO1xyXG4gICAgdGhpcy5zdWJ0eXBlcyA9IFtdO1xyXG4gICAgLy8gbm93IHByb2Nlc3MgYW55IGRhdGEvbmF2IHByb3BzXHJcbiAgICBpZiAoZXRDb25maWcgJiYgZXRDb25maWcuZGF0YVByb3BlcnRpZXMpIHtcclxuICAgICAgYWRkUHJvcGVydGllcyh0aGlzLCBldENvbmZpZy5kYXRhUHJvcGVydGllcywgRGF0YVByb3BlcnR5KTtcclxuICAgIH1cclxuICAgIGlmIChldENvbmZpZyAmJiBldENvbmZpZy5uYXZpZ2F0aW9uUHJvcGVydGllcykge1xyXG4gICAgICBhZGRQcm9wZXJ0aWVzKHRoaXMsIGV0Q29uZmlnLm5hdmlnYXRpb25Qcm9wZXJ0aWVzLCBOYXZpZ2F0aW9uUHJvcGVydHkpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgR2VuZXJhbCBwdXJwb3NlIHByb3BlcnR5IHNldCBtZXRob2RcclxuICA+ICAgICAgLy8gYXNzdW1lIGVtMSBpcyBhbiBFbnRpdHlNYW5hZ2VyIGNvbnRhaW5pbmcgYSBudW1iZXIgb2YgZXhpc3RpbmcgZW50aXRpZXMuXHJcbiAgPiAgICAgIGxldCBjdXN0VHlwZSA9IGVtMS5tZXRhZGF0YVN0b3JlLmdldEVudGl0eVR5cGUoXCJDdXN0b21lclwiKTtcclxuICA+ICAgICAgY3VzdFR5cGUuc2V0UHJvcGVydGllcygge1xyXG4gID4gICAgICAgICAgYXV0b0dlbmVyYXRlZEtleVR5cGU6IEF1dG9HZW5lcmF0ZWRLZXlUeXBlLklkZW50aXR5O1xyXG4gID4gICAgICAgICAgZGVmYXVsdFJlc291cmNlTmFtZTogXCJDdXN0b21lcnNBbmRJbmNsdWRlZE9yZGVyc1wiXHJcbiAgPiAgICAgICl9O1xyXG4gIEBwYXJhbSBjb25maWcgLSBhIGNvbmZpZ3VyYXRpb24gb2JqZWN0XHJcbiAgKiovXHJcbiAgc2V0UHJvcGVydGllcyhjb25maWc6IEVudGl0eVR5cGVTZXRDb25maWcpIHtcclxuICAgIGFzc2VydENvbmZpZyhjb25maWcpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiYXV0b0dlbmVyYXRlZEtleVR5cGVcIikuaXNFbnVtT2YoQXV0b0dlbmVyYXRlZEtleVR5cGUpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAud2hlcmVQYXJhbShcImRlZmF1bHRSZXNvdXJjZU5hbWVcIikuaXNTdHJpbmcoKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJzZXJpYWxpemVyRm5cIikuaXNGdW5jdGlvbigpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAud2hlcmVQYXJhbShcImN1c3RvbVwiKS5pc09wdGlvbmFsKClcclxuICAgICAgLmFwcGx5QWxsKHRoaXMpO1xyXG4gICAgaWYgKGNvbmZpZy5kZWZhdWx0UmVzb3VyY2VOYW1lKSB7XHJcbiAgICAgIHRoaXMuZGVmYXVsdFJlc291cmNlTmFtZSA9IGNvbmZpZy5kZWZhdWx0UmVzb3VyY2VOYW1lO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyB3aGV0aGVyIHRoaXMgdHlwZSBpcyBhIHN1YnR5cGUgb2YgYSBzcGVjaWZpZWQgdHlwZS5cclxuICAqKi9cclxuICBpc1N1YnR5cGVPZihlbnRpdHlUeXBlOiBFbnRpdHlUeXBlKSB7XHJcbiAgICBhc3NlcnRQYXJhbShlbnRpdHlUeXBlLCBcImVudGl0eVR5cGVcIikuaXNJbnN0YW5jZU9mKEVudGl0eVR5cGUpLmNoZWNrKCk7XHJcbiAgICBsZXQgYmFzZVR5cGU6IEVudGl0eVR5cGUgPSB0aGlzO1xyXG4gICAgZG8ge1xyXG4gICAgICBpZiAoYmFzZVR5cGUgPT09IGVudGl0eVR5cGUpIHJldHVybiB0cnVlO1xyXG4gICAgICBiYXNlVHlwZSA9IGJhc2VUeXBlLmJhc2VFbnRpdHlUeXBlO1xyXG4gICAgfSB3aGlsZSAoYmFzZVR5cGUpO1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhbiBhcnJheSBjb250YWluaW5nIHRoaXMgdHlwZSBhbmQgYW55L2FsbCBzdWJ0eXBlcyBvZiB0aGlzIHR5cGUgZG93biB0aHJ1IHRoZSBoaWVyYXJjaHkuXHJcbiAgKiovXHJcbiAgZ2V0U2VsZkFuZFN1YnR5cGVzKCkge1xyXG4gICAgbGV0IHJlc3VsdCA9IFt0aGlzXTtcclxuICAgIHRoaXMuc3VidHlwZXMuZm9yRWFjaChmdW5jdGlvbiAoc3QpIHtcclxuICAgICAgbGV0IHN1YnR5cGVzID0gc3QuZ2V0U2VsZkFuZFN1YnR5cGVzKCk7XHJcbiAgICAgIHJlc3VsdC5wdXNoLmFwcGx5KHJlc3VsdCwgc3VidHlwZXMpO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG4gIH1cclxuXHJcbiAgZ2V0QWxsVmFsaWRhdG9ycygpIHtcclxuICAgIGxldCByZXN1bHQgPSB0aGlzLnZhbGlkYXRvcnMuc2xpY2UoMCk7XHJcbiAgICBsZXQgYnQgPSB0aGlzLmJhc2VFbnRpdHlUeXBlO1xyXG4gICAgd2hpbGUgKGJ0KSB7XHJcbiAgICAgIHJlc3VsdC5wdXNoLmFwcGx5KHJlc3VsdCwgYnQudmFsaWRhdG9ycyk7XHJcbiAgICAgIGJ0ID0gYnQuYmFzZUVudGl0eVR5cGU7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgQWRkcyBhICBbW0RhdGFQcm9wZXJ0eV1dIG9yIGEgW1tOYXZpZ2F0aW9uUHJvcGVydHldXSB0byB0aGlzIEVudGl0eVR5cGUuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBteUVudGl0eVR5cGUgaXMgYSBuZXdseSBjb25zdHJ1Y3RlZCBFbnRpdHlUeXBlLlxyXG4gID4gICAgICBteUVudGl0eVR5cGUuYWRkUHJvcGVydHkoZGF0YVByb3BlcnR5MSk7XHJcbiAgPiAgICAgIG15RW50aXR5VHlwZS5hZGRQcm9wZXJ0eShkYXRhUHJvcGVydHkyKTtcclxuICA+ICAgICAgbXlFbnRpdHlUeXBlLmFkZFByb3BlcnR5KG5hdmlnYXRpb25Qcm9wZXJ0eTEpO1xyXG4gICoqL1xyXG4gIGFkZFByb3BlcnR5KHByb3BlcnR5OiBFbnRpdHlQcm9wZXJ0eSkge1xyXG4gICAgYXNzZXJ0UGFyYW0ocHJvcGVydHksIFwicHJvcGVydHlcIikuaXNJbnN0YW5jZU9mKERhdGFQcm9wZXJ0eSkub3IoKS5pc0luc3RhbmNlT2YoTmF2aWdhdGlvblByb3BlcnR5KS5jaGVjaygpO1xyXG5cclxuICAgIC8vIHRydWUgaXMgMm5kIGFyZyB0byBmb3JjZSByZXNvbHZlIG9mIGFueSBuYXZpZ2F0aW9uIHByb3BlcnRpZXMuXHJcbiAgICBsZXQgbmV3cHJvcCA9IHRoaXMuX2FkZFByb3BlcnR5Q29yZShwcm9wZXJ0eSwgdHJ1ZSk7XHJcblxyXG4gICAgaWYgKHRoaXMuc3VidHlwZXMgJiYgdGhpcy5zdWJ0eXBlcy5sZW5ndGgpIHtcclxuICAgICAgbGV0IHN0eXBlID0gdGhpcztcclxuICAgICAgc3R5cGUuZ2V0U2VsZkFuZFN1YnR5cGVzKCkuZm9yRWFjaChmdW5jdGlvbiAoc3QpIHtcclxuICAgICAgICBpZiAoc3QgIT09IHN0eXBlKSB7XHJcbiAgICAgICAgICBpZiAocHJvcGVydHkuaXNOYXZpZ2F0aW9uUHJvcGVydHkpIHtcclxuICAgICAgICAgICAgc3QuX2FkZFByb3BlcnR5Q29yZShuZXcgTmF2aWdhdGlvblByb3BlcnR5KHByb3BlcnR5KSwgdHJ1ZSk7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBzdC5fYWRkUHJvcGVydHlDb3JlKG5ldyBEYXRhUHJvcGVydHkocHJvcGVydHkgYXMgRGF0YVByb3BlcnR5KSwgdHJ1ZSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXdwcm9wO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3VwZGF0ZUZyb21CYXNlKGJhc2VFbnRpdHlUeXBlOiBFbnRpdHlUeXBlKSB7XHJcbiAgICB0aGlzLmJhc2VFbnRpdHlUeXBlID0gYmFzZUVudGl0eVR5cGU7XHJcbiAgICBpZiAodGhpcy5hdXRvR2VuZXJhdGVkS2V5VHlwZSA9PT0gQXV0b0dlbmVyYXRlZEtleVR5cGUuTm9uZSkge1xyXG4gICAgICB0aGlzLmF1dG9HZW5lcmF0ZWRLZXlUeXBlID0gYmFzZUVudGl0eVR5cGUuYXV0b0dlbmVyYXRlZEtleVR5cGU7XHJcbiAgICB9XHJcblxyXG4gICAgYmFzZUVudGl0eVR5cGUuZGF0YVByb3BlcnRpZXMuZm9yRWFjaCgoZHApID0+IHtcclxuICAgICAgbGV0IG5ld0RwID0gbmV3IERhdGFQcm9wZXJ0eShkcCk7XHJcbiAgICAgIC8vIGRvbid0IG5lZWQgdG8gY29weSB2YWxpZGF0b3JzIGJlY2F1ZSB3ZSB3aWxsIHdhbGsgdGhlIGhpZXJhcmNoeSB0byBmaW5kIHRoZW1cclxuICAgICAgbmV3RHAudmFsaWRhdG9ycyA9IFtdO1xyXG4gICAgICBuZXdEcC5iYXNlUHJvcGVydHkgPSBkcDtcclxuICAgICAgdGhpcy5fYWRkUHJvcGVydHlDb3JlKG5ld0RwKTtcclxuICAgIH0sIHRoaXMpO1xyXG4gICAgYmFzZUVudGl0eVR5cGUubmF2aWdhdGlvblByb3BlcnRpZXMuZm9yRWFjaCgobnApID0+IHtcclxuICAgICAgbGV0IG5ld05wID0gbmV3IE5hdmlnYXRpb25Qcm9wZXJ0eShucCk7XHJcbiAgICAgIC8vIGRvbid0IG5lZWQgdG8gY29weSB2YWxpZGF0b3JzIGJlY2F1ZSB3ZSB3aWxsIHdhbGsgdGhlIGhpZXJhcmNoeSB0byBmaW5kIHRoZW1cclxuICAgICAgbmV3TnAudmFsaWRhdG9ycyA9IFtdO1xyXG4gICAgICBuZXdOcC5iYXNlUHJvcGVydHkgPSBucDtcclxuICAgICAgdGhpcy5fYWRkUHJvcGVydHlDb3JlKG5ld05wKTtcclxuICAgIH0sIHRoaXMpO1xyXG4gICAgYmFzZUVudGl0eVR5cGUuc3VidHlwZXMucHVzaCh0aGlzKTtcclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9hZGRQcm9wZXJ0eUNvcmUocHJvcGVydHk6IEVudGl0eVByb3BlcnR5LCBzaG91bGRSZXNvbHZlOiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgIGlmICh0aGlzLmlzRnJvemVuKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSAnXCIgKyB0aGlzLm5hbWUgKyBcIicgRW50aXR5VHlwZS9Db21wbGV4VHlwZSBoYXMgYmVlbiBmcm96ZW4uIFlvdSBjYW4gb25seSBhZGQgcHJvcGVydGllcyB0byBhbiBFbnRpdHlUeXBlL0NvbXBsZXhUeXBlIGJlZm9yZSBhbnkgaW5zdGFuY2VzIG9mIHRoYXQgdHlwZSBoYXZlIGJlZW4gY3JlYXRlZCBhbmQgYXR0YWNoZWQgdG8gYW4gZW50aXR5TWFuYWdlci5cIik7XHJcbiAgICB9XHJcbiAgICBsZXQgcGFyZW50VHlwZSA9IHByb3BlcnR5LnBhcmVudFR5cGU7XHJcbiAgICBpZiAocGFyZW50VHlwZSkge1xyXG4gICAgICBpZiAocGFyZW50VHlwZSAhPT0gdGhpcykge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoaXMgcHJvcGVydHk6IFwiICsgcHJvcGVydHkubmFtZSArIFwiIGhhcyBhbHJlYWR5IGJlZW4gYWRkZWQgdG8gXCIgKyBwcm9wZXJ0eS5wYXJlbnRUeXBlLm5hbWUpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIGFkZGluZyB0aGUgc2FtZSBwcm9wZXJ0eSBtb3JlIHRoYW4gb25jZSB0byB0aGUgc2FtZSBlbnRpdHlUeXBlIGlzIGp1c3QgaWdub3JlZC5cclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHByb3BlcnR5LnBhcmVudFR5cGUgPSB0aGlzO1xyXG4gICAgbGV0IG1zID0gdGhpcy5tZXRhZGF0YVN0b3JlO1xyXG4gICAgLy8gaWYgKHByb3BlcnR5LmlzRGF0YVByb3BlcnR5KSB7IC8vIG1vZGlmaWVkIGJlY2F1c2UgZG9lc24ndCBhY3QgYXMgYSB0eXBlIGd1YXJkIFxyXG4gICAgaWYgKHByb3BlcnR5IGluc3RhbmNlb2YgRGF0YVByb3BlcnR5KSB7XHJcbiAgICAgIHRoaXMuX2FkZERhdGFQcm9wZXJ0eShwcm9wZXJ0eSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLl9hZGROYXZpZ2F0aW9uUHJvcGVydHkocHJvcGVydHkpO1xyXG4gICAgICAvLyBtZXRhZGF0YVN0b3JlIGNhbiBiZSB1bmRlZmluZWQgaWYgdGhpcyBlbnRpdHlUeXBlIGhhcyBub3QgeWV0IGJlZW4gYWRkZWQgdG8gYSBNZXRhZGF0YVN0b3JlLlxyXG4gICAgICBpZiAoc2hvdWxkUmVzb2x2ZSAmJiBtcykge1xyXG4gICAgICAgIHRyeVJlc29sdmVOcChwcm9wZXJ0eSwgbXMpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyB1bm1hcHBlZCBwcm9wZXJ0aWVzIGNhbiBiZSBhZGRlZCBBRlRFUiBlbnRpdHlUeXBlIGhhcyBhbHJlYWR5IHJlc29sdmVkIGFsbCBwcm9wZXJ0eSBuYW1lcy5cclxuICAgIGlmIChtcyAmJiAhKHByb3BlcnR5Lm5hbWUgJiYgcHJvcGVydHkubmFtZU9uU2VydmVyKSkge1xyXG4gICAgICB1cGRhdGVDbGllbnRTZXJ2ZXJOYW1lcyhtcy5uYW1pbmdDb252ZW50aW9uLCBwcm9wZXJ0eSwgXCJuYW1lXCIpO1xyXG4gICAgfVxyXG4gICAgLy8gcHJvcHMgY2FuIGJlIGFkZGVkIGFmdGVyIGVudGl0eSBwcm90b3R5cGUgaGFzIGFscmVhZHkgYmVlbiB3cmFwcGVkLlxyXG4gICAgaWYgKG1zICYmIHRoaXMuX2V4dHJhKSB7XHJcbiAgICAgIGlmICh0aGlzLl9leHRyYS5hbHJlYWR5V3JhcHBlZFByb3BzKSB7XHJcbiAgICAgICAgbGV0IHByb3RvID0gdGhpcy5fY3Rvci5wcm90b3R5cGU7XHJcbiAgICAgICAgY29uZmlnLmludGVyZmFjZVJlZ2lzdHJ5Lm1vZGVsTGlicmFyeS5nZXREZWZhdWx0SW5zdGFuY2UoKS5pbml0aWFsaXplRW50aXR5UHJvdG90eXBlKHByb3RvKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgQ3JlYXRlIGEgbmV3IGVudGl0eSBvZiB0aGlzIHR5cGUuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBlbTEgaXMgYW4gRW50aXR5TWFuYWdlciBjb250YWluaW5nIGEgbnVtYmVyIG9mIGV4aXN0aW5nIGVudGl0aWVzLlxyXG4gID4gICAgICBsZXQgY3VzdFR5cGUgPSBlbTEubWV0YWRhdGFTdG9yZS5nZXRBc0VudGl0eVR5cGUoXCJDdXN0b21lclwiKTtcclxuICA+ICAgICAgbGV0IGN1c3QxID0gY3VzdFR5cGUuY3JlYXRlRW50aXR5KCk7XHJcbiAgPiAgICAgIGVtMS5hZGRFbnRpdHkoY3VzdDEpO1xyXG4gIEBwYXJhbSBpbml0aWFsVmFsdWVzLSBDb25maWd1cmF0aW9uIG9iamVjdCBvZiB0aGUgcHJvcGVydGllcyB0byBzZXQgaW1tZWRpYXRlbHkgYWZ0ZXIgY3JlYXRpb24uXHJcbiAgQHJldHVybiBUaGUgbmV3IGVudGl0eS5cclxuICAqKi9cclxuICBjcmVhdGVFbnRpdHkoaW5pdGlhbFZhbHVlcz86IGFueSk6IGFueSB7XHJcbiAgICAvLyBpZ25vcmUgdGhlIF8kZXJlZiBvbmNlIHRoZSBlbnRpdHkgaXMgYXR0YWNoZWQgdG8gYW4gZW50aXR5TWFuYWdlci5cclxuICAgIGlmIChpbml0aWFsVmFsdWVzICYmIGluaXRpYWxWYWx1ZXMuXyRlcmVmICYmICFpbml0aWFsVmFsdWVzLl8kZXJlZi5lbnRpdHlBc3BlY3QuZW50aXR5TWFuYWdlcikgcmV0dXJuIGluaXRpYWxWYWx1ZXMuXyRlcmVmO1xyXG5cclxuICAgIGxldCBpbnN0YW5jZSA9IHRoaXMuX2NyZWF0ZUluc3RhbmNlQ29yZSgpO1xyXG5cclxuICAgIGlmIChpbml0aWFsVmFsdWVzKSB7XHJcbiAgICAgIC8vIG9ubHkgYXNzaWduIGFuIF9lcmVmIGlmIHRoZSBvYmplY3QgaXMgZnVsbHkgXCJrZXllZFwiXHJcbiAgICAgIGlmICh0aGlzLmtleVByb3BlcnRpZXMuZXZlcnkoZnVuY3Rpb24gKGtwKSB7XHJcbiAgICAgICAgcmV0dXJuIGluaXRpYWxWYWx1ZXNba3AubmFtZV0gIT0gbnVsbDtcclxuICAgICAgfSkpIHtcclxuICAgICAgICBpbml0aWFsVmFsdWVzLl8kZXJlZiA9IGluc3RhbmNlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLl91cGRhdGVUYXJnZXRGcm9tUmF3KGluc3RhbmNlLCBpbml0aWFsVmFsdWVzLCBnZXRSYXdWYWx1ZUZyb21Db25maWcpO1xyXG5cclxuICAgICAgdGhpcy5uYXZpZ2F0aW9uUHJvcGVydGllcy5mb3JFYWNoKGZ1bmN0aW9uIChucCkge1xyXG4gICAgICAgIGxldCByZWxhdGVkRW50aXR5OiBhbnk7XHJcbiAgICAgICAgbGV0IHZhbCA9IGluaXRpYWxWYWx1ZXNbbnAubmFtZV07XHJcbiAgICAgICAgaWYgKHZhbCAhPSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgIGxldCBuYXZFbnRpdHlUeXBlID0gbnAuZW50aXR5VHlwZTtcclxuICAgICAgICAgIGlmIChucC5pc1NjYWxhcikge1xyXG4gICAgICAgICAgICByZWxhdGVkRW50aXR5ID0gdmFsLmVudGl0eUFzcGVjdCA/IHZhbCA6IG5hdkVudGl0eVR5cGUuY3JlYXRlRW50aXR5KHZhbCk7XHJcbiAgICAgICAgICAgIGluc3RhbmNlLnNldFByb3BlcnR5KG5wLm5hbWUsIHJlbGF0ZWRFbnRpdHkpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbGV0IHJlbGF0ZWRFbnRpdGllcyA9IGluc3RhbmNlLmdldFByb3BlcnR5KG5wLm5hbWUpO1xyXG4gICAgICAgICAgICB2YWwuZm9yRWFjaCgodjogYW55KSA9PiB7XHJcbiAgICAgICAgICAgICAgcmVsYXRlZEVudGl0eSA9IHYuZW50aXR5QXNwZWN0ID8gdiA6IG5hdkVudGl0eVR5cGUuY3JlYXRlRW50aXR5KHYpO1xyXG4gICAgICAgICAgICAgIHJlbGF0ZWRFbnRpdGllcy5wdXNoKHJlbGF0ZWRFbnRpdHkpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX2luaXRpYWxpemVJbnN0YW5jZShpbnN0YW5jZSk7XHJcbiAgICByZXR1cm4gaW5zdGFuY2U7XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfY3JlYXRlSW5zdGFuY2VDb3JlKCkge1xyXG4gICAgbGV0IGFDdG9yID0gdGhpcy5nZXRDdG9yKCk7XHJcbiAgICBsZXQgaW5zdGFuY2UgPSBuZXcgYUN0b3IoKTtcclxuICAgIG5ldyBFbnRpdHlBc3BlY3QoaW5zdGFuY2UgYXMgRW50aXR5KTtcclxuICAgIHJldHVybiBpbnN0YW5jZTtcclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9pbml0aWFsaXplSW5zdGFuY2UoaW5zdGFuY2U6IGFueSkge1xyXG4gICAgaWYgKHRoaXMuYmFzZUVudGl0eVR5cGUpIHtcclxuICAgICAgdGhpcy5iYXNlRW50aXR5VHlwZS5faW5pdGlhbGl6ZUluc3RhbmNlKGluc3RhbmNlKTtcclxuICAgIH1cclxuICAgIGxldCBpbml0Rm4gPSB0aGlzLmluaXRGbjtcclxuICAgIGlmIChpbml0Rm4pIHtcclxuICAgICAgbGV0IGZuID0gKHR5cGVvZiBpbml0Rm4gPT09IFwic3RyaW5nXCIpID8gaW5zdGFuY2VbaW5pdEZuXSA6IGluaXRGbjtcclxuICAgICAgZm4oaW5zdGFuY2UpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5jb21wbGV4UHJvcGVydGllcyAmJiB0aGlzLmNvbXBsZXhQcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24gKGNwKSB7XHJcbiAgICAgIGxldCBjb21wbGV4VHlwZSA9IGNwLmRhdGFUeXBlIGFzIENvbXBsZXhUeXBlO1xyXG4gICAgICBsZXQgY3RJbnN0YW5jZSA9IGluc3RhbmNlLmdldFByb3BlcnR5KGNwLm5hbWUpO1xyXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShjdEluc3RhbmNlKSkge1xyXG4gICAgICAgIGN0SW5zdGFuY2UuZm9yRWFjaCgoY3RJbnN0KSA9PiB7XHJcbiAgICAgICAgICBjb21wbGV4VHlwZS5faW5pdGlhbGl6ZUluc3RhbmNlKGN0SW5zdCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgY29tcGxleFR5cGUuX2luaXRpYWxpemVJbnN0YW5jZShjdEluc3RhbmNlKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICAvLyBub3QgbmVlZGVkIGZvciBjb21wbGV4T2JqZWN0c1xyXG4gICAgaWYgKGluc3RhbmNlLmVudGl0eUFzcGVjdCkge1xyXG4gICAgICBpbnN0YW5jZS5lbnRpdHlBc3BlY3QuX2luaXRpYWxpemVkID0gdHJ1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgdGhlIGNvbnN0cnVjdG9yIGZvciB0aGlzIEVudGl0eVR5cGUuXHJcbiAgQHBhcmFtIGZvcmNlUmVmcmVzaCAtIFdoZXRoZXIgdG8gaWdub3JlIGFueSBjYWNoZWQgdmVyc2lvbiBvZiB0aGlzIGNvbnN0cnVjdG9yLiAoZGVmYXVsdCA9PSBmYWxzZSlcclxuICBAcmV0dXJuIFRoZSBjb25zdHJ1Y3RvciBmb3IgdGhpcyBFbnRpdHlUeXBlLlxyXG4gICoqL1xyXG4gIGdldEN0b3IoZm9yY2VSZWZyZXNoOiBib29sZWFuID0gZmFsc2UpOiB7IG5ldyAoKTogU3RydWN0dXJhbE9iamVjdCB9IHtcclxuICAgIGlmICh0aGlzLl9jdG9yICYmICFmb3JjZVJlZnJlc2gpIHJldHVybiB0aGlzLl9jdG9yO1xyXG5cclxuICAgIGxldCBjdG9yUmVnaXN0cnkgPSB0aGlzLm1ldGFkYXRhU3RvcmUuX2N0b3JSZWdpc3RyeTtcclxuICAgIGxldCByID0gY3RvclJlZ2lzdHJ5W3RoaXMubmFtZV0gfHwgY3RvclJlZ2lzdHJ5W3RoaXMuc2hvcnROYW1lXSB8fCB7fSBhcyBDdG9yUmVjb3JkO1xyXG4gICAgbGV0IGFDdG9yID0gci5jdG9yIHx8IHRoaXMuX2N0b3I7XHJcblxyXG4gICAgbGV0IGN0b3JUeXBlID0gYUN0b3IgJiYgYUN0b3IucHJvdG90eXBlICYmIChhQ3Rvci5wcm90b3R5cGUuZW50aXR5VHlwZSB8fCBhQ3Rvci5wcm90b3R5cGUuY29tcGxleFR5cGUpO1xyXG4gICAgaWYgKGN0b3JUeXBlICYmIGN0b3JUeXBlLm1ldGFkYXRhU3RvcmUgIT09IHRoaXMubWV0YWRhdGFTdG9yZSkge1xyXG4gICAgICAvLyBXZSBjYW4ndCByaXNrIGEgbWlzbWF0Y2ggYmV0d2VlbiB0aGUgY3RvciBhbmQgdGhlIHR5cGUgaW5mbyBpbiBhIHNwZWNpZmljIG1ldGFkYXRhc3RvcmVcclxuICAgICAgLy8gYmVjYXVzZSBtb2RlbExpYnJhcmllcyByZWx5IG9uIHR5cGUgaW5mbyB0byBpbnRlcmNlcHQgY3RvciBwcm9wZXJ0aWVzXHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCByZWdpc3RlciB0aGUgc2FtZSBjb25zdHJ1Y3RvciBmb3IgXCIgKyB0aGlzLm5hbWUgKyBcIiBpbiBkaWZmZXJlbnQgbWV0YWRhdGEgc3RvcmVzLiAgUGxlYXNlIGRlZmluZSBhIHNlcGFyYXRlIGNvbnN0cnVjdG9yIGZvciBlYWNoIG1ldGFkYXRhIHN0b3JlLlwiKTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgaWYgKHIuY3RvciAmJiBmb3JjZVJlZnJlc2gpIHtcclxuICAgICAgdGhpcy5fZXh0cmEgPSB1bmRlZmluZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFhQ3Rvcikge1xyXG4gICAgICBsZXQgY3JlYXRlQ3RvciA9IGNvbmZpZy5pbnRlcmZhY2VSZWdpc3RyeS5tb2RlbExpYnJhcnkuZ2V0RGVmYXVsdEluc3RhbmNlKCkuY3JlYXRlQ3RvcjtcclxuICAgICAgYUN0b3IgPSBjcmVhdGVDdG9yID8gY3JlYXRlQ3Rvcih0aGlzKSA6IGNyZWF0ZUVtcHR5Q3Rvcih0aGlzKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmluaXRGbiA9IHIuaW5pdEZuO1xyXG4gICAgdGhpcy5ub1RyYWNraW5nRm4gPSByLm5vVHJhY2tpbmdGbjtcclxuXHJcbiAgICBhQ3Rvci5wcm90b3R5cGUuXyR0eXBlTmFtZSA9IHRoaXMubmFtZTtcclxuICAgIHRoaXMuX3NldEN0b3IoYUN0b3IpO1xyXG4gICAgcmV0dXJuIGFDdG9yO1xyXG4gIH1cclxuXHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIC8vIE1heSBtYWtlIHB1YmxpYyBsYXRlci5cclxuICBfc2V0Q3RvcihhQ3RvcjogeyBuZXcgKCk6IFN0cnVjdHVyYWxPYmplY3QgfSwgaW50ZXJjZXB0b3I/OiBhbnkpIHtcclxuXHJcbiAgICBsZXQgaW5zdGFuY2VQcm90byA9IGFDdG9yLnByb3RvdHlwZTtcclxuXHJcbiAgICAvLyBwbGFjZSBmb3IgZXh0cmEgYnJlZXplIHJlbGF0ZWQgZGF0YVxyXG4gICAgdGhpcy5fZXh0cmEgPSB0aGlzLl9leHRyYSB8fCB7fTtcclxuXHJcbiAgICBsZXQgaW5zdGFuY2UgPSBuZXcgYUN0b3IoKTtcclxuICAgIGNhbGNVbm1hcHBlZFByb3BlcnRpZXModGhpcywgaW5zdGFuY2UpO1xyXG5cclxuICAgIGlmICh0aGlzLl8kdHlwZU5hbWUgPT09IFwiRW50aXR5VHlwZVwiKSB7XHJcbiAgICAgIC8vIGluc3VyZSB0aGF0IGFsbCBvZiB0aGUgcHJvcGVydGllcyBhcmUgb24gdGhlICd0ZW1wbGF0ZScgaW5zdGFuY2UgYmVmb3JlIHdhdGNoaW5nIHRoZSBjbGFzcy5cclxuICAgICAgaW5zdGFuY2VQcm90by5lbnRpdHlUeXBlID0gdGhpcztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGluc3RhbmNlUHJvdG8uY29tcGxleFR5cGUgPSB0aGlzO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGRlZmF1bHRQcm9wZXJ0eUludGVyY2VwdG9yIGlzIGEgJ2dsb2JhbCcgKGJ1dCBpbnRlcm5hbCB0byBicmVlemUpIGZ1bmN0aW9uO1xyXG4gICAgKGluc3RhbmNlUHJvdG8gYXMgYW55KS5fJGludGVyY2VwdG9yID0gaW50ZXJjZXB0b3IgfHwgZGVmYXVsdFByb3BlcnR5SW50ZXJjZXB0b3I7XHJcbiAgICBjb25maWcuaW50ZXJmYWNlUmVnaXN0cnkubW9kZWxMaWJyYXJ5LmdldERlZmF1bHRJbnN0YW5jZSgpLmluaXRpYWxpemVFbnRpdHlQcm90b3R5cGUoaW5zdGFuY2VQcm90byk7XHJcbiAgICB0aGlzLl9jdG9yID0gYUN0b3I7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBBZGRzIGVpdGhlciBhbiBlbnRpdHkgb3IgcHJvcGVydHkgbGV2ZWwgdmFsaWRhdG9yIHRvIHRoaXMgRW50aXR5VHlwZS5cclxuICA+ICAgICAgLy8gYXNzdW1lIGVtMSBpcyBhbiBFbnRpdHlNYW5hZ2VyIGNvbnRhaW5pbmcgYSBudW1iZXIgb2YgZXhpc3RpbmcgZW50aXRpZXMuXHJcbiAgPiAgICAgIGxldCBjdXN0VHlwZSA9IGVtMS5tZXRhZGF0YVN0b3JlLmdldEVudGl0eVR5cGUoXCJDdXN0b21lclwiKTtcclxuICA+ICAgICAgbGV0IGNvdW50cnlQcm9wID0gY3VzdFR5cGUuZ2V0UHJvcGVydHkoXCJDb3VudHJ5XCIpO1xyXG4gID4gICAgICBsZXQgdmFsRm4gPSBmdW5jdGlvbiAodikge1xyXG4gID4gICAgICAgICAgICAgIGlmICh2ID09IG51bGwpIHJldHVybiB0cnVlO1xyXG4gID4gICAgICAgICAgICAgIHJldHVybiAoY29yZS5zdHJpbmdTdGFydHNXaXRoKHYsIFwiVVNcIikpO1xyXG4gID4gICAgICAgICAgfTtcclxuICA+ICAgICAgbGV0IGNvdW50cnlWYWxpZGF0b3IgPSBuZXcgVmFsaWRhdG9yKFwiY291bnRyeUlzVVNcIiwgdmFsRm4sXHJcbiAgPiAgICAgIHsgZGlzcGxheU5hbWU6IFwiQ291bnRyeVwiLCBtZXNzYWdlVGVtcGxhdGU6IFwiJyVkaXNwbGF5TmFtZSUnIG11c3Qgc3RhcnQgd2l0aCAnVVMnXCIgfSk7XHJcbiAgPiAgICAgIGN1c3RUeXBlLmFkZFZhbGlkYXRvcihjb3VudHJ5VmFsaWRhdG9yLCBjb3VudHJ5UHJvcCk7XHJcblxyXG4gIFRoaXMgaXMgdGhlIHNhbWUgYXMgYWRkaW5nIGFuIGVudGl0eSBsZXZlbCB2YWxpZGF0b3IgdmlhIHRoZSAndmFsaWRhdG9ycycgcHJvcGVydHkgb2YgRGF0YVByb3BlcnR5IG9yIE5hdmlnYXRpb25Qcm9wZXJ0eVxyXG4gID4gICAgICBjb3VudHJ5UHJvcC52YWxpZGF0b3JzLnB1c2goY291bnRyeVZhbGlkYXRvcik7XHJcblxyXG4gIEVudGl0eSBsZXZlbCB2YWxpZGF0b3JzIGNhbiBhbHNvIGJlIGFkZGVkIGJ5IG9taXR0aW5nIHRoZSAncHJvcGVydHknIHBhcmFtZXRlci5cclxuICA+ICAgICAgY3VzdFR5cGUuYWRkVmFsaWRhdG9yKHNvbWVFbnRpdHlMZXZlbFZhbGlkYXRvcik7XHJcblxyXG4gIG9yXHJcbiAgPiAgICAgIGN1c3RUeXBlLnZhbGlkYXRvcnMucHVzaChzb21lRW50aXR5TGV2ZWxWYWxpZGF0b3IpO1xyXG4gIEBwYXJhbSB2YWxpZGF0b3IgLSBWYWxpZGF0b3IgdG8gYWRkLlxyXG4gIEBwYXJhbSBwcm9wZXJ0eSAtIFByb3BlcnR5IHRvIGFkZCB0aGlzIHZhbGlkYXRvciB0by4gIElmIG9taXR0ZWQsIHRoZSB2YWxpZGF0b3IgaXMgYXNzdW1lZCB0byBiZSBhblxyXG4gIGVudGl0eSBsZXZlbCB2YWxpZGF0b3IgYW5kIGlzIGFkZGVkIHRvIHRoZSBFbnRpdHlUeXBlJ3MgJ3ZhbGlkYXRvcnMnLlxyXG4gICoqL1xyXG4gIGFkZFZhbGlkYXRvcih2YWxpZGF0b3I6IFZhbGlkYXRvciwgcHJvcGVydHk/OiBFbnRpdHlQcm9wZXJ0eSB8IHN0cmluZykge1xyXG4gICAgYXNzZXJ0UGFyYW0odmFsaWRhdG9yLCBcInZhbGlkYXRvclwiKS5pc0luc3RhbmNlT2YoVmFsaWRhdG9yKS5jaGVjaygpO1xyXG4gICAgYXNzZXJ0UGFyYW0ocHJvcGVydHksIFwicHJvcGVydHlcIikuaXNPcHRpb25hbCgpLmlzU3RyaW5nKCkub3IoKS5pc0VudGl0eVByb3BlcnR5KCkuY2hlY2soKTtcclxuICAgIGlmIChwcm9wZXJ0eSAhPSBudWxsKSB7XHJcbiAgICAgIGxldCBwcm9wID0gKHR5cGVvZiBwcm9wZXJ0eSA9PT0gJ3N0cmluZycpID8gdGhpcy5nZXRQcm9wZXJ0eShwcm9wZXJ0eSwgdHJ1ZSkgOiBwcm9wZXJ0eTtcclxuICAgICAgcHJvcCEudmFsaWRhdG9ycy5wdXNoKHZhbGlkYXRvcik7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnZhbGlkYXRvcnMucHVzaCh2YWxpZGF0b3IpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhbGwgb2YgdGhlIHByb3BlcnRpZXMgKCBkYXRhUHJvcGVydGllcyBhbmQgbmF2aWdhdGlvblByb3BlcnRpZXMpIGZvciB0aGlzIEVudGl0eVR5cGUuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBlbTEgaXMgYW4gRW50aXR5TWFuYWdlciBjb250YWluaW5nIGEgbnVtYmVyIG9mIGV4aXN0aW5nIGVudGl0aWVzLlxyXG4gID4gICAgICBsZXQgY3VzdFR5cGUgPSBlbTEubWV0YWRhdGFTdG9yZS5nZXRFbnRpdHlUeXBlKFwiQ3VzdG9tZXJcIik7XHJcbiAgPiAgICAgIGxldCBhcnJheU9mUHJvcHMgPSBjdXN0VHlwZS5nZXRQcm9wZXJ0aWVzKCk7XHJcbiAgQHJldHVybiBBbiBhcnJheSBvZiBEYXRhIGFuZCBOYXZpZ2F0aW9uIHByb3BlcnRpZXMuXHJcbiAgKiovXHJcbiAgZ2V0UHJvcGVydGllcygpOiBFbnRpdHlQcm9wZXJ0eVtdIHtcclxuICAgIHJldHVybiAodGhpcy5kYXRhUHJvcGVydGllcyBhcyBFbnRpdHlQcm9wZXJ0eVtdKS5jb25jYXQodGhpcy5uYXZpZ2F0aW9uUHJvcGVydGllcyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIGFsbCBvZiB0aGUgcHJvcGVydHkgbmFtZXMgKCBmb3IgYm90aCBkYXRhUHJvcGVydGllcyBhbmQgbmF2aWdhdGlvblByb3BlcnRpZXMpIGZvciB0aGlzIEVudGl0eVR5cGUuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBlbTEgaXMgYW4gRW50aXR5TWFuYWdlciBjb250YWluaW5nIGEgbnVtYmVyIG9mIGV4aXN0aW5nIGVudGl0aWVzLlxyXG4gID4gICAgICBsZXQgY3VzdFR5cGUgPSBlbTEubWV0YWRhdGFTdG9yZS5nZXRFbnRpdHlUeXBlKFwiQ3VzdG9tZXJcIik7XHJcbiAgPiAgICAgIGxldCBhcnJheU9mUHJvcE5hbWVzID0gY3VzdFR5cGUuZ2V0UHJvcGVydHlOYW1lcygpO1xyXG4gICoqL1xyXG4gIGdldFByb3BlcnR5TmFtZXMoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5nZXRQcm9wZXJ0aWVzKCkubWFwKGNvcmUucGx1Y2soJ25hbWUnKSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIGEgZGF0YSBwcm9wZXJ0eSB3aXRoIHRoZSBzcGVjaWZpZWQgbmFtZSBvciBudWxsLlxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGFuIEVudGl0eU1hbmFnZXIgY29udGFpbmluZyBhIG51bWJlciBvZiBleGlzdGluZyBlbnRpdGllcy5cclxuICA+ICAgICAgbGV0IGN1c3RUeXBlID0gZW0xLm1ldGFkYXRhU3RvcmUuZ2V0RW50aXR5VHlwZShcIkN1c3RvbWVyXCIpO1xyXG4gID4gICAgICBsZXQgY3VzdG9tZXJOYW1lRGF0YVByb3AgPSBjdXN0VHlwZS5nZXREYXRhUHJvcGVydHkoXCJDdXN0b21lck5hbWVcIik7XHJcbiAgQHJldHVybiBBIERhdGFQcm9wZXJ0eSBvciBudWxsIGlmIG5vdCBmb3VuZC5cclxuICAqKi9cclxuICBnZXREYXRhUHJvcGVydHkocHJvcGVydHlOYW1lOiBzdHJpbmcpIHtcclxuICAgIHJldHVybiBjb3JlLmFycmF5Rmlyc3QodGhpcy5kYXRhUHJvcGVydGllcywgY29yZS5wcm9wRXEoJ25hbWUnLCBwcm9wZXJ0eU5hbWUpKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgYSBuYXZpZ2F0aW9uIHByb3BlcnR5IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIG9yIG51bGwuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBlbTEgaXMgYW4gRW50aXR5TWFuYWdlciBjb250YWluaW5nIGEgbnVtYmVyIG9mIGV4aXN0aW5nIGVudGl0aWVzLlxyXG4gID4gICAgICBsZXQgY3VzdFR5cGUgPSBlbTEubWV0YWRhdGFTdG9yZS5nZXRFbnRpdHlUeXBlKFwiQ3VzdG9tZXJcIik7XHJcbiAgPiAgICAgIGxldCBjdXN0b21lck9yZGVyc05hdlByb3AgPSBjdXN0VHlwZS5nZXREYXRhUHJvcGVydHkoXCJPcmRlcnNcIik7XHJcbiAgQHJldHVybiBBIE5hdmlnYXRpb25Qcm9wZXJ0eSBvciBudWxsIGlmIG5vdCBmb3VuZC5cclxuICAqKi9cclxuICBnZXROYXZpZ2F0aW9uUHJvcGVydHkocHJvcGVydHlOYW1lOiBzdHJpbmcpIHtcclxuICAgIHJldHVybiBjb3JlLmFycmF5Rmlyc3QodGhpcy5uYXZpZ2F0aW9uUHJvcGVydGllcywgY29yZS5wcm9wRXEoJ25hbWUnLCBwcm9wZXJ0eU5hbWUpKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgZWl0aGVyIGEgRGF0YVByb3BlcnR5IG9yIGEgTmF2aWdhdGlvblByb3BlcnR5IHdpdGggdGhlIHNwZWNpZmllZCBuYW1lIG9yIG51bGwuXHJcbiAgXHJcbiAgVGhpcyBtZXRob2QgYWxzbyBhY2NlcHRzIGEgJy4nIGRlbGltaXRlZCBwcm9wZXJ0eSBwYXRoIGFuZCB3aWxsIHJldHVybiB0aGUgJ3Byb3BlcnR5JyBhdCB0aGVcclxuICBlbmQgb2YgdGhlIHBhdGguXHJcbiAgPiAgICAgIGxldCBjdXN0VHlwZSA9IGVtMS5tZXRhZGF0YVN0b3JlLmdldEVudGl0eVR5cGUoXCJDdXN0b21lclwiKTtcclxuICA+ICAgICAgbGV0IGNvbXBhbnlOYW1lUHJvcCA9IGN1c3RUeXBlLmdldFByb3BlcnR5KFwiQ29tcGFueU5hbWVcIik7XHJcblxyXG4gIFRoaXMgbWV0aG9kIGNhbiBhbHNvIHdhbGsgYSBwcm9wZXJ0eSBwYXRoIHRvIHJldHVybiBhIHByb3BlcnR5XHJcbiAgPiAgICAgIGxldCBvcmRlckRldGFpbFR5cGUgPSBlbTEubWV0YWRhdGFTdG9yZS5nZXRFbnRpdHlUeXBlKFwiT3JkZXJEZXRhaWxcIik7XHJcbiAgPiAgICAgIGxldCBjb21wYW55TmFtZVByb3AyID0gb3JkZXJEZXRhaWxUeXBlLmdldFByb3BlcnR5KFwiT3JkZXIuQ3VzdG9tZXIuQ29tcGFueU5hbWVcIik7XHJcbiAgPiAgICAgIC8vIGNvbXBhbnlOYW1lUHJvcCA9PT0gY29tcGFueU5hbWVQcm9wMlxyXG4gIEBwYXJhbSBbdGhyb3dJZk5vdEZvdW5kPWZhbHNlXSB7Qm9vbGVhbn0gV2hldGhlciB0byB0aHJvdyBhbiBleGNlcHRpb24gaWYgbm90IGZvdW5kLlxyXG4gIEByZXR1cm4gQSBEYXRhUHJvcGVydHkgb3IgTmF2aWdhdGlvblByb3BlcnR5IG9yIG51bGwgaWYgbm90IGZvdW5kLlxyXG4gICoqL1xyXG4gIGdldFByb3BlcnR5KHByb3BlcnR5UGF0aDogc3RyaW5nLCB0aHJvd0lmTm90Rm91bmQ6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG4gICAgbGV0IHByb3BzID0gdGhpcy5nZXRQcm9wZXJ0aWVzT25QYXRoKHByb3BlcnR5UGF0aCwgZmFsc2UsIHRocm93SWZOb3RGb3VuZCk7XHJcbiAgICByZXR1cm4gKHByb3BzICYmIHByb3BzLmxlbmd0aCA+IDApID8gcHJvcHNbcHJvcHMubGVuZ3RoIC0gMV0gOiBudWxsO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgLy8gVE9ETzogaGF2ZSB0aGlzIHJldHVybiBlbXB0eSBhcnJheSBpbnN0ZWFkIG9mIG51bGwgYW5kIGZpeCBjb25zdW1lcnMuXHJcbiAgLy8gVE9ETzogdGhpbmsgYWJvdXQgcmVuYW1pbmcgd2l0aCAnXycgcHJlZml4LlxyXG4gIGdldFByb3BlcnRpZXNPblBhdGgocHJvcGVydHlQYXRoOiBzdHJpbmcsIHVzZVNlcnZlck5hbWU6IGJvb2xlYW4gfCBudWxsLCB0aHJvd0lmTm90Rm91bmQ6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG4gICAgbGV0IHByb3BlcnR5TmFtZXM6IHN0cmluZ1tdID0gKEFycmF5LmlzQXJyYXkocHJvcGVydHlQYXRoKSkgPyBwcm9wZXJ0eVBhdGggOiBwcm9wZXJ0eVBhdGgudHJpbSgpLnNwbGl0KCcuJyk7XHJcblxyXG4gICAgbGV0IG9rID0gdHJ1ZTtcclxuICAgIGxldCBrZXkgPSB1c2VTZXJ2ZXJOYW1lID09PSB0cnVlID8gXCJuYW1lT25TZXJ2ZXJcIiA6IHVzZVNlcnZlck5hbWUgPT09IGZhbHNlID8gXCJuYW1lXCIgOiBudWxsO1xyXG4gICAgbGV0IHBhcmVudFR5cGUgPSB0aGlzIGFzIFN0cnVjdHVyYWxUeXBlO1xyXG4gICAgXHJcbiAgICBjb25zdCBnZXRQcm9wcyA9IChwcm9wTmFtZTogc3RyaW5nKSA9PiB7IFxyXG4gICAgICBjb25zdCBmbiA9IGtleSA9PT0gbnVsbCA/IGNvcmUucHJvcHNFcShcIm5hbWVcIiwgXCJuYW1lT25TZXJ2ZXJcIiwgcHJvcE5hbWUpIDogY29yZS5wcm9wRXEoa2V5LCBwcm9wTmFtZSk7XHJcbiAgICAgIGxldCBwcm9wID0gY29yZS5hcnJheUZpcnN0KHBhcmVudFR5cGUuZ2V0UHJvcGVydGllcygpLCBmbik7XHJcbiAgICAgIGlmIChwcm9wKSB7XHJcbiAgICAgICAgcGFyZW50VHlwZSA9IChwcm9wIGluc3RhbmNlb2YgTmF2aWdhdGlvblByb3BlcnR5KSA/IHByb3AuZW50aXR5VHlwZSA6IHByb3AuZGF0YVR5cGUgYXMgQ29tcGxleFR5cGU7XHJcbiAgICAgICAgLy8gcGFyZW50VHlwZSA9IHByb3AuaXNOYXZpZ2F0aW9uUHJvcGVydHkgPyBwcm9wLmVudGl0eVR5cGUgOiBwcm9wLmRhdGFUeXBlO1xyXG4gICAgICB9IGVsc2UgaWYgKHRocm93SWZOb3RGb3VuZCkge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcInVuYWJsZSB0byBsb2NhdGUgcHJvcGVydHk6IFwiICsgcHJvcE5hbWUgKyBcIiBvbiBlbnRpdHlUeXBlOiBcIiArIHBhcmVudFR5cGUubmFtZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgb2sgPSBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gcHJvcDtcclxuICAgIH07XHJcblxyXG4gICAgbGV0IHByb3BzID0gcHJvcGVydHlOYW1lcy5tYXAoZ2V0UHJvcHMpIGFzIEVudGl0eVByb3BlcnR5W107XHJcbiAgICByZXR1cm4gb2sgPyBwcm9wcyA6IG51bGw7XHJcbiAgfVxyXG5cclxuICAvKiogRm9yIHVzZSBpbiBwbHVnZ2FibGUgYWRhcHRlcnMuICovXHJcbiAgLy8gVE9ETzogZG9jdW1lbnQgdXNlXHJcbiAgY2xpZW50UHJvcGVydHlQYXRoVG9TZXJ2ZXIocHJvcGVydHlQYXRoOiBzdHJpbmcsIGRlbGltaXRlcjogc3RyaW5nID0gJy4nKSB7XHJcbiAgICBsZXQgcHJvcE5hbWVzOiBzdHJpbmdbXTtcclxuICAgIGlmICh0aGlzLmlzQW5vbnltb3VzKSB7XHJcbiAgICAgIGxldCBmbiA9IHRoaXMubWV0YWRhdGFTdG9yZS5uYW1pbmdDb252ZW50aW9uLmNsaWVudFByb3BlcnR5TmFtZVRvU2VydmVyO1xyXG4gICAgICBwcm9wTmFtZXMgPSBwcm9wZXJ0eVBhdGguc3BsaXQoXCIuXCIpLm1hcChmdW5jdGlvbiAocHJvcE5hbWUpIHtcclxuICAgICAgICByZXR1cm4gZm4ocHJvcE5hbWUpO1xyXG4gICAgICB9KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGxldCBwcm9wcyA9IHRoaXMuZ2V0UHJvcGVydGllc09uUGF0aChwcm9wZXJ0eVBhdGgsIGZhbHNlLCB0cnVlKTtcclxuICAgICAgcHJvcE5hbWVzID0gcHJvcHMhLm1hcCgocHJvcDogRW50aXR5UHJvcGVydHkpID0+IHByb3AubmFtZU9uU2VydmVyKTtcclxuICAgIH1cclxuICAgIHJldHVybiBwcm9wTmFtZXMuam9pbihkZWxpbWl0ZXIpO1xyXG4gIH1cclxuXHJcbiAgLyoqIEZvciB1c2UgaW4gcGx1Z2dhYmxlIGFkYXB0ZXJzLiAqL1xyXG4gIC8vIFRPRE86IGRvY3VtZW50IHVzZVxyXG4gIGdldEVudGl0eUtleUZyb21SYXdFbnRpdHkocmF3RW50aXR5OiBhbnksIHJhd1ZhbHVlRm46IEZ1bmN0aW9uKSB7XHJcbiAgICBsZXQga2V5VmFsdWVzID0gdGhpcy5rZXlQcm9wZXJ0aWVzLm1hcCgoZHApID0+IHtcclxuICAgICAgbGV0IHZhbCA9IHJhd1ZhbHVlRm4ocmF3RW50aXR5LCBkcCk7XHJcbiAgICAgIHJldHVybiBEYXRhVHlwZS5wYXJzZVJhd1ZhbHVlKHZhbCwgZHAuZGF0YVR5cGUgYXMgRGF0YVR5cGUpO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gbmV3IEVudGl0eUtleSh0aGlzLCBrZXlWYWx1ZXMpO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3VwZGF0ZVRhcmdldEZyb21SYXcodGFyZ2V0OiBTdHJ1Y3R1cmFsT2JqZWN0LCByYXc6IGFueSwgcmF3VmFsdWVGbjogRnVuY3Rpb24pIHtcclxuICAgIC8vIGNhbGxlZCByZWN1cnNpdmVseSBmb3IgY29tcGxleCBwcm9wZXJ0aWVzXHJcbiAgICB0aGlzLmRhdGFQcm9wZXJ0aWVzLmZvckVhY2goKGRwKSA9PiB7XHJcbiAgICAgIGlmICghZHAuaXNTZXR0YWJsZSkgcmV0dXJuO1xyXG4gICAgICBsZXQgcmF3VmFsID0gcmF3VmFsdWVGbihyYXcsIGRwKTtcclxuICAgICAgaWYgKHJhd1ZhbCA9PT0gdW5kZWZpbmVkKSByZXR1cm47XHJcbiAgICAgIGxldCBkYXRhVHlwZSA9IGRwLmRhdGFUeXBlOyAvLyB0aGlzIHdpbGwgYmUgYSBjb21wbGV4VHlwZSB3aGVuIGRwIGlzIGEgY29tcGxleFByb3BlcnR5XHJcbiAgICAgIGxldCBvbGRWYWw6IGFueTtcclxuICAgICAgaWYgKGRwLmlzQ29tcGxleFByb3BlcnR5KSB7XHJcbiAgICAgICAgbGV0IGNvbXBsZXhUeXBlID0gZHAuZGF0YVR5cGUgYXMgQ29tcGxleFR5cGU7XHJcbiAgICAgICAgaWYgKHJhd1ZhbCA9PT0gbnVsbCkgcmV0dXJuOyAvLyByYXdWYWwgbWF5IGJlIG51bGwgaW4gbm9zcWwgZGJzIHdoZXJlIGl0IHdhcyBuZXZlciBkZWZpbmVkIGZvciB0aGUgZ2l2ZW4gcm93LlxyXG4gICAgICAgIG9sZFZhbCA9IHRhcmdldC5nZXRQcm9wZXJ0eShkcC5uYW1lKTtcclxuICAgICAgICBpZiAoZHAuaXNTY2FsYXIpIHtcclxuICAgICAgICAgIGNvbXBsZXhUeXBlLl91cGRhdGVUYXJnZXRGcm9tUmF3KG9sZFZhbCwgcmF3VmFsLCByYXdWYWx1ZUZuKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmF3VmFsKSkge1xyXG4gICAgICAgICAgICBsZXQgbmV3VmFsID0gcmF3VmFsLm1hcChmdW5jdGlvbiAocmF3Q28pIHtcclxuICAgICAgICAgICAgICBsZXQgbmV3Q28gPSBjb21wbGV4VHlwZS5fY3JlYXRlSW5zdGFuY2VDb3JlKHRhcmdldCwgZHApO1xyXG4gICAgICAgICAgICAgIGNvbXBsZXhUeXBlLl91cGRhdGVUYXJnZXRGcm9tUmF3KG5ld0NvLCByYXdDbywgcmF3VmFsdWVGbik7XHJcbiAgICAgICAgICAgICAgY29tcGxleFR5cGUuX2luaXRpYWxpemVJbnN0YW5jZShuZXdDbyk7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIG5ld0NvO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgaWYgKCFjb3JlLmFycmF5RXF1YWxzKG9sZFZhbCwgbmV3VmFsLCBjb0VxdWFscykpIHtcclxuICAgICAgICAgICAgICAvLyBjbGVhciB0aGUgb2xkIGFycmF5IGFuZCBwdXNoIG5ldyBvYmplY3RzIGludG8gaXQuXHJcbiAgICAgICAgICAgICAgb2xkVmFsLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgICAgICAgbmV3VmFsLmZvckVhY2goZnVuY3Rpb24gKG52KSB7XHJcbiAgICAgICAgICAgICAgICBvbGRWYWwucHVzaChudik7XHJcbiAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIG9sZFZhbC5sZW5ndGggPSAwO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAoZHAuaXNTY2FsYXIpIHtcclxuICAgICAgICAgIGxldCBuZXdWYWwgPSBEYXRhVHlwZS5wYXJzZVJhd1ZhbHVlKHJhd1ZhbCwgZGF0YVR5cGUgYXMgRGF0YVR5cGUpO1xyXG4gICAgICAgICAgdGFyZ2V0LnNldFByb3BlcnR5KGRwLm5hbWUsIG5ld1ZhbCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIG9sZFZhbCA9IHRhcmdldC5nZXRQcm9wZXJ0eShkcC5uYW1lKTtcclxuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJhd1ZhbCkpIHtcclxuICAgICAgICAgICAgLy8gbmVlZCB0byBjb21wYXJlIHZhbHVlc1xyXG4gICAgICAgICAgICBsZXQgbmV3VmFsID0gcmF3VmFsLm1hcCgocnYpID0+IHtcclxuICAgICAgICAgICAgICByZXR1cm4gRGF0YVR5cGUucGFyc2VSYXdWYWx1ZShydiwgZGF0YVR5cGUgYXMgRGF0YVR5cGUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgaWYgKCFjb3JlLmFycmF5RXF1YWxzKG9sZFZhbCwgbmV3VmFsKSkge1xyXG4gICAgICAgICAgICAgIC8vIGNsZWFyIHRoZSBvbGQgYXJyYXkgYW5kIHB1c2ggbmV3IG9iamVjdHMgaW50byBpdC5cclxuICAgICAgICAgICAgICBvbGRWYWwubGVuZ3RoID0gMDtcclxuICAgICAgICAgICAgICBuZXdWYWwuZm9yRWFjaChmdW5jdGlvbiAobnYpIHtcclxuICAgICAgICAgICAgICAgIG9sZFZhbC5wdXNoKG52KTtcclxuICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgb2xkVmFsLmxlbmd0aCA9IDA7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gaWYgbWVyZ2luZyBmcm9tIGFuIGltcG9ydCB0aGVuIHJhdyB3aWxsIGhhdmUgYW4gZW50aXR5QXNwZWN0IG9yIGEgY29tcGxleEFzcGVjdFxyXG4gICAgbGV0IHJhd0FzcGVjdCA9IHJhdy5lbnRpdHlBc3BlY3QgfHwgcmF3LmNvbXBsZXhBc3BlY3Q7XHJcbiAgICBpZiAocmF3QXNwZWN0KSB7XHJcblxyXG4gICAgICBsZXQgdGFyZ2V0QXNwZWN0ID0gRW50aXR5QXNwZWN0LmlzRW50aXR5KHRhcmdldCkgPyB0YXJnZXQuZW50aXR5QXNwZWN0IDogdGFyZ2V0LmNvbXBsZXhBc3BlY3Q7XHJcbiAgICAgIGlmIChyYXdBc3BlY3Qub3JpZ2luYWxWYWx1ZXNNYXApIHtcclxuICAgICAgICB0YXJnZXRBc3BlY3Qub3JpZ2luYWxWYWx1ZXMgPSByYXdBc3BlY3Qub3JpZ2luYWxWYWx1ZXNNYXA7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHJhd0FzcGVjdC5leHRyYU1ldGFkYXRhKSB7XHJcbiAgICAgICAgdGFyZ2V0QXNwZWN0LmV4dHJhTWV0YWRhdGEgPSByYXdBc3BlY3QuZXh0cmFNZXRhZGF0YTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcblxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoaXMgRW50aXR5VHlwZS5cclxuICAqKi9cclxuICB0b1N0cmluZygpIHtcclxuICAgIHJldHVybiB0aGlzLm5hbWU7XHJcbiAgfVxyXG5cclxuICB0b0pTT04oKSB7XHJcbiAgICByZXR1cm4gY29yZS50b0pzb24odGhpcywge1xyXG4gICAgICBzaG9ydE5hbWU6IG51bGwsXHJcbiAgICAgIG5hbWVzcGFjZTogbnVsbCxcclxuICAgICAgYmFzZVR5cGVOYW1lOiBudWxsLFxyXG4gICAgICBpc0Fic3RyYWN0OiBmYWxzZSxcclxuICAgICAgYXV0b0dlbmVyYXRlZEtleVR5cGU6IG51bGwsIC8vIGRvIG5vdCBzdXBwcmVzcyBkZWZhdWx0IHZhbHVlXHJcbiAgICAgIGRlZmF1bHRSZXNvdXJjZU5hbWU6IG51bGwsXHJcbiAgICAgIGRhdGFQcm9wZXJ0aWVzOiBsb2NhbFByb3BzT25seSxcclxuICAgICAgbmF2aWdhdGlvblByb3BlcnRpZXM6IGxvY2FsUHJvcHNPbmx5LFxyXG4gICAgICB2YWxpZGF0b3JzOiBudWxsLFxyXG4gICAgICBjdXN0b206IG51bGxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3VwZGF0ZU5hbWVzKHByb3BlcnR5OiBFbnRpdHlQcm9wZXJ0eSkge1xyXG4gICAgbGV0IG5jID0gdGhpcy5tZXRhZGF0YVN0b3JlLm5hbWluZ0NvbnZlbnRpb247XHJcbiAgICB1cGRhdGVDbGllbnRTZXJ2ZXJOYW1lcyhuYywgcHJvcGVydHksIFwibmFtZVwiKTtcclxuXHJcbiAgICBpZiAocHJvcGVydHkuaXNOYXZpZ2F0aW9uUHJvcGVydHkpIHtcclxuICAgICAgdXBkYXRlQ2xpZW50U2VydmVyTmFtZXMobmMsIHByb3BlcnR5LCBcImZvcmVpZ25LZXlOYW1lc1wiKTtcclxuICAgICAgdXBkYXRlQ2xpZW50U2VydmVyTmFtZXMobmMsIHByb3BlcnR5LCBcImludkZvcmVpZ25LZXlOYW1lc1wiKTtcclxuXHJcbiAgICAgIC8vIHRoZXNlIHdpbGwgZ2V0IHNldCBsYXRlciB2aWEgX3VwZGF0ZU5wc1xyXG4gICAgICAvLyB0aGlzLmludmVyc2VcclxuICAgICAgLy8gdGhpcy5lbnRpdHlUeXBlXHJcbiAgICAgIC8vIHRoaXMucmVsYXRlZERhdGFQcm9wZXJ0aWVzXHJcbiAgICAgIC8vICAgIGRhdGFQcm9wZXJ0eS5yZWxhdGVkTmF2aWdhdGlvblByb3BlcnR5XHJcbiAgICAgIC8vICAgIGRhdGFQcm9wZXJ0eS5pbnZlcnNlTmF2aWdhdGlvblByb3BlcnR5XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfY2hlY2tOYXZQcm9wZXJ0eShuYXZpZ2F0aW9uUHJvcGVydHk6IE5hdmlnYXRpb25Qcm9wZXJ0eSB8IHN0cmluZykge1xyXG4gICAgLy8gaWYgKG5hdmlnYXRpb25Qcm9wZXJ0eS5pc05hdmlnYXRpb25Qcm9wZXJ0eSkge1xyXG4gICAgaWYgKG5hdmlnYXRpb25Qcm9wZXJ0eSBpbnN0YW5jZW9mIE5hdmlnYXRpb25Qcm9wZXJ0eSkge1xyXG4gICAgICBpZiAobmF2aWdhdGlvblByb3BlcnR5LnBhcmVudFR5cGUgIT09IHRoaXMpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoY29yZS5mb3JtYXRTdHJpbmcoXCJUaGUgbmF2aWdhdGlvblByb3BlcnR5ICclMScgaXMgbm90IGEgcHJvcGVydHkgb2YgZW50aXR5IHR5cGUgJyUyJ1wiLFxyXG4gICAgICAgICAgbmF2aWdhdGlvblByb3BlcnR5Lm5hbWUsIHRoaXMubmFtZSkpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBuYXZpZ2F0aW9uUHJvcGVydHk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGVvZiAobmF2aWdhdGlvblByb3BlcnR5KSA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgbGV0IG5wID0gdGhpcy5nZXRQcm9wZXJ0eShuYXZpZ2F0aW9uUHJvcGVydHkpO1xyXG4gICAgICAvLyBpZiAobnAgJiYgbnAuaXNOYXZpZ2F0aW9uUHJvcGVydHkpIHJldHVybiBucDtcclxuICAgICAgaWYgKG5wICYmIG5wIGluc3RhbmNlb2YgTmF2aWdhdGlvblByb3BlcnR5KSByZXR1cm4gbnA7XHJcbiAgICB9XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgJ25hdmlnYXRpb25Qcm9wZXJ0eScgcGFyYW1ldGVyIG11c3QgZWl0aGVyIGJlIGEgTmF2aWdhdGlvblByb3BlcnR5IG9yIHRoZSBuYW1lIG9mIGEgTmF2aWdhdGlvblByb3BlcnR5XCIpO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2FkZERhdGFQcm9wZXJ0eShkcDogRGF0YVByb3BlcnR5KSB7XHJcblxyXG4gICAgdGhpcy5kYXRhUHJvcGVydGllcy5wdXNoKGRwKTtcclxuXHJcbiAgICBpZiAoZHAuaXNQYXJ0T2ZLZXkpIHtcclxuICAgICAgdGhpcy5rZXlQcm9wZXJ0aWVzLnB1c2goZHApO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChkcC5pc0NvbXBsZXhQcm9wZXJ0eSkge1xyXG4gICAgICB0aGlzLmNvbXBsZXhQcm9wZXJ0aWVzLnB1c2goZHApO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChkcC5jb25jdXJyZW5jeU1vZGUgJiYgZHAuY29uY3VycmVuY3lNb2RlICE9PSBcIk5vbmVcIikge1xyXG4gICAgICB0aGlzLmNvbmN1cnJlbmN5UHJvcGVydGllcy5wdXNoKGRwKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZHAuaXNVbm1hcHBlZCkge1xyXG4gICAgICB0aGlzLnVubWFwcGVkUHJvcGVydGllcy5wdXNoKGRwKTtcclxuICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfYWRkTmF2aWdhdGlvblByb3BlcnR5KG5wOiBOYXZpZ2F0aW9uUHJvcGVydHkpIHtcclxuXHJcbiAgICB0aGlzLm5hdmlnYXRpb25Qcm9wZXJ0aWVzLnB1c2gobnApO1xyXG5cclxuICAgIGlmICghaXNRdWFsaWZpZWRUeXBlTmFtZShucC5lbnRpdHlUeXBlTmFtZSkpIHtcclxuICAgICAgbnAuZW50aXR5VHlwZU5hbWUgPSBxdWFsaWZ5VHlwZU5hbWUobnAuZW50aXR5VHlwZU5hbWUsIHRoaXMubmFtZXNwYWNlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF91cGRhdGVDcHMoKSB7XHJcbiAgICBsZXQgbWV0YWRhdGFTdG9yZSA9IHRoaXMubWV0YWRhdGFTdG9yZTtcclxuICAgIGxldCBpbmNvbXBsZXRlVHlwZU1hcCA9IG1ldGFkYXRhU3RvcmUuX2luY29tcGxldGVDb21wbGV4VHlwZU1hcDtcclxuICAgIHRoaXMuY29tcGxleFByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbiAoY3ApIHtcclxuICAgICAgaWYgKGNwLmNvbXBsZXhUeXBlKSByZXR1cm47XHJcbiAgICAgIGlmICghcmVzb2x2ZUNwKGNwLCBtZXRhZGF0YVN0b3JlKSkge1xyXG4gICAgICAgIGNvcmUuZ2V0QXJyYXkoaW5jb21wbGV0ZVR5cGVNYXAsIGNwLmNvbXBsZXhUeXBlTmFtZSkucHVzaChjcCk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIGlmICh0aGlzLmlzQ29tcGxleFR5cGUpIHtcclxuICAgICAgKGluY29tcGxldGVUeXBlTWFwW3RoaXMubmFtZV0gfHwgW10pLmZvckVhY2goZnVuY3Rpb24gKGNwOiBEYXRhUHJvcGVydHkpIHtcclxuICAgICAgICByZXNvbHZlQ3AoY3AsIG1ldGFkYXRhU3RvcmUpO1xyXG4gICAgICB9KTtcclxuICAgICAgZGVsZXRlIGluY29tcGxldGVUeXBlTWFwW3RoaXMubmFtZV07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfdXBkYXRlTnBzKCkge1xyXG4gICAgbGV0IG1ldGFkYXRhU3RvcmUgPSB0aGlzLm1ldGFkYXRhU3RvcmU7XHJcblxyXG4gICAgLy8gcmVzb2x2ZSBhbGwgbmF2UHJvcHMgZm9yIHRoaXMgZW50aXR5VHlwZVxyXG4gICAgdGhpcy5uYXZpZ2F0aW9uUHJvcGVydGllcy5mb3JFYWNoKGZ1bmN0aW9uIChucCkge1xyXG4gICAgICB0cnlSZXNvbHZlTnAobnAsIG1ldGFkYXRhU3RvcmUpO1xyXG4gICAgfSk7XHJcbiAgICBsZXQgaW5jb21wbGV0ZVR5cGVNYXAgPSBtZXRhZGF0YVN0b3JlLl9pbmNvbXBsZXRlVHlwZU1hcDtcclxuICAgIC8vIG5leHQgcmVzb2x2ZSBhbGwgbmF2UHJvcCB0aGF0IHBvaW50IHRvIHRoaXMgZW50aXR5VHlwZS5cclxuICAgIChpbmNvbXBsZXRlVHlwZU1hcFt0aGlzLm5hbWVdIHx8IFtdKS5mb3JFYWNoKGZ1bmN0aW9uIChucDogTmF2aWdhdGlvblByb3BlcnR5KSB7XHJcbiAgICAgIHRyeVJlc29sdmVOcChucCwgbWV0YWRhdGFTdG9yZSk7XHJcbiAgICB9KTtcclxuICAgIC8vIGV2ZXJ5IG5hdlByb3AgdGhhdCBwb2ludGVkIHRvIHRoaXMgdHlwZSBzaG91bGQgbm93IGJlIHJlc29sdmVkXHJcbiAgICBkZWxldGUgaW5jb21wbGV0ZVR5cGVNYXBbdGhpcy5uYW1lXTtcclxuICB9XHJcbn1cclxuXHJcbkVudGl0eVR5cGUucHJvdG90eXBlLl8kdHlwZU5hbWUgPSBcIkVudGl0eVR5cGVcIjtcclxuXHJcbmZ1bmN0aW9uIGdldFJhd1ZhbHVlRnJvbUNvbmZpZyhyYXdFbnRpdHk6IGFueSwgZHA6IERhdGFQcm9wZXJ0eSkge1xyXG4gIC8vICd0cnVlJyBmb3JrIGNhbiBoYXBwZW4gaWYgYW4gaW5pdGlhbGl6ZXIgY29udGFpbnMgYW4gYWN0YXVsIGluc3RhbmNlIG9mIGFuIGFscmVhZHkgY3JlYXRlZCBjb21wbGV4IG9iamVjdC5cclxuICByZXR1cm4gKHJhd0VudGl0eS5lbnRpdHlBc3BlY3QgfHwgcmF3RW50aXR5LmNvbXBsZXhBc3BlY3QpID8gcmF3RW50aXR5LmdldFByb3BlcnR5KGRwLm5hbWUpIDogcmF3RW50aXR5W2RwLm5hbWVdO1xyXG59XHJcblxyXG5mdW5jdGlvbiB1cGRhdGVDbGllbnRTZXJ2ZXJOYW1lcyhuYzogTmFtaW5nQ29udmVudGlvbiwgcGFyZW50OiBhbnksIGNsaWVudFByb3BOYW1lOiBzdHJpbmcpIHtcclxuICBsZXQgc2VydmVyUHJvcE5hbWUgPSBjbGllbnRQcm9wTmFtZSArIFwiT25TZXJ2ZXJcIjtcclxuICBsZXQgY2xpZW50TmFtZSA9IHBhcmVudFtjbGllbnRQcm9wTmFtZV07XHJcbiAgaWYgKGNsaWVudE5hbWUgJiYgY2xpZW50TmFtZS5sZW5ndGgpIHtcclxuICAgIC8vIGlmIChwYXJlbnQuaXNVbm1hcHBlZCkgcmV0dXJuO1xyXG4gICAgbGV0IHNlcnZlck5hbWVzID0gY29yZS50b0FycmF5KGNsaWVudE5hbWUpLm1hcChmdW5jdGlvbiAoY05hbWUpIHtcclxuICAgICAgbGV0IHNOYW1lID0gbmMuY2xpZW50UHJvcGVydHlOYW1lVG9TZXJ2ZXIoY05hbWUsIHBhcmVudCk7XHJcbiAgICAgIGxldCB0ZXN0TmFtZSA9IG5jLnNlcnZlclByb3BlcnR5TmFtZVRvQ2xpZW50KHNOYW1lLCBwYXJlbnQpO1xyXG4gICAgICBpZiAoY05hbWUgIT09IHRlc3ROYW1lKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTmFtaW5nQ29udmVudGlvbiBmb3IgdGhpcyBjbGllbnQgcHJvcGVydHkgbmFtZSBkb2VzIG5vdCByb3VuZHRyaXAgcHJvcGVybHk6XCIgKyBjTmFtZSArIFwiLS0+XCIgKyB0ZXN0TmFtZSk7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIHNOYW1lO1xyXG4gICAgfSk7XHJcbiAgICBwYXJlbnRbc2VydmVyUHJvcE5hbWVdID0gQXJyYXkuaXNBcnJheShjbGllbnROYW1lKSA/IHNlcnZlck5hbWVzIDogc2VydmVyTmFtZXNbMF07XHJcbiAgfSBlbHNlIHtcclxuICAgIGxldCBzZXJ2ZXJOYW1lID0gcGFyZW50W3NlcnZlclByb3BOYW1lXTtcclxuICAgIGlmICgoIXNlcnZlck5hbWUpIHx8IHNlcnZlck5hbWUubGVuZ3RoID09PSAwKSByZXR1cm47XHJcbiAgICBsZXQgY2xpZW50TmFtZXMgPSBjb3JlLnRvQXJyYXkoc2VydmVyTmFtZSkubWFwKGZ1bmN0aW9uIChzTmFtZSkge1xyXG4gICAgICBsZXQgY05hbWUgPSBuYy5zZXJ2ZXJQcm9wZXJ0eU5hbWVUb0NsaWVudChzTmFtZSwgcGFyZW50KTtcclxuICAgICAgbGV0IHRlc3ROYW1lID0gbmMuY2xpZW50UHJvcGVydHlOYW1lVG9TZXJ2ZXIoY05hbWUsIHBhcmVudCk7XHJcbiAgICAgIGlmIChzTmFtZSAhPT0gdGVzdE5hbWUpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJOYW1pbmdDb252ZW50aW9uIGZvciB0aGlzIHNlcnZlciBwcm9wZXJ0eSBuYW1lIGRvZXMgbm90IHJvdW5kdHJpcCBwcm9wZXJseTpcIiArIHNOYW1lICsgXCItLT5cIiArIHRlc3ROYW1lKTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gY05hbWU7XHJcbiAgICB9KTtcclxuICAgIHBhcmVudFtjbGllbnRQcm9wTmFtZV0gPSBBcnJheS5pc0FycmF5KHNlcnZlck5hbWUpID8gY2xpZW50TmFtZXMgOiBjbGllbnROYW1lc1swXTtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUVtcHR5Q3Rvcih0eXBlOiBhbnkpIHtcclxuICBpZiAoY29uZmlnLm5vRXZhbCkge1xyXG4gICAgbGV0IEVudGl0eSA9IGZ1bmN0aW9uKCkge307XHJcbiAgICByZXR1cm4gRW50aXR5O1xyXG4gIH0gZWxzZSB7XHJcbiAgICBsZXQgbmFtZSA9IHR5cGUubmFtZS5yZXBsYWNlKC9cXFcvZywgJ18nKTtcclxuICAgIHJldHVybiBGdW5jdGlvbigncmV0dXJuIGZ1bmN0aW9uICcgKyBuYW1lICsgJygpe30nKSgpO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gY29FcXVhbHMoY28xOiBDb21wbGV4T2JqZWN0LCBjbzI6IENvbXBsZXhPYmplY3QpOiBib29sZWFuIHtcclxuICBsZXQgY29tcGxleFR5cGUgPSBjbzEuY29tcGxleEFzcGVjdCEucGFyZW50UHJvcGVydHkhLmRhdGFUeXBlIGFzIENvbXBsZXhUeXBlO1xyXG4gIGxldCBkYXRhUHJvcHMgPSBjb21wbGV4VHlwZS5kYXRhUHJvcGVydGllcztcclxuICBsZXQgYXJlRXF1YWwgPSBkYXRhUHJvcHMuZXZlcnkoZnVuY3Rpb24gKGRwKSB7XHJcbiAgICBpZiAoIWRwLmlzU2V0dGFibGUpIHJldHVybiB0cnVlO1xyXG4gICAgbGV0IHYxID0gY28xLmdldFByb3BlcnR5KGRwLm5hbWUpO1xyXG4gICAgbGV0IHYyID0gY28yLmdldFByb3BlcnR5KGRwLm5hbWUpO1xyXG4gICAgaWYgKGRwLmlzQ29tcGxleFByb3BlcnR5ICYmIGRwLmlzU2NhbGFyKSB7XHJcbiAgICAgIHJldHVybiBjb0VxdWFscyh2MSwgdjIpO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAoZHAuaXNDb21wbGV4UHJvcGVydHkgJiYgIWRwLmlzU2NhbGFyKSB7XHJcbiAgICAgIHJldHVybiBjb3JlLmFycmF5RXF1YWxzKHYxLCB2MiwgY29FcXVhbHMpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbGV0IGRhdGFUeXBlID0gPGFueT5kcC5kYXRhVHlwZTsgLy8gdGhpcyB3aWxsIGJlIGEgY29tcGxleFR5cGUgd2hlbiBkcCBpcyBhIGNvbXBsZXhQcm9wZXJ0eVxyXG4gICAgICByZXR1cm4gKHYxID09PSB2MiB8fCAoZGF0YVR5cGUgJiYgZGF0YVR5cGUubm9ybWFsaXplICYmIHYxICYmIHYyICYmIGRhdGFUeXBlLm5vcm1hbGl6ZSh2MSkgPT09IGRhdGFUeXBlLm5vcm1hbGl6ZSh2MikpKTtcclxuICAgIH1cclxuICB9KTtcclxuICByZXR1cm4gYXJlRXF1YWw7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGxvY2FsUHJvcHNPbmx5KHByb3BzOiBFbnRpdHlQcm9wZXJ0eVtdKSB7XHJcbiAgcmV0dXJuIHByb3BzLmZpbHRlcihmdW5jdGlvbiAocHJvcCkge1xyXG4gICAgcmV0dXJuIHByb3AuYmFzZVByb3BlcnR5ID09IG51bGw7XHJcbiAgfSk7XHJcbn1cclxuXHJcblxyXG5mdW5jdGlvbiByZXNvbHZlQ3AoY3A6IERhdGFQcm9wZXJ0eSwgbWV0YWRhdGFTdG9yZTogTWV0YWRhdGFTdG9yZSkge1xyXG4gIGxldCBjb21wbGV4VHlwZSA9IG1ldGFkYXRhU3RvcmUuX2dldFN0cnVjdHVyYWxUeXBlKGNwLmNvbXBsZXhUeXBlTmFtZSwgdHJ1ZSk7XHJcbiAgaWYgKCFjb21wbGV4VHlwZSkgcmV0dXJuIGZhbHNlO1xyXG4gIGlmICghKGNvbXBsZXhUeXBlIGluc3RhbmNlb2YgQ29tcGxleFR5cGUpKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmFibGUgdG8gcmVzb2x2ZSBDb21wbGV4VHlwZSB3aXRoIHRoZSBuYW1lOiBcIiArIGNwLmNvbXBsZXhUeXBlTmFtZSArIFwiIGZvciB0aGUgcHJvcGVydHk6IFwiICsgY3AubmFtZSk7XHJcbiAgfVxyXG4gIGNwLmRhdGFUeXBlID0gY29tcGxleFR5cGU7XHJcbiAgY3AuZGVmYXVsdFZhbHVlID0gbnVsbDtcclxuICByZXR1cm4gdHJ1ZTtcclxufVxyXG5cclxuZnVuY3Rpb24gdHJ5UmVzb2x2ZU5wKG5wOiBOYXZpZ2F0aW9uUHJvcGVydHksIG1ldGFkYXRhU3RvcmU6IE1ldGFkYXRhU3RvcmUpIHtcclxuICBpZiAobnAuZW50aXR5VHlwZSkgcmV0dXJuIHRydWU7XHJcblxyXG4gIGxldCBlbnRpdHlUeXBlID0gbWV0YWRhdGFTdG9yZS5fZ2V0U3RydWN0dXJhbFR5cGUobnAuZW50aXR5VHlwZU5hbWUsIHRydWUpIGFzIEVudGl0eVR5cGU7XHJcbiAgaWYgKGVudGl0eVR5cGUpIHtcclxuICAgIG5wLmVudGl0eVR5cGUgPSBlbnRpdHlUeXBlO1xyXG4gICAgbnAuX3Jlc29sdmVOcCgpO1xyXG4gICAgLy8gZG9uJ3QgYm90aGVyIHJlbW92aW5nIC0gX3VwZGF0ZU5wcyB3aWxsIGRvIGl0IGxhdGVyLlxyXG4gICAgLy8gX19hcnJheVJlbW92ZUl0ZW0oaW5jb21wbGV0ZU5wcywgbnAsIGZhbHNlKTtcclxuICB9IGVsc2Uge1xyXG4gICAgbGV0IGluY29tcGxldGVOcHMgPSBjb3JlLmdldEFycmF5KG1ldGFkYXRhU3RvcmUuX2luY29tcGxldGVUeXBlTWFwLCBucC5lbnRpdHlUeXBlTmFtZSk7XHJcbiAgICBjb3JlLmFycmF5QWRkSXRlbVVuaXF1ZShpbmNvbXBsZXRlTnBzLCBucCk7XHJcbiAgfVxyXG4gIHJldHVybiAhIWVudGl0eVR5cGU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNhbGNVbm1hcHBlZFByb3BlcnRpZXMoc3R5cGU6IFN0cnVjdHVyYWxUeXBlLCBpbnN0YW5jZTogYW55KSB7XHJcbiAgbGV0IG1ldGFkYXRhUHJvcE5hbWVzID0gc3R5cGUuZ2V0UHJvcGVydHlOYW1lcygpO1xyXG4gIGxldCBtb2RlbExpYiA9IGNvbmZpZy5pbnRlcmZhY2VSZWdpc3RyeS5tb2RlbExpYnJhcnkuZ2V0RGVmYXVsdEluc3RhbmNlKCk7XHJcbiAgbGV0IHRyYWNrYWJsZVByb3BOYW1lcyA9IG1vZGVsTGliLmdldFRyYWNrYWJsZVByb3BlcnR5TmFtZXMoaW5zdGFuY2UpO1xyXG4gIHRyYWNrYWJsZVByb3BOYW1lcy5mb3JFYWNoKGZ1bmN0aW9uIChwbjogc3RyaW5nKSB7XHJcbiAgICBpZiAobWV0YWRhdGFQcm9wTmFtZXMuaW5kZXhPZihwbikgPT09IC0xKSB7XHJcbiAgICAgIGxldCB2YWwgPSBpbnN0YW5jZVtwbl07XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2YWwgPT09IFwiZnVuY3Rpb25cIikgdmFsID0gdmFsKCk7XHJcbiAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgfVxyXG4gICAgICBsZXQgZHQgPSBEYXRhVHlwZS5mcm9tVmFsdWUodmFsKTtcclxuICAgICAgbGV0IG5ld1Byb3AgPSBuZXcgRGF0YVByb3BlcnR5KHtcclxuICAgICAgICBuYW1lOiBwbixcclxuICAgICAgICBkYXRhVHlwZTogZHQsXHJcbiAgICAgICAgaXNOdWxsYWJsZTogdHJ1ZSxcclxuICAgICAgICBpc1VubWFwcGVkOiB0cnVlXHJcbiAgICAgIH0pO1xyXG4gICAgICBuZXdQcm9wLmlzU2V0dGFibGUgPSBjb3JlLmlzU2V0dGFibGUoaW5zdGFuY2UsIHBuKTtcclxuICAgICAgaWYgKHN0eXBlIGluc3RhbmNlb2YgRW50aXR5VHlwZSAmJiBzdHlwZS5zdWJ0eXBlcyAhPSBudWxsICYmIHN0eXBlLnN1YnR5cGVzLmxlbmd0aCkge1xyXG4gICAgICAgIHN0eXBlLmdldFNlbGZBbmRTdWJ0eXBlcygpLmZvckVhY2goKHN0KSA9PiB7XHJcbiAgICAgICAgICBzdC5fYWRkUHJvcGVydHlDb3JlKG5ldyBEYXRhUHJvcGVydHkobmV3UHJvcCkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHN0eXBlLl9hZGRQcm9wZXJ0eUNvcmUobmV3UHJvcCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9KTtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBDb21wbGV4VHlwZUNvbmZpZyB7XHJcbiAgc2hvcnROYW1lPzogc3RyaW5nO1xyXG4gIG5hbWVzcGFjZT86IHN0cmluZztcclxuICBkYXRhUHJvcGVydGllcz86IERhdGFQcm9wZXJ0eVtdIHwgT2JqZWN0W10gfCBPYmplY3Q7XHJcbiAgaXNDb21wbGV4VHlwZT86IGJvb2xlYW47ICAvLyBuZWVkZWQgYmVjYXVzZSB0aGlzIGN0b3IgY2FuIGdldCBjYWxsZWQgZnJvbSB0aGUgYWRkRW50aXR5VHlwZSBtZXRob2Qgd2hpY2ggbmVlZHMgdGhlIGlzQ29tcGxleFR5cGUgcHJvcFxyXG4gIGN1c3RvbT86IGFueTtcclxufVxyXG5cclxuLyoqICBDb250YWluZXIgZm9yIGFsbCBvZiB0aGUgbWV0YWRhdGEgYWJvdXQgYSBzcGVjaWZpYyB0eXBlIG9mIENvbXBsZXggb2JqZWN0LlxyXG4+ICAgICBsZXQgY29tcGxleFR5cGUgPSBuZXcgQ29tcGxleFR5cGUoIHtcclxuPiAgICAgICAgIHNob3J0TmFtZTogXCJhZGRyZXNzXCIsXHJcbj4gICAgICAgICBuYW1lc3BhY2U6IFwibXlBcHBOYW1lc3BhY2VcIlxyXG4+ICAgICB9KTtcclxuQHBhcmFtIGNvbmZpZyAtIENvbmZpZ3VyYXRpb24gc2V0dGluZ3NcclxuKiovXHJcbmV4cG9ydCBjbGFzcyBDb21wbGV4VHlwZSB7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgZGVjbGFyZSBfJHR5cGVOYW1lOiBzdHJpbmc7IC8vIG9uIHByb3RvXHJcbiAgLyoqIEZvciBwb2x5bW9ycGhpYyBwdXJwb3NlIG9ubHkgLSBhbHdheXMgdHJ1ZSBoZXJlICovXHJcbiAgaXNDb21wbGV4VHlwZSA9IHRydWU7XHJcblxyXG4gIC8qKiBUaGUgW1tNZXRhZGF0YVN0b3JlXV0gY29udGFpbmluZyB0aGlzIENvbXBsZXhUeXBlLiAqL1xyXG4gIG1ldGFkYXRhU3RvcmU6IE1ldGFkYXRhU3RvcmU7XHJcblxyXG4gIC8qKiAgVGhlIGZ1bGx5IHF1YWxpZmVkIG5hbWUgb2YgdGhpcyBDb21wbGV4VHlwZS4gX19SZWFkIE9ubHlfXyAgKiovXHJcbiAgbmFtZTogc3RyaW5nO1xyXG4gIC8qKiAgVGhlIHNob3J0LCB1bnF1YWxpZmllZCwgbmFtZSBmb3IgdGhpcyBDb21wbGV4VHlwZS4gX19SZWFkIE9ubHlfXyAqKi9cclxuICBzaG9ydE5hbWU6IHN0cmluZztcclxuXHJcbiAgLyoqIFRoZSBuYW1lc3BhY2UgZm9yIHRoaXMgQ29tcGxleFR5cGUuIF9fUmVhZCBPbmx5X18gKiovXHJcbiAgbmFtZXNwYWNlOiBzdHJpbmc7XHJcbiAgLyoqIFRoZSBEYXRhUHJvcGVydGllcyAoc2VlIFtbRGF0YVByb3BlcnR5XV0gYXNzb2NpYXRlZCB3aXRoIHRoaXMgQ29tcGxleFR5cGUuIF9fUmVhZCBPbmx5X18gKi9cclxuICBkYXRhUHJvcGVydGllczogRGF0YVByb3BlcnR5W107XHJcbiAgLyoqIFRoZSBEYXRhUHJvcGVydGllcyBmb3IgdGhpcyBDb21wbGV4VHlwZSB0aGF0IGNvbnRhaW4gaW5zdGFuY2VzIG9mIGEgW1tDb21wbGV4VHlwZV1dLiBfX1JlYWQgT25seV9fICovXHJcbiAgY29tcGxleFByb3BlcnRpZXM6IERhdGFQcm9wZXJ0eVtdO1xyXG5cclxuICAvKipcclxuICBUaGUgZW50aXR5IGxldmVsIHZhbGlkYXRvcnMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgQ29tcGxleFR5cGUuIFZhbGlkYXRvcnMgY2FuIGJlIGFkZGVkIGFuZFxyXG4gIHJlbW92ZWQgZnJvbSB0aGlzIGNvbGxlY3Rpb24uIF9fUmVhZCBPbmx5X18gICoqL1xyXG4gIHZhbGlkYXRvcnM6IFZhbGlkYXRvcltdO1xyXG4gIC8qKiBGb3IgcG9seW1vcnBoaWMgcHVycG9zZSBvbmx5IC0gYWx3YXlzIGVtcHR5IGhlcmUgKi9cclxuICBjb25jdXJyZW5jeVByb3BlcnRpZXM6IERhdGFQcm9wZXJ0eVtdO1xyXG4gIC8qKiBUaGUgRGF0YVByb3BlcnRpZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgQ29tcGxleFR5cGUgdGhhdCBhcmUgbm90IG1hcHBlZCB0byBhbnkgYmFja2VuZCBkYXRhc3RvcmUuIFRoZXNlIGFyZSBlZmZlY3RpdmVseSBmcmVlIHN0YW5kaW5nXHJcbiAgcHJvcGVydGllcy4gX19SZWFkIE9ubHlfXyAgICoqL1xyXG4gIHVubWFwcGVkUHJvcGVydGllczogRGF0YVByb3BlcnR5W107XHJcblxyXG4gIC8vIGtleVByb3BlcnRpZXMgYW5kIG5hdmlnYXRpb25Qcm9wZXJ0aWVzIGFyZSBub3QgdXNlZCBvbiBjb21wbGV4VHlwZXMgLSBidXQgaGVyZSB0byBhbGxvdyBzaGFyaW5nIG9mIGNvZGUgYmV0d2VlbiBFbnRpdHlUeXBlIGFuZCBDb21wbGV4VHlwZS5cclxuICBuYXZpZ2F0aW9uUHJvcGVydGllczogRGF0YVByb3BlcnR5W107XHJcbiAgLy8gYW5kIG1heSBiZSB1c2VkIGxhdGVyIHRvIGVuZm9yY2UgdW5pcXVlbmVzcyBvbiBhcnJheXMgb2YgY29tcGxleHR5cGVzLlxyXG4gIGtleVByb3BlcnRpZXM6IERhdGFQcm9wZXJ0eVtdO1xyXG4gIHdhcm5pbmdzOiBhbnlbXTtcclxuICBzZXJpYWxpemVyRm4/OiAocHJvcDogRW50aXR5UHJvcGVydHksIHZhbDogYW55KSA9PiBhbnk7XHJcblxyXG4gIC8qKiBBIGZyZWUgZm9ybSBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byBkZWZpbmUgYW55IGN1c3RvbSBtZXRhZGF0YSBmb3IgdGhpcyBDb21wbGV4VHlwZS4gKioqL1xyXG4gIGN1c3RvbT86IGFueTtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfbWFwcGVkUHJvcGVydGllc0NvdW50OiBudW1iZXI7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2V4dHJhPzogYW55O1xyXG5cclxuICAvLyBjb3B5IGVudGl0eVR5cGUgbWV0aG9kcyBvbnRvIGNvbXBsZXhUeXBlXHJcbiAgLyoqIFNlZSBbW0VudGl0eVR5cGUuZ2V0Q3Rvcl1dICovXHJcbiAgZ2V0Q3RvciA9IEVudGl0eVR5cGUucHJvdG90eXBlLmdldEN0b3I7XHJcbiAgLy8gbm90ZSB0aGUgbmFtZSBjaGFuZ2UuXHJcbiAgY3JlYXRlSW5zdGFuY2UgPSBFbnRpdHlUeXBlLnByb3RvdHlwZS5jcmVhdGVFbnRpdHk7XHJcbiAgLyoqIFNlZSBbRW50aXR5VHlwZS5hZGRWYWxpZGF0b3JdICovXHJcbiAgYWRkVmFsaWRhdG9yID0gRW50aXR5VHlwZS5wcm90b3R5cGUuYWRkVmFsaWRhdG9yO1xyXG4gIGdldFByb3BlcnR5ID0gRW50aXR5VHlwZS5wcm90b3R5cGUuZ2V0UHJvcGVydHk7XHJcbiAgZ2V0UHJvcGVydGllc09uUGF0aCA9IEVudGl0eVR5cGUucHJvdG90eXBlLmdldFByb3BlcnRpZXNPblBhdGg7XHJcbiAgZ2V0UHJvcGVydHlOYW1lcyA9IEVudGl0eVR5cGUucHJvdG90eXBlLmdldFByb3BlcnR5TmFtZXM7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2FkZFByb3BlcnR5Q29yZSA9IEVudGl0eVR5cGUucHJvdG90eXBlLl9hZGRQcm9wZXJ0eUNvcmU7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX2FkZERhdGFQcm9wZXJ0eSA9IEVudGl0eVR5cGUucHJvdG90eXBlLl9hZGREYXRhUHJvcGVydHk7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3VwZGF0ZU5hbWVzID0gRW50aXR5VHlwZS5wcm90b3R5cGUuX3VwZGF0ZU5hbWVzO1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF91cGRhdGVDcHMgPSBFbnRpdHlUeXBlLnByb3RvdHlwZS5fdXBkYXRlQ3BzO1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9pbml0aWFsaXplSW5zdGFuY2UgPSBFbnRpdHlUeXBlLnByb3RvdHlwZS5faW5pdGlhbGl6ZUluc3RhbmNlO1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF91cGRhdGVUYXJnZXRGcm9tUmF3ID0gRW50aXR5VHlwZS5wcm90b3R5cGUuX3VwZGF0ZVRhcmdldEZyb21SYXc7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgX3NldEN0b3IgPSBFbnRpdHlUeXBlLnByb3RvdHlwZS5fc2V0Q3RvcjtcclxuXHJcbiAgY29uc3RydWN0b3IoY29uZmlnOiBDb21wbGV4VHlwZUNvbmZpZykge1xyXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSBDb21wbGV4VHlwZSBjdG9yIGhhcyBhIHNpbmdsZSBhcmd1bWVudCB0aGF0IGlzIGEgY29uZmlndXJhdGlvbiBvYmplY3QuXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzc2VydENvbmZpZyhjb25maWcpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwic2hvcnROYW1lXCIpLmlzTm9uRW1wdHlTdHJpbmcoKVxyXG4gICAgICAud2hlcmVQYXJhbShcIm5hbWVzcGFjZVwiKS5pc1N0cmluZygpLmlzT3B0aW9uYWwoKS53aXRoRGVmYXVsdChcIlwiKVxyXG4gICAgICAud2hlcmVQYXJhbShcImRhdGFQcm9wZXJ0aWVzXCIpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAud2hlcmVQYXJhbShcImlzQ29tcGxleFR5cGVcIikuaXNPcHRpb25hbCgpLmlzQm9vbGVhbigpICAgLy8gbmVlZGVkIGJlY2F1c2UgdGhpcyBjdG9yIGNhbiBnZXQgY2FsbGVkIGZyb20gdGhlIGFkZEVudGl0eVR5cGUgbWV0aG9kIHdoaWNoIG5lZWRzIHRoZSBpc0NvbXBsZXhUeXBlIHByb3BcclxuICAgICAgLndoZXJlUGFyYW0oXCJjdXN0b21cIikuaXNPcHRpb25hbCgpXHJcbiAgICAgIC5hcHBseUFsbCh0aGlzKTtcclxuXHJcbiAgICB0aGlzLm5hbWUgPSBxdWFsaWZ5VHlwZU5hbWUodGhpcy5zaG9ydE5hbWUsIHRoaXMubmFtZXNwYWNlKTtcclxuICAgIHRoaXMuaXNDb21wbGV4VHlwZSA9IHRydWU7XHJcbiAgICB0aGlzLmRhdGFQcm9wZXJ0aWVzID0gW107XHJcbiAgICB0aGlzLmNvbXBsZXhQcm9wZXJ0aWVzID0gW107XHJcbiAgICB0aGlzLnZhbGlkYXRvcnMgPSBbXTtcclxuICAgIHRoaXMuY29uY3VycmVuY3lQcm9wZXJ0aWVzID0gW107XHJcbiAgICB0aGlzLnVubWFwcGVkUHJvcGVydGllcyA9IFtdO1xyXG4gICAgdGhpcy5fbWFwcGVkUHJvcGVydGllc0NvdW50ID0gMDtcclxuICAgIC8vIGtleVByb3BlcnRpZXMgYW5kIG5hdmlnYXRpb25Qcm9wZXJ0aWVzIGFyZSBub3QgdXNlZCBvbiBjb21wbGV4VHlwZXMgLSBidXQgaGVyZSB0byBhbGxvdyBzaGFyaW5nIG9mIGNvZGUgYmV0d2VlbiBFbnRpdHlUeXBlIGFuZCBDb21wbGV4VHlwZS5cclxuICAgIHRoaXMubmF2aWdhdGlvblByb3BlcnRpZXMgPSBbXTtcclxuICAgIHRoaXMua2V5UHJvcGVydGllcyA9IFtdOyAvLyBtYXkgYmUgdXNlZCBsYXRlciB0byBlbmZvcmNlIHVuaXF1ZW5lc3Mgb24gYXJyYXlzIG9mIGNvbXBsZXh0eXBlcy5cclxuICAgIGlmIChjb25maWcuZGF0YVByb3BlcnRpZXMpIHtcclxuICAgICAgYWRkUHJvcGVydGllcyh0aGlzLCBjb25maWcuZGF0YVByb3BlcnRpZXMsIERhdGFQcm9wZXJ0eSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBHZW5lcmFsIHB1cnBvc2UgcHJvcGVydHkgc2V0IG1ldGhvZFxyXG4gID4gICAgICAvLyBhc3N1bWUgZW0xIGlzIGFuIEVudGl0eU1hbmFnZXJcclxuICA+ICAgICAgbGV0IGFkZHJlc3N0VHlwZSA9IGVtMS5tZXRhZGF0YVN0b3JlLmdldEVudGl0eVR5cGUoXCJBZGRyZXNzXCIpO1xyXG4gID4gICAgICBhZGRyZXNzVHlwZS5zZXRQcm9wZXJ0aWVzKCB7XHJcbiAgPiAgICAgICAgICBjdXN0b206IHsgZm9vOiA3LCBiYXI6IFwidGVzdFwiIH1cclxuICA+ICAgICAgfSk7XHJcbiAgQHBhcmFtIGNvbmZpZyAtIEN1c3RvbSBjb25maWcgb2JqZWN0XHJcbiAgQHBhcmFtIGNvbmZpZy5jdXN0b20gLSB7T2JqZWN0fVxyXG4gICoqL1xyXG4gIHNldFByb3BlcnRpZXMoY29uZmlnOiB7IGN1c3RvbT86IGFueSB9KSB7XHJcbiAgICBhc3NlcnRDb25maWcoY29uZmlnKVxyXG4gICAgICAud2hlcmVQYXJhbShcImN1c3RvbVwiKS5pc09wdGlvbmFsKClcclxuICAgICAgLmFwcGx5QWxsKHRoaXMpO1xyXG4gIH1cclxuXHJcblxyXG4gIGdldEFsbFZhbGlkYXRvcnMoKSB7XHJcbiAgICAvLyBDb21wbGV4VHlwZSBpbmhlcml0YW5jZSBpcyBub3QgWUVUIHN1cHBvcnRlZC5cclxuICAgIHJldHVybiB0aGlzLnZhbGlkYXRvcnM7XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfY3JlYXRlSW5zdGFuY2VDb3JlKHBhcmVudDogU3RydWN0dXJhbE9iamVjdCwgcGFyZW50UHJvcGVydHk6IERhdGFQcm9wZXJ0eSkge1xyXG4gICAgbGV0IGFDdG9yID0gdGhpcy5nZXRDdG9yKCk7XHJcbiAgICBsZXQgaW5zdGFuY2UgPSBuZXcgYUN0b3IoKSBhcyBDb21wbGV4T2JqZWN0O1xyXG4gICAgbmV3IENvbXBsZXhBc3BlY3QoaW5zdGFuY2UsIHBhcmVudCwgcGFyZW50UHJvcGVydHkpO1xyXG4gICAgLy8gaW5pdGlhbGl6YXRpb24gb2NjdXJzIGR1cmluZyBlaXRoZXIgYXR0YWNoIG9yIGluIGNyZWF0ZUluc3RhbmNlIGNhbGwuXHJcbiAgICByZXR1cm4gaW5zdGFuY2U7XHJcbiAgfVxyXG5cclxuXHJcbiAgYWRkUHJvcGVydHkoZGF0YVByb3BlcnR5OiBEYXRhUHJvcGVydHkpIHtcclxuICAgIGFzc2VydFBhcmFtKGRhdGFQcm9wZXJ0eSwgXCJkYXRhUHJvcGVydHlcIikuaXNJbnN0YW5jZU9mKERhdGFQcm9wZXJ0eSkuY2hlY2soKTtcclxuICAgIHJldHVybiB0aGlzLl9hZGRQcm9wZXJ0eUNvcmUoZGF0YVByb3BlcnR5KTtcclxuICB9XHJcblxyXG4gIGdldFByb3BlcnRpZXMoKTogRW50aXR5UHJvcGVydHlbXSB7XHJcbiAgICByZXR1cm4gdGhpcy5kYXRhUHJvcGVydGllcztcclxuICB9XHJcblxyXG4gIHRvSlNPTigpIHtcclxuICAgIHJldHVybiBjb3JlLnRvSnNvbih0aGlzLCB7XHJcbiAgICAgIHNob3J0TmFtZTogbnVsbCxcclxuICAgICAgbmFtZXNwYWNlOiBudWxsLFxyXG4gICAgICBpc0NvbXBsZXhUeXBlOiBudWxsLFxyXG4gICAgICBkYXRhUHJvcGVydGllczogbnVsbCxcclxuICAgICAgdmFsaWRhdG9yczogbnVsbCxcclxuICAgICAgY3VzdG9tOiBudWxsXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG59XHJcbkNvbXBsZXhUeXBlLnByb3RvdHlwZS5fJHR5cGVOYW1lID0gXCJDb21wbGV4VHlwZVwiO1xyXG4vKiogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiB0aGlzIGNvbXBsZXhUeXBlICovXHJcbkNvbXBsZXhUeXBlLnByb3RvdHlwZS5jcmVhdGVJbnN0YW5jZSA9IEVudGl0eVR5cGUucHJvdG90eXBlLmNyZWF0ZUVudGl0eTtcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRGF0YVByb3BlcnR5Q29uZmlnIHtcclxuICBuYW1lPzogc3RyaW5nO1xyXG4gIG5hbWVPblNlcnZlcj86IHN0cmluZztcclxuICBkYXRhVHlwZT86IERhdGFUeXBlIHwgc3RyaW5nIHwgQ29tcGxleFR5cGU7XHJcbiAgY29tcGxleFR5cGVOYW1lPzogc3RyaW5nO1xyXG4gIGlzTnVsbGFibGU/OiBib29sZWFuO1xyXG4gIGlzU2NhbGFyPzogYm9vbGVhbjsgLy8gd2lsbCBiZSBmYWxzZSBmb3Igc29tZSBOb1NRTCBkYXRhYmFzZXMuXHJcbiAgZGVmYXVsdFZhbHVlPzogYW55O1xyXG4gIGlzUGFydE9mS2V5PzogYm9vbGVhbjtcclxuICBpc1VubWFwcGVkPzogYm9vbGVhbjtcclxuICBpc1NldHRhYmxlPzogYm9vbGVhbjtcclxuICBjb25jdXJyZW5jeU1vZGU/OiBzdHJpbmc7XHJcbiAgbWF4TGVuZ3RoPzogbnVtYmVyO1xyXG4gIHZhbGlkYXRvcnM/OiBWYWxpZGF0b3JbXTtcclxuICBkaXNwbGF5TmFtZT86IHN0cmluZztcclxuICBlbnVtVHlwZT86IHN0cmluZztcclxuICByYXdUeXBlTmFtZT86IHN0cmluZzsgIC8vIG9jY3VycyB3aXRoIHVuZGVmaW5lZCBkYXRhdHlwZXNcclxuICBjdXN0b20/OiBhbnk7XHJcbn1cclxuXHJcbi8qKlxyXG5BIERhdGFQcm9wZXJ0eSBkZXNjcmliZXMgdGhlIG1ldGFkYXRhIGZvciBhIHNpbmdsZSBwcm9wZXJ0eSBvZiBhbiAgW1tFbnRpdHlUeXBlXV0gdGhhdCBjb250YWlucyBzaW1wbGUgZGF0YS5cclxuXHJcbkluc3RhbmNlcyBvZiB0aGUgRGF0YVByb3BlcnR5IGNsYXNzIGFyZSBjb25zdHJ1Y3RlZCBhdXRvbWF0aWNhbGx5IGR1cmluZyBNZXRhZGF0YSByZXRyaWV2YWwuIEhvd2V2ZXIgaXQgaXMgYWxzbyBwb3NzaWJsZSB0byBjb25zdHJ1Y3QgdGhlbVxyXG5kaXJlY3RseSB2aWEgdGhlIGNvbnN0cnVjdG9yLlxyXG4qKi9cclxuZXhwb3J0IGNsYXNzIERhdGFQcm9wZXJ0eSB7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgZGVjbGFyZSBfJHR5cGVOYW1lOiBzdHJpbmc7IC8vIG9uIHByb3RvXHJcbiAgLyoqIElzIHRoaXMgYSBEYXRhUHJvcGVydHk/IC0gYWx3YXlzIHRydWUgaGVyZS4gQWxsb3dzIHBvbHltb3JwaGljIHRyZWF0bWVudCBvZiBEYXRhUHJvcGVydGllcyBhbmQgTmF2aWdhdGlvblByb3BlcnRpZXMuIF9fUmVhZCBPbmx5X18gKi9cclxuICBpc0RhdGFQcm9wZXJ0eSA9IHRydWU7XHJcbiAgLyoqIElzIHRoaXMgYSBOYXZpZ2F0aW9uUHJvcGVydHk/IC0gYWx3YXlzIGZhbHNlIGhlcmUuICBBbGxvd3MgcG9seW1vcnBoaWMgdHJlYXRtZW50IG9mIERhdGFQcm9wZXJ0aWVzIGFuZCBOYXZpZ2F0aW9uUHJvcGVydGllcy4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGlzTmF2aWdhdGlvblByb3BlcnR5ID0gZmFsc2U7XHJcbiAgLyoqIFRoZSBuYW1lIG9mIHRoaXMgcHJvcGVydHkuIF9fUmVhZCBPbmx5X18gICoqL1xyXG4gIGRlY2xhcmUgbmFtZTogc3RyaW5nO1xyXG4gIC8qKiBUaGUgbmFtZSBvZiB0aGlzIHByb3BlcnR5IG9uIHRoZSBzZXJ2ZXIuIF9fUmVhZCBPbmx5X18gKiovXHJcbiAgZGVjbGFyZSBuYW1lT25TZXJ2ZXI6IHN0cmluZztcclxuICAvKiogVGhlIFtbRGF0YVR5cGVdXSBvZiB0aGlzIHByb3BlcnR5LiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSBkYXRhVHlwZTogRGF0YVR5cGUgfCBDb21wbGV4VHlwZTsgLy8gdGhpcyB3aWxsIGJlIGEgY29tcGxleFR5cGUgd2hlbiBkcCBpcyBhIGNvbXBsZXhQcm9wZXJ0eVxyXG4gIC8qKiBUaGUgbmFtZSBvZiB0aGUgW1tDb21wbGV4VHlwZV1dIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHByb3BlcnR5OyBtYXkgYmUgbnVsbC4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgY29tcGxleFR5cGVOYW1lOiBzdHJpbmc7XHJcbiAgLyoqIFRoZSBbW0NvbXBsZXhUeXBlXV0gYXNzb2NpYXRlZCB3aXRoIHRoaXMgcHJvcGVydHk7IG1heSBiZSB1bmRlZmluZWQuIF9fUmVhZCBPbmx5X18gKi9cclxuICBkZWNsYXJlIGNvbXBsZXhUeXBlPzogQ29tcGxleFR5cGU7XHJcbiAgLyoqICBXaGV0aGVyIHRoZSBjb250ZW50cyBvZiB0aGlzIHByb3BlcnR5IGlzIGFuIGluc3RhbmNlIG9mIGEgW1tDb21wbGV4VHlwZV1dLiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSBpc0NvbXBsZXhQcm9wZXJ0eTogYm9vbGVhbjtcclxuICAvKiogV2hldGhlciB0aGlzIHByb3BlcnR5IGlzIG51bGxhYmxlLiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSBpc051bGxhYmxlOiBib29sZWFuO1xyXG4gIC8qKiAgV2hldGhlciB0aGlzIHByb3BlcnR5IGlzIHNjYWxhciAoaS5lLiwgcmV0dXJucyBhIHNpbmdsZSB2YWx1ZSBhcyBvcHBvc2VkIHRvIGFuIGFycmF5KS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgaXNTY2FsYXI6IGJvb2xlYW47IC8vIHdpbGwgYmUgZmFsc2UgZm9yIHNvbWUgTm9TUUwgZGF0YWJhc2VzLlxyXG4gIC8qKiBUaGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhpcyBwcm9wZXJ0eS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgZGVmYXVsdFZhbHVlOiBhbnk7XHJcbiAgLyoqICBXaGV0aGVyIHRoaXMgcHJvcGVydHkgaXMgYSAna2V5JyBwcm9wZXJ0eS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgaXNQYXJ0T2ZLZXk6IGJvb2xlYW47XHJcbiAgLyoqIFdoZXRoZXIgdGhpcyBwcm9wZXJ0eSBpcyBhbiAndW5tYXBwZWQnIHByb3BlcnR5LiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSBpc1VubWFwcGVkOiBib29sZWFuO1xyXG4gIC8qKiBXaGV0aGVyIHRoaXMgcHJvcGVydHkgaXMgJ3NldHRhYmxlJy4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgaXNTZXR0YWJsZTogYm9vbGVhbjtcclxuICAvLyBUT0RPOiBkb2MgdGhpc1xyXG4gIGRlY2xhcmUgY29uY3VycmVuY3lNb2RlOiBzdHJpbmc7XHJcbiAgLyoqICBUaGUgbWF4aW11bSBsZW5ndGggZm9yIHRoZSB2YWx1ZSBvZiB0aGlzIHByb3BlcnR5LiBPbmx5IG1lYW5pbmdmdWwgZm9yIHN0cmluZ3MuIF9fUmVhZCBPbmx5X18gKi9cclxuICBkZWNsYXJlIG1heExlbmd0aD86IG51bWJlcjtcclxuICAvKiogVGhlIFtbVmFsaWRhdG9yXV0gaW5zdGFuY2VzIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHByb3BlcnR5LiBWYWxpZGF0b3JzIGNhbiBiZSBhZGRlZCBhbmRcclxuICByZW1vdmVkIGZyb20gdGhpcyBjb2xsZWN0aW9uLiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSB2YWxpZGF0b3JzOiBWYWxpZGF0b3JbXTtcclxuICAvKiogVGhlIGRpc3BsYXkgbmFtZSBvZiB0aGlzIHByb3BlcnR5LiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSBkaXNwbGF5TmFtZTogc3RyaW5nO1xyXG4gIC8qKiBUaGUgZnVsbCBuYW1lIG9mIHRoZSBlbnVtIHR5cGUgKi9cclxuICBkZWNsYXJlIGVudW1UeXBlPzogc3RyaW5nO1xyXG4gIC8qKiBUaGUgcmF3IHR5cGUgbmFtZSBvZiB0aGlzIHByb3BlcnR5LiB3aWxsIG9ubHkgYmUgZGVmaW5lZCBmb3IgcHJvcGVydGllcyB3aXRoIGEgRGF0YVR5cGUgb2YgJ1VuZGVmaW5lZCcgKi9cclxuICBkZWNsYXJlIHJhd1R5cGVOYW1lPzogc3RyaW5nOyAgLy8gb2NjdXJzIHdpdGggdW5kZWZpbmVkIGRhdGF0eXBlc1xyXG4gIC8qKiAgQSBmcmVlIGZvcm0gb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgdG8gZGVmaW5lIGFueSBjdXN0b20gbWV0YWRhdGEgZm9yIHRoaXMgRGF0YVByb3BlcnR5LiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSBjdXN0b20/OiBhbnk7XHJcbiAgLy8gVE9ETzogZG9jIHRoaXNcclxuICBkZWNsYXJlIGludmVyc2VOYXZpZ2F0aW9uUHJvcGVydHk/OiBOYXZpZ2F0aW9uUHJvcGVydHk7XHJcbiAgLyoqXHJcbiAgVGhlIG5hdmlnYXRpb24gcHJvcGVydHkgcmVsYXRlZCB0byB0aGlzIHByb3BlcnR5LiAgV2lsbCBvbmx5IGJlIHNldCBpZiB0aGlzIGlzIGEgZm9yZWlnbiBrZXkgcHJvcGVydHkuIF9fUmVhZCBPbmx5X18gKi9cclxuICBkZWNsYXJlIHJlbGF0ZWROYXZpZ2F0aW9uUHJvcGVydHk/OiBOYXZpZ2F0aW9uUHJvcGVydHk7XHJcbiAgLyoqIFRoZSBwYXJlbnQgdHlwZSB0aGF0IHRoaXMgcHJvcGVydHkgYmVsb25ncyB0byAtIHdpbGwgYmUgZWl0aGVyIGEgW1tFbnRpdHlUeXBlXV0gb3IgYSBbW0NvbXBsZXhUeXBlXV0uIF9fUmVhZCBPbmx5X18gKi9cclxuICBkZWNsYXJlIHBhcmVudFR5cGU6IFN0cnVjdHVyYWxUeXBlO1xyXG4gIC8qKiBQcm9wZXJ0eSBvbiB0aGUgYmFzZSB0eXBlIHRoYXQgdGhpcyBwcm9wZXJ0eSBpcyBpbmhlcml0ZWQgZnJvbS4gV2lsbCBiZSBudWxsIGlmIHRoZSBwcm9wZXJ0eSBpcyBub3Qgb24gdGhlIGJhc2UgdHlwZS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgYmFzZVByb3BlcnR5PzogRGF0YVByb3BlcnR5O1xyXG5cclxuICAvKiogRGF0YVByb3BlcnR5IGNvbnN0cnVjdG9yXHJcbiAgPiAgICAgIGxldCBsYXN0TmFtZVByb3AgPSBuZXcgRGF0YVByb3BlcnR5KCB7XHJcbiAgPiAgICAgICAgICBuYW1lOiBcImxhc3ROYW1lXCIsXHJcbiAgPiAgICAgICAgICBkYXRhVHlwZTogRGF0YVR5cGUuU3RyaW5nLFxyXG4gID4gICAgICAgICAgaXNOdWxsYWJsZTogdHJ1ZSxcclxuICA+ICAgICAgICAgIG1heExlbmd0aDogMjBcclxuICA+ICAgICAgfSk7XHJcbiAgPiAgICAgIC8vIGFzc3VtaW5nIHBlcnNvbkVudGl0eVR5cGUgaXMgYSBuZXdseSBjb25zdHJ1Y3RlZCBFbnRpdHlUeXBlXHJcbiAgPiAgICAgIHBlcnNvbkVudGl0eVR5cGUuYWRkUHJvcGVydHkobGFzdE5hbWVQcm9wZXJ0eSk7XHJcbiAgQHBhcmFtIGNvbmZpZyAtIEEgY29uZmlndXJhdGlvbiBPYmplY3Qgb3IgYSBEYXRhUHJvcGVydHlcclxuICAqL1xyXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogRGF0YVByb3BlcnR5Q29uZmlnIHwgRGF0YVByb3BlcnR5KSB7XHJcbiAgICBhc3NlcnRDb25maWcoY29uZmlnKVxyXG4gICAgICAud2hlcmVQYXJhbShcIm5hbWVcIikuaXNTdHJpbmcoKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJuYW1lT25TZXJ2ZXJcIikuaXNTdHJpbmcoKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJkYXRhVHlwZVwiKS5pc0VudW1PZihEYXRhVHlwZSkuaXNPcHRpb25hbCgpLm9yKCkuaXNTdHJpbmcoKS5vcigpLmlzSW5zdGFuY2VPZihDb21wbGV4VHlwZSlcclxuICAgICAgLndoZXJlUGFyYW0oXCJjb21wbGV4VHlwZU5hbWVcIikuaXNPcHRpb25hbCgpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiaXNOdWxsYWJsZVwiKS5pc0Jvb2xlYW4oKS5pc09wdGlvbmFsKCkud2l0aERlZmF1bHQodHJ1ZSlcclxuICAgICAgLndoZXJlUGFyYW0oXCJpc1NjYWxhclwiKS5pc09wdGlvbmFsKCkud2l0aERlZmF1bHQodHJ1ZSkvLyB3aWxsIGJlIGZhbHNlIGZvciBzb21lIE5vU1FMIGRhdGFiYXNlcy5cclxuICAgICAgLndoZXJlUGFyYW0oXCJkZWZhdWx0VmFsdWVcIikuaXNPcHRpb25hbCgpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiaXNQYXJ0T2ZLZXlcIikuaXNCb29sZWFuKCkuaXNPcHRpb25hbCgpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiaXNVbm1hcHBlZFwiKS5pc0Jvb2xlYW4oKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJpc1NldHRhYmxlXCIpLmlzQm9vbGVhbigpLmlzT3B0aW9uYWwoKS53aXRoRGVmYXVsdCh0cnVlKVxyXG4gICAgICAud2hlcmVQYXJhbShcImNvbmN1cnJlbmN5TW9kZVwiKS5pc1N0cmluZygpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAud2hlcmVQYXJhbShcIm1heExlbmd0aFwiKS5pc051bWJlcigpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAud2hlcmVQYXJhbShcInZhbGlkYXRvcnNcIikuaXNJbnN0YW5jZU9mKFZhbGlkYXRvcikuaXNBcnJheSgpLmlzT3B0aW9uYWwoKS53aXRoRGVmYXVsdChbXSlcclxuICAgICAgLndoZXJlUGFyYW0oXCJkaXNwbGF5TmFtZVwiKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJlbnVtVHlwZVwiKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJyYXdUeXBlTmFtZVwiKS5pc09wdGlvbmFsKCkgLy8gb2NjdXJzIHdpdGggdW5kZWZpbmVkIGRhdGF0eXBlc1xyXG4gICAgICAud2hlcmVQYXJhbShcImN1c3RvbVwiKS5pc09wdGlvbmFsKClcclxuICAgICAgLmFwcGx5QWxsKHRoaXMpO1xyXG4gICAgbGV0IGhhc05hbWUgPSAhISh0aGlzLm5hbWUgfHwgdGhpcy5uYW1lT25TZXJ2ZXIpO1xyXG4gICAgaWYgKCFoYXNOYW1lKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgRGF0YVByb3BlcnR5IG11c3QgYmUgaW5zdGFudGlhdGVkIHdpdGggZWl0aGVyIGEgJ25hbWUnIG9yIGEgJ25hbWVPblNlcnZlcicgcHJvcGVydHlcIik7XHJcbiAgICB9XHJcbiAgICAvLyBuYW1lL25hbWVPblNlcnZlciBpcyByZXNvbHZlZCBsYXRlciB3aGVuIGEgbWV0YWRhdGFTdG9yZSBpcyBhdmFpbGFibGUuXHJcblxyXG4gICAgaWYgKHRoaXMuY29tcGxleFR5cGVOYW1lKSB7XHJcbiAgICAgIHRoaXMuaXNDb21wbGV4UHJvcGVydHkgPSB0cnVlO1xyXG4gICAgICAvLyB0aGlzLmRhdGFUeXBlID0gbnVsbDsgLy8gVE9ETzogd291bGQgbGlrZSB0byByZW1vdmUgdGhpcyBsaW5lIGJlY2F1c2UgZGF0YVR5cGUgd2lsbCBiZSBzZXQgbGF0ZXIuXHJcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiAodGhpcy5kYXRhVHlwZSkgPT09IFwic3RyaW5nXCIpIHtcclxuICAgICAgbGV0IGR0ID0gRGF0YVR5cGUuZnJvbU5hbWUodGhpcy5kYXRhVHlwZSk7XHJcbiAgICAgIGlmICghZHQpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmFibGUgdG8gZmluZCBhIERhdGFUeXBlIGVudW1lcmF0aW9uIGJ5IHRoZSBuYW1lIG9mOiBcIiArIHRoaXMuZGF0YVR5cGUpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuZGF0YVR5cGUgPSBkdDtcclxuICAgIH0gZWxzZSBpZiAoIXRoaXMuZGF0YVR5cGUpIHtcclxuICAgICAgdGhpcy5kYXRhVHlwZSA9IERhdGFUeXBlLlN0cmluZztcclxuICAgIH1cclxuXHJcbiAgICAvLyA9PSBhcyBvcHBvc2VkIHRvID09PSBpcyBkZWxpYmVyYXRlIGhlcmUuXHJcbiAgICBpZiAodGhpcy5kZWZhdWx0VmFsdWUgPT0gbnVsbCkge1xyXG4gICAgICBpZiAodGhpcy5pc051bGxhYmxlKSB7XHJcbiAgICAgICAgdGhpcy5kZWZhdWx0VmFsdWUgPSBudWxsO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmICh0aGlzLmlzQ29tcGxleFByb3BlcnR5KSB7XHJcbiAgICAgICAgICAvLyB3aGF0IHRvIGRvPyAtIHNob3VsZG4ndCBoYXBwZW4gZnJvbSBFRiAtIGJ1dCBvdGhlcndpc2UgPz8/XHJcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmRhdGFUeXBlID09PSBEYXRhVHlwZS5CaW5hcnkpIHtcclxuICAgICAgICAgIHRoaXMuZGVmYXVsdFZhbHVlID0gXCJBQUFBQUFBQUozVT1cIjsgLy8gaGFjayBmb3IgYWxsIGJpbmFyeSBmaWVsZHMgYnV0IHZhbHVlIGlzIHNwZWNpZmljYWxseSB2YWxpZCBmb3IgdGltZXN0YW1wIGZpZWxkcyAtIGFyYml0cmFyeSB2YWxpZCA4IGJ5dGUgYmFzZTY0IHZhbHVlLlxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0aGlzLmRlZmF1bHRWYWx1ZSA9ICh0aGlzLmRhdGFUeXBlIGFzIGFueSkuZGVmYXVsdFZhbHVlO1xyXG4gICAgICAgICAgY29uc3QgbXNnID0gXCJBIG5vbm51bGxhYmxlIERhdGFQcm9wZXJ0eSBjYW5ub3QgaGF2ZSBhIG51bGwgZGVmYXVsdFZhbHVlLiBOYW1lOiBcIiArICh0aGlzLm5hbWUgfHwgdGhpcy5uYW1lT25TZXJ2ZXIpO1xyXG4gICAgICAgICAgaWYgKHRoaXMuZGVmYXVsdFZhbHVlID09PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihtc2cpOyAgLy8gaWYgZGVmYXVsdFZhbHVlIGlzIGV4cGxpY2l0eSBzZXQgdG8gbnVsbCwgdGhhdCdzIGFuIGVycm9yXHJcbiAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuZGVmYXVsdFZhbHVlID09IG51bGwpIHtcclxuICAgICAgICAgICAgY29uc29sZS53YXJuKG1zZyk7ICAvLyBpZiBkZWZhdWx0VmFsdWUgaXMgbm90IHNldCwgdGhhdCdzIGEgd2FybmluZ1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSBlbHNlIGlmICgodGhpcy5kYXRhVHlwZSBhcyBhbnkpLmlzTnVtZXJpYykge1xyXG4gICAgICAvLyBpbiBjYXNlIHRoZSBkZWZhdWx0VmFsdWUgY29tZXMgaW4gYXMgYSBzdHJpbmcgKCB3aGljaCBpdCBkb2VzIGluIEVGNikuXHJcbiAgICAgIGlmICh0eXBlb2YgKHRoaXMuZGVmYXVsdFZhbHVlKSA9PT0gXCJzdHJpbmdcIikge1xyXG4gICAgICAgIHRoaXMuZGVmYXVsdFZhbHVlID0gcGFyc2VGbG9hdCh0aGlzLmRlZmF1bHRWYWx1ZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5pc0NvbXBsZXhQcm9wZXJ0eSkge1xyXG4gICAgICB0aGlzLmlzU2NhbGFyID0gdGhpcy5pc1NjYWxhciA9PSBudWxsIHx8IHRoaXMuaXNTY2FsYXIgPT09IHRydWU7XHJcbiAgICB9XHJcblxyXG4gIH1cclxuXHJcbiAgc3RhdGljIGdldFJhd1ZhbHVlRnJvbVNlcnZlcihyYXdFbnRpdHk6IE9iamVjdCAmIFJlY29yZDxzdHJpbmcsIGFueT4sIGRwOiBEYXRhUHJvcGVydHkpIHtcclxuICAgIGlmIChkcC5pc1VubWFwcGVkKSB7XHJcbiAgICAgIHJldHVybiByYXdFbnRpdHlbZHAubmFtZU9uU2VydmVyIHx8IGRwLm5hbWVdO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbGV0IHZhbCA9IHJhd0VudGl0eVtkcC5uYW1lT25TZXJ2ZXJdO1xyXG4gICAgICByZXR1cm4gdmFsICE9PSB1bmRlZmluZWQgPyB2YWwgOiBkcC5kZWZhdWx0VmFsdWU7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzdGF0aWMgZ2V0UmF3VmFsdWVGcm9tQ2xpZW50KHJhd0VudGl0eTogT2JqZWN0ICYgUmVjb3JkPHN0cmluZywgYW55PiwgZHA6IERhdGFQcm9wZXJ0eSkge1xyXG4gICAgbGV0IHZhbCA9IHJhd0VudGl0eVtkcC5uYW1lXTtcclxuICAgIHJldHVybiB2YWwgIT09IHVuZGVmaW5lZCA/IHZhbCA6IGRwLmRlZmF1bHRWYWx1ZTtcclxuICB9XHJcblxyXG4gIHJlc29sdmVQcm9wZXJ0eShwcm9wTmFtZTogc3RyaW5nKSB7XHJcbiAgICBsZXQgcmVzdWx0ID0gdGhpc1twcm9wTmFtZV07XHJcbiAgICBsZXQgYmFzZVByb3AgPSB0aGlzLmJhc2VQcm9wZXJ0eTtcclxuICAgIHdoaWxlIChyZXN1bHQgPT0gdW5kZWZpbmVkICYmIGJhc2VQcm9wICE9IG51bGwpIHtcclxuICAgICAgcmVzdWx0ID0gYmFzZVByb3BbcHJvcE5hbWVdO1xyXG4gICAgICBiYXNlUHJvcCA9IGJhc2VQcm9wLmJhc2VQcm9wZXJ0eTtcclxuICAgIH1cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG5cclxuICBmb3JtYXROYW1lKCkge1xyXG4gICAgcmV0dXJuIHRoaXMucGFyZW50VHlwZS5uYW1lICsgXCItLVwiICsgdGhpcy5uYW1lO1xyXG4gIH1cclxuXHJcblxyXG4gIC8qKlxyXG4gIEdlbmVyYWwgcHVycG9zZSBwcm9wZXJ0eSBzZXQgbWV0aG9kXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBlbTEgaXMgYW4gRW50aXR5TWFuYWdlclxyXG4gID4gICAgICBsZXQgcHJvcCA9IG15RW50aXR5VHlwZS5nZXRQcm9wZXJ0eShcIm15UHJvcGVydHlcIik7XHJcbiAgPiAgICAgIHByb3Auc2V0UHJvcGVydGllcygge1xyXG4gID4gICAgICAgICAgY3VzdG9tOiB7IGZvbzogNywgYmFyOiBcInRlc3RcIiB9XHJcbiAgPiAgICAgIH0pO1xyXG4gIEBwYXJhbSBjb25maWcgLSBBIGNvbmZpZ3VyYXRpb24gb2JqZWN0LlxyXG4gICoqL1xyXG4gIHNldFByb3BlcnRpZXMoY29uZmlnOiB7IGRpc3BsYXlOYW1lPzogc3RyaW5nLCBjdXN0b20/OiBPYmplY3QgfSkge1xyXG4gICAgYXNzZXJ0Q29uZmlnKGNvbmZpZylcclxuICAgICAgLndoZXJlUGFyYW0oXCJkaXNwbGF5TmFtZVwiKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJjdXN0b21cIikuaXNPcHRpb25hbCgpXHJcbiAgICAgIC5hcHBseUFsbCh0aGlzKTtcclxuICB9XHJcblxyXG4gIGdldEFsbFZhbGlkYXRvcnMoKSB7XHJcbiAgICBsZXQgdmFsaWRhdG9ycyA9IHRoaXMudmFsaWRhdG9ycy5zbGljZSgwKTtcclxuICAgIGxldCBiYXNlUHJvcCA9IHRoaXMuYmFzZVByb3BlcnR5O1xyXG4gICAgd2hpbGUgKGJhc2VQcm9wKSB7XHJcbiAgICAgIHZhbGlkYXRvcnMucHVzaC5hcHBseSh2YWxpZGF0b3JzLCBiYXNlUHJvcC52YWxpZGF0b3JzKTtcclxuICAgICAgYmFzZVByb3AgPSBiYXNlUHJvcC5iYXNlUHJvcGVydHk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdmFsaWRhdG9ycztcclxuICB9XHJcblxyXG4gIHRvSlNPTigpIHtcclxuICAgIC8vIGRvIG5vdCBzZXJpYWxpemUgZGF0YVR5cGVzIHRoYXQgYXJlIGNvbXBsZXhUeXBlc1xyXG4gICAgcmV0dXJuIGNvcmUudG9Kc29uKHRoaXMsIHtcclxuICAgICAgbmFtZTogbnVsbCxcclxuICAgICAgZGF0YVR5cGU6IGZ1bmN0aW9uICh2OiBhbnkpIHtcclxuICAgICAgICByZXR1cm4gKHYgJiYgdiBpbnN0YW5jZW9mIERhdGFUeXBlKSA/IHYubmFtZSA6IHVuZGVmaW5lZDtcclxuICAgICAgfSwgLy8gZG8gbm90IHNlcmlhbGl6ZSBkYXRhVHlwZXMgdGhhdCBhcmUgY29tcGxleFR5cGVzXHJcbiAgICAgIGNvbXBsZXhUeXBlTmFtZTogbnVsbCxcclxuICAgICAgaXNOdWxsYWJsZTogdHJ1ZSxcclxuICAgICAgZGVmYXVsdFZhbHVlOiBudWxsLFxyXG4gICAgICBpc1BhcnRPZktleTogZmFsc2UsXHJcbiAgICAgIGlzVW5tYXBwZWQ6IGZhbHNlLFxyXG4gICAgICBpc1NldHRhYmxlOiB0cnVlLFxyXG4gICAgICBjb25jdXJyZW5jeU1vZGU6IG51bGwsXHJcbiAgICAgIG1heExlbmd0aDogbnVsbCxcclxuICAgICAgdmFsaWRhdG9yczogbnVsbCxcclxuICAgICAgZGlzcGxheU5hbWU6IG51bGwsXHJcbiAgICAgIGVudW1UeXBlOiBudWxsLFxyXG4gICAgICByYXdUeXBlTmFtZTogbnVsbCxcclxuICAgICAgaXNTY2FsYXI6IHRydWUsXHJcbiAgICAgIGN1c3RvbTogbnVsbFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBzdGF0aWMgZnJvbUpTT04oanNvbjogYW55KSB7XHJcbiAgICBqc29uLmRhdGFUeXBlID0gRGF0YVR5cGUuZnJvbU5hbWUoanNvbi5kYXRhVHlwZSk7XHJcbiAgICAvLyBQYXJzZSBkZWZhdWx0IHZhbHVlIGludG8gY29ycmVjdCBkYXRhIHR5cGUuIChkYXRlVGltZSBpbnN0YW5jZXMgcmVxdWlyZSBleHRyYSB3b3JrIHRvIGRlc2VyaWFsaXplIHByb3Blcmx5LilcclxuICAgIGlmIChqc29uLmRlZmF1bHRWYWx1ZSAmJiBqc29uLmRhdGFUeXBlICYmIGpzb24uZGF0YVR5cGUucGFyc2UpIHtcclxuICAgICAganNvbi5kZWZhdWx0VmFsdWUgPSBqc29uLmRhdGFUeXBlLnBhcnNlKGpzb24uZGVmYXVsdFZhbHVlLCB0eXBlb2YganNvbi5kZWZhdWx0VmFsdWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChqc29uLnZhbGlkYXRvcnMpIHtcclxuICAgICAganNvbi52YWxpZGF0b3JzID0ganNvbi52YWxpZGF0b3JzLm1hcChWYWxpZGF0b3IuZnJvbUpTT04pO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBuZXcgRGF0YVByb3BlcnR5KGpzb24pO1xyXG4gIH1cclxuXHJcbn1cclxuRGF0YVByb3BlcnR5LnByb3RvdHlwZS5fJHR5cGVOYW1lID0gXCJEYXRhUHJvcGVydHlcIjtcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgTmF2aWdhdGlvblByb3BlcnR5Q29uZmlnIHtcclxuICBuYW1lPzogc3RyaW5nO1xyXG4gIG5hbWVPblNlcnZlcj86IHN0cmluZztcclxuICBlbnRpdHlUeXBlTmFtZT86IHN0cmluZztcclxuICBpc1NjYWxhcj86IGJvb2xlYW47XHJcbiAgYXNzb2NpYXRpb25OYW1lPzogc3RyaW5nO1xyXG4gIGZvcmVpZ25LZXlOYW1lcz86IHN0cmluZ1tdO1xyXG4gIGZvcmVpZ25LZXlOYW1lc09uU2VydmVyPzogc3RyaW5nW107XHJcbiAgaW52Rm9yZWlnbktleU5hbWVzPzogc3RyaW5nW107XHJcbiAgaW52Rm9yZWlnbktleU5hbWVzT25TZXJ2ZXI/OiBzdHJpbmdbXTtcclxuICB2YWxpZGF0b3JzPzogVmFsaWRhdG9yW107XHJcbiAgZGlzcGxheU5hbWU/OiBzdHJpbmc7XHJcbiAgY3VzdG9tPzogYW55O1xyXG59XHJcblxyXG4vKiogICBBIE5hdmlnYXRpb25Qcm9wZXJ0eSBkZXNjcmliZXMgdGhlIG1ldGFkYXRhIGZvciBhIHNpbmdsZSBwcm9wZXJ0eSBvZiBhbiBbW0VudGl0eVR5cGVdXSB0aGF0IHJldHVybiBpbnN0YW5jZXMgb2Ygb3RoZXIgRW50aXR5VHlwZXMuXHJcblxyXG5JbnN0YW5jZXMgb2YgdGhlIE5hdmlnYXRpb25Qcm9wZXJ0eSBjbGFzcyBhcmUgY29uc3RydWN0ZWQgYXV0b21hdGljYWxseSBkdXJpbmcgTWV0YWRhdGEgcmV0cmlldmFsLiAgIEhvd2V2ZXIgaXQgaXMgYWxzbyBwb3NzaWJsZSB0byBjb25zdHJ1Y3QgdGhlbVxyXG5kaXJlY3RseSB2aWEgdGhlIGNvbnN0cnVjdG9yLlxyXG4qKi9cclxuZXhwb3J0IGNsYXNzIE5hdmlnYXRpb25Qcm9wZXJ0eSB7XHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgZGVjbGFyZSBfJHR5cGVOYW1lOiBzdHJpbmc7XHJcbiAgLyoqIElzIHRoaXMgYSBEYXRhUHJvcGVydHk/IC0gYWx3YXlzIGZhbHNlIGhlcmUgXHJcbiAgQWxsb3dzIHBvbHltb3JwaGljIHRyZWF0bWVudCBvZiBEYXRhUHJvcGVydGllcyBhbmQgTmF2aWdhdGlvblByb3BlcnRpZXMuIF9fUmVhZCBPbmx5X18gKi9cclxuICBpc0RhdGFQcm9wZXJ0eSA9IGZhbHNlO1xyXG4gIC8qKiBJcyB0aGlzIGEgTmF2aWdhdGlvblByb3BlcnR5PyAtIGFsd2F5cyB0cnVlIGhlcmVcclxuICBBbGxvd3MgcG9seW1vcnBoaWMgdHJlYXRtZW50IG9mIERhdGFQcm9wZXJ0aWVzIGFuZCBOYXZpZ2F0aW9uUHJvcGVydGllcy4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGlzTmF2aWdhdGlvblByb3BlcnR5ID0gdHJ1ZTtcclxuXHJcbiAgZm9ybWF0TmFtZSA9IERhdGFQcm9wZXJ0eS5wcm90b3R5cGUuZm9ybWF0TmFtZTtcclxuICBnZXRBbGxWYWxpZGF0b3JzID0gRGF0YVByb3BlcnR5LnByb3RvdHlwZS5nZXRBbGxWYWxpZGF0b3JzO1xyXG4gIHJlc29sdmVQcm9wZXJ0eSA9IERhdGFQcm9wZXJ0eS5wcm90b3R5cGUucmVzb2x2ZVByb3BlcnR5O1xyXG5cclxuICAvKiogVGhlIFtbRW50aXR5VHlwZV1dIHJldHVybmVkIGJ5IHRoaXMgcHJvcGVydHkuIF9fUmVhZCBPbmx5X18gKi9cclxuICBkZWNsYXJlIGVudGl0eVR5cGU6IEVudGl0eVR5cGU7XHJcbiAgLyoqIFRoZSBuYW1lIG9mIHRoZSBbW0VudGl0eVR5cGVdXSByZXR1cm5lZCBieSB0aGlzIHByb3BlcnR5LiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSBlbnRpdHlUeXBlTmFtZTogc3RyaW5nO1xyXG4gIC8qKiBUaGUgW1tFbnRpdHlUeXBlXV0gdGhhdCB0aGlzIHByb3BlcnR5IGJlbG9uZ3MgdG8uICggc2FtZSBhcyBlbnRpdHlUeXBlKS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgcGFyZW50VHlwZTogRW50aXR5VHlwZTsgLy8gPz8gc2FtZSBhcyBlbnRpdHlUeXBlXHJcbiAgLyoqIFRoZSBbW0VudGl0eVR5cGVdXSB0aGF0IHRoaXMgcHJvcGVydHkgYmVsb25ncyB0by4gKCBzYW1lIGFzIGVudGl0eVR5cGUpLiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSBwYXJlbnRFbnRpdHlUeXBlOiBFbnRpdHlUeXBlOyAvLyA/PyBzYW1lIGFzIGFib3ZlXHJcbiAgLyoqIFByb3BlcnR5IG9uIHRoZSBiYXNlIHR5cGUgdGhhdCB0aGlzIHByb3BlcnR5IGlzIGluaGVyaXRlZCBmcm9tLiBXaWxsIGJlIG51bGwgaWYgdGhlIHByb3BlcnR5IGlzIG5vdCBvbiB0aGUgYmFzZSB0eXBlLiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSBiYXNlUHJvcGVydHk/OiBOYXZpZ2F0aW9uUHJvcGVydHk7XHJcbiAgLyoqIFRoZSBpbnZlcnNlIG9mIHRoaXMgTmF2aWdhdGlvblByb3BlcnR5LiAgVGhlIE5hdmlnYXRpb25Qcm9wZXJ0eSB0aGF0IHJlcHJlc2VudHMgYSBuYXZpZ2F0aW9uIGluIHRoZSBvcHBvc2l0ZSBkaXJlY3Rpb25cclxuICB0byB0aGlzIE5hdmlnYXRpb25Qcm9wZXJ0eS4gTWF5IGJlIHVuZGVmaW5lZCBmb3IgYSB1bmRpcmVjdGlvbmFsIE5hdmlnYXRpb25Qcm9wZXJ0eS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgcHJpdmF0ZSBfaW52ZXJzZT86IE5hdmlnYXRpb25Qcm9wZXJ0eTtcclxuICAvKiogVGhlIG5hbWUgb2YgdGhpcyBwcm9wZXJ0eS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgbmFtZTogc3RyaW5nO1xyXG4gIC8qKiBUaGUgbmFtZSBvZiB0aGlzIHByb3BlcnR5IG9uIHRoZSBzZXJ2ZXIuIF9fUmVhZCBPbmx5X18gKi9cclxuICBkZWNsYXJlIG5hbWVPblNlcnZlcjogc3RyaW5nO1xyXG4gIC8qKlxyXG4gIFdoZXRoZXIgdGhpcyBwcm9wZXJ0eSByZXR1cm5zIGEgc2luZ2xlIGVudGl0eSBhcyBvcHBvc2VkIHRvICBhbiBhcnJheSBvZiBlbnRpdGllcy4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgaXNTY2FsYXI6IGJvb2xlYW47XHJcbiAgLyoqIFRoZSBuYW1lIG9mIHRoZSBhc3NvY2lhdGlvbiB0byB3aGljaCB0aGF0IHRoaXMgcHJvcGVydHkgYmVsb25ncy4gIFRoaXMgYXNzb2NpYXRpb25OYW1lIHdpbGwgYmUgc2hhcmVkIHdpdGggdGhpc1xyXG4gIHByb3BlcnRpZXMgJ2ludmVyc2UnLiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSBhc3NvY2lhdGlvbk5hbWU6IHN0cmluZztcclxuICAvKiogVGhlIG5hbWVzIG9mIHRoZSBmb3JlaWduIGtleSBEYXRhUHJvcGVydGllcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBOYXZpZ2F0aW9uUHJvcGVydHkuIFRoZXJlIHdpbGwgdXN1YWxseSBvbmx5IGJlIGEgc2luZ2xlIERhdGFQcm9wZXJ0eSBhc3NvY2lhdGVkXHJcbiAgd2l0aCBhIE5hdmlnYXRpb24gcHJvcGVydHkgZXhjZXB0IGluIHRoZSBjYXNlIG9mIGVudGl0aWVzIHdpdGggbXVsdGlwYXJ0IGtleXMuIF9fUmVhZCBPbmx5X18gKi9cclxuICBkZWNsYXJlIGZvcmVpZ25LZXlOYW1lczogc3RyaW5nW107XHJcbiAgLyoqIFRoZSBzZXJ2ZXIgc2lkZSBuYW1lcyBvZiB0aGUgZm9yZWlnbiBrZXkgRGF0YVByb3BlcnRpZXMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgTmF2aWdhdGlvblByb3BlcnR5LiBUaGVyZSB3aWxsIHVzdWFsbHkgb25seSBiZSBhIHNpbmdsZSBEYXRhUHJvcGVydHkgYXNzb2NpYXRlZFxyXG4gIHdpdGggYSBOYXZpZ2F0aW9uIHByb3BlcnR5IGV4Y2VwdCBpbiB0aGUgY2FzZSBvZiBlbnRpdGllcyB3aXRoIG11bHRpcGFydCBrZXlzLiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSBmb3JlaWduS2V5TmFtZXNPblNlcnZlcjogc3RyaW5nW107XHJcbiAgLyoqIFRoZSBuYW1lcyBvZiB0aGUgZm9yZWlnbiBrZXkgRGF0YVByb3BlcnRpZXMgYXQgdGhlIG90aGVyIGVuZCBvZiB0aGUgcmVsYXRpb25zaGlwLiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSBpbnZGb3JlaWduS2V5TmFtZXM6IHN0cmluZ1tdO1xyXG4gIC8qKiBUaGUgc2VydmVyIHNpZGUgbmFtZXMgb2YgdGhlIGZvcmVpZ24ga2V5IERhdGFQcm9wZXJ0aWVzIGF0IHRoZSBvdGhlciBlbmQgb2YgdGhlIHJlbGF0aW9uc2hpcC4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgaW52Rm9yZWlnbktleU5hbWVzT25TZXJ2ZXI6IHN0cmluZ1tdO1xyXG4gIC8qKiBUaGUgJ2ZvcmVpZ24ga2V5JyBEYXRhUHJvcGVydGllcyBhc3NvY2lhdGVkIHdpdGggdGhpcyBOYXZpZ2F0aW9uUHJvcGVydHkuIFRoZXJlIHdpbGwgdXN1YWxseSBvbmx5IGJlIGEgc2luZ2xlIERhdGFQcm9wZXJ0eSBhc3NvY2lhdGVkXHJcbiAgd2l0aCBhIE5hdmlnYXRpb24gcHJvcGVydHkgZXhjZXB0IGluIHRoZSBjYXNlIG9mIGVudGl0aWVzIHdpdGggbXVsdGlwYXJ0IGtleXMuIF9fUmVhZCBPbmx5X18gKi9cclxuICBkZWNsYXJlIHJlbGF0ZWREYXRhUHJvcGVydGllczogRGF0YVByb3BlcnR5W107XHJcbiAgLyoqIFRoZSBbW1ZhbGlkYXRvcl1dIGluc3RhbmNlcyB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggdGhpcyBwcm9wZXJ0eS4gVmFsaWRhdG9ycyBjYW4gYmUgYWRkZWQgYW5kXHJcbiAgcmVtb3ZlZCBmcm9tIHRoaXMgY29sbGVjdGlvbi4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgdmFsaWRhdG9yczogVmFsaWRhdG9yW107XHJcbiAgLyoqIFRoZSBkaXNwbGF5IG5hbWUgb2YgdGhpcyBwcm9wZXJ0eS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgZGlzcGxheU5hbWU6IHN0cmluZztcclxuICBkZWNsYXJlIGlzVW5tYXBwZWQ6IGJvb2xlYW47XHJcbiAgLyoqIEEgZnJlZSBmb3JtIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIHRvIGRlZmluZSBhbnkgY3VzdG9tIG1ldGFkYXRhIGZvciB0aGlzIE5hdmlnYXRpb25Qcm9wZXJ0eS4gICAqKi9cclxuICBkZWNsYXJlIGN1c3RvbTogYW55O1xyXG5cclxuICAvKiogTmF2aWdhdGlvblByb3BlcnR5IGNvbnN0cnVjdG9yXHJcbiAgPiAgICAgIGxldCBob21lQWRkcmVzc1Byb3AgPSBuZXcgTmF2aWdhdGlvblByb3BlcnR5KCB7XHJcbiAgPiAgICAgICAgICBuYW1lOiBcImhvbWVBZGRyZXNzXCIsXHJcbiAgPiAgICAgICAgICBlbnRpdHlUeXBlTmFtZTogXCJBZGRyZXNzOiNteU5hbWVzcGFjZVwiLFxyXG4gID4gICAgICAgICAgaXNTY2FsYXI6IHRydWUsXHJcbiAgPiAgICAgICAgICBhc3NvY2lhdGlvbk5hbWU6IFwiYWRkcmVzc19wZXJzb25cIixcclxuICA+ICAgICAgICAgIGZvcmVpZ25LZXlOYW1lczogW1wiaG9tZUFkZHJlc3NJZFwiXVxyXG4gID4gICAgICB9KTtcclxuICA+ICAgICAgbGV0IGhvbWVBZGRyZXNzSWRQcm9wID0gbmV3IERhdGFQcm9wZXJ0eSgge1xyXG4gID4gICAgICAgICAgbmFtZTogXCJob21lQWRkcmVzc0lkXCJcclxuICA+ICAgICAgICAgIGRhdGFUeXBlOiBEYXRhVHlwZS5JbnRlZ2VyXHJcbiAgPiAgICAgIH0pO1xyXG4gID4gICAgICAvLyBhc3N1bWluZyBwZXJzb25FbnRpdHlUeXBlIGlzIGEgbmV3bHkgY29uc3RydWN0ZWQgRW50aXR5VHlwZVxyXG4gID4gICAgICBwZXJzb25FbnRpdHlUeXBlLmFkZFByb3BlcnR5KGhvbWVBZGRyZXNzUHJvcCk7XHJcbiAgPiAgICAgIHBlcnNvbkVudGl0eVR5cGUuYWRkUHJvcGVydHkoaG9tZUFkZHJlc3NJZFByb3ApO1xyXG4gIEBwYXJhbSBjb25maWcgLSBBIGNvbmZpZ3VyYXRpb24gb2JqZWN0LlxyXG4gICoqL1xyXG4gIGNvbnN0cnVjdG9yKGNvbmZpZzogTmF2aWdhdGlvblByb3BlcnR5Q29uZmlnKSB7XHJcbiAgICBhc3NlcnRDb25maWcoY29uZmlnKVxyXG4gICAgICAud2hlcmVQYXJhbShcIm5hbWVcIikuaXNTdHJpbmcoKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJuYW1lT25TZXJ2ZXJcIikuaXNTdHJpbmcoKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJlbnRpdHlUeXBlTmFtZVwiKS5pc1N0cmluZygpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiaXNTY2FsYXJcIikuaXNCb29sZWFuKCkuaXNPcHRpb25hbCgpLndpdGhEZWZhdWx0KHRydWUpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiYXNzb2NpYXRpb25OYW1lXCIpLmlzU3RyaW5nKCkuaXNPcHRpb25hbCgpXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiZm9yZWlnbktleU5hbWVzXCIpLmlzQXJyYXkoKS5pc1N0cmluZygpLmlzT3B0aW9uYWwoKS53aXRoRGVmYXVsdChbXSlcclxuICAgICAgLndoZXJlUGFyYW0oXCJmb3JlaWduS2V5TmFtZXNPblNlcnZlclwiKS5pc0FycmF5KCkuaXNTdHJpbmcoKS5pc09wdGlvbmFsKCkud2l0aERlZmF1bHQoW10pXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiaW52Rm9yZWlnbktleU5hbWVzXCIpLmlzQXJyYXkoKS5pc1N0cmluZygpLmlzT3B0aW9uYWwoKS53aXRoRGVmYXVsdChbXSlcclxuICAgICAgLndoZXJlUGFyYW0oXCJpbnZGb3JlaWduS2V5TmFtZXNPblNlcnZlclwiKS5pc0FycmF5KCkuaXNTdHJpbmcoKS5pc09wdGlvbmFsKCkud2l0aERlZmF1bHQoW10pXHJcbiAgICAgIC53aGVyZVBhcmFtKFwidmFsaWRhdG9yc1wiKS5pc0luc3RhbmNlT2YoVmFsaWRhdG9yKS5pc0FycmF5KCkuaXNPcHRpb25hbCgpLndpdGhEZWZhdWx0KFtdKVxyXG4gICAgICAud2hlcmVQYXJhbShcImRpc3BsYXlOYW1lXCIpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAud2hlcmVQYXJhbShcImN1c3RvbVwiKS5pc09wdGlvbmFsKClcclxuICAgICAgLmFwcGx5QWxsKHRoaXMpO1xyXG4gICAgbGV0IGhhc05hbWUgPSAhISh0aGlzLm5hbWUgfHwgdGhpcy5uYW1lT25TZXJ2ZXIpO1xyXG5cclxuICAgIGlmICghaGFzTmFtZSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBIE5hdmlnYXRpb24gcHJvcGVydHkgbXVzdCBiZSBpbnN0YW50aWF0ZWQgd2l0aCBlaXRoZXIgYSAnbmFtZScgb3IgYSAnbmFtZU9uU2VydmVyJyBwcm9wZXJ0eVwiKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIEdlbmVyYWwgcHVycG9zZSBwcm9wZXJ0eSBzZXQgbWV0aG9kXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBteUVudGl0eVR5cGUgaXMgYW4gRW50aXR5VHlwZVxyXG4gID4gICAgICBsZXQgcHJvcCA9IG15RW50aXR5VHlwZS5nZXRQcm9wZXJ0eShcIm15UHJvcGVydHlcIik7XHJcbiAgPiAgICAgIHByb3Auc2V0UHJvcGVydGllcygge1xyXG4gID4gICAgICAgICAgY3VzdG9tOiB7IGZvbzogNywgYmFyOiBcInRlc3RcIiB9XHJcbiAgPiAgICAgIH0pO1xyXG4gIEBwYXJhbSBjb25maWcgLSBBIGNvbmZpZyBvYmplY3RcclxuICAqKi9cclxuICAvLyBUT0RPOiBjcmVhdGUgYW4gaW50ZXJmYWNlIGZvciB0aGlzLlxyXG4gIHNldFByb3BlcnRpZXMoY29uZmlnOiB7XHJcbiAgICBkaXNwbGF5TmFtZT86IHN0cmluZyxcclxuICAgIGZvcmVpZ25LZXlOYW1lcz86IHN0cmluZ1tdLFxyXG4gICAgaW52Rm9yZWlnbktleU5hbWVzPzogc3RyaW5nW10sXHJcbiAgICBpbnZlcnNlPzogTmF2aWdhdGlvblByb3BlcnR5IHwgc3RyaW5nLFxyXG4gICAgY3VzdG9tPzogYW55XHJcbiAgfSkge1xyXG4gICAgaWYgKCF0aGlzLnBhcmVudFR5cGUpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGNhbGwgTmF2aWdhdGlvblByb3BlcnR5LnNldFByb3BlcnRpZXMgdW50aWwgdGhlIHBhcmVudCBFbnRpdHlUeXBlIG9mIHRoZSBOYXZpZ2F0aW9uUHJvcGVydHkgaGFzIGJlZW4gc2V0LlwiKTtcclxuICAgIH1cclxuICAgIGxldCBpbnZlcnNlID0gY29uZmlnLmludmVyc2U7XHJcbiAgICBpZiAoaW52ZXJzZSkgZGVsZXRlIGNvbmZpZy5pbnZlcnNlO1xyXG4gICAgYXNzZXJ0Q29uZmlnKGNvbmZpZylcclxuICAgICAgLndoZXJlUGFyYW0oXCJkaXNwbGF5TmFtZVwiKS5pc09wdGlvbmFsKClcclxuICAgICAgLndoZXJlUGFyYW0oXCJmb3JlaWduS2V5TmFtZXNcIikuaXNBcnJheSgpLmlzU3RyaW5nKCkuaXNPcHRpb25hbCgpLndpdGhEZWZhdWx0KFtdKVxyXG4gICAgICAud2hlcmVQYXJhbShcImludkZvcmVpZ25LZXlOYW1lc1wiKS5pc0FycmF5KCkuaXNTdHJpbmcoKS5pc09wdGlvbmFsKCkud2l0aERlZmF1bHQoW10pXHJcbiAgICAgIC53aGVyZVBhcmFtKFwiY3VzdG9tXCIpLmlzT3B0aW9uYWwoKVxyXG4gICAgICAuYXBwbHlBbGwodGhpcyk7XHJcbiAgICB0aGlzLnBhcmVudFR5cGUuX3VwZGF0ZU5hbWVzKHRoaXMpO1xyXG5cclxuICAgIHRoaXMuX3Jlc29sdmVOcCgpO1xyXG4gICAgaWYgKGludmVyc2UpIHtcclxuICAgICAgdGhpcy5zZXRJbnZlcnNlKGludmVyc2UpO1xyXG4gICAgfVxyXG5cclxuICB9XHJcblxyXG4gIC8qKiBUaGUgaW52ZXJzZSBvZiB0aGlzIE5hdmlnYXRpb25Qcm9wZXJ0eS4gIFRoZSBOYXZpZ2F0aW9uUHJvcGVydHkgdGhhdCByZXByZXNlbnRzIGEgbmF2aWdhdGlvbiBpbiB0aGUgb3Bwb3NpdGUgZGlyZWN0aW9uXHJcbiAgdG8gdGhpcyBOYXZpZ2F0aW9uUHJvcGVydHkuIE1heSBiZSB1bmRlZmluZWQgZm9yIGEgdW5kaXJlY3Rpb25hbCBOYXZpZ2F0aW9uUHJvcGVydHkuIF9fUmVhZCBPbmx5X18gKi9cclxuICBnZXQgaW52ZXJzZSgpOiBOYXZpZ2F0aW9uUHJvcGVydHkgfCB1bmRlZmluZWQge1xyXG4gICAgcmV0dXJuIHRoaXMuZ2V0SW52ZXJzZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgZ2V0SW52ZXJzZSgpOiBOYXZpZ2F0aW9uUHJvcGVydHkgfCB1bmRlZmluZWQge1xyXG4gICAgbGV0IG5wOiBOYXZpZ2F0aW9uUHJvcGVydHkgPSB0aGlzO1xyXG4gICAgd2hpbGUgKCFucC5faW52ZXJzZSAmJiBucC5iYXNlUHJvcGVydHkpIHtcclxuICAgICAgbnAgPSBucC5iYXNlUHJvcGVydHk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbnAuX2ludmVyc2U7XHJcbiAgfVxyXG5cclxuICBzZXRJbnZlcnNlKGludmVyc2VOcDogTmF2aWdhdGlvblByb3BlcnR5IHwgc3RyaW5nKSB7XHJcbiAgICAvLyBsZXQgaW52TnA6IE5hdmlnYXRpb25Qcm9wZXJ0eTtcclxuICAgIGxldCBpbnZOcCA9IChpbnZlcnNlTnAgaW5zdGFuY2VvZiBOYXZpZ2F0aW9uUHJvcGVydHkpID8gaW52ZXJzZU5wIDogdGhpcy5lbnRpdHlUeXBlLmdldE5hdmlnYXRpb25Qcm9wZXJ0eShpbnZlcnNlTnApO1xyXG5cclxuICAgIGlmICghaW52TnApIHtcclxuICAgICAgdGhyb3cgdGhyb3dTZXRJbnZlcnNlRXJyb3IodGhpcywgXCJVbmFibGUgdG8gZmluZCBpbnZlcnNlIHByb3BlcnR5OiBcIiArIGludmVyc2VOcCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuX2ludmVyc2UgfHwgaW52TnAuX2ludmVyc2UpIHtcclxuICAgICAgdGhyb3dTZXRJbnZlcnNlRXJyb3IodGhpcywgXCJJdCBoYXMgYWxyZWFkeSBiZWVuIHNldCBvbiBvbmUgc2lkZSBvciB0aGUgb3RoZXIuXCIpO1xyXG4gICAgfVxyXG4gICAgaWYgKGludk5wLmVudGl0eVR5cGUgIT09IHRoaXMucGFyZW50VHlwZSkge1xyXG4gICAgICB0aHJvd1NldEludmVyc2VFcnJvcih0aGlzLCBpbnZOcC5mb3JtYXROYW1lICsgXCIgaXMgbm90IGEgdmFsaWQgaW52ZXJzZSBwcm9wZXJ0eSBmb3IgdGhpcy5cIik7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5hc3NvY2lhdGlvbk5hbWUpIHtcclxuICAgICAgaW52TnAuYXNzb2NpYXRpb25OYW1lID0gdGhpcy5hc3NvY2lhdGlvbk5hbWU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAoIWludk5wLmFzc29jaWF0aW9uTmFtZSkge1xyXG4gICAgICAgIGludk5wLmFzc29jaWF0aW9uTmFtZSA9IHRoaXMuZm9ybWF0TmFtZSgpICsgXCJfXCIgKyBpbnZOcC5mb3JtYXROYW1lKCk7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5hc3NvY2lhdGlvbk5hbWUgPSBpbnZOcC5hc3NvY2lhdGlvbk5hbWU7XHJcbiAgICB9XHJcbiAgICB0aGlzLl9yZXNvbHZlTnAoKTtcclxuICAgIGludk5wLl9yZXNvbHZlTnAoKTtcclxuICB9XHJcblxyXG4gIC8vIC8vIEluIHByb2dyZXNzIC0gd2lsbCBiZSB1c2VkIGZvciBtYW51YWwgbWV0YWRhdGEgY29uZmlnXHJcbiAgLy8gY3JlYXRlSW52ZXJzZShjb25maWc6IGFueSkge1xyXG5cclxuICAvLyAgIGlmICghdGhpcy5lbnRpdHlUeXBlKSB7XHJcbiAgLy8gICAgIHRocm93Q3JlYXRlSW52ZXJzZUVycm9yKHRoaXMsIFwiaGFzIG5vdCB5ZXQgYmVlbiBkZWZpbmVkLlwiKTtcclxuICAvLyAgIH1cclxuICAvLyAgIGlmICh0aGlzLmVudGl0eVR5cGUuaXNGcm96ZW4pIHtcclxuICAvLyAgICAgdGhyb3dDcmVhdGVJbnZlcnNlRXJyb3IodGhpcywgXCJpcyBmcm96ZW4uXCIpO1xyXG4gIC8vICAgfVxyXG4gIC8vICAgbGV0IG1ldGFkYXRhU3RvcmUgPSB0aGlzLmVudGl0eVR5cGUubWV0YWRhdGFTdG9yZTtcclxuICAvLyAgIGlmIChtZXRhZGF0YVN0b3JlID09IG51bGwpIHtcclxuICAvLyAgICAgdGhyb3dDcmVhdGVJbnZlcnNlRXJyb3IodGhpcywgXCJoYXMgbm90IHlldCBiZWVuIGFkZGVkIHRvIHRoZSBtZXRhZGF0YVN0b3JlLlwiKTtcclxuICAvLyAgIH1cclxuXHJcbiAgLy8gICBjb25maWcuZW50aXR5VHlwZU5hbWUgPSB0aGlzLnBhcmVudEVudGl0eVR5cGUubmFtZTtcclxuICAvLyAgIGNvbmZpZy5hc3NvY2lhdGlvbk5hbWUgPSB0aGlzLmFzc29jaWF0aW9uTmFtZTtcclxuICAvLyAgIGxldCBpbnZOcCA9IG5ldyBOYXZpZ2F0aW9uUHJvcGVydHkoY29uZmlnKTtcclxuICAvLyAgIHRoaXMucGFyZW50RW50aXR5VHlwZS5hZGROYXZpZ2F0aW9uUHJvcGVydHkoaW52TnApO1xyXG4gIC8vICAgcmV0dXJuIGludk5wO1xyXG4gIC8vIH07XHJcblxyXG5cclxuXHJcbiAgdG9KU09OKCkge1xyXG4gICAgcmV0dXJuIGNvcmUudG9Kc29uKHRoaXMsIHtcclxuICAgICAgbmFtZTogbnVsbCxcclxuICAgICAgZW50aXR5VHlwZU5hbWU6IG51bGwsXHJcbiAgICAgIGlzU2NhbGFyOiBudWxsLFxyXG4gICAgICBhc3NvY2lhdGlvbk5hbWU6IG51bGwsXHJcbiAgICAgIHZhbGlkYXRvcnM6IG51bGwsXHJcbiAgICAgIGRpc3BsYXlOYW1lOiBudWxsLFxyXG4gICAgICBmb3JlaWduS2V5TmFtZXM6IG51bGwsXHJcbiAgICAgIGludkZvcmVpZ25LZXlOYW1lczogbnVsbCxcclxuICAgICAgY3VzdG9tOiBudWxsXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHN0YXRpYyBmcm9tSlNPTihqc29uOiBhbnkpIHtcclxuICAgIGlmIChqc29uLnZhbGlkYXRvcnMpIHtcclxuICAgICAganNvbi52YWxpZGF0b3JzID0ganNvbi52YWxpZGF0b3JzLm1hcChWYWxpZGF0b3IuZnJvbUpTT04pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5ldyBOYXZpZ2F0aW9uUHJvcGVydHkoanNvbik7XHJcbiAgfVxyXG5cclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfcmVzb2x2ZU5wKCkge1xyXG4gICAgbGV0IG5wID0gdGhpcztcclxuICAgIGxldCBlbnRpdHlUeXBlID0gbnAuZW50aXR5VHlwZTtcclxuICAgIGxldCBpbnZOcCA9IGNvcmUuYXJyYXlGaXJzdChlbnRpdHlUeXBlLm5hdmlnYXRpb25Qcm9wZXJ0aWVzLCAoYWx0TnApID0+IHtcclxuICAgICAgLy8gQ2FuJ3QgZG8gdGhpcyBiZWNhdXNlIG9mIHBvc3NpYmlsaXR5IG9mIGNvbXBhcmluZyBhIGJhc2UgY2xhc3MgbnAgd2l0aCBhIHN1YmNsYXNzIGFsdE5wLlxyXG4gICAgICAvLyByZXR1cm4gYWx0TnAuYXNzb2NpYXRpb25OYW1lID09PSBucC5hc3NvY2lhdGlvbk5hbWVcclxuICAgICAgLy8gICAgJiYgYWx0TnAgIT09IG5wO1xyXG4gICAgICAvLyBTbyB1c2UgdGhpcyBpbnN0ZWFkLlxyXG4gICAgICByZXR1cm4gYWx0TnAuYXNzb2NpYXRpb25OYW1lID09PSBucC5hc3NvY2lhdGlvbk5hbWUgJiZcclxuICAgICAgICAoYWx0TnAubmFtZSAhPT0gbnAubmFtZSB8fCBhbHROcC5lbnRpdHlUeXBlTmFtZSAhPT0gbnAuZW50aXR5VHlwZU5hbWUpO1xyXG4gICAgfSk7XHJcbiAgICBucC5faW52ZXJzZSA9IGludk5wIHx8IHVuZGVmaW5lZDtcclxuICAgIC8vaWYgKGludk5wICYmIGludk5wLmludmVyc2UgPT0gbnVsbCkge1xyXG4gICAgLy8gICAgaW52TnAuX3Jlc29sdmVOcCgpO1xyXG4gICAgLy99XHJcbiAgICBpZiAoIWludk5wKSB7XHJcbiAgICAgIC8vIHVuaWRpcmVjdGlvbmFsIDEtbiByZWxhdGlvbnNoaXBcclxuICAgICAgbnAuaW52Rm9yZWlnbktleU5hbWVzLmZvckVhY2goZnVuY3Rpb24gKGludkZrTmFtZSkge1xyXG4gICAgICAgIGxldCBma1Byb3AgPSBlbnRpdHlUeXBlLmdldERhdGFQcm9wZXJ0eShpbnZGa05hbWUpO1xyXG4gICAgICAgIGlmIChma1Byb3AgPT0gbnVsbCkge1xyXG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRW50aXR5VHlwZSAnXCIgKyBucC5lbnRpdHlUeXBlTmFtZSArIFwiJyBoYXMgbm8gZm9yZWlnbiBrZXkgbWF0Y2hpbmcgJ1wiICsgaW52RmtOYW1lICsgXCInXCIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgaW52RW50aXR5VHlwZSA9IG5wLnBhcmVudFR5cGU7XHJcbiAgICAgICAgaW52TnAgPSBjb3JlLmFycmF5Rmlyc3QoaW52RW50aXR5VHlwZS5uYXZpZ2F0aW9uUHJvcGVydGllcywgKG5wMikgPT4ge1xyXG4gICAgICAgICAgcmV0dXJuIG5wMi5pbnZGb3JlaWduS2V5TmFtZXMgJiYgbnAyLmludkZvcmVpZ25LZXlOYW1lcy5pbmRleE9mKGZrUHJvcCEubmFtZSkgPj0gMCAmJiBucDIuZW50aXR5VHlwZSA9PT0gZmtQcm9wIS5wYXJlbnRUeXBlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGZrUHJvcC5pbnZlcnNlTmF2aWdhdGlvblByb3BlcnR5ID0gaW52TnAgfHwgdW5kZWZpbmVkO1xyXG4gICAgICAgIGNvcmUuYXJyYXlBZGRJdGVtVW5pcXVlKGVudGl0eVR5cGUuZm9yZWlnbktleVByb3BlcnRpZXMsIGZrUHJvcCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHJlc29sdmVSZWxhdGVkKG5wKTtcclxuICB9XHJcblxyXG59XHJcbk5hdmlnYXRpb25Qcm9wZXJ0eS5wcm90b3R5cGUuXyR0eXBlTmFtZSA9IFwiTmF2aWdhdGlvblByb3BlcnR5XCI7XHJcblxyXG5mdW5jdGlvbiB0aHJvd1NldEludmVyc2VFcnJvcihucDogTmF2aWdhdGlvblByb3BlcnR5LCBtZXNzYWdlOiBzdHJpbmcpIHtcclxuICB0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3Qgc2V0IHRoZSBpbnZlcnNlIHByb3BlcnR5IGZvcjogXCIgKyBucC5mb3JtYXROYW1lKCkgKyBcIi4gXCIgKyBtZXNzYWdlKTtcclxufVxyXG5cclxuLy8gTm90IGN1cnJlbnQgdXNlZC5cclxuLy8gZnVuY3Rpb24gdGhyb3dDcmVhdGVJbnZlcnNlRXJyb3IobnA6IE5hdmlnYXRpb25Qcm9wZXJ0eSwgbWVzc2FnZTogc3RyaW5nKSB7XHJcbi8vICAgdGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGNyZWF0ZSBpbnZlcnNlIGZvcjogXCIgKyBucC5mb3JtYXROYW1lKCkgKyBcIi4gVGhlIGVudGl0eVR5cGUgZm9yIHRoaXMgbmF2aWdhdGlvbiBwcm9wZXJ0eSBcIiArIG1lc3NhZ2UpO1xyXG4vLyB9XHJcblxyXG4vLyBzZXRzIG5hdmlnYXRpb24gcHJvcGVydHk6IHJlbGF0ZWREYXRhUHJvcGVydGllcyBhbmQgZGF0YVByb3BlcnR5OiByZWxhdGVkTmF2aWdhdGlvblByb3BlcnR5XHJcbmZ1bmN0aW9uIHJlc29sdmVSZWxhdGVkKG5wOiBOYXZpZ2F0aW9uUHJvcGVydHkpIHtcclxuXHJcbiAgbGV0IGZrTmFtZXMgPSBucC5mb3JlaWduS2V5TmFtZXM7XHJcbiAgaWYgKGZrTmFtZXMubGVuZ3RoID09PSAwKSByZXR1cm47XHJcblxyXG4gIGxldCBwYXJlbnRFbnRpdHlUeXBlID0gbnAucGFyZW50VHlwZTtcclxuICBsZXQgZmtQcm9wcyA9IGZrTmFtZXMubWFwKGZ1bmN0aW9uIChma05hbWUpIHtcclxuICAgIHJldHVybiBwYXJlbnRFbnRpdHlUeXBlLmdldERhdGFQcm9wZXJ0eShma05hbWUpO1xyXG4gIH0pO1xyXG4gIGxldCBma1Byb3BDb2xsZWN0aW9uID0gcGFyZW50RW50aXR5VHlwZS5mb3JlaWduS2V5UHJvcGVydGllcztcclxuXHJcbiAgZmtQcm9wcy5mb3JFYWNoKChkcDogRGF0YVByb3BlcnR5KSA9PiB7XHJcbiAgICBjb3JlLmFycmF5QWRkSXRlbVVuaXF1ZShma1Byb3BDb2xsZWN0aW9uLCBkcCk7XHJcbiAgICBkcC5yZWxhdGVkTmF2aWdhdGlvblByb3BlcnR5ID0gbnA7XHJcbiAgICAvLyBub3cgdXBkYXRlIHRoZSBpbnZlcnNlXHJcbiAgICBjb3JlLmFycmF5QWRkSXRlbVVuaXF1ZShucC5lbnRpdHlUeXBlLmludmVyc2VGb3JlaWduS2V5UHJvcGVydGllcywgZHApO1xyXG4gICAgaWYgKG5wLnJlbGF0ZWREYXRhUHJvcGVydGllcykge1xyXG4gICAgICBjb3JlLmFycmF5QWRkSXRlbVVuaXF1ZShucC5yZWxhdGVkRGF0YVByb3BlcnRpZXMsIGRwKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIG5wLnJlbGF0ZWREYXRhUHJvcGVydGllcyA9IFtkcF07XHJcbiAgICB9XHJcbiAgfSk7XHJcbn1cclxuXHJcblxyXG4vKipcclxuQXV0b0dlbmVyYXRlZEtleVR5cGUgaXMgYW4gJ0VudW0nIGNvbnRhaW5pbmcgYWxsIG9mIHRoZSB2YWxpZCBzdGF0ZXMgZm9yIGFuIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGtleS5cclxuKiovXHJcbmV4cG9ydCBjbGFzcyBBdXRvR2VuZXJhdGVkS2V5VHlwZSBleHRlbmRzIEJyZWV6ZUVudW0ge1xyXG5cclxuICAvKipcclxuICBUaGlzIGVudGl0eSBkb2VzIG5vdCBoYXZlIGFuIGF1dG9nZW5lcmF0ZWQga2V5LlxyXG4gIFRoZSBjbGllbnQgbXVzdCBzZXQgdGhlIGtleSBiZWZvcmUgYWRkaW5nIHRoZSBlbnRpdHkgdG8gdGhlIEVudGl0eU1hbmFnZXJcclxuICAqKi9cclxuICBzdGF0aWMgTm9uZSA9IG5ldyBBdXRvR2VuZXJhdGVkS2V5VHlwZSgpO1xyXG4gIC8qKiBcclxuICBUaGlzIGVudGl0eSdzIGtleSBpcyBhbiBJZGVudGl0eSBjb2x1bW4gYW5kIGlzIHNldCBieSB0aGUgYmFja2VuZCBkYXRhYmFzZS5cclxuICBLZXlzIGZvciBuZXcgZW50aXRpZXMgd2lsbCBiZSB0ZW1wb3JhcnkgdW50aWwgdGhlIGVudGl0aWVzIGFyZSBzYXZlZCBhdCB3aGljaCBwb2ludCB0aGUga2V5cyB3aWxsXHJcbiAgYmUgY29udmVydGVkIHRvIHRoZWlyICdyZWFsJyB2ZXJzaW9ucy5cclxuICAqKi9cclxuICBzdGF0aWMgSWRlbnRpdHkgPSBuZXcgQXV0b0dlbmVyYXRlZEtleVR5cGUoKTtcclxuICAvKipcclxuICBUaGlzIGVudGl0eSdzIGtleSBpcyBnZW5lcmF0ZWQgYnkgYSBLZXlHZW5lcmF0b3IgYW5kIGlzIHNldCBieSB0aGUgYmFja2VuZCBkYXRhYmFzZS5cclxuICBLZXlzIGZvciBuZXcgZW50aXRpZXMgd2lsbCBiZSB0ZW1wb3JhcnkgdW50aWwgdGhlIGVudGl0aWVzIGFyZSBzYXZlZCBhdCB3aGljaCBwb2ludCB0aGUga2V5cyB3aWxsXHJcbiAgYmUgY29udmVydGVkIHRvIHRoZWlyICdyZWFsJyB2ZXJzaW9ucy5cclxuICAqKi9cclxuICBzdGF0aWMgS2V5R2VuZXJhdG9yID0gbmV3IEF1dG9HZW5lcmF0ZWRLZXlUeXBlKCk7XHJcblxyXG59XHJcbkF1dG9HZW5lcmF0ZWRLZXlUeXBlLnByb3RvdHlwZS5fJHR5cGVOYW1lID0gXCJBdXRvR2VuZXJhdGVkS2V5VHlwZVwiO1xyXG5FcnJvclsneCddID0gQXV0b0dlbmVyYXRlZEtleVR5cGUucmVzb2x2ZVN5bWJvbHMoKTtcclxuXHJcblxyXG4vLyBtaXhpbiBtZXRob2RzXHJcbi8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG5kZWNsYXJlIG1vZHVsZSBcIi4vYXNzZXJ0LXBhcmFtXCIge1xyXG4gIGludGVyZmFjZSBQYXJhbSB7XHJcbiAgICBpc0VudGl0eSgpOiBQYXJhbTtcclxuICAgIGlzRW50aXR5UHJvcGVydHkoKTogUGFyYW07XHJcbiAgfVxyXG59XHJcblxyXG5sZXQgcHJvdG8gPSBQYXJhbS5wcm90b3R5cGU7XHJcblxyXG4vLyAndGhpcycgYmVsb3cgaXMgVFMgYW5ub3RhdGlvbiBcclxucHJvdG8uaXNFbnRpdHkgPSBmdW5jdGlvbiAodGhpczogUGFyYW0pIHtcclxuICByZXR1cm4gdGhpcy5fYWRkQ29udGV4dCh7XHJcbiAgICBmbjogaXNFbnRpdHksXHJcbiAgICBtc2c6IFwiIG11c3QgYmUgYW4gZW50aXR5XCJcclxuICB9KTtcclxufTtcclxuXHJcbmZ1bmN0aW9uIGlzRW50aXR5KGNvbnRleHQ6IGFueSwgdjogYW55KSB7XHJcbiAgaWYgKHYgPT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xyXG4gIHJldHVybiAodi5lbnRpdHlUeXBlICE9PSB1bmRlZmluZWQpO1xyXG59XHJcblxyXG5wcm90by5pc0VudGl0eVByb3BlcnR5ID0gZnVuY3Rpb24gKHRoaXM6IFBhcmFtKSB7XHJcbiAgcmV0dXJuIHRoaXMuX2FkZENvbnRleHQoe1xyXG4gICAgZm46IGlzRW50aXR5UHJvcGVydHksXHJcbiAgICBtc2c6IFwiIG11c3QgYmUgZWl0aGVyIGEgRGF0YVByb3BlcnR5IG9yIGEgTmF2aWdhdGlvblByb3BlcnR5XCJcclxuICB9KTtcclxufTtcclxuXHJcbmZ1bmN0aW9uIGlzRW50aXR5UHJvcGVydHkoY29udGV4dDogYW55LCB2OiBhbnkpIHtcclxuICBpZiAodiA9PSBudWxsKSByZXR1cm4gZmFsc2U7XHJcbiAgcmV0dXJuICh2LmlzRGF0YVByb3BlcnR5IHx8IHYuaXNOYXZpZ2F0aW9uUHJvcGVydHkpO1xyXG59XHJcblxyXG4vLyBmdW5jdGlvbnMgc2hhcmVkIGJldHdlZW4gY2xhc3NlcyByZWxhdGVkIHRvIE1ldGFkYXRhXHJcblxyXG5mdW5jdGlvbiBpc1F1YWxpZmllZFR5cGVOYW1lKGVudGl0eVR5cGVOYW1lOiBzdHJpbmcpIHtcclxuICByZXR1cm4gZW50aXR5VHlwZU5hbWUuaW5kZXhPZihcIjojXCIpID49IDA7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBxdWFsaWZ5VHlwZU5hbWUoc2hvcnROYW1lOiBzdHJpbmcsIG5zPzogc3RyaW5nKSB7XHJcbiAgaWYgKG5zICYmIG5zLmxlbmd0aCA+IDApIHtcclxuICAgIHJldHVybiBzaG9ydE5hbWUgKyBcIjojXCIgKyBucztcclxuICB9IGVsc2Uge1xyXG4gICAgcmV0dXJuIHNob3J0TmFtZTtcclxuICB9XHJcbn1cclxuXHJcbi8vIFVzZWQgYnkgYm90aCBDb21wbGV4VHlwZSBhbmQgRW50aXR5VHlwZVxyXG5mdW5jdGlvbiBhZGRQcm9wZXJ0aWVzKGVudGl0eVR5cGU6IFN0cnVjdHVyYWxUeXBlLCBwcm9wT2JqOiBPYmplY3QgfCB1bmRlZmluZWQsIGN0b3I6IGFueSkge1xyXG4gIGlmIChwcm9wT2JqID09IG51bGwpIHJldHVybjtcclxuICBpZiAoQXJyYXkuaXNBcnJheShwcm9wT2JqKSkge1xyXG4gICAgcHJvcE9iai5mb3JFYWNoKGVudGl0eVR5cGUuX2FkZFByb3BlcnR5Q29yZS5iaW5kKGVudGl0eVR5cGUpKTtcclxuICB9IGVsc2UgaWYgKHR5cGVvZiAocHJvcE9iaikgPT09ICdvYmplY3QnKSB7XHJcbiAgICBmb3IgKGxldCBrZXkgaW4gcHJvcE9iaikge1xyXG4gICAgICBpZiAoY29yZS5oYXNPd25Qcm9wZXJ0eShwcm9wT2JqLCBrZXkpKSB7XHJcbiAgICAgICAgbGV0IHZhbHVlID0gcHJvcE9ialtrZXldO1xyXG4gICAgICAgIHZhbHVlLm5hbWUgPSBrZXk7XHJcbiAgICAgICAgbGV0IHByb3AgPSBuZXcgY3Rvcih2YWx1ZSk7XHJcbiAgICAgICAgZW50aXR5VHlwZS5fYWRkUHJvcGVydHlDb3JlKHByb3ApO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSBlbHNlIHtcclxuICAgIHRocm93IG5ldyBFcnJvcihcIlRoZSAnZGF0YVByb3BlcnRpZXMnIG9yICduYXZpZ2F0aW9uUHJvcGVydGllcycgdmFsdWVzIG11c3QgYmUgZWl0aGVyIGFuIGFycmF5IG9mIGRhdGEvbmF2IHByb3BlcnRpZXMgb3IgYW4gb2JqZWN0IHdoZXJlIGVhY2ggcHJvcGVydHkgZGVmaW5lcyBhIGRhdGEvbmF2IHByb3BlcnR5XCIpO1xyXG4gIH1cclxufVxyXG5cclxuXHJcblxyXG5cclxuXHJcbiJdfQ==