breeze-client 2.2.0 → 2.2.1-cjs

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 (377) hide show
  1. package/adapter-ajax-angularjs/{index.d.ts → breeze-client-adapter-ajax-angularjs.d.ts} +0 -1
  2. package/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.metadata.json +1 -0
  3. package/adapter-ajax-angularjs/package.json +13 -0
  4. package/adapter-ajax-fetch/{index.d.ts → breeze-client-adapter-ajax-fetch.d.ts} +0 -1
  5. package/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.metadata.json +1 -0
  6. package/adapter-ajax-fetch/package.json +13 -0
  7. package/adapter-ajax-httpclient/{index.d.ts → breeze-client-adapter-ajax-httpclient.d.ts} +0 -1
  8. package/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.metadata.json +1 -0
  9. package/adapter-ajax-httpclient/package.json +13 -0
  10. package/adapter-ajax-jquery/{index.d.ts → breeze-client-adapter-ajax-jquery.d.ts} +0 -1
  11. package/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.metadata.json +1 -0
  12. package/adapter-ajax-jquery/package.json +13 -0
  13. package/adapter-ajax-post/{index.d.ts → breeze-client-adapter-ajax-post.d.ts} +0 -1
  14. package/adapter-ajax-post/breeze-client-adapter-ajax-post.metadata.json +1 -0
  15. package/adapter-ajax-post/package.json +13 -0
  16. package/adapter-data-service-odata/{index.d.ts → breeze-client-adapter-data-service-odata.d.ts} +0 -1
  17. package/adapter-data-service-odata/breeze-client-adapter-data-service-odata.metadata.json +1 -0
  18. package/adapter-data-service-odata/package.json +13 -0
  19. package/adapter-data-service-webapi/{index.d.ts → breeze-client-adapter-data-service-webapi.d.ts} +0 -1
  20. package/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.metadata.json +1 -0
  21. package/adapter-data-service-webapi/package.json +13 -0
  22. package/adapter-model-library-backing-store/{index.d.ts → breeze-client-adapter-model-library-backing-store.d.ts} +0 -1
  23. package/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.metadata.json +1 -0
  24. package/adapter-model-library-backing-store/package.json +13 -0
  25. package/adapter-model-library-ko/{index.d.ts → breeze-client-adapter-model-library-ko.d.ts} +0 -1
  26. package/adapter-model-library-ko/breeze-client-adapter-model-library-ko.metadata.json +1 -0
  27. package/adapter-model-library-ko/package.json +13 -0
  28. package/adapter-uri-builder-json/{index.d.ts → breeze-client-adapter-uri-builder-json.d.ts} +0 -1
  29. package/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.metadata.json +1 -0
  30. package/adapter-uri-builder-json/package.json +13 -0
  31. package/adapter-uri-builder-odata/{index.d.ts → breeze-client-adapter-uri-builder-odata.d.ts} +0 -1
  32. package/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.metadata.json +1 -0
  33. package/adapter-uri-builder-odata/package.json +13 -0
  34. package/breeze-client.d.ts +8 -0
  35. package/breeze-client.metadata.json +1 -0
  36. package/bundles/breeze-client-adapter-ajax-angularjs.umd.js +190 -0
  37. package/bundles/breeze-client-adapter-ajax-angularjs.umd.js.map +1 -0
  38. package/bundles/breeze-client-adapter-ajax-angularjs.umd.min.js +2 -0
  39. package/bundles/breeze-client-adapter-ajax-angularjs.umd.min.js.map +1 -0
  40. package/bundles/breeze-client-adapter-ajax-fetch.umd.js +190 -0
  41. package/bundles/breeze-client-adapter-ajax-fetch.umd.js.map +1 -0
  42. package/bundles/breeze-client-adapter-ajax-fetch.umd.min.js +2 -0
  43. package/bundles/breeze-client-adapter-ajax-fetch.umd.min.js.map +1 -0
  44. package/bundles/breeze-client-adapter-ajax-httpclient.umd.js +195 -0
  45. package/bundles/breeze-client-adapter-ajax-httpclient.umd.js.map +1 -0
  46. package/bundles/breeze-client-adapter-ajax-httpclient.umd.min.js +2 -0
  47. package/bundles/breeze-client-adapter-ajax-httpclient.umd.min.js.map +1 -0
  48. package/bundles/breeze-client-adapter-ajax-jquery.umd.js +115 -0
  49. package/bundles/breeze-client-adapter-ajax-jquery.umd.js.map +1 -0
  50. package/bundles/breeze-client-adapter-ajax-jquery.umd.min.js +2 -0
  51. package/bundles/breeze-client-adapter-ajax-jquery.umd.min.js.map +1 -0
  52. package/bundles/breeze-client-adapter-ajax-post.umd.js +92 -0
  53. package/bundles/breeze-client-adapter-ajax-post.umd.js.map +1 -0
  54. package/bundles/breeze-client-adapter-ajax-post.umd.min.js +2 -0
  55. package/bundles/breeze-client-adapter-ajax-post.umd.min.js.map +1 -0
  56. package/bundles/breeze-client-adapter-data-service-odata.umd.js +747 -0
  57. package/bundles/breeze-client-adapter-data-service-odata.umd.js.map +1 -0
  58. package/bundles/breeze-client-adapter-data-service-odata.umd.min.js +16 -0
  59. package/bundles/breeze-client-adapter-data-service-odata.umd.min.js.map +1 -0
  60. package/bundles/breeze-client-adapter-data-service-webapi.umd.js +333 -0
  61. package/bundles/breeze-client-adapter-data-service-webapi.umd.js.map +1 -0
  62. package/bundles/breeze-client-adapter-data-service-webapi.umd.min.js +16 -0
  63. package/bundles/breeze-client-adapter-data-service-webapi.umd.min.js.map +1 -0
  64. package/bundles/breeze-client-adapter-model-library-backing-store.umd.js +280 -0
  65. package/bundles/breeze-client-adapter-model-library-backing-store.umd.js.map +1 -0
  66. package/bundles/breeze-client-adapter-model-library-backing-store.umd.min.js +2 -0
  67. package/bundles/breeze-client-adapter-model-library-backing-store.umd.min.js.map +1 -0
  68. package/bundles/breeze-client-adapter-model-library-ko.umd.js +252 -0
  69. package/bundles/breeze-client-adapter-model-library-ko.umd.js.map +1 -0
  70. package/bundles/breeze-client-adapter-model-library-ko.umd.min.js +2 -0
  71. package/bundles/breeze-client-adapter-model-library-ko.umd.min.js.map +1 -0
  72. package/bundles/breeze-client-adapter-uri-builder-json.umd.js +96 -0
  73. package/bundles/breeze-client-adapter-uri-builder-json.umd.js.map +1 -0
  74. package/bundles/breeze-client-adapter-uri-builder-json.umd.min.js +2 -0
  75. package/bundles/breeze-client-adapter-uri-builder-json.umd.min.js.map +1 -0
  76. package/bundles/breeze-client-adapter-uri-builder-odata.umd.js +262 -0
  77. package/bundles/breeze-client-adapter-uri-builder-odata.umd.js.map +1 -0
  78. package/bundles/breeze-client-adapter-uri-builder-odata.umd.min.js +2 -0
  79. package/bundles/breeze-client-adapter-uri-builder-odata.umd.min.js.map +1 -0
  80. package/bundles/breeze-client-mixin-get-entity-graph.umd.js +258 -0
  81. package/bundles/breeze-client-mixin-get-entity-graph.umd.js.map +1 -0
  82. package/bundles/breeze-client-mixin-get-entity-graph.umd.min.js +2 -0
  83. package/bundles/breeze-client-mixin-get-entity-graph.umd.min.js.map +1 -0
  84. package/bundles/breeze-client-mixin-save-queuing.umd.js +579 -0
  85. package/bundles/breeze-client-mixin-save-queuing.umd.js.map +1 -0
  86. package/bundles/breeze-client-mixin-save-queuing.umd.min.js +16 -0
  87. package/bundles/breeze-client-mixin-save-queuing.umd.min.js.map +1 -0
  88. package/bundles/breeze-client.umd.js +14234 -0
  89. package/bundles/breeze-client.umd.js.map +1 -0
  90. package/bundles/breeze-client.umd.min.js +16 -0
  91. package/bundles/breeze-client.umd.min.js.map +1 -0
  92. package/esm2015/adapter-ajax-angularjs/adapter-ajax-angularjs.js +130 -0
  93. package/esm2015/adapter-ajax-angularjs/adapter-core.js +49 -0
  94. package/esm2015/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.js +5 -0
  95. package/esm2015/adapter-ajax-fetch/adapter-ajax-fetch.js +130 -0
  96. package/esm2015/adapter-ajax-fetch/adapter-core.js +49 -0
  97. package/esm2015/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.js +5 -0
  98. package/esm2015/adapter-ajax-httpclient/adapter-ajax-httpclient.js +137 -0
  99. package/esm2015/adapter-ajax-httpclient/adapter-core.js +49 -0
  100. package/esm2015/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.js +5 -0
  101. package/esm2015/adapter-ajax-jquery/adapter-ajax-jquery.js +103 -0
  102. package/esm2015/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.js +5 -0
  103. package/esm2015/adapter-ajax-post/adapter-ajax-post.js +77 -0
  104. package/esm2015/adapter-ajax-post/breeze-client-adapter-ajax-post.js +5 -0
  105. package/esm2015/adapter-data-service-odata/adapter-core.js +49 -0
  106. package/esm2015/adapter-data-service-odata/adapter-data-service-odata.js +463 -0
  107. package/esm2015/adapter-data-service-odata/breeze-client-adapter-data-service-odata.js +5 -0
  108. package/esm2015/adapter-data-service-webapi/adapter-data-service-webapi.js +100 -0
  109. package/esm2015/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.js +5 -0
  110. package/esm2015/adapter-model-library-backing-store/adapter-model-library-backing-store.js +268 -0
  111. package/esm2015/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.js +5 -0
  112. package/esm2015/adapter-model-library-ko/adapter-model-library-ko.js +240 -0
  113. package/esm2015/adapter-model-library-ko/breeze-client-adapter-model-library-ko.js +5 -0
  114. package/esm2015/adapter-uri-builder-json/adapter-core.js +49 -0
  115. package/esm2015/adapter-uri-builder-json/adapter-uri-builder-json.js +36 -0
  116. package/esm2015/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.js +5 -0
  117. package/esm2015/adapter-uri-builder-odata/adapter-core.js +49 -0
  118. package/esm2015/adapter-uri-builder-odata/adapter-uri-builder-odata.js +192 -0
  119. package/esm2015/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.js +5 -0
  120. package/esm2015/breeze-client.js +9 -0
  121. package/esm2015/index.js +2 -0
  122. package/esm2015/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.js +5 -0
  123. package/esm2015/mixin-get-entity-graph/mixin-get-entity-graph.js +269 -0
  124. package/esm2015/mixin-save-queuing/breeze-client-mixin-save-queuing.js +5 -0
  125. package/esm2015/mixin-save-queuing/mixin-save-queuing.js +400 -0
  126. package/esm2015/src/abstract-data-service-adapter.js +327 -0
  127. package/esm2015/src/array.js +4 -0
  128. package/esm2015/src/assert-param.js +312 -0
  129. package/esm2015/src/breeze.js +85 -0
  130. package/esm2015/src/complex-array.js +119 -0
  131. package/esm2015/src/config.js +223 -0
  132. package/esm2015/src/core.js +714 -0
  133. package/esm2015/src/csdl-metadata-parser.js +385 -0
  134. package/esm2015/src/data-service.js +203 -0
  135. package/esm2015/src/data-type.js +506 -0
  136. package/esm2015/src/default-property-interceptor.js +460 -0
  137. package/{esm2022/src/entity-action.mjs → esm2015/src/entity-action.js} +25 -25
  138. package/esm2015/src/entity-aspect.js +804 -0
  139. package/esm2015/src/entity-group.js +187 -0
  140. package/esm2015/src/entity-key.js +116 -0
  141. package/esm2015/src/entity-manager.js +2094 -0
  142. package/esm2015/src/entity-metadata.js +2109 -0
  143. package/esm2015/src/entity-query.js +1015 -0
  144. package/esm2015/src/entity-state.js +107 -0
  145. package/esm2015/src/enum.js +141 -0
  146. package/esm2015/src/event.js +256 -0
  147. package/esm2015/src/interface-registry.js +41 -0
  148. package/esm2015/src/key-generator.js +108 -0
  149. package/esm2015/src/local-query-comparison-options.js +65 -0
  150. package/esm2015/src/mapping-context.js +411 -0
  151. package/esm2015/src/naming-convention.js +88 -0
  152. package/esm2015/src/observable-array.js +185 -0
  153. package/esm2015/src/predicate.js +1242 -0
  154. package/esm2015/src/primitive-array.js +87 -0
  155. package/esm2015/src/query-options.js +152 -0
  156. package/esm2015/src/relation-array.js +175 -0
  157. package/esm2015/src/save-options.js +41 -0
  158. package/esm2015/src/unattached-children-map.js +58 -0
  159. package/esm2015/src/validate.js +991 -0
  160. package/esm2015/src/validation-options.js +64 -0
  161. package/esm5/adapter-ajax-angularjs/adapter-ajax-angularjs.js +132 -0
  162. package/esm5/adapter-ajax-angularjs/adapter-core.js +49 -0
  163. package/esm5/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.js +5 -0
  164. package/esm5/adapter-ajax-fetch/adapter-ajax-fetch.js +132 -0
  165. package/esm5/adapter-ajax-fetch/adapter-core.js +49 -0
  166. package/esm5/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.js +5 -0
  167. package/esm5/adapter-ajax-httpclient/adapter-ajax-httpclient.js +139 -0
  168. package/esm5/adapter-ajax-httpclient/adapter-core.js +49 -0
  169. package/esm5/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.js +5 -0
  170. package/esm5/adapter-ajax-jquery/adapter-ajax-jquery.js +105 -0
  171. package/esm5/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.js +5 -0
  172. package/esm5/adapter-ajax-post/adapter-ajax-post.js +81 -0
  173. package/esm5/adapter-ajax-post/breeze-client-adapter-ajax-post.js +5 -0
  174. package/esm5/adapter-data-service-odata/adapter-core.js +49 -0
  175. package/{esm2022/adapter-data-service-odata/adapter-data-service-odata.mjs → esm5/adapter-data-service-odata/adapter-data-service-odata.js} +147 -138
  176. package/esm5/adapter-data-service-odata/breeze-client-adapter-data-service-odata.js +5 -0
  177. package/esm5/adapter-data-service-webapi/adapter-data-service-webapi.js +105 -0
  178. package/esm5/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.js +5 -0
  179. package/esm5/adapter-model-library-backing-store/adapter-model-library-backing-store.js +270 -0
  180. package/esm5/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.js +5 -0
  181. package/esm5/adapter-model-library-ko/adapter-model-library-ko.js +242 -0
  182. package/esm5/adapter-model-library-ko/breeze-client-adapter-model-library-ko.js +5 -0
  183. package/esm5/adapter-uri-builder-json/adapter-core.js +49 -0
  184. package/esm5/adapter-uri-builder-json/adapter-uri-builder-json.js +38 -0
  185. package/esm5/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.js +5 -0
  186. package/esm5/adapter-uri-builder-odata/adapter-core.js +49 -0
  187. package/esm5/adapter-uri-builder-odata/adapter-uri-builder-odata.js +197 -0
  188. package/esm5/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.js +5 -0
  189. package/esm5/breeze-client.js +9 -0
  190. package/esm5/index.js +2 -0
  191. package/esm5/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.js +5 -0
  192. package/esm5/mixin-get-entity-graph/mixin-get-entity-graph.js +269 -0
  193. package/esm5/mixin-save-queuing/breeze-client-mixin-save-queuing.js +5 -0
  194. package/esm5/mixin-save-queuing/mixin-save-queuing.js +412 -0
  195. package/esm5/src/abstract-data-service-adapter.js +333 -0
  196. package/esm5/src/array.js +4 -0
  197. package/esm5/src/assert-param.js +317 -0
  198. package/esm5/src/breeze.js +85 -0
  199. package/esm5/src/complex-array.js +119 -0
  200. package/esm5/src/config.js +228 -0
  201. package/esm5/src/core.js +722 -0
  202. package/esm5/src/csdl-metadata-parser.js +385 -0
  203. package/esm5/src/data-service.js +207 -0
  204. package/esm5/src/data-type.js +513 -0
  205. package/esm5/src/default-property-interceptor.js +460 -0
  206. package/esm5/src/entity-action.js +52 -0
  207. package/esm5/src/entity-aspect.js +810 -0
  208. package/esm5/src/entity-group.js +189 -0
  209. package/esm5/src/entity-key.js +118 -0
  210. package/esm5/src/entity-manager.js +2112 -0
  211. package/esm5/src/entity-metadata.js +2144 -0
  212. package/esm5/src/entity-query.js +1042 -0
  213. package/esm5/src/entity-state.js +114 -0
  214. package/esm5/src/enum.js +144 -0
  215. package/esm5/src/event.js +259 -0
  216. package/esm5/src/interface-registry.js +43 -0
  217. package/esm5/src/key-generator.js +111 -0
  218. package/esm5/src/local-query-comparison-options.js +67 -0
  219. package/esm5/src/mapping-context.js +413 -0
  220. package/esm5/src/naming-convention.js +90 -0
  221. package/esm5/src/observable-array.js +201 -0
  222. package/esm5/src/predicate.js +1307 -0
  223. package/esm5/src/primitive-array.js +87 -0
  224. package/esm5/src/query-options.js +167 -0
  225. package/esm5/src/relation-array.js +175 -0
  226. package/esm5/src/save-options.js +43 -0
  227. package/esm5/src/unattached-children-map.js +60 -0
  228. package/{esm2022/src/validate.mjs → esm5/src/validate.js} +110 -116
  229. package/esm5/src/validation-options.js +66 -0
  230. package/{fesm2022/breeze-client-adapter-ajax-angularjs.mjs → fesm2015/breeze-client-adapter-ajax-angularjs.js} +1 -6
  231. package/fesm2015/breeze-client-adapter-ajax-angularjs.js.map +1 -0
  232. package/{fesm2022/breeze-client-adapter-ajax-fetch.mjs → fesm2015/breeze-client-adapter-ajax-fetch.js} +4 -9
  233. package/fesm2015/breeze-client-adapter-ajax-fetch.js.map +1 -0
  234. package/{fesm2022/breeze-client-adapter-ajax-httpclient.mjs → fesm2015/breeze-client-adapter-ajax-httpclient.js} +4 -6
  235. package/fesm2015/breeze-client-adapter-ajax-httpclient.js.map +1 -0
  236. package/{fesm2022/breeze-client-adapter-ajax-jquery.mjs → fesm2015/breeze-client-adapter-ajax-jquery.js} +2 -6
  237. package/fesm2015/breeze-client-adapter-ajax-jquery.js.map +1 -0
  238. package/{fesm2022/breeze-client-adapter-ajax-post.mjs → fesm2015/breeze-client-adapter-ajax-post.js} +1 -1
  239. package/fesm2015/breeze-client-adapter-ajax-post.js.map +1 -0
  240. package/{fesm2022/breeze-client-adapter-data-service-odata.mjs → fesm2015/breeze-client-adapter-data-service-odata.js} +69 -68
  241. package/fesm2015/breeze-client-adapter-data-service-odata.js.map +1 -0
  242. package/{fesm2022/breeze-client-adapter-data-service-webapi.mjs → fesm2015/breeze-client-adapter-data-service-webapi.js} +30 -30
  243. package/fesm2015/breeze-client-adapter-data-service-webapi.js.map +1 -0
  244. package/{fesm2022/breeze-client-adapter-model-library-backing-store.mjs → fesm2015/breeze-client-adapter-model-library-backing-store.js} +13 -14
  245. package/fesm2015/breeze-client-adapter-model-library-backing-store.js.map +1 -0
  246. package/{fesm2022/breeze-client-adapter-model-library-ko.mjs → fesm2015/breeze-client-adapter-model-library-ko.js} +13 -14
  247. package/fesm2015/breeze-client-adapter-model-library-ko.js.map +1 -0
  248. package/{fesm2022/breeze-client-adapter-uri-builder-json.mjs → fesm2015/breeze-client-adapter-uri-builder-json.js} +8 -9
  249. package/fesm2015/breeze-client-adapter-uri-builder-json.js.map +1 -0
  250. package/{fesm2022/breeze-client-adapter-uri-builder-odata.mjs → fesm2015/breeze-client-adapter-uri-builder-odata.js} +86 -86
  251. package/fesm2015/breeze-client-adapter-uri-builder-odata.js.map +1 -0
  252. package/{fesm2022/breeze-client-mixin-get-entity-graph.mjs → fesm2015/breeze-client-mixin-get-entity-graph.js} +1 -1
  253. package/fesm2015/breeze-client-mixin-get-entity-graph.js.map +1 -0
  254. package/{fesm2022/breeze-client-mixin-save-queuing.mjs → fesm2015/breeze-client-mixin-save-queuing.js} +2 -23
  255. package/fesm2015/breeze-client-mixin-save-queuing.js.map +1 -0
  256. package/{fesm2022/breeze-client.mjs → fesm2015/breeze-client.js} +1543 -2042
  257. package/fesm2015/breeze-client.js.map +1 -0
  258. package/fesm5/breeze-client-adapter-ajax-angularjs.js +186 -0
  259. package/fesm5/breeze-client-adapter-ajax-angularjs.js.map +1 -0
  260. package/fesm5/breeze-client-adapter-ajax-fetch.js +186 -0
  261. package/fesm5/breeze-client-adapter-ajax-fetch.js.map +1 -0
  262. package/fesm5/breeze-client-adapter-ajax-httpclient.js +193 -0
  263. package/fesm5/breeze-client-adapter-ajax-httpclient.js.map +1 -0
  264. package/fesm5/breeze-client-adapter-ajax-jquery.js +111 -0
  265. package/fesm5/breeze-client-adapter-ajax-jquery.js.map +1 -0
  266. package/fesm5/breeze-client-adapter-ajax-post.js +86 -0
  267. package/fesm5/breeze-client-adapter-ajax-post.js.map +1 -0
  268. package/fesm5/breeze-client-adapter-data-service-odata.js +523 -0
  269. package/fesm5/breeze-client-adapter-data-service-odata.js.map +1 -0
  270. package/fesm5/breeze-client-adapter-data-service-webapi.js +111 -0
  271. package/fesm5/breeze-client-adapter-data-service-webapi.js.map +1 -0
  272. package/fesm5/breeze-client-adapter-model-library-backing-store.js +276 -0
  273. package/fesm5/breeze-client-adapter-model-library-backing-store.js.map +1 -0
  274. package/fesm5/breeze-client-adapter-model-library-ko.js +248 -0
  275. package/fesm5/breeze-client-adapter-model-library-ko.js.map +1 -0
  276. package/fesm5/breeze-client-adapter-uri-builder-json.js +92 -0
  277. package/fesm5/breeze-client-adapter-uri-builder-json.js.map +1 -0
  278. package/fesm5/breeze-client-adapter-uri-builder-odata.js +250 -0
  279. package/fesm5/breeze-client-adapter-uri-builder-odata.js.map +1 -0
  280. package/fesm5/breeze-client-mixin-get-entity-graph.js +254 -0
  281. package/fesm5/breeze-client-mixin-get-entity-graph.js.map +1 -0
  282. package/fesm5/breeze-client-mixin-save-queuing.js +356 -0
  283. package/fesm5/breeze-client-mixin-save-queuing.js.map +1 -0
  284. package/fesm5/breeze-client.js +13956 -0
  285. package/fesm5/breeze-client.js.map +1 -0
  286. package/mixin-get-entity-graph/{index.d.ts → breeze-client-mixin-get-entity-graph.d.ts} +0 -1
  287. package/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.metadata.json +1 -0
  288. package/mixin-get-entity-graph/package.json +13 -0
  289. package/mixin-save-queuing/{index.d.ts → breeze-client-mixin-save-queuing.d.ts} +0 -1
  290. package/mixin-save-queuing/breeze-client-mixin-save-queuing.metadata.json +1 -0
  291. package/mixin-save-queuing/package.json +13 -0
  292. package/package.json +12 -94
  293. package/src/config.d.ts +1 -1
  294. package/src/core.d.ts +1 -1
  295. package/src/entity-aspect.d.ts +1 -1
  296. package/src/entity-metadata.d.ts +6 -8
  297. package/src/entity-query.d.ts +1 -1
  298. package/esm2022/adapter-ajax-angularjs/adapter-ajax-angularjs.mjs +0 -135
  299. package/esm2022/adapter-ajax-angularjs/adapter-core.mjs +0 -49
  300. package/esm2022/adapter-ajax-angularjs/breeze-client-adapter-ajax-angularjs.mjs +0 -5
  301. package/esm2022/adapter-ajax-fetch/adapter-ajax-fetch.mjs +0 -135
  302. package/esm2022/adapter-ajax-fetch/adapter-core.mjs +0 -49
  303. package/esm2022/adapter-ajax-fetch/breeze-client-adapter-ajax-fetch.mjs +0 -5
  304. package/esm2022/adapter-ajax-httpclient/adapter-ajax-httpclient.mjs +0 -139
  305. package/esm2022/adapter-ajax-httpclient/adapter-core.mjs +0 -49
  306. package/esm2022/adapter-ajax-httpclient/breeze-client-adapter-ajax-httpclient.mjs +0 -5
  307. package/esm2022/adapter-ajax-jquery/adapter-ajax-jquery.mjs +0 -107
  308. package/esm2022/adapter-ajax-jquery/breeze-client-adapter-ajax-jquery.mjs +0 -5
  309. package/esm2022/adapter-ajax-post/adapter-ajax-post.mjs +0 -77
  310. package/esm2022/adapter-ajax-post/breeze-client-adapter-ajax-post.mjs +0 -5
  311. package/esm2022/adapter-data-service-odata/adapter-core.mjs +0 -49
  312. package/esm2022/adapter-data-service-odata/breeze-client-adapter-data-service-odata.mjs +0 -5
  313. package/esm2022/adapter-data-service-webapi/adapter-data-service-webapi.mjs +0 -100
  314. package/esm2022/adapter-data-service-webapi/breeze-client-adapter-data-service-webapi.mjs +0 -5
  315. package/esm2022/adapter-model-library-backing-store/adapter-model-library-backing-store.mjs +0 -269
  316. package/esm2022/adapter-model-library-backing-store/breeze-client-adapter-model-library-backing-store.mjs +0 -5
  317. package/esm2022/adapter-model-library-ko/adapter-model-library-ko.mjs +0 -241
  318. package/esm2022/adapter-model-library-ko/breeze-client-adapter-model-library-ko.mjs +0 -5
  319. package/esm2022/adapter-uri-builder-json/adapter-core.mjs +0 -49
  320. package/esm2022/adapter-uri-builder-json/adapter-uri-builder-json.mjs +0 -37
  321. package/esm2022/adapter-uri-builder-json/breeze-client-adapter-uri-builder-json.mjs +0 -5
  322. package/esm2022/adapter-uri-builder-odata/adapter-core.mjs +0 -49
  323. package/esm2022/adapter-uri-builder-odata/adapter-uri-builder-odata.mjs +0 -191
  324. package/esm2022/adapter-uri-builder-odata/breeze-client-adapter-uri-builder-odata.mjs +0 -5
  325. package/esm2022/breeze-client.mjs +0 -5
  326. package/esm2022/index.mjs +0 -2
  327. package/esm2022/mixin-get-entity-graph/breeze-client-mixin-get-entity-graph.mjs +0 -5
  328. package/esm2022/mixin-get-entity-graph/mixin-get-entity-graph.mjs +0 -269
  329. package/esm2022/mixin-save-queuing/breeze-client-mixin-save-queuing.mjs +0 -5
  330. package/esm2022/mixin-save-queuing/mixin-save-queuing.mjs +0 -421
  331. package/esm2022/src/abstract-data-service-adapter.mjs +0 -325
  332. package/esm2022/src/array.mjs +0 -4
  333. package/esm2022/src/assert-param.mjs +0 -330
  334. package/esm2022/src/breeze.mjs +0 -85
  335. package/esm2022/src/complex-array.mjs +0 -117
  336. package/esm2022/src/config.mjs +0 -232
  337. package/esm2022/src/core.mjs +0 -712
  338. package/esm2022/src/csdl-metadata-parser.mjs +0 -385
  339. package/esm2022/src/data-service.mjs +0 -239
  340. package/esm2022/src/data-type.mjs +0 -510
  341. package/esm2022/src/default-property-interceptor.mjs +0 -460
  342. package/esm2022/src/entity-aspect.mjs +0 -897
  343. package/esm2022/src/entity-group.mjs +0 -192
  344. package/esm2022/src/entity-key.mjs +0 -127
  345. package/esm2022/src/entity-manager.mjs +0 -2183
  346. package/esm2022/src/entity-metadata.mjs +0 -2242
  347. package/esm2022/src/entity-query.mjs +0 -1024
  348. package/esm2022/src/entity-state.mjs +0 -107
  349. package/esm2022/src/enum.mjs +0 -143
  350. package/esm2022/src/event.mjs +0 -264
  351. package/esm2022/src/interface-registry.mjs +0 -39
  352. package/esm2022/src/key-generator.mjs +0 -110
  353. package/esm2022/src/local-query-comparison-options.mjs +0 -75
  354. package/esm2022/src/mapping-context.mjs +0 -422
  355. package/esm2022/src/naming-convention.mjs +0 -96
  356. package/esm2022/src/observable-array.mjs +0 -183
  357. package/esm2022/src/predicate.mjs +0 -1259
  358. package/esm2022/src/primitive-array.mjs +0 -85
  359. package/esm2022/src/query-options.mjs +0 -160
  360. package/esm2022/src/relation-array.mjs +0 -173
  361. package/esm2022/src/save-options.mjs +0 -51
  362. package/esm2022/src/unattached-children-map.mjs +0 -56
  363. package/esm2022/src/validation-options.mjs +0 -78
  364. package/fesm2022/breeze-client-adapter-ajax-angularjs.mjs.map +0 -1
  365. package/fesm2022/breeze-client-adapter-ajax-fetch.mjs.map +0 -1
  366. package/fesm2022/breeze-client-adapter-ajax-httpclient.mjs.map +0 -1
  367. package/fesm2022/breeze-client-adapter-ajax-jquery.mjs.map +0 -1
  368. package/fesm2022/breeze-client-adapter-ajax-post.mjs.map +0 -1
  369. package/fesm2022/breeze-client-adapter-data-service-odata.mjs.map +0 -1
  370. package/fesm2022/breeze-client-adapter-data-service-webapi.mjs.map +0 -1
  371. package/fesm2022/breeze-client-adapter-model-library-backing-store.mjs.map +0 -1
  372. package/fesm2022/breeze-client-adapter-model-library-ko.mjs.map +0 -1
  373. package/fesm2022/breeze-client-adapter-uri-builder-json.mjs.map +0 -1
  374. package/fesm2022/breeze-client-adapter-uri-builder-odata.mjs.map +0 -1
  375. package/fesm2022/breeze-client-mixin-get-entity-graph.mjs.map +0 -1
  376. package/fesm2022/breeze-client-mixin-save-queuing.mjs.map +0 -1
  377. package/fesm2022/breeze-client.mjs.map +0 -1
@@ -0,0 +1,1042 @@
1
+ import { __extends, __read, __spread } from "tslib";
2
+ import { core } from './core';
3
+ import { assertParam } from './assert-param';
4
+ import { DataType } from './data-type';
5
+ import { EntityAspect } from './entity-aspect';
6
+ import { EntityKey } from './entity-key';
7
+ import { BreezeEnum } from './enum';
8
+ import { DataService } from './data-service';
9
+ import { EntityType } from './entity-metadata';
10
+ import { QueryOptions } from './query-options';
11
+ import { Predicate } from './predicate';
12
+ /**
13
+ An EntityQuery instance is used to query entities either from a remote datasource or from a local [[EntityManager]].
14
+
15
+ EntityQueries are immutable - this means that all EntityQuery methods that return an EntityQuery actually create a new EntityQuery. This means that
16
+ EntityQueries can be 'modified' without affecting any current instances.
17
+ @dynamic
18
+ **/
19
+ var EntityQuery = /** @class */ (function () {
20
+ /** Constructor
21
+ > let query = new EntityQuery("Customers")
22
+
23
+ Usually this constructor will be followed by calls to filtering, ordering or selection methods
24
+ > let query = new EntityQuery("Customers")
25
+ > .where("CompanyName", "startsWith", "C")
26
+ > .orderBy("Region");
27
+ @param resourceName - either a resource name or a serialized EntityQuery ( created by [[EntityQuery.toJSON]])
28
+ **/
29
+ function EntityQuery(resourceName) {
30
+ if (resourceName != null && (typeof resourceName !== 'string')) {
31
+ return fromJSON(this, resourceName);
32
+ }
33
+ // TODO: cast as string below needed for early versions of TypeDoc - but not for regular compile - check later
34
+ this.resourceName = resourceName;
35
+ this.fromEntityType = undefined;
36
+ this.wherePredicate = undefined;
37
+ this.orderByClause = undefined;
38
+ this.selectClause = undefined;
39
+ this.skipCount = undefined;
40
+ this.takeCount = undefined;
41
+ this.expandClause = undefined;
42
+ this.parameters = {};
43
+ this.inlineCountEnabled = false;
44
+ this.noTrackingEnabled = false;
45
+ this.usePostEnabled = false;
46
+ // default is to get queryOptions and dataService from the entityManager.
47
+ // this.queryOptions = new QueryOptions();
48
+ // this.dataService = new DataService();
49
+ this.entityManager = undefined;
50
+ }
51
+ /**
52
+ Specifies the resource to query for this EntityQuery.
53
+ > let query = new EntityQuery()
54
+ > .from("Customers");
55
+
56
+ is the same as
57
+ > let query = new EntityQuery("Customers");
58
+ @param resourceName - The resource to query.
59
+ **/
60
+ EntityQuery.prototype.from = function (resourceName) {
61
+ // TODO: think about allowing entityType as well
62
+ assertParam(resourceName, "resourceName").isString().check();
63
+ return clone(this, "resourceName", resourceName);
64
+ };
65
+ /**
66
+ This is a static version of the "from" method and it creates a 'base' entityQuery for the specified resource name.
67
+ > let query = EntityQuery.from("Customers");
68
+
69
+ is the same as
70
+ > let query = new EntityQuery("Customers");
71
+ @param resourceName - The resource to query.
72
+ **/
73
+ EntityQuery.from = function (resourceName) {
74
+ assertParam(resourceName, "resourceName").isString().check();
75
+ return new EntityQuery(resourceName);
76
+ };
77
+ /**
78
+ Specifies the top level EntityType that this query will return. Only needed when a query returns a json result that does not include type information,
79
+ or when using a resource name that is not associated to an EntityType.
80
+ > let query = new EntityQuery()
81
+ > .from("MyCustomMethod")
82
+ > .toType("Customer")
83
+ @param entityType - The top level EntityType that this query will return.
84
+ @summary If the json result consists of more than a simple entity or array of entities, consider using a [[JsonResultsAdapter]] instead.
85
+ **/
86
+ EntityQuery.prototype.toType = function (entityType) {
87
+ assertParam(entityType, "entityType").isString().or().isInstanceOf(EntityType).check();
88
+ return clone(this, "resultEntityType", entityType);
89
+ };
90
+ /**
91
+ Returns a new query with an added filter criteria; Can be called multiple times which means to 'and' with any existing
92
+ Predicate or can be called with null to clear all predicates.
93
+ > let query = new EntityQuery("Customers")
94
+ > .where("CompanyName", "startsWith", "C");
95
+
96
+ This can also be expressed using an explicit [[FilterQueryOp]] as
97
+ > let query = new EntityQuery("Customers")
98
+ > .where("CompanyName", FilterQueryOp.StartsWith, "C");
99
+
100
+ or a preconstructed [[Predicate]] may be used
101
+ > let pred = new Predicate("CompanyName", FilterQueryOp.StartsWith, "C");
102
+ > let query = new EntityQuery("Customers").where(pred);
103
+
104
+ Predicates are often useful when you want to combine multiple conditions in a single filter, such as
105
+ > let pred = Predicate.create("CompanyName", "startswith", "C").and("Region", FilterQueryOp.Equals, null);
106
+ > let query = new EntityQuery("Customers")
107
+ > .where(pred);
108
+
109
+ More complicated queries can make use of nested property paths
110
+ > let query = new EntityQuery("Products")
111
+ > .where("Category.CategoryName", "startswith", "S");
112
+
113
+ or OData functions - A list of valid OData functions can be found within the [[Predicate]] documentation.
114
+
115
+ > let query = new EntityQuery("Customers")
116
+ > .where("toLower(CompanyName)", "startsWith", "c");
117
+
118
+ or to be even more baroque
119
+ > let query = new EntityQuery("Customers")
120
+ > .where("toUpper(substring(CompanyName, 1, 2))", FilterQueryOp.Equals, "OM");
121
+ @param predicate - Can be either
122
+ - a single [[Predicate]]
123
+
124
+ - the parameters to create a 'simple' Predicate
125
+ - - a property name, a property path with '.' as path seperators or a property expression {String}
126
+ - - an operator - [[FilterQueryOp]] or it's string representation. Case is ignored
127
+ when if a string is provided and any string that matches one of the FilterQueryOp aliases will be accepted.
128
+ - - a value {Object} - This will be treated as either a property expression or a literal depending on context.
129
+ In general, if the value can be interpreted as a property expression it will be, otherwise it will be treated as a literal.
130
+ In most cases this works well, but you can also force the interpretation by making the value argument itself an object
131
+ with a 'value' property and an 'isLiteral' property set to either true or false.
132
+ Breeze also tries to infer the dataType of any literal based on context, if this fails you can force this inference by making the value argument
133
+ an object with a 'value' property and a 'dataType'property set to one of the DataType enumeration instances.
134
+
135
+ - a null or undefined ( this causes any existing where clause to be removed)
136
+ **/
137
+ EntityQuery.prototype.where = function () {
138
+ var args = [];
139
+ for (var _i = 0; _i < arguments.length; _i++) {
140
+ args[_i] = arguments[_i];
141
+ }
142
+ var wherePredicate;
143
+ if (args.length > 0 && args[0] != null) {
144
+ wherePredicate = Predicate.create.apply(Predicate, __spread(args));
145
+ if (this.fromEntityType)
146
+ wherePredicate._validate(this.fromEntityType);
147
+ if (this.wherePredicate) {
148
+ wherePredicate = this.wherePredicate.and(wherePredicate);
149
+ }
150
+ }
151
+ return clone(this, "wherePredicate", wherePredicate);
152
+ };
153
+ /**
154
+ Returns a new query that orders the results of the query by property name. By default sorting occurs is ascending order, but sorting in descending order is supported as well.
155
+ OrderBy clauses may be chained.
156
+ > let query = new EntityQuery("Customers")
157
+ > .orderBy("CompanyName");
158
+
159
+ or to sort across multiple properties
160
+ > let query = new EntityQuery("Customers")
161
+ > .orderBy("Region, CompanyName");
162
+
163
+ Nested property paths are also supported
164
+ > let query = new EntityQuery("Products")
165
+ > .orderBy("Category.CategoryName");
166
+
167
+ Sorting in descending order is supported via the addition of ' desc' to the end of any property path.
168
+ > let query = new EntityQuery("Customers")
169
+ > .orderBy("CompanyName desc");
170
+
171
+ or
172
+ > let query = new EntityQuery("Customers")
173
+ > .orderBy("Region desc, CompanyName desc");
174
+ @param propertyPaths - A comma-separated (',') string of property paths or an array of property paths.
175
+ Each property path can optionally end with " desc" to force a descending sort order. If 'propertyPaths' is either null or omitted then all ordering is removed.
176
+ @param isDescending - If specified, overrides all of the embedded 'desc' tags in the previously specified property paths.
177
+ **/
178
+ EntityQuery.prototype.orderBy = function (propertyPaths, isDescending) {
179
+ // propertyPaths: can pass in create("A.X,B") or create("A.X desc, B") or create("A.X desc,B", true])
180
+ // isDesc parameter trumps isDesc in propertyName.
181
+ var orderByClause = propertyPaths == null ? null : new OrderByClause(normalizePropertyPaths(propertyPaths), isDescending);
182
+ if (this.orderByClause && orderByClause) {
183
+ orderByClause = new OrderByClause([this.orderByClause, orderByClause]);
184
+ }
185
+ return clone(this, "orderByClause", orderByClause);
186
+ };
187
+ /**
188
+ Returns a new query that orders the results of the query by property name in descending order.
189
+ > let query = new EntityQuery("Customers")
190
+ > .orderByDesc("CompanyName");
191
+
192
+ or to sort across multiple properties
193
+ > let query = new EntityQuery("Customers")
194
+ > .orderByDesc("Region, CompanyName");
195
+
196
+ Nested property paths are also supported
197
+ > let query = new EntityQuery("Products")
198
+ > .orderByDesc("Category.CategoryName");
199
+ @param propertyPaths - A comma-separated (',') string of property paths or an array of property paths.
200
+ If 'propertyPaths' is either null or omitted then all ordering is removed.
201
+ **/
202
+ EntityQuery.prototype.orderByDesc = function (propertyPaths) {
203
+ return this.orderBy(propertyPaths, true);
204
+ };
205
+ /**
206
+ Returns a new query that selects a list of properties from the results of the original query and returns the values of just these properties. This
207
+ will be referred to as a projection.
208
+ If the result of this selection "projection" contains entities, these entities will automatically be added to EntityManager's cache and will
209
+ be made 'observable'.
210
+ Any simple properties, i.e. strings, numbers or dates within a projection will not be cached are will NOT be made 'observable'.
211
+
212
+ Simple data properties can be projected
213
+ > let query = new EntityQuery("Customers")
214
+ > .where("CompanyName", "startsWith", "C")
215
+ > .select("CompanyName");
216
+
217
+ This will return an array of objects each with a single "CompanyName" property of type string.
218
+ A similar query could return a navigation property instead
219
+ > let query = new EntityQuery("Customers")
220
+ > .where("CompanyName", "startsWith", "C")
221
+ > .select("Orders");
222
+
223
+ where the result would be an array of objects each with a single "Orders" property that would itself be an array of "Order" entities.
224
+ Composite projections are also possible:
225
+ > let query = new EntityQuery("Customers")
226
+ > .where("CompanyName", "startsWith", "C")
227
+ > .select("CompanyName, Orders");
228
+
229
+ As well as projections involving nested property paths
230
+ > let query = EntityQuery("Orders")
231
+ > .where("Customer.CompanyName", "startsWith", "C")
232
+ > .select("Customer.CompanyName, Customer, OrderDate");
233
+ @param propertyPaths - A comma-separated (',') string of property paths or an array of property paths.
234
+ If 'propertyPaths' is either null or omitted then any existing projection on the query is removed.
235
+ **/
236
+ EntityQuery.prototype.select = function (propertyPaths) {
237
+ var selectClause = propertyPaths == null ? null : new SelectClause(normalizePropertyPaths(propertyPaths));
238
+ return clone(this, "selectClause", selectClause);
239
+ };
240
+ /**
241
+ Returns a new query that skips the specified number of entities when returning results.
242
+ Any existing 'skip' can be cleared by calling 'skip' with no arguments.
243
+ > let query = new EntityQuery("Customers")
244
+ > .where("CompanyName", "startsWith", "C")
245
+ > .skip(5);
246
+ @param count - The number of entities to skip over. If omitted or null any existing skip count on the query is removed.
247
+ **/
248
+ EntityQuery.prototype.skip = function (count) {
249
+ assertParam(count, "count").isOptional().isNumber().check();
250
+ return clone(this, "skipCount", (count == null) ? null : count);
251
+ };
252
+ /**
253
+ Returns a new query that returns only the specified number of entities when returning results. - Same as 'take'.
254
+ Any existing 'top' can be cleared by calling 'top' with no arguments.
255
+ > let query = new EntityQuery("Customers")
256
+ > .top(5);
257
+ @param count - The number of entities to return.
258
+ If 'count' is either null or omitted then any existing 'top' count on the query is removed.
259
+ **/
260
+ EntityQuery.prototype.top = function (count) {
261
+ return this.take(count);
262
+ };
263
+ /**
264
+ Returns a new query that returns only the specified number of entities when returning results - Same as 'top'.
265
+ Any existing take can be cleared by calling take with no arguments.
266
+ > let query = new EntityQuery("Customers")
267
+ > .take(5);
268
+ @param count - The number of entities to return.
269
+ If 'count' is either null or omitted then any existing 'take' count on the query is removed.
270
+ **/
271
+ EntityQuery.prototype.take = function (count) {
272
+ assertParam(count, "count").isOptional().isNumber().check();
273
+ return clone(this, "takeCount", (count == null) ? null : count);
274
+ };
275
+ /**
276
+ Returns a new query that will return related entities nested within its results. The expand method allows you to identify related entities, via navigation property
277
+ names such that a graph of entities may be retrieved with a single request. Any filtering occurs before the results are 'expanded'.
278
+ > let query = new EntityQuery("Customers")
279
+ > .where("CompanyName", "startsWith", "C")
280
+ > .expand("Orders");
281
+
282
+ will return the filtered customers each with its "Orders" properties fully resolved.
283
+ Multiple paths may be specified by separating the paths by a ','
284
+ > let query = new EntityQuery("Orders")
285
+ > .expand("Customer, Employee")
286
+
287
+ and nested property paths my be specified as well
288
+ > let query = new EntityQuery("Orders")
289
+ > .expand("Customer, OrderDetails, OrderDetails.Product")
290
+ @param propertyPaths - A comma-separated list of navigation property names or an array of navigation property names. Each Navigation Property name can be followed
291
+ by a '.' and another navigation property name to enable identifying a multi-level relationship.
292
+ If 'propertyPaths' is either null or omitted then any existing 'expand' clause on the query is removed.
293
+ **/
294
+ EntityQuery.prototype.expand = function (propertyPaths) {
295
+ var expandClause = propertyPaths == null ? null : new ExpandClause(normalizePropertyPaths(propertyPaths));
296
+ return clone(this, "expandClause", expandClause);
297
+ };
298
+ /**
299
+ Returns a new query that includes a collection of parameters to pass to the server.
300
+ > let query = EntityQuery.from("EmployeesFilteredByCountryAndBirthdate")
301
+ > .withParameters({ BirthDate: "1/1/1960", Country: "USA" });
302
+
303
+ will call the 'EmployeesFilteredByCountryAndBirthdate' method on the server and pass in 2 parameters. This
304
+ query will be uri encoded as
305
+ > {serviceApi}/EmployeesFilteredByCountryAndBirthdate?birthDate=1%2F1%2F1960&country=USA
306
+
307
+ Parameters may also be mixed in with other query criteria.
308
+ > let query = EntityQuery.from("EmployeesFilteredByCountryAndBirthdate")
309
+ > .withParameters({ BirthDate: "1/1/1960", Country: "USA" })
310
+ > .where("LastName", "startsWith", "S")
311
+ > .orderBy("BirthDate");
312
+ @param parameters - A parameters object where the keys are the parameter names and the values are the parameter values.
313
+ **/
314
+ EntityQuery.prototype.withParameters = function (parameters) {
315
+ assertParam(parameters, "parameters").isObject().check();
316
+ return clone(this, "parameters", parameters);
317
+ };
318
+ /**
319
+ Returns a query with the `inlineCount` capability either enabled or disabled. With `inlineCount` enabled, an additional 'inlineCount' property
320
+ will be returned with the query results that will contain the number of entities that would have been returned by this
321
+ query with only the 'where'/'filter' clauses applied, i.e. without any 'skip'/'take' operators applied. For local queries this clause is ignored.
322
+ > let query = new EntityQuery("Customers")
323
+ > .take(20)
324
+ > .orderBy("CompanyName")
325
+ > .inlineCount(true);
326
+
327
+ will return the first 20 customers as well as a count of _all_ of the customers in the remote store.
328
+ @param enabled - (default = true) Whether or not inlineCount capability should be enabled. If this parameter is omitted, true is assumed.
329
+ **/
330
+ EntityQuery.prototype.inlineCount = function (enabled) {
331
+ assertParam(enabled, "enabled").isBoolean().isOptional().check();
332
+ enabled = (enabled === undefined) ? true : !!enabled;
333
+ return clone(this, "inlineCountEnabled", enabled);
334
+ };
335
+ EntityQuery.prototype.useNameOnServer = function (usesNameOnServer) {
336
+ assertParam(usesNameOnServer, "usesNameOnServer").isBoolean().isOptional().check();
337
+ usesNameOnServer = (usesNameOnServer === undefined) ? true : !!usesNameOnServer;
338
+ return clone(this, "usesNameOnServer", usesNameOnServer);
339
+ };
340
+ /**
341
+ Returns a query with the `noTracking` capability either enabled or disabled. With `noTracking` enabled, the results of this query
342
+ will not be coerced into entities but will instead look like raw javascript projections. i.e. simple javascript objects.
343
+ > let query = new EntityQuery("Customers")
344
+ > .take(20)
345
+ > .orderBy("CompanyName")
346
+ > .noTracking(true);
347
+ @param enabled - (default = true) Whether or not the noTracking capability should be enabled. If this parameter is omitted, true is assumed.
348
+ **/
349
+ EntityQuery.prototype.noTracking = function (enabled) {
350
+ assertParam(enabled, "enabled").isBoolean().isOptional().check();
351
+ enabled = (enabled === undefined) ? true : !!enabled;
352
+ return clone(this, "noTrackingEnabled", enabled);
353
+ };
354
+ /**
355
+ Returns a query with the `usePost` capability either enabled or disabled. With `usePost` enabled, the query is sent
356
+ as a POST request (instead of GET) and the query expression will be sent as JSON in the body of the post.
357
+ Note that the server must be able to parse the body of the request; otherwise the query expression will be ignored.
358
+ > let query = new EntityQuery("Customers")
359
+ > .where("companyId", "eq", 1)
360
+ > .usePost(true);
361
+ results in a POST request to `{host}/{path}/Customers`
362
+ with body `{"where": {"companyId":{"eq":1}}}`
363
+ @param enabled - (default = true) Whether or not usePost should be enabled. If this parameter is omitted, true is assumed.
364
+ **/
365
+ EntityQuery.prototype.usePost = function (enabled) {
366
+ assertParam(enabled, "enabled").isBoolean().isOptional().check();
367
+ enabled = (enabled === undefined) ? true : !!enabled;
368
+ return clone(this, "usePostEnabled", enabled);
369
+ };
370
+ /**
371
+ Returns a copy of this EntityQuery with the specified [[EntityManager]], [[DataService]],
372
+ [[JsonResultsAdapter]], [[MergeStrategy]] or [[FetchStrategy]] applied.
373
+ > // 'using' can be used to return a new query with a specified EntityManager.
374
+ > let em = new EntityManager(serviceName);
375
+ > let query = new EntityQuery("Orders")
376
+ > .using(em);
377
+
378
+ or with a specified [[MergeStrategy]]
379
+ > let em = new EntityManager(serviceName);
380
+ > let query = new EntityQuery("Orders")
381
+ > .using(MergeStrategy.PreserveChanges);
382
+
383
+ or with a specified [[FetchStrategy]]
384
+ > let em = new EntityManager(serviceName);
385
+ > let query = new EntityQuery("Orders")
386
+ > .using(FetchStrategy.FromLocalCache);
387
+ @param obj - The object to update in creating a new EntityQuery from an existing one.
388
+ **/
389
+ EntityQuery.prototype.using = function (obj) {
390
+ if (!obj)
391
+ return this;
392
+ var eq = clone(this);
393
+ processUsing(eq, {
394
+ "entityManager": null,
395
+ "dataService": null,
396
+ "queryOptions": null,
397
+ "fetchStrategy": function (eq, val) {
398
+ eq.queryOptions = (eq.queryOptions || new QueryOptions()).using(val);
399
+ },
400
+ "mergeStrategy": function (eq, val) {
401
+ eq.queryOptions = (eq.queryOptions || new QueryOptions()).using(val);
402
+ },
403
+ "jsonResultsAdapter": function (eq, val) {
404
+ eq.dataService = (eq.dataService || new DataService()).using({ jsonResultsAdapter: val });
405
+ }
406
+ }, obj);
407
+ return eq;
408
+ };
409
+ /**
410
+ Executes this query. This method requires that an EntityManager has been previously specified via the "using" method.
411
+
412
+ This method can be called using a 'promises' syntax ( recommended)
413
+ > let em = new EntityManager(serviceName);
414
+ > let query = new EntityQuery("Orders").using(em);
415
+ > query.execute().then( function(data) {
416
+ > ... query results processed here
417
+ > }).catch( function(err) {
418
+ > ... query failure processed here
419
+ > });
420
+
421
+ or with callbacks
422
+ > let em = new EntityManager(serviceName);
423
+ > let query = new EntityQuery("Orders").using(em);
424
+ > query.execute(
425
+ > function(data) {
426
+ > let orders = data.results;
427
+ > ... query results processed here
428
+ > },
429
+ > function(err) {
430
+ > ... query failure processed here
431
+ > });
432
+
433
+ Either way this method is the same as calling the EntityManager 'execute' method.
434
+ > let em = new EntityManager(serviceName);
435
+ > let query = new EntityQuery("Orders");
436
+ > em.executeQuery(query).then( function(data) {
437
+ > let orders = data.results;
438
+ > ... query results processed here
439
+ > }).catch( function(err) {
440
+ > ... query failure processed here
441
+ > });
442
+
443
+ @param callback - Function called on success.
444
+ @param errorCallback - Function called on failure.
445
+ @return Promise
446
+ **/
447
+ EntityQuery.prototype.execute = function (callback, errorCallback) {
448
+ if (!this.entityManager) {
449
+ throw new Error("An EntityQuery must have its EntityManager property set before calling 'execute'");
450
+ }
451
+ return this.entityManager.executeQuery(this, callback, errorCallback);
452
+ };
453
+ /**
454
+ Executes this query against the local cache. This method requires that an EntityManager have been previously specified via the "using" method.
455
+ > // assume em is an entityManager already filled with order entities;
456
+ > let query = new EntityQuery("Orders").using(em);
457
+ > let orders = query.executeLocally();
458
+
459
+ Note that calling this method is the same as calling [[EntityManager.executeQueryLocally]].
460
+ **/
461
+ EntityQuery.prototype.executeLocally = function () {
462
+ if (!this.entityManager) {
463
+ throw new Error("An EntityQuery must have its EntityManager property set before calling 'executeLocally'");
464
+ }
465
+ return this.entityManager.executeQueryLocally(this);
466
+ };
467
+ EntityQuery.prototype.toJSON = function () {
468
+ return this.toJSONExt();
469
+ };
470
+ /** Typically only for use when building UriBuilderAdapters.
471
+ @hidden @internal
472
+ */
473
+ EntityQuery.prototype.toJSONExt = function (context) {
474
+ context = context || {};
475
+ context.entityType = context.entityType || this.fromEntityType;
476
+ context.propertyPathFn = context.toNameOnServer ? context.entityType.clientPropertyPathToServer.bind(context.entityType) : core.identity;
477
+ var toJSONExtFn = function (v) {
478
+ return v ? v.toJSONExt(context) : undefined;
479
+ };
480
+ return core.toJson(this, {
481
+ "from,resourceName": null,
482
+ "toType,resultEntityType": function (v) {
483
+ // resultEntityType can be either a string or an entityType
484
+ return v ? (typeof v === 'string' ? v : v.name) : undefined;
485
+ },
486
+ "where,wherePredicate": toJSONExtFn,
487
+ "orderBy,orderByClause": toJSONExtFn,
488
+ "select,selectClause": toJSONExtFn,
489
+ "expand,expandClause": toJSONExtFn,
490
+ "skip,skipCount": null,
491
+ "take,takeCount": null,
492
+ parameters: function (v) {
493
+ return core.isEmpty(v) ? undefined : v;
494
+ },
495
+ "inlineCount,inlineCountEnabled": false,
496
+ "noTracking,noTrackingEnabled": false,
497
+ queryOptions: null
498
+ });
499
+ };
500
+ /**
501
+ Static method that creates an EntityQuery that will allow 'requerying' an entity or a collection of entities by primary key. This can be useful
502
+ to force a requery of selected entities, or to restrict an existing collection of entities according to some filter.
503
+
504
+ Works for a single entity or an array of entities of the SAME type.
505
+ Does not work for an array of entities of different types.
506
+ > // assuming 'customers' is an array of 'Customer' entities retrieved earlier.
507
+ > let customersQuery = EntityQuery.fromEntities(customers);
508
+
509
+ The resulting query can, of course, be extended
510
+ > // assuming 'customers' is an array of 'Customer' entities retrieved earlier.
511
+ > let customersQuery = EntityQuery.fromEntities(customers)
512
+ > .where("Region", FilterQueryOp.NotEquals, null);
513
+
514
+ Single entities can requeried as well.
515
+ > // assuming 'customer' is a 'Customer' entity retrieved earlier.
516
+ > let customerQuery = EntityQuery.fromEntities(customer);
517
+
518
+ will create a query that will return an array containing a single customer entity.
519
+ @param entities - The entities for which we want to create an EntityQuery.
520
+ **/
521
+ EntityQuery.fromEntities = function (entities) {
522
+ assertParam(entities, "entities").isEntity().or().isNonEmptyArray().isEntity().check();
523
+ var ents = (Array.isArray(entities)) ? entities : [entities];
524
+ var firstEntity = ents[0];
525
+ var type = firstEntity.entityType;
526
+ if (ents.some(function (e) {
527
+ return e.entityType !== type;
528
+ })) {
529
+ throw new Error("All 'fromEntities' must be the same type; at least one is not of type " +
530
+ type.name);
531
+ }
532
+ var q = new EntityQuery(type.defaultResourceName);
533
+ var preds = ents.map(function (entity) {
534
+ return buildPredicate(entity);
535
+ });
536
+ var pred = Predicate.or(preds);
537
+ q = q.where(pred);
538
+ var em = firstEntity.entityAspect.entityManager;
539
+ if (em) {
540
+ q = q.using(em);
541
+ }
542
+ return q;
543
+ };
544
+ /**
545
+ Creates an EntityQuery for the specified [[EntityKey]].
546
+ > let empType = metadataStore.getEntityType("Employee");
547
+ > let entityKey = new EntityKey(empType, 1);
548
+ > let query = EntityQuery.fromEntityKey(entityKey);
549
+
550
+ or
551
+ > // 'employee' is a previously queried employee
552
+ > let entityKey = employee.entityAspect.getKey();
553
+ > let query = EntityQuery.fromEntityKey(entityKey);
554
+ @param entityKey - The [[EntityKey]] for which a query will be created.
555
+ **/
556
+ EntityQuery.fromEntityKey = function (entityKey) {
557
+ assertParam(entityKey, "entityKey").isInstanceOf(EntityKey).check();
558
+ var q = new EntityQuery(entityKey.entityType.defaultResourceName);
559
+ var pred = buildKeyPredicate(entityKey);
560
+ q = q.where(pred).toType(entityKey.entityType);
561
+ return q;
562
+ };
563
+ // protected methods
564
+ /** @hidden @internal */
565
+ EntityQuery.prototype._getFromEntityType = function (metadataStore, throwErrorIfNotFound) {
566
+ // Uncomment next two lines if we make this method public.
567
+ // assertParam(metadataStore, "metadataStore").isInstanceOf(MetadataStore).check();
568
+ // assertParam(throwErrorIfNotFound, "throwErrorIfNotFound").isBoolean().isOptional().check();
569
+ var entityType = this.fromEntityType;
570
+ if (entityType)
571
+ return entityType;
572
+ var resourceName = this.resourceName;
573
+ if (!resourceName) {
574
+ throw new Error("There is no resourceName for this query");
575
+ }
576
+ if (metadataStore.isEmpty()) {
577
+ if (throwErrorIfNotFound) {
578
+ throw new Error("There is no metadata available for this query. " +
579
+ "Are you querying the local cache before you've fetched metadata?");
580
+ }
581
+ else {
582
+ return undefined;
583
+ }
584
+ }
585
+ var entityTypeName = metadataStore.getEntityTypeNameForResourceName(resourceName);
586
+ if (entityTypeName) {
587
+ entityType = metadataStore._getStructuralType(entityTypeName);
588
+ }
589
+ else {
590
+ entityType = this._getToEntityType(metadataStore, true);
591
+ }
592
+ if (!entityType) {
593
+ if (throwErrorIfNotFound) {
594
+ throw new Error(core.formatString("Cannot find an entityType for resourceName: '%1'. ", resourceName) + core.strings.TO_TYPE);
595
+ }
596
+ else {
597
+ return undefined;
598
+ }
599
+ }
600
+ this.fromEntityType = entityType;
601
+ return entityType;
602
+ };
603
+ /** @hidden @internal */
604
+ EntityQuery.prototype._getToEntityType = function (metadataStore, skipFromCheck) {
605
+ // skipFromCheck is to avoid recursion if called from _getFromEntityType;
606
+ if (this.resultEntityType instanceof EntityType) {
607
+ return this.resultEntityType;
608
+ }
609
+ else if (this.resultEntityType) {
610
+ // resultEntityType is a string
611
+ this.resultEntityType = metadataStore._getStructuralType(this.resultEntityType, false);
612
+ return this.resultEntityType;
613
+ }
614
+ else {
615
+ // resolve it, if possible, via the resourceName
616
+ // do not cache this value in this case
617
+ // cannot determine the resultEntityType if a selectClause is present.
618
+ // return skipFromCheck ? null : (!this.selectClause) && this._getFromEntityType(metadataStore, false);
619
+ if (skipFromCheck || this.selectClause) {
620
+ return undefined;
621
+ }
622
+ else {
623
+ this._getFromEntityType(metadataStore, false);
624
+ }
625
+ }
626
+ };
627
+ /** @hidden @internal */
628
+ // for testing
629
+ EntityQuery.prototype._toUri = function (em) {
630
+ var ds = DataService.resolve([em.dataService]);
631
+ return ds.uriBuilder.buildUri(this, em.metadataStore);
632
+ };
633
+ /**
634
+ Creates an EntityQuery for the specified entity and [[NavigationProperty]].
635
+ > // 'employee' is a previously queried employee
636
+ > let ordersNavProp = employee.entityType.getProperty("Orders");
637
+ > let query = EntityQuery.fromEntityNavigation(employee, ordersNavProp);
638
+
639
+ will return a query for the "Orders" of the specified 'employee'.
640
+ @param entity - The Entity whose navigation property will be queried.
641
+ @param navigationProperty - The [[NavigationProperty]] or name of the NavigationProperty to be queried.
642
+ **/
643
+ EntityQuery.fromEntityNavigation = function (entity, navigationProperty) {
644
+ assertParam(entity, "entity").isEntity().check();
645
+ var navProperty = entity.entityType._checkNavProperty(navigationProperty);
646
+ var q = new EntityQuery(navProperty.entityType.defaultResourceName);
647
+ var pred = buildNavigationPredicate(entity, navProperty);
648
+ if (pred == null) {
649
+ throw new Error("Unable to create a NavigationQuery for navigationProperty: " + navProperty.name);
650
+ }
651
+ q = q.where(pred);
652
+ var em = entity.entityAspect.entityManager;
653
+ return em ? q.using(em) : q;
654
+ };
655
+ return EntityQuery;
656
+ }());
657
+ export { EntityQuery };
658
+ EntityQuery.prototype._$typeName = "EntityQuery";
659
+ // private functions
660
+ function fromJSON(eq, json) {
661
+ core.toJson(json, {
662
+ "resourceName,from": null,
663
+ // just the name comes back and will be resolved later
664
+ "resultEntityType,toType": null,
665
+ "wherePredicate,where": function (v) {
666
+ return v ? new Predicate(v) : undefined;
667
+ },
668
+ "orderByClause,orderBy": function (v) {
669
+ return v ? new OrderByClause(v) : undefined;
670
+ },
671
+ "selectClause,select": function (v) {
672
+ return v ? new SelectClause(v) : undefined;
673
+ },
674
+ "expandClause,expand": function (v) {
675
+ return v ? new ExpandClause(v) : undefined;
676
+ },
677
+ "skipCount,skip": null,
678
+ "takeCount,take": null,
679
+ parameters: function (v) {
680
+ return core.isEmpty(v) ? undefined : v;
681
+ },
682
+ "inlineCountEnabled,inlineCount": false,
683
+ "noTrackingEnabled,noTracking": false,
684
+ "usePostEnabled,usePost": false,
685
+ queryOptions: function (v) {
686
+ return v ? QueryOptions.fromJSON(v) : undefined;
687
+ }
688
+ }, eq);
689
+ return eq;
690
+ }
691
+ function clone(eq, propName, value) {
692
+ // immutable queries mean that we don't need to clone if no change in value.
693
+ if (propName) {
694
+ if (eq[propName] === value)
695
+ return eq;
696
+ }
697
+ // copying QueryOptions is safe because they are are immutable;
698
+ var copy = core.extend(new EntityQuery(), eq, [
699
+ "resourceName",
700
+ "fromEntityType",
701
+ "wherePredicate",
702
+ "orderByClause",
703
+ "selectClause",
704
+ "skipCount",
705
+ "takeCount",
706
+ "expandClause",
707
+ "inlineCountEnabled",
708
+ "noTrackingEnabled",
709
+ "usePostEnabled",
710
+ "usesNameOnServer",
711
+ "queryOptions",
712
+ "entityManager",
713
+ "dataService",
714
+ "resultEntityType"
715
+ ]);
716
+ copy.parameters = core.extend({}, eq.parameters);
717
+ if (propName) {
718
+ copy[propName] = value;
719
+ }
720
+ return copy;
721
+ }
722
+ function processUsing(eq, map, value, propertyName) {
723
+ var typeName = value._$typeName || ((value instanceof BreezeEnum) && value.constructor.name);
724
+ var key = typeName && typeName.substr(0, 1).toLowerCase() + typeName.substr(1);
725
+ if (propertyName && key !== propertyName) {
726
+ throw new Error("Invalid value for property: " + propertyName);
727
+ }
728
+ if (key) {
729
+ var fn = map[key];
730
+ if (fn === undefined) {
731
+ throw new Error("Invalid config property: " + key);
732
+ }
733
+ else if (fn === null) {
734
+ eq[key] = value;
735
+ }
736
+ else {
737
+ fn(eq, value);
738
+ }
739
+ }
740
+ else {
741
+ core.objectForEach(value, function (propName, val) {
742
+ processUsing(eq, map, val, propName);
743
+ });
744
+ }
745
+ }
746
+ function normalizePropertyPaths(propertyPaths) {
747
+ assertParam(propertyPaths, "propertyPaths").isOptional().isString().or().isArray().isString().check();
748
+ if (typeof propertyPaths === 'string') {
749
+ propertyPaths = propertyPaths.split(",");
750
+ }
751
+ propertyPaths = propertyPaths.map(function (pp) {
752
+ return pp.trim();
753
+ });
754
+ return propertyPaths;
755
+ }
756
+ function buildPredicate(entity) {
757
+ var entityType = entity.entityType;
758
+ var predParts = entityType.keyProperties.map(function (kp) {
759
+ return Predicate.create(kp.name, FilterQueryOp.Equals, entity.getProperty(kp.name));
760
+ });
761
+ var pred = Predicate.and(predParts);
762
+ return pred;
763
+ }
764
+ function buildKeyPredicate(entityKey) {
765
+ var keyProps = entityKey.entityType.keyProperties;
766
+ var preds = core.arrayZip(keyProps, entityKey.values, function (kp, v) {
767
+ return Predicate.create(kp.name, FilterQueryOp.Equals, v);
768
+ });
769
+ var pred = Predicate.and(preds);
770
+ return pred;
771
+ }
772
+ function buildNavigationPredicate(entity, navigationProperty) {
773
+ if (navigationProperty.isScalar) {
774
+ if (navigationProperty.foreignKeyNames.length === 0)
775
+ return null;
776
+ var relatedKeyValues = navigationProperty.foreignKeyNames.map(function (fkName) {
777
+ return entity.getProperty(fkName);
778
+ });
779
+ var entityKey = new EntityKey(navigationProperty.entityType, relatedKeyValues);
780
+ return buildKeyPredicate(entityKey);
781
+ }
782
+ else {
783
+ var inverseNp = navigationProperty.inverse;
784
+ var foreignKeyNames = inverseNp ? inverseNp.foreignKeyNames : navigationProperty.invForeignKeyNames;
785
+ if (foreignKeyNames.length === 0)
786
+ return null;
787
+ var keyValues = entity.entityAspect.getKey().values;
788
+ var predParts = core.arrayZip(foreignKeyNames, keyValues, function (fkName, kv) {
789
+ return Predicate.create(fkName, FilterQueryOp.Equals, kv);
790
+ });
791
+ return Predicate.and(predParts);
792
+ }
793
+ }
794
+ /**
795
+ FilterQueryOp is an 'Enum' containing all of the valid [[Predicate]]
796
+ filter operators for an [[EntityQuery]].
797
+ **/
798
+ var FilterQueryOp = /** @class */ (function (_super) {
799
+ __extends(FilterQueryOp, _super);
800
+ function FilterQueryOp() {
801
+ return _super !== null && _super.apply(this, arguments) || this;
802
+ }
803
+ /** Aliases: "eq", "==" **/
804
+ FilterQueryOp.Equals = new FilterQueryOp({ operator: "eq" });
805
+ /** Aliases: "ne", "!=" **/
806
+ FilterQueryOp.NotEquals = new FilterQueryOp({ operator: "ne" });
807
+ /** Aliases: "gt", ">" **/
808
+ FilterQueryOp.GreaterThan = new FilterQueryOp({ operator: "gt" });
809
+ /** Aliases: "lt", "<" **/
810
+ FilterQueryOp.LessThan = new FilterQueryOp({ operator: "lt" });
811
+ /** Aliases: "ge", ">=" **/
812
+ FilterQueryOp.GreaterThanOrEqual = new FilterQueryOp({ operator: "ge" });
813
+ /** Aliases: "le", "<=" **/
814
+ FilterQueryOp.LessThanOrEqual = new FilterQueryOp({ operator: "le" });
815
+ /** String operation: Is a string a substring of another string. Aliases: "substringof" **/
816
+ FilterQueryOp.Contains = new FilterQueryOp({ operator: "contains" });
817
+ /** No aliases */
818
+ FilterQueryOp.StartsWith = new FilterQueryOp({ operator: "startswith" });
819
+ /** No aliases */
820
+ FilterQueryOp.EndsWith = new FilterQueryOp({ operator: "endswith" });
821
+ /** Aliases: "some" **/
822
+ FilterQueryOp.Any = new FilterQueryOp({ operator: "any" });
823
+ /** Aliases: "every" **/
824
+ FilterQueryOp.All = new FilterQueryOp({ operator: "all" });
825
+ /** No aliases */
826
+ FilterQueryOp.In = new FilterQueryOp({ operator: "in" });
827
+ /** No aliases */
828
+ FilterQueryOp.IsTypeOf = new FilterQueryOp({ operator: "isof" });
829
+ return FilterQueryOp;
830
+ }(BreezeEnum));
831
+ export { FilterQueryOp };
832
+ FilterQueryOp.prototype._$typeName = "FilterQueryOp";
833
+ Error['x'] = FilterQueryOp.resolveSymbols();
834
+ /**
835
+ BooleanQueryOp is an 'Enum' containing all of the valid boolean
836
+ operators for an [[EntityQuery]].
837
+ **/
838
+ var BooleanQueryOp = /** @class */ (function (_super) {
839
+ __extends(BooleanQueryOp, _super);
840
+ function BooleanQueryOp() {
841
+ return _super !== null && _super.apply(this, arguments) || this;
842
+ }
843
+ BooleanQueryOp.And = new BooleanQueryOp({ operator: "and" });
844
+ BooleanQueryOp.Or = new BooleanQueryOp({ operator: "or" });
845
+ BooleanQueryOp.Not = new BooleanQueryOp({ operator: "not" });
846
+ return BooleanQueryOp;
847
+ }(BreezeEnum));
848
+ export { BooleanQueryOp };
849
+ BooleanQueryOp.prototype._$typeName = "BooleanQueryOp";
850
+ Error['x'] = BooleanQueryOp.resolveSymbols();
851
+ /** For use by breeze plugin authors only. The class is used in most [[IUriBuilderAdapter]] implementations
852
+ @adapter (see [[IUriBuilderAdapter]])
853
+ @hidden
854
+
855
+ An OrderByClause is a description of the properties and direction that the result
856
+ of a query should be sorted in. OrderByClauses are immutable, which means that any
857
+ method that would modify an OrderByClause actually returns a new OrderByClause.
858
+
859
+ For example for an Employee object with properties of 'Company' and 'LastName' the following would be valid expressions:
860
+ > let obc = new OrderByClause("Company.CompanyName, LastName")
861
+
862
+ or
863
+ > let obc = new OrderByClause("Company.CompanyName desc, LastName")
864
+
865
+ or
866
+ > let obc = new OrderByClause("Company.CompanyName, LastName", true);
867
+ */
868
+ var OrderByClause = /** @class */ (function () {
869
+ function OrderByClause(propertyPaths, isDesc) {
870
+ if (propertyPaths.length === 0) {
871
+ throw new Error("OrderByClause cannot be empty");
872
+ }
873
+ // you can also pass in an array of orderByClauses
874
+ if (propertyPaths[0] instanceof OrderByClause) {
875
+ var clauses = propertyPaths;
876
+ this.items = core.arrayFlatMap(clauses, function (c) { return c.items; });
877
+ // this.items = Array.prototype.concat.apply(clauses[0].items, clauses.slice(1).map(core.pluck("items")));
878
+ // this.items = Array.prototype.concat.apply([], clauses.map(core.pluck("items")));
879
+ }
880
+ else {
881
+ this.items = propertyPaths.map(function (pp) {
882
+ return new OrderByItem(pp, isDesc);
883
+ });
884
+ }
885
+ }
886
+ OrderByClause.prototype.validate = function (entityType) {
887
+ if (entityType == null || entityType.isAnonymous)
888
+ return;
889
+ this.items.forEach(function (item) {
890
+ item.validate(entityType);
891
+ });
892
+ };
893
+ OrderByClause.prototype.getComparer = function (entityType) {
894
+ var orderByFuncs = this.items.map(function (obc) {
895
+ return obc.getComparer(entityType);
896
+ });
897
+ return function (entity1, entity2) {
898
+ for (var i = 0; i < orderByFuncs.length; i++) {
899
+ var result = orderByFuncs[i](entity1, entity2);
900
+ if (result !== 0) {
901
+ return result;
902
+ }
903
+ }
904
+ return 0;
905
+ };
906
+ };
907
+ OrderByClause.prototype.toJSONExt = function (context) {
908
+ return this.items.map(function (item) {
909
+ return context.propertyPathFn(item.propertyPath) + (item.isDesc ? " desc" : "");
910
+ });
911
+ };
912
+ return OrderByClause;
913
+ }());
914
+ export { OrderByClause };
915
+ /** @hidden @internal */
916
+ var OrderByItem = /** @class */ (function () {
917
+ function OrderByItem(propertyPath, isDesc) {
918
+ if (!(typeof propertyPath === 'string')) {
919
+ throw new Error("propertyPath is not a string");
920
+ }
921
+ propertyPath = propertyPath.trim();
922
+ var parts = propertyPath.split(' ');
923
+ // parts[0] is the propertyPath; [1] would be whether descending or not.
924
+ // if (parts.length > 1 && isDesc !== true && isDesc !== false) {
925
+ if (parts.length > 1 && isDesc == null) {
926
+ isDesc = core.stringStartsWith(parts[1].toLowerCase(), "desc");
927
+ if (!isDesc) {
928
+ // isDesc is false but check to make sure its intended.
929
+ var isAsc = core.stringStartsWith(parts[1].toLowerCase(), "asc");
930
+ if (!isAsc) {
931
+ throw new Error("the second word in the propertyPath must begin with 'desc' or 'asc'");
932
+ }
933
+ }
934
+ }
935
+ this.propertyPath = parts[0];
936
+ this.isDesc = isDesc || false;
937
+ }
938
+ OrderByItem.prototype.validate = function (entityType) {
939
+ if (entityType == null || entityType.isAnonymous)
940
+ return;
941
+ // will throw an exception on bad propertyPath
942
+ this.lastProperty = entityType.getProperty(this.propertyPath, true);
943
+ return this.lastProperty;
944
+ };
945
+ OrderByItem.prototype.getComparer = function (entityType) {
946
+ var propDataType;
947
+ var isCaseSensitive;
948
+ if (!this.lastProperty)
949
+ this.validate(entityType);
950
+ if (this.lastProperty) {
951
+ propDataType = this.lastProperty.dataType;
952
+ isCaseSensitive = this.lastProperty.parentType.metadataStore.localQueryComparisonOptions.isCaseSensitive;
953
+ }
954
+ var propertyPath = this.propertyPath;
955
+ var isDesc = this.isDesc;
956
+ return function (entity1, entity2) {
957
+ var value1 = EntityAspect.getPropertyPathValue(entity1, propertyPath);
958
+ var value2 = EntityAspect.getPropertyPathValue(entity2, propertyPath);
959
+ var dataType = propDataType || (value1 && DataType.fromValue(value1)) || DataType.fromValue(value2);
960
+ if (dataType === DataType.String) {
961
+ if (isCaseSensitive) {
962
+ value1 = value1 || "";
963
+ value2 = value2 || "";
964
+ }
965
+ else {
966
+ value1 = (value1 || "").toLowerCase();
967
+ value2 = (value2 || "").toLowerCase();
968
+ }
969
+ }
970
+ else {
971
+ var normalize = DataType.getComparableFn(dataType);
972
+ value1 = normalize(value1);
973
+ value2 = normalize(value2);
974
+ }
975
+ if (value1 === value2) {
976
+ return 0;
977
+ }
978
+ else if (value1 > value2 || value2 === undefined) {
979
+ return isDesc ? -1 : 1;
980
+ }
981
+ else {
982
+ return isDesc ? 1 : -1;
983
+ }
984
+ };
985
+ };
986
+ return OrderByItem;
987
+ }());
988
+ export { OrderByItem };
989
+ /** For use by breeze plugin authors only. The class is used in most [[IUriBuilderAdapter]] implementations
990
+ @adapter (see [[IUriBuilderAdapter]])
991
+ @hidden
992
+ **/
993
+ var SelectClause = /** @class */ (function () {
994
+ function SelectClause(propertyPaths) {
995
+ this.propertyPaths = propertyPaths;
996
+ this._pathNames = propertyPaths.map(function (pp) {
997
+ return pp.replace(".", "_");
998
+ });
999
+ }
1000
+ SelectClause.prototype.validate = function (entityType) {
1001
+ if (entityType == null || entityType.isAnonymous)
1002
+ return; // can't validate yet
1003
+ // will throw an exception on bad propertyPath
1004
+ this.propertyPaths.forEach(function (path) {
1005
+ entityType.getProperty(path, true);
1006
+ });
1007
+ };
1008
+ SelectClause.prototype.toFunction = function ( /* config */) {
1009
+ var that = this;
1010
+ return function (entity) {
1011
+ var result = {};
1012
+ that.propertyPaths.forEach(function (path, i) {
1013
+ result[that._pathNames[i]] = EntityAspect.getPropertyPathValue(entity, path);
1014
+ });
1015
+ return result;
1016
+ };
1017
+ };
1018
+ SelectClause.prototype.toJSONExt = function (context) {
1019
+ return this.propertyPaths.map(function (pp) {
1020
+ return context.propertyPathFn(pp);
1021
+ });
1022
+ };
1023
+ return SelectClause;
1024
+ }());
1025
+ export { SelectClause };
1026
+ /** For use by breeze plugin authors only. The class is used in most [[IUriBuilderAdapter]] implementations
1027
+ @adapter (see [[IUriBuilderAdapter]])
1028
+ @hidden
1029
+ **/
1030
+ var ExpandClause = /** @class */ (function () {
1031
+ function ExpandClause(propertyPaths) {
1032
+ this.propertyPaths = propertyPaths;
1033
+ }
1034
+ ExpandClause.prototype.toJSONExt = function (context) {
1035
+ return this.propertyPaths.map(function (pp) {
1036
+ return context.propertyPathFn(pp);
1037
+ });
1038
+ };
1039
+ return ExpandClause;
1040
+ }());
1041
+ export { ExpandClause };
1042
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW50aXR5LXF1ZXJ5LmpzIiwic291cmNlUm9vdCI6Im5nOi8vYnJlZXplLWNsaWVudC8iLCJzb3VyY2VzIjpbInNyYy9lbnRpdHktcXVlcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxJQUFJLEVBQTJCLE1BQU0sUUFBUSxDQUFDO0FBQ3ZELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxZQUFZLEVBQVUsTUFBTSxpQkFBaUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxRQUFRLENBQUM7QUFDcEMsT0FBTyxFQUFFLFdBQVcsRUFBc0IsTUFBTSxnQkFBZ0IsQ0FBQztBQUVqRSxPQUFPLEVBQWlCLFVBQVUsRUFBc0MsTUFBTSxtQkFBbUIsQ0FBQztBQUNsRyxPQUFPLEVBQUUsWUFBWSxFQUFnQyxNQUFNLGlCQUFpQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFXeEM7Ozs7OztHQU1HO0FBQ0g7SUEwQ0U7Ozs7Ozs7O09BUUc7SUFDSCxxQkFBWSxZQUE4QjtRQUN4QyxJQUFJLFlBQVksSUFBSSxJQUFJLElBQUksQ0FBQyxPQUFPLFlBQVksS0FBSyxRQUFRLENBQUMsRUFBRTtZQUM5RCxPQUFPLFFBQVEsQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLENBQUM7U0FDckM7UUFDRCw4R0FBOEc7UUFDOUcsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFzQixDQUFDO1FBQzNDLElBQUksQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFDO1FBQ2hDLElBQUksQ0FBQyxhQUFhLEdBQUcsU0FBUyxDQUFDO1FBQy9CLElBQUksQ0FB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Q0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFO1lBQ3hDLE9BQU8sT0FBTyxDQUFDLGNBQWUsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNyQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFSCxtQkFBQztBQUFELENBQUMsQUFiRCxJQWFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29yZSwgQ2FsbGJhY2ssIEVycm9yQ2FsbGJhY2sgfSBmcm9tICcuL2NvcmUnO1xyXG5pbXBvcnQgeyBhc3NlcnRQYXJhbSB9IGZyb20gJy4vYXNzZXJ0LXBhcmFtJztcclxuaW1wb3J0IHsgRGF0YVR5cGUgfSBmcm9tICcuL2RhdGEtdHlwZSc7XHJcbmltcG9ydCB7IEVudGl0eUFzcGVjdCwgRW50aXR5IH0gZnJvbSAnLi9lbnRpdHktYXNwZWN0JztcclxuaW1wb3J0IHsgRW50aXR5S2V5IH0gZnJvbSAnLi9lbnRpdHkta2V5JztcclxuaW1wb3J0IHsgQnJlZXplRW51bSB9IGZyb20gJy4vZW51bSc7XHJcbmltcG9ydCB7IERhdGFTZXJ2aWNlLCBKc29uUmVzdWx0c0FkYXB0ZXIgfSBmcm9tICcuL2RhdGEtc2VydmljZSc7XHJcbmltcG9ydCB7IEVudGl0eU1hbmFnZXIsIFF1ZXJ5UmVzdWx0IH0gZnJvbSAnLi9lbnRpdHktbWFuYWdlcic7XHJcbmltcG9ydCB7IE1ldGFkYXRhU3RvcmUsIEVudGl0eVR5cGUsIE5hdmlnYXRpb25Qcm9wZXJ0eSwgRW50aXR5UHJvcGVydHkgfSBmcm9tICcuL2VudGl0eS1tZXRhZGF0YSc7XHJcbmltcG9ydCB7IFF1ZXJ5T3B0aW9ucywgTWVyZ2VTdHJhdGVneSwgRmV0Y2hTdHJhdGVneSB9IGZyb20gJy4vcXVlcnktb3B0aW9ucyc7XHJcbmltcG9ydCB7IFByZWRpY2F0ZSB9IGZyb20gJy4vcHJlZGljYXRlJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgUmVjdXJzaXZlQXJyYXk8VD4ge1xyXG4gIFtpOiBudW1iZXJdOiBUIHwgUmVjdXJzaXZlQXJyYXk8VD47XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRW50aXR5UXVlcnlKc29uQ29udGV4dCB7XHJcbiAgZW50aXR5VHlwZT86IEVudGl0eVR5cGU7XHJcbiAgcHJvcGVydHlQYXRoRm4/OiBGdW5jdGlvbjsgLy8gVE9ET1xyXG4gIHRvTmFtZU9uU2VydmVyPzogYm9vbGVhbjtcclxufVxyXG4vKipcclxuQW4gRW50aXR5UXVlcnkgaW5zdGFuY2UgaXMgdXNlZCB0byBxdWVyeSBlbnRpdGllcyBlaXRoZXIgZnJvbSBhIHJlbW90ZSBkYXRhc291cmNlIG9yIGZyb20gYSBsb2NhbCBbW0VudGl0eU1hbmFnZXJdXS5cclxuXHJcbkVudGl0eVF1ZXJpZXMgYXJlIGltbXV0YWJsZSAtIHRoaXMgbWVhbnMgdGhhdCBhbGwgRW50aXR5UXVlcnkgbWV0aG9kcyB0aGF0IHJldHVybiBhbiBFbnRpdHlRdWVyeSBhY3R1YWxseSBjcmVhdGUgYSBuZXcgRW50aXR5UXVlcnkuICBUaGlzIG1lYW5zIHRoYXRcclxuRW50aXR5UXVlcmllcyBjYW4gYmUgJ21vZGlmaWVkJyB3aXRob3V0IGFmZmVjdGluZyBhbnkgY3VycmVudCBpbnN0YW5jZXMuXHJcbkBkeW5hbWljXHJcbioqL1xyXG5leHBvcnQgY2xhc3MgRW50aXR5UXVlcnkge1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIGRlY2xhcmUgXyR0eXBlTmFtZTogc3RyaW5nOyAvLyBhY3R1YWxseSBwbGFjZWQgb24gcHJvdG90eXBlXHJcbiAgLy8gdG9wID0gdGhpcy50YWtlOyAvLyBUT0RPOiBjb25zaWRlclxyXG4gIC8qKiBUaGUgcmVzb3VyY2UgbmFtZSB1c2VkIGJ5IHRoaXMgcXVlcnkuIF9fUmVhZCBPbmx5X18gKi9cclxuICBkZWNsYXJlIHJlc291cmNlTmFtZT86IHN0cmluZztcclxuICAvKiogVGhlIFtbRW50aXR5VHlwZV1dIHRoYXQgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZSAnZnJvbScgY2xhdXNlICggcmVzb3VyY2VOYW1lKSBvZiB0aGUgcXVlcnkuICBUaGlzIGlzIG9ubHkgZ3VhcmFudGVlZCB0byBiZSBiZSBzZXQgQUZURVIgdGhlIHF1ZXJ5XHJcbiAgaGFzIGJlZW4gZXhlY3V0ZWQgYmVjYXVzZSBpdCBkZXBlbmRzIG9uIHRoZSBbW01ldGFkYXRhU3RvcmVdXSBhc3NvY2lhdGVkIHdpdGggdGhlIFtbRW50aXR5TWFuYWdlcl1dIHRoYXQgdGhlIHF1ZXJ5IHdhcyBleGVjdXRlZCBhZ2FpbnN0LlxyXG4gIFRoaXMgdmFsdWUgbWF5IGJlIG51bGwgaWYgdGhlIGVudGl0eVR5cGUgY2Fubm90IGJlIGFzc29jaWF0ZWQgd2l0aCBhIHJlc291cmNlTmFtZS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgZnJvbUVudGl0eVR5cGU/OiBFbnRpdHlUeXBlO1xyXG4gIC8qKiBUaGUgJ3doZXJlJyBbW1ByZWRpY2F0ZV1dIHVzZWQgYnkgdGhpcyBxdWVyeS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgd2hlcmVQcmVkaWNhdGU6IFByZWRpY2F0ZTsgLy8gVE9ET1xyXG4gIC8qKiBUaGUgW1tPcmRlckJ5Q2xhdXNlXV0gdXNlZCBieSB0aGlzIHF1ZXJ5LiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSBvcmRlckJ5Q2xhdXNlPzogT3JkZXJCeUNsYXVzZTtcclxuICAvKiogVGhlIFtbRXhwYW5kQ2xhdXNlXV0gdXNlZCBieSB0aGlzIHF1ZXJ5LiBfX1JlYWQgT25seV9fICovXHJcbiAgZGVjbGFyZSBleHBhbmRDbGF1c2U/OiBFeHBhbmRDbGF1c2U7XHJcbiAgLyoqIFRoZSBbW1NlbGVjdENsYXVzZV1dIHVzZWQgYnkgdGhpcyBxdWVyeS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgc2VsZWN0Q2xhdXNlPzogU2VsZWN0Q2xhdXNlO1xyXG4gIC8qKiBUaGUgbnVtYmVyIG9mIGVudGl0aWVzIHRvICdza2lwJyBmb3IgdGhpcyBxdWVyeS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgc2tpcENvdW50PzogbnVtYmVyO1xyXG4gIC8qKiBUaGUgbnVtYmVyIG9mIGVudGl0aWVzIHRvICd0YWtlJyBmb3IgdGhpcyBxdWVyeS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgdGFrZUNvdW50PzogbnVtYmVyO1xyXG4gIC8qKiBBbnkgYWRkaXRpb25hbCBwYXJhbWV0ZXJzIHRoYXQgd2VyZSBhZGRlZCB0byB0aGUgcXVlcnkgdmlhIHRoZSAnd2l0aFBhcmFtZXRlcnMnIG1ldGhvZC4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgcGFyYW1ldGVyczogT2JqZWN0O1xyXG4gIC8qKiBXaGV0aGVyIGFuIGlubGluZSBjb3VudCBpcyByZXR1cm5lZCBmb3IgdGhpcyBxdWVyeS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgaW5saW5lQ291bnRFbmFibGVkOiBib29sZWFuO1xyXG4gIC8qKiBXaGV0aGVyIGVudGl0eSB0cmFja2luZyBoYXMgYmVlbiBkaXNhYmxlZCBmb3IgdGhpcyBxdWVyeS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgbm9UcmFja2luZ0VuYWJsZWQ6IGJvb2xlYW47XHJcbiAgLyoqIFdoZXRoZXIgdG8gc2VuZCBxdWVyeSBhcyB0aGUgYm9keSBvZiBhIFBPU1QgcmVxdWVzdC4gIChTZXJ2ZXIgbmVlZHMgdG8gYWNjb21vZGF0ZSBQT1NUKS4gX19SZWFkIE9ubHlfXyAqL1xyXG4gIGRlY2xhcmUgdXNlUG9zdEVuYWJsZWQ6IGJvb2xlYW47XHJcbiAgLyoqIFRoZSBbW1F1ZXJ5T3B0aW9uc11dIGZvciB0aGlzIHF1ZXJ5LiBfX1JlYWQgT25seV9fICAqKi9cclxuICAvLyBkZWZhdWx0IGlzIHRvIGdldCBxdWVyeU9wdGlvbnMgYW5kIGRhdGFTZXJ2aWNlIGZyb20gdGhlIGVudGl0eU1hbmFnZXIuXHJcbiAgZGVjbGFyZSBxdWVyeU9wdGlvbnM/OiBRdWVyeU9wdGlvbnM7XHJcbiAgLyoqIFRoZSBbW0RhdGFTZXJ2aWNlXV0gZm9yIHRoaXMgcXVlcnkuIF9fUmVhZCBPbmx5X18gICoqL1xyXG4gIGRlY2xhcmUgZGF0YVNlcnZpY2U/OiBEYXRhU2VydmljZTtcclxuICAvKiogVGhlIFtbRW50aXR5TWFuYWdlcl1dIGZvciB0aGlzIHF1ZXJ5LiBUaGlzIG1heSBiZSBudWxsIGFuZCBjYW4gYmUgc2V0IHZpYSB0aGUgJ3VzaW5nJyBtZXRob2QuICAqKi9cclxuICBkZWNsYXJlIGVudGl0eU1hbmFnZXI/OiBFbnRpdHlNYW5hZ2VyO1xyXG4gIC8qKiAgVGhlIGVudGl0eVR5cGUgdGhhdCB3aWxsIGJlIHJldHVybmVkIGJ5IHRoaXMgcXVlcnkuIFxyXG4gIFRoaXMgcHJvcGVydHkgd2lsbCBvbmx5IGJlIHNldCBpZiB0aGUgJ3RvVHlwZScgbWV0aG9kIHdhcyBjYWxsZWQuIF9fUmVhZCBPbmx5X18gKi9cclxuICBkZWNsYXJlIHJlc3VsdEVudGl0eVR5cGU6IEVudGl0eVR5cGUgfCBzdHJpbmc7XHJcbiAgZGVjbGFyZSB1c2VzTmFtZU9uU2VydmVyPzogYm9vbGVhbjtcclxuXHJcbiAgLyoqIENvbnN0cnVjdG9yXHJcbiAgPiAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIilcclxuXHJcbiAgVXN1YWxseSB0aGlzIGNvbnN0cnVjdG9yIHdpbGwgYmUgZm9sbG93ZWQgYnkgY2FsbHMgdG8gZmlsdGVyaW5nLCBvcmRlcmluZyBvciBzZWxlY3Rpb24gbWV0aG9kc1xyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIilcclxuICA+ICAgICAgICAud2hlcmUoXCJDb21wYW55TmFtZVwiLCBcInN0YXJ0c1dpdGhcIiwgXCJDXCIpXHJcbiAgPiAgICAgICAgLm9yZGVyQnkoXCJSZWdpb25cIik7XHJcbiAgQHBhcmFtIHJlc291cmNlTmFtZSAtIGVpdGhlciBhIHJlc291cmNlIG5hbWUgb3IgYSBzZXJpYWxpemVkIEVudGl0eVF1ZXJ5ICggY3JlYXRlZCBieSBbW0VudGl0eVF1ZXJ5LnRvSlNPTl1dKVxyXG4gICoqL1xyXG4gIGNvbnN0cnVjdG9yKHJlc291cmNlTmFtZT86IHN0cmluZyB8IE9iamVjdCkge1xyXG4gICAgaWYgKHJlc291cmNlTmFtZSAhPSBudWxsICYmICh0eXBlb2YgcmVzb3VyY2VOYW1lICE9PSAnc3RyaW5nJykpIHtcclxuICAgICAgcmV0dXJuIGZyb21KU09OKHRoaXMsIHJlc291cmNlTmFtZSk7XHJcbiAgICB9XHJcbiAgICAvLyBUT0RPOiBjYXN0IGFzIHN0cmluZyBiZWxvdyBuZWVkZWQgZm9yIGVhcmx5IHZlcnNpb25zIG9mIFR5cGVEb2MgLSBidXQgbm90IGZvciByZWd1bGFyIGNvbXBpbGUgLSBjaGVjayBsYXRlclxyXG4gICAgdGhpcy5yZXNvdXJjZU5hbWUgPSByZXNvdXJjZU5hbWUgYXMgc3RyaW5nO1xyXG4gICAgdGhpcy5mcm9tRW50aXR5VHlwZSA9IHVuZGVmaW5lZDtcclxuICAgIHRoaXMud2hlcmVQcmVkaWNhdGUgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLm9yZGVyQnlDbGF1c2UgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLnNlbGVjdENsYXVzZSA9IHVuZGVmaW5lZDtcclxuICAgIHRoaXMuc2tpcENvdW50ID0gdW5kZWZpbmVkO1xyXG4gICAgdGhpcy50YWtlQ291bnQgPSB1bmRlZmluZWQ7XHJcbiAgICB0aGlzLmV4cGFuZENsYXVzZSA9IHVuZGVmaW5lZDtcclxuICAgIHRoaXMucGFyYW1ldGVycyA9IHt9O1xyXG4gICAgdGhpcy5pbmxpbmVDb3VudEVuYWJsZWQgPSBmYWxzZTtcclxuICAgIHRoaXMubm9UcmFja2luZ0VuYWJsZWQgPSBmYWxzZTtcclxuICAgIHRoaXMudXNlUG9zdEVuYWJsZWQgPSBmYWxzZTtcclxuICAgIC8vIGRlZmF1bHQgaXMgdG8gZ2V0IHF1ZXJ5T3B0aW9ucyBhbmQgZGF0YVNlcnZpY2UgZnJvbSB0aGUgZW50aXR5TWFuYWdlci5cclxuICAgIC8vIHRoaXMucXVlcnlPcHRpb25zID0gbmV3IFF1ZXJ5T3B0aW9ucygpO1xyXG4gICAgLy8gdGhpcy5kYXRhU2VydmljZSA9IG5ldyBEYXRhU2VydmljZSgpO1xyXG4gICAgdGhpcy5lbnRpdHlNYW5hZ2VyID0gdW5kZWZpbmVkO1xyXG5cclxuICB9XHJcblxyXG5cclxuICAvKipcclxuICBTcGVjaWZpZXMgdGhlIHJlc291cmNlIHRvIHF1ZXJ5IGZvciB0aGlzIEVudGl0eVF1ZXJ5LlxyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoKVxyXG4gID4gICAgICAgIC5mcm9tKFwiQ3VzdG9tZXJzXCIpO1xyXG5cclxuICBpcyB0aGUgc2FtZSBhc1xyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIik7XHJcbiAgQHBhcmFtIHJlc291cmNlTmFtZSAtIFRoZSByZXNvdXJjZSB0byBxdWVyeS5cclxuICAqKi9cclxuICBmcm9tKHJlc291cmNlTmFtZTogc3RyaW5nKSB7XHJcbiAgICAvLyBUT0RPOiB0aGluayBhYm91dCBhbGxvd2luZyBlbnRpdHlUeXBlIGFzIHdlbGxcclxuICAgIGFzc2VydFBhcmFtKHJlc291cmNlTmFtZSwgXCJyZXNvdXJjZU5hbWVcIikuaXNTdHJpbmcoKS5jaGVjaygpO1xyXG4gICAgcmV0dXJuIGNsb25lKHRoaXMsIFwicmVzb3VyY2VOYW1lXCIsIHJlc291cmNlTmFtZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBUaGlzIGlzIGEgc3RhdGljIHZlcnNpb24gb2YgdGhlIFwiZnJvbVwiIG1ldGhvZCBhbmQgaXQgY3JlYXRlcyBhICdiYXNlJyBlbnRpdHlRdWVyeSBmb3IgdGhlIHNwZWNpZmllZCByZXNvdXJjZSBuYW1lLlxyXG4gID4gICAgICBsZXQgcXVlcnkgPSBFbnRpdHlRdWVyeS5mcm9tKFwiQ3VzdG9tZXJzXCIpO1xyXG5cclxuICBpcyB0aGUgc2FtZSBhc1xyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIik7XHJcbiAgQHBhcmFtIHJlc291cmNlTmFtZSAtIFRoZSByZXNvdXJjZSB0byBxdWVyeS5cclxuICAqKi9cclxuICBzdGF0aWMgZnJvbShyZXNvdXJjZU5hbWU6IHN0cmluZykge1xyXG4gICAgYXNzZXJ0UGFyYW0ocmVzb3VyY2VOYW1lLCBcInJlc291cmNlTmFtZVwiKS5pc1N0cmluZygpLmNoZWNrKCk7XHJcbiAgICByZXR1cm4gbmV3IEVudGl0eVF1ZXJ5KHJlc291cmNlTmFtZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBTcGVjaWZpZXMgdGhlIHRvcCBsZXZlbCBFbnRpdHlUeXBlIHRoYXQgdGhpcyBxdWVyeSB3aWxsIHJldHVybi4gIE9ubHkgbmVlZGVkIHdoZW4gYSBxdWVyeSByZXR1cm5zIGEganNvbiByZXN1bHQgdGhhdCBkb2VzIG5vdCBpbmNsdWRlIHR5cGUgaW5mb3JtYXRpb24sXHJcbiAgb3Igd2hlbiB1c2luZyBhIHJlc291cmNlIG5hbWUgdGhhdCBpcyBub3QgYXNzb2NpYXRlZCB0byBhbiBFbnRpdHlUeXBlLlxyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoKVxyXG4gID4gICAgICAgIC5mcm9tKFwiTXlDdXN0b21NZXRob2RcIilcclxuICA+ICAgICAgICAudG9UeXBlKFwiQ3VzdG9tZXJcIilcclxuICBAcGFyYW0gZW50aXR5VHlwZSAtIFRoZSB0b3AgbGV2ZWwgRW50aXR5VHlwZSB0aGF0IHRoaXMgcXVlcnkgd2lsbCByZXR1cm4uXHJcbiAgQHN1bW1hcnkgSWYgdGhlIGpzb24gcmVzdWx0IGNvbnNpc3RzIG9mIG1vcmUgdGhhbiBhIHNpbXBsZSBlbnRpdHkgb3IgYXJyYXkgb2YgZW50aXRpZXMsIGNvbnNpZGVyIHVzaW5nIGEgW1tKc29uUmVzdWx0c0FkYXB0ZXJdXSBpbnN0ZWFkLlxyXG4gICoqL1xyXG4gIHRvVHlwZShlbnRpdHlUeXBlOiBzdHJpbmcgfCBFbnRpdHlUeXBlKSB7XHJcbiAgICBhc3NlcnRQYXJhbShlbnRpdHlUeXBlLCBcImVudGl0eVR5cGVcIikuaXNTdHJpbmcoKS5vcigpLmlzSW5zdGFuY2VPZihFbnRpdHlUeXBlKS5jaGVjaygpO1xyXG4gICAgcmV0dXJuIGNsb25lKHRoaXMsIFwicmVzdWx0RW50aXR5VHlwZVwiLCBlbnRpdHlUeXBlKTtcclxuICB9XHJcblxyXG5cclxuICB3aGVyZShwcmVkaWNhdGU/OiBQcmVkaWNhdGUpOiBFbnRpdHlRdWVyeTtcclxuICB3aGVyZShwcmVkaWNhdGU6IE9iamVjdCk6IEVudGl0eVF1ZXJ5O1xyXG4gIHdoZXJlKHByb3BlcnR5OiBzdHJpbmcsIG9wZXJhdG9yOiBzdHJpbmcsIHZhbHVlOiBhbnkpOiBFbnRpdHlRdWVyeTtcclxuICB3aGVyZShwcm9wZXJ0eTogc3RyaW5nLCBvcGVyYXRvcjogRmlsdGVyUXVlcnlPcCwgdmFsdWU6IGFueSk6IEVudGl0eVF1ZXJ5O1xyXG4gIHdoZXJlKHByb3BlcnR5OiBzdHJpbmcsIGZpbHRlcm9wOiBGaWx0ZXJRdWVyeU9wLCBwcm9wZXJ0eTI6IHN0cmluZywgZmlsdGVyb3AyOiBGaWx0ZXJRdWVyeU9wLCB2YWx1ZTogYW55KTogRW50aXR5UXVlcnk7ICAvLyBmb3IgYW55L2FsbCBjbGF1c2VzXHJcbiAgd2hlcmUocHJvcGVydHk6IHN0cmluZywgZmlsdGVyb3A6IHN0cmluZywgcHJvcGVydHkyOiBzdHJpbmcsIGZpbHRlcm9wMjogc3RyaW5nLCB2YWx1ZTogYW55KTogRW50aXR5UXVlcnk7ICAvLyBmb3IgYW55L2FsbCBjbGF1c2VzXHJcbiAgd2hlcmUocHJvcGVydHk6IHN0cmluZywgZmlsdGVyb3A6IHN0cmluZywgcHJvcGVydHkyOiBzdHJpbmcsIGZpbHRlcm9wMjogc3RyaW5nLCBwcm9wZXJ0eTM6IHN0cmluZywgZmlsdGVyb3AzOiBzdHJpbmcsIHZhbHVlOiBhbnkpOiBFbnRpdHlRdWVyeTsgIC8vIGZvciBhbnkvYWxsIGNsYXVzZXNcclxuICB3aGVyZShhbkFycmF5OiBSZWN1cnNpdmVBcnJheTxzdHJpbmcgfCBudW1iZXIgfCBGaWx0ZXJRdWVyeU9wIHwgUHJlZGljYXRlPik6IEVudGl0eVF1ZXJ5O1xyXG4gIC8qKlxyXG4gIFJldHVybnMgYSBuZXcgcXVlcnkgd2l0aCBhbiBhZGRlZCBmaWx0ZXIgY3JpdGVyaWE7IENhbiBiZSBjYWxsZWQgbXVsdGlwbGUgdGltZXMgd2hpY2ggbWVhbnMgdG8gJ2FuZCcgd2l0aCBhbnkgZXhpc3RpbmdcclxuICBQcmVkaWNhdGUgb3IgY2FuIGJlIGNhbGxlZCB3aXRoIG51bGwgdG8gY2xlYXIgYWxsIHByZWRpY2F0ZXMuXHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgICAgLndoZXJlKFwiQ29tcGFueU5hbWVcIiwgXCJzdGFydHNXaXRoXCIsIFwiQ1wiKTtcclxuXHJcbiAgVGhpcyBjYW4gYWxzbyBiZSBleHByZXNzZWQgdXNpbmcgYW4gZXhwbGljaXQgW1tGaWx0ZXJRdWVyeU9wXV0gYXNcclxuICA+ICAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiQ3VzdG9tZXJzXCIpXHJcbiAgPiAgICAgICAgICAud2hlcmUoXCJDb21wYW55TmFtZVwiLCBGaWx0ZXJRdWVyeU9wLlN0YXJ0c1dpdGgsIFwiQ1wiKTtcclxuXHJcbiAgb3IgYSBwcmVjb25zdHJ1Y3RlZCBbW1ByZWRpY2F0ZV1dIG1heSBiZSB1c2VkXHJcbiAgPiAgICAgIGxldCBwcmVkID0gbmV3IFByZWRpY2F0ZShcIkNvbXBhbnlOYW1lXCIsIEZpbHRlclF1ZXJ5T3AuU3RhcnRzV2l0aCwgXCJDXCIpO1xyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIikud2hlcmUocHJlZCk7XHJcblxyXG4gIFByZWRpY2F0ZXMgYXJlIG9mdGVuIHVzZWZ1bCB3aGVuIHlvdSB3YW50IHRvIGNvbWJpbmUgbXVsdGlwbGUgY29uZGl0aW9ucyBpbiBhIHNpbmdsZSBmaWx0ZXIsIHN1Y2ggYXNcclxuICA+ICAgICAgbGV0IHByZWQgPSBQcmVkaWNhdGUuY3JlYXRlKFwiQ29tcGFueU5hbWVcIiwgXCJzdGFydHN3aXRoXCIsIFwiQ1wiKS5hbmQoXCJSZWdpb25cIiwgRmlsdGVyUXVlcnlPcC5FcXVhbHMsIG51bGwpO1xyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIilcclxuICA+ICAgICAgICAgIC53aGVyZShwcmVkKTtcclxuXHJcbiAgTW9yZSBjb21wbGljYXRlZCBxdWVyaWVzIGNhbiBtYWtlIHVzZSBvZiBuZXN0ZWQgcHJvcGVydHkgcGF0aHNcclxuICA+ICAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiUHJvZHVjdHNcIilcclxuICA+ICAgICAgICAgIC53aGVyZShcIkNhdGVnb3J5LkNhdGVnb3J5TmFtZVwiLCBcInN0YXJ0c3dpdGhcIiwgXCJTXCIpO1xyXG5cclxuICBvciBPRGF0YSBmdW5jdGlvbnMgLSBBIGxpc3Qgb2YgdmFsaWQgT0RhdGEgZnVuY3Rpb25zIGNhbiBiZSBmb3VuZCB3aXRoaW4gdGhlIFtbUHJlZGljYXRlXV0gZG9jdW1lbnRhdGlvbi5cclxuICBcclxuICA+ICAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiQ3VzdG9tZXJzXCIpXHJcbiAgPiAgICAgICAgICAud2hlcmUoXCJ0b0xvd2VyKENvbXBhbnlOYW1lKVwiLCBcInN0YXJ0c1dpdGhcIiwgXCJjXCIpO1xyXG5cclxuICBvciB0byBiZSBldmVuIG1vcmUgYmFyb3F1ZVxyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIilcclxuICA+ICAgICAgICAgIC53aGVyZShcInRvVXBwZXIoc3Vic3RyaW5nKENvbXBhbnlOYW1lLCAxLCAyKSlcIiwgRmlsdGVyUXVlcnlPcC5FcXVhbHMsIFwiT01cIik7XHJcbiAgQHBhcmFtIHByZWRpY2F0ZSAtICBDYW4gYmUgZWl0aGVyXHJcbiAgICAtIGEgc2luZ2xlIFtbUHJlZGljYXRlXV1cclxuXHJcbiAgICAtIHRoZSBwYXJhbWV0ZXJzIHRvIGNyZWF0ZSBhICdzaW1wbGUnIFByZWRpY2F0ZVxyXG4gICAgLSAtICBhIHByb3BlcnR5IG5hbWUsIGEgcHJvcGVydHkgcGF0aCB3aXRoICcuJyBhcyBwYXRoIHNlcGVyYXRvcnMgb3IgYSBwcm9wZXJ0eSBleHByZXNzaW9uIHtTdHJpbmd9XHJcbiAgICAtIC0gIGFuIG9wZXJhdG9yIC0gW1tGaWx0ZXJRdWVyeU9wXV0gb3IgaXQncyBzdHJpbmcgcmVwcmVzZW50YXRpb24uIENhc2UgaXMgaWdub3JlZFxyXG4gICAgd2hlbiBpZiBhIHN0cmluZyBpcyBwcm92aWRlZCBhbmQgYW55IHN0cmluZyB0aGF0IG1hdGNoZXMgb25lIG9mIHRoZSBGaWx0ZXJRdWVyeU9wIGFsaWFzZXMgd2lsbCBiZSBhY2NlcHRlZC5cclxuICAgIC0gLSAgYSB2YWx1ZSB7T2JqZWN0fSAtIFRoaXMgd2lsbCBiZSB0cmVhdGVkIGFzIGVpdGhlciBhIHByb3BlcnR5IGV4cHJlc3Npb24gb3IgYSBsaXRlcmFsIGRlcGVuZGluZyBvbiBjb250ZXh0LiAgXHJcbiAgICBJbiBnZW5lcmFsLCBpZiB0aGUgdmFsdWUgY2FuIGJlIGludGVycHJldGVkIGFzIGEgcHJvcGVydHkgZXhwcmVzc2lvbiBpdCB3aWxsIGJlLCBvdGhlcndpc2UgaXQgd2lsbCBiZSB0cmVhdGVkIGFzIGEgbGl0ZXJhbC5cclxuICAgIEluIG1vc3QgY2FzZXMgdGhpcyB3b3JrcyB3ZWxsLCBidXQgeW91IGNhbiBhbHNvIGZvcmNlIHRoZSBpbnRlcnByZXRhdGlvbiBieSBtYWtpbmcgdGhlIHZhbHVlIGFyZ3VtZW50IGl0c2VsZiBhbiBvYmplY3QgXHJcbiAgICB3aXRoIGEgJ3ZhbHVlJyBwcm9wZXJ0eSBhbmQgYW4gJ2lzTGl0ZXJhbCcgcHJvcGVydHkgc2V0IHRvIGVpdGhlciB0cnVlIG9yIGZhbHNlLlxyXG4gICAgQnJlZXplIGFsc28gdHJpZXMgdG8gaW5mZXIgdGhlIGRhdGFUeXBlIG9mIGFueSBsaXRlcmFsIGJhc2VkIG9uIGNvbnRleHQsIGlmIHRoaXMgZmFpbHMgeW91IGNhbiBmb3JjZSB0aGlzIGluZmVyZW5jZSBieSBtYWtpbmcgdGhlIHZhbHVlIGFyZ3VtZW50IFxyXG4gICAgYW4gb2JqZWN0IHdpdGggYSAndmFsdWUnIHByb3BlcnR5IGFuZCBhICdkYXRhVHlwZSdwcm9wZXJ0eSBzZXQgdG8gb25lIG9mIHRoZSBEYXRhVHlwZSBlbnVtZXJhdGlvbiBpbnN0YW5jZXMuXHJcblxyXG4gICAgLSBhIG51bGwgb3IgdW5kZWZpbmVkICggdGhpcyBjYXVzZXMgYW55IGV4aXN0aW5nIHdoZXJlIGNsYXVzZSB0byBiZSByZW1vdmVkKVxyXG4gICoqL1xyXG4gIHdoZXJlKC4uLmFyZ3M6IGFueVtdKSB7XHJcbiAgICBsZXQgd2hlcmVQcmVkaWNhdGU6IFByZWRpY2F0ZSB8IHVuZGVmaW5lZDtcclxuICAgIGlmIChhcmdzLmxlbmd0aCA+IDAgJiYgYXJnc1swXSAhPSBudWxsKSB7XHJcbiAgICAgIHdoZXJlUHJlZGljYXRlID0gUHJlZGljYXRlLmNyZWF0ZSguLi48YW55PmFyZ3MpO1xyXG4gICAgICBpZiAodGhpcy5mcm9tRW50aXR5VHlwZSkgd2hlcmVQcmVkaWNhdGUuX3ZhbGlkYXRlKHRoaXMuZnJvbUVudGl0eVR5cGUpO1xyXG4gICAgICBpZiAodGhpcy53aGVyZVByZWRpY2F0ZSkge1xyXG4gICAgICAgIHdoZXJlUHJlZGljYXRlID0gdGhpcy53aGVyZVByZWRpY2F0ZS5hbmQod2hlcmVQcmVkaWNhdGUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY2xvbmUodGhpcywgXCJ3aGVyZVByZWRpY2F0ZVwiLCB3aGVyZVByZWRpY2F0ZSk7XHJcbiAgfVxyXG5cclxuXHJcbiAgb3JkZXJCeShwcm9wZXJ0eVBhdGhzPzogc3RyaW5nLCBpc0Rlc2NlbmRpbmc/OiBib29sZWFuKTogRW50aXR5UXVlcnk7XHJcbiAgb3JkZXJCeShwcm9wZXJ0eVBhdGhzOiBzdHJpbmdbXSwgaXNEZXNjZW5kaW5nPzogYm9vbGVhbik6IEVudGl0eVF1ZXJ5O1xyXG4gIC8qKlxyXG4gIFJldHVybnMgYSBuZXcgcXVlcnkgdGhhdCBvcmRlcnMgdGhlIHJlc3VsdHMgb2YgdGhlIHF1ZXJ5IGJ5IHByb3BlcnR5IG5hbWUuICBCeSBkZWZhdWx0IHNvcnRpbmcgb2NjdXJzIGlzIGFzY2VuZGluZyBvcmRlciwgYnV0IHNvcnRpbmcgaW4gZGVzY2VuZGluZyBvcmRlciBpcyBzdXBwb3J0ZWQgYXMgd2VsbC5cclxuICBPcmRlckJ5IGNsYXVzZXMgbWF5IGJlIGNoYWluZWQuXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiQ3VzdG9tZXJzXCIpXHJcbiAgPiAgICAgICAgLm9yZGVyQnkoXCJDb21wYW55TmFtZVwiKTtcclxuXHJcbiAgb3IgdG8gc29ydCBhY3Jvc3MgbXVsdGlwbGUgcHJvcGVydGllc1xyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgIC5vcmRlckJ5KFwiUmVnaW9uLCBDb21wYW55TmFtZVwiKTtcclxuXHJcbiAgTmVzdGVkIHByb3BlcnR5IHBhdGhzIGFyZSBhbHNvIHN1cHBvcnRlZFxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIlByb2R1Y3RzXCIpXHJcbiAgPiAgICAgICAgLm9yZGVyQnkoXCJDYXRlZ29yeS5DYXRlZ29yeU5hbWVcIik7XHJcblxyXG4gIFNvcnRpbmcgaW4gZGVzY2VuZGluZyBvcmRlciBpcyBzdXBwb3J0ZWQgdmlhIHRoZSBhZGRpdGlvbiBvZiAnIGRlc2MnIHRvIHRoZSBlbmQgb2YgYW55IHByb3BlcnR5IHBhdGguXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiQ3VzdG9tZXJzXCIpXHJcbiAgPiAgICAgICAgLm9yZGVyQnkoXCJDb21wYW55TmFtZSBkZXNjXCIpO1xyXG5cclxuICBvclxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgIC5vcmRlckJ5KFwiUmVnaW9uIGRlc2MsIENvbXBhbnlOYW1lIGRlc2NcIik7XHJcbiAgQHBhcmFtIHByb3BlcnR5UGF0aHMgLSBBIGNvbW1hLXNlcGFyYXRlZCAoJywnKSBzdHJpbmcgb2YgcHJvcGVydHkgcGF0aHMgb3IgYW4gYXJyYXkgb2YgcHJvcGVydHkgcGF0aHMuXHJcbiAgRWFjaCBwcm9wZXJ0eSBwYXRoIGNhbiBvcHRpb25hbGx5IGVuZCB3aXRoIFwiIGRlc2NcIiB0byBmb3JjZSBhIGRlc2NlbmRpbmcgc29ydCBvcmRlci4gSWYgJ3Byb3BlcnR5UGF0aHMnIGlzIGVpdGhlciBudWxsIG9yIG9taXR0ZWQgdGhlbiBhbGwgb3JkZXJpbmcgaXMgcmVtb3ZlZC5cclxuICBAcGFyYW0gaXNEZXNjZW5kaW5nIC0gSWYgc3BlY2lmaWVkLCBvdmVycmlkZXMgYWxsIG9mIHRoZSBlbWJlZGRlZCAnZGVzYycgdGFncyBpbiB0aGUgcHJldmlvdXNseSBzcGVjaWZpZWQgcHJvcGVydHkgcGF0aHMuXHJcbiAgKiovXHJcbiAgb3JkZXJCeShwcm9wZXJ0eVBhdGhzOiBzdHJpbmcgfCBzdHJpbmdbXSwgaXNEZXNjZW5kaW5nPzogYm9vbGVhbikge1xyXG4gICAgLy8gcHJvcGVydHlQYXRoczogY2FuIHBhc3MgaW4gY3JlYXRlKFwiQS5YLEJcIikgb3IgY3JlYXRlKFwiQS5YIGRlc2MsIEJcIikgb3IgY3JlYXRlKFwiQS5YIGRlc2MsQlwiLCB0cnVlXSlcclxuICAgIC8vIGlzRGVzYyBwYXJhbWV0ZXIgdHJ1bXBzIGlzRGVzYyBpbiBwcm9wZXJ0eU5hbWUuXHJcbiAgICBsZXQgb3JkZXJCeUNsYXVzZSA9IHByb3BlcnR5UGF0aHMgPT0gbnVsbCA/IG51bGwgOiBuZXcgT3JkZXJCeUNsYXVzZShub3JtYWxpemVQcm9wZXJ0eVBhdGhzKHByb3BlcnR5UGF0aHMpLCBpc0Rlc2NlbmRpbmcpO1xyXG4gICAgaWYgKHRoaXMub3JkZXJCeUNsYXVzZSAmJiBvcmRlckJ5Q2xhdXNlKSB7XHJcbiAgICAgIG9yZGVyQnlDbGF1c2UgPSBuZXcgT3JkZXJCeUNsYXVzZShbdGhpcy5vcmRlckJ5Q2xhdXNlLCBvcmRlckJ5Q2xhdXNlXSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gY2xvbmUodGhpcywgXCJvcmRlckJ5Q2xhdXNlXCIsIG9yZGVyQnlDbGF1c2UpO1xyXG4gIH1cclxuXHJcblxyXG4gIG9yZGVyQnlEZXNjKHByb3BlcnR5UGF0aHM6IHN0cmluZyk6IEVudGl0eVF1ZXJ5O1xyXG4gIG9yZGVyQnlEZXNjKHByb3BlcnR5UGF0aHM6IHN0cmluZ1tdKTogRW50aXR5UXVlcnk7XHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIG5ldyBxdWVyeSB0aGF0IG9yZGVycyB0aGUgcmVzdWx0cyBvZiB0aGUgcXVlcnkgYnkgcHJvcGVydHkgbmFtZSBpbiBkZXNjZW5kaW5nIG9yZGVyLlxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgIC5vcmRlckJ5RGVzYyhcIkNvbXBhbnlOYW1lXCIpO1xyXG5cclxuICBvciB0byBzb3J0IGFjcm9zcyBtdWx0aXBsZSBwcm9wZXJ0aWVzXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiQ3VzdG9tZXJzXCIpXHJcbiAgPiAgICAgICAgLm9yZGVyQnlEZXNjKFwiUmVnaW9uLCBDb21wYW55TmFtZVwiKTtcclxuXHJcbiAgTmVzdGVkIHByb3BlcnR5IHBhdGhzIGFyZSBhbHNvIHN1cHBvcnRlZFxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIlByb2R1Y3RzXCIpXHJcbiAgPiAgICAgICAgLm9yZGVyQnlEZXNjKFwiQ2F0ZWdvcnkuQ2F0ZWdvcnlOYW1lXCIpO1xyXG4gIEBwYXJhbSBwcm9wZXJ0eVBhdGhzIC0gQSBjb21tYS1zZXBhcmF0ZWQgKCcsJykgc3RyaW5nIG9mIHByb3BlcnR5IHBhdGhzIG9yIGFuIGFycmF5IG9mIHByb3BlcnR5IHBhdGhzLlxyXG4gIElmICdwcm9wZXJ0eVBhdGhzJyBpcyBlaXRoZXIgbnVsbCBvciBvbWl0dGVkIHRoZW4gYWxsIG9yZGVyaW5nIGlzIHJlbW92ZWQuXHJcbiAgKiovXHJcbiAgb3JkZXJCeURlc2MocHJvcGVydHlQYXRoczogc3RyaW5nIHwgc3RyaW5nW10pIHtcclxuICAgIHJldHVybiB0aGlzLm9yZGVyQnkocHJvcGVydHlQYXRocyBhcyBhbnksIHRydWUpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIG5ldyBxdWVyeSB0aGF0IHNlbGVjdHMgYSBsaXN0IG9mIHByb3BlcnRpZXMgZnJvbSB0aGUgcmVzdWx0cyBvZiB0aGUgb3JpZ2luYWwgcXVlcnkgYW5kIHJldHVybnMgdGhlIHZhbHVlcyBvZiBqdXN0IHRoZXNlIHByb3BlcnRpZXMuIFRoaXNcclxuICB3aWxsIGJlIHJlZmVycmVkIHRvIGFzIGEgcHJvamVjdGlvbi5cclxuICBJZiB0aGUgcmVzdWx0IG9mIHRoaXMgc2VsZWN0aW9uIFwicHJvamVjdGlvblwiIGNvbnRhaW5zIGVudGl0aWVzLCB0aGVzZSBlbnRpdGllcyB3aWxsIGF1dG9tYXRpY2FsbHkgYmUgYWRkZWQgdG8gRW50aXR5TWFuYWdlcidzIGNhY2hlIGFuZCB3aWxsXHJcbiAgYmUgbWFkZSAnb2JzZXJ2YWJsZScuXHJcbiAgQW55IHNpbXBsZSBwcm9wZXJ0aWVzLCBpLmUuIHN0cmluZ3MsIG51bWJlcnMgb3IgZGF0ZXMgd2l0aGluIGEgcHJvamVjdGlvbiB3aWxsIG5vdCBiZSBjYWNoZWQgYXJlIHdpbGwgTk9UIGJlIG1hZGUgJ29ic2VydmFibGUnLlxyXG4gIFxyXG4gIFNpbXBsZSBkYXRhIHByb3BlcnRpZXMgY2FuIGJlIHByb2plY3RlZFxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgICAud2hlcmUoXCJDb21wYW55TmFtZVwiLCBcInN0YXJ0c1dpdGhcIiwgXCJDXCIpXHJcbiAgPiAgICAgICAgIC5zZWxlY3QoXCJDb21wYW55TmFtZVwiKTtcclxuXHJcbiAgVGhpcyB3aWxsIHJldHVybiBhbiBhcnJheSBvZiBvYmplY3RzIGVhY2ggd2l0aCBhIHNpbmdsZSBcIkNvbXBhbnlOYW1lXCIgcHJvcGVydHkgb2YgdHlwZSBzdHJpbmcuXHJcbiAgQSBzaW1pbGFyIHF1ZXJ5IGNvdWxkIHJldHVybiBhIG5hdmlnYXRpb24gcHJvcGVydHkgaW5zdGVhZFxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgIC53aGVyZShcIkNvbXBhbnlOYW1lXCIsIFwic3RhcnRzV2l0aFwiLCBcIkNcIilcclxuICA+ICAgICAgICAuc2VsZWN0KFwiT3JkZXJzXCIpO1xyXG5cclxuICB3aGVyZSB0aGUgcmVzdWx0IHdvdWxkIGJlIGFuIGFycmF5IG9mIG9iamVjdHMgZWFjaCB3aXRoIGEgc2luZ2xlIFwiT3JkZXJzXCIgcHJvcGVydHkgdGhhdCB3b3VsZCBpdHNlbGYgYmUgYW4gYXJyYXkgb2YgXCJPcmRlclwiIGVudGl0aWVzLlxyXG4gIENvbXBvc2l0ZSBwcm9qZWN0aW9ucyBhcmUgYWxzbyBwb3NzaWJsZTpcclxuICA+ICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIilcclxuICA+ICAgICAgICAud2hlcmUoXCJDb21wYW55TmFtZVwiLCBcInN0YXJ0c1dpdGhcIiwgXCJDXCIpXHJcbiAgPiAgICAgICAgLnNlbGVjdChcIkNvbXBhbnlOYW1lLCBPcmRlcnNcIik7XHJcblxyXG4gIEFzIHdlbGwgYXMgcHJvamVjdGlvbnMgaW52b2x2aW5nIG5lc3RlZCBwcm9wZXJ0eSBwYXRoc1xyXG4gID4gICAgIGxldCBxdWVyeSA9IEVudGl0eVF1ZXJ5KFwiT3JkZXJzXCIpXHJcbiAgPiAgICAgICAgLndoZXJlKFwiQ3VzdG9tZXIuQ29tcGFueU5hbWVcIiwgXCJzdGFydHNXaXRoXCIsIFwiQ1wiKVxyXG4gID4gICAgICAgIC5zZWxlY3QoXCJDdXN0b21lci5Db21wYW55TmFtZSwgQ3VzdG9tZXIsIE9yZGVyRGF0ZVwiKTtcclxuICBAcGFyYW0gcHJvcGVydHlQYXRocyAtIEEgY29tbWEtc2VwYXJhdGVkICgnLCcpIHN0cmluZyBvZiBwcm9wZXJ0eSBwYXRocyBvciBhbiBhcnJheSBvZiBwcm9wZXJ0eSBwYXRocy5cclxuICBJZiAncHJvcGVydHlQYXRocycgaXMgZWl0aGVyIG51bGwgb3Igb21pdHRlZCB0aGVuIGFueSBleGlzdGluZyBwcm9qZWN0aW9uIG9uIHRoZSBxdWVyeSBpcyByZW1vdmVkLlxyXG4gICoqL1xyXG4gIHNlbGVjdChwcm9wZXJ0eVBhdGhzPzogc3RyaW5nIHwgc3RyaW5nW10pIHtcclxuICAgIGxldCBzZWxlY3RDbGF1c2UgPSBwcm9wZXJ0eVBhdGhzID09IG51bGwgPyBudWxsIDogbmV3IFNlbGVjdENsYXVzZShub3JtYWxpemVQcm9wZXJ0eVBhdGhzKHByb3BlcnR5UGF0aHMpKTtcclxuICAgIHJldHVybiBjbG9uZSh0aGlzLCBcInNlbGVjdENsYXVzZVwiLCBzZWxlY3RDbGF1c2UpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIG5ldyBxdWVyeSB0aGF0IHNraXBzIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGVudGl0aWVzIHdoZW4gcmV0dXJuaW5nIHJlc3VsdHMuXHJcbiAgQW55IGV4aXN0aW5nICdza2lwJyBjYW4gYmUgY2xlYXJlZCBieSBjYWxsaW5nICdza2lwJyB3aXRoIG5vIGFyZ3VtZW50cy5cclxuICA+ICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIilcclxuICA+ICAgICAgIC53aGVyZShcIkNvbXBhbnlOYW1lXCIsIFwic3RhcnRzV2l0aFwiLCBcIkNcIilcclxuICA+ICAgICAgIC5za2lwKDUpO1xyXG4gIEBwYXJhbSBjb3VudCAtIFRoZSBudW1iZXIgb2YgZW50aXRpZXMgdG8gc2tpcCBvdmVyLiBJZiBvbWl0dGVkIG9yIG51bGwgYW55IGV4aXN0aW5nIHNraXAgY291bnQgb24gdGhlIHF1ZXJ5IGlzIHJlbW92ZWQuXHJcbiAgKiovXHJcbiAgc2tpcChjb3VudD86IG51bWJlcikge1xyXG4gICAgYXNzZXJ0UGFyYW0oY291bnQsIFwiY291bnRcIikuaXNPcHRpb25hbCgpLmlzTnVtYmVyKCkuY2hlY2soKTtcclxuICAgIHJldHVybiBjbG9uZSh0aGlzLCBcInNraXBDb3VudFwiLCAoY291bnQgPT0gbnVsbCkgPyBudWxsIDogY291bnQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIG5ldyBxdWVyeSB0aGF0IHJldHVybnMgb25seSB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBlbnRpdGllcyB3aGVuIHJldHVybmluZyByZXN1bHRzLiAtIFNhbWUgYXMgJ3Rha2UnLlxyXG4gIEFueSBleGlzdGluZyAndG9wJyBjYW4gYmUgY2xlYXJlZCBieSBjYWxsaW5nICd0b3AnIHdpdGggbm8gYXJndW1lbnRzLlxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgIC50b3AoNSk7XHJcbiAgQHBhcmFtIGNvdW50IC0gVGhlIG51bWJlciBvZiBlbnRpdGllcyB0byByZXR1cm4uXHJcbiAgSWYgJ2NvdW50JyBpcyBlaXRoZXIgbnVsbCBvciBvbWl0dGVkIHRoZW4gYW55IGV4aXN0aW5nICd0b3AnIGNvdW50IG9uIHRoZSBxdWVyeSBpcyByZW1vdmVkLlxyXG4gICoqL1xyXG4gIHRvcChjb3VudD86IG51bWJlcikge1xyXG4gICAgcmV0dXJuIHRoaXMudGFrZShjb3VudCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIGEgbmV3IHF1ZXJ5IHRoYXQgcmV0dXJucyBvbmx5IHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGVudGl0aWVzIHdoZW4gcmV0dXJuaW5nIHJlc3VsdHMgLSBTYW1lIGFzICd0b3AnLlxyXG4gIEFueSBleGlzdGluZyB0YWtlIGNhbiBiZSBjbGVhcmVkIGJ5IGNhbGxpbmcgdGFrZSB3aXRoIG5vIGFyZ3VtZW50cy5cclxuICA+ICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJDdXN0b21lcnNcIilcclxuICA+ICAgICAgICAudGFrZSg1KTtcclxuICBAcGFyYW0gY291bnQgLSBUaGUgbnVtYmVyIG9mIGVudGl0aWVzIHRvIHJldHVybi5cclxuICBJZiAnY291bnQnIGlzIGVpdGhlciBudWxsIG9yIG9taXR0ZWQgdGhlbiBhbnkgZXhpc3RpbmcgJ3Rha2UnIGNvdW50IG9uIHRoZSBxdWVyeSBpcyByZW1vdmVkLlxyXG4gICoqL1xyXG4gIHRha2UoY291bnQ/OiBudW1iZXIpIHtcclxuICAgIGFzc2VydFBhcmFtKGNvdW50LCBcImNvdW50XCIpLmlzT3B0aW9uYWwoKS5pc051bWJlcigpLmNoZWNrKCk7XHJcbiAgICByZXR1cm4gY2xvbmUodGhpcywgXCJ0YWtlQ291bnRcIiwgKGNvdW50ID09IG51bGwpID8gbnVsbCA6IGNvdW50KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgYSBuZXcgcXVlcnkgdGhhdCB3aWxsIHJldHVybiByZWxhdGVkIGVudGl0aWVzIG5lc3RlZCB3aXRoaW4gaXRzIHJlc3VsdHMuIFRoZSBleHBhbmQgbWV0aG9kIGFsbG93cyB5b3UgdG8gaWRlbnRpZnkgcmVsYXRlZCBlbnRpdGllcywgdmlhIG5hdmlnYXRpb24gcHJvcGVydHlcclxuICBuYW1lcyBzdWNoIHRoYXQgYSBncmFwaCBvZiBlbnRpdGllcyBtYXkgYmUgcmV0cmlldmVkIHdpdGggYSBzaW5nbGUgcmVxdWVzdC4gQW55IGZpbHRlcmluZyBvY2N1cnMgYmVmb3JlIHRoZSByZXN1bHRzIGFyZSAnZXhwYW5kZWQnLlxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgIC53aGVyZShcIkNvbXBhbnlOYW1lXCIsIFwic3RhcnRzV2l0aFwiLCBcIkNcIilcclxuICA+ICAgICAgICAuZXhwYW5kKFwiT3JkZXJzXCIpO1xyXG5cclxuICB3aWxsIHJldHVybiB0aGUgZmlsdGVyZWQgY3VzdG9tZXJzIGVhY2ggd2l0aCBpdHMgXCJPcmRlcnNcIiBwcm9wZXJ0aWVzIGZ1bGx5IHJlc29sdmVkLlxyXG4gIE11bHRpcGxlIHBhdGhzIG1heSBiZSBzcGVjaWZpZWQgYnkgc2VwYXJhdGluZyB0aGUgcGF0aHMgYnkgYSAnLCdcclxuICA+ICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJPcmRlcnNcIilcclxuICA+ICAgICAgICAuZXhwYW5kKFwiQ3VzdG9tZXIsIEVtcGxveWVlXCIpXHJcblxyXG4gIGFuZCBuZXN0ZWQgcHJvcGVydHkgcGF0aHMgbXkgYmUgc3BlY2lmaWVkIGFzIHdlbGxcclxuICA+ICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJPcmRlcnNcIilcclxuICA+ICAgICAgICAuZXhwYW5kKFwiQ3VzdG9tZXIsIE9yZGVyRGV0YWlscywgT3JkZXJEZXRhaWxzLlByb2R1Y3RcIilcclxuICBAcGFyYW0gcHJvcGVydHlQYXRocyAtIEEgY29tbWEtc2VwYXJhdGVkIGxpc3Qgb2YgbmF2aWdhdGlvbiBwcm9wZXJ0eSBuYW1lcyBvciBhbiBhcnJheSBvZiBuYXZpZ2F0aW9uIHByb3BlcnR5IG5hbWVzLiBFYWNoIE5hdmlnYXRpb24gUHJvcGVydHkgbmFtZSBjYW4gYmUgZm9sbG93ZWRcclxuICBieSBhICcuJyBhbmQgYW5vdGhlciBuYXZpZ2F0aW9uIHByb3BlcnR5IG5hbWUgdG8gZW5hYmxlIGlkZW50aWZ5aW5nIGEgbXVsdGktbGV2ZWwgcmVsYXRpb25zaGlwLlxyXG4gIElmICdwcm9wZXJ0eVBhdGhzJyBpcyBlaXRoZXIgbnVsbCBvciBvbWl0dGVkIHRoZW4gYW55IGV4aXN0aW5nICdleHBhbmQnIGNsYXVzZSBvbiB0aGUgcXVlcnkgaXMgcmVtb3ZlZC5cclxuICAqKi9cclxuICBleHBhbmQocHJvcGVydHlQYXRocz86IHN0cmluZyB8IHN0cmluZ1tdKSB7XHJcbiAgICBsZXQgZXhwYW5kQ2xhdXNlID0gcHJvcGVydHlQYXRocyA9PSBudWxsID8gbnVsbCA6IG5ldyBFeHBhbmRDbGF1c2Uobm9ybWFsaXplUHJvcGVydHlQYXRocyhwcm9wZXJ0eVBhdGhzKSk7XHJcbiAgICByZXR1cm4gY2xvbmUodGhpcywgXCJleHBhbmRDbGF1c2VcIiwgZXhwYW5kQ2xhdXNlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgYSBuZXcgcXVlcnkgdGhhdCBpbmNsdWRlcyBhIGNvbGxlY3Rpb24gb2YgcGFyYW1ldGVycyB0byBwYXNzIHRvIHRoZSBzZXJ2ZXIuXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gRW50aXR5UXVlcnkuZnJvbShcIkVtcGxveWVlc0ZpbHRlcmVkQnlDb3VudHJ5QW5kQmlydGhkYXRlXCIpXHJcbiAgPiAgICAgICAgLndpdGhQYXJhbWV0ZXJzKHsgQmlydGhEYXRlOiBcIjEvMS8xOTYwXCIsIENvdW50cnk6IFwiVVNBXCIgfSk7XHJcbiAgIFxyXG4gIHdpbGwgY2FsbCB0aGUgJ0VtcGxveWVlc0ZpbHRlcmVkQnlDb3VudHJ5QW5kQmlydGhkYXRlJyBtZXRob2Qgb24gdGhlIHNlcnZlciBhbmQgcGFzcyBpbiAyIHBhcmFtZXRlcnMuIFRoaXNcclxuICBxdWVyeSB3aWxsIGJlIHVyaSBlbmNvZGVkIGFzXHJcbiAgPiAgICAgIHtzZXJ2aWNlQXBpfS9FbXBsb3llZXNGaWx0ZXJlZEJ5Q291bnRyeUFuZEJpcnRoZGF0ZT9iaXJ0aERhdGU9MSUyRjElMkYxOTYwJmNvdW50cnk9VVNBXHJcblxyXG4gIFBhcmFtZXRlcnMgbWF5IGFsc28gYmUgbWl4ZWQgaW4gd2l0aCBvdGhlciBxdWVyeSBjcml0ZXJpYS5cclxuICA+ICAgICBsZXQgcXVlcnkgPSBFbnRpdHlRdWVyeS5mcm9tKFwiRW1wbG95ZWVzRmlsdGVyZWRCeUNvdW50cnlBbmRCaXJ0aGRhdGVcIilcclxuICA+ICAgICAgICAud2l0aFBhcmFtZXRlcnMoeyBCaXJ0aERhdGU6IFwiMS8xLzE5NjBcIiwgQ291bnRyeTogXCJVU0FcIiB9KVxyXG4gID4gICAgICAgIC53aGVyZShcIkxhc3ROYW1lXCIsIFwic3RhcnRzV2l0aFwiLCBcIlNcIilcclxuICA+ICAgICAgICAub3JkZXJCeShcIkJpcnRoRGF0ZVwiKTtcclxuICBAcGFyYW0gcGFyYW1ldGVycyAtIEEgcGFyYW1ldGVycyBvYmplY3Qgd2hlcmUgdGhlIGtleXMgYXJlIHRoZSBwYXJhbWV0ZXIgbmFtZXMgYW5kIHRoZSB2YWx1ZXMgYXJlIHRoZSBwYXJhbWV0ZXIgdmFsdWVzLlxyXG4gICoqL1xyXG4gIHdpdGhQYXJhbWV0ZXJzKHBhcmFtZXRlcnM6IE9iamVjdCkge1xyXG4gICAgYXNzZXJ0UGFyYW0ocGFyYW1ldGVycywgXCJwYXJhbWV0ZXJzXCIpLmlzT2JqZWN0KCkuY2hlY2soKTtcclxuICAgIHJldHVybiBjbG9uZSh0aGlzLCBcInBhcmFtZXRlcnNcIiwgcGFyYW1ldGVycyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBSZXR1cm5zIGEgcXVlcnkgd2l0aCB0aGUgYGlubGluZUNvdW50YCBjYXBhYmlsaXR5IGVpdGhlciBlbmFibGVkIG9yIGRpc2FibGVkLiAgV2l0aCBgaW5saW5lQ291bnRgIGVuYWJsZWQsIGFuIGFkZGl0aW9uYWwgJ2lubGluZUNvdW50JyBwcm9wZXJ0eVxyXG4gIHdpbGwgYmUgcmV0dXJuZWQgd2l0aCB0aGUgcXVlcnkgcmVzdWx0cyB0aGF0IHdpbGwgY29udGFpbiB0aGUgbnVtYmVyIG9mIGVudGl0aWVzIHRoYXQgd291bGQgaGF2ZSBiZWVuIHJldHVybmVkIGJ5IHRoaXNcclxuICBxdWVyeSB3aXRoIG9ubHkgdGhlICd3aGVyZScvJ2ZpbHRlcicgY2xhdXNlcyBhcHBsaWVkLCBpLmUuIHdpdGhvdXQgYW55ICdza2lwJy8ndGFrZScgb3BlcmF0b3JzIGFwcGxpZWQuIEZvciBsb2NhbCBxdWVyaWVzIHRoaXMgY2xhdXNlIGlzIGlnbm9yZWQuXHJcbiAgPiAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiQ3VzdG9tZXJzXCIpXHJcbiAgPiAgICAgICAgLnRha2UoMjApXHJcbiAgPiAgICAgICAgLm9yZGVyQnkoXCJDb21wYW55TmFtZVwiKVxyXG4gID4gICAgICAgIC5pbmxpbmVDb3VudCh0cnVlKTtcclxuXHJcbiAgd2lsbCByZXR1cm4gdGhlIGZpcnN0IDIwIGN1c3RvbWVycyBhcyB3ZWxsIGFzIGEgY291bnQgb2YgX2FsbF8gb2YgdGhlIGN1c3RvbWVycyBpbiB0aGUgcmVtb3RlIHN0b3JlLlxyXG4gIEBwYXJhbSBlbmFibGVkIC0gKGRlZmF1bHQgPSB0cnVlKSBXaGV0aGVyIG9yIG5vdCBpbmxpbmVDb3VudCBjYXBhYmlsaXR5IHNob3VsZCBiZSBlbmFibGVkLiBJZiB0aGlzIHBhcmFtZXRlciBpcyBvbWl0dGVkLCB0cnVlIGlzIGFzc3VtZWQuXHJcbiAgKiovXHJcbiAgaW5saW5lQ291bnQoZW5hYmxlZD86IGJvb2xlYW4pIHtcclxuICAgIGFzc2VydFBhcmFtKGVuYWJsZWQsIFwiZW5hYmxlZFwiKS5pc0Jvb2xlYW4oKS5pc09wdGlvbmFsKCkuY2hlY2soKTtcclxuICAgIGVuYWJsZWQgPSAoZW5hYmxlZCA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiAhIWVuYWJsZWQ7XHJcbiAgICByZXR1cm4gY2xvbmUodGhpcywgXCJpbmxpbmVDb3VudEVuYWJsZWRcIiwgZW5hYmxlZCk7XHJcbiAgfVxyXG5cclxuICB1c2VOYW1lT25TZXJ2ZXIodXNlc05hbWVPblNlcnZlcj86IGJvb2xlYW4pIHtcclxuICAgIGFzc2VydFBhcmFtKHVzZXNOYW1lT25TZXJ2ZXIsIFwidXNlc05hbWVPblNlcnZlclwiKS5pc0Jvb2xlYW4oKS5pc09wdGlvbmFsKCkuY2hlY2soKTtcclxuICAgIHVzZXNOYW1lT25TZXJ2ZXIgPSAodXNlc05hbWVPblNlcnZlciA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiAhIXVzZXNOYW1lT25TZXJ2ZXI7XHJcbiAgICByZXR1cm4gY2xvbmUodGhpcywgXCJ1c2VzTmFtZU9uU2VydmVyXCIsIHVzZXNOYW1lT25TZXJ2ZXIpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIHF1ZXJ5IHdpdGggdGhlIGBub1RyYWNraW5nYCBjYXBhYmlsaXR5IGVpdGhlciBlbmFibGVkIG9yIGRpc2FibGVkLiAgV2l0aCBgbm9UcmFja2luZ2AgZW5hYmxlZCwgdGhlIHJlc3VsdHMgb2YgdGhpcyBxdWVyeVxyXG4gIHdpbGwgbm90IGJlIGNvZXJjZWQgaW50byBlbnRpdGllcyBidXQgd2lsbCBpbnN0ZWFkIGxvb2sgbGlrZSByYXcgamF2YXNjcmlwdCBwcm9qZWN0aW9ucy4gaS5lLiBzaW1wbGUgamF2YXNjcmlwdCBvYmplY3RzLlxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgICAudGFrZSgyMClcclxuICA+ICAgICAgICAgLm9yZGVyQnkoXCJDb21wYW55TmFtZVwiKVxyXG4gID4gICAgICAgICAubm9UcmFja2luZyh0cnVlKTtcclxuICBAcGFyYW0gZW5hYmxlZCAtIChkZWZhdWx0ID0gdHJ1ZSkgV2hldGhlciBvciBub3QgdGhlIG5vVHJhY2tpbmcgY2FwYWJpbGl0eSBzaG91bGQgYmUgZW5hYmxlZC4gSWYgdGhpcyBwYXJhbWV0ZXIgaXMgb21pdHRlZCwgdHJ1ZSBpcyBhc3N1bWVkLlxyXG4gICoqL1xyXG4gIG5vVHJhY2tpbmcoZW5hYmxlZD86IGJvb2xlYW4pIHtcclxuICAgIGFzc2VydFBhcmFtKGVuYWJsZWQsIFwiZW5hYmxlZFwiKS5pc0Jvb2xlYW4oKS5pc09wdGlvbmFsKCkuY2hlY2soKTtcclxuICAgIGVuYWJsZWQgPSAoZW5hYmxlZCA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiAhIWVuYWJsZWQ7XHJcbiAgICByZXR1cm4gY2xvbmUodGhpcywgXCJub1RyYWNraW5nRW5hYmxlZFwiLCBlbmFibGVkKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIFJldHVybnMgYSBxdWVyeSB3aXRoIHRoZSBgdXNlUG9zdGAgY2FwYWJpbGl0eSBlaXRoZXIgZW5hYmxlZCBvciBkaXNhYmxlZC4gIFdpdGggYHVzZVBvc3RgIGVuYWJsZWQsIHRoZSBxdWVyeSBpcyBzZW50XHJcbiAgYXMgYSBQT1NUIHJlcXVlc3QgKGluc3RlYWQgb2YgR0VUKSBhbmQgdGhlIHF1ZXJ5IGV4cHJlc3Npb24gd2lsbCBiZSBzZW50IGFzIEpTT04gaW4gdGhlIGJvZHkgb2YgdGhlIHBvc3QuXHJcbiAgTm90ZSB0aGF0IHRoZSBzZXJ2ZXIgbXVzdCBiZSBhYmxlIHRvIHBhcnNlIHRoZSBib2R5IG9mIHRoZSByZXF1ZXN0OyBvdGhlcndpc2UgdGhlIHF1ZXJ5IGV4cHJlc3Npb24gd2lsbCBiZSBpZ25vcmVkLlxyXG4gID4gICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIkN1c3RvbWVyc1wiKVxyXG4gID4gICAgICAgICAud2hlcmUoXCJjb21wYW55SWRcIiwgXCJlcVwiLCAxKVxyXG4gID4gICAgICAgICAudXNlUG9zdCh0cnVlKTtcclxuICByZXN1bHRzIGluIGEgUE9TVCByZXF1ZXN0IHRvIGB7aG9zdH0ve3BhdGh9L0N1c3RvbWVyc2BcclxuICB3aXRoIGJvZHkgYHtcIndoZXJlXCI6IHtcImNvbXBhbnlJZFwiOntcImVxXCI6MX19fWBcclxuICBAcGFyYW0gZW5hYmxlZCAtIChkZWZhdWx0ID0gdHJ1ZSkgV2hldGhlciBvciBub3QgdXNlUG9zdCBzaG91bGQgYmUgZW5hYmxlZC4gSWYgdGhpcyBwYXJhbWV0ZXIgaXMgb21pdHRlZCwgdHJ1ZSBpcyBhc3N1bWVkLlxyXG4gICoqL1xyXG4gIHVzZVBvc3QoZW5hYmxlZD86IGJvb2xlYW4pIHtcclxuICAgIGFzc2VydFBhcmFtKGVuYWJsZWQsIFwiZW5hYmxlZFwiKS5pc0Jvb2xlYW4oKS5pc09wdGlvbmFsKCkuY2hlY2soKTtcclxuICAgIGVuYWJsZWQgPSAoZW5hYmxlZCA9PT0gdW5kZWZpbmVkKSA/IHRydWUgOiAhIWVuYWJsZWQ7XHJcbiAgICByZXR1cm4gY2xvbmUodGhpcywgXCJ1c2VQb3N0RW5hYmxlZFwiLCBlbmFibGVkKTtcclxuICB9XHJcblxyXG4gIHVzaW5nKG9iajogRW50aXR5TWFuYWdlcik6IEVudGl0eVF1ZXJ5O1xyXG4gIHVzaW5nKG9iajogRGF0YVNlcnZpY2UpOiBFbnRpdHlRdWVyeTtcclxuICB1c2luZyhvYmo6IEpzb25SZXN1bHRzQWRhcHRlcik6IEVudGl0eVF1ZXJ5O1xyXG4gIHVzaW5nKG9iajogUXVlcnlPcHRpb25zKTogRW50aXR5UXVlcnk7XHJcbiAgdXNpbmcob2JqOiBNZXJnZVN0cmF0ZWd5KTogRW50aXR5UXVlcnk7XHJcbiAgdXNpbmcob2JqOiBGZXRjaFN0cmF0ZWd5KTogRW50aXR5UXVlcnk7XHJcbiAgLyoqXHJcbiAgUmV0dXJucyBhIGNvcHkgb2YgdGhpcyBFbnRpdHlRdWVyeSB3aXRoIHRoZSBzcGVjaWZpZWQgW1tFbnRpdHlNYW5hZ2VyXV0sIFtbRGF0YVNlcnZpY2VdXSxcclxuICBbW0pzb25SZXN1bHRzQWRhcHRlcl1dLCBbW01lcmdlU3RyYXRlZ3ldXSBvciBbW0ZldGNoU3RyYXRlZ3ldXSBhcHBsaWVkLlxyXG4gID4gICAgICAvLyAndXNpbmcnIGNhbiBiZSB1c2VkIHRvIHJldHVybiBhIG5ldyBxdWVyeSB3aXRoIGEgc3BlY2lmaWVkIEVudGl0eU1hbmFnZXIuXHJcbiAgPiAgICAgIGxldCBlbSA9IG5ldyBFbnRpdHlNYW5hZ2VyKHNlcnZpY2VOYW1lKTtcclxuICA+ICAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiT3JkZXJzXCIpXHJcbiAgPiAgICAgICAgLnVzaW5nKGVtKTtcclxuXHJcbiAgb3Igd2l0aCBhIHNwZWNpZmllZCBbW01lcmdlU3RyYXRlZ3ldXVxyXG4gID4gICAgICBsZXQgZW0gPSBuZXcgRW50aXR5TWFuYWdlcihzZXJ2aWNlTmFtZSk7XHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIk9yZGVyc1wiKVxyXG4gID4gICAgICAgIC51c2luZyhNZXJnZVN0cmF0ZWd5LlByZXNlcnZlQ2hhbmdlcyk7XHJcblxyXG4gIG9yIHdpdGggYSBzcGVjaWZpZWQgW1tGZXRjaFN0cmF0ZWd5XV1cclxuICA+ICAgICAgbGV0IGVtID0gbmV3IEVudGl0eU1hbmFnZXIoc2VydmljZU5hbWUpO1xyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJPcmRlcnNcIilcclxuICA+ICAgICAgICAudXNpbmcoRmV0Y2hTdHJhdGVneS5Gcm9tTG9jYWxDYWNoZSk7XHJcbiAgQHBhcmFtIG9iaiAtIFRoZSBvYmplY3QgdG8gdXBkYXRlIGluIGNyZWF0aW5nIGEgbmV3IEVudGl0eVF1ZXJ5IGZyb20gYW4gZXhpc3Rpbmcgb25lLlxyXG4gICoqL1xyXG4gIHVzaW5nKG9iajogYW55KSB7XHJcbiAgICBpZiAoIW9iaikgcmV0dXJuIHRoaXM7XHJcbiAgICBsZXQgZXEgPSBjbG9uZSh0aGlzKTtcclxuICAgIHByb2Nlc3NVc2luZyhlcSwge1xyXG4gICAgICBcImVudGl0eU1hbmFnZXJcIjogbnVsbCxcclxuICAgICAgXCJkYXRhU2VydmljZVwiOiBudWxsLFxyXG4gICAgICBcInF1ZXJ5T3B0aW9uc1wiOiBudWxsLFxyXG4gICAgICBcImZldGNoU3RyYXRlZ3lcIjogKGVxOiBFbnRpdHlRdWVyeSwgdmFsOiBhbnkpID0+IHtcclxuICAgICAgICBlcS5xdWVyeU9wdGlvbnMgPSAoZXEucXVlcnlPcHRpb25zIHx8IG5ldyBRdWVyeU9wdGlvbnMoKSkudXNpbmcodmFsKTtcclxuICAgICAgfSxcclxuICAgICAgXCJtZXJnZVN0cmF0ZWd5XCI6IChlcTogRW50aXR5UXVlcnksIHZhbDogYW55KSA9PiB7XHJcbiAgICAgICAgZXEucXVlcnlPcHRpb25zID0gKGVxLnF1ZXJ5T3B0aW9ucyB8fCBuZXcgUXVlcnlPcHRpb25zKCkpLnVzaW5nKHZhbCk7XHJcbiAgICAgIH0sXHJcbiAgICAgIFwianNvblJlc3VsdHNBZGFwdGVyXCI6IChlcTogRW50aXR5UXVlcnksIHZhbDogYW55KSA9PiB7XHJcbiAgICAgICAgZXEuZGF0YVNlcnZpY2UgPSAoZXEuZGF0YVNlcnZpY2UgfHwgbmV3IERhdGFTZXJ2aWNlKCkpLnVzaW5nKHsganNvblJlc3VsdHNBZGFwdGVyOiB2YWwgfSk7XHJcbiAgICAgIH1cclxuICAgIH0sIG9iaik7XHJcbiAgICByZXR1cm4gZXE7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBFeGVjdXRlcyB0aGlzIHF1ZXJ5LiAgVGhpcyBtZXRob2QgcmVxdWlyZXMgdGhhdCBhbiBFbnRpdHlNYW5hZ2VyIGhhcyBiZWVuIHByZXZpb3VzbHkgc3BlY2lmaWVkIHZpYSB0aGUgXCJ1c2luZ1wiIG1ldGhvZC5cclxuICBcclxuICBUaGlzIG1ldGhvZCBjYW4gYmUgY2FsbGVkIHVzaW5nIGEgJ3Byb21pc2VzJyBzeW50YXggKCByZWNvbW1lbmRlZClcclxuICA+ICAgICAgbGV0IGVtID0gbmV3IEVudGl0eU1hbmFnZXIoc2VydmljZU5hbWUpO1xyXG4gID4gICAgICBsZXQgcXVlcnkgPSBuZXcgRW50aXR5UXVlcnkoXCJPcmRlcnNcIikudXNpbmcoZW0pO1xyXG4gID4gICAgICBxdWVyeS5leGVjdXRlKCkudGhlbiggZnVuY3Rpb24oZGF0YSkge1xyXG4gID4gICAgICAgICAgLi4uIHF1ZXJ5IHJlc3VsdHMgcHJvY2Vzc2VkIGhlcmVcclxuICA+ICAgICAgfSkuY2F0Y2goIGZ1bmN0aW9uKGVycikge1xyXG4gID4gICAgICAgICAgLi4uIHF1ZXJ5IGZhaWx1cmUgcHJvY2Vzc2VkIGhlcmVcclxuICA+ICAgICAgfSk7XHJcblxyXG4gIG9yIHdpdGggY2FsbGJhY2tzXHJcbiAgPiAgICAgIGxldCBlbSA9IG5ldyBFbnRpdHlNYW5hZ2VyKHNlcnZpY2VOYW1lKTtcclxuICA+ICAgICAgbGV0IHF1ZXJ5ID0gbmV3IEVudGl0eVF1ZXJ5KFwiT3JkZXJzXCIpLnVzaW5nKGVtKTtcclxuICA+ICAgICAgcXVlcnkuZXhlY3V0ZShcclxuICA+ICAgICAgICBmdW5jdGlvbihkYXRhKSB7XHJcbiAgPiAgICAgICAgICAgICAgICAgICAgbGV0IG9yZGVycyA9IGRhdGEucmVzdWx0cztcclxuICA+ICAgICAgICAgICAgICAgICAgICAuLi4gcXVlcnkgcmVzdWx0cyBwcm9jZXNzZWQgaGVyZVxyXG4gID4gICAgICAgICAgICAgICAgfSxcclxuICA+ICAgICAgICBmdW5jdGlvbihlcnIpIHtcclxuICA+ICAgICAgICAgICAgICAgICAgICAuLi4gcXVlcnkgZmFpbHVyZSBwcm9jZXNzZWQgaGVyZVxyXG4gID4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gIEVpdGhlciB3YXkgdGhpcyBtZXRob2QgaXMgdGhlIHNhbWUgYXMgY2FsbGluZyB0aGUgRW50aXR5TWFuYWdlciAnZXhlY3V0ZScgbWV0aG9kLlxyXG4gID4gICAgICBsZXQgZW0gPSBuZXcgRW50aXR5TWFuYWdlcihzZXJ2aWNlTmFtZSk7XHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIk9yZGVyc1wiKTtcclxuICA+ICAgICAgZW0uZXhlY3V0ZVF1ZXJ5KHF1ZXJ5KS50aGVuKCBmdW5jdGlvbihkYXRhKSB7XHJcbiAgPiAgICAgICAgIGxldCBvcmRlcnMgPSBkYXRhLnJlc3VsdHM7XHJcbiAgPiAgICAgICAgICAuLi4gcXVlcnkgcmVzdWx0cyBwcm9jZXNzZWQgaGVyZVxyXG4gID4gICAgICB9KS5jYXRjaCggZnVuY3Rpb24oZXJyKSB7XHJcbiAgPiAgICAgICAgIC4uLiBxdWVyeSBmYWlsdXJlIHByb2Nlc3NlZCBoZXJlXHJcbiAgPiAgICAgIH0pO1xyXG5cclxuICBAcGFyYW0gY2FsbGJhY2sgLSAgRnVuY3Rpb24gY2FsbGVkIG9uIHN1Y2Nlc3MuXHJcbiAgQHBhcmFtIGVycm9yQ2FsbGJhY2sgLSBGdW5jdGlvbiBjYWxsZWQgb24gZmFpbHVyZS5cclxuICBAcmV0dXJuIFByb21pc2VcclxuICAqKi9cclxuICBleGVjdXRlKGNhbGxiYWNrPzogQ2FsbGJhY2ssIGVycm9yQ2FsbGJhY2s/OiBFcnJvckNhbGxiYWNrKTogUHJvbWlzZTxRdWVyeVJlc3VsdD4ge1xyXG4gICAgaWYgKCF0aGlzLmVudGl0eU1hbmFnZXIpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiQW4gRW50aXR5UXVlcnkgbXVzdCBoYXZlIGl0cyBFbnRpdHlNYW5hZ2VyIHByb3BlcnR5IHNldCBiZWZvcmUgY2FsbGluZyAnZXhlY3V0ZSdcIik7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5lbnRpdHlNYW5hZ2VyLmV4ZWN1dGVRdWVyeSh0aGlzLCBjYWxsYmFjaywgZXJyb3JDYWxsYmFjayk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBFeGVjdXRlcyB0aGlzIHF1ZXJ5IGFnYWluc3QgdGhlIGxvY2FsIGNhY2hlLiAgVGhpcyBtZXRob2QgcmVxdWlyZXMgdGhhdCBhbiBFbnRpdHlNYW5hZ2VyIGhhdmUgYmVlbiBwcmV2aW91c2x5IHNwZWNpZmllZCB2aWEgdGhlIFwidXNpbmdcIiBtZXRob2QuXHJcbiAgPiAgICAgIC8vIGFzc3VtZSBlbSBpcyBhbiBlbnRpdHlNYW5hZ2VyIGFscmVhZHkgZmlsbGVkIHdpdGggb3JkZXIgZW50aXRpZXM7XHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IG5ldyBFbnRpdHlRdWVyeShcIk9yZGVyc1wiKS51c2luZyhlbSk7XHJcbiAgPiAgICAgIGxldCBvcmRlcnMgPSBxdWVyeS5leGVjdXRlTG9jYWxseSgpO1xyXG5cclxuICBOb3RlIHRoYXQgY2FsbGluZyB0aGlzIG1ldGhvZCBpcyB0aGUgc2FtZSBhcyBjYWxsaW5nIFtbRW50aXR5TWFuYWdlci5leGVjdXRlUXVlcnlMb2NhbGx5XV0uXHJcbiAgKiovXHJcbiAgZXhlY3V0ZUxvY2FsbHkoKSB7XHJcbiAgICBpZiAoIXRoaXMuZW50aXR5TWFuYWdlcikge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBbiBFbnRpdHlRdWVyeSBtdXN0IGhhdmUgaXRzIEVudGl0eU1hbmFnZXIgcHJvcGVydHkgc2V0IGJlZm9yZSBjYWxsaW5nICdleGVjdXRlTG9jYWxseSdcIik7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5lbnRpdHlNYW5hZ2VyLmV4ZWN1dGVRdWVyeUxvY2FsbHkodGhpcyk7XHJcbiAgfVxyXG5cclxuICB0b0pTT04oKSB7XHJcbiAgICByZXR1cm4gdGhpcy50b0pTT05FeHQoKTtcclxuICB9XHJcblxyXG4gIC8qKiBUeXBpY2FsbHkgb25seSBmb3IgdXNlIHdoZW4gYnVpbGRpbmcgVXJpQnVpbGRlckFkYXB0ZXJzLiAgXHJcbiAgQGhpZGRlbiBAaW50ZXJuYWwgIFxyXG4gICovXHJcbiAgdG9KU09ORXh0KGNvbnRleHQ/OiBFbnRpdHlRdWVyeUpzb25Db250ZXh0KSB7XHJcbiAgICBjb250ZXh0ID0gY29udGV4dCB8fCB7fTtcclxuICAgIGNvbnRleHQuZW50aXR5VHlwZSA9IGNvbnRleHQuZW50aXR5VHlwZSB8fCB0aGlzLmZyb21FbnRpdHlUeXBlO1xyXG4gICAgY29udGV4dC5wcm9wZXJ0eVBhdGhGbiA9IGNvbnRleHQudG9OYW1lT25TZXJ2ZXIgPyBjb250ZXh0LmVudGl0eVR5cGUhLmNsaWVudFByb3BlcnR5UGF0aFRvU2VydmVyLmJpbmQoY29udGV4dC5lbnRpdHlUeXBlKSA6IGNvcmUuaWRlbnRpdHk7XHJcblxyXG4gICAgbGV0IHRvSlNPTkV4dEZuID0gZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICByZXR1cm4gdiA/IHYudG9KU09ORXh0KGNvbnRleHQpIDogdW5kZWZpbmVkO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBjb3JlLnRvSnNvbih0aGlzLCB7XHJcbiAgICAgIFwiZnJvbSxyZXNvdXJjZU5hbWVcIjogbnVsbCxcclxuICAgICAgXCJ0b1R5cGUscmVzdWx0RW50aXR5VHlwZVwiOiBmdW5jdGlvbiAodjogYW55KSB7XHJcbiAgICAgICAgLy8gcmVzdWx0RW50aXR5VHlwZSBjYW4gYmUgZWl0aGVyIGEgc3RyaW5nIG9yIGFuIGVudGl0eVR5cGVcclxuICAgICAgICByZXR1cm4gdiA/ICh0eXBlb2YgdiA9PT0gJ3N0cmluZycgPyB2IDogdi5uYW1lKSA6IHVuZGVmaW5lZDtcclxuICAgICAgfSxcclxuICAgICAgXCJ3aGVyZSx3aGVyZVByZWRpY2F0ZVwiOiB0b0pTT05FeHRGbixcclxuICAgICAgXCJvcmRlckJ5LG9yZGVyQnlDbGF1c2VcIjogdG9KU09ORXh0Rm4sXHJcbiAgICAgIFwic2VsZWN0LHNlbGVjdENsYXVzZVwiOiB0b0pTT05FeHRGbixcclxuICAgICAgXCJleHBhbmQsZXhwYW5kQ2xhdXNlXCI6IHRvSlNPTkV4dEZuLFxyXG4gICAgICBcInNraXAsc2tpcENvdW50XCI6IG51bGwsXHJcbiAgICAgIFwidGFrZSx0YWtlQ291bnRcIjogbnVsbCxcclxuICAgICAgcGFyYW1ldGVyczogZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICAgIHJldHVybiBjb3JlLmlzRW1wdHkodikgPyB1bmRlZmluZWQgOiB2O1xyXG4gICAgICB9LFxyXG4gICAgICBcImlubGluZUNvdW50LGlubGluZUNvdW50RW5hYmxlZFwiOiBmYWxzZSxcclxuICAgICAgXCJub1RyYWNraW5nLG5vVHJhY2tpbmdFbmFibGVkXCI6IGZhbHNlLFxyXG4gICAgICBxdWVyeU9wdGlvbnM6IG51bGxcclxuICAgIH0pO1xyXG5cclxuICB9XHJcblxyXG4gIHN0YXRpYyBmcm9tRW50aXRpZXMoZW50aXR5OiBFbnRpdHkpOiBFbnRpdHlRdWVyeTtcclxuICBzdGF0aWMgZnJvbUVudGl0aWVzKGVudGl0aWVzOiBFbnRpdHlbXSk6IEVudGl0eVF1ZXJ5O1xyXG4gIC8qKlxyXG4gIFN0YXRpYyBtZXRob2QgdGhhdCBjcmVhdGVzIGFuIEVudGl0eVF1ZXJ5IHRoYXQgd2lsbCBhbGxvdyAncmVxdWVyeWluZycgYW4gZW50aXR5IG9yIGEgY29sbGVjdGlvbiBvZiBlbnRpdGllcyBieSBwcmltYXJ5IGtleS4gVGhpcyBjYW4gYmUgdXNlZnVsXHJcbiAgdG8gZm9yY2UgYSByZXF1ZXJ5IG9mIHNlbGVjdGVkIGVudGl0aWVzLCBvciB0byByZXN0cmljdCBhbiBleGlzdGluZyBjb2xsZWN0aW9uIG9mIGVudGl0aWVzIGFjY29yZGluZyB0byBzb21lIGZpbHRlci5cclxuXHJcbiAgV29ya3MgZm9yIGEgc2luZ2xlIGVudGl0eSBvciBhbiBhcnJheSBvZiBlbnRpdGllcyBvZiB0aGUgU0FNRSB0eXBlLlxyXG4gIERvZXMgbm90IHdvcmsgZm9yIGFuIGFycmF5IG9mIGVudGl0aWVzIG9mIGRpZmZlcmVudCB0eXBlcy5cclxuICA+ICAgICAgLy8gYXNzdW1pbmcgJ2N1c3RvbWVycycgaXMgYW4gYXJyYXkgb2YgJ0N1c3RvbWVyJyBlbnRpdGllcyByZXRyaWV2ZWQgZWFybGllci5cclxuICA+ICAgICAgbGV0IGN1c3RvbWVyc1F1ZXJ5ID0gRW50aXR5UXVlcnkuZnJvbUVudGl0aWVzKGN1c3RvbWVycyk7XHJcblxyXG4gIFRoZSByZXN1bHRpbmcgcXVlcnkgY2FuLCBvZiBjb3Vyc2UsIGJlIGV4dGVuZGVkXHJcbiAgPiAgICAgIC8vIGFzc3VtaW5nICdjdXN0b21lcnMnIGlzIGFuIGFycmF5IG9mICdDdXN0b21lcicgZW50aXRpZXMgcmV0cmlldmVkIGVhcmxpZXIuXHJcbiAgPiAgICAgIGxldCBjdXN0b21lcnNRdWVyeSA9IEVudGl0eVF1ZXJ5LmZyb21FbnRpdGllcyhjdXN0b21lcnMpXHJcbiAgPiAgICAgICAgLndoZXJlKFwiUmVnaW9uXCIsIEZpbHRlclF1ZXJ5T3AuTm90RXF1YWxzLCBudWxsKTtcclxuXHJcbiAgU2luZ2xlIGVudGl0aWVzIGNhbiByZXF1ZXJpZWQgYXMgd2VsbC5cclxuICA+ICAgICAgLy8gYXNzdW1pbmcgJ2N1c3RvbWVyJyBpcyBhICdDdXN0b21lcicgZW50aXR5IHJldHJpZXZlZCBlYXJsaWVyLlxyXG4gID4gICAgICBsZXQgY3VzdG9tZXJRdWVyeSA9IEVudGl0eVF1ZXJ5LmZyb21FbnRpdGllcyhjdXN0b21lcik7XHJcblxyXG4gIHdpbGwgY3JlYXRlIGEgcXVlcnkgdGhhdCB3aWxsIHJldHVybiBhbiBhcnJheSBjb250YWluaW5nIGEgc2luZ2xlIGN1c3RvbWVyIGVudGl0eS5cclxuICBAcGFyYW0gZW50aXRpZXMgLSBUaGUgZW50aXRpZXMgZm9yIHdoaWNoIHdlIHdhbnQgdG8gY3JlYXRlIGFuIEVudGl0eVF1ZXJ5LlxyXG4gICoqL1xyXG4gIHN0YXRpYyBmcm9tRW50aXRpZXMoZW50aXRpZXM6IEVudGl0eSB8IEVudGl0eVtdKSB7XHJcbiAgICBhc3NlcnRQYXJhbShlbnRpdGllcywgXCJlbnRpdGllc1wiKS5pc0VudGl0eSgpLm9yKCkuaXNOb25FbXB0eUFycmF5KCkuaXNFbnRpdHkoKS5jaGVjaygpO1xyXG4gICAgbGV0IGVudHMgPSAoQXJyYXkuaXNBcnJheShlbnRpdGllcykpID8gZW50aXRpZXMgOiBbZW50aXRpZXNdO1xyXG5cclxuICAgIGxldCBmaXJzdEVudGl0eSA9IGVudHNbMF07XHJcbiAgICBsZXQgdHlwZSA9IGZpcnN0RW50aXR5LmVudGl0eVR5cGU7XHJcbiAgICBpZiAoZW50cy5zb21lKGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgIHJldHVybiBlLmVudGl0eVR5cGUgIT09IHR5cGU7XHJcbiAgICB9KSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJBbGwgJ2Zyb21FbnRpdGllcycgbXVzdCBiZSB0aGUgc2FtZSB0eXBlOyBhdCBsZWFzdCBvbmUgaXMgbm90IG9mIHR5cGUgXCIgK1xyXG4gICAgICAgIHR5cGUubmFtZSk7XHJcbiAgICB9XHJcbiAgICBsZXQgcSA9IG5ldyBFbnRpdHlRdWVyeSh0eXBlLmRlZmF1bHRSZXNvdXJjZU5hbWUpO1xyXG4gICAgbGV0IHByZWRzID0gZW50cy5tYXAoZnVuY3Rpb24gKGVudGl0eSkge1xyXG4gICAgICByZXR1cm4gYnVpbGRQcmVkaWNhdGUoZW50aXR5KTtcclxuICAgIH0pO1xyXG4gICAgbGV0IHByZWQgPSBQcmVkaWNhdGUub3IocHJlZHMpO1xyXG4gICAgcSA9IHEud2hlcmUocHJlZCk7XHJcbiAgICBsZXQgZW0gPSBmaXJzdEVudGl0eS5lbnRpdHlBc3BlY3QuZW50aXR5TWFuYWdlcjtcclxuICAgIGlmIChlbSkge1xyXG4gICAgICBxID0gcS51c2luZyhlbSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gcTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gIENyZWF0ZXMgYW4gRW50aXR5UXVlcnkgZm9yIHRoZSBzcGVjaWZpZWQgW1tFbnRpdHlLZXldXS5cclxuICA+ICAgICAgbGV0IGVtcFR5cGUgPSBtZXRhZGF0YVN0b3JlLmdldEVudGl0eVR5cGUoXCJFbXBsb3llZVwiKTtcclxuICA+ICAgICAgbGV0IGVudGl0eUtleSA9IG5ldyBFbnRpdHlLZXkoZW1wVHlwZSwgMSk7XHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IEVudGl0eVF1ZXJ5LmZyb21FbnRpdHlLZXkoZW50aXR5S2V5KTtcclxuXHJcbiAgb3JcclxuICA+ICAgICAgLy8gJ2VtcGxveWVlJyBpcyBhIHByZXZpb3VzbHkgcXVlcmllZCBlbXBsb3llZVxyXG4gID4gICAgICBsZXQgZW50aXR5S2V5ID0gZW1wbG95ZWUuZW50aXR5QXNwZWN0LmdldEtleSgpO1xyXG4gID4gICAgICBsZXQgcXVlcnkgPSBFbnRpdHlRdWVyeS5mcm9tRW50aXR5S2V5KGVudGl0eUtleSk7XHJcbiAgQHBhcmFtIGVudGl0eUtleSAtIFRoZSBbW0VudGl0eUtleV1dIGZvciB3aGljaCBhIHF1ZXJ5IHdpbGwgYmUgY3JlYXRlZC5cclxuICAqKi9cclxuICBzdGF0aWMgZnJvbUVudGl0eUtleShlbnRpdHlLZXk6IEVudGl0eUtleSkge1xyXG4gICAgYXNzZXJ0UGFyYW0oZW50aXR5S2V5LCBcImVudGl0eUtleVwiKS5pc0luc3RhbmNlT2YoRW50aXR5S2V5KS5jaGVjaygpO1xyXG4gICAgbGV0IHEgPSBuZXcgRW50aXR5UXVlcnkoZW50aXR5S2V5LmVudGl0eVR5cGUuZGVmYXVsdFJlc291cmNlTmFtZSk7XHJcbiAgICBsZXQgcHJlZCA9IGJ1aWxkS2V5UHJlZGljYXRlKGVudGl0eUtleSk7XHJcbiAgICBxID0gcS53aGVyZShwcmVkKS50b1R5cGUoZW50aXR5S2V5LmVudGl0eVR5cGUpO1xyXG4gICAgcmV0dXJuIHE7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICBDcmVhdGVzIGFuIEVudGl0eVF1ZXJ5IGZvciB0aGUgc3BlY2lmaWVkIGVudGl0eSBhbmQgW1tOYXZpZ2F0aW9uUHJvcGVydHldXS5cclxuICA+ICAgICAgLy8gJ2VtcGxveWVlJyBpcyBhIHByZXZpb3VzbHkgcXVlcmllZCBlbXBsb3llZVxyXG4gID4gICAgICBsZXQgb3JkZXJzTmF2UHJvcCA9IGVtcGxveWVlLmVudGl0eVR5cGUuZ2V0UHJvcGVydHkoXCJPcmRlcnNcIik7XHJcbiAgPiAgICAgIGxldCBxdWVyeSA9IEVudGl0eVF1ZXJ5LmZyb21FbnRpdHlOYXZpZ2F0aW9uKGVtcGxveWVlLCBvcmRlcnNOYXZQcm9wKTtcclxuXHJcbiAgd2lsbCByZXR1cm4gYSBxdWVyeSBmb3IgdGhlIFwiT3JkZXJzXCIgb2YgdGhlIHNwZWNpZmllZCAnZW1wbG95ZWUnLlxyXG4gIEBwYXJhbSBlbnRpdHkgLSBUaGUgRW50aXR5IHdob3NlIG5hdmlnYXRpb24gcHJvcGVydHkgd2lsbCBiZSBxdWVyaWVkLlxyXG4gIEBwYXJhbSBuYXZpZ2F0aW9uUHJvcGVydHkgLSBUaGUgW1tOYXZpZ2F0aW9uUHJvcGVydHldXSBvciBuYW1lIG9mIHRoZSBOYXZpZ2F0aW9uUHJvcGVydHkgdG8gYmUgcXVlcmllZC5cclxuICAqKi9cclxuICBzdGF0aWMgZnJvbUVudGl0eU5hdmlnYXRpb24gPSBmdW5jdGlvbiAoZW50aXR5OiBFbnRpdHksIG5hdmlnYXRpb25Qcm9wZXJ0eTogTmF2aWdhdGlvblByb3BlcnR5IHwgc3RyaW5nKSB7XHJcbiAgICBhc3NlcnRQYXJhbShlbnRpdHksIFwiZW50aXR5XCIpLmlzRW50aXR5KCkuY2hlY2soKTtcclxuICAgIGxldCBuYXZQcm9wZXJ0eSA9IGVudGl0eS5lbnRpdHlUeXBlLl9jaGVja05hdlByb3BlcnR5KG5hdmlnYXRpb25Qcm9wZXJ0eSk7XHJcbiAgICBsZXQgcSA9IG5ldyBFbnRpdHlRdWVyeShuYXZQcm9wZXJ0eS5lbnRpdHlUeXBlLmRlZmF1bHRSZXNvdXJjZU5hbWUpO1xyXG4gICAgbGV0IHByZWQgPSBidWlsZE5hdmlnYXRpb25QcmVkaWNhdGUoZW50aXR5LCBuYXZQcm9wZXJ0eSk7XHJcbiAgICBpZiAocHJlZCA9PSBudWxsKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlVuYWJsZSB0byBjcmVhdGUgYSBOYXZpZ2F0aW9uUXVlcnkgZm9yIG5hdmlnYXRpb25Qcm9wZXJ0eTogXCIgKyBuYXZQcm9wZXJ0eS5uYW1lICk7XHJcbiAgICB9XHJcbiAgICBxID0gcS53aGVyZShwcmVkKTtcclxuICAgIGxldCBlbSA9IGVudGl0eS5lbnRpdHlBc3BlY3QuZW50aXR5TWFuYWdlcjtcclxuICAgIHJldHVybiBlbSA/IHEudXNpbmcoZW0pIDogcTtcclxuICB9O1xyXG5cclxuICAvLyBwcm90ZWN0ZWQgbWV0aG9kc1xyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9nZXRGcm9tRW50aXR5VHlwZShtZXRhZGF0YVN0b3JlOiBNZXRhZGF0YVN0b3JlLCB0aHJvd0Vycm9ySWZOb3RGb3VuZD86IGJvb2xlYW4pIHtcclxuICAgIC8vIFVuY29tbWVudCBuZXh0IHR3byBsaW5lcyBpZiB3ZSBtYWtlIHRoaXMgbWV0aG9kIHB1YmxpYy5cclxuICAgIC8vIGFzc2VydFBhcmFtKG1ldGFkYXRhU3RvcmUsIFwibWV0YWRhdGFTdG9yZVwiKS5pc0luc3RhbmNlT2YoTWV0YWRhdGFTdG9yZSkuY2hlY2soKTtcclxuICAgIC8vIGFzc2VydFBhcmFtKHRocm93RXJyb3JJZk5vdEZvdW5kLCBcInRocm93RXJyb3JJZk5vdEZvdW5kXCIpLmlzQm9vbGVhbigpLmlzT3B0aW9uYWwoKS5jaGVjaygpO1xyXG4gICAgbGV0IGVudGl0eVR5cGUgPSB0aGlzLmZyb21FbnRpdHlUeXBlO1xyXG4gICAgaWYgKGVudGl0eVR5cGUpIHJldHVybiBlbnRpdHlUeXBlO1xyXG5cclxuICAgIGxldCByZXNvdXJjZU5hbWUgPSB0aGlzLnJlc291cmNlTmFtZTtcclxuICAgIGlmICghcmVzb3VyY2VOYW1lKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlRoZXJlIGlzIG5vIHJlc291cmNlTmFtZSBmb3IgdGhpcyBxdWVyeVwiKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAobWV0YWRhdGFTdG9yZS5pc0VtcHR5KCkpIHtcclxuICAgICAgaWYgKHRocm93RXJyb3JJZk5vdEZvdW5kKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhlcmUgaXMgbm8gbWV0YWRhdGEgYXZhaWxhYmxlIGZvciB0aGlzIHF1ZXJ5LiBcIiArXHJcbiAgICAgICAgICBcIkFyZSB5b3UgcXVlcnlpbmcgdGhlIGxvY2FsIGNhY2hlIGJlZm9yZSB5b3UndmUgZmV0Y2hlZCBtZXRhZGF0YT9cIik7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGxldCBlbnRpdHlUeXBlTmFtZSA9IG1ldGFkYXRhU3RvcmUuZ2V0RW50aXR5VHlwZU5hbWVGb3JSZXNvdXJjZU5hbWUocmVzb3VyY2VOYW1lKTtcclxuICAgIGlmIChlbnRpdHlUeXBlTmFtZSkge1xyXG4gICAgICBlbnRpdHlUeXBlID0gbWV0YWRhdGFTdG9yZS5fZ2V0U3RydWN0dXJhbFR5cGUoZW50aXR5VHlwZU5hbWUpIGFzIEVudGl0eVR5cGU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBlbnRpdHlUeXBlID0gdGhpcy5fZ2V0VG9FbnRpdHlUeXBlKG1ldGFkYXRhU3RvcmUsIHRydWUpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghZW50aXR5VHlwZSkge1xyXG4gICAgICBpZiAodGhyb3dFcnJvcklmTm90Rm91bmQpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoY29yZS5mb3JtYXRTdHJpbmcoXCJDYW5ub3QgZmluZCBhbiBlbnRpdHlUeXBlIGZvciByZXNvdXJjZU5hbWU6ICclMScuIFwiLCByZXNvdXJjZU5hbWUpICsgY29yZS5zdHJpbmdzLlRPX1RZUEUpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLmZyb21FbnRpdHlUeXBlID0gZW50aXR5VHlwZTtcclxuICAgIHJldHVybiBlbnRpdHlUeXBlO1xyXG5cclxuICB9XHJcblxyXG4gIC8qKiBAaGlkZGVuIEBpbnRlcm5hbCAqL1xyXG4gIF9nZXRUb0VudGl0eVR5cGUobWV0YWRhdGFTdG9yZTogTWV0YWRhdGFTdG9yZSwgc2tpcEZyb21DaGVjaz86IGJvb2xlYW4pOiBFbnRpdHlUeXBlIHwgdW5kZWZpbmVkIHtcclxuICAgIC8vIHNraXBGcm9tQ2hlY2sgaXMgdG8gYXZvaWQgcmVjdXJzaW9uIGlmIGNhbGxlZCBmcm9tIF9nZXRGcm9tRW50aXR5VHlwZTtcclxuICAgIGlmICh0aGlzLnJlc3VsdEVudGl0eVR5cGUgaW5zdGFuY2VvZiBFbnRpdHlUeXBlKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLnJlc3VsdEVudGl0eVR5cGU7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMucmVzdWx0RW50aXR5VHlwZSkge1xyXG4gICAgICAvLyByZXN1bHRFbnRpdHlUeXBlIGlzIGEgc3RyaW5nXHJcbiAgICAgIHRoaXMucmVzdWx0RW50aXR5VHlwZSA9IG1ldGFkYXRhU3RvcmUuX2dldFN0cnVjdHVyYWxUeXBlKHRoaXMucmVzdWx0RW50aXR5VHlwZSwgZmFsc2UpIGFzIEVudGl0eVR5cGU7XHJcbiAgICAgIHJldHVybiB0aGlzLnJlc3VsdEVudGl0eVR5cGU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyByZXNvbHZlIGl0LCBpZiBwb3NzaWJsZSwgdmlhIHRoZSByZXNvdXJjZU5hbWVcclxuICAgICAgLy8gZG8gbm90IGNhY2hlIHRoaXMgdmFsdWUgaW4gdGhpcyBjYXNlXHJcbiAgICAgIC8vIGNhbm5vdCBkZXRlcm1pbmUgdGhlIHJlc3VsdEVudGl0eVR5cGUgaWYgYSBzZWxlY3RDbGF1c2UgaXMgcHJlc2VudC5cclxuICAgICAgLy8gcmV0dXJuIHNraXBGcm9tQ2hlY2sgPyBudWxsIDogKCF0aGlzLnNlbGVjdENsYXVzZSkgJiYgdGhpcy5fZ2V0RnJvbUVudGl0eVR5cGUobWV0YWRhdGFTdG9yZSwgZmFsc2UpO1xyXG4gICAgICBpZiAoc2tpcEZyb21DaGVjayB8fCB0aGlzLnNlbGVjdENsYXVzZSkge1xyXG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5fZ2V0RnJvbUVudGl0eVR5cGUobWV0YWRhdGFTdG9yZSwgZmFsc2UpO1xyXG4gICAgICB9XHJcblxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqIEBoaWRkZW4gQGludGVybmFsICovXHJcbiAgLy8gZm9yIHRlc3RpbmdcclxuICBfdG9VcmkoZW06IEVudGl0eU1hbmFnZXIpIHtcclxuICAgIGxldCBkcyA9IERhdGFTZXJ2aWNlLnJlc29sdmUoW2VtLmRhdGFTZXJ2aWNlXSk7XHJcbiAgICByZXR1cm4gZHMhLnVyaUJ1aWxkZXIhLmJ1aWxkVXJpKHRoaXMsIGVtLm1ldGFkYXRhU3RvcmUpO1xyXG4gIH1cclxuXHJcbn1cclxuRW50aXR5UXVlcnkucHJvdG90eXBlLl8kdHlwZU5hbWUgPSBcIkVudGl0eVF1ZXJ5XCI7XHJcblxyXG4vLyBwcml2YXRlIGZ1bmN0aW9uc1xyXG5cclxuZnVuY3Rpb24gZnJvbUpTT04oZXE6IEVudGl0eVF1ZXJ5LCBqc29uOiBPYmplY3QpIHtcclxuICBjb3JlLnRvSnNvbihqc29uLCB7XHJcbiAgICBcInJlc291cmNlTmFtZSxmcm9tXCI6IG51bGwsXHJcbiAgICAvLyBqdXN0IHRoZSBuYW1lIGNvbWVzIGJhY2sgYW5kIHdpbGwgYmUgcmVzb2x2ZWQgbGF0ZXJcclxuICAgIFwicmVzdWx0RW50aXR5VHlwZSx0b1R5cGVcIjogbnVsbCxcclxuICAgIFwid2hlcmVQcmVkaWNhdGUsd2hlcmVcIjogZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICByZXR1cm4gdiA/IG5ldyBQcmVkaWNhdGUodikgOiB1bmRlZmluZWQ7XHJcbiAgICB9LFxyXG4gICAgXCJvcmRlckJ5Q2xhdXNlLG9yZGVyQnlcIjogZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICByZXR1cm4gdiA/IG5ldyBPcmRlckJ5Q2xhdXNlKHYpIDogdW5kZWZpbmVkO1xyXG4gICAgfSxcclxuICAgIFwic2VsZWN0Q2xhdXNlLHNlbGVjdFwiOiBmdW5jdGlvbiAodjogYW55KSB7XHJcbiAgICAgIHJldHVybiB2ID8gbmV3IFNlbGVjdENsYXVzZSh2KSA6IHVuZGVmaW5lZDtcclxuICAgIH0sXHJcbiAgICBcImV4cGFuZENsYXVzZSxleHBhbmRcIjogZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICByZXR1cm4gdiA/IG5ldyBFeHBhbmRDbGF1c2UodikgOiB1bmRlZmluZWQ7XHJcbiAgICB9LFxyXG4gICAgXCJza2lwQ291bnQsc2tpcFwiOiBudWxsLFxyXG4gICAgXCJ0YWtlQ291bnQsdGFrZVwiOiBudWxsLFxyXG4gICAgcGFyYW1ldGVyczogZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICByZXR1cm4gY29yZS5pc0VtcHR5KHYpID8gdW5kZWZpbmVkIDogdjtcclxuICAgIH0sXHJcbiAgICBcImlubGluZUNvdW50RW5hYmxlZCxpbmxpbmVDb3VudFwiOiBmYWxzZSxcclxuICAgIFwibm9UcmFja2luZ0VuYWJsZWQsbm9UcmFja2luZ1wiOiBmYWxzZSxcclxuICAgIFwidXNlUG9zdEVuYWJsZWQsdXNlUG9zdFwiOiBmYWxzZSxcclxuICAgIHF1ZXJ5T3B0aW9uczogZnVuY3Rpb24gKHY6IGFueSkge1xyXG4gICAgICByZXR1cm4gdiA/IFF1ZXJ5T3B0aW9ucy5mcm9tSlNPTih2KSA6IHVuZGVmaW5lZDtcclxuICAgIH1cclxuICB9LCBlcSk7XHJcbiAgcmV0dXJuIGVxO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjbG9uZShlcTogRW50aXR5UXVlcnksIHByb3BOYW1lPzogc3RyaW5nLCB2YWx1ZT86IGFueSkge1xyXG4gIC8vIGltbXV0YWJsZSBxdWVyaWVzIG1lYW4gdGhhdCB3ZSBkb24ndCBuZWVkIHRvIGNsb25lIGlmIG5vIGNoYW5nZSBpbiB2YWx1ZS5cclxuICBpZiAocHJvcE5hbWUpIHtcclxuICAgIGlmIChlcVtwcm9wTmFtZV0gPT09IHZhbHVlKSByZXR1cm4gZXE7XHJcbiAgfVxyXG4gIC8vIGNvcHlpbmcgUXVlcnlPcHRpb25zIGlzIHNhZmUgYmVjYXVzZSB0aGV5IGFyZSBhcmUgaW1tdXRhYmxlO1xyXG4gIGxldCBjb3B5ID0gY29yZS5leHRlbmQobmV3IEVudGl0eVF1ZXJ5KCksIGVxLCBbXHJcbiAgICBcInJlc291cmNlTmFtZVwiLFxyXG4gICAgXCJmcm9tRW50aXR5VHlwZVwiLFxyXG4gICAgXCJ3aGVyZVByZWRpY2F0ZVwiLFxyXG4gICAgXCJvcmRlckJ5Q2xhdXNlXCIsXHJcbiAgICBcInNlbGVjdENsYXVzZVwiLFxyXG4gICAgXCJza2lwQ291bnRcIixcclxuICAgIFwidGFrZUNvdW50XCIsXHJcbiAgICBcImV4cGFuZENsYXVzZVwiLFxyXG4gICAgXCJpbmxpbmVDb3VudEVuYWJsZWRcIixcclxuICAgIFwibm9UcmFja2luZ0VuYWJsZWRcIixcclxuICAgIFwidXNlUG9zdEVuYWJsZWRcIixcclxuICAgIFwidXNlc05hbWVPblNlcnZlclwiLFxyXG4gICAgXCJxdWVyeU9wdGlvbnNcIixcclxuICAgIFwiZW50aXR5TWFuYWdlclwiLFxyXG4gICAgXCJkYXRhU2VydmljZVwiLFxyXG4gICAgXCJyZXN1bHRFbnRpdHlUeXBlXCJcclxuICBdKSBhcyBFbnRpdHlRdWVyeTtcclxuICBjb3B5LnBhcmFtZXRlcnMgPSBjb3JlLmV4dGVuZCh7fSwgZXEucGFyYW1ldGVycyk7XHJcbiAgaWYgKHByb3BOYW1lKSB7XHJcbiAgICBjb3B5W3Byb3BOYW1lXSA9IHZhbHVlO1xyXG4gIH1cclxuICByZXR1cm4gY29weTtcclxufVxyXG5cclxuZnVuY3Rpb24gcHJvY2Vzc1VzaW5nKGVxOiBFbnRpdHlRdWVyeSwgbWFwOiBPYmplY3QsIHZhbHVlOiBhbnksIHByb3BlcnR5TmFtZT86IHN0cmluZykge1xyXG4gIGxldCB0eXBlTmFtZSA9IHZhbHVlLl8kdHlwZU5hbWUgfHwgKCh2YWx1ZSBpbnN0YW5jZW9mIEJyZWV6ZUVudW0pICYmICh2YWx1ZS5jb25zdHJ1Y3RvciBhcyBhbnkpLm5hbWUpO1xyXG4gIGxldCBrZXkgPSB0eXBlTmFtZSAmJiB0eXBlTmFtZS5zdWJzdHIoMCwgMSkudG9Mb3dlckNhc2UoKSArIHR5cGVOYW1lLnN1YnN0cigxKTtcclxuICBpZiAocHJvcGVydHlOYW1lICYmIGtleSAhPT0gcHJvcGVydHlOYW1lKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJJbnZhbGlkIHZhbHVlIGZvciBwcm9wZXJ0eTogXCIgKyBwcm9wZXJ0eU5hbWUpO1xyXG4gIH1cclxuICBpZiAoa2V5KSB7XHJcbiAgICBsZXQgZm4gPSBtYXBba2V5XTtcclxuICAgIGlmIChmbiA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgY29uZmlnIHByb3BlcnR5OiBcIiArIGtleSk7XHJcbiAgICB9IGVsc2UgaWYgKGZuID09PSBudWxsKSB7XHJcbiAgICAgIGVxW2tleV0gPSB2YWx1ZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGZuKGVxLCB2YWx1ZSk7XHJcbiAgICB9XHJcbiAgfSBlbHNlIHtcclxuICAgIGNvcmUub2JqZWN0Rm9yRWFjaCh2YWx1ZSwgKHByb3BOYW1lLCB2YWwpID0+IHtcclxuICAgICAgcHJvY2Vzc1VzaW5nKGVxLCBtYXAsIHZhbCwgcHJvcE5hbWUpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBub3JtYWxpemVQcm9wZXJ0eVBhdGhzKHByb3BlcnR5UGF0aHM6IHN0cmluZyB8IHN0cmluZ1tdKSB7XHJcbiAgYXNzZXJ0UGFyYW0ocHJvcGVydHlQYXRocywgXCJwcm9wZXJ0eVBhdGhzXCIpLmlzT3B0aW9uYWwoKS5pc1N0cmluZygpLm9yKCkuaXNBcnJheSgpLmlzU3RyaW5nKCkuY2hlY2soKTtcclxuICBpZiAodHlwZW9mIHByb3BlcnR5UGF0aHMgPT09ICdzdHJpbmcnKSB7XHJcbiAgICBwcm9wZXJ0eVBhdGhzID0gcHJvcGVydHlQYXRocy5zcGxpdChcIixcIik7XHJcbiAgfVxyXG5cclxuICBwcm9wZXJ0eVBhdGhzID0gcHJvcGVydHlQYXRocy5tYXAoZnVuY3Rpb24gKHBwKSB7XHJcbiAgICByZXR1cm4gcHAudHJpbSgpO1xyXG4gIH0pO1xyXG4gIHJldHVybiBwcm9wZXJ0eVBhdGhzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBidWlsZFByZWRpY2F0ZShlbnRpdHk6IEVudGl0eSkge1xyXG4gIGxldCBlbnRpdHlUeXBlID0gZW50aXR5LmVudGl0eVR5cGU7XHJcbiAgbGV0IHByZWRQYXJ0cyA9IGVudGl0eVR5cGUua2V5UHJvcGVydGllcy5tYXAoZnVuY3Rpb24gKGtwKSB7XHJcbiAgICByZXR1cm4gUHJlZGljYXRlLmNyZWF0ZShrcC5uYW1lLCBGaWx0ZXJRdWVyeU9wLkVxdWFscywgZW50aXR5LmdldFByb3BlcnR5KGtwLm5hbWUpKTtcclxuICB9KTtcclxuICBsZXQgcHJlZCA9IFByZWRpY2F0ZS5hbmQocHJlZFBhcnRzKTtcclxuICByZXR1cm4gcHJlZDtcclxufVxyXG5cclxuZnVuY3Rpb24gYnVpbGRLZXlQcmVkaWNhdGUoZW50aXR5S2V5OiBFbnRpdHlLZXkpIHtcclxuICBsZXQga2V5UHJvcHMgPSBlbnRpdHlLZXkuZW50aXR5VHlwZS5rZXlQcm9wZXJ0aWVzO1xyXG4gIGxldCBwcmVkcyA9IGNvcmUuYXJyYXlaaXAoa2V5UHJvcHMsIGVudGl0eUtleS52YWx1ZXMsIGZ1bmN0aW9uIChrcCwgdikge1xyXG4gICAgcmV0dXJuIFByZWRpY2F0ZS5jcmVhdGUoa3AubmFtZSwgRmlsdGVyUXVlcnlPcC5FcXVhbHMsIHYpO1xyXG4gIH0pO1xyXG4gIGxldCBwcmVkID0gUHJlZGljYXRlLmFuZChwcmVkcyk7XHJcbiAgcmV0dXJuIHByZWQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGJ1aWxkTmF2aWdhdGlvblByZWRpY2F0ZShlbnRpdHk6IEVudGl0eSwgbmF2aWdhdGlvblByb3BlcnR5OiBOYXZpZ2F0aW9uUHJvcGVydHkpIHtcclxuICBpZiAobmF2aWdhdGlvblByb3BlcnR5LmlzU2NhbGFyKSB7XHJcbiAgICBpZiAobmF2aWdhdGlvblByb3BlcnR5LmZvcmVpZ25LZXlOYW1lcy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xyXG4gICAgbGV0IHJlbGF0ZWRLZXlWYWx1ZXMgPSBuYXZpZ2F0aW9uUHJvcGVydHkuZm9yZWlnbktleU5hbWVzLm1hcCgoZmtOYW1lKSA9PiB7XHJcbiAgICAgIHJldHVybiBlbnRpdHkuZ2V0UHJvcGVydHkoZmtOYW1lKTtcclxuICAgIH0pO1xyXG4gICAgbGV0IGVudGl0eUtleSA9IG5ldyBFbnRpdHlLZXkobmF2aWdhdGlvblByb3BlcnR5LmVudGl0eVR5cGUsIHJlbGF0ZWRLZXlWYWx1ZXMpO1xyXG4gICAgcmV0dXJuIGJ1aWxkS2V5UHJlZGljYXRlKGVudGl0eUtleSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIGxldCBpbnZlcnNlTnAgPSBuYXZpZ2F0aW9uUHJvcGVydHkuaW52ZXJzZTtcclxuICAgIGxldCBmb3JlaWduS2V5TmFtZXMgPSBpbnZlcnNlTnAgPyBpbnZlcnNlTnAuZm9yZWlnbktleU5hbWVzIDogbmF2aWdhdGlvblByb3BlcnR5LmludkZvcmVpZ25LZXlOYW1lcztcclxuICAgIGlmIChmb3JlaWduS2V5TmFtZXMubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcclxuICAgIGxldCBrZXlWYWx1ZXMgPSBlbnRpdHkuZW50aXR5QXNwZWN0LmdldEtleSgpLnZhbHVlcztcclxuICAgIGxldCBwcmVkUGFydHMgPSBjb3JlLmFycmF5WmlwKGZvcmVpZ25LZXlOYW1lcywga2V5VmFsdWVzLCAoZmtOYW1lLCBrdikgPT4ge1xyXG4gICAgICByZXR1cm4gUHJlZGljYXRlLmNyZWF0ZShma05hbWUsIEZpbHRlclF1ZXJ5T3AuRXF1YWxzLCBrdik7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBQcmVkaWNhdGUuYW5kKHByZWRQYXJ0cyk7XHJcbiAgfVxyXG59XHJcblxyXG4vKiogQmFzZSBjbGFzcyBmb3IgQm9vbGVhblF1ZXJ5T3AgYW5kIEZpbHRlclF1ZXJ5T3AgKi9cclxuZXhwb3J0IGludGVyZmFjZSBRdWVyeU9wIHtcclxuICAvKiogVGhlIG9wZXJhdG9yIGZvciB0aGlzIGVudW0uICovXHJcbiAgb3BlcmF0b3I6IHN0cmluZztcclxufVxyXG5cclxuXHJcblxyXG4vKipcclxuRmlsdGVyUXVlcnlPcCBpcyBhbiAnRW51bScgY29udGFpbmluZyBhbGwgb2YgdGhlIHZhbGlkICBbW1ByZWRpY2F0ZV1dXHJcbmZpbHRlciBvcGVyYXRvcnMgZm9yIGFuIFtbRW50aXR5UXVlcnldXS5cclxuKiovXHJcbmV4cG9ydCBjbGFzcyBGaWx0ZXJRdWVyeU9wIGV4dGVuZHMgQnJlZXplRW51bSBpbXBsZW1lbnRzIFF1ZXJ5T3Age1xyXG4gIC8qKiBUaGUgb3BlcmF0b3IgZm9yIHRoaXMgZW51bS4gKi9cclxuICBkZWNsYXJlIG9wZXJhdG9yOiBzdHJpbmc7XHJcblxyXG4gIC8qKiBBbGlhc2VzOiBcImVxXCIsIFwiPT1cIiAqKi9cclxuICBzdGF0aWMgRXF1YWxzID0gbmV3IEZpbHRlclF1ZXJ5T3AoeyBvcGVyYXRvcjogXCJlcVwiIH0pO1xyXG4gIC8qKiAgQWxpYXNlczogXCJuZVwiLCBcIiE9XCIgICoqL1xyXG4gIHN0YXRpYyBOb3RFcXVhbHMgPSBuZXcgRmlsdGVyUXVlcnlPcCh7IG9wZXJhdG9yOiBcIm5lXCIgfSk7XHJcbiAgLyoqIEFsaWFzZXM6IFwiZ3RcIiwgXCI+XCIgICAqKi9cclxuICBzdGF0aWMgR3JlYXRlclRoYW4gPSBuZXcgRmlsdGVyUXVlcnlPcCh7IG9wZXJhdG9yOiBcImd0XCIgfSk7XHJcbiAgLyoqIEFsaWFzZXM6IFwibHRcIiwgXCI8XCIgICoqL1xyXG4gIHN0YXRpYyBMZXNzVGhhbiA9IG5ldyBGaWx0ZXJRdWVyeU9wKHsgb3BlcmF0b3I6IFwibHRcIiB9KTtcclxuICAvKiogIEFsaWFzZXM6IFwiZ2VcIiwgXCI+PVwiICAqKi9cclxuICBzdGF0aWMgR3JlYXRlclRoYW5PckVxdWFsID0gbmV3IEZpbHRlclF1ZXJ5T3AoeyBvcGVyYXRvcjogXCJnZVwiIH0pO1xyXG4gIC8qKiAgQWxpYXNlczogXCJsZVwiLCBcIjw9XCIgICoqL1xyXG4gIHN0YXRpYyBMZXNzVGhhbk9yRXF1YWwgPSBuZXcgRmlsdGVyUXVlcnlPcCh7IG9wZXJhdG9yOiBcImxlXCIgfSk7XHJcbiAgLyoqICBTdHJpbmcgb3BlcmF0aW9uOiBJcyBhIHN0cmluZyBhIHN1YnN0cmluZyBvZiBhbm90aGVyIHN0cmluZy4gIEFsaWFzZXM6IFwic3Vic3RyaW5nb2ZcIiAgICoqL1xyXG4gIHN0YXRpYyBDb250YWlucyA9IG5ldyBGaWx0ZXJRdWVyeU9wKHsgb3BlcmF0b3I6IFwiY29udGFpbnNcIiB9KTtcclxuICAvKiogTm8gYWxpYXNlcyAqL1xyXG4gIHN0YXRpYyBTdGFydHNXaXRoID0gbmV3IEZpbHRlclF1ZXJ5T3AoeyBvcGVyYXRvcjogXCJzdGFydHN3aXRoXCIgfSk7XHJcbiAgLyoqIE5vIGFsaWFzZXMgKi9cclxuICBzdGF0aWMgRW5kc1dpdGggPSBuZXcgRmlsdGVyUXVlcnlPcCh7IG9wZXJhdG9yOiBcImVuZHN3aXRoXCIgfSk7XHJcbiAgLyoqICBBbGlhc2VzOiBcInNvbWVcIiAgKiovXHJcbiAgc3RhdGljIEFueSA9IG5ldyBGaWx0ZXJRdWVyeU9wKHsgb3BlcmF0b3I6IFwiYW55XCIgfSk7XHJcbiAgLyoqICBBbGlhc2VzOiBcImV2ZXJ5XCIgICoqL1xyXG4gIHN0YXRpYyBBbGwgPSBuZXcgRmlsdGVyUXVlcnlPcCh7IG9wZXJhdG9yOiBcImFsbFwiIH0pO1xyXG4gIC8qKiBObyBhbGlhc2VzICovXHJcbiAgc3RhdGljIEluID0gbmV3IEZpbHRlclF1ZXJ5T3AoeyBvcGVyYXRvcjogXCJpblwiIH0pO1xyXG4gIC8qKiBObyBhbGlhc2VzICovXHJcbiAgc3RhdGljIElzVHlwZU9mID0gbmV3IEZpbHRlclF1ZXJ5T3AoeyBvcGVyYXRvcjogXCJpc29mXCIgfSk7XHJcbn1cclxuRmlsdGVyUXVlcnlPcC5wcm90b3R5cGUuXyR0eXBlTmFtZSA9IFwiRmlsdGVyUXVlcnlPcFwiO1xyXG5FcnJvclsneCddID0gRmlsdGVyUXVlcnlPcC5yZXNvbHZlU3ltYm9scygpO1xyXG5cclxuXHJcbi8qKlxyXG4gQm9vbGVhblF1ZXJ5T3AgaXMgYW4gJ0VudW0nIGNvbnRhaW5pbmcgYWxsIG9mIHRoZSB2YWxpZCAgYm9vbGVhblxyXG5vcGVyYXRvcnMgZm9yIGFuIFtbRW50aXR5UXVlcnldXS5cclxuKiovXHJcbmV4cG9ydCBjbGFzcyBCb29sZWFuUXVlcnlPcCBleHRlbmRzIEJyZWV6ZUVudW0gaW1wbGVtZW50cyBRdWVyeU9wIHtcclxuICAvKiogVGhlIG9wZXJhdG9yIGZvciB0aGlzIGVudW0uICovXHJcbiAgZGVjbGFyZSBvcGVyYXRvcjogc3RyaW5nO1xyXG5cclxuICBzdGF0aWMgQW5kID0gbmV3IEJvb2xlYW5RdWVyeU9wKHsgb3BlcmF0b3I6IFwiYW5kXCIgfSk7XHJcbiAgc3RhdGljIE9yID0gbmV3IEJvb2xlYW5RdWVyeU9wKHsgb3BlcmF0b3I6IFwib3JcIiB9KTtcclxuICBzdGF0aWMgTm90ID0gbmV3IEJvb2xlYW5RdWVyeU9wKHsgb3BlcmF0b3I6IFwibm90XCIgfSk7XHJcblxyXG59XHJcbkJvb2xlYW5RdWVyeU9wLnByb3RvdHlwZS5fJHR5cGVOYW1lID0gXCJCb29sZWFuUXVlcnlPcFwiO1xyXG5FcnJvclsneCddID0gQm9vbGVhblF1ZXJ5T3AucmVzb2x2ZVN5bWJvbHMoKTtcclxuXHJcblxyXG4vKiogRm9yIHVzZSBieSBicmVlemUgcGx1Z2luIGF1dGhvcnMgb25seS4gIFRoZSBjbGFzcyBpcyB1c2VkIGluIG1vc3QgW1tJVXJpQnVpbGRlckFkYXB0ZXJdXSBpbXBsZW1lbnRhdGlvbnNcclxuQGFkYXB0ZXIgKHNlZSBbW0lVcmlCdWlsZGVyQWRhcHRlcl1dKSAgICBcclxuQGhpZGRlblxyXG5cclxuQW4gT3JkZXJCeUNsYXVzZSBpcyBhIGRlc2NyaXB0aW9uIG9mIHRoZSBwcm9wZXJ0aWVzIGFuZCBkaXJlY3Rpb24gdGhhdCB0aGUgcmVzdWx0XHJcbm9mIGEgcXVlcnkgc2hvdWxkIGJlIHNvcnRlZCBpbi4gIE9yZGVyQnlDbGF1c2VzIGFyZSBpbW11dGFibGUsIHdoaWNoIG1lYW5zIHRoYXQgYW55XHJcbm1ldGhvZCB0aGF0IHdvdWxkIG1vZGlmeSBhbiBPcmRlckJ5Q2xhdXNlIGFjdHVhbGx5IHJldHVybnMgYSBuZXcgT3JkZXJCeUNsYXVzZS5cclxuXHJcbkZvciBleGFtcGxlIGZvciBhbiBFbXBsb3llZSBvYmplY3Qgd2l0aCBwcm9wZXJ0aWVzIG9mICdDb21wYW55JyBhbmQgJ0xhc3ROYW1lJyB0aGUgZm9sbG93aW5nIHdvdWxkIGJlIHZhbGlkIGV4cHJlc3Npb25zOlxyXG4+ICAgICBsZXQgb2JjID0gbmV3IE9yZGVyQnlDbGF1c2UoXCJDb21wYW55LkNvbXBhbnlOYW1lLCBMYXN0TmFtZVwiKVxyXG5cclxub3JcclxuPiAgICAgbGV0IG9iYyA9IG5ldyBPcmRlckJ5Q2xhdXNlKFwiQ29tcGFueS5Db21wYW55TmFtZSBkZXNjLCBMYXN0TmFtZVwiKVxyXG5cclxub3JcclxuPiAgICAgbGV0IG9iYyA9IG5ldyBPcmRlckJ5Q2xhdXNlKFwiQ29tcGFueS5Db21wYW55TmFtZSwgTGFzdE5hbWVcIiwgdHJ1ZSk7XHJcbiovXHJcbmV4cG9ydCBjbGFzcyBPcmRlckJ5Q2xhdXNlIHtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBpdGVtczogT3JkZXJCeUl0ZW1bXTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJvcGVydHlQYXRoczogc3RyaW5nW10gfCBPcmRlckJ5Q2xhdXNlW10sIGlzRGVzYz86IGJvb2xlYW4pIHtcclxuICAgIGlmIChwcm9wZXJ0eVBhdGhzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJPcmRlckJ5Q2xhdXNlIGNhbm5vdCBiZSBlbXB0eVwiKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyB5b3UgY2FuIGFsc28gcGFzcyBpbiBhbiBhcnJheSBvZiBvcmRlckJ5Q2xhdXNlc1xyXG4gICAgaWYgKHByb3BlcnR5UGF0aHNbMF0gaW5zdGFuY2VvZiBPcmRlckJ5Q2xhdXNlKSB7XHJcbiAgICAgIGxldCBjbGF1c2VzID0gcHJvcGVydHlQYXRocyBhcyBPcmRlckJ5Q2xhdXNlW107XHJcbiAgICAgIHRoaXMuaXRlbXMgPSBjb3JlLmFycmF5RmxhdE1hcChjbGF1c2VzLCBjID0+IGMuaXRlbXMpO1xyXG4gICAgICAvLyB0aGlzLml0ZW1zID0gQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseShjbGF1c2VzWzBdLml0ZW1zLCBjbGF1c2VzLnNsaWNlKDEpLm1hcChjb3JlLnBsdWNrKFwiaXRlbXNcIikpKTtcclxuICAgICAgLy8gdGhpcy5pdGVtcyA9IEFycmF5LnByb3RvdHlwZS5jb25jYXQuYXBwbHkoW10sIGNsYXVzZXMubWFwKGNvcmUucGx1Y2soXCJpdGVtc1wiKSkpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5pdGVtcyA9IChwcm9wZXJ0eVBhdGhzIGFzIHN0cmluZ1tdKS5tYXAoZnVuY3Rpb24gKHBwKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBPcmRlckJ5SXRlbShwcCwgaXNEZXNjKTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gIH1cclxuXHJcbiAgdmFsaWRhdGUoZW50aXR5VHlwZTogRW50aXR5VHlwZSkge1xyXG4gICAgaWYgKGVudGl0eVR5cGUgPT0gbnVsbCB8fCBlbnRpdHlUeXBlLmlzQW5vbnltb3VzKSByZXR1cm47XHJcbiAgICB0aGlzLml0ZW1zLmZvckVhY2goKGl0ZW0pID0+IHtcclxuICAgICAgaXRlbS52YWxpZGF0ZShlbnRpdHlUeXBlKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZ2V0Q29tcGFyZXIoZW50aXR5VHlwZTogRW50aXR5VHlwZSkge1xyXG4gICAgbGV0IG9yZGVyQnlGdW5jcyA9IHRoaXMuaXRlbXMubWFwKGZ1bmN0aW9uIChvYmMpIHtcclxuICAgICAgcmV0dXJuIG9iYy5nZXRDb21wYXJlcihlbnRpdHlUeXBlKTtcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChlbnRpdHkxOiBhbnksIGVudGl0eTI6IGFueSkge1xyXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG9yZGVyQnlGdW5jcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGxldCByZXN1bHQgPSBvcmRlckJ5RnVuY3NbaV0oZW50aXR5MSwgZW50aXR5Mik7XHJcbiAgICAgICAgaWYgKHJlc3VsdCAhPT0gMCkge1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIDA7XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgdG9KU09ORXh0KGNvbnRleHQ6IEVudGl0eVF1ZXJ5SnNvbkNvbnRleHQpIHtcclxuICAgIHJldHVybiB0aGlzLml0ZW1zLm1hcChmdW5jdGlvbiAoaXRlbSkge1xyXG4gICAgICByZXR1cm4gY29udGV4dC5wcm9wZXJ0eVBhdGhGbiEoaXRlbS5wcm9wZXJ0eVBhdGgpICsgKGl0ZW0uaXNEZXNjID8gXCIgZGVzY1wiIDogXCJcIik7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG59XHJcblxyXG4vKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuZXhwb3J0IGNsYXNzIE9yZGVyQnlJdGVtIHtcclxuICBwcm9wZXJ0eVBhdGg6IHN0cmluZztcclxuICBpc0Rlc2M6IGJvb2xlYW47XHJcbiAgbGFzdFByb3BlcnR5OiBFbnRpdHlQcm9wZXJ0eTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJvcGVydHlQYXRoOiBzdHJpbmcsIGlzRGVzYz86IGJvb2xlYW4pIHtcclxuICAgIGlmICghKHR5cGVvZiBwcm9wZXJ0eVBhdGggPT09ICdzdHJpbmcnKSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJwcm9wZXJ0eVBhdGggaXMgbm90IGEgc3RyaW5nXCIpO1xyXG4gICAgfVxyXG4gICAgcHJvcGVydHlQYXRoID0gcHJvcGVydHlQYXRoLnRyaW0oKTtcclxuXHJcbiAgICBsZXQgcGFydHMgPSBwcm9wZXJ0eVBhdGguc3BsaXQoJyAnKTtcclxuICAgIC8vIHBhcnRzWzBdIGlzIHRoZSBwcm9wZXJ0eVBhdGg7IFsxXSB3b3VsZCBiZSB3aGV0aGVyIGRlc2NlbmRpbmcgb3Igbm90LlxyXG4gICAgLy8gaWYgKHBhcnRzLmxlbmd0aCA+IDEgJiYgaXNEZXNjICE9PSB0cnVlICYmIGlzRGVzYyAhPT0gZmFsc2UpIHtcclxuICAgIGlmIChwYXJ0cy5sZW5ndGggPiAxICYmIGlzRGVzYyA9PSBudWxsKSB7XHJcbiAgICAgIGlzRGVzYyA9IGNvcmUuc3RyaW5nU3RhcnRzV2l0aChwYXJ0c1sxXS50b0xvd2VyQ2FzZSgpLCBcImRlc2NcIik7XHJcbiAgICAgIGlmICghaXNEZXNjKSB7XHJcbiAgICAgICAgLy8gaXNEZXNjIGlzIGZhbHNlIGJ1dCBjaGVjayB0byBtYWtlIHN1cmUgaXRzIGludGVuZGVkLlxyXG4gICAgICAgIGxldCBpc0FzYyA9IGNvcmUuc3RyaW5nU3RhcnRzV2l0aChwYXJ0c1sxXS50b0xvd2VyQ2FzZSgpLCBcImFzY1wiKTtcclxuICAgICAgICBpZiAoIWlzQXNjKSB7XHJcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJ0aGUgc2Vjb25kIHdvcmQgaW4gdGhlIHByb3BlcnR5UGF0aCBtdXN0IGJlZ2luIHdpdGggJ2Rlc2MnIG9yICdhc2MnXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHRoaXMucHJvcGVydHlQYXRoID0gcGFydHNbMF07XHJcbiAgICB0aGlzLmlzRGVzYyA9IGlzRGVzYyB8fCBmYWxzZTtcclxuICB9XHJcblxyXG4gIHZhbGlkYXRlKGVudGl0eVR5cGU6IEVudGl0eVR5cGUpOiBFbnRpdHlQcm9wZXJ0eSB8IHVuZGVmaW5lZCB7XHJcbiAgICBpZiAoZW50aXR5VHlwZSA9PSBudWxsIHx8IGVudGl0eVR5cGUuaXNBbm9ueW1vdXMpIHJldHVybjtcclxuICAgIC8vIHdpbGwgdGhyb3cgYW4gZXhjZXB0aW9uIG9uIGJhZCBwcm9wZXJ0eVBhdGhcclxuICAgIHRoaXMubGFzdFByb3BlcnR5ID0gZW50aXR5VHlwZS5nZXRQcm9wZXJ0eSh0aGlzLnByb3BlcnR5UGF0aCwgdHJ1ZSkgYXMgRW50aXR5UHJvcGVydHk7XHJcbiAgICByZXR1cm4gdGhpcy5sYXN0UHJvcGVydHk7XHJcbiAgfVxyXG5cclxuICBnZXRDb21wYXJlcihlbnRpdHlUeXBlOiBFbnRpdHlUeXBlKSB7XHJcbiAgICBsZXQgcHJvcERhdGFUeXBlOiBEYXRhVHlwZTtcclxuICAgIGxldCBpc0Nhc2VTZW5zaXRpdmU6IGJvb2xlYW47XHJcbiAgICBpZiAoIXRoaXMubGFzdFByb3BlcnR5KSB0aGlzLnZhbGlkYXRlKGVudGl0eVR5cGUpO1xyXG4gICAgaWYgKHRoaXMubGFzdFByb3BlcnR5KSB7XHJcbiAgICAgIHByb3BEYXRhVHlwZSA9ICh0aGlzLmxhc3RQcm9wZXJ0eSBhcyBhbnkpLmRhdGFUeXBlO1xyXG4gICAgICBpc0Nhc2VTZW5zaXRpdmUgPSB0aGlzLmxhc3RQcm9wZXJ0eS5wYXJlbnRUeXBlLm1ldGFkYXRhU3RvcmUubG9jYWxRdWVyeUNvbXBhcmlzb25PcHRpb25zLmlzQ2FzZVNlbnNpdGl2ZTtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgcHJvcGVydHlQYXRoID0gdGhpcy5wcm9wZXJ0eVBhdGg7XHJcbiAgICBsZXQgaXNEZXNjID0gdGhpcy5pc0Rlc2M7XHJcblxyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChlbnRpdHkxOiBhbnksIGVudGl0eTI6IGFueSkge1xyXG4gICAgICBsZXQgdmFsdWUxID0gRW50aXR5QXNwZWN0LmdldFByb3BlcnR5UGF0aFZhbHVlKGVudGl0eTEsIHByb3BlcnR5UGF0aCk7XHJcbiAgICAgIGxldCB2YWx1ZTIgPSBFbnRpdHlBc3BlY3QuZ2V0UHJvcGVydHlQYXRoVmFsdWUoZW50aXR5MiwgcHJvcGVydHlQYXRoKTtcclxuICAgICAgbGV0IGRhdGFUeXBlID0gcHJvcERhdGFUeXBlIHx8ICh2YWx1ZTEgJiYgRGF0YVR5cGUuZnJvbVZhbHVlKHZhbHVlMSkpIHx8IERhdGFUeXBlLmZyb21WYWx1ZSh2YWx1ZTIpO1xyXG4gICAgICBpZiAoZGF0YVR5cGUgPT09IERhdGFUeXBlLlN0cmluZykge1xyXG4gICAgICAgIGlmIChpc0Nhc2VTZW5zaXRpdmUpIHtcclxuICAgICAgICAgIHZhbHVlMSA9IHZhbHVlMSB8fCBcIlwiO1xyXG4gICAgICAgICAgdmFsdWUyID0gdmFsdWUyIHx8IFwiXCI7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHZhbHVlMSA9ICh2YWx1ZTEgfHwgXCJcIikudG9Mb3dlckNhc2UoKTtcclxuICAgICAgICAgIHZhbHVlMiA9ICh2YWx1ZTIgfHwgXCJcIikudG9Mb3dlckNhc2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgbGV0IG5vcm1hbGl6ZSA9IERhdGFUeXBlLmdldENvbXBhcmFibGVGbihkYXRhVHlwZSk7XHJcbiAgICAgICAgdmFsdWUxID0gbm9ybWFsaXplKHZhbHVlMSk7XHJcbiAgICAgICAgdmFsdWUyID0gbm9ybWFsaXplKHZhbHVlMik7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHZhbHVlMSA9PT0gdmFsdWUyKSB7XHJcbiAgICAgICAgcmV0dXJuIDA7XHJcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUxID4gdmFsdWUyIHx8IHZhbHVlMiA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgcmV0dXJuIGlzRGVzYyA/IC0xIDogMTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICByZXR1cm4gaXNEZXNjID8gMSA6IC0xO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gIH1cclxufVxyXG5cclxuLyoqIEZvciB1c2UgYnkgYnJlZXplIHBsdWdpbiBhdXRob3JzIG9ubHkuICBUaGUgY2xhc3MgaXMgdXNlZCBpbiBtb3N0IFtbSVVyaUJ1aWxkZXJBZGFwdGVyXV0gaW1wbGVtZW50YXRpb25zXHJcbkBhZGFwdGVyIChzZWUgW1tJVXJpQnVpbGRlckFkYXB0ZXJdXSkgICAgXHJcbkBoaWRkZW4gXHJcbioqL1xyXG5leHBvcnQgY2xhc3MgU2VsZWN0Q2xhdXNlIHtcclxuICBwcm9wZXJ0eVBhdGhzOiBzdHJpbmdbXTtcclxuICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cclxuICBfcGF0aE5hbWVzOiBzdHJpbmdbXTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJvcGVydHlQYXRoczogc3RyaW5nW10pIHtcclxuICAgIHRoaXMucHJvcGVydHlQYXRocyA9IHByb3BlcnR5UGF0aHM7XHJcbiAgICB0aGlzLl9wYXRoTmFtZXMgPSBwcm9wZXJ0eVBhdGhzLm1hcChmdW5jdGlvbiAocHApIHtcclxuICAgICAgcmV0dXJuIHBwLnJlcGxhY2UoXCIuXCIsIFwiX1wiKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgdmFsaWRhdGUoZW50aXR5VHlwZTogRW50aXR5VHlwZSkge1xyXG4gICAgaWYgKGVudGl0eVR5cGUgPT0gbnVsbCB8fCBlbnRpdHlUeXBlLmlzQW5vbnltb3VzKSByZXR1cm47IC8vIGNhbid0IHZhbGlkYXRlIHlldFxyXG4gICAgLy8gd2lsbCB0aHJvdyBhbiBleGNlcHRpb24gb24gYmFkIHByb3BlcnR5UGF0aFxyXG4gICAgdGhpcy5wcm9wZXJ0eVBhdGhzLmZvckVhY2goZnVuY3Rpb24gKHBhdGgpIHtcclxuICAgICAgZW50aXR5VHlwZS5nZXRQcm9wZXJ0eShwYXRoLCB0cnVlKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgdG9GdW5jdGlvbigvKiBjb25maWcgKi8pIHtcclxuICAgIGxldCB0aGF0ID0gdGhpcztcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZW50aXR5OiBFbnRpdHkpIHtcclxuICAgICAgbGV0IHJlc3VsdCA9IHt9O1xyXG4gICAgICB0aGF0LnByb3BlcnR5UGF0aHMuZm9yRWFjaChmdW5jdGlvbiAocGF0aCwgaSkge1xyXG4gICAgICAgIHJlc3VsdFt0aGF0Ll9wYXRoTmFtZXNbaV1dID0gRW50aXR5QXNwZWN0LmdldFByb3BlcnR5UGF0aFZhbHVlKGVudGl0eSwgcGF0aCk7XHJcbiAgICAgIH0pO1xyXG4gICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHRvSlNPTkV4dChjb250ZXh0OiBFbnRpdHlRdWVyeUpzb25Db250ZXh0KSB7XHJcbiAgICByZXR1cm4gdGhpcy5wcm9wZXJ0eVBhdGhzLm1hcChmdW5jdGlvbiAocHApIHtcclxuICAgICAgcmV0dXJuIGNvbnRleHQucHJvcGVydHlQYXRoRm4hKHBwKTtcclxuICAgIH0pO1xyXG4gIH1cclxufVxyXG5cclxuLyoqIEZvciB1c2UgYnkgYnJlZXplIHBsdWdpbiBhdXRob3JzIG9ubHkuICBUaGUgY2xhc3MgaXMgdXNlZCBpbiBtb3N0IFtbSVVyaUJ1aWxkZXJBZGFwdGVyXV0gaW1wbGVtZW50YXRpb25zXHJcbkBhZGFwdGVyIChzZWUgW1tJVXJpQnVpbGRlckFkYXB0ZXJdXSkgICAgXHJcbkBoaWRkZW4gXHJcbioqL1xyXG5leHBvcnQgY2xhc3MgRXhwYW5kQ2xhdXNlIHtcclxuICBwcm9wZXJ0eVBhdGhzOiBzdHJpbmdbXTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJvcGVydHlQYXRoczogc3RyaW5nW10pIHtcclxuICAgIHRoaXMucHJvcGVydHlQYXRocyA9IHByb3BlcnR5UGF0aHM7XHJcbiAgfVxyXG5cclxuICB0b0pTT05FeHQoY29udGV4dDogRW50aXR5UXVlcnlKc29uQ29udGV4dCkge1xyXG4gICAgcmV0dXJuIHRoaXMucHJvcGVydHlQYXRocy5tYXAoZnVuY3Rpb24gKHBwKSB7XHJcbiAgICAgIHJldHVybiBjb250ZXh0LnByb3BlcnR5UGF0aEZuIShwcCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG59XHJcblxyXG5cclxuIl19