@microsoft/terraform-cdk-constructs 1.2.0 → 1.3.1

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 (291) hide show
  1. package/.jsii +54630 -26185
  2. package/API.md +72091 -23784
  3. package/lib/azure-actiongroup/index.d.ts +0 -10
  4. package/lib/azure-actiongroup/index.js +1 -11
  5. package/lib/azure-actiongroup/lib/action-group.d.ts +0 -10
  6. package/lib/azure-actiongroup/lib/action-group.js +6 -32
  7. package/lib/azure-actiongroup/lib/index.d.ts +1 -4
  8. package/lib/azure-actiongroup/lib/index.js +2 -5
  9. package/lib/azure-activitylogalert/index.d.ts +0 -10
  10. package/lib/azure-activitylogalert/index.js +1 -11
  11. package/lib/azure-activitylogalert/lib/activity-log-alert.d.ts +0 -10
  12. package/lib/azure-activitylogalert/lib/activity-log-alert.js +6 -32
  13. package/lib/azure-activitylogalert/lib/index.d.ts +1 -4
  14. package/lib/azure-activitylogalert/lib/index.js +2 -5
  15. package/lib/azure-aks/index.d.ts +0 -8
  16. package/lib/azure-aks/index.js +1 -11
  17. package/lib/azure-aks/lib/aks-cluster.d.ts +4 -13
  18. package/lib/azure-aks/lib/aks-cluster.js +13 -36
  19. package/lib/azure-aks/lib/index.d.ts +1 -10
  20. package/lib/azure-aks/lib/index.js +2 -21
  21. package/lib/azure-diagnosticsettings/index.d.ts +0 -6
  22. package/lib/azure-diagnosticsettings/index.js +1 -7
  23. package/lib/azure-diagnosticsettings/lib/diagnostic-settings.d.ts +0 -10
  24. package/lib/azure-diagnosticsettings/lib/diagnostic-settings.js +6 -32
  25. package/lib/azure-diagnosticsettings/lib/index.d.ts +1 -7
  26. package/lib/azure-diagnosticsettings/lib/index.js +2 -8
  27. package/lib/azure-dnsforwardingruleset/index.d.ts +1 -0
  28. package/lib/azure-dnsforwardingruleset/index.js +18 -0
  29. package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset-schemas.d.ts +24 -0
  30. package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset-schemas.js +206 -0
  31. package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset.d.ts +174 -0
  32. package/lib/azure-dnsforwardingruleset/lib/dns-forwarding-ruleset.js +214 -0
  33. package/lib/azure-dnsforwardingruleset/lib/forwarding-rule-schemas.d.ts +24 -0
  34. package/lib/azure-dnsforwardingruleset/lib/forwarding-rule-schemas.js +242 -0
  35. package/lib/azure-dnsforwardingruleset/lib/forwarding-rule.d.ts +193 -0
  36. package/lib/azure-dnsforwardingruleset/lib/forwarding-rule.js +193 -0
  37. package/lib/azure-dnsforwardingruleset/lib/index.d.ts +6 -0
  38. package/lib/azure-dnsforwardingruleset/lib/index.js +23 -0
  39. package/lib/azure-dnsforwardingruleset/lib/virtual-network-link-schemas.d.ts +24 -0
  40. package/lib/azure-dnsforwardingruleset/lib/virtual-network-link-schemas.js +199 -0
  41. package/lib/azure-dnsforwardingruleset/lib/virtual-network-link.d.ts +160 -0
  42. package/lib/azure-dnsforwardingruleset/lib/virtual-network-link.js +178 -0
  43. package/lib/azure-dnsforwardingruleset/test/dns-forwarding-ruleset.integ.d.ts +9 -0
  44. package/lib/azure-dnsforwardingruleset/test/dns-forwarding-ruleset.integ.js +133 -0
  45. package/lib/azure-dnsforwardingruleset/test/dns-forwarding-ruleset.spec.d.ts +9 -0
  46. package/lib/azure-dnsforwardingruleset/test/dns-forwarding-ruleset.spec.js +350 -0
  47. package/lib/azure-dnsforwardingruleset/test/forwarding-rule.spec.d.ts +9 -0
  48. package/lib/azure-dnsforwardingruleset/test/forwarding-rule.spec.js +397 -0
  49. package/lib/azure-dnsforwardingruleset/test/virtual-network-link.spec.d.ts +9 -0
  50. package/lib/azure-dnsforwardingruleset/test/virtual-network-link.spec.js +285 -0
  51. package/lib/azure-dnsresolver/index.d.ts +1 -0
  52. package/lib/azure-dnsresolver/index.js +18 -0
  53. package/lib/azure-dnsresolver/lib/dns-resolver-schemas.d.ts +24 -0
  54. package/lib/azure-dnsresolver/lib/dns-resolver-schemas.js +218 -0
  55. package/lib/azure-dnsresolver/lib/dns-resolver.d.ts +170 -0
  56. package/lib/azure-dnsresolver/lib/dns-resolver.js +236 -0
  57. package/lib/azure-dnsresolver/lib/inbound-endpoint-schemas.d.ts +24 -0
  58. package/lib/azure-dnsresolver/lib/inbound-endpoint-schemas.js +261 -0
  59. package/lib/azure-dnsresolver/lib/inbound-endpoint.d.ts +189 -0
  60. package/lib/azure-dnsresolver/lib/inbound-endpoint.js +243 -0
  61. package/lib/azure-dnsresolver/lib/index.d.ts +6 -0
  62. package/lib/azure-dnsresolver/lib/index.js +23 -0
  63. package/lib/azure-dnsresolver/lib/outbound-endpoint-schemas.d.ts +24 -0
  64. package/lib/azure-dnsresolver/lib/outbound-endpoint-schemas.js +231 -0
  65. package/lib/azure-dnsresolver/lib/outbound-endpoint.d.ts +175 -0
  66. package/lib/azure-dnsresolver/lib/outbound-endpoint.js +234 -0
  67. package/lib/azure-dnsresolver/test/dns-resolver.integ.d.ts +14 -0
  68. package/lib/azure-dnsresolver/test/dns-resolver.integ.js +117 -0
  69. package/lib/azure-dnsresolver/test/dns-resolver.spec.d.ts +9 -0
  70. package/lib/azure-dnsresolver/test/dns-resolver.spec.js +353 -0
  71. package/lib/azure-dnsresolver/test/inbound-endpoint.integ.d.ts +9 -0
  72. package/lib/azure-dnsresolver/test/inbound-endpoint.integ.js +151 -0
  73. package/lib/azure-dnsresolver/test/inbound-endpoint.spec.d.ts +9 -0
  74. package/lib/azure-dnsresolver/test/inbound-endpoint.spec.js +441 -0
  75. package/lib/azure-dnsresolver/test/outbound-endpoint.integ.d.ts +9 -0
  76. package/lib/azure-dnsresolver/test/outbound-endpoint.integ.js +149 -0
  77. package/lib/azure-dnsresolver/test/outbound-endpoint.spec.d.ts +9 -0
  78. package/lib/azure-dnsresolver/test/outbound-endpoint.spec.js +301 -0
  79. package/lib/azure-dnszone/index.d.ts +1 -0
  80. package/lib/azure-dnszone/index.js +18 -0
  81. package/lib/azure-dnszone/lib/dns-zone-schemas.d.ts +24 -0
  82. package/lib/azure-dnszone/lib/dns-zone-schemas.js +191 -0
  83. package/lib/azure-dnszone/lib/dns-zone.d.ts +182 -0
  84. package/lib/azure-dnszone/lib/dns-zone.js +228 -0
  85. package/lib/azure-dnszone/lib/index.d.ts +2 -0
  86. package/lib/azure-dnszone/lib/index.js +19 -0
  87. package/lib/azure-dnszone/test/dns-zone.integ.d.ts +9 -0
  88. package/lib/azure-dnszone/test/dns-zone.integ.js +85 -0
  89. package/lib/azure-dnszone/test/dns-zone.spec.d.ts +9 -0
  90. package/lib/azure-dnszone/test/dns-zone.spec.js +285 -0
  91. package/lib/azure-metricalert/index.d.ts +0 -10
  92. package/lib/azure-metricalert/index.js +1 -11
  93. package/lib/azure-metricalert/lib/index.d.ts +1 -4
  94. package/lib/azure-metricalert/lib/index.js +2 -5
  95. package/lib/azure-metricalert/lib/metric-alert.d.ts +0 -10
  96. package/lib/azure-metricalert/lib/metric-alert.js +6 -32
  97. package/lib/azure-networkinterface/index.d.ts +0 -3
  98. package/lib/azure-networkinterface/index.js +1 -4
  99. package/lib/azure-networkinterface/lib/index.d.ts +1 -5
  100. package/lib/azure-networkinterface/lib/index.js +2 -5
  101. package/lib/azure-networkinterface/lib/network-interface.d.ts +4 -9
  102. package/lib/azure-networkinterface/lib/network-interface.js +14 -29
  103. package/lib/azure-networkinterface/test/network-interface.integ.js +20 -6
  104. package/lib/azure-networksecuritygroup/index.d.ts +0 -5
  105. package/lib/azure-networksecuritygroup/index.js +1 -6
  106. package/lib/azure-networksecuritygroup/lib/index.d.ts +2 -5
  107. package/lib/azure-networksecuritygroup/lib/index.js +17 -14
  108. package/lib/azure-networksecuritygroup/lib/network-security-group.d.ts +4 -13
  109. package/lib/azure-networksecuritygroup/lib/network-security-group.js +14 -36
  110. package/lib/azure-policyassignment/index.d.ts +1 -0
  111. package/lib/azure-policyassignment/index.js +18 -0
  112. package/lib/azure-policyassignment/lib/index.d.ts +2 -0
  113. package/lib/azure-policyassignment/lib/index.js +19 -0
  114. package/lib/azure-policyassignment/lib/policy-assignment-schemas.d.ts +25 -0
  115. package/lib/azure-policyassignment/lib/policy-assignment-schemas.js +260 -0
  116. package/lib/azure-policyassignment/lib/policy-assignment.d.ts +349 -0
  117. package/lib/azure-policyassignment/lib/policy-assignment.js +237 -0
  118. package/lib/azure-policyassignment/test/policy-assignment.integ.d.ts +13 -0
  119. package/lib/azure-policyassignment/test/policy-assignment.integ.js +153 -0
  120. package/lib/azure-policyassignment/test/policy-assignment.spec.d.ts +9 -0
  121. package/lib/azure-policyassignment/test/policy-assignment.spec.js +651 -0
  122. package/lib/azure-policydefinition/index.d.ts +1 -0
  123. package/lib/azure-policydefinition/index.js +18 -0
  124. package/lib/azure-policydefinition/lib/index.d.ts +2 -0
  125. package/lib/azure-policydefinition/lib/index.js +19 -0
  126. package/lib/azure-policydefinition/lib/policy-definition-schemas.d.ts +25 -0
  127. package/lib/azure-policydefinition/lib/policy-definition-schemas.js +210 -0
  128. package/lib/azure-policydefinition/lib/policy-definition.d.ts +281 -0
  129. package/lib/azure-policydefinition/lib/policy-definition.js +236 -0
  130. package/lib/azure-policydefinition/test/policy-definition.integ.d.ts +9 -0
  131. package/lib/azure-policydefinition/test/policy-definition.integ.js +137 -0
  132. package/lib/azure-policydefinition/test/policy-definition.spec.d.ts +9 -0
  133. package/lib/azure-policydefinition/test/policy-definition.spec.js +806 -0
  134. package/lib/azure-privatednszone/index.d.ts +1 -0
  135. package/lib/azure-privatednszone/index.js +18 -0
  136. package/lib/azure-privatednszone/lib/index.d.ts +2 -0
  137. package/lib/azure-privatednszone/lib/index.js +19 -0
  138. package/lib/azure-privatednszone/lib/private-dns-zone-schemas.d.ts +24 -0
  139. package/lib/azure-privatednszone/lib/private-dns-zone-schemas.js +254 -0
  140. package/lib/azure-privatednszone/lib/private-dns-zone.d.ts +178 -0
  141. package/lib/azure-privatednszone/lib/private-dns-zone.js +272 -0
  142. package/lib/azure-privatednszone/test/private-dns-zone.integ.d.ts +9 -0
  143. package/lib/azure-privatednszone/test/private-dns-zone.integ.js +84 -0
  144. package/lib/azure-privatednszone/test/private-dns-zone.spec.d.ts +9 -0
  145. package/lib/azure-privatednszone/test/private-dns-zone.spec.js +341 -0
  146. package/lib/azure-privatednszonelink/index.d.ts +1 -0
  147. package/lib/azure-privatednszonelink/index.js +18 -0
  148. package/lib/azure-privatednszonelink/lib/index.d.ts +2 -0
  149. package/lib/azure-privatednszonelink/lib/index.js +19 -0
  150. package/lib/azure-privatednszonelink/lib/private-dns-zone-link-schemas.d.ts +24 -0
  151. package/lib/azure-privatednszonelink/lib/private-dns-zone-link-schemas.js +262 -0
  152. package/lib/azure-privatednszonelink/lib/private-dns-zone-link.d.ts +202 -0
  153. package/lib/azure-privatednszonelink/lib/private-dns-zone-link.js +250 -0
  154. package/lib/azure-privatednszonelink/test/private-dns-zone-link.integ.d.ts +9 -0
  155. package/lib/azure-privatednszonelink/test/private-dns-zone-link.integ.js +110 -0
  156. package/lib/azure-privatednszonelink/test/private-dns-zone-link.spec.d.ts +9 -0
  157. package/lib/azure-privatednszonelink/test/private-dns-zone-link.spec.js +465 -0
  158. package/lib/azure-publicipaddress/index.d.ts +0 -5
  159. package/lib/azure-publicipaddress/index.js +1 -6
  160. package/lib/azure-publicipaddress/lib/index.d.ts +2 -9
  161. package/lib/azure-publicipaddress/lib/index.js +17 -17
  162. package/lib/azure-publicipaddress/lib/public-ip-address.d.ts +4 -13
  163. package/lib/azure-publicipaddress/lib/public-ip-address.js +14 -36
  164. package/lib/azure-resourcegroup/index.d.ts +0 -37
  165. package/lib/azure-resourcegroup/index.js +1 -39
  166. package/lib/azure-resourcegroup/lib/index.d.ts +1 -44
  167. package/lib/azure-resourcegroup/lib/index.js +2 -43
  168. package/lib/azure-resourcegroup/lib/resource-group.d.ts +9 -23
  169. package/lib/azure-resourcegroup/lib/resource-group.js +23 -56
  170. package/lib/azure-resourcegroup/test/resource-group.spec.js +13 -19
  171. package/lib/azure-roleassignment/index.d.ts +1 -0
  172. package/lib/azure-roleassignment/index.js +18 -0
  173. package/lib/azure-roleassignment/lib/index.d.ts +2 -0
  174. package/lib/azure-roleassignment/lib/index.js +19 -0
  175. package/lib/azure-roleassignment/lib/role-assignment-schemas.d.ts +25 -0
  176. package/lib/azure-roleassignment/lib/role-assignment-schemas.js +238 -0
  177. package/lib/azure-roleassignment/lib/role-assignment.d.ts +294 -0
  178. package/lib/azure-roleassignment/lib/role-assignment.js +257 -0
  179. package/lib/azure-roleassignment/test/role-assignment.integ.d.ts +12 -0
  180. package/lib/azure-roleassignment/test/role-assignment.integ.js +101 -0
  181. package/lib/azure-roleassignment/test/role-assignment.spec.d.ts +9 -0
  182. package/lib/azure-roleassignment/test/role-assignment.spec.js +633 -0
  183. package/lib/azure-roledefinition/index.d.ts +1 -0
  184. package/lib/azure-roledefinition/index.js +18 -0
  185. package/lib/azure-roledefinition/lib/index.d.ts +2 -0
  186. package/lib/azure-roledefinition/lib/index.js +19 -0
  187. package/lib/azure-roledefinition/lib/role-definition-schemas.d.ts +25 -0
  188. package/lib/azure-roledefinition/lib/role-definition-schemas.js +195 -0
  189. package/lib/azure-roledefinition/lib/role-definition.d.ts +236 -0
  190. package/lib/azure-roledefinition/lib/role-definition.js +192 -0
  191. package/lib/azure-roledefinition/test/role-definition.integ.d.ts +12 -0
  192. package/lib/azure-roledefinition/test/role-definition.integ.js +142 -0
  193. package/lib/azure-roledefinition/test/role-definition.spec.d.ts +9 -0
  194. package/lib/azure-roledefinition/test/role-definition.spec.js +946 -0
  195. package/lib/azure-storageaccount/index.d.ts +0 -19
  196. package/lib/azure-storageaccount/index.js +1 -20
  197. package/lib/azure-storageaccount/lib/index.d.ts +1 -7
  198. package/lib/azure-storageaccount/lib/index.js +2 -8
  199. package/lib/azure-storageaccount/lib/storage-account.d.ts +4 -9
  200. package/lib/azure-storageaccount/lib/storage-account.js +15 -29
  201. package/lib/azure-subnet/index.d.ts +0 -3
  202. package/lib/azure-subnet/index.js +1 -4
  203. package/lib/azure-subnet/lib/index.d.ts +1 -4
  204. package/lib/azure-subnet/lib/index.js +2 -5
  205. package/lib/azure-subnet/lib/subnet.d.ts +3 -14
  206. package/lib/azure-subnet/lib/subnet.js +28 -47
  207. package/lib/azure-subnet/test/subnet.integ.js +19 -7
  208. package/lib/azure-subnet/test/subnet.spec.js +1 -2
  209. package/lib/azure-virtualmachine/index.d.ts +0 -6
  210. package/lib/azure-virtualmachine/index.js +1 -7
  211. package/lib/azure-virtualmachine/lib/index.d.ts +1 -10
  212. package/lib/azure-virtualmachine/lib/index.js +2 -21
  213. package/lib/azure-virtualmachine/lib/virtual-machine.d.ts +4 -13
  214. package/lib/azure-virtualmachine/lib/virtual-machine.js +15 -36
  215. package/lib/azure-virtualnetwork/index.d.ts +0 -9
  216. package/lib/azure-virtualnetwork/index.js +1 -11
  217. package/lib/azure-virtualnetwork/lib/index.d.ts +2 -9
  218. package/lib/azure-virtualnetwork/lib/index.js +17 -20
  219. package/lib/azure-virtualnetwork/lib/virtual-network.d.ts +4 -13
  220. package/lib/azure-virtualnetwork/lib/virtual-network.js +15 -36
  221. package/lib/azure-virtualnetworkmanager/index.d.ts +1 -0
  222. package/lib/azure-virtualnetworkmanager/index.js +18 -0
  223. package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration-schemas.d.ts +48 -0
  224. package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration-schemas.js +265 -0
  225. package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration.d.ts +185 -0
  226. package/lib/azure-virtualnetworkmanager/lib/connectivity-configuration.js +206 -0
  227. package/lib/azure-virtualnetworkmanager/lib/index.d.ts +14 -0
  228. package/lib/azure-virtualnetworkmanager/lib/index.js +31 -0
  229. package/lib/azure-virtualnetworkmanager/lib/network-group-schemas.d.ts +32 -0
  230. package/lib/azure-virtualnetworkmanager/lib/network-group-schemas.js +189 -0
  231. package/lib/azure-virtualnetworkmanager/lib/network-group-static-member-schemas.d.ts +32 -0
  232. package/lib/azure-virtualnetworkmanager/lib/network-group-static-member-schemas.js +201 -0
  233. package/lib/azure-virtualnetworkmanager/lib/network-group-static-member.d.ts +135 -0
  234. package/lib/azure-virtualnetworkmanager/lib/network-group-static-member.js +163 -0
  235. package/lib/azure-virtualnetworkmanager/lib/network-group.d.ts +139 -0
  236. package/lib/azure-virtualnetworkmanager/lib/network-group.js +158 -0
  237. package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration-schemas.d.ts +32 -0
  238. package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration-schemas.js +182 -0
  239. package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration.d.ts +144 -0
  240. package/lib/azure-virtualnetworkmanager/lib/security-admin-configuration.js +164 -0
  241. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection-schemas.d.ts +38 -0
  242. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection-schemas.js +206 -0
  243. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection.d.ts +142 -0
  244. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-collection.js +162 -0
  245. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-schemas.d.ts +39 -0
  246. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule-schemas.js +359 -0
  247. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule.d.ts +221 -0
  248. package/lib/azure-virtualnetworkmanager/lib/security-admin-rule.js +204 -0
  249. package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager-schemas.d.ts +32 -0
  250. package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager-schemas.js +236 -0
  251. package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager.d.ts +337 -0
  252. package/lib/azure-virtualnetworkmanager/lib/virtual-network-manager.js +283 -0
  253. package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.integ.d.ts +25 -0
  254. package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.integ.js +402 -0
  255. package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.spec.d.ts +9 -0
  256. package/lib/azure-virtualnetworkmanager/test/virtual-network-manager.spec.js +1652 -0
  257. package/lib/azure-vmss/index.d.ts +0 -5
  258. package/lib/azure-vmss/index.js +1 -6
  259. package/lib/azure-vmss/lib/index.d.ts +0 -7
  260. package/lib/azure-vmss/lib/index.js +1 -21
  261. package/lib/azure-vmss/lib/virtual-machine-scale-set.d.ts +5 -13
  262. package/lib/azure-vmss/lib/virtual-machine-scale-set.js +29 -53
  263. package/lib/core-azure/lib/azapi/azapi-resource-tags.spec.d.ts +10 -0
  264. package/lib/core-azure/lib/azapi/azapi-resource-tags.spec.js +218 -0
  265. package/lib/core-azure/lib/azapi/azapi-resource.d.ts +206 -26
  266. package/lib/core-azure/lib/azapi/azapi-resource.js +379 -91
  267. package/lib/core-azure/lib/azapi/azapi-resource.spec.js +2 -2
  268. package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-client-config/index.js +2 -2
  269. package/lib/core-azure/lib/azapi/providers-azapi/data-azapi-resource/index.js +5 -5
  270. package/lib/core-azure/lib/azapi/providers-azapi/provider/index.js +5 -3
  271. package/lib/core-azure/lib/azapi/providers-azapi/resource/index.js +5 -5
  272. package/lib/core-azure/lib/azapi/providers-azapi/resource-action/index.js +3 -3
  273. package/lib/core-azure/lib/azapi/providers-azapi/update-resource/index.js +3 -3
  274. package/lib/core-azure/lib/azapi/resource-schema-validator.d.ts +118 -0
  275. package/lib/core-azure/lib/azapi/resource-schema-validator.js +236 -0
  276. package/lib/core-azure/lib/azapi/resource-version-manager.d.ts +103 -0
  277. package/lib/core-azure/lib/azapi/resource-version-manager.js +168 -0
  278. package/lib/core-azure/lib/azapi/schema-mapper/schema-mapper.js +11 -6
  279. package/lib/core-azure/lib/index.d.ts +2 -2
  280. package/lib/core-azure/lib/index.js +5 -5
  281. package/lib/core-azure/lib/version-manager/api-version-manager.js +1 -1
  282. package/lib/core-azure/lib/version-manager/interfaces/version-interfaces.js +7 -7
  283. package/lib/index.d.ts +19 -0
  284. package/lib/index.js +21 -2
  285. package/lib/testing/index.js +2 -2
  286. package/lib/testing/lib/cleanup.d.ts +1 -0
  287. package/lib/testing/lib/cleanup.js +19 -12
  288. package/lib/testing/lib/metadata.js +19 -16
  289. package/package.json +1 -1
  290. package/scripts/cleanup-test-resources.ts +22 -4
  291. package/scripts/generate-index.js +25 -8
@@ -0,0 +1,806 @@
1
+ "use strict";
2
+ /**
3
+ * Comprehensive tests for the unified PolicyDefinition implementation
4
+ *
5
+ * This test suite validates the unified PolicyDefinition class that uses
6
+ * the VersionedAzapiResource framework. Tests cover automatic version resolution,
7
+ * explicit version pinning, schema validation, property transformation, and
8
+ * policy-specific functionality.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ const cdktf_1 = require("cdktf");
12
+ const cdktf = require("cdktf");
13
+ const api_version_manager_1 = require("../../core-azure/lib/version-manager/api-version-manager");
14
+ const version_interfaces_1 = require("../../core-azure/lib/version-manager/interfaces/version-interfaces");
15
+ const policy_definition_1 = require("../lib/policy-definition");
16
+ const policy_definition_schemas_1 = require("../lib/policy-definition-schemas");
17
+ describe("PolicyDefinition - Unified Implementation", () => {
18
+ let app;
19
+ let stack;
20
+ let manager;
21
+ beforeEach(() => {
22
+ app = cdktf_1.Testing.app();
23
+ stack = new cdktf.TerraformStack(app, "TestStack");
24
+ manager = api_version_manager_1.ApiVersionManager.instance();
25
+ // Ensure Policy Definition schemas are registered
26
+ try {
27
+ manager.registerResourceType(policy_definition_schemas_1.POLICY_DEFINITION_TYPE, policy_definition_schemas_1.ALL_POLICY_DEFINITION_VERSIONS);
28
+ }
29
+ catch (error) {
30
+ // Ignore if already registered
31
+ }
32
+ });
33
+ describe("Constructor and Basic Properties", () => {
34
+ it("should create policy definition with automatic latest version resolution", () => {
35
+ const props = {
36
+ name: "test-policy",
37
+ policyRule: {
38
+ if: {
39
+ field: "tags['Environment']",
40
+ exists: "false",
41
+ },
42
+ then: {
43
+ effect: "deny",
44
+ },
45
+ },
46
+ };
47
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", props);
48
+ expect(policyDefinition).toBeInstanceOf(policy_definition_1.PolicyDefinition);
49
+ expect(policyDefinition.resolvedApiVersion).toBe("2021-06-01"); // Latest version
50
+ expect(policyDefinition.props).toBe(props);
51
+ expect(policyDefinition.name).toBe("test-policy");
52
+ });
53
+ it("should create policy definition with explicit version pinning", () => {
54
+ const props = {
55
+ name: "test-policy-pinned",
56
+ apiVersion: "2021-06-01",
57
+ policyRule: {
58
+ if: {
59
+ field: "type",
60
+ equals: "Microsoft.Compute/virtualMachines",
61
+ },
62
+ then: {
63
+ effect: "audit",
64
+ },
65
+ },
66
+ };
67
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", props);
68
+ expect(policyDefinition.resolvedApiVersion).toBe("2021-06-01");
69
+ });
70
+ it("should create policy definition with all optional properties", () => {
71
+ const props = {
72
+ name: "test-policy-full",
73
+ displayName: "Test Policy Definition",
74
+ description: "A test policy definition for unit testing",
75
+ policyType: "Custom",
76
+ mode: "All",
77
+ policyRule: {
78
+ if: {
79
+ field: "location",
80
+ notIn: ["eastus", "westus"],
81
+ },
82
+ then: {
83
+ effect: "deny",
84
+ },
85
+ },
86
+ parameters: {
87
+ allowedLocations: {
88
+ type: "Array",
89
+ metadata: {
90
+ displayName: "Allowed locations",
91
+ description: "The list of allowed locations for resources",
92
+ },
93
+ },
94
+ },
95
+ metadata: {
96
+ category: "General",
97
+ version: "1.0.0",
98
+ },
99
+ ignoreChanges: ["metadata"],
100
+ enableValidation: true,
101
+ enableMigrationAnalysis: true,
102
+ enableTransformation: true,
103
+ };
104
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", props);
105
+ expect(policyDefinition.props.displayName).toBe("Test Policy Definition");
106
+ expect(policyDefinition.props.description).toBe("A test policy definition for unit testing");
107
+ expect(policyDefinition.props.policyType).toBe("Custom");
108
+ expect(policyDefinition.props.mode).toBe("All");
109
+ expect(policyDefinition.props.parameters).toBeDefined();
110
+ expect(policyDefinition.props.metadata).toBeDefined();
111
+ });
112
+ it("should use default name when name is not provided", () => {
113
+ const props = {
114
+ policyRule: {
115
+ if: {
116
+ field: "type",
117
+ equals: "Microsoft.Storage/storageAccounts",
118
+ },
119
+ then: {
120
+ effect: "audit",
121
+ },
122
+ },
123
+ };
124
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", props);
125
+ expect(policyDefinition.name).toBe("TestPolicyDefinition");
126
+ });
127
+ it("should require policyRule to be provided", () => {
128
+ const props = {
129
+ name: "test-policy",
130
+ };
131
+ expect(() => {
132
+ new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", props);
133
+ }).toThrow("Required property 'policyRule' is missing");
134
+ });
135
+ });
136
+ describe("Framework Integration", () => {
137
+ it("should resolve latest API version automatically", () => {
138
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
139
+ name: "test-policy",
140
+ policyRule: { if: {}, then: { effect: "deny" } },
141
+ });
142
+ expect(policyDefinition.resolvedApiVersion).toBe("2021-06-01");
143
+ expect(policyDefinition.latestVersion()).toBe("2021-06-01");
144
+ });
145
+ it("should support all registered API versions", () => {
146
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
147
+ name: "test-policy",
148
+ policyRule: { if: {}, then: { effect: "deny" } },
149
+ });
150
+ const supportedVersions = policyDefinition.supportedVersions();
151
+ expect(supportedVersions).toContain("2021-06-01");
152
+ });
153
+ it("should validate version support", () => {
154
+ // Valid version
155
+ expect(() => {
156
+ new policy_definition_1.PolicyDefinition(stack, "ValidVersion", {
157
+ name: "test-policy",
158
+ policyRule: { if: {}, then: { effect: "deny" } },
159
+ apiVersion: "2021-06-01",
160
+ });
161
+ }).not.toThrow();
162
+ // Invalid version
163
+ expect(() => {
164
+ new policy_definition_1.PolicyDefinition(stack, "InvalidVersion", {
165
+ name: "test-policy",
166
+ policyRule: { if: {}, then: { effect: "deny" } },
167
+ apiVersion: "2022-01-01",
168
+ });
169
+ }).toThrow("Unsupported API version '2022-01-01'");
170
+ });
171
+ it("should load correct schema for resolved version", () => {
172
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
173
+ name: "test-policy",
174
+ policyRule: { if: {}, then: { effect: "deny" } },
175
+ apiVersion: "2021-06-01",
176
+ });
177
+ expect(policyDefinition.schema).toBeDefined();
178
+ expect(policyDefinition.schema.resourceType).toBe(policy_definition_schemas_1.POLICY_DEFINITION_TYPE);
179
+ expect(policyDefinition.schema.version).toBe("2021-06-01");
180
+ expect(policyDefinition.schema.properties).toBeDefined();
181
+ });
182
+ it("should load version configuration correctly", () => {
183
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
184
+ name: "test-policy",
185
+ policyRule: { if: {}, then: { effect: "deny" } },
186
+ });
187
+ expect(policyDefinition.versionConfig).toBeDefined();
188
+ expect(policyDefinition.versionConfig.version).toBe("2021-06-01");
189
+ expect(policyDefinition.versionConfig.supportLevel).toBe(version_interfaces_1.VersionSupportLevel.ACTIVE);
190
+ });
191
+ });
192
+ describe("Property Validation", () => {
193
+ it("should validate properties when validation is enabled", () => {
194
+ const props = {
195
+ name: "test-policy",
196
+ policyRule: {
197
+ if: {
198
+ field: "type",
199
+ equals: "Microsoft.Compute/virtualMachines",
200
+ },
201
+ then: {
202
+ effect: "audit",
203
+ },
204
+ },
205
+ enableValidation: true,
206
+ };
207
+ expect(() => {
208
+ new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", props);
209
+ }).not.toThrow();
210
+ });
211
+ it("should have validation results for valid properties", () => {
212
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
213
+ name: "valid-policy",
214
+ displayName: "Valid Policy",
215
+ policyRule: { if: {}, then: { effect: "deny" } },
216
+ enableValidation: true,
217
+ });
218
+ expect(policyDefinition.validationResult).toBeDefined();
219
+ expect(policyDefinition.validationResult.valid).toBe(true);
220
+ expect(policyDefinition.validationResult.errors).toHaveLength(0);
221
+ });
222
+ it("should skip validation when disabled", () => {
223
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
224
+ name: "test-policy",
225
+ policyRule: { if: {}, then: { effect: "deny" } },
226
+ enableValidation: false,
227
+ });
228
+ expect(policyDefinition).toBeDefined();
229
+ });
230
+ });
231
+ describe("Migration Analysis", () => {
232
+ it("should skip migration analysis for single version", () => {
233
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
234
+ name: "test-policy",
235
+ policyRule: { if: {}, then: { effect: "deny" } },
236
+ apiVersion: "2021-06-01",
237
+ });
238
+ // Since there's only one version, migration analysis should be skipped
239
+ expect(policyDefinition).toBeDefined();
240
+ });
241
+ it("should skip migration analysis when disabled", () => {
242
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
243
+ name: "test-policy",
244
+ policyRule: { if: {}, then: { effect: "deny" } },
245
+ enableMigrationAnalysis: false,
246
+ });
247
+ expect(policyDefinition.migrationAnalysis).toBeUndefined();
248
+ });
249
+ });
250
+ describe("Resource Creation and Body", () => {
251
+ it("should create correct resource body with minimal properties", () => {
252
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
253
+ name: "test-policy",
254
+ policyRule: {
255
+ if: {
256
+ field: "tags['Environment']",
257
+ exists: "false",
258
+ },
259
+ then: {
260
+ effect: "deny",
261
+ },
262
+ },
263
+ });
264
+ expect(policyDefinition).toBeDefined();
265
+ expect(policyDefinition.props.policyRule).toBeDefined();
266
+ });
267
+ it("should create correct resource body with all properties", () => {
268
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
269
+ name: "test-policy",
270
+ displayName: "Test Policy",
271
+ description: "A test policy",
272
+ policyType: "Custom",
273
+ mode: "Indexed",
274
+ policyRule: {
275
+ if: {
276
+ field: "location",
277
+ notIn: ["eastus", "westus"],
278
+ },
279
+ then: {
280
+ effect: "deny",
281
+ },
282
+ },
283
+ parameters: {
284
+ allowedLocations: {
285
+ type: "Array",
286
+ },
287
+ },
288
+ metadata: {
289
+ category: "Compliance",
290
+ },
291
+ });
292
+ expect(policyDefinition).toBeDefined();
293
+ expect(policyDefinition.props.displayName).toBe("Test Policy");
294
+ expect(policyDefinition.props.policyType).toBe("Custom");
295
+ expect(policyDefinition.props.mode).toBe("Indexed");
296
+ });
297
+ it("should create Terraform outputs", () => {
298
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
299
+ name: "test-policy-outputs",
300
+ policyRule: { if: {}, then: { effect: "deny" } },
301
+ });
302
+ expect(policyDefinition.idOutput).toBeInstanceOf(cdktf.TerraformOutput);
303
+ expect(policyDefinition.nameOutput).toBeInstanceOf(cdktf.TerraformOutput);
304
+ });
305
+ });
306
+ describe("Public Methods and Properties", () => {
307
+ let policyDefinition;
308
+ beforeEach(() => {
309
+ policyDefinition = new policy_definition_1.PolicyDefinition(stack, "TestPolicyDefinition", {
310
+ name: "test-policy",
311
+ displayName: "Test Policy",
312
+ policyType: "Custom",
313
+ mode: "All",
314
+ policyRule: {
315
+ if: {
316
+ field: "type",
317
+ equals: "Microsoft.Compute/virtualMachines",
318
+ },
319
+ then: {
320
+ effect: "audit",
321
+ },
322
+ },
323
+ });
324
+ });
325
+ it("should have correct id format", () => {
326
+ expect(policyDefinition.id).toMatch(/^\$\{.*\.id\}$/);
327
+ });
328
+ it("should have resourceId property matching id", () => {
329
+ expect(policyDefinition.resourceId).toBe(policyDefinition.id);
330
+ });
331
+ it("should return correct policyType", () => {
332
+ expect(policyDefinition.policyType).toBe("Custom");
333
+ });
334
+ it("should return correct policyMode", () => {
335
+ expect(policyDefinition.policyMode).toBe("All");
336
+ });
337
+ it("should use default policyType when not provided", () => {
338
+ const defaultPolicy = new policy_definition_1.PolicyDefinition(stack, "DefaultTypePolicy", {
339
+ name: "default-policy",
340
+ policyRule: { if: {}, then: { effect: "deny" } },
341
+ });
342
+ expect(defaultPolicy.policyType).toBe("Custom");
343
+ });
344
+ it("should use default mode when not provided", () => {
345
+ const defaultPolicy = new policy_definition_1.PolicyDefinition(stack, "DefaultModePolicy", {
346
+ name: "default-policy",
347
+ policyRule: { if: {}, then: { effect: "deny" } },
348
+ });
349
+ expect(defaultPolicy.policyMode).toBe("All");
350
+ });
351
+ });
352
+ describe("Ignore Changes Configuration", () => {
353
+ it("should apply ignore changes lifecycle rules", () => {
354
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "IgnoreChangesPolicy", {
355
+ name: "test-policy",
356
+ policyRule: { if: {}, then: { effect: "deny" } },
357
+ ignoreChanges: ["metadata", "description"],
358
+ });
359
+ expect(policyDefinition).toBeInstanceOf(policy_definition_1.PolicyDefinition);
360
+ });
361
+ it("should handle empty ignore changes array", () => {
362
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "EmptyIgnorePolicy", {
363
+ name: "test-policy",
364
+ policyRule: { if: {}, then: { effect: "deny" } },
365
+ ignoreChanges: [],
366
+ });
367
+ expect(policyDefinition).toBeInstanceOf(policy_definition_1.PolicyDefinition);
368
+ });
369
+ });
370
+ describe("Policy Rule Validation", () => {
371
+ it("should accept complex policy rules", () => {
372
+ const complexRule = {
373
+ if: {
374
+ allOf: [
375
+ {
376
+ field: "type",
377
+ equals: "Microsoft.Storage/storageAccounts",
378
+ },
379
+ {
380
+ field: "Microsoft.Storage/storageAccounts/enableHttpsTrafficOnly",
381
+ notEquals: "true",
382
+ },
383
+ ],
384
+ },
385
+ then: {
386
+ effect: "deny",
387
+ },
388
+ };
389
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "ComplexRulePolicy", {
390
+ name: "complex-policy",
391
+ policyRule: complexRule,
392
+ });
393
+ expect(policyDefinition).toBeDefined();
394
+ expect(policyDefinition.props.policyRule).toEqual(complexRule);
395
+ });
396
+ it("should accept policy rules with parameters", () => {
397
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "ParameterizedPolicy", {
398
+ name: "parameterized-policy",
399
+ policyRule: {
400
+ if: {
401
+ field: "[concat('tags[', parameters('tagName'), ']')]",
402
+ exists: "false",
403
+ },
404
+ then: {
405
+ effect: "[parameters('effect')]",
406
+ },
407
+ },
408
+ parameters: {
409
+ tagName: {
410
+ type: "String",
411
+ metadata: {
412
+ displayName: "Tag Name",
413
+ description: "Name of the tag to check",
414
+ },
415
+ },
416
+ effect: {
417
+ type: "String",
418
+ allowedValues: ["audit", "deny"],
419
+ defaultValue: "audit",
420
+ },
421
+ },
422
+ });
423
+ expect(policyDefinition).toBeDefined();
424
+ expect(policyDefinition.props.parameters).toBeDefined();
425
+ });
426
+ it("should preserve complex allOf conditions with multiple field comparisons", () => {
427
+ const complexRule = {
428
+ if: {
429
+ allOf: [
430
+ {
431
+ field: "type",
432
+ equals: "Microsoft.Storage/storageAccounts",
433
+ },
434
+ {
435
+ field: "Microsoft.Storage/storageAccounts/networkAcls.defaultAction",
436
+ notEquals: "Deny",
437
+ },
438
+ ],
439
+ },
440
+ then: {
441
+ effect: "audit",
442
+ },
443
+ };
444
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "ComplexAllOf", {
445
+ name: "complex-allof-policy",
446
+ displayName: "Complex AllOf Policy",
447
+ policyRule: complexRule,
448
+ });
449
+ expect(policyDefinition).toBeDefined();
450
+ expect(policyDefinition.props.policyRule).toEqual(complexRule);
451
+ // Synthesize and verify the structure is preserved
452
+ const synthesized = cdktf_1.Testing.synth(stack);
453
+ const stackConfig = JSON.parse(synthesized);
454
+ const azapiResource = Object.values(stackConfig.resource.azapi_resource)[0];
455
+ // The body is jsonencode() wrapped, so we need to parse the actual policy rule from props
456
+ expect(policyDefinition.props.policyRule.if.allOf).toHaveLength(2);
457
+ expect(policyDefinition.props.policyRule.if.allOf[0].field).toBe("type");
458
+ expect(policyDefinition.props.policyRule.if.allOf[0].equals).toBe("Microsoft.Storage/storageAccounts");
459
+ expect(policyDefinition.props.policyRule.if.allOf[1].field).toBe("Microsoft.Storage/storageAccounts/networkAcls.defaultAction");
460
+ expect(policyDefinition.props.policyRule.if.allOf[1].notEquals).toBe("Deny");
461
+ expect(policyDefinition.props.policyRule.then.effect).toBe("audit");
462
+ // Verify the synthesized config has the body property set
463
+ expect(azapiResource.body).toBeDefined();
464
+ });
465
+ it("should preserve Azure Policy expressions without converting them", () => {
466
+ const rule = {
467
+ if: {
468
+ field: "location",
469
+ notIn: "[parameters('allowedLocations')]",
470
+ },
471
+ then: {
472
+ effect: "[parameters('effect')]",
473
+ },
474
+ };
475
+ new policy_definition_1.PolicyDefinition(stack, "AzurePolicyExpressions", {
476
+ name: "azure-expressions-policy",
477
+ policyRule: rule,
478
+ parameters: {
479
+ allowedLocations: { type: "Array" },
480
+ effect: { type: "String" },
481
+ },
482
+ });
483
+ const synthesized = cdktf_1.Testing.synth(stack);
484
+ const stackConfig = JSON.parse(synthesized);
485
+ const azapiResource = Object.values(stackConfig.resource.azapi_resource)[0];
486
+ // Verify Azure Policy expressions are preserved in the construct's props
487
+ expect(rule.if.notIn).toBe("[parameters('allowedLocations')]");
488
+ expect(rule.then.effect).toBe("[parameters('effect')]");
489
+ // Verify the synthesized config has the body property set
490
+ expect(azapiResource.body).toBeDefined();
491
+ });
492
+ it("should preserve DeployIfNotExists policy with ARM template", () => {
493
+ const complexRule = {
494
+ if: {
495
+ field: "type",
496
+ equals: "Microsoft.Network/virtualNetworks",
497
+ },
498
+ then: {
499
+ effect: "DeployIfNotExists",
500
+ details: {
501
+ type: "Microsoft.Network/networkManagers/networkGroups/staticMembers",
502
+ deploymentScope: "subscription",
503
+ existenceScope: "subscription",
504
+ roleDefinitionIds: [
505
+ "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c",
506
+ ],
507
+ deployment: {
508
+ location: "[field('location')]",
509
+ properties: {
510
+ mode: "incremental",
511
+ resourceGroup: "[variables('avnmResourceGroup')]",
512
+ subscriptionId: "[parameters('avnmSubscriptionId')]",
513
+ template: {
514
+ $schema: "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
515
+ contentVersion: "1.0.0.0",
516
+ parameters: {
517
+ vnetId: {
518
+ type: "string",
519
+ },
520
+ },
521
+ variables: {
522
+ staticMemberName: "[guid(parameters('vnetId'))]",
523
+ },
524
+ resources: [
525
+ {
526
+ type: "Microsoft.Network/networkManagers/networkGroups/staticMembers",
527
+ apiVersion: "2023-04-01",
528
+ name: "[concat(parameters('avnmId'), '/', variables('staticMemberName'))]",
529
+ properties: {
530
+ resourceId: "[parameters('vnetId')]",
531
+ },
532
+ },
533
+ ],
534
+ outputs: {
535
+ memberId: {
536
+ type: "string",
537
+ value: "[resourceId('Microsoft.Network/networkManagers/networkGroups/staticMembers', variables('staticMemberName'))]",
538
+ },
539
+ },
540
+ },
541
+ parameters: {
542
+ vnetId: {
543
+ value: "[field('id')]",
544
+ },
545
+ },
546
+ },
547
+ },
548
+ },
549
+ },
550
+ };
551
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "DeployIfNotExistsPolicy", {
552
+ name: "deploy-if-not-exists-policy",
553
+ displayName: "Deploy If Not Exists with ARM Template",
554
+ policyRule: complexRule,
555
+ parameters: {
556
+ avnmSubscriptionId: { type: "String" },
557
+ },
558
+ });
559
+ expect(policyDefinition).toBeDefined();
560
+ const synthesized = cdktf_1.Testing.synth(stack);
561
+ const stackConfig = JSON.parse(synthesized);
562
+ const azapiResource = Object.values(stackConfig.resource.azapi_resource)[0];
563
+ const details = policyDefinition.props.policyRule.then.details;
564
+ // Verify deployment structure is preserved (not converted to null)
565
+ expect(details.deployment).toBeDefined();
566
+ expect(details.deployment.location).toBe("[field('location')]");
567
+ expect(details.deployment.properties).toBeDefined();
568
+ expect(details.deployment.properties.mode).toBe("incremental");
569
+ expect(details.deployment.properties.resourceGroup).toBe("[variables('avnmResourceGroup')]");
570
+ expect(details.deployment.properties.subscriptionId).toBe("[parameters('avnmSubscriptionId')]");
571
+ // Verify ARM template is fully preserved (not converted to null)
572
+ const template = details.deployment.properties.template;
573
+ expect(template).toBeDefined();
574
+ expect(template.$schema).toBe("https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#");
575
+ expect(template.contentVersion).toBe("1.0.0.0");
576
+ expect(template.parameters).toBeDefined();
577
+ expect(template.parameters.vnetId).toBeDefined();
578
+ expect(template.variables).toBeDefined();
579
+ expect(template.variables.staticMemberName).toBe("[guid(parameters('vnetId'))]");
580
+ expect(template.resources).toHaveLength(1);
581
+ expect(template.resources[0].name).toBe("[concat(parameters('avnmId'), '/', variables('staticMemberName'))]");
582
+ expect(template.outputs).toBeDefined();
583
+ expect(template.outputs.memberId.value).toBe("[resourceId('Microsoft.Network/networkManagers/networkGroups/staticMembers', variables('staticMemberName'))]");
584
+ // Verify ARM template parameters are preserved
585
+ const deploymentParams = details.deployment.properties.parameters;
586
+ expect(deploymentParams).toBeDefined();
587
+ expect(deploymentParams.vnetId.value).toBe("[field('id')]");
588
+ // Verify schema validation is disabled to allow complex nested structures
589
+ expect(azapiResource.schema_validation_enabled).toBe(false);
590
+ expect(azapiResource.ignore_missing_property).toBe(true);
591
+ // Verify the synthesized config has the body property set
592
+ expect(azapiResource.body).toBeDefined();
593
+ });
594
+ it("should preserve deeply nested logical operators", () => {
595
+ const complexRule = {
596
+ if: {
597
+ allOf: [
598
+ {
599
+ field: "type",
600
+ equals: "Microsoft.Network/virtualNetworks",
601
+ },
602
+ {
603
+ anyOf: [
604
+ {
605
+ field: "Microsoft.Network/virtualNetworks/enableDdosProtection",
606
+ equals: "false",
607
+ },
608
+ {
609
+ not: {
610
+ field: "Microsoft.Network/virtualNetworks/subnets[*].serviceEndpoints[*].service",
611
+ contains: "Microsoft.Storage",
612
+ },
613
+ },
614
+ ],
615
+ },
616
+ ],
617
+ },
618
+ then: {
619
+ effect: "audit",
620
+ },
621
+ };
622
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "DeeplyNested", {
623
+ name: "deeply-nested-policy",
624
+ policyRule: complexRule,
625
+ });
626
+ expect(policyDefinition.props.policyRule).toEqual(complexRule);
627
+ const synthesized = cdktf_1.Testing.synth(stack);
628
+ const stackConfig = JSON.parse(synthesized);
629
+ const azapiResource = Object.values(stackConfig.resource.azapi_resource)[0];
630
+ // Verify the deeply nested structure is preserved in the construct's props
631
+ expect(policyDefinition.props.policyRule.if.allOf[1].anyOf[1].not).toBeDefined();
632
+ expect(policyDefinition.props.policyRule.if.allOf[1].anyOf[1].not.field).toBe("Microsoft.Network/virtualNetworks/subnets[*].serviceEndpoints[*].service");
633
+ // Verify the synthesized config has the body property set
634
+ expect(azapiResource.body).toBeDefined();
635
+ });
636
+ });
637
+ describe("Error Handling", () => {
638
+ it("should handle invalid API versions gracefully", () => {
639
+ expect(() => {
640
+ new policy_definition_1.PolicyDefinition(stack, "InvalidAPI", {
641
+ name: "test-policy",
642
+ policyRule: { if: {}, then: { effect: "deny" } },
643
+ apiVersion: "invalid-version",
644
+ });
645
+ }).toThrow("Unsupported API version 'invalid-version'");
646
+ });
647
+ it("should handle validation errors when validation is enabled", () => {
648
+ expect(() => {
649
+ new policy_definition_1.PolicyDefinition(stack, "ValidationError", {
650
+ name: "test-policy",
651
+ policyRule: undefined, // Missing required policyRule
652
+ enableValidation: true,
653
+ });
654
+ }).toThrow("Required property 'policyRule' is missing");
655
+ });
656
+ it("should handle schema registration errors gracefully", () => {
657
+ expect(() => {
658
+ new policy_definition_1.PolicyDefinition(stack, "SchemaTest", {
659
+ name: "test-policy",
660
+ policyRule: { if: {}, then: { effect: "deny" } },
661
+ });
662
+ }).not.toThrow();
663
+ });
664
+ });
665
+ describe("JSII Compliance", () => {
666
+ it("should have JSII-compliant constructor", () => {
667
+ expect(() => {
668
+ new policy_definition_1.PolicyDefinition(stack, "JsiiTest", {
669
+ name: "jsii-test",
670
+ policyRule: { if: {}, then: { effect: "deny" } },
671
+ });
672
+ }).not.toThrow();
673
+ });
674
+ it("should have JSII-compliant properties", () => {
675
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "JsiiProps", {
676
+ name: "jsii-props",
677
+ policyRule: { if: {}, then: { effect: "deny" } },
678
+ });
679
+ expect(typeof policyDefinition.id).toBe("string");
680
+ expect(typeof policyDefinition.name).toBe("string");
681
+ expect(typeof policyDefinition.resolvedApiVersion).toBe("string");
682
+ expect(typeof policyDefinition.policyType).toBe("string");
683
+ expect(typeof policyDefinition.policyMode).toBe("string");
684
+ });
685
+ it("should have JSII-compliant methods", () => {
686
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "JsiiMethods", {
687
+ name: "jsii-methods",
688
+ policyRule: { if: {}, then: { effect: "deny" } },
689
+ });
690
+ expect(typeof policyDefinition.latestVersion).toBe("function");
691
+ expect(typeof policyDefinition.supportedVersions).toBe("function");
692
+ });
693
+ it("should serialize complex objects correctly", () => {
694
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "JsiiSerialization", {
695
+ name: "jsii-serialization",
696
+ policyRule: {
697
+ if: { field: "location", equals: "eastus" },
698
+ then: { effect: "deny" },
699
+ },
700
+ parameters: {
701
+ testParam: {
702
+ type: "String",
703
+ },
704
+ },
705
+ });
706
+ expect(() => JSON.stringify(policyDefinition.validationResult)).not.toThrow();
707
+ expect(() => JSON.stringify(policyDefinition.schema)).not.toThrow();
708
+ expect(() => JSON.stringify(policyDefinition.versionConfig)).not.toThrow();
709
+ });
710
+ });
711
+ describe("CDK Terraform Integration", () => {
712
+ it("should synthesize to valid Terraform configuration", () => {
713
+ new policy_definition_1.PolicyDefinition(stack, "SynthTest", {
714
+ name: "synth-test",
715
+ policyRule: {
716
+ if: {
717
+ field: "type",
718
+ equals: "Microsoft.Compute/virtualMachines",
719
+ },
720
+ then: {
721
+ effect: "audit",
722
+ },
723
+ },
724
+ });
725
+ const synthesized = cdktf_1.Testing.synth(stack);
726
+ expect(synthesized).toBeDefined();
727
+ const stackConfig = JSON.parse(synthesized);
728
+ expect(stackConfig.resource).toBeDefined();
729
+ });
730
+ it("should work in complex CDK constructs", () => {
731
+ class ComplexConstruct extends cdktf.TerraformStack {
732
+ constructor(scope, id) {
733
+ super(scope, id);
734
+ const policy1 = new policy_definition_1.PolicyDefinition(this, "Policy1", {
735
+ name: "policy-1",
736
+ displayName: "First Policy",
737
+ policyRule: { if: {}, then: { effect: "audit" } },
738
+ });
739
+ const policy2 = new policy_definition_1.PolicyDefinition(this, "Policy2", {
740
+ name: "policy-2",
741
+ displayName: "Second Policy",
742
+ policyRule: { if: {}, then: { effect: "deny" } },
743
+ apiVersion: "2021-06-01",
744
+ });
745
+ new cdktf.TerraformOutput(this, "Policy1Id", {
746
+ value: policy1.id,
747
+ });
748
+ new cdktf.TerraformOutput(this, "Policy2Id", {
749
+ value: policy2.id,
750
+ });
751
+ }
752
+ }
753
+ expect(() => {
754
+ new ComplexConstruct(app, "ComplexStack");
755
+ }).not.toThrow();
756
+ });
757
+ it("should handle multiple policy definitions in the same stack", () => {
758
+ const policy1 = new policy_definition_1.PolicyDefinition(stack, "PolicyDefinition1", {
759
+ name: "policy-1",
760
+ policyRule: { if: {}, then: { effect: "audit" } },
761
+ });
762
+ const policy2 = new policy_definition_1.PolicyDefinition(stack, "PolicyDefinition2", {
763
+ name: "policy-2",
764
+ policyRule: { if: {}, then: { effect: "deny" } },
765
+ apiVersion: "2021-06-01",
766
+ });
767
+ expect(policy1.resolvedApiVersion).toBe("2021-06-01");
768
+ expect(policy2.resolvedApiVersion).toBe("2021-06-01");
769
+ const synthesized = cdktf_1.Testing.synth(stack);
770
+ expect(synthesized).toBeDefined();
771
+ });
772
+ });
773
+ describe("Policy Definition Types", () => {
774
+ it("should support BuiltIn policy type", () => {
775
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "BuiltInPolicy", {
776
+ name: "builtin-policy",
777
+ policyType: "BuiltIn",
778
+ policyRule: { if: {}, then: { effect: "audit" } },
779
+ });
780
+ expect(policyDefinition.policyType).toBe("BuiltIn");
781
+ });
782
+ it("should support Static policy type", () => {
783
+ const policyDefinition = new policy_definition_1.PolicyDefinition(stack, "StaticPolicy", {
784
+ name: "static-policy",
785
+ policyType: "Static",
786
+ policyRule: { if: {}, then: { effect: "audit" } },
787
+ });
788
+ expect(policyDefinition.policyType).toBe("Static");
789
+ });
790
+ it("should support different policy modes", () => {
791
+ const indexedPolicy = new policy_definition_1.PolicyDefinition(stack, "IndexedPolicy", {
792
+ name: "indexed-policy",
793
+ mode: "Indexed",
794
+ policyRule: { if: {}, then: { effect: "audit" } },
795
+ });
796
+ expect(indexedPolicy.policyMode).toBe("Indexed");
797
+ const resourceProviderPolicy = new policy_definition_1.PolicyDefinition(stack, "ResourceProviderPolicy", {
798
+ name: "resource-provider-policy",
799
+ mode: "Microsoft.KeyVault.Data",
800
+ policyRule: { if: {}, then: { effect: "audit" } },
801
+ });
802
+ expect(resourceProviderPolicy.policyMode).toBe("Microsoft.KeyVault.Data");
803
+ });
804
+ });
805
+ });
806
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9saWN5LWRlZmluaXRpb24uc3BlYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9henVyZS1wb2xpY3lkZWZpbml0aW9uL3Rlc3QvcG9saWN5LWRlZmluaXRpb24uc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7R0FPRzs7QUFFSCxpQ0FBZ0M7QUFDaEMsK0JBQStCO0FBQy9CLGtHQUE2RjtBQUM3RiwyR0FBeUc7QUFDekcsZ0VBR2tDO0FBQ2xDLGdGQUcwQztBQUUxQyxRQUFRLENBQUMsMkNBQTJDLEVBQUUsR0FBRyxFQUFFO0lBQ3pELElBQUksR0FBYyxDQUFDO0lBQ25CLElBQUksS0FBMkIsQ0FBQztJQUNoQyxJQUFJLE9BQTBCLENBQUM7SUFFL0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtRQUNkLEdBQUcsR0FBRyxlQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDcEIsS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDbkQsT0FBTyxHQUFHLHVDQUFpQixDQUFDLFFBQVEsRUFBRSxDQUFDO1FBRXZDLGtEQUFrRDtRQUNsRCxJQUFJLENBQUM7WUFDSCxPQUFPLENBQUMsb0JBQW9CLENBQzFCLGtEQUFzQixFQUN0QiwwREFBOEIsQ0FDL0IsQ0FBQztRQUNKLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsK0JBQStCO1FBQ2pDLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVILFFBQVEsQ0FBQyxrQ0FBa0MsRUFBRSxHQUFHLEVBQUU7UUFDaEQsRUFBRSxDQUFDLDBFQUEwRSxFQUFFLEdBQUcsRUFBRTtZQUNsRixNQUFNLEtBQUssR0FBMEI7Z0JBQ25DLElBQUksRUFBRSxhQUFhO2dCQUNuQixVQUFVLEVBQUU7b0JBQ1YsRUFBRSxFQUFFO3dCQUNGLEtBQUssRUFBRSxxQkFBcUI7d0JBQzVCLE1BQU0sRUFBRSxP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QUFJLG9DQUFnQixDQUNqRCxLQUFLLEVBQ0wsd0JBQXdCLEVBQ3hCO2dCQUNFLElBQUksRUFBRSwwQkFBMEI7Z0JBQ2hDLElBQUksRUFBRSx5QkFBeUI7Z0JBQy9CLFVBQVUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxFQUFFO2FBQ2xELENBQ0YsQ0FBQztZQUVGLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxVQUFVLENBQUMsQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsQ0FBQztRQUM1RSxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENvbXByZWhlbnNpdmUgdGVzdHMgZm9yIHRoZSB1bmlmaWVkIFBvbGljeURlZmluaXRpb24gaW1wbGVtZW50YXRpb25cbiAqXG4gKiBUaGlzIHRlc3Qgc3VpdGUgdmFsaWRhdGVzIHRoZSB1bmlmaWVkIFBvbGljeURlZmluaXRpb24gY2xhc3MgdGhhdCB1c2VzXG4gKiB0aGUgVmVyc2lvbmVkQXphcGlSZXNvdXJjZSBmcmFtZXdvcmsuIFRlc3RzIGNvdmVyIGF1dG9tYXRpYyB2ZXJzaW9uIHJlc29sdXRpb24sXG4gKiBleHBsaWNpdCB2ZXJzaW9uIHBpbm5pbmcsIHNjaGVtYSB2YWxpZGF0aW9uLCBwcm9wZXJ0eSB0cmFuc2Zvcm1hdGlvbiwgYW5kXG4gKiBwb2xpY3ktc3BlY2lmaWMgZnVuY3Rpb25hbGl0eS5cbiAqL1xuXG5pbXBvcnQgeyBUZXN0aW5nIH0gZnJvbSBcImNka3RmXCI7XG5pbXBvcnQgKiBhcyBjZGt0ZiBmcm9tIFwiY2RrdGZcIjtcbmltcG9ydCB7IEFwaVZlcnNpb25NYW5hZ2VyIH0gZnJvbSBcIi4uLy4uL2NvcmUtYXp1cmUvbGliL3ZlcnNpb24tbWFuYWdlci9hcGktdmVyc2lvbi1tYW5hZ2VyXCI7XG5pbXBvcnQgeyBWZXJzaW9uU3VwcG9ydExldmVsIH0gZnJvbSBcIi4uLy4uL2NvcmUtYXp1cmUvbGliL3ZlcnNpb24tbWFuYWdlci9pbnRlcmZhY2VzL3ZlcnNpb24taW50ZXJmYWNlc1wiO1xuaW1wb3J0IHtcbiAgUG9saWN5RGVmaW5pdGlvbixcbiAgUG9saWN5RGVmaW5pdGlvblByb3BzLFxufSBmcm9tIFwiLi4vbGliL3BvbGljeS1kZWZpbml0aW9uXCI7XG5pbXBvcnQge1xuICBBTExfUE9MSUNZX0RFRklOSVRJT05fVkVSU0lPTlMsXG4gIFBPTElDWV9ERUZJTklUSU9OX1RZUEUsXG59IGZyb20gXCIuLi9saWIvcG9saWN5LWRlZmluaXRpb24tc2NoZW1hc1wiO1xuXG5kZXNjcmliZShcIlBvbGljeURlZmluaXRpb24gLSBVbmlmaWVkIEltcGxlbWVudGF0aW9uXCIsICgpID0+IHtcbiAgbGV0IGFwcDogY2RrdGYuQXBwO1xuICBsZXQgc3RhY2s6IGNka3RmLlRlcnJhZm9ybVN0YWNrO1xuICBsZXQgbWFuYWdlcjogQXBpVmVyc2lvbk1hbmFnZXI7XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgYXBwID0gVGVzdGluZy5hcHAoKTtcbiAgICBzdGFjayA9IG5ldyBjZGt0Zi5UZXJyYWZvcm1TdGFjayhhcHAsIFwiVGVzdFN0YWNrXCIpO1xuICAgIG1hbmFnZXIgPSBBcGlWZXJzaW9uTWFuYWdlci5pbnN0YW5jZSgpO1xuXG4gICAgLy8gRW5zdXJlIFBvbGljeSBEZWZpbml0aW9uIHNjaGVtYXMgYXJlIHJlZ2lzdGVyZWRcbiAgICB0cnkge1xuICAgICAgbWFuYWdlci5yZWdpc3RlclJlc291cmNlVHlwZShcbiAgICAgICAgUE9MSUNZX0RFRklOSVRJT05fVFlQRSxcbiAgICAgICAgQUxMX1BPTElDWV9ERUZJTklUSU9OX1ZFUlNJT05TLFxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gSWdub3JlIGlmIGFscmVhZHkgcmVnaXN0ZXJlZFxuICAgIH1cbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDb25zdHJ1Y3RvciBhbmQgQmFzaWMgUHJvcGVydGllc1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIHBvbGljeSBkZWZpbml0aW9uIHdpdGggYXV0b21hdGljIGxhdGVzdCB2ZXJzaW9uIHJlc29sdXRpb25cIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFBvbGljeURlZmluaXRpb25Qcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LXBvbGljeVwiLFxuICAgICAgICBwb2xpY3lSdWxlOiB7XG4gICAgICAgICAgaWY6IHtcbiAgICAgICAgICAgIGZpZWxkOiBcInRhZ3NbJ0Vudmlyb25tZW50J11cIixcbiAgICAgICAgICAgIGV4aXN0czogXCJmYWxzZVwiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGhlbjoge1xuICAgICAgICAgICAgZWZmZWN0OiBcImRlbnlcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiLFxuICAgICAgICBwcm9wcyxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uKS50b0JlSW5zdGFuY2VPZihQb2xpY3lEZWZpbml0aW9uKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcIjIwMjEtMDYtMDFcIik7IC8vIExhdGVzdCB2ZXJzaW9uXG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wcm9wcykudG9CZShwcm9wcyk7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5uYW1lKS50b0JlKFwidGVzdC1wb2xpY3lcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBjcmVhdGUgcG9saWN5IGRlZmluaXRpb24gd2l0aCBleHBsaWNpdCB2ZXJzaW9uIHBpbm5pbmdcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFBvbGljeURlZmluaXRpb25Qcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LXBvbGljeS1waW5uZWRcIixcbiAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIxLTA2LTAxXCIsXG4gICAgICAgIHBvbGljeVJ1bGU6IHtcbiAgICAgICAgICBpZjoge1xuICAgICAgICAgICAgZmllbGQ6IFwidHlwZVwiLFxuICAgICAgICAgICAgZXF1YWxzOiBcIk1pY3Jvc29mdC5Db21wdXRlL3ZpcnR1YWxNYWNoaW5lc1wiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGhlbjoge1xuICAgICAgICAgICAgZWZmZWN0OiBcImF1ZGl0XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHBvbGljeURlZmluaXRpb24gPSBuZXcgUG9saWN5RGVmaW5pdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiVGVzdFBvbGljeURlZmluaXRpb25cIixcbiAgICAgICAgcHJvcHMsXG4gICAgICApO1xuXG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5yZXNvbHZlZEFwaVZlcnNpb24pLnRvQmUoXCIyMDIxLTA2LTAxXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIHBvbGljeSBkZWZpbml0aW9uIHdpdGggYWxsIG9wdGlvbmFsIHByb3BlcnRpZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFBvbGljeURlZmluaXRpb25Qcm9wcyA9IHtcbiAgICAgICAgbmFtZTogXCJ0ZXN0LXBvbGljeS1mdWxsXCIsXG4gICAgICAgIGRpc3BsYXlOYW1lOiBcIlRlc3QgUG9saWN5IERlZmluaXRpb25cIixcbiAgICAgICAgZGVzY3JpcHRpb246IFwiQSB0ZXN0IHBvbGljeSBkZWZpbml0aW9uIGZvciB1bml0IHRlc3RpbmdcIixcbiAgICAgICAgcG9saWN5VHlwZTogXCJDdXN0b21cIixcbiAgICAgICAgbW9kZTogXCJBbGxcIixcbiAgICAgICAgcG9saWN5UnVsZToge1xuICAgICAgICAgIGlmOiB7XG4gICAgICAgICAgICBmaWVsZDogXCJsb2NhdGlvblwiLFxuICAgICAgICAgICAgbm90SW46IFtcImVhc3R1c1wiLCBcIndlc3R1c1wiXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRoZW46IHtcbiAgICAgICAgICAgIGVmZmVjdDogXCJkZW55XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgIGFsbG93ZWRMb2NhdGlvbnM6IHtcbiAgICAgICAgICAgIHR5cGU6IFwiQXJyYXlcIixcbiAgICAgICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICAgIGRpc3BsYXlOYW1lOiBcIkFsbG93ZWQgbG9jYXRpb25zXCIsXG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlRoZSBsaXN0IG9mIGFsbG93ZWQgbG9jYXRpb25zIGZvciByZXNvdXJjZXNcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICBjYXRlZ29yeTogXCJHZW5lcmFsXCIsXG4gICAgICAgICAgdmVyc2lvbjogXCIxLjAuMFwiLFxuICAgICAgICB9LFxuICAgICAgICBpZ25vcmVDaGFuZ2VzOiBbXCJtZXRhZGF0YVwiXSxcbiAgICAgICAgZW5hYmxlVmFsaWRhdGlvbjogdHJ1ZSxcbiAgICAgICAgZW5hYmxlTWlncmF0aW9uQW5hbHlzaXM6IHRydWUsXG4gICAgICAgIGVuYWJsZVRyYW5zZm9ybWF0aW9uOiB0cnVlLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiLFxuICAgICAgICBwcm9wcyxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnByb3BzLmRpc3BsYXlOYW1lKS50b0JlKFwiVGVzdCBQb2xpY3kgRGVmaW5pdGlvblwiKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnByb3BzLmRlc2NyaXB0aW9uKS50b0JlKFxuICAgICAgICBcIkEgdGVzdCBwb2xpY3kgZGVmaW5pdGlvbiBmb3IgdW5pdCB0ZXN0aW5nXCIsXG4gICAgICApO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ucHJvcHMucG9saWN5VHlwZSkudG9CZShcIkN1c3RvbVwiKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnByb3BzLm1vZGUpLnRvQmUoXCJBbGxcIik7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wcm9wcy5wYXJhbWV0ZXJzKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ucHJvcHMubWV0YWRhdGEpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCB1c2UgZGVmYXVsdCBuYW1lIHdoZW4gbmFtZSBpcyBub3QgcHJvdmlkZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcHJvcHM6IFBvbGljeURlZmluaXRpb25Qcm9wcyA9IHtcbiAgICAgICAgcG9saWN5UnVsZToge1xuICAgICAgICAgIGlmOiB7XG4gICAgICAgICAgICBmaWVsZDogXCJ0eXBlXCIsXG4gICAgICAgICAgICBlcXVhbHM6IFwiTWljcm9zb2Z0LlN0b3JhZ2Uvc3RvcmFnZUFjY291bnRzXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0aGVuOiB7XG4gICAgICAgICAgICBlZmZlY3Q6IFwiYXVkaXRcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiLFxuICAgICAgICBwcm9wcyxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLm5hbWUpLnRvQmUoXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHJlcXVpcmUgcG9saWN5UnVsZSB0byBiZSBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogYW55ID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICB9O1xuXG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgUG9saWN5RGVmaW5pdGlvbihzdGFjaywgXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiLCBwcm9wcyk7XG4gICAgICB9KS50b1Rocm93KFwiUmVxdWlyZWQgcHJvcGVydHkgJ3BvbGljeVJ1bGUnIGlzIG1pc3NpbmdcIik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiRnJhbWV3b3JrIEludGVncmF0aW9uXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCByZXNvbHZlIGxhdGVzdCBBUEkgdmVyc2lvbiBhdXRvbWF0aWNhbGx5XCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHBvbGljeURlZmluaXRpb24gPSBuZXcgUG9saWN5RGVmaW5pdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiVGVzdFBvbGljeURlZmluaXRpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwidGVzdC1wb2xpY3lcIixcbiAgICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiZGVueVwiIH0gfSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcIjIwMjEtMDYtMDFcIik7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5sYXRlc3RWZXJzaW9uKCkpLnRvQmUoXCIyMDIxLTA2LTAxXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgc3VwcG9ydCBhbGwgcmVnaXN0ZXJlZCBBUEkgdmVyc2lvbnNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJ0ZXN0LXBvbGljeVwiLFxuICAgICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJkZW55XCIgfSB9LFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgY29uc3Qgc3VwcG9ydGVkVmVyc2lvbnMgPSBwb2xpY3lEZWZpbml0aW9uLnN1cHBvcnRlZFZlcnNpb25zKCk7XG4gICAgICBleHBlY3Qoc3VwcG9ydGVkVmVyc2lvbnMpLnRvQ29udGFpbihcIjIwMjEtMDYtMDFcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCB2YWxpZGF0ZSB2ZXJzaW9uIHN1cHBvcnRcIiwgKCkgPT4ge1xuICAgICAgLy8gVmFsaWQgdmVyc2lvblxuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IFBvbGljeURlZmluaXRpb24oc3RhY2ssIFwiVmFsaWRWZXJzaW9uXCIsIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIxLTA2LTAxXCIsXG4gICAgICAgIH0pO1xuICAgICAgfSkubm90LnRvVGhyb3coKTtcblxuICAgICAgLy8gSW52YWxpZCB2ZXJzaW9uXG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgUG9saWN5RGVmaW5pdGlvbihzdGFjaywgXCJJbnZhbGlkVmVyc2lvblwiLCB7XG4gICAgICAgICAgbmFtZTogXCJ0ZXN0LXBvbGljeVwiLFxuICAgICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJkZW55XCIgfSB9LFxuICAgICAgICAgIGFwaVZlcnNpb246IFwiMjAyMi0wMS0wMVwiLFxuICAgICAgICB9KTtcbiAgICAgIH0pLnRvVGhyb3coXCJVbnN1cHBvcnRlZCBBUEkgdmVyc2lvbiAnMjAyMi0wMS0wMSdcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBsb2FkIGNvcnJlY3Qgc2NoZW1hIGZvciByZXNvbHZlZCB2ZXJzaW9uXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHBvbGljeURlZmluaXRpb24gPSBuZXcgUG9saWN5RGVmaW5pdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiVGVzdFBvbGljeURlZmluaXRpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwidGVzdC1wb2xpY3lcIixcbiAgICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiZGVueVwiIH0gfSxcbiAgICAgICAgICBhcGlWZXJzaW9uOiBcIjIwMjEtMDYtMDFcIixcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnNjaGVtYSkudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnNjaGVtYS5yZXNvdXJjZVR5cGUpLnRvQmUoUE9MSUNZX0RFRklOSVRJT05fVFlQRSk7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5zY2hlbWEudmVyc2lvbikudG9CZShcIjIwMjEtMDYtMDFcIik7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5zY2hlbWEucHJvcGVydGllcykudG9CZURlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGxvYWQgdmVyc2lvbiBjb25maWd1cmF0aW9uIGNvcnJlY3RseVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlRlc3RQb2xpY3lEZWZpbml0aW9uXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi52ZXJzaW9uQ29uZmlnKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24udmVyc2lvbkNvbmZpZy52ZXJzaW9uKS50b0JlKFwiMjAyMS0wNi0wMVwiKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnZlcnNpb25Db25maWcuc3VwcG9ydExldmVsKS50b0JlKFxuICAgICAgICBWZXJzaW9uU3VwcG9ydExldmVsLkFDVElWRSxcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUHJvcGVydHkgVmFsaWRhdGlvblwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgdmFsaWRhdGUgcHJvcGVydGllcyB3aGVuIHZhbGlkYXRpb24gaXMgZW5hYmxlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wczogUG9saWN5RGVmaW5pdGlvblByb3BzID0ge1xuICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgIHBvbGljeVJ1bGU6IHtcbiAgICAgICAgICBpZjoge1xuICAgICAgICAgICAgZmllbGQ6IFwidHlwZVwiLFxuICAgICAgICAgICAgZXF1YWxzOiBcIk1pY3Jvc29mdC5Db21wdXRlL3ZpcnR1YWxNYWNoaW5lc1wiLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdGhlbjoge1xuICAgICAgICAgICAgZWZmZWN0OiBcImF1ZGl0XCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICAgZW5hYmxlVmFsaWRhdGlvbjogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIGV4cGVjdCgoKSA9PiB7XG4gICAgICAgIG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIlRlc3RQb2xpY3lEZWZpbml0aW9uXCIsIHByb3BzKTtcbiAgICAgIH0pLm5vdC50b1Rocm93KCk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYXZlIHZhbGlkYXRpb24gcmVzdWx0cyBmb3IgdmFsaWQgcHJvcGVydGllc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlRlc3RQb2xpY3lEZWZpbml0aW9uXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInZhbGlkLXBvbGljeVwiLFxuICAgICAgICAgIGRpc3BsYXlOYW1lOiBcIlZhbGlkIFBvbGljeVwiLFxuICAgICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJkZW55XCIgfSB9LFxuICAgICAgICAgIGVuYWJsZVZhbGlkYXRpb246IHRydWUsXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi52YWxpZGF0aW9uUmVzdWx0KS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24udmFsaWRhdGlvblJlc3VsdCEudmFsaWQpLnRvQmUodHJ1ZSk7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi52YWxpZGF0aW9uUmVzdWx0IS5lcnJvcnMpLnRvSGF2ZUxlbmd0aCgwKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHNraXAgdmFsaWRhdGlvbiB3aGVuIGRpc2FibGVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHBvbGljeURlZmluaXRpb24gPSBuZXcgUG9saWN5RGVmaW5pdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiVGVzdFBvbGljeURlZmluaXRpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwidGVzdC1wb2xpY3lcIixcbiAgICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiZGVueVwiIH0gfSxcbiAgICAgICAgICBlbmFibGVWYWxpZGF0aW9uOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIk1pZ3JhdGlvbiBBbmFseXNpc1wiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgc2tpcCBtaWdyYXRpb24gYW5hbHlzaXMgZm9yIHNpbmdsZSB2ZXJzaW9uXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHBvbGljeURlZmluaXRpb24gPSBuZXcgUG9saWN5RGVmaW5pdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiVGVzdFBvbGljeURlZmluaXRpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwidGVzdC1wb2xpY3lcIixcbiAgICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiZGVueVwiIH0gfSxcbiAgICAgICAgICBhcGlWZXJzaW9uOiBcIjIwMjEtMDYtMDFcIixcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIC8vIFNpbmNlIHRoZXJlJ3Mgb25seSBvbmUgdmVyc2lvbiwgbWlncmF0aW9uIGFuYWx5c2lzIHNob3VsZCBiZSBza2lwcGVkXG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbikudG9CZURlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHNraXAgbWlncmF0aW9uIGFuYWx5c2lzIHdoZW4gZGlzYWJsZWRcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJ0ZXN0LXBvbGljeVwiLFxuICAgICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJkZW55XCIgfSB9LFxuICAgICAgICAgIGVuYWJsZU1pZ3JhdGlvbkFuYWx5c2lzOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLm1pZ3JhdGlvbkFuYWx5c2lzKS50b0JlVW5kZWZpbmVkKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUmVzb3VyY2UgQ3JlYXRpb24gYW5kIEJvZHlcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBjb3JyZWN0IHJlc291cmNlIGJvZHkgd2l0aCBtaW5pbWFsIHByb3BlcnRpZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJ0ZXN0LXBvbGljeVwiLFxuICAgICAgICAgIHBvbGljeVJ1bGU6IHtcbiAgICAgICAgICAgIGlmOiB7XG4gICAgICAgICAgICAgIGZpZWxkOiBcInRhZ3NbJ0Vudmlyb25tZW50J11cIixcbiAgICAgICAgICAgICAgZXhpc3RzOiBcImZhbHNlXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhlbjoge1xuICAgICAgICAgICAgICBlZmZlY3Q6IFwiZGVueVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24pLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wcm9wcy5wb2xpY3lSdWxlKS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgY3JlYXRlIGNvcnJlY3QgcmVzb3VyY2UgYm9keSB3aXRoIGFsbCBwcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHBvbGljeURlZmluaXRpb24gPSBuZXcgUG9saWN5RGVmaW5pdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiVGVzdFBvbGljeURlZmluaXRpb25cIixcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwidGVzdC1wb2xpY3lcIixcbiAgICAgICAgICBkaXNwbGF5TmFtZTogXCJUZXN0IFBvbGljeVwiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkEgdGVzdCBwb2xpY3lcIixcbiAgICAgICAgICBwb2xpY3lUeXBlOiBcIkN1c3RvbVwiLFxuICAgICAgICAgIG1vZGU6IFwiSW5kZXhlZFwiLFxuICAgICAgICAgIHBvbGljeVJ1bGU6IHtcbiAgICAgICAgICAgIGlmOiB7XG4gICAgICAgICAgICAgIGZpZWxkOiBcImxvY2F0aW9uXCIsXG4gICAgICAgICAgICAgIG5vdEluOiBbXCJlYXN0dXNcIiwgXCJ3ZXN0dXNcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdGhlbjoge1xuICAgICAgICAgICAgICBlZmZlY3Q6IFwiZGVueVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgIGFsbG93ZWRMb2NhdGlvbnM6IHtcbiAgICAgICAgICAgICAgdHlwZTogXCJBcnJheVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICBjYXRlZ29yeTogXCJDb21wbGlhbmNlXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ucHJvcHMuZGlzcGxheU5hbWUpLnRvQmUoXCJUZXN0IFBvbGljeVwiKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnByb3BzLnBvbGljeVR5cGUpLnRvQmUoXCJDdXN0b21cIik7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wcm9wcy5tb2RlKS50b0JlKFwiSW5kZXhlZFwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBUZXJyYWZvcm0gb3V0cHV0c1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIlRlc3RQb2xpY3lEZWZpbml0aW9uXCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5LW91dHB1dHNcIixcbiAgICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiZGVueVwiIH0gfSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLmlkT3V0cHV0KS50b0JlSW5zdGFuY2VPZihjZGt0Zi5UZXJyYWZvcm1PdXRwdXQpO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ubmFtZU91dHB1dCkudG9CZUluc3RhbmNlT2YoY2RrdGYuVGVycmFmb3JtT3V0cHV0KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJQdWJsaWMgTWV0aG9kcyBhbmQgUHJvcGVydGllc1wiLCAoKSA9PiB7XG4gICAgbGV0IHBvbGljeURlZmluaXRpb246IFBvbGljeURlZmluaXRpb247XG5cbiAgICBiZWZvcmVFYWNoKCgpID0+IHtcbiAgICAgIHBvbGljeURlZmluaXRpb24gPSBuZXcgUG9saWN5RGVmaW5pdGlvbihzdGFjaywgXCJUZXN0UG9saWN5RGVmaW5pdGlvblwiLCB7XG4gICAgICAgIG5hbWU6IFwidGVzdC1wb2xpY3lcIixcbiAgICAgICAgZGlzcGxheU5hbWU6IFwiVGVzdCBQb2xpY3lcIixcbiAgICAgICAgcG9saWN5VHlwZTogXCJDdXN0b21cIixcbiAgICAgICAgbW9kZTogXCJBbGxcIixcbiAgICAgICAgcG9saWN5UnVsZToge1xuICAgICAgICAgIGlmOiB7XG4gICAgICAgICAgICBmaWVsZDogXCJ0eXBlXCIsXG4gICAgICAgICAgICBlcXVhbHM6IFwiTWljcm9zb2Z0LkNvbXB1dGUvdmlydHVhbE1hY2hpbmVzXCIsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0aGVuOiB7XG4gICAgICAgICAgICBlZmZlY3Q6IFwiYXVkaXRcIixcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYXZlIGNvcnJlY3QgaWQgZm9ybWF0XCIsICgpID0+IHtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLmlkKS50b01hdGNoKC9eXFwkXFx7LipcXC5pZFxcfSQvKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhdmUgcmVzb3VyY2VJZCBwcm9wZXJ0eSBtYXRjaGluZyBpZFwiLCAoKSA9PiB7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5yZXNvdXJjZUlkKS50b0JlKHBvbGljeURlZmluaXRpb24uaWQpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgcmV0dXJuIGNvcnJlY3QgcG9saWN5VHlwZVwiLCAoKSA9PiB7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wb2xpY3lUeXBlKS50b0JlKFwiQ3VzdG9tXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgcmV0dXJuIGNvcnJlY3QgcG9saWN5TW9kZVwiLCAoKSA9PiB7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wb2xpY3lNb2RlKS50b0JlKFwiQWxsXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgdXNlIGRlZmF1bHQgcG9saWN5VHlwZSB3aGVuIG5vdCBwcm92aWRlZFwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBkZWZhdWx0UG9saWN5ID0gbmV3IFBvbGljeURlZmluaXRpb24oc3RhY2ssIFwiRGVmYXVsdFR5cGVQb2xpY3lcIiwge1xuICAgICAgICBuYW1lOiBcImRlZmF1bHQtcG9saWN5XCIsXG4gICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJkZW55XCIgfSB9LFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChkZWZhdWx0UG9saWN5LnBvbGljeVR5cGUpLnRvQmUoXCJDdXN0b21cIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCB1c2UgZGVmYXVsdCBtb2RlIHdoZW4gbm90IHByb3ZpZGVkXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGRlZmF1bHRQb2xpY3kgPSBuZXcgUG9saWN5RGVmaW5pdGlvbihzdGFjaywgXCJEZWZhdWx0TW9kZVBvbGljeVwiLCB7XG4gICAgICAgIG5hbWU6IFwiZGVmYXVsdC1wb2xpY3lcIixcbiAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGRlZmF1bHRQb2xpY3kucG9saWN5TW9kZSkudG9CZShcIkFsbFwiKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJJZ25vcmUgQ2hhbmdlcyBDb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBhcHBseSBpZ25vcmUgY2hhbmdlcyBsaWZlY3ljbGUgcnVsZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJJZ25vcmVDaGFuZ2VzUG9saWN5XCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICAgICAgaWdub3JlQ2hhbmdlczogW1wibWV0YWRhdGFcIiwgXCJkZXNjcmlwdGlvblwiXSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uKS50b0JlSW5zdGFuY2VPZihQb2xpY3lEZWZpbml0aW9uKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhbmRsZSBlbXB0eSBpZ25vcmUgY2hhbmdlcyBhcnJheVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIkVtcHR5SWdub3JlUG9saWN5XCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICAgICAgaWdub3JlQ2hhbmdlczogW10sXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbikudG9CZUluc3RhbmNlT2YoUG9saWN5RGVmaW5pdGlvbik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUG9saWN5IFJ1bGUgVmFsaWRhdGlvblwiLCAoKSA9PiB7XG4gICAgaXQoXCJzaG91bGQgYWNjZXB0IGNvbXBsZXggcG9saWN5IHJ1bGVzXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbXBsZXhSdWxlID0ge1xuICAgICAgICBpZjoge1xuICAgICAgICAgIGFsbE9mOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGZpZWxkOiBcInR5cGVcIixcbiAgICAgICAgICAgICAgZXF1YWxzOiBcIk1pY3Jvc29mdC5TdG9yYWdlL3N0b3JhZ2VBY2NvdW50c1wiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZmllbGQ6IFwiTWljcm9zb2Z0LlN0b3JhZ2Uvc3RvcmFnZUFjY291bnRzL2VuYWJsZUh0dHBzVHJhZmZpY09ubHlcIixcbiAgICAgICAgICAgICAgbm90RXF1YWxzOiBcInRydWVcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgICAgdGhlbjoge1xuICAgICAgICAgIGVmZmVjdDogXCJkZW55XCIsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIkNvbXBsZXhSdWxlUG9saWN5XCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcImNvbXBsZXgtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogY29tcGxleFJ1bGUsXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbikudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnByb3BzLnBvbGljeVJ1bGUpLnRvRXF1YWwoY29tcGxleFJ1bGUpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgYWNjZXB0IHBvbGljeSBydWxlcyB3aXRoIHBhcmFtZXRlcnNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJQYXJhbWV0ZXJpemVkUG9saWN5XCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInBhcmFtZXRlcml6ZWQtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZToge1xuICAgICAgICAgICAgaWY6IHtcbiAgICAgICAgICAgICAgZmllbGQ6IFwiW2NvbmNhdCgndGFnc1snLCBwYXJhbWV0ZXJzKCd0YWdOYW1lJyksICddJyldXCIsXG4gICAgICAgICAgICAgIGV4aXN0czogXCJmYWxzZVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHRoZW46IHtcbiAgICAgICAgICAgICAgZWZmZWN0OiBcIltwYXJhbWV0ZXJzKCdlZmZlY3QnKV1cIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICB0YWdOYW1lOiB7XG4gICAgICAgICAgICAgIHR5cGU6IFwiU3RyaW5nXCIsXG4gICAgICAgICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICAgICAgZGlzcGxheU5hbWU6IFwiVGFnIE5hbWVcIixcbiAgICAgICAgICAgICAgICBkZXNjcmlwdGlvbjogXCJOYW1lIG9mIHRoZSB0YWcgdG8gY2hlY2tcIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlZmZlY3Q6IHtcbiAgICAgICAgICAgICAgdHlwZTogXCJTdHJpbmdcIixcbiAgICAgICAgICAgICAgYWxsb3dlZFZhbHVlczogW1wiYXVkaXRcIiwgXCJkZW55XCJdLFxuICAgICAgICAgICAgICBkZWZhdWx0VmFsdWU6IFwiYXVkaXRcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ucHJvcHMucGFyYW1ldGVycykudG9CZURlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHByZXNlcnZlIGNvbXBsZXggYWxsT2YgY29uZGl0aW9ucyB3aXRoIG11bHRpcGxlIGZpZWxkIGNvbXBhcmlzb25zXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbXBsZXhSdWxlID0ge1xuICAgICAgICBpZjoge1xuICAgICAgICAgIGFsbE9mOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGZpZWxkOiBcInR5cGVcIixcbiAgICAgICAgICAgICAgZXF1YWxzOiBcIk1pY3Jvc29mdC5TdG9yYWdlL3N0b3JhZ2VBY2NvdW50c1wiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgZmllbGQ6XG4gICAgICAgICAgICAgICAgXCJNaWNyb3NvZnQuU3RvcmFnZS9zdG9yYWdlQWNjb3VudHMvbmV0d29ya0FjbHMuZGVmYXVsdEFjdGlvblwiLFxuICAgICAgICAgICAgICBub3RFcXVhbHM6IFwiRGVueVwiLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICB0aGVuOiB7XG4gICAgICAgICAgZWZmZWN0OiBcImF1ZGl0XCIsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oc3RhY2ssIFwiQ29tcGxleEFsbE9mXCIsIHtcbiAgICAgICAgbmFtZTogXCJjb21wbGV4LWFsbG9mLXBvbGljeVwiLFxuICAgICAgICBkaXNwbGF5TmFtZTogXCJDb21wbGV4IEFsbE9mIFBvbGljeVwiLFxuICAgICAgICBwb2xpY3lSdWxlOiBjb21wbGV4UnVsZSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbikudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnByb3BzLnBvbGljeVJ1bGUpLnRvRXF1YWwoY29tcGxleFJ1bGUpO1xuXG4gICAgICAvLyBTeW50aGVzaXplIGFuZCB2ZXJpZnkgdGhlIHN0cnVjdHVyZSBpcyBwcmVzZXJ2ZWRcbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBjb25zdCBzdGFja0NvbmZpZyA9IEpTT04ucGFyc2Uoc3ludGhlc2l6ZWQpO1xuICAgICAgY29uc3QgYXphcGlSZXNvdXJjZSA9IE9iamVjdC52YWx1ZXMoXG4gICAgICAgIHN0YWNrQ29uZmlnLnJlc291cmNlLmF6YXBpX3Jlc291cmNlLFxuICAgICAgKVswXSBhcyBhbnk7XG5cbiAgICAgIC8vIFRoZSBib2R5IGlzIGpzb25lbmNvZGUoKSB3cmFwcGVkLCBzbyB3ZSBuZWVkIHRvIHBhcnNlIHRoZSBhY3R1YWwgcG9saWN5IHJ1bGUgZnJvbSBwcm9wc1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ucHJvcHMucG9saWN5UnVsZS5pZi5hbGxPZikudG9IYXZlTGVuZ3RoKDIpO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ucHJvcHMucG9saWN5UnVsZS5pZi5hbGxPZlswXS5maWVsZCkudG9CZShcInR5cGVcIik7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wcm9wcy5wb2xpY3lSdWxlLmlmLmFsbE9mWzBdLmVxdWFscykudG9CZShcbiAgICAgICAgXCJNaWNyb3NvZnQuU3RvcmFnZS9zdG9yYWdlQWNjb3VudHNcIixcbiAgICAgICk7XG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wcm9wcy5wb2xpY3lSdWxlLmlmLmFsbE9mWzFdLmZpZWxkKS50b0JlKFxuICAgICAgICBcIk1pY3Jvc29mdC5TdG9yYWdlL3N0b3JhZ2VBY2NvdW50cy9uZXR3b3JrQWNscy5kZWZhdWx0QWN0aW9uXCIsXG4gICAgICApO1xuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24ucHJvcHMucG9saWN5UnVsZS5pZi5hbGxPZlsxXS5ub3RFcXVhbHMpLnRvQmUoXG4gICAgICAgIFwiRGVueVwiLFxuICAgICAgKTtcbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnByb3BzLnBvbGljeVJ1bGUudGhlbi5lZmZlY3QpLnRvQmUoXCJhdWRpdFwiKTtcblxuICAgICAgLy8gVmVyaWZ5IHRoZSBzeW50aGVzaXplZCBjb25maWcgaGFzIHRoZSBib2R5IHByb3BlcnR5IHNldFxuICAgICAgZXhwZWN0KGF6YXBpUmVzb3VyY2UuYm9keSkudG9CZURlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHByZXNlcnZlIEF6dXJlIFBvbGljeSBleHByZXNzaW9ucyB3aXRob3V0IGNvbnZlcnRpbmcgdGhlbVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBydWxlID0ge1xuICAgICAgICBpZjoge1xuICAgICAgICAgIGZpZWxkOiBcImxvY2F0aW9uXCIsXG4gICAgICAgICAgbm90SW46IFwiW3BhcmFtZXRlcnMoJ2FsbG93ZWRMb2NhdGlvbnMnKV1cIixcbiAgICAgICAgfSxcbiAgICAgICAgdGhlbjoge1xuICAgICAgICAgIGVmZmVjdDogXCJbcGFyYW1ldGVycygnZWZmZWN0JyldXCIsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBuZXcgUG9saWN5RGVmaW5pdGlvbihzdGFjaywgXCJBenVyZVBvbGljeUV4cHJlc3Npb25zXCIsIHtcbiAgICAgICAgbmFtZTogXCJhenVyZS1leHByZXNzaW9ucy1wb2xpY3lcIixcbiAgICAgICAgcG9saWN5UnVsZTogcnVsZSxcbiAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgIGFsbG93ZWRMb2NhdGlvbnM6IHsgdHlwZTogXCJBcnJheVwiIH0sXG4gICAgICAgICAgZWZmZWN0OiB7IHR5cGU6IFwiU3RyaW5nXCIgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBzeW50aGVzaXplZCA9IFRlc3Rpbmcuc3ludGgoc3RhY2spO1xuICAgICAgY29uc3Qgc3RhY2tDb25maWcgPSBKU09OLnBhcnNlKHN5bnRoZXNpemVkKTtcbiAgICAgIGNvbnN0IGF6YXBpUmVzb3VyY2UgPSBPYmplY3QudmFsdWVzKFxuICAgICAgICBzdGFja0NvbmZpZy5yZXNvdXJjZS5hemFwaV9yZXNvdXJjZSxcbiAgICAgIClbMF0gYXMgYW55O1xuXG4gICAgICAvLyBWZXJpZnkgQXp1cmUgUG9saWN5IGV4cHJlc3Npb25zIGFyZSBwcmVzZXJ2ZWQgaW4gdGhlIGNvbnN0cnVjdCdzIHByb3BzXG4gICAgICBleHBlY3QocnVsZS5pZi5ub3RJbikudG9CZShcIltwYXJhbWV0ZXJzKCdhbGxvd2VkTG9jYXRpb25zJyldXCIpO1xuICAgICAgZXhwZWN0KHJ1bGUudGhlbi5lZmZlY3QpLnRvQmUoXCJbcGFyYW1ldGVycygnZWZmZWN0JyldXCIpO1xuXG4gICAgICAvLyBWZXJpZnkgdGhlIHN5bnRoZXNpemVkIGNvbmZpZyBoYXMgdGhlIGJvZHkgcHJvcGVydHkgc2V0XG4gICAgICBleHBlY3QoYXphcGlSZXNvdXJjZS5ib2R5KS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgcHJlc2VydmUgRGVwbG95SWZOb3RFeGlzdHMgcG9saWN5IHdpdGggQVJNIHRlbXBsYXRlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IGNvbXBsZXhSdWxlID0ge1xuICAgICAgICBpZjoge1xuICAgICAgICAgIGZpZWxkOiBcInR5cGVcIixcbiAgICAgICAgICBlcXVhbHM6IFwiTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtzXCIsXG4gICAgICAgIH0sXG4gICAgICAgIHRoZW46IHtcbiAgICAgICAgICBlZmZlY3Q6IFwiRGVwbG95SWZOb3RFeGlzdHNcIixcbiAgICAgICAgICBkZXRhaWxzOiB7XG4gICAgICAgICAgICB0eXBlOiBcIk1pY3Jvc29mdC5OZXR3b3JrL25ldHdvcmtNYW5hZ2Vycy9uZXR3b3JrR3JvdXBzL3N0YXRpY01lbWJlcnNcIixcbiAgICAgICAgICAgIGRlcGxveW1lbnRTY29wZTogXCJzdWJzY3JpcHRpb25cIixcbiAgICAgICAgICAgIGV4aXN0ZW5jZVNjb3BlOiBcInN1YnNjcmlwdGlvblwiLFxuICAgICAgICAgICAgcm9sZURlZmluaXRpb25JZHM6IFtcbiAgICAgICAgICAgICAgXCIvcHJvdmlkZXJzL01pY3Jvc29mdC5BdXRob3JpemF0aW9uL3JvbGVEZWZpbml0aW9ucy9iMjQ5ODhhYy02MTgwLTQyYTAtYWI4OC0yMGY3MzgyZGQyNGNcIixcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBkZXBsb3ltZW50OiB7XG4gICAgICAgICAgICAgIGxvY2F0aW9uOiBcIltmaWVsZCgnbG9jYXRpb24nKV1cIixcbiAgICAgICAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgICAgICAgIG1vZGU6IFwiaW5jcmVtZW50YWxcIixcbiAgICAgICAgICAgICAgICByZXNvdXJjZUdyb3VwOiBcIlt2YXJpYWJsZXMoJ2F2bm1SZXNvdXJjZUdyb3VwJyldXCIsXG4gICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uSWQ6IFwiW3BhcmFtZXRlcnMoJ2F2bm1TdWJzY3JpcHRpb25JZCcpXVwiLFxuICAgICAgICAgICAgICAgIHRlbXBsYXRlOiB7XG4gICAgICAgICAgICAgICAgICAkc2NoZW1hOlxuICAgICAgICAgICAgICAgICAgICBcImh0dHBzOi8vc2NoZW1hLm1hbmFnZW1lbnQuYXp1cmUuY29tL3NjaGVtYXMvMjAxOS0wNC0wMS9kZXBsb3ltZW50VGVtcGxhdGUuanNvbiNcIixcbiAgICAgICAgICAgICAgICAgIGNvbnRlbnRWZXJzaW9uOiBcIjEuMC4wLjBcIixcbiAgICAgICAgICAgICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgdm5ldElkOiB7XG4gICAgICAgICAgICAgICAgICAgICAgdHlwZTogXCJzdHJpbmdcIixcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICB2YXJpYWJsZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgc3RhdGljTWVtYmVyTmFtZTogXCJbZ3VpZChwYXJhbWV0ZXJzKCd2bmV0SWQnKSldXCIsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICB0eXBlOiBcIk1pY3Jvc29mdC5OZXR3b3JrL25ldHdvcmtNYW5hZ2Vycy9uZXR3b3JrR3JvdXBzL3N0YXRpY01lbWJlcnNcIixcbiAgICAgICAgICAgICAgICAgICAgICBhcGlWZXJzaW9uOiBcIjIwMjMtMDQtMDFcIixcbiAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBcIltjb25jYXQocGFyYW1ldGVycygnYXZubUlkJyksICcvJywgdmFyaWFibGVzKCdzdGF0aWNNZW1iZXJOYW1lJykpXVwiLFxuICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc291cmNlSWQ6IFwiW3BhcmFtZXRlcnMoJ3ZuZXRJZCcpXVwiLFxuICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgb3V0cHV0czoge1xuICAgICAgICAgICAgICAgICAgICBtZW1iZXJJZDoge1xuICAgICAgICAgICAgICAgICAgICAgIHR5cGU6IFwic3RyaW5nXCIsXG4gICAgICAgICAgICAgICAgICAgICAgdmFsdWU6XG4gICAgICAgICAgICAgICAgICAgICAgICBcIltyZXNvdXJjZUlkKCdNaWNyb3NvZnQuTmV0d29yay9uZXR3b3JrTWFuYWdlcnMvbmV0d29ya0dyb3Vwcy9zdGF0aWNNZW1iZXJzJywgdmFyaWFibGVzKCdzdGF0aWNNZW1iZXJOYW1lJykpXVwiLFxuICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgICAgICAgIHZuZXRJZDoge1xuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogXCJbZmllbGQoJ2lkJyldXCIsXG4gICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oXG4gICAgICAgIHN0YWNrLFxuICAgICAgICBcIkRlcGxveUlmTm90RXhpc3RzUG9saWN5XCIsXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcImRlcGxveS1pZi1ub3QtZXhpc3RzLXBvbGljeVwiLFxuICAgICAgICAgIGRpc3BsYXlOYW1lOiBcIkRlcGxveSBJZiBOb3QgRXhpc3RzIHdpdGggQVJNIFRlbXBsYXRlXCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogY29tcGxleFJ1bGUsXG4gICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgYXZubVN1YnNjcmlwdGlvbklkOiB7IHR5cGU6IFwiU3RyaW5nXCIgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHBvbGljeURlZmluaXRpb24pLnRvQmVEZWZpbmVkKCk7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBjb25zdCBzdGFja0NvbmZpZyA9IEpTT04ucGFyc2Uoc3ludGhlc2l6ZWQpO1xuICAgICAgY29uc3QgYXphcGlSZXNvdXJjZSA9IE9iamVjdC52YWx1ZXMoXG4gICAgICAgIHN0YWNrQ29uZmlnLnJlc291cmNlLmF6YXBpX3Jlc291cmNlLFxuICAgICAgKVswXSBhcyBhbnk7XG5cbiAgICAgIGNvbnN0IGRldGFpbHMgPSBwb2xpY3lEZWZpbml0aW9uLnByb3BzLnBvbGljeVJ1bGUudGhlbi5kZXRhaWxzO1xuXG4gICAgICAvLyBWZXJpZnkgZGVwbG95bWVudCBzdHJ1Y3R1cmUgaXMgcHJlc2VydmVkIChub3QgY29udmVydGVkIHRvIG51bGwpXG4gICAgICBleHBlY3QoZGV0YWlscy5kZXBsb3ltZW50KS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KGRldGFpbHMuZGVwbG95bWVudC5sb2NhdGlvbikudG9CZShcIltmaWVsZCgnbG9jYXRpb24nKV1cIik7XG4gICAgICBleHBlY3QoZGV0YWlscy5kZXBsb3ltZW50LnByb3BlcnRpZXMpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QoZGV0YWlscy5kZXBsb3ltZW50LnByb3BlcnRpZXMubW9kZSkudG9CZShcImluY3JlbWVudGFsXCIpO1xuICAgICAgZXhwZWN0KGRldGFpbHMuZGVwbG95bWVudC5wcm9wZXJ0aWVzLnJlc291cmNlR3JvdXApLnRvQmUoXG4gICAgICAgIFwiW3ZhcmlhYmxlcygnYXZubVJlc291cmNlR3JvdXAnKV1cIixcbiAgICAgICk7XG4gICAgICBleHBlY3QoZGV0YWlscy5kZXBsb3ltZW50LnByb3BlcnRpZXMuc3Vic2NyaXB0aW9uSWQpLnRvQmUoXG4gICAgICAgIFwiW3BhcmFtZXRlcnMoJ2F2bm1TdWJzY3JpcHRpb25JZCcpXVwiLFxuICAgICAgKTtcblxuICAgICAgLy8gVmVyaWZ5IEFSTSB0ZW1wbGF0ZSBpcyBmdWxseSBwcmVzZXJ2ZWQgKG5vdCBjb252ZXJ0ZWQgdG8gbnVsbClcbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gZGV0YWlscy5kZXBsb3ltZW50LnByb3BlcnRpZXMudGVtcGxhdGU7XG4gICAgICBleHBlY3QodGVtcGxhdGUpLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QodGVtcGxhdGUuJHNjaGVtYSkudG9CZShcbiAgICAgICAgXCJodHRwczovL3NjaGVtYS5tYW5hZ2VtZW50LmF6dXJlLmNvbS9zY2hlbWFzLzIwMTktMDQtMDEvZGVwbG95bWVudFRlbXBsYXRlLmpzb24jXCIsXG4gICAgICApO1xuICAgICAgZXhwZWN0KHRlbXBsYXRlLmNvbnRlbnRWZXJzaW9uKS50b0JlKFwiMS4wLjAuMFwiKTtcbiAgICAgIGV4cGVjdCh0ZW1wbGF0ZS5wYXJhbWV0ZXJzKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHRlbXBsYXRlLnBhcmFtZXRlcnMudm5ldElkKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHRlbXBsYXRlLnZhcmlhYmxlcykudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdCh0ZW1wbGF0ZS52YXJpYWJsZXMuc3RhdGljTWVtYmVyTmFtZSkudG9CZShcbiAgICAgICAgXCJbZ3VpZChwYXJhbWV0ZXJzKCd2bmV0SWQnKSldXCIsXG4gICAgICApO1xuICAgICAgZXhwZWN0KHRlbXBsYXRlLnJlc291cmNlcykudG9IYXZlTGVuZ3RoKDEpO1xuICAgICAgZXhwZWN0KHRlbXBsYXRlLnJlc291cmNlc1swXS5uYW1lKS50b0JlKFxuICAgICAgICBcIltjb25jYXQocGFyYW1ldGVycygnYXZubUlkJyksICcvJywgdmFyaWFibGVzKCdzdGF0aWNNZW1iZXJOYW1lJykpXVwiLFxuICAgICAgKTtcbiAgICAgIGV4cGVjdCh0ZW1wbGF0ZS5vdXRwdXRzKS50b0JlRGVmaW5lZCgpO1xuICAgICAgZXhwZWN0KHRlbXBsYXRlLm91dHB1dHMubWVtYmVySWQudmFsdWUpLnRvQmUoXG4gICAgICAgIFwiW3Jlc291cmNlSWQoJ01pY3Jvc29mdC5OZXR3b3JrL25ldHdvcmtNYW5hZ2Vycy9uZXR3b3JrR3JvdXBzL3N0YXRpY01lbWJlcnMnLCB2YXJpYWJsZXMoJ3N0YXRpY01lbWJlck5hbWUnKSldXCIsXG4gICAgICApO1xuXG4gICAgICAvLyBWZXJpZnkgQVJNIHRlbXBsYXRlIHBhcmFtZXRlcnMgYXJlIHByZXNlcnZlZFxuICAgICAgY29uc3QgZGVwbG95bWVudFBhcmFtcyA9IGRldGFpbHMuZGVwbG95bWVudC5wcm9wZXJ0aWVzLnBhcmFtZXRlcnM7XG4gICAgICBleHBlY3QoZGVwbG95bWVudFBhcmFtcykudG9CZURlZmluZWQoKTtcbiAgICAgIGV4cGVjdChkZXBsb3ltZW50UGFyYW1zLnZuZXRJZC52YWx1ZSkudG9CZShcIltmaWVsZCgnaWQnKV1cIik7XG5cbiAgICAgIC8vIFZlcmlmeSBzY2hlbWEgdmFsaWRhdGlvbiBpcyBkaXNhYmxlZCB0byBhbGxvdyBjb21wbGV4IG5lc3RlZCBzdHJ1Y3R1cmVzXG4gICAgICBleHBlY3QoYXphcGlSZXNvdXJjZS5zY2hlbWFfdmFsaWRhdGlvbl9lbmFibGVkKS50b0JlKGZhbHNlKTtcbiAgICAgIGV4cGVjdChhemFwaVJlc291cmNlLmlnbm9yZV9taXNzaW5nX3Byb3BlcnR5KS50b0JlKHRydWUpO1xuXG4gICAgICAvLyBWZXJpZnkgdGhlIHN5bnRoZXNpemVkIGNvbmZpZyBoYXMgdGhlIGJvZHkgcHJvcGVydHkgc2V0XG4gICAgICBleHBlY3QoYXphcGlSZXNvdXJjZS5ib2R5KS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgcHJlc2VydmUgZGVlcGx5IG5lc3RlZCBsb2dpY2FsIG9wZXJhdG9yc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBjb21wbGV4UnVsZSA9IHtcbiAgICAgICAgaWY6IHtcbiAgICAgICAgICBhbGxPZjogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBmaWVsZDogXCJ0eXBlXCIsXG4gICAgICAgICAgICAgIGVxdWFsczogXCJNaWNyb3NvZnQuTmV0d29yay92aXJ0dWFsTmV0d29ya3NcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIGFueU9mOiBbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgZmllbGQ6XG4gICAgICAgICAgICAgICAgICAgIFwiTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtzL2VuYWJsZURkb3NQcm90ZWN0aW9uXCIsXG4gICAgICAgICAgICAgICAgICBlcXVhbHM6IFwiZmFsc2VcIixcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIG5vdDoge1xuICAgICAgICAgICAgICAgICAgICBmaWVsZDpcbiAgICAgICAgICAgICAgICAgICAgICBcIk1pY3Jvc29mdC5OZXR3b3JrL3ZpcnR1YWxOZXR3b3Jrcy9zdWJuZXRzWypdLnNlcnZpY2VFbmRwb2ludHNbKl0uc2VydmljZVwiLFxuICAgICAgICAgICAgICAgICAgICBjb250YWluczogXCJNaWNyb3NvZnQuU3RvcmFnZVwiLFxuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICBdLFxuICAgICAgICB9LFxuICAgICAgICB0aGVuOiB7XG4gICAgICAgICAgZWZmZWN0OiBcImF1ZGl0XCIsXG4gICAgICAgIH0sXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oc3RhY2ssIFwiRGVlcGx5TmVzdGVkXCIsIHtcbiAgICAgICAgbmFtZTogXCJkZWVwbHktbmVzdGVkLXBvbGljeVwiLFxuICAgICAgICBwb2xpY3lSdWxlOiBjb21wbGV4UnVsZSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wcm9wcy5wb2xpY3lSdWxlKS50b0VxdWFsKGNvbXBsZXhSdWxlKTtcblxuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHN0YWNrKTtcbiAgICAgIGNvbnN0IHN0YWNrQ29uZmlnID0gSlNPTi5wYXJzZShzeW50aGVzaXplZCk7XG4gICAgICBjb25zdCBhemFwaVJlc291cmNlID0gT2JqZWN0LnZhbHVlcyhcbiAgICAgICAgc3RhY2tDb25maWcucmVzb3VyY2UuYXphcGlfcmVzb3VyY2UsXG4gICAgICApWzBdIGFzIGFueTtcblxuICAgICAgLy8gVmVyaWZ5IHRoZSBkZWVwbHkgbmVzdGVkIHN0cnVjdHVyZSBpcyBwcmVzZXJ2ZWQgaW4gdGhlIGNvbnN0cnVjdCdzIHByb3BzXG4gICAgICBleHBlY3QoXG4gICAgICAgIHBvbGljeURlZmluaXRpb24ucHJvcHMucG9saWN5UnVsZS5pZi5hbGxPZlsxXS5hbnlPZlsxXS5ub3QsXG4gICAgICApLnRvQmVEZWZpbmVkKCk7XG4gICAgICBleHBlY3QoXG4gICAgICAgIHBvbGljeURlZmluaXRpb24ucHJvcHMucG9saWN5UnVsZS5pZi5hbGxPZlsxXS5hbnlPZlsxXS5ub3QuZmllbGQsXG4gICAgICApLnRvQmUoXG4gICAgICAgIFwiTWljcm9zb2Z0Lk5ldHdvcmsvdmlydHVhbE5ldHdvcmtzL3N1Ym5ldHNbKl0uc2VydmljZUVuZHBvaW50c1sqXS5zZXJ2aWNlXCIsXG4gICAgICApO1xuXG4gICAgICAvLyBWZXJpZnkgdGhlIHN5bnRoZXNpemVkIGNvbmZpZyBoYXMgdGhlIGJvZHkgcHJvcGVydHkgc2V0XG4gICAgICBleHBlY3QoYXphcGlSZXNvdXJjZS5ib2R5KS50b0JlRGVmaW5lZCgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZShcIkVycm9yIEhhbmRsaW5nXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBoYW5kbGUgaW52YWxpZCBBUEkgdmVyc2lvbnMgZ3JhY2VmdWxseVwiLCAoKSA9PiB7XG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgUG9saWN5RGVmaW5pdGlvbihzdGFjaywgXCJJbnZhbGlkQVBJXCIsIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICAgICAgYXBpVmVyc2lvbjogXCJpbnZhbGlkLXZlcnNpb25cIixcbiAgICAgICAgfSk7XG4gICAgICB9KS50b1Rocm93KFwiVW5zdXBwb3J0ZWQgQVBJIHZlcnNpb24gJ2ludmFsaWQtdmVyc2lvbidcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYW5kbGUgdmFsaWRhdGlvbiBlcnJvcnMgd2hlbiB2YWxpZGF0aW9uIGlzIGVuYWJsZWRcIiwgKCkgPT4ge1xuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IFBvbGljeURlZmluaXRpb24oc3RhY2ssIFwiVmFsaWRhdGlvbkVycm9yXCIsIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogdW5kZWZpbmVkIGFzIGFueSwgLy8gTWlzc2luZyByZXF1aXJlZCBwb2xpY3lSdWxlXG4gICAgICAgICAgZW5hYmxlVmFsaWRhdGlvbjogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgICB9KS50b1Rocm93KFwiUmVxdWlyZWQgcHJvcGVydHkgJ3BvbGljeVJ1bGUnIGlzIG1pc3NpbmdcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYW5kbGUgc2NoZW1hIHJlZ2lzdHJhdGlvbiBlcnJvcnMgZ3JhY2VmdWxseVwiLCAoKSA9PiB7XG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgUG9saWN5RGVmaW5pdGlvbihzdGFjaywgXCJTY2hlbWFUZXN0XCIsIHtcbiAgICAgICAgICBuYW1lOiBcInRlc3QtcG9saWN5XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICAgIH0pO1xuICAgICAgfSkubm90LnRvVGhyb3coKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJKU0lJIENvbXBsaWFuY2VcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIGhhdmUgSlNJSS1jb21wbGlhbnQgY29uc3RydWN0b3JcIiwgKCkgPT4ge1xuICAgICAgZXhwZWN0KCgpID0+IHtcbiAgICAgICAgbmV3IFBvbGljeURlZmluaXRpb24oc3RhY2ssIFwiSnNpaVRlc3RcIiwge1xuICAgICAgICAgIG5hbWU6IFwianNpaS10ZXN0XCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICAgIH0pO1xuICAgICAgfSkubm90LnRvVGhyb3coKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhdmUgSlNJSS1jb21wbGlhbnQgcHJvcGVydGllc1wiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oc3RhY2ssIFwiSnNpaVByb3BzXCIsIHtcbiAgICAgICAgbmFtZTogXCJqc2lpLXByb3BzXCIsXG4gICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJkZW55XCIgfSB9LFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdCh0eXBlb2YgcG9saWN5RGVmaW5pdGlvbi5pZCkudG9CZShcInN0cmluZ1wiKTtcbiAgICAgIGV4cGVjdCh0eXBlb2YgcG9saWN5RGVmaW5pdGlvbi5uYW1lKS50b0JlKFwic3RyaW5nXCIpO1xuICAgICAgZXhwZWN0KHR5cGVvZiBwb2xpY3lEZWZpbml0aW9uLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcInN0cmluZ1wiKTtcbiAgICAgIGV4cGVjdCh0eXBlb2YgcG9saWN5RGVmaW5pdGlvbi5wb2xpY3lUeXBlKS50b0JlKFwic3RyaW5nXCIpO1xuICAgICAgZXhwZWN0KHR5cGVvZiBwb2xpY3lEZWZpbml0aW9uLnBvbGljeU1vZGUpLnRvQmUoXCJzdHJpbmdcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBoYXZlIEpTSUktY29tcGxpYW50IG1ldGhvZHNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIkpzaWlNZXRob2RzXCIsIHtcbiAgICAgICAgbmFtZTogXCJqc2lpLW1ldGhvZHNcIixcbiAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9IH0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHR5cGVvZiBwb2xpY3lEZWZpbml0aW9uLmxhdGVzdFZlcnNpb24pLnRvQmUoXCJmdW5jdGlvblwiKTtcbiAgICAgIGV4cGVjdCh0eXBlb2YgcG9saWN5RGVmaW5pdGlvbi5zdXBwb3J0ZWRWZXJzaW9ucykudG9CZShcImZ1bmN0aW9uXCIpO1xuICAgIH0pO1xuXG4gICAgaXQoXCJzaG91bGQgc2VyaWFsaXplIGNvbXBsZXggb2JqZWN0cyBjb3JyZWN0bHlcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5RGVmaW5pdGlvbiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKFxuICAgICAgICBzdGFjayxcbiAgICAgICAgXCJKc2lpU2VyaWFsaXphdGlvblwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJqc2lpLXNlcmlhbGl6YXRpb25cIixcbiAgICAgICAgICBwb2xpY3lSdWxlOiB7XG4gICAgICAgICAgICBpZjogeyBmaWVsZDogXCJsb2NhdGlvblwiLCBlcXVhbHM6IFwiZWFzdHVzXCIgfSxcbiAgICAgICAgICAgIHRoZW46IHsgZWZmZWN0OiBcImRlbnlcIiB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgcGFyYW1ldGVyczoge1xuICAgICAgICAgICAgdGVzdFBhcmFtOiB7XG4gICAgICAgICAgICAgIHR5cGU6IFwiU3RyaW5nXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICApO1xuXG4gICAgICBleHBlY3QoKCkgPT5cbiAgICAgICAgSlNPTi5zdHJpbmdpZnkocG9saWN5RGVmaW5pdGlvbi52YWxpZGF0aW9uUmVzdWx0KSxcbiAgICAgICkubm90LnRvVGhyb3coKTtcbiAgICAgIGV4cGVjdCgoKSA9PiBKU09OLnN0cmluZ2lmeShwb2xpY3lEZWZpbml0aW9uLnNjaGVtYSkpLm5vdC50b1Rocm93KCk7XG4gICAgICBleHBlY3QoKCkgPT5cbiAgICAgICAgSlNPTi5zdHJpbmdpZnkocG9saWN5RGVmaW5pdGlvbi52ZXJzaW9uQ29uZmlnKSxcbiAgICAgICkubm90LnRvVGhyb3coKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoXCJDREsgVGVycmFmb3JtIEludGVncmF0aW9uXCIsICgpID0+IHtcbiAgICBpdChcInNob3VsZCBzeW50aGVzaXplIHRvIHZhbGlkIFRlcnJhZm9ybSBjb25maWd1cmF0aW9uXCIsICgpID0+IHtcbiAgICAgIG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIlN5bnRoVGVzdFwiLCB7XG4gICAgICAgIG5hbWU6IFwic3ludGgtdGVzdFwiLFxuICAgICAgICBwb2xpY3lSdWxlOiB7XG4gICAgICAgICAgaWY6IHtcbiAgICAgICAgICAgIGZpZWxkOiBcInR5cGVcIixcbiAgICAgICAgICAgIGVxdWFsczogXCJNaWNyb3NvZnQuQ29tcHV0ZS92aXJ0dWFsTWFjaGluZXNcIixcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRoZW46IHtcbiAgICAgICAgICAgIGVmZmVjdDogXCJhdWRpdFwiLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgc3ludGhlc2l6ZWQgPSBUZXN0aW5nLnN5bnRoKHN0YWNrKTtcbiAgICAgIGV4cGVjdChzeW50aGVzaXplZCkudG9CZURlZmluZWQoKTtcblxuICAgICAgY29uc3Qgc3RhY2tDb25maWcgPSBKU09OLnBhcnNlKHN5bnRoZXNpemVkKTtcbiAgICAgIGV4cGVjdChzdGFja0NvbmZpZy5yZXNvdXJjZSkudG9CZURlZmluZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHdvcmsgaW4gY29tcGxleCBDREsgY29uc3RydWN0c1wiLCAoKSA9PiB7XG4gICAgICBjbGFzcyBDb21wbGV4Q29uc3RydWN0IGV4dGVuZHMgY2RrdGYuVGVycmFmb3JtU3RhY2sge1xuICAgICAgICBjb25zdHJ1Y3RvcihzY29wZTogY2RrdGYuQXBwLCBpZDogc3RyaW5nKSB7XG4gICAgICAgICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgICAgICAgIGNvbnN0IHBvbGljeTEgPSBuZXcgUG9saWN5RGVmaW5pdGlvbih0aGlzLCBcIlBvbGljeTFcIiwge1xuICAgICAgICAgICAgbmFtZTogXCJwb2xpY3ktMVwiLFxuICAgICAgICAgICAgZGlzcGxheU5hbWU6IFwiRmlyc3QgUG9saWN5XCIsXG4gICAgICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiYXVkaXRcIiB9IH0sXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBjb25zdCBwb2xpY3kyID0gbmV3IFBvbGljeURlZmluaXRpb24odGhpcywgXCJQb2xpY3kyXCIsIHtcbiAgICAgICAgICAgIG5hbWU6IFwicG9saWN5LTJcIixcbiAgICAgICAgICAgIGRpc3BsYXlOYW1lOiBcIlNlY29uZCBQb2xpY3lcIixcbiAgICAgICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJkZW55XCIgfSB9LFxuICAgICAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIxLTA2LTAxXCIsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBuZXcgY2RrdGYuVGVycmFmb3JtT3V0cHV0KHRoaXMsIFwiUG9saWN5MUlkXCIsIHtcbiAgICAgICAgICAgIHZhbHVlOiBwb2xpY3kxLmlkLFxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgbmV3IGNka3RmLlRlcnJhZm9ybU91dHB1dCh0aGlzLCBcIlBvbGljeTJJZFwiLCB7XG4gICAgICAgICAgICB2YWx1ZTogcG9saWN5Mi5pZCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBleHBlY3QoKCkgPT4ge1xuICAgICAgICBuZXcgQ29tcGxleENvbnN0cnVjdChhcHAsIFwiQ29tcGxleFN0YWNrXCIpO1xuICAgICAgfSkubm90LnRvVGhyb3coKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIGhhbmRsZSBtdWx0aXBsZSBwb2xpY3kgZGVmaW5pdGlvbnMgaW4gdGhlIHNhbWUgc3RhY2tcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgcG9saWN5MSA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIlBvbGljeURlZmluaXRpb24xXCIsIHtcbiAgICAgICAgbmFtZTogXCJwb2xpY3ktMVwiLFxuICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiYXVkaXRcIiB9IH0sXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcG9saWN5MiA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIlBvbGljeURlZmluaXRpb24yXCIsIHtcbiAgICAgICAgbmFtZTogXCJwb2xpY3ktMlwiLFxuICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiZGVueVwiIH0gfSxcbiAgICAgICAgYXBpVmVyc2lvbjogXCIyMDIxLTA2LTAxXCIsXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KHBvbGljeTEucmVzb2x2ZWRBcGlWZXJzaW9uKS50b0JlKFwiMjAyMS0wNi0wMVwiKTtcbiAgICAgIGV4cGVjdChwb2xpY3kyLnJlc29sdmVkQXBpVmVyc2lvbikudG9CZShcIjIwMjEtMDYtMDFcIik7XG5cbiAgICAgIGNvbnN0IHN5bnRoZXNpemVkID0gVGVzdGluZy5zeW50aChzdGFjayk7XG4gICAgICBleHBlY3Qoc3ludGhlc2l6ZWQpLnRvQmVEZWZpbmVkKCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKFwiUG9saWN5IERlZmluaXRpb24gVHlwZXNcIiwgKCkgPT4ge1xuICAgIGl0KFwic2hvdWxkIHN1cHBvcnQgQnVpbHRJbiBwb2xpY3kgdHlwZVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBwb2xpY3lEZWZpbml0aW9uID0gbmV3IFBvbGljeURlZmluaXRpb24oc3RhY2ssIFwiQnVpbHRJblBvbGljeVwiLCB7XG4gICAgICAgIG5hbWU6IFwiYnVpbHRpbi1wb2xpY3lcIixcbiAgICAgICAgcG9saWN5VHlwZTogXCJCdWlsdEluXCIsXG4gICAgICAgIHBvbGljeVJ1bGU6IHsgaWY6IHt9LCB0aGVuOiB7IGVmZmVjdDogXCJhdWRpdFwiIH0gfSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QocG9saWN5RGVmaW5pdGlvbi5wb2xpY3lUeXBlKS50b0JlKFwiQnVpbHRJblwiKTtcbiAgICB9KTtcblxuICAgIGl0KFwic2hvdWxkIHN1cHBvcnQgU3RhdGljIHBvbGljeSB0eXBlXCIsICgpID0+IHtcbiAgICAgIGNvbnN0IHBvbGljeURlZmluaXRpb24gPSBuZXcgUG9saWN5RGVmaW5pdGlvbihzdGFjaywgXCJTdGF0aWNQb2xpY3lcIiwge1xuICAgICAgICBuYW1lOiBcInN0YXRpYy1wb2xpY3lcIixcbiAgICAgICAgcG9saWN5VHlwZTogXCJTdGF0aWNcIixcbiAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImF1ZGl0XCIgfSB9LFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChwb2xpY3lEZWZpbml0aW9uLnBvbGljeVR5cGUpLnRvQmUoXCJTdGF0aWNcIik7XG4gICAgfSk7XG5cbiAgICBpdChcInNob3VsZCBzdXBwb3J0IGRpZmZlcmVudCBwb2xpY3kgbW9kZXNcIiwgKCkgPT4ge1xuICAgICAgY29uc3QgaW5kZXhlZFBvbGljeSA9IG5ldyBQb2xpY3lEZWZpbml0aW9uKHN0YWNrLCBcIkluZGV4ZWRQb2xpY3lcIiwge1xuICAgICAgICBuYW1lOiBcImluZGV4ZWQtcG9saWN5XCIsXG4gICAgICAgIG1vZGU6IFwiSW5kZXhlZFwiLFxuICAgICAgICBwb2xpY3lSdWxlOiB7IGlmOiB7fSwgdGhlbjogeyBlZmZlY3Q6IFwiYXVkaXRcIiB9IH0sXG4gICAgICB9KTtcblxuICAgICAgZXhwZWN0KGluZGV4ZWRQb2xpY3kucG9saWN5TW9kZSkudG9CZShcIkluZGV4ZWRcIik7XG5cbiAgICAgIGNvbnN0IHJlc291cmNlUHJvdmlkZXJQb2xpY3kgPSBuZXcgUG9saWN5RGVmaW5pdGlvbihcbiAgICAgICAgc3RhY2ssXG4gICAgICAgIFwiUmVzb3VyY2VQcm92aWRlclBvbGljeVwiLFxuICAgICAgICB7XG4gICAgICAgICAgbmFtZTogXCJyZXNvdXJjZS1wcm92aWRlci1wb2xpY3lcIixcbiAgICAgICAgICBtb2RlOiBcIk1pY3Jvc29mdC5LZXlWYXVsdC5EYXRhXCIsXG4gICAgICAgICAgcG9saWN5UnVsZTogeyBpZjoge30sIHRoZW46IHsgZWZmZWN0OiBcImF1ZGl0XCIgfSB9LFxuICAgICAgICB9LFxuICAgICAgKTtcblxuICAgICAgZXhwZWN0KHJlc291cmNlUHJvdmlkZXJQb2xpY3kucG9saWN5TW9kZSkudG9CZShcIk1pY3Jvc29mdC5LZXlWYXVsdC5EYXRhXCIpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19