@gravitee/ui-components 3.25.3 → 3.25.4

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 (547) hide show
  1. package/package.json +10 -7
  2. package/src/atoms/gv-autocomplete.d.ts +104 -0
  3. package/src/atoms/gv-autocomplete.js +339 -353
  4. package/src/atoms/gv-autocomplete.js.map +1 -0
  5. package/src/atoms/gv-button.d.ts +109 -0
  6. package/src/atoms/gv-button.js +315 -152
  7. package/src/atoms/gv-button.js.map +1 -0
  8. package/src/atoms/gv-checkbox.d.ts +114 -0
  9. package/src/atoms/gv-checkbox.js +128 -78
  10. package/src/atoms/gv-checkbox.js.map +1 -0
  11. package/src/atoms/gv-date-picker-calendar.d.ts +190 -0
  12. package/src/atoms/gv-date-picker-calendar.js +699 -699
  13. package/src/atoms/gv-date-picker-calendar.js.map +1 -0
  14. package/src/atoms/gv-date-picker-cell.d.ts +80 -0
  15. package/src/atoms/gv-date-picker-cell.js +117 -108
  16. package/src/atoms/gv-date-picker-cell.js.map +1 -0
  17. package/src/atoms/gv-date-picker.d.ts +194 -0
  18. package/src/atoms/gv-date-picker.js +549 -442
  19. package/src/atoms/gv-date-picker.js.map +1 -0
  20. package/src/atoms/gv-file-upload.d.ts +64 -0
  21. package/src/atoms/gv-file-upload.js +288 -196
  22. package/src/atoms/gv-file-upload.js.map +1 -0
  23. package/src/atoms/gv-icon.d.ts +26 -0
  24. package/src/atoms/gv-icon.js +59 -47
  25. package/src/atoms/gv-icon.js.map +1 -0
  26. package/src/atoms/gv-image.d.ts +45 -0
  27. package/src/atoms/gv-image.js +93 -66
  28. package/src/atoms/gv-image.js.map +1 -0
  29. package/src/atoms/gv-input-message.d.ts +20 -0
  30. package/src/atoms/gv-input-message.js +49 -29
  31. package/src/atoms/gv-input-message.js.map +1 -0
  32. package/src/atoms/gv-input.d.ts +246 -0
  33. package/src/atoms/gv-input.js +400 -421
  34. package/src/atoms/gv-input.js.map +1 -0
  35. package/src/atoms/gv-link.d.ts +67 -0
  36. package/src/atoms/gv-link.js +143 -70
  37. package/src/atoms/gv-link.js.map +1 -0
  38. package/src/atoms/gv-message.d.ts +23 -0
  39. package/src/atoms/gv-message.js +98 -41
  40. package/src/atoms/gv-message.js.map +1 -0
  41. package/src/atoms/gv-metric.d.ts +32 -0
  42. package/src/atoms/gv-metric.js +74 -29
  43. package/src/atoms/gv-metric.js.map +1 -0
  44. package/src/atoms/gv-relative-time.d.ts +45 -0
  45. package/src/atoms/gv-relative-time.js +107 -148
  46. package/src/atoms/gv-relative-time.js.map +1 -0
  47. package/src/atoms/gv-select-native.d.ts +174 -0
  48. package/src/atoms/gv-select-native.js +289 -194
  49. package/src/atoms/gv-select-native.js.map +1 -0
  50. package/src/atoms/gv-select.d.ts +71 -0
  51. package/src/atoms/gv-select.js +323 -226
  52. package/src/atoms/gv-select.js.map +1 -0
  53. package/src/atoms/gv-spinner.d.ts +10 -0
  54. package/src/atoms/gv-spinner.js +29 -10
  55. package/src/atoms/gv-spinner.js.map +1 -0
  56. package/src/atoms/gv-state.d.ts +50 -0
  57. package/src/atoms/gv-state.js +76 -39
  58. package/src/atoms/gv-state.js.map +1 -0
  59. package/src/atoms/gv-switch.d.ts +60 -0
  60. package/src/atoms/gv-switch.js +187 -74
  61. package/src/atoms/gv-switch.js.map +1 -0
  62. package/src/atoms/gv-tag.d.ts +69 -0
  63. package/src/atoms/gv-tag.js +92 -45
  64. package/src/atoms/gv-tag.js.map +1 -0
  65. package/src/atoms/gv-text.d.ts +110 -0
  66. package/src/atoms/gv-text.js +105 -51
  67. package/src/atoms/gv-text.js.map +1 -0
  68. package/src/charts/gv-chart-bar.d.ts +50 -0
  69. package/src/charts/gv-chart-bar.js +64 -69
  70. package/src/charts/gv-chart-bar.js.map +1 -0
  71. package/src/charts/gv-chart-gauge.d.ts +58 -0
  72. package/src/charts/gv-chart-gauge.js +58 -62
  73. package/src/charts/gv-chart-gauge.js.map +1 -0
  74. package/src/charts/gv-chart-histogram.d.ts +48 -0
  75. package/src/charts/gv-chart-histogram.js +46 -58
  76. package/src/charts/gv-chart-histogram.js.map +1 -0
  77. package/src/charts/gv-chart-line.d.ts +52 -0
  78. package/src/charts/gv-chart-line.js +173 -189
  79. package/src/charts/gv-chart-line.js.map +1 -0
  80. package/src/charts/gv-chart-map.d.ts +50 -0
  81. package/src/charts/gv-chart-map.js +73 -75
  82. package/src/charts/gv-chart-map.js.map +1 -0
  83. package/src/charts/gv-chart-pie.d.ts +50 -0
  84. package/src/charts/gv-chart-pie.js +52 -57
  85. package/src/charts/gv-chart-pie.js.map +1 -0
  86. package/src/index.d.ts +77 -0
  87. package/src/index.js +1 -1
  88. package/src/index.js.map +1 -0
  89. package/src/lib/cron-expression.d.ts +1 -0
  90. package/src/lib/cron-expression.js +143 -176
  91. package/src/lib/cron-expression.js.map +1 -0
  92. package/src/lib/date.d.ts +1 -0
  93. package/src/lib/date.js +26 -35
  94. package/src/lib/date.js.map +1 -0
  95. package/src/lib/events.d.ts +1 -0
  96. package/src/lib/events.js +10 -11
  97. package/src/lib/events.js.map +1 -0
  98. package/src/lib/http-client-schema-form.d.ts +68 -0
  99. package/src/lib/http-client-schema-form.js +50 -50
  100. package/src/lib/http-client-schema-form.js.map +1 -0
  101. package/src/lib/http.d.ts +222 -0
  102. package/src/lib/http.js +221 -221
  103. package/src/lib/http.js.map +1 -0
  104. package/src/lib/i18n.d.ts +30 -0
  105. package/src/lib/i18n.js +40 -57
  106. package/src/lib/i18n.js.map +1 -0
  107. package/src/lib/item.d.ts +12 -0
  108. package/src/lib/item.js +66 -74
  109. package/src/lib/item.js.map +1 -0
  110. package/src/lib/properties.d.ts +42 -0
  111. package/src/lib/properties.js +110 -162
  112. package/src/lib/properties.js.map +1 -0
  113. package/src/lib/schema-form.d.ts +5 -0
  114. package/src/lib/schema-form.js +13 -16
  115. package/src/lib/schema-form.js.map +1 -0
  116. package/src/lib/studio.d.ts +2 -0
  117. package/src/lib/studio.js +116 -65
  118. package/src/lib/studio.js.map +1 -0
  119. package/src/lib/style.d.ts +6 -0
  120. package/src/lib/style.js +18 -19
  121. package/src/lib/style.js.map +1 -0
  122. package/src/lib/text-format.d.ts +6 -0
  123. package/src/lib/text-format.js +45 -55
  124. package/src/lib/text-format.js.map +1 -0
  125. package/src/lib/theme.d.ts +4 -0
  126. package/src/lib/theme.js +38 -43
  127. package/src/lib/theme.js.map +1 -0
  128. package/src/lib/utils.d.ts +9 -0
  129. package/src/lib/utils.js +72 -75
  130. package/src/lib/utils.js.map +1 -0
  131. package/src/mixins/chart-element.d.ts +39 -0
  132. package/src/mixins/chart-element.js +118 -106
  133. package/src/mixins/chart-element.js.map +1 -0
  134. package/src/mixins/input-element.d.ts +64 -0
  135. package/src/mixins/input-element.js +111 -131
  136. package/src/mixins/input-element.js.map +1 -0
  137. package/src/mixins/item-resource.d.ts +56 -0
  138. package/src/mixins/item-resource.js +76 -95
  139. package/src/mixins/item-resource.js.map +1 -0
  140. package/src/mixins/keyboard-element.d.ts +25 -0
  141. package/src/mixins/keyboard-element.js +44 -51
  142. package/src/mixins/keyboard-element.js.map +1 -0
  143. package/src/mixins/update-after-browser.d.ts +11 -0
  144. package/src/mixins/update-after-browser.js +10 -12
  145. package/src/mixins/update-after-browser.js.map +1 -0
  146. package/src/mixins/with-resize-observer.d.ts +12 -0
  147. package/src/mixins/with-resize-observer.js +46 -61
  148. package/src/mixins/with-resize-observer.js.map +1 -0
  149. package/src/mixins/with-skeleton-attribute.d.ts +35 -0
  150. package/src/mixins/with-skeleton-attribute.js +80 -88
  151. package/src/mixins/with-skeleton-attribute.js.map +1 -0
  152. package/src/molecules/gv-card-full.d.ts +78 -0
  153. package/src/molecules/gv-card-full.js +160 -47
  154. package/src/molecules/gv-card-full.js.map +1 -0
  155. package/src/molecules/gv-card-list.d.ts +33 -0
  156. package/src/molecules/gv-card-list.js +65 -47
  157. package/src/molecules/gv-card-list.js.map +1 -0
  158. package/src/molecules/gv-card.d.ts +65 -0
  159. package/src/molecules/gv-card.js +94 -22
  160. package/src/molecules/gv-card.js.map +1 -0
  161. package/src/molecules/gv-category-list.d.ts +17 -0
  162. package/src/molecules/gv-category-list.js +23 -15
  163. package/src/molecules/gv-category-list.js.map +1 -0
  164. package/src/molecules/gv-category.d.ts +64 -0
  165. package/src/molecules/gv-category.js +117 -43
  166. package/src/molecules/gv-category.js.map +1 -0
  167. package/src/molecules/gv-code.d.ts +192 -0
  168. package/src/molecules/gv-code.js +258 -220
  169. package/src/molecules/gv-code.js.map +1 -0
  170. package/src/molecules/gv-confirm.d.ts +60 -0
  171. package/src/molecules/gv-confirm.js +131 -113
  172. package/src/molecules/gv-confirm.js.map +1 -0
  173. package/src/molecules/gv-cron-editor.d.ts +115 -0
  174. package/src/molecules/gv-cron-editor.js +597 -375
  175. package/src/molecules/gv-cron-editor.js.map +1 -0
  176. package/src/molecules/gv-dropdown-menu.d.ts +28 -0
  177. package/src/molecules/gv-dropdown-menu.js +77 -52
  178. package/src/molecules/gv-dropdown-menu.js.map +1 -0
  179. package/src/molecules/gv-expandable.d.ts +37 -0
  180. package/src/molecules/gv-expandable.js +77 -54
  181. package/src/molecules/gv-expandable.js.map +1 -0
  182. package/src/molecules/gv-expression-language.d.ts +150 -0
  183. package/src/molecules/gv-expression-language.js +212 -256
  184. package/src/molecules/gv-expression-language.js.map +1 -0
  185. package/src/molecules/gv-identity-picture.d.ts +44 -0
  186. package/src/molecules/gv-identity-picture.js +102 -87
  187. package/src/molecules/gv-identity-picture.js.map +1 -0
  188. package/src/molecules/gv-list.d.ts +123 -0
  189. package/src/molecules/gv-list.js +167 -87
  190. package/src/molecules/gv-list.js.map +1 -0
  191. package/src/molecules/gv-metrics.d.ts +65 -0
  192. package/src/molecules/gv-metrics.js +103 -105
  193. package/src/molecules/gv-metrics.js.map +1 -0
  194. package/src/molecules/gv-modal.d.ts +64 -0
  195. package/src/molecules/gv-modal.js +157 -99
  196. package/src/molecules/gv-modal.js.map +1 -0
  197. package/src/molecules/gv-nav.d.ts +41 -0
  198. package/src/molecules/gv-nav.js +134 -123
  199. package/src/molecules/gv-nav.js.map +1 -0
  200. package/src/molecules/gv-option.d.ts +65 -0
  201. package/src/molecules/gv-option.js +177 -115
  202. package/src/molecules/gv-option.js.map +1 -0
  203. package/src/molecules/gv-plans.d.ts +73 -0
  204. package/src/molecules/gv-plans.js +327 -232
  205. package/src/molecules/gv-plans.js.map +1 -0
  206. package/src/molecules/gv-popover.d.ts +91 -0
  207. package/src/molecules/gv-popover.js +265 -172
  208. package/src/molecules/gv-popover.js.map +1 -0
  209. package/src/molecules/gv-promote.d.ts +108 -0
  210. package/src/molecules/gv-promote.js +152 -39
  211. package/src/molecules/gv-promote.js.map +1 -0
  212. package/src/molecules/gv-rating-list.d.ts +77 -0
  213. package/src/molecules/gv-rating-list.js +287 -184
  214. package/src/molecules/gv-rating-list.js.map +1 -0
  215. package/src/molecules/gv-rating.d.ts +55 -0
  216. package/src/molecules/gv-rating.js +187 -152
  217. package/src/molecules/gv-rating.js.map +1 -0
  218. package/src/molecules/gv-row-expandable.d.ts +8 -0
  219. package/src/molecules/gv-row-expandable.js +18 -14
  220. package/src/molecules/gv-row-expandable.js.map +1 -0
  221. package/src/molecules/gv-row.d.ts +37 -0
  222. package/src/molecules/gv-row.js +164 -42
  223. package/src/molecules/gv-row.js.map +1 -0
  224. package/src/molecules/gv-stats.d.ts +53 -0
  225. package/src/molecules/gv-stats.js +70 -55
  226. package/src/molecules/gv-stats.js.map +1 -0
  227. package/src/molecules/gv-stepper.d.ts +46 -0
  228. package/src/molecules/gv-stepper.js +225 -94
  229. package/src/molecules/gv-stepper.js.map +1 -0
  230. package/src/molecules/gv-table.d.ts +159 -0
  231. package/src/molecules/gv-table.js +530 -460
  232. package/src/molecules/gv-table.js.map +1 -0
  233. package/src/molecules/gv-tree.d.ts +44 -0
  234. package/src/molecules/gv-tree.js +189 -77
  235. package/src/molecules/gv-tree.js.map +1 -0
  236. package/src/organisms/gv-documentation.d.ts +52 -0
  237. package/src/organisms/gv-documentation.js +155 -81
  238. package/src/organisms/gv-documentation.js.map +1 -0
  239. package/src/organisms/gv-header.d.ts +60 -0
  240. package/src/organisms/gv-header.js +227 -80
  241. package/src/organisms/gv-header.js.map +1 -0
  242. package/src/organisms/gv-http-client.d.ts +57 -0
  243. package/src/organisms/gv-http-client.js +203 -83
  244. package/src/organisms/gv-http-client.js.map +1 -0
  245. package/src/organisms/gv-menu.d.ts +74 -0
  246. package/src/organisms/gv-menu.js +206 -89
  247. package/src/organisms/gv-menu.js.map +1 -0
  248. package/src/organisms/gv-newsletter-subscription.d.ts +82 -0
  249. package/src/organisms/gv-newsletter-subscription.js +212 -83
  250. package/src/organisms/gv-newsletter-subscription.js.map +1 -0
  251. package/src/organisms/gv-pagination.d.ts +63 -0
  252. package/src/organisms/gv-pagination.js +134 -124
  253. package/src/organisms/gv-pagination.js.map +1 -0
  254. package/src/organisms/gv-properties.d.ts +229 -0
  255. package/src/organisms/gv-properties.js +778 -616
  256. package/src/organisms/gv-properties.js.map +1 -0
  257. package/src/organisms/gv-resizable-views.d.ts +33 -0
  258. package/src/organisms/gv-resizable-views.js +334 -140
  259. package/src/organisms/gv-resizable-views.js.map +1 -0
  260. package/src/organisms/gv-resources.d.ts +125 -0
  261. package/src/organisms/gv-resources.js +434 -365
  262. package/src/organisms/gv-resources.js.map +1 -0
  263. package/src/organisms/gv-schema-form-array.d.ts +55 -0
  264. package/src/organisms/gv-schema-form-array.js +196 -98
  265. package/src/organisms/gv-schema-form-array.js.map +1 -0
  266. package/src/organisms/gv-schema-form-control-object.d.ts +64 -0
  267. package/src/organisms/gv-schema-form-control-object.js +110 -108
  268. package/src/organisms/gv-schema-form-control-object.js.map +1 -0
  269. package/src/organisms/gv-schema-form-control.d.ts +90 -0
  270. package/src/organisms/gv-schema-form-control.js +353 -349
  271. package/src/organisms/gv-schema-form-control.js.map +1 -0
  272. package/src/organisms/gv-schema-form.d.ts +156 -0
  273. package/src/organisms/gv-schema-form.js +611 -556
  274. package/src/organisms/gv-schema-form.js.map +1 -0
  275. package/src/organisms/gv-tabs.d.ts +56 -0
  276. package/src/organisms/gv-tabs.js +149 -125
  277. package/src/organisms/gv-tabs.js.map +1 -0
  278. package/src/organisms/gv-user-menu.d.ts +56 -0
  279. package/src/organisms/gv-user-menu.js +244 -94
  280. package/src/organisms/gv-user-menu.js.map +1 -0
  281. package/src/organisms/gv-vertical-menu.d.ts +28 -0
  282. package/src/organisms/gv-vertical-menu.js +84 -46
  283. package/src/organisms/gv-vertical-menu.js.map +1 -0
  284. package/src/policy-studio/gv-flow-step.d.ts +142 -0
  285. package/src/policy-studio/gv-flow-step.js +390 -250
  286. package/src/policy-studio/gv-flow-step.js.map +1 -0
  287. package/src/policy-studio/gv-flow.d.ts +89 -0
  288. package/src/policy-studio/gv-flow.js +512 -358
  289. package/src/policy-studio/gv-flow.js.map +1 -0
  290. package/src/policy-studio/gv-policy-studio-menu.d.ts +94 -0
  291. package/src/policy-studio/gv-policy-studio-menu.js +657 -403
  292. package/src/policy-studio/gv-policy-studio-menu.js.map +1 -0
  293. package/src/policy-studio/gv-policy-studio.d.ts +464 -0
  294. package/src/policy-studio/gv-policy-studio.js +1531 -1599
  295. package/src/policy-studio/gv-policy-studio.js.map +1 -0
  296. package/src/styles/empty.d.ts +1 -0
  297. package/src/styles/empty.js +21 -4
  298. package/src/styles/empty.js.map +1 -0
  299. package/src/styles/input.d.ts +1 -0
  300. package/src/styles/input.js +247 -3
  301. package/src/styles/input.js.map +1 -0
  302. package/src/styles/link.d.ts +1 -0
  303. package/src/styles/link.js +16 -3
  304. package/src/styles/link.js.map +1 -0
  305. package/src/styles/shapes.d.ts +2 -0
  306. package/src/styles/shapes.js +1 -1
  307. package/src/styles/shapes.js.map +1 -0
  308. package/src/styles/skeleton.d.ts +1 -0
  309. package/src/styles/skeleton.js +37 -3
  310. package/src/styles/skeleton.js.map +1 -0
  311. package/src/styles/zoom.d.ts +1 -0
  312. package/src/styles/zoom.js +24 -3
  313. package/src/styles/zoom.js.map +1 -0
  314. package/src/theme/gv-theme.d.ts +81 -0
  315. package/src/theme/gv-theme.js +115 -81
  316. package/src/theme/gv-theme.js.map +1 -0
  317. package/wc/gv-autocomplete.d.ts +1 -0
  318. package/wc/gv-autocomplete.js +2 -1
  319. package/wc/gv-autocomplete.js.map +1 -0
  320. package/wc/gv-button.d.ts +1 -0
  321. package/wc/gv-button.js +2 -1
  322. package/wc/gv-button.js.map +1 -0
  323. package/wc/gv-card-full.d.ts +1 -0
  324. package/wc/gv-card-full.js +2 -1
  325. package/wc/gv-card-full.js.map +1 -0
  326. package/wc/gv-card-list.d.ts +1 -0
  327. package/wc/gv-card-list.js +2 -1
  328. package/wc/gv-card-list.js.map +1 -0
  329. package/wc/gv-card.d.ts +1 -0
  330. package/wc/gv-card.js +2 -1
  331. package/wc/gv-card.js.map +1 -0
  332. package/wc/gv-category-list.d.ts +1 -0
  333. package/wc/gv-category-list.js +2 -1
  334. package/wc/gv-category-list.js.map +1 -0
  335. package/wc/gv-category.d.ts +1 -0
  336. package/wc/gv-category.js +2 -1
  337. package/wc/gv-category.js.map +1 -0
  338. package/wc/gv-chart-bar.d.ts +1 -0
  339. package/wc/gv-chart-bar.js +2 -1
  340. package/wc/gv-chart-bar.js.map +1 -0
  341. package/wc/gv-chart-gauge.d.ts +1 -0
  342. package/wc/gv-chart-gauge.js +2 -1
  343. package/wc/gv-chart-gauge.js.map +1 -0
  344. package/wc/gv-chart-histogram.d.ts +1 -0
  345. package/wc/gv-chart-histogram.js +2 -1
  346. package/wc/gv-chart-histogram.js.map +1 -0
  347. package/wc/gv-chart-line.d.ts +1 -0
  348. package/wc/gv-chart-line.js +2 -1
  349. package/wc/gv-chart-line.js.map +1 -0
  350. package/wc/gv-chart-map.d.ts +1 -0
  351. package/wc/gv-chart-map.js +2 -1
  352. package/wc/gv-chart-map.js.map +1 -0
  353. package/wc/gv-chart-pie.d.ts +1 -0
  354. package/wc/gv-chart-pie.js +2 -1
  355. package/wc/gv-chart-pie.js.map +1 -0
  356. package/wc/gv-checkbox.d.ts +1 -0
  357. package/wc/gv-checkbox.js +2 -1
  358. package/wc/gv-checkbox.js.map +1 -0
  359. package/wc/gv-code.d.ts +1 -0
  360. package/wc/gv-code.js +2 -1
  361. package/wc/gv-code.js.map +1 -0
  362. package/wc/gv-confirm.d.ts +1 -0
  363. package/wc/gv-confirm.js +2 -1
  364. package/wc/gv-confirm.js.map +1 -0
  365. package/wc/gv-cron-editor.d.ts +1 -0
  366. package/wc/gv-cron-editor.js +2 -1
  367. package/wc/gv-cron-editor.js.map +1 -0
  368. package/wc/gv-date-picker-calendar.d.ts +1 -0
  369. package/wc/gv-date-picker-calendar.js +2 -1
  370. package/wc/gv-date-picker-calendar.js.map +1 -0
  371. package/wc/gv-date-picker-cell.d.ts +1 -0
  372. package/wc/gv-date-picker-cell.js +2 -1
  373. package/wc/gv-date-picker-cell.js.map +1 -0
  374. package/wc/gv-date-picker.d.ts +1 -0
  375. package/wc/gv-date-picker.js +2 -1
  376. package/wc/gv-date-picker.js.map +1 -0
  377. package/wc/gv-documentation.d.ts +1 -0
  378. package/wc/gv-documentation.js +2 -1
  379. package/wc/gv-documentation.js.map +1 -0
  380. package/wc/gv-dropdown-menu.d.ts +1 -0
  381. package/wc/gv-dropdown-menu.js +2 -1
  382. package/wc/gv-dropdown-menu.js.map +1 -0
  383. package/wc/gv-expandable.d.ts +1 -0
  384. package/wc/gv-expandable.js +2 -1
  385. package/wc/gv-expandable.js.map +1 -0
  386. package/wc/gv-expression-language.d.ts +1 -0
  387. package/wc/gv-expression-language.js +2 -1
  388. package/wc/gv-expression-language.js.map +1 -0
  389. package/wc/gv-file-upload.d.ts +1 -0
  390. package/wc/gv-file-upload.js +2 -1
  391. package/wc/gv-file-upload.js.map +1 -0
  392. package/wc/gv-flow-step.d.ts +1 -0
  393. package/wc/gv-flow-step.js +2 -1
  394. package/wc/gv-flow-step.js.map +1 -0
  395. package/wc/gv-flow.d.ts +1 -0
  396. package/wc/gv-flow.js +2 -1
  397. package/wc/gv-flow.js.map +1 -0
  398. package/wc/gv-header.d.ts +1 -0
  399. package/wc/gv-header.js +2 -1
  400. package/wc/gv-header.js.map +1 -0
  401. package/wc/gv-http-client.d.ts +1 -0
  402. package/wc/gv-http-client.js +2 -1
  403. package/wc/gv-http-client.js.map +1 -0
  404. package/wc/gv-icon.d.ts +1 -0
  405. package/wc/gv-icon.js +2 -1
  406. package/wc/gv-icon.js.map +1 -0
  407. package/wc/gv-identity-picture.d.ts +1 -0
  408. package/wc/gv-identity-picture.js +2 -1
  409. package/wc/gv-identity-picture.js.map +1 -0
  410. package/wc/gv-image.d.ts +1 -0
  411. package/wc/gv-image.js +2 -1
  412. package/wc/gv-image.js.map +1 -0
  413. package/wc/gv-input-message.d.ts +1 -0
  414. package/wc/gv-input-message.js +2 -1
  415. package/wc/gv-input-message.js.map +1 -0
  416. package/wc/gv-input.d.ts +1 -0
  417. package/wc/gv-input.js +2 -1
  418. package/wc/gv-input.js.map +1 -0
  419. package/wc/gv-link.d.ts +1 -0
  420. package/wc/gv-link.js +2 -1
  421. package/wc/gv-link.js.map +1 -0
  422. package/wc/gv-list.d.ts +1 -0
  423. package/wc/gv-list.js +2 -1
  424. package/wc/gv-list.js.map +1 -0
  425. package/wc/gv-menu.d.ts +1 -0
  426. package/wc/gv-menu.js +2 -1
  427. package/wc/gv-menu.js.map +1 -0
  428. package/wc/gv-message.d.ts +1 -0
  429. package/wc/gv-message.js +2 -1
  430. package/wc/gv-message.js.map +1 -0
  431. package/wc/gv-metric.d.ts +1 -0
  432. package/wc/gv-metric.js +2 -1
  433. package/wc/gv-metric.js.map +1 -0
  434. package/wc/gv-metrics.d.ts +1 -0
  435. package/wc/gv-metrics.js +2 -1
  436. package/wc/gv-metrics.js.map +1 -0
  437. package/wc/gv-modal.d.ts +1 -0
  438. package/wc/gv-modal.js +2 -1
  439. package/wc/gv-modal.js.map +1 -0
  440. package/wc/gv-nav.d.ts +1 -0
  441. package/wc/gv-nav.js +2 -1
  442. package/wc/gv-nav.js.map +1 -0
  443. package/wc/gv-newsletter-subscription.d.ts +1 -0
  444. package/wc/gv-newsletter-subscription.js +2 -1
  445. package/wc/gv-newsletter-subscription.js.map +1 -0
  446. package/wc/gv-option.d.ts +1 -0
  447. package/wc/gv-option.js +2 -1
  448. package/wc/gv-option.js.map +1 -0
  449. package/wc/gv-pagination.d.ts +1 -0
  450. package/wc/gv-pagination.js +2 -1
  451. package/wc/gv-pagination.js.map +1 -0
  452. package/wc/gv-plans.d.ts +1 -0
  453. package/wc/gv-plans.js +2 -1
  454. package/wc/gv-plans.js.map +1 -0
  455. package/wc/gv-policy-studio-menu.d.ts +1 -0
  456. package/wc/gv-policy-studio-menu.js +2 -1
  457. package/wc/gv-policy-studio-menu.js.map +1 -0
  458. package/wc/gv-policy-studio.d.ts +1 -0
  459. package/wc/gv-policy-studio.js +2 -1
  460. package/wc/gv-policy-studio.js.map +1 -0
  461. package/wc/gv-popover.d.ts +1 -0
  462. package/wc/gv-popover.js +2 -1
  463. package/wc/gv-popover.js.map +1 -0
  464. package/wc/gv-promote.d.ts +1 -0
  465. package/wc/gv-promote.js +2 -1
  466. package/wc/gv-promote.js.map +1 -0
  467. package/wc/gv-properties.d.ts +1 -0
  468. package/wc/gv-properties.js +2 -1
  469. package/wc/gv-properties.js.map +1 -0
  470. package/wc/gv-rating-list.d.ts +1 -0
  471. package/wc/gv-rating-list.js +2 -1
  472. package/wc/gv-rating-list.js.map +1 -0
  473. package/wc/gv-rating.d.ts +1 -0
  474. package/wc/gv-rating.js +2 -1
  475. package/wc/gv-rating.js.map +1 -0
  476. package/wc/gv-relative-time.d.ts +1 -0
  477. package/wc/gv-relative-time.js +2 -1
  478. package/wc/gv-relative-time.js.map +1 -0
  479. package/wc/gv-resizable-views.d.ts +1 -0
  480. package/wc/gv-resizable-views.js +2 -1
  481. package/wc/gv-resizable-views.js.map +1 -0
  482. package/wc/gv-resources.d.ts +1 -0
  483. package/wc/gv-resources.js +2 -1
  484. package/wc/gv-resources.js.map +1 -0
  485. package/wc/gv-row-expandable.d.ts +1 -0
  486. package/wc/gv-row-expandable.js +2 -1
  487. package/wc/gv-row-expandable.js.map +1 -0
  488. package/wc/gv-row.d.ts +1 -0
  489. package/wc/gv-row.js +2 -1
  490. package/wc/gv-row.js.map +1 -0
  491. package/wc/gv-schema-form-array.d.ts +1 -0
  492. package/wc/gv-schema-form-array.js +2 -1
  493. package/wc/gv-schema-form-array.js.map +1 -0
  494. package/wc/gv-schema-form-control-object.d.ts +1 -0
  495. package/wc/gv-schema-form-control-object.js +2 -1
  496. package/wc/gv-schema-form-control-object.js.map +1 -0
  497. package/wc/gv-schema-form-control.d.ts +1 -0
  498. package/wc/gv-schema-form-control.js +2 -1
  499. package/wc/gv-schema-form-control.js.map +1 -0
  500. package/wc/gv-schema-form.d.ts +1 -0
  501. package/wc/gv-schema-form.js +2 -1
  502. package/wc/gv-schema-form.js.map +1 -0
  503. package/wc/gv-select-native.d.ts +1 -0
  504. package/wc/gv-select-native.js +2 -1
  505. package/wc/gv-select-native.js.map +1 -0
  506. package/wc/gv-select.d.ts +1 -0
  507. package/wc/gv-select.js +2 -1
  508. package/wc/gv-select.js.map +1 -0
  509. package/wc/gv-spinner.d.ts +1 -0
  510. package/wc/gv-spinner.js +2 -1
  511. package/wc/gv-spinner.js.map +1 -0
  512. package/wc/gv-state.d.ts +1 -0
  513. package/wc/gv-state.js +2 -1
  514. package/wc/gv-state.js.map +1 -0
  515. package/wc/gv-stats.d.ts +1 -0
  516. package/wc/gv-stats.js +2 -1
  517. package/wc/gv-stats.js.map +1 -0
  518. package/wc/gv-stepper.d.ts +1 -0
  519. package/wc/gv-stepper.js +2 -1
  520. package/wc/gv-stepper.js.map +1 -0
  521. package/wc/gv-switch.d.ts +1 -0
  522. package/wc/gv-switch.js +2 -1
  523. package/wc/gv-switch.js.map +1 -0
  524. package/wc/gv-table.d.ts +1 -0
  525. package/wc/gv-table.js +2 -1
  526. package/wc/gv-table.js.map +1 -0
  527. package/wc/gv-tabs.d.ts +1 -0
  528. package/wc/gv-tabs.js +2 -1
  529. package/wc/gv-tabs.js.map +1 -0
  530. package/wc/gv-tag.d.ts +1 -0
  531. package/wc/gv-tag.js +2 -1
  532. package/wc/gv-tag.js.map +1 -0
  533. package/wc/gv-text.d.ts +1 -0
  534. package/wc/gv-text.js +2 -1
  535. package/wc/gv-text.js.map +1 -0
  536. package/wc/gv-theme.d.ts +1 -0
  537. package/wc/gv-theme.js +2 -1
  538. package/wc/gv-theme.js.map +1 -0
  539. package/wc/gv-tree.d.ts +1 -0
  540. package/wc/gv-tree.js +2 -1
  541. package/wc/gv-tree.js.map +1 -0
  542. package/wc/gv-user-menu.d.ts +1 -0
  543. package/wc/gv-user-menu.js +2 -1
  544. package/wc/gv-user-menu.js.map +1 -0
  545. package/wc/gv-vertical-menu.d.ts +1 -0
  546. package/wc/gv-vertical-menu.js +2 -1
  547. package/wc/gv-vertical-menu.js.map +1 -0
@@ -68,1714 +68,1646 @@ const FLOW_STEP_FORM_ID = 'flow-step-form';
68
68
  * @attr {Object} debugResponse - true if debug tab should be displayed
69
69
  * @attr {Boolean} has-conditional-steps - true if steps can be conditioned
70
70
  */
71
-
72
71
  export class GvPolicyStudio extends KeyboardElement(LitElement) {
73
- static get properties() {
74
- return {
75
- policies: {
76
- type: Array
77
- },
78
- services: {
79
- type: Object
80
- },
81
- resourceTypes: {
82
- type: Array,
83
- attribute: 'resource-types'
84
- },
85
- propertyProviders: {
86
- type: Array,
87
- attribute: 'property-providers'
88
- },
89
- dynamicPropertySchema: {
90
- type: Object,
91
- attribute: 'dynamic-property-schema'
92
- },
93
- tabId: {
94
- type: String,
95
- attribute: 'tab-id'
96
- },
97
- _tabId: {
98
- type: String,
99
- attribute: false
100
- },
101
- definition: {
102
- type: Object
103
- },
104
- _definition: {
105
- type: Object,
106
- attribute: false
107
- },
108
- documentation: {
109
- type: Object
110
- },
111
- flowSchema: {
112
- type: Object,
113
- attribute: 'flow-schema'
114
- },
115
- configurationSchema: {
116
- type: Object,
117
- attribute: 'configuration-schema'
118
- },
119
- _configurationSchema: {
120
- type: Object,
121
- attribute: false
122
- },
123
- configurationInformation: {
124
- type: String,
125
- attribute: 'configuration-information'
126
- },
127
- isDirty: {
128
- type: Boolean,
129
- attribute: 'dirty',
130
- reflect: true
131
- },
132
- _dragPolicy: {
133
- type: Object,
134
- attribute: false
135
- },
136
- _dropPolicy: {
137
- type: Object,
138
- attribute: false
139
- },
140
- selectedFlowsId: {
141
- type: Array,
142
- attribute: 'selected-flows-id'
143
- },
144
- _selectedFlowsId: {
145
- type: Array,
146
- attribute: false
147
- },
148
- _currentPolicyId: {
149
- type: String,
150
- attribute: false
151
- },
152
- _searchPolicyQuery: {
153
- type: String,
154
- attribute: false
155
- },
156
- _searchFlowQuery: {
157
- type: String,
158
- attribute: false
159
- },
160
- _flowStepSchema: {
161
- type: Object,
162
- attribute: false
163
- },
164
- _currentFlowStep: {
165
- type: Object,
166
- attribute: false
167
- },
168
- _policyFilter: {
169
- type: Array,
170
- attribute: false
171
- },
172
- _flowFilter: {
173
- type: Array,
174
- attribute: false
175
- },
176
- _currentAskConfirmation: {
177
- type: Boolean,
178
- attribute: false
179
- },
180
- hasProperties: {
181
- type: Boolean,
182
- attribute: 'has-properties'
183
- },
184
- _hasProperties: {
185
- type: Boolean,
186
- attribute: false
187
- },
188
- hasResources: {
189
- type: Boolean,
190
- attribute: 'has-resources'
191
- },
192
- hasPolicyFilter: {
193
- type: Boolean,
194
- attribute: 'has-policy-filter'
195
- },
196
- flowsTitle: {
197
- type: String,
198
- attribute: 'flows-title'
199
- },
200
- sortable: {
201
- type: Boolean
202
- },
203
- canAdd: {
204
- type: Boolean,
205
- attribute: 'can-add'
206
- },
207
- readonly: {
208
- type: Boolean
209
- },
210
- readonlyPlans: {
211
- type: Boolean,
212
- attribute: 'readonly-plans'
213
- },
214
- canDebug: {
215
- type: Boolean,
216
- attribute: 'can-debug'
217
- },
218
- _canDebug: {
219
- type: Boolean,
220
- attribute: false
221
- },
222
- debugResponse: {
223
- type: Object,
224
- attribute: 'debug-response'
225
- },
226
- hasConditionalSteps: {
227
- type: Boolean,
228
- attribute: 'has-conditional-steps'
229
- }
230
- };
231
- }
232
-
233
- static get styles() {
234
- return [empty, methods, // language=CSS
235
- css`:host{box-sizing:border-box;--height:var(--gv-policy-studio--h, calc(100vh - 32px));height:var(--height);--height-in-tabs:calc(var(--height) - 25px)}.box{height:var(--height);display:flex}.design,.properties{display:flex}gv-resizable-views{width:100%}.editable-name{padding:.5rem 1rem;font-size:16px}.editable-name span{color:#bfbfbf;font-size:12px}.form__control{margin:.5rem}gv-input{width:100%}.flow-name{display:flex;align-items:center}.flow-name.dirty{font-style:italic;opacity:.8}.flow-name gv-icon{--gv-icon--s:24px;margin-right:.2rem}.flow-path{margin-left:.2rem}.title_methods{margin-left:.5rem}.two-cols{display:flex;width:100%;height:100%}.two-cols>*{flex:1}.left-menu{border-left:1px solid #d9d9d9;height:var(--height-in-tabs)}.right-menu{border-right:1px solid #d9d9d9;height:var(--height-in-tabs)}.two-cols>:first-child{border-right:1px solid #d9d9d9}.flow-step__container{overflow:hidden;position:relative;overflow:hidden;height:99%}.flow-step__form{padding:0 .5rem;overflow:auto}.flow-step__form-title{text-transform:uppercase;letter-spacing:.2rem}gv-tabs{width:100%;height:100%;display:inline-block}gv-properties,gv-resizable-views,gv-resources{height:var(--height-in-tabs)}gv-properties,gv-resources{width:100%}gv-properties.properties{--gv-properties-table--colmg:10px}.api-settings{display:flex;flex-direction:column;border-left:1px solid #bfbfbf;height:var(--height-in-tabs)}.debug{display:flex;flex-direction:column;border-left:1px solid #bfbfbf;height:var(--height-in-tabs)}.api-settings-information{display:flex;align-items:center}.api-settings-information__icon{--gv-icon--c:var(--gv-theme-color, #5a7684);--gv-icon-opacity--c:var(--gv-theme-color-info-light, #64b5f6)}.api-settings-information__blockquote,.debug-information__blockquote{border-left:1px solid var(--gv-theme-color,#5a7684);margin:15px;padding-left:15px;font-size:14px}.flow-settings gv-schema-form{flex:1;padding:.5rem}.search{display:flex;justify-content:stretch}gv-input{margin:.2rem 0;width:100%}.header-actions,.search-policies{display:flex;flex-direction:column;align-items:center;margin:.5rem}.search-policies{margin:1.5rem .5rem .5rem}.footer-actions>gv-button.btn-large,.footer-actions>gv-option{width:100%}.footer-actions{display:flex;flex-direction:column;align-items:center;padding:.5rem 0;margin:.5rem 15px;border-top:1px solid #bfbfbf}.header-actions .title{text-transform:uppercase;text-align:center;letter-spacing:.3rem;color:#bfbfbf;font-size:18px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:240px;min-height:25px}.header-actions>*,.search-policies>*{margin-bottom:1rem}`];
236
- }
237
-
238
- constructor() {
239
- super();
240
- this.isDirty = false;
241
- this.policies = [];
242
- this.resourceTypes = [];
243
- this.tabId = 'design';
244
- this.selectedFlowsId = [];
245
- this.flowsTitle = 'Flows';
246
- this.sortable = false;
247
- this.services = {};
248
- this._definition = {
249
- flows: []
250
- };
251
- this._tabs = [{
252
- id: 'design',
253
- title: 'Design',
254
- icon: 'navigation:exchange'
255
- }];
256
- this._policyFilter = [];
257
- this._flowFilter = [];
258
- }
259
-
260
- set hasProperties(value) {
261
- if (value) {
262
- import('../organisms/gv-properties').then(() => {
263
- this._tabs = [...this._tabs, {
264
- id: 'properties',
265
- title: 'Properties',
266
- icon: 'general:settings#1'
267
- }];
268
- this.requestUpdate();
269
- });
270
- }
271
-
272
- this._hasProperties = value;
273
- }
274
-
275
- get hasProperties() {
276
- return this._hasProperties;
277
- }
278
-
279
- set hasResources(value) {
280
- if (value) {
281
- import('../organisms/gv-resources').then(() => {
282
- this._tabs = [...this._tabs, {
283
- id: 'resources',
284
- title: 'Resources',
285
- icon: 'general:settings#5'
286
- }];
287
- this.requestUpdate();
288
- });
289
- }
290
- }
291
-
292
- set canDebug(value) {
293
- if (value) {
294
- this._tabs = [...this._tabs, {
295
- id: 'debug',
296
- title: 'Try it',
297
- icon: 'content:send'
298
- }];
299
- }
300
- }
301
-
302
- get _flowFilterOptions() {
303
- if (this.definedPlans.length > 0) {
304
- return [{
305
- id: 'api',
306
- title: 'Api',
307
- icon: 'shopping:box#3'
308
- }, {
309
- id: 'plan',
310
- title: 'Plans',
311
- icon: 'shopping:sale#2'
312
- }];
313
- }
314
- }
315
-
316
- set hasPolicyFilter(value) {
317
- if (value) {
318
- this._policyFilterOptions = [{
319
- id: 'onRequest',
320
- title: 'Request',
321
- icon: 'navigation:arrow-from-left'
322
- }, {
323
- id: 'onResponse',
324
- title: 'Response',
325
- icon: 'navigation:arrow-from-right'
326
- }];
327
- }
328
- }
329
-
330
- set configurationSchema(value) {
331
- if (value) {
332
- this._tabs.splice(1, 0, {
333
- id: 'settings',
334
- title: 'Configuration',
335
- icon: 'general:settings#2'
336
- });
72
+ static get properties() {
73
+ return {
74
+ policies: { type: Array },
75
+ services: { type: Object },
76
+ resourceTypes: { type: Array, attribute: 'resource-types' },
77
+ propertyProviders: { type: Array, attribute: 'property-providers' },
78
+ dynamicPropertySchema: { type: Object, attribute: 'dynamic-property-schema' },
79
+ tabId: { type: String, attribute: 'tab-id' },
80
+ _tabId: { type: String, attribute: false },
81
+ definition: { type: Object },
82
+ _definition: { type: Object, attribute: false },
83
+ documentation: { type: Object },
84
+ flowSchema: { type: Object, attribute: 'flow-schema' },
85
+ configurationSchema: { type: Object, attribute: 'configuration-schema' },
86
+ _configurationSchema: { type: Object, attribute: false },
87
+ configurationInformation: { type: String, attribute: 'configuration-information' },
88
+ isDirty: { type: Boolean, attribute: 'dirty', reflect: true },
89
+ _dragPolicy: { type: Object, attribute: false },
90
+ _dropPolicy: { type: Object, attribute: false },
91
+ selectedFlowsId: { type: Array, attribute: 'selected-flows-id' },
92
+ _selectedFlowsId: { type: Array, attribute: false },
93
+ _currentPolicyId: { type: String, attribute: false },
94
+ _searchPolicyQuery: { type: String, attribute: false },
95
+ _searchFlowQuery: { type: String, attribute: false },
96
+ _flowStepSchema: { type: Object, attribute: false },
97
+ _currentFlowStep: { type: Object, attribute: false },
98
+ _policyFilter: { type: Array, attribute: false },
99
+ _flowFilter: { type: Array, attribute: false },
100
+ _currentAskConfirmation: { type: Boolean, attribute: false },
101
+ hasProperties: { type: Boolean, attribute: 'has-properties' },
102
+ _hasProperties: { type: Boolean, attribute: false },
103
+ hasResources: { type: Boolean, attribute: 'has-resources' },
104
+ hasPolicyFilter: { type: Boolean, attribute: 'has-policy-filter' },
105
+ flowsTitle: { type: String, attribute: 'flows-title' },
106
+ sortable: { type: Boolean },
107
+ canAdd: { type: Boolean, attribute: 'can-add' },
108
+ readonly: { type: Boolean },
109
+ readonlyPlans: { type: Boolean, attribute: 'readonly-plans' },
110
+ canDebug: { type: Boolean, attribute: 'can-debug' },
111
+ _canDebug: { type: Boolean, attribute: false },
112
+ debugResponse: { type: Object, attribute: 'debug-response' },
113
+ hasConditionalSteps: { type: Boolean, attribute: 'has-conditional-steps' },
114
+ };
337
115
  }
116
+ static get styles() {
117
+ return [
118
+ empty,
119
+ methods,
120
+ // language=CSS
121
+ css `
122
+ :host {
123
+ box-sizing: border-box;
124
+ --height: var(--gv-policy-studio--h, calc(100vh - 32px));
125
+ height: var(--height);
126
+ --height-in-tabs: calc(var(--height) - 25px);
127
+ }
338
128
 
339
- this._configurationSchema = value;
340
- }
341
-
342
- get configurationSchema() {
343
- return this._configurationSchema;
344
- }
345
-
346
- onKeyboard() {
347
- if (this._currentAskConfirmation == null) {
348
- if (this.isPressed(KEYS.Shift, KEYS.Ctrl, KEYS.Space)) {
349
- const search = this.shadowRoot.querySelector('#search-policy');
129
+ .box {
130
+ height: var(--height);
131
+ display: flex;
132
+ }
350
133
 
351
- if (search) {
352
- search.focus();
134
+ .design,
135
+ .properties {
136
+ display: flex;
353
137
  }
354
- } else if (this.isPressed(KEYS.Ctrl, KEYS.Space)) {
355
- const search = this.shadowRoot.querySelector('#search-flow');
356
138
 
357
- if (search) {
358
- search.focus();
139
+ gv-resizable-views {
140
+ width: 100%;
359
141
  }
360
- }
361
- }
362
- }
363
142
 
364
- set tabId(tabId) {
365
- if (tabId != null && ['design', 'settings', 'properties', 'resources', 'debug'].includes(tabId)) {
366
- this._tabId = tabId;
367
- } else {
368
- this._tabId = 'design';
369
- }
370
- }
143
+ .editable-name {
144
+ padding: 0.5rem 1rem;
145
+ font-size: 16px;
146
+ }
371
147
 
372
- get tabId() {
373
- return this._tabId;
374
- }
148
+ .editable-name span {
149
+ color: #bfbfbf;
150
+ font-size: 12px;
151
+ }
375
152
 
376
- set definition(definition) {
377
- if (definition) {
378
- const flows = this._generateFlowsId(definition.flows);
153
+ .form__control {
154
+ margin: 0.5rem;
155
+ }
379
156
 
380
- const resources = this._generateId('resource-', definition.resources);
157
+ gv-input {
158
+ width: 100%;
159
+ }
381
160
 
382
- const plans = definition.plans == null ? [] : definition.plans.map(plan => {
383
- return { ...plan,
384
- flows: this._generatePlanFlowsId(plan)
385
- };
386
- });
387
- this._initialDefinition = { ...definition,
388
- flows,
389
- resources,
390
- plans
391
- };
392
- this._definition = deepClone(this._initialDefinition);
393
- this.isDirty = false;
161
+ .flow-name {
162
+ display: flex;
163
+ align-items: center;
164
+ }
394
165
 
395
- this._selectFirstFlow();
396
- }
397
- }
166
+ .flow-name.dirty {
167
+ font-style: italic;
168
+ opacity: 0.8;
169
+ }
398
170
 
399
- get definition() {
400
- return this._definition;
401
- }
171
+ .flow-name gv-icon {
172
+ --gv-icon--s: 24px;
173
+ margin-right: 0.2rem;
174
+ }
402
175
 
403
- set selectedFlowsId(selectedFlowsId) {
404
- if (selectedFlowsId != null && Array.isArray(selectedFlowsId)) {
405
- this._selectedFlowsId = selectedFlowsId.filter(id => this._findFlowById(id) != null);
176
+ .flow-path {
177
+ margin-left: 0.2rem;
178
+ }
406
179
 
407
- if (selectedFlowsId.length !== this._selectedFlowsId.length) {
408
- this._selectFirstFlow(true);
409
- }
410
- }
411
- }
180
+ .title_methods {
181
+ margin-left: 0.5rem;
182
+ }
412
183
 
413
- get selectedFlowsId() {
414
- return this._selectedFlowsId.filter(id => this._findFlowById(id) != null);
415
- }
184
+ .two-cols {
185
+ display: flex;
186
+ width: 100%;
187
+ height: 100%;
188
+ }
416
189
 
417
- _updateSelectedFlows(selectedFlowsId) {
418
- this.selectedFlowsId = selectedFlowsId;
419
- dispatchCustomEvent(this, 'select-flows', {
420
- flows: this.selectedFlowsId
421
- });
422
- }
190
+ .two-cols > * {
191
+ flex: 1;
192
+ }
423
193
 
424
- _selectFirstFlow(dispatch = false) {
425
- if (this.selectedFlowsId.length === 0) {
426
- let candidate = null;
194
+ .left-menu {
195
+ border-left: 1px solid #d9d9d9;
196
+ height: var(--height-in-tabs);
197
+ }
427
198
 
428
- if (this.definedFlows.length > 0 && this.definedFlows[0]._id != null) {
429
- candidate = this.definedFlows[0];
430
- } else if (this.definedPlans.length > 0) {
431
- const plan = this.definedPlans.find(plan => plan.flows != null && plan.flows.length > 0 && plan.flows[0]._id != null);
199
+ .right-menu {
200
+ border-right: 1px solid #d9d9d9;
201
+ height: var(--height-in-tabs);
202
+ }
432
203
 
433
- if (plan) {
434
- candidate = plan.flows[0];
204
+ .two-cols > *:first-child {
205
+ border-right: 1px solid #d9d9d9;
435
206
  }
436
- }
437
207
 
438
- if (candidate != null) {
439
- if (dispatch) {
440
- this._updateSelectedFlows([candidate._id]);
441
- } else {
442
- this.selectedFlowsId = [candidate._id];
208
+ .flow-step__container {
209
+ overflow: hidden;
210
+ position: relative;
211
+ overflow: hidden;
212
+ height: 99%;
443
213
  }
444
- }
445
- }
446
- }
447
214
 
448
- _getFlowElement(flowId) {
449
- return this.shadowRoot.querySelector(`[id="${flowId}"]`);
450
- }
215
+ .flow-step__form {
216
+ padding: 0 0.5rem;
217
+ overflow: auto;
218
+ }
451
219
 
452
- _onDragEndPolicy() {
453
- this.shadowRoot.querySelectorAll('gv-flow').forEach(e => e.onDragEnd());
454
- }
220
+ .flow-step__form-title {
221
+ text-transform: uppercase;
222
+ letter-spacing: 0.2rem;
223
+ }
455
224
 
456
- async _onDropPolicy({
457
- detail
458
- }) {
459
- try {
460
- await this._askToValidateForms();
461
- const policy = detail.policy;
225
+ gv-tabs {
226
+ width: 100%;
227
+ height: 100%;
228
+ display: inline-block;
229
+ }
462
230
 
463
- const targetFlow = this._findFlowById(detail.flowId);
231
+ gv-resizable-views,
232
+ gv-properties,
233
+ gv-resources {
234
+ height: var(--height-in-tabs);
235
+ }
464
236
 
465
- let name = policy.name;
466
- let description = '';
467
- let condition = '';
468
- let configuration = {};
237
+ gv-properties,
238
+ gv-resources {
239
+ width: 100%;
240
+ }
469
241
 
470
- let _id;
242
+ gv-properties.properties {
243
+ --gv-properties-table--colmg: 10px;
244
+ }
471
245
 
472
- let _new = false;
246
+ .api-settings {
247
+ display: flex;
248
+ flex-direction: column;
249
+ border-left: 1px solid #bfbfbf;
250
+ height: var(--height-in-tabs);
251
+ }
473
252
 
474
- if (detail.flowStep) {
475
- _id = detail.flowStep._id;
476
- name = detail.flowStep.name;
477
- description = detail.flowStep.description || '';
478
- condition = detail.flowStep.condition || '';
479
- configuration = detail.flowStep.configuration;
480
- } else {
481
- _id = this._generateFlowStepId(targetFlow._id, detail.flowKey, detail.position);
482
- _new = true;
483
- }
253
+ .debug {
254
+ display: flex;
255
+ flex-direction: column;
256
+ border-left: 1px solid #bfbfbf;
257
+ height: var(--height-in-tabs);
258
+ }
484
259
 
485
- const flowStep = {
486
- _id,
487
- _new,
488
- name,
489
- policy: policy.id,
490
- description,
491
- condition,
492
- enabled: true,
493
- configuration
494
- };
495
- const sourceFlow = detail.sourceFlowId != null ? this._findFlowById(detail.sourceFlowId) : targetFlow;
260
+ .api-settings-information {
261
+ display: flex;
262
+ align-items: center;
263
+ }
496
264
 
497
- if (detail.sourcePosition != null) {
498
- if (detail.sourceFlowKey && detail.sourceFlowKey !== detail.flowKey) {
499
- sourceFlow[detail.sourceFlowKey].splice(detail.sourcePosition, 1);
500
- targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
265
+ .api-settings-information__icon {
266
+ --gv-icon--c: var(--gv-theme-color, #5a7684);
267
+ --gv-icon-opacity--c: var(--gv-theme-color-info-light, #64b5f6);
268
+ }
501
269
 
502
- if (this._currentFlowStep != null && this._currentFlowStep.step._id === _id) {
503
- this._currentFlowStep.group = detail.flowKey; // Special case for update schema after change request to response or inverse
270
+ .api-settings-information__blockquote,
271
+ .debug-information__blockquote {
272
+ border-left: 1px solid var(--gv-theme-color, #5a7684);
273
+ margin: 15px;
274
+ padding-left: 15px;
275
+ font-size: 14px;
276
+ }
504
277
 
505
- const schema = this.buildSchema(this._currentFlowStep.policy);
506
- await this._setCurrentFlowStep(this._currentFlowStep, schema, true);
278
+ .flow-settings gv-schema-form {
279
+ flex: 1;
280
+ padding: 0.5rem;
281
+ }
507
282
 
508
- this._getFlowElement(targetFlow._id).requestUpdate();
509
- }
510
- } else {
511
- if (detail.position > detail.sourcePosition) {
512
- targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
513
- sourceFlow[detail.flowKey].splice(detail.sourcePosition, 1);
514
- } else {
515
- sourceFlow[detail.flowKey].splice(detail.sourcePosition, 1);
516
- targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
517
- }
518
- } // Force Refresh source flow element when move to other flow
283
+ .search {
284
+ display: flex;
285
+ justify-content: stretch;
286
+ }
519
287
 
288
+ gv-input {
289
+ margin: 0.2rem 0;
290
+ width: 100%;
291
+ }
520
292
 
521
- if (targetFlow._id !== sourceFlow._id) {
522
- this._getFlowElement(targetFlow._id).requestUpdate();
293
+ .header-actions,
294
+ .search-policies {
295
+ display: flex;
296
+ flex-direction: column;
297
+ align-items: center;
298
+ margin: 0.5rem;
523
299
  }
524
- } else {
525
- targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
526
300
 
527
- const currentFlowForm = this._getFlowStepForm();
301
+ .search-policies {
302
+ margin: 1.5rem 0.5rem 0.5rem;
303
+ }
528
304
 
529
- if (currentFlowForm == null || currentFlowForm.dirty !== true) {
530
- let step = targetFlow[detail.flowKey][detail.position];
305
+ .footer-actions > gv-button.btn-large,
306
+ .footer-actions > gv-option {
307
+ width: 100%;
308
+ }
531
309
 
532
- if (step == null) {
533
- // When confirm lose change after drop policy
534
- step = targetFlow[detail.flowKey][detail.position - 1];
535
- }
310
+ .footer-actions {
311
+ display: flex;
312
+ flex-direction: column;
313
+ align-items: center;
314
+ padding: 0.5rem 0;
315
+ margin: 0.5rem 15px;
316
+ border-top: 1px solid #bfbfbf;
317
+ }
536
318
 
537
- if (detail.cancelEdit !== true) {
538
- setTimeout(async () => {
539
- await this._editFlowStep({
540
- step,
541
- policy,
542
- flow: targetFlow,
543
- group: detail.flowKey
544
- });
545
- this.updateComplete.then(() => {
546
- const flowElement = this._getFlowElement(targetFlow._id);
319
+ .header-actions .title {
320
+ text-transform: uppercase;
321
+ text-align: center;
322
+ letter-spacing: 0.3rem;
323
+ color: #bfbfbf;
324
+ font-size: 18px;
325
+ white-space: nowrap;
326
+ overflow: hidden;
327
+ text-overflow: ellipsis;
328
+ width: 240px;
329
+ min-height: 25px;
330
+ }
547
331
 
548
- flowElement.selectedStepId = step._id;
549
- flowElement.requestUpdate();
550
- });
332
+ .header-actions > *,
333
+ .search-policies > * {
334
+ margin-bottom: 1rem;
335
+ }
336
+ `,
337
+ ];
338
+ }
339
+ constructor() {
340
+ super();
341
+ this.isDirty = false;
342
+ this.policies = [];
343
+ this.resourceTypes = [];
344
+ this.tabId = 'design';
345
+ this.selectedFlowsId = [];
346
+ this.flowsTitle = 'Flows';
347
+ this.sortable = false;
348
+ this.services = {};
349
+ this._definition = {
350
+ flows: [],
351
+ };
352
+ this._tabs = [{ id: 'design', title: 'Design', icon: 'navigation:exchange' }];
353
+ this._policyFilter = [];
354
+ this._flowFilter = [];
355
+ }
356
+ set hasProperties(value) {
357
+ if (value) {
358
+ import('../organisms/gv-properties').then(() => {
359
+ this._tabs = [...this._tabs, { id: 'properties', title: 'Properties', icon: 'general:settings#1' }];
360
+ this.requestUpdate();
551
361
  });
552
- }
553
362
  }
554
- }
555
-
556
- targetFlow._dirty = true;
557
- sourceFlow._dirty = true;
558
- this.isDirty = true;
559
- this.shadowRoot.querySelectorAll('gv-flow').forEach(gvFlow => gvFlow.removeCandidate());
560
- setTimeout(() => {
561
- this._dragPolicy = null;
562
- this._dropPolicy = null;
563
- }, 0);
564
- } catch (e) {
565
- this._currentAskConfirmation = null;
566
- }
567
- }
568
-
569
- _onDeletePolicy({
570
- detail
571
- }) {
572
- const targetFlow = this._findFlowById(detail.flowId);
573
-
574
- targetFlow[detail.flowKey].splice(detail.position, 1);
575
- targetFlow._dirty = true;
576
- this.isDirty = true;
577
-
578
- if (detail.target.editing) {
579
- this._closeFlowStepForm(true);
363
+ this._hasProperties = value;
580
364
  }
581
-
582
- this._getFlowElement(detail.flowId).requestUpdate();
583
- }
584
-
585
- _onDesign() {
586
- this._changeTab('design');
587
-
588
- this._splitMainViews();
589
- }
590
-
591
- buildSchema({
592
- schema
593
- }) {
594
- const commonDescription = {
595
- title: 'Description',
596
- description: 'Description of flow step',
597
- type: 'string'
598
- };
599
- const commonCondition = {
600
- title: 'Condition',
601
- description: 'Condition the execution of the flow step (support EL)',
602
- type: 'string',
603
- 'x-schema-form': {
604
- 'expression-language': true
605
- }
606
- };
607
-
608
- if (schema) {
609
- const jsonSchema = typeof schema === 'string' ? JSON.parse(schema) : schema;
610
- const properties = {
611
- commonDescription,
612
- ...(this.hasConditionalSteps ? {
613
- commonCondition
614
- } : {}),
615
- ...jsonSchema.properties
616
- };
617
- return { ...jsonSchema,
618
- properties
619
- };
365
+ get hasProperties() {
366
+ return this._hasProperties;
620
367
  }
621
-
622
- return {
623
- properties: {
624
- commonDescription,
625
- ...(this.hasConditionalSteps ? {
626
- commonCondition
627
- } : {})
628
- }
629
- };
630
- }
631
-
632
- async _editFlowStep({
633
- step,
634
- flow,
635
- policy,
636
- group
637
- }) {
638
- if (step) {
639
- this._currentPolicyId = policy.id;
640
- const currentFlowStep = {
641
- flow,
642
- step,
643
- policy,
644
- group
645
- };
646
- const schema = this.buildSchema(policy);
647
-
648
- try {
649
- await this._setCurrentFlowStep(currentFlowStep, schema);
650
-
651
- this._updateSelectedFlows([flow._id]);
652
-
653
- this._splitMainViews();
654
-
655
- if (localStorage.getItem('gv-policy-studio:keep-documentation-close') == null) {
656
- this._onOpenDocumentation();
657
- }
658
- } catch (e) {
659
- this._currentAskConfirmation = null;
660
- }
661
- } else {
662
- await this._closeFlowStepForm();
663
-
664
- this._maximizeTopView();
368
+ set hasResources(value) {
369
+ if (value) {
370
+ import('../organisms/gv-resources').then(() => {
371
+ this._tabs = [...this._tabs, { id: 'resources', title: 'Resources', icon: 'general:settings#5' }];
372
+ this.requestUpdate();
373
+ });
374
+ }
665
375
  }
666
- }
667
-
668
- async _onEditFlowStep({
669
- detail: {
670
- step,
671
- flow,
672
- policy,
673
- group
674
- }
675
- }) {
676
- return this._editFlowStep({
677
- step,
678
- flow,
679
- policy,
680
- group
681
- });
682
- }
683
-
684
- _getResizableViews() {
685
- return this.shadowRoot.querySelector('gv-resizable-views');
686
- }
687
-
688
- _maximizeTopView() {
689
- if (this.selectedFlowsId.length <= 1) {
690
- this._getResizableViews().maximizeTop();
376
+ set canDebug(value) {
377
+ if (value) {
378
+ this._tabs = [...this._tabs, { id: 'debug', title: 'Try it', icon: 'content:send' }];
379
+ }
691
380
  }
692
- }
693
-
694
- _maximizeBottomView() {
695
- this._getResizableViews().maximizeBottom();
696
- }
697
-
698
- _splitMainViews() {
699
- this._getResizableViews().split();
700
- }
701
-
702
- _onChangeFlowStepState({
703
- detail
704
- }) {
705
- const targetFlow = this._findFlowById(detail.flowId);
706
-
707
- const step = targetFlow[detail.flowKey][detail.position];
708
- step.enabled = detail.enabled;
709
- targetFlow._dirty = true;
710
- this.isDirty = true;
711
- }
712
-
713
- async _onCloseFlowStepForm() {
714
- try {
715
- await this._closeFlowStepForm();
716
- } catch (err) {
717
- this._currentAskConfirmation = null;
381
+ get _flowFilterOptions() {
382
+ if (this.definedPlans.length > 0) {
383
+ return [
384
+ { id: 'api', title: 'Api', icon: 'shopping:box#3' },
385
+ { id: 'plan', title: 'Plans', icon: 'shopping:sale#2' },
386
+ ];
387
+ }
718
388
  }
719
- }
720
-
721
- async _closeFlowStepForm(force = false) {
722
- await this._setCurrentFlowStep(null, null, force);
723
- }
724
-
725
- async _askToValidateForms() {
726
- if (this._currentAskConfirmation == null) {
727
- this._currentAskConfirmation = true;
728
- return Promise.all(this._submitOrConfirmForms()).then(forms => {
729
- if (forms.filter(r => r != null).length > 0) {
730
- this._definition = this._buildDefinitionToSave();
731
- this.getChildren().forEach(e => e.requestUpdate()); // Refresh if lose changes lost current step selection
732
-
733
- return this._checkCurrentFlowStep().then(() => {
734
- this.getChildren().forEach(e => e.requestUpdate());
735
- return this.updateComplete.then(() => {
736
- this._currentAskConfirmation = null;
737
- return forms;
738
- });
739
- });
740
- } else {
741
- this._currentAskConfirmation = null;
742
- return forms;
389
+ set hasPolicyFilter(value) {
390
+ if (value) {
391
+ this._policyFilterOptions = [
392
+ { id: 'onRequest', title: 'Request', icon: 'navigation:arrow-from-left' },
393
+ { id: 'onResponse', title: 'Response', icon: 'navigation:arrow-from-right' },
394
+ ];
743
395
  }
744
- });
745
396
  }
746
-
747
- throw new Error('ask already waiting');
748
- }
749
-
750
- async _setCurrentFlowStep(currentFlowStep, flowStepSchema, force = false) {
751
- if (!force) {
752
- await this._askToValidateForms();
397
+ set configurationSchema(value) {
398
+ if (value) {
399
+ this._tabs.splice(1, 0, { id: 'settings', title: 'Configuration', icon: 'general:settings#2' });
400
+ }
401
+ this._configurationSchema = value;
402
+ }
403
+ get configurationSchema() {
404
+ return this._configurationSchema;
405
+ }
406
+ onKeyboard() {
407
+ if (this._currentAskConfirmation == null) {
408
+ if (this.isPressed(KEYS.Shift, KEYS.Ctrl, KEYS.Space)) {
409
+ const search = this.shadowRoot.querySelector('#search-policy');
410
+ if (search) {
411
+ search.focus();
412
+ }
413
+ }
414
+ else if (this.isPressed(KEYS.Ctrl, KEYS.Space)) {
415
+ const search = this.shadowRoot.querySelector('#search-flow');
416
+ if (search) {
417
+ search.focus();
418
+ }
419
+ }
420
+ }
753
421
  }
754
-
755
- const schema = deepClone(flowStepSchema);
756
-
757
- if (currentFlowStep != null) {
758
- const configuration = typeof currentFlowStep.step.configuration === 'string' ? JSON.parse(currentFlowStep.step.configuration) : currentFlowStep.step.configuration;
759
- const step = { ...currentFlowStep.step,
760
- configuration
761
- };
762
- const _initialValues = { ...step.configuration,
763
- commonDescription: step.description,
764
- commonCondition: step.condition
765
- };
766
- this._currentFlowStep = { ...currentFlowStep,
767
- step,
768
- _initialValues
769
- };
770
-
771
- if (flowStepSchema && flowStepSchema.properties.scope) {
772
- const _enum = schema.properties.scope.enum;
773
-
774
- if (_enum.find(scope => ['REQUEST', 'REQUEST_CONTENT', 'RESPONSE', 'RESPONSE_CONTENT'].includes(scope)) != null) {
775
- const filtered = this._currentFlowStep.group === 'pre' ? ['REQUEST', 'REQUEST_CONTENT'] : ['RESPONSE', 'RESPONSE_CONTENT'];
776
- schema.properties.scope.enum = _enum.filter(scope => filtered.includes(scope));
777
- const scope = this._currentFlowStep.step.configuration.scope;
778
-
779
- if (scope == null || !schema.properties.scope.enum.includes(scope)) {
780
- schema.properties.scope.default = schema.properties.scope.enum[0];
781
- this._currentFlowStep.step.configuration.scope = schema.properties.scope.enum[0];
782
- this._currentFlowStep._initialValues.scope = schema.properties.scope.enum[0];
783
-
784
- if (this._currentFlowStep._values) {
785
- this._currentFlowStep._values.scope = schema.properties.scope.enum[0];
422
+ set tabId(tabId) {
423
+ if (tabId != null && ['design', 'settings', 'properties', 'resources', 'debug'].includes(tabId)) {
424
+ this._tabId = tabId;
425
+ }
426
+ else {
427
+ this._tabId = 'design';
428
+ }
429
+ }
430
+ get tabId() {
431
+ return this._tabId;
432
+ }
433
+ set definition(definition) {
434
+ if (definition) {
435
+ const flows = this._generateFlowsId(definition.flows);
436
+ const resources = this._generateId('resource-', definition.resources);
437
+ const plans = definition.plans == null
438
+ ? []
439
+ : definition.plans.map((plan) => {
440
+ return { ...plan, flows: this._generatePlanFlowsId(plan) };
441
+ });
442
+ this._initialDefinition = { ...definition, flows, resources, plans };
443
+ this._definition = deepClone(this._initialDefinition);
444
+ this.isDirty = false;
445
+ this._selectFirstFlow();
446
+ }
447
+ }
448
+ get definition() {
449
+ return this._definition;
450
+ }
451
+ set selectedFlowsId(selectedFlowsId) {
452
+ if (selectedFlowsId != null && Array.isArray(selectedFlowsId)) {
453
+ this._selectedFlowsId = selectedFlowsId.filter((id) => this._findFlowById(id) != null);
454
+ if (selectedFlowsId.length !== this._selectedFlowsId.length) {
455
+ this._selectFirstFlow(true);
786
456
  }
787
- }
788
457
  }
789
- }
790
- } else {
791
- this._currentFlowStep = null;
792
458
  }
793
-
794
- this._flowStepSchema = schema;
795
- }
796
-
797
- _refresh(closeStepForm = true) {
798
- if (closeStepForm) {
799
- this._closeFlowStepForm(true);
459
+ get selectedFlowsId() {
460
+ return this._selectedFlowsId.filter((id) => this._findFlowById(id) != null);
800
461
  }
801
-
802
- this._definition = deepClone(this._definition);
803
- }
804
-
805
- async _onSelectFlows({
806
- detail
807
- }) {
808
- try {
809
- await this._closeFlowStepForm();
810
-
811
- this._onCloseDocumentation();
812
-
813
- this._updateSelectedFlows(detail.flows);
814
-
815
- this._onDesign();
816
- } catch (e) {
817
- this._currentAskConfirmation = null;
462
+ _updateSelectedFlows(selectedFlowsId) {
463
+ this.selectedFlowsId = selectedFlowsId;
464
+ dispatchCustomEvent(this, 'select-flows', { flows: this.selectedFlowsId });
818
465
  }
819
- }
820
-
821
- async _onOpenDocumentationFromMenu({
822
- detail: {
823
- policy
824
- }
825
- }) {
826
- try {
827
- if (this.documentation == null || this.documentation.id !== policy.id) {
828
- await this._closeFlowStepForm();
829
- this._currentPolicyId = policy.id;
830
-
831
- if (this.getSelectedFlow()) {
832
- this._splitMainViews();
833
- } else {
834
- this._maximizeBottomView();
466
+ _selectFirstFlow(dispatch = false) {
467
+ if (this.selectedFlowsId.length === 0) {
468
+ let candidate = null;
469
+ if (this.definedFlows.length > 0 && this.definedFlows[0]._id != null) {
470
+ candidate = this.definedFlows[0];
471
+ }
472
+ else if (this.definedPlans.length > 0) {
473
+ const plan = this.definedPlans.find((plan) => plan.flows != null && plan.flows.length > 0 && plan.flows[0]._id != null);
474
+ if (plan) {
475
+ candidate = plan.flows[0];
476
+ }
477
+ }
478
+ if (candidate != null) {
479
+ if (dispatch) {
480
+ this._updateSelectedFlows([candidate._id]);
481
+ }
482
+ else {
483
+ this.selectedFlowsId = [candidate._id];
484
+ }
485
+ }
835
486
  }
836
-
837
- dispatchCustomEvent(this, 'fetch-documentation', {
838
- policy
839
- });
840
- }
841
- } catch (e) {}
842
- }
843
-
844
- _fetchDocumentation(policy) {
845
- if (this.documentation == null || this.documentation.id !== policy.id) {
846
- dispatchCustomEvent(this, 'fetch-documentation', {
847
- policy
848
- });
849
487
  }
850
- }
851
-
852
- _onOpenDocumentation() {
853
- if (this._currentFlowStep && this._currentFlowStep.policy) {
854
- this._fetchDocumentation(this._currentFlowStep.policy);
488
+ _getFlowElement(flowId) {
489
+ return this.shadowRoot.querySelector(`[id="${flowId}"]`);
490
+ }
491
+ _onDragEndPolicy() {
492
+ this.shadowRoot.querySelectorAll('gv-flow').forEach((e) => e.onDragEnd());
493
+ }
494
+ async _onDropPolicy({ detail }) {
495
+ try {
496
+ await this._askToValidateForms();
497
+ const policy = detail.policy;
498
+ const targetFlow = this._findFlowById(detail.flowId);
499
+ let name = policy.name;
500
+ let description = '';
501
+ let condition = '';
502
+ let configuration = {};
503
+ let _id;
504
+ let _new = false;
505
+ if (detail.flowStep) {
506
+ _id = detail.flowStep._id;
507
+ name = detail.flowStep.name;
508
+ description = detail.flowStep.description || '';
509
+ condition = detail.flowStep.condition || '';
510
+ configuration = detail.flowStep.configuration;
511
+ }
512
+ else {
513
+ _id = this._generateFlowStepId(targetFlow._id, detail.flowKey, detail.position);
514
+ _new = true;
515
+ }
516
+ const flowStep = { _id, _new, name, policy: policy.id, description, condition, enabled: true, configuration };
517
+ const sourceFlow = detail.sourceFlowId != null ? this._findFlowById(detail.sourceFlowId) : targetFlow;
518
+ if (detail.sourcePosition != null) {
519
+ if (detail.sourceFlowKey && detail.sourceFlowKey !== detail.flowKey) {
520
+ sourceFlow[detail.sourceFlowKey].splice(detail.sourcePosition, 1);
521
+ targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
522
+ if (this._currentFlowStep != null && this._currentFlowStep.step._id === _id) {
523
+ this._currentFlowStep.group = detail.flowKey;
524
+ // Special case for update schema after change request to response or inverse
525
+ const schema = this.buildSchema(this._currentFlowStep.policy);
526
+ await this._setCurrentFlowStep(this._currentFlowStep, schema, true);
527
+ this._getFlowElement(targetFlow._id).requestUpdate();
528
+ }
529
+ }
530
+ else {
531
+ if (detail.position > detail.sourcePosition) {
532
+ targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
533
+ sourceFlow[detail.flowKey].splice(detail.sourcePosition, 1);
534
+ }
535
+ else {
536
+ sourceFlow[detail.flowKey].splice(detail.sourcePosition, 1);
537
+ targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
538
+ }
539
+ }
540
+ // Force Refresh source flow element when move to other flow
541
+ if (targetFlow._id !== sourceFlow._id) {
542
+ this._getFlowElement(targetFlow._id).requestUpdate();
543
+ }
544
+ }
545
+ else {
546
+ targetFlow[detail.flowKey].splice(detail.position, 0, flowStep);
547
+ const currentFlowForm = this._getFlowStepForm();
548
+ if (currentFlowForm == null || currentFlowForm.dirty !== true) {
549
+ let step = targetFlow[detail.flowKey][detail.position];
550
+ if (step == null) {
551
+ // When confirm lose change after drop policy
552
+ step = targetFlow[detail.flowKey][detail.position - 1];
553
+ }
554
+ if (detail.cancelEdit !== true) {
555
+ setTimeout(async () => {
556
+ await this._editFlowStep({ step, policy, flow: targetFlow, group: detail.flowKey });
557
+ this.updateComplete.then(() => {
558
+ const flowElement = this._getFlowElement(targetFlow._id);
559
+ flowElement.selectedStepId = step._id;
560
+ flowElement.requestUpdate();
561
+ });
562
+ });
563
+ }
564
+ }
565
+ }
566
+ targetFlow._dirty = true;
567
+ sourceFlow._dirty = true;
568
+ this.isDirty = true;
569
+ this.shadowRoot.querySelectorAll('gv-flow').forEach((gvFlow) => gvFlow.removeCandidate());
570
+ setTimeout(() => {
571
+ this._dragPolicy = null;
572
+ this._dropPolicy = null;
573
+ }, 0);
574
+ }
575
+ catch (e) {
576
+ this._currentAskConfirmation = null;
577
+ }
855
578
  }
856
- }
857
-
858
- _onOpenDocumentationFromForm() {
859
- localStorage.removeItem('gv-policy-studio:keep-documentation-close');
860
-
861
- this._onOpenDocumentation();
862
- }
863
-
864
- _findFlowCollection(flowId) {
865
- const plan = this.definedPlans.find(plan => plan.flows.find(flow => flow._id === flowId) != null);
866
- return {
867
- plan,
868
- flows: plan != null ? plan.flows : this.definedFlows
869
- };
870
- }
871
-
872
- _findFlowById(flowId) {
873
- let flow = this.definedFlows.find(flow => flow._id === flowId);
874
-
875
- if (flow == null) {
876
- const plansFlows = this.definedPlans.map(plan => plan.flows).reduce((acc, val) => acc.concat(val), []);
877
- flow = plansFlows.find(flow => flow._id === flowId);
579
+ _onDeletePolicy({ detail }) {
580
+ const targetFlow = this._findFlowById(detail.flowId);
581
+ targetFlow[detail.flowKey].splice(detail.position, 1);
582
+ targetFlow._dirty = true;
583
+ this.isDirty = true;
584
+ if (detail.target.editing) {
585
+ this._closeFlowStepForm(true);
586
+ }
587
+ this._getFlowElement(detail.flowId).requestUpdate();
878
588
  }
879
-
880
- return flow;
881
- }
882
-
883
- getSelectedFlow(index = 0) {
884
- const selectedFlowId = this.selectedFlowsId[index];
885
- return this._findFlowById(selectedFlowId);
886
- }
887
-
888
- _onTargetPolicy({
889
- detail
890
- }) {
891
- if (this._currentAskConfirmation == null) {
892
- this._dragPolicy = detail;
589
+ _onDesign() {
590
+ this._changeTab('design');
591
+ this._splitMainViews();
893
592
  }
894
- }
895
-
896
- _onChangeFlowStep({
897
- detail
898
- }) {
899
- this._currentFlowStep._values = detail.values;
900
- }
901
-
902
- _writeFlowStep(values) {
903
- const {
904
- commonDescription,
905
- commonCondition,
906
- ...configuration
907
- } = values;
908
-
909
- if (this._currentFlowStep.step._new || this._currentFlowStep.step.description !== commonDescription || this._currentFlowStep.step.condition !== commonCondition || !deepEqual(this._currentFlowStep.step.configuration, configuration)) {
910
- const flow = this._findFlowById(this._currentFlowStep.flow._id);
911
-
912
- const position = flow[this._currentFlowStep.group].findIndex(step => step._id === this._currentFlowStep.step._id);
913
-
914
- flow[this._currentFlowStep.group][position].description = commonDescription;
915
- flow[this._currentFlowStep.group][position].condition = commonCondition;
916
- flow[this._currentFlowStep.group][position].configuration = deepClone(configuration);
917
- delete flow[this._currentFlowStep.group][position]._new;
918
- flow[this._currentFlowStep.group][position]._dirty = true;
919
- flow._dirty = true;
920
- this.isDirty = true;
921
- this._currentFlowStep.flow = flow;
922
- this._currentFlowStep.step = flow[this._currentFlowStep.group][position];
923
- }
924
- }
925
-
926
- async _onSubmitFlowStep({
927
- detail
928
- }) {
929
- this._writeFlowStep(detail.values);
930
-
931
- await this.requestUpdate('_definition');
932
- this.getChildren().forEach(c => c.requestUpdate());
933
- }
934
-
935
- _onCancelFlow() {
936
- this._onDesign();
937
- }
938
-
939
- _onSubmitFlow({
940
- detail: {
941
- values
593
+ buildSchema({ schema }) {
594
+ const commonDescription = {
595
+ title: 'Description',
596
+ description: 'Description of flow step',
597
+ type: 'string',
598
+ };
599
+ const commonCondition = {
600
+ title: 'Condition',
601
+ description: 'Condition the execution of the flow step (support EL)',
602
+ type: 'string',
603
+ 'x-schema-form': {
604
+ 'expression-language': true,
605
+ },
606
+ };
607
+ if (schema) {
608
+ const jsonSchema = typeof schema === 'string' ? JSON.parse(schema) : schema;
609
+ const properties = { commonDescription, ...(this.hasConditionalSteps ? { commonCondition } : {}), ...jsonSchema.properties };
610
+ return { ...jsonSchema, properties };
611
+ }
612
+ return { properties: { commonDescription, ...(this.hasConditionalSteps ? { commonCondition } : {}) } };
613
+ }
614
+ async _editFlowStep({ step, flow, policy, group }) {
615
+ if (step) {
616
+ this._currentPolicyId = policy.id;
617
+ const currentFlowStep = { flow, step, policy, group };
618
+ const schema = this.buildSchema(policy);
619
+ try {
620
+ await this._setCurrentFlowStep(currentFlowStep, schema);
621
+ this._updateSelectedFlows([flow._id]);
622
+ this._splitMainViews();
623
+ if (localStorage.getItem('gv-policy-studio:keep-documentation-close') == null) {
624
+ this._onOpenDocumentation();
625
+ }
626
+ }
627
+ catch (e) {
628
+ this._currentAskConfirmation = null;
629
+ }
630
+ }
631
+ else {
632
+ await this._closeFlowStepForm();
633
+ this._maximizeTopView();
634
+ }
942
635
  }
943
- }) {
944
- const selectedFlow = this.getSelectedFlow();
945
-
946
- const _values = Object.assign({}, this._createFlowFromSchema(), values);
947
-
948
- const selectedFlowUpdated = Object.assign({}, selectedFlow, _values);
949
-
950
- if (!deepEqual(selectedFlow, selectedFlowUpdated)) {
951
- Object.assign(selectedFlow, selectedFlowUpdated, {
952
- _dirty: true
953
- });
954
- this.isDirty = true;
955
-
956
- this._refresh();
636
+ async _onEditFlowStep({ detail: { step, flow, policy, group } }) {
637
+ return this._editFlowStep({ step, flow, policy, group });
957
638
  }
958
- }
959
-
960
- _onCancelFlowMode() {
961
- this._onDesign();
962
- }
963
-
964
- _onSubmitFlowMode({
965
- detail: {
966
- values
639
+ _getResizableViews() {
640
+ return this.shadowRoot.querySelector('gv-resizable-views');
967
641
  }
968
- }) {
969
- this._definition['flow-mode'] = values['flow-mode'] || 'DEFAULT';
970
- this.isDirty = true;
971
-
972
- this._refresh();
973
- }
974
-
975
- _onChangeTab({
976
- detail
977
- }) {
978
- this._changeTab(detail.value);
979
- }
980
-
981
- async _changeTabValidator({
982
- from,
983
- to
984
- }) {
985
- if (from === 'properties') {
986
- const component = this.shadowRoot.querySelector('gv-properties');
987
-
988
- if (component.dirty) {
989
- return component.confirm();
990
- }
991
- } else if (from === 'resources') {
992
- const component = this.shadowRoot.querySelector('gv-resources');
993
-
994
- if (component.dirty) {
995
- return component.confirm();
996
- }
997
- } else {
998
- try {
999
- return await this._askToValidateForms();
1000
- } catch (e) {
1001
- this._currentAskConfirmation = null;
1002
- throw e;
1003
- }
642
+ _maximizeTopView() {
643
+ if (this.selectedFlowsId.length <= 1) {
644
+ this._getResizableViews().maximizeTop();
645
+ }
1004
646
  }
1005
-
1006
- return Promise.resolve();
1007
- }
1008
-
1009
- _changeTab(tabId) {
1010
- if (this._currentAskConfirmation == null) {
1011
- this.tabId = tabId;
1012
- dispatchCustomEvent(this, 'change-tab', this.tabId);
647
+ _maximizeBottomView() {
648
+ this._getResizableViews().maximizeBottom();
1013
649
  }
1014
- }
1015
-
1016
- _onDragStartFlowStep(flow, {
1017
- detail
1018
- }) {
1019
- if (this._currentAskConfirmation == null) {
1020
- this._dropPolicy = detail;
1021
- this._dragPolicy = detail;
1022
- }
1023
- }
1024
-
1025
- _renderFlowEmptyState(readonlyMode) {
1026
- return html`<div slot="content" class="empty"> <div> Select a flow ${readonlyMode !== true ? html`or <gv-button @gv-button:click="${this._onAddFlow}" outlined icon="code:plus" large>design new one</gv-button>` : ''} </div> </div>`;
1027
- }
1028
-
1029
- _renderFlow(index = 0, hasEmptyState = true, readonlyMode) {
1030
- const flow = this.getSelectedFlow(index);
1031
-
1032
- if (flow) {
1033
- const {
1034
- plan
1035
- } = this._findFlowCollection(flow._id);
1036
-
1037
- const selectedStepId = this._currentFlowStep ? this._currentFlowStep.step._id : null;
1038
- return html` <gv-flow style="height:100%" .id="${flow._id}" .flow="${flow}" .plan="${plan}" .policies="${this.policies}" slot="content" ?disabled="${this._currentAskConfirmation}" .dragPolicy="${this._dragPolicy}" .dropPolicy="${this._dropPolicy}" .selectedStepId="${selectedStepId}" ?readonly="${readonlyMode}" ?has-policy-filter="${this._policyFilterOptions != null}" flows-title="${this.flowsTitle}" @gv-flow:drag-start="${this._onDragStartFlowStep.bind(this, flow)}" @gv-flow:edit="${this._onEditFlowStep}" @gv-flow:change-state="${this._onChangeFlowStepState}" @gv-flow:drop="${this._onDropPolicy}" @gv-flow:delete="${this._onDeletePolicy}"></gv-flow>`;
1039
- } else if (hasEmptyState) {
1040
- return this._renderFlowEmptyState(readonlyMode);
650
+ _splitMainViews() {
651
+ this._getResizableViews().split();
1041
652
  }
1042
-
1043
- return html``;
1044
- }
1045
-
1046
- _onFetchResources(event) {
1047
- const {
1048
- currentTarget,
1049
- regexTypes
1050
- } = event.detail;
1051
- const options = this.definedResources.filter(resource => regexTypes == null || new RegExp(regexTypes).test(resource.type)).map((resource, index) => {
1052
- const resourceType = this.resourceTypes.find(type => type.id === resource.type);
1053
- const row = document.createElement('gv-row');
1054
- const picture = resourceType.icon ? resourceType.icon : null;
1055
- row.item = {
1056
- picture,
1057
- name: resource.name
1058
- };
1059
- return {
1060
- element: row,
1061
- value: resource.name,
1062
- id: resource.type
1063
- };
1064
- });
1065
- currentTarget.options = options;
1066
- }
1067
-
1068
- _renderPolicy(readonlyMode) {
1069
- if (this._flowStepSchema && this.documentation) {
1070
- return html`<gv-resizable-views direction="horizontal" no-overflow> <div slot="top">${this._renderFlowStepForm(readonlyMode)}</div> <div slot="bottom"> <gv-documentation .text="${this.documentation.content}" .image="${this.documentation.image}" ?disabled="${this._currentAskConfirmation}" @gv-documentation:close="${this._onCloseDocumentation}"></gv-documentation> </div> </gv-resizable-views>`;
1071
- } else if (this.documentation) {
1072
- return html`<gv-documentation .text="${this.documentation.content}" .image="${this.documentation.image}" ?disabled="${this._currentAskConfirmation}" @gv-documentation:close="${this._onCloseDocumentation}"></gv-documentation>`;
1073
- } else if (this._flowStepSchema) {
1074
- return this._renderFlowStepForm(readonlyMode);
653
+ _onChangeFlowStepState({ detail }) {
654
+ const targetFlow = this._findFlowById(detail.flowId);
655
+ const step = targetFlow[detail.flowKey][detail.position];
656
+ step.enabled = detail.enabled;
657
+ targetFlow._dirty = true;
658
+ this.isDirty = true;
1075
659
  }
1076
-
1077
- return html``;
1078
- }
1079
-
1080
- _getFlowStepForm() {
1081
- return this.shadowRoot.querySelector(`#${FLOW_STEP_FORM_ID}`);
1082
- }
1083
-
1084
- _onResetFlowStep() {
1085
- if (this._currentFlowStep) {
1086
- delete this._currentFlowStep._values;
1087
-
1088
- this._getFlowStepForm().reset();
660
+ async _onCloseFlowStepForm() {
661
+ try {
662
+ await this._closeFlowStepForm();
663
+ }
664
+ catch (err) {
665
+ this._currentAskConfirmation = null;
666
+ }
1089
667
  }
1090
- }
1091
-
1092
- _generateFlowsId(list, force = false) {
1093
- return this._generateId('f', list, force, true);
1094
- }
1095
-
1096
- _generatePlanFlowsId(plan, force = false) {
1097
- return this._generateId(plan.id, plan.flows, force, true);
1098
- }
1099
-
1100
- _generateFlowStepId(flowId, flowKey, position) {
1101
- return `${flowId}_${flowKey}_${position}`;
1102
- }
1103
-
1104
- _generateId(prefix, list, force = false, isFlow = false) {
1105
- if (list) {
1106
- return list.map((e, index) => {
1107
- const _id = `${prefix}_${index}`;
1108
-
1109
- if (isFlow) {
1110
- if (e.pre) {
1111
- e.pre.forEach((step, stepIndex) => step._id = this._generateFlowStepId(_id, 'pre', stepIndex));
1112
- }
1113
-
1114
- if (e.post) {
1115
- e.post.forEach((step, stepIndex) => step._id = this._generateFlowStepId(_id, 'post', stepIndex));
1116
- }
668
+ async _closeFlowStepForm(force = false) {
669
+ await this._setCurrentFlowStep(null, null, force);
670
+ }
671
+ async _askToValidateForms() {
672
+ if (this._currentAskConfirmation == null) {
673
+ this._currentAskConfirmation = true;
674
+ return Promise.all(this._submitOrConfirmForms()).then((forms) => {
675
+ if (forms.filter((r) => r != null).length > 0) {
676
+ this._definition = this._buildDefinitionToSave();
677
+ this.getChildren().forEach((e) => e.requestUpdate());
678
+ // Refresh if lose changes lost current step selection
679
+ return this._checkCurrentFlowStep().then(() => {
680
+ this.getChildren().forEach((e) => e.requestUpdate());
681
+ return this.updateComplete.then(() => {
682
+ this._currentAskConfirmation = null;
683
+ return forms;
684
+ });
685
+ });
686
+ }
687
+ else {
688
+ this._currentAskConfirmation = null;
689
+ return forms;
690
+ }
691
+ });
1117
692
  }
1118
-
1119
- if (force || e._id == null) {
1120
- return { ...e,
1121
- _id
1122
- };
693
+ throw new Error('ask already waiting');
694
+ }
695
+ async _setCurrentFlowStep(currentFlowStep, flowStepSchema, force = false) {
696
+ if (!force) {
697
+ await this._askToValidateForms();
1123
698
  }
1124
-
1125
- return e;
1126
- });
699
+ const schema = deepClone(flowStepSchema);
700
+ if (currentFlowStep != null) {
701
+ const configuration = typeof currentFlowStep.step.configuration === 'string'
702
+ ? JSON.parse(currentFlowStep.step.configuration)
703
+ : currentFlowStep.step.configuration;
704
+ const step = { ...currentFlowStep.step, configuration };
705
+ const _initialValues = { ...step.configuration, commonDescription: step.description, commonCondition: step.condition };
706
+ this._currentFlowStep = { ...currentFlowStep, step, _initialValues };
707
+ if (flowStepSchema && flowStepSchema.properties.scope) {
708
+ const _enum = schema.properties.scope.enum;
709
+ if (_enum.find((scope) => ['REQUEST', 'REQUEST_CONTENT', 'RESPONSE', 'RESPONSE_CONTENT'].includes(scope)) != null) {
710
+ const filtered = this._currentFlowStep.group === 'pre' ? ['REQUEST', 'REQUEST_CONTENT'] : ['RESPONSE', 'RESPONSE_CONTENT'];
711
+ schema.properties.scope.enum = _enum.filter((scope) => filtered.includes(scope));
712
+ const scope = this._currentFlowStep.step.configuration.scope;
713
+ if (scope == null || !schema.properties.scope.enum.includes(scope)) {
714
+ schema.properties.scope.default = schema.properties.scope.enum[0];
715
+ this._currentFlowStep.step.configuration.scope = schema.properties.scope.enum[0];
716
+ this._currentFlowStep._initialValues.scope = schema.properties.scope.enum[0];
717
+ if (this._currentFlowStep._values) {
718
+ this._currentFlowStep._values.scope = schema.properties.scope.enum[0];
719
+ }
720
+ }
721
+ }
722
+ }
723
+ }
724
+ else {
725
+ this._currentFlowStep = null;
726
+ }
727
+ this._flowStepSchema = schema;
1127
728
  }
1128
-
1129
- return list;
1130
- }
1131
-
1132
- getChildren() {
1133
- return [...Array.from(this.shadowRoot.querySelectorAll('gv-flow')), ...Array.from(this.shadowRoot.querySelectorAll('gv-resizable-views'))];
1134
- }
1135
-
1136
- async getUpdateComplete() {
1137
- await super.getUpdateComplete();
1138
- await Promise.all(this.getChildren().map(e => e.updateComplete));
1139
- }
1140
-
1141
- shouldUpdate(changedProperties) {
1142
- // Just refresh gv-flow components
1143
- if (changedProperties.has('_dragPolicy')) {
1144
- this.shadowRoot.querySelectorAll('gv-flow').forEach(flow => flow.dragPolicy = this._dragPolicy);
1145
- return false;
729
+ _refresh(closeStepForm = true) {
730
+ if (closeStepForm) {
731
+ this._closeFlowStepForm(true);
732
+ }
733
+ this._definition = deepClone(this._definition);
734
+ }
735
+ async _onSelectFlows({ detail }) {
736
+ try {
737
+ await this._closeFlowStepForm();
738
+ this._onCloseDocumentation();
739
+ this._updateSelectedFlows(detail.flows);
740
+ this._onDesign();
741
+ }
742
+ catch (e) {
743
+ this._currentAskConfirmation = null;
744
+ }
1146
745
  }
1147
-
1148
- if (changedProperties.has('_dropPolicy')) {
1149
- this.shadowRoot.querySelectorAll('gv-flow').forEach(flow => flow.dropPolicy = this._dropPolicy);
1150
- return false;
746
+ async _onOpenDocumentationFromMenu({ detail: { policy } }) {
747
+ try {
748
+ if (this.documentation == null || this.documentation.id !== policy.id) {
749
+ await this._closeFlowStepForm();
750
+ this._currentPolicyId = policy.id;
751
+ if (this.getSelectedFlow()) {
752
+ this._splitMainViews();
753
+ }
754
+ else {
755
+ this._maximizeBottomView();
756
+ }
757
+ dispatchCustomEvent(this, 'fetch-documentation', { policy });
758
+ }
759
+ }
760
+ catch (e) { }
1151
761
  }
1152
-
1153
- return super.shouldUpdate(changedProperties);
1154
- }
1155
-
1156
- updated(props) {
1157
- if (props.has('documentation') && this.documentation != null && this.selectedFlowsId.length > 1) {
1158
- this._updateSelectedFlows([this.selectedFlowsId[0]]);
762
+ _fetchDocumentation(policy) {
763
+ if (this.documentation == null || this.documentation.id !== policy.id) {
764
+ dispatchCustomEvent(this, 'fetch-documentation', { policy });
765
+ }
1159
766
  }
1160
- }
1161
-
1162
- _renderFlowStepForm(readonlyMode) {
1163
- const values = this._currentFlowStep._values || this._currentFlowStep._initialValues;
1164
- const groups = [{
1165
- items: ['commonDescription', 'commonCondition']
1166
- }, {
1167
- name: i18n('gv-policy-studio.policy-settings'),
1168
- default: true
1169
- }];
1170
- return html`${cache(this._flowStepSchema && this._currentFlowStep ? html`<div class="flow-step__container"> <div class="flow-step__form"> <gv-schema-form .id="${FLOW_STEP_FORM_ID}" .schema="${this._flowStepSchema}" .icon="design:edit" has-header validate-on-render .values="${values}" .dirty="${this._currentFlowStep._values != null}" ?readonly="${readonlyMode}" scrollable .groups="${groups}" @gv-schema-form:change="${this._onChangeFlowStep}" @gv-schema-form:reset="${this._onResetFlowStep}" @gv-schema-form:fetch-resources="${this._onFetchResources}" @gv-schema-form:submit="${this._onSubmitFlowStep}"> <div slot="title" class="flow-step__form-title">${this._currentFlowStep.step.name}</div> <gv-button slot="header-left" icon="general:close" outlined small @gv-button:click="${this._onCloseFlowStepForm}" title="Close"></gv-button> <gv-button slot="header-left" icon="home:book" ?disabled="${this.documentation != null}" outlined small @gv-button:click="${this._onOpenDocumentationFromForm}" title="Open documentation"></gv-button> </gv-schema-form> </div> </div>` : '')}`;
1171
- }
1172
-
1173
- _onCloseDocumentation() {
1174
- this.documentation = null;
1175
-
1176
- if (this._currentFlowStep == null) {
1177
- this._maximizeTopView();
1178
- } else {
1179
- localStorage.setItem('gv-policy-studio:keep-documentation-close', true);
767
+ _onOpenDocumentation() {
768
+ if (this._currentFlowStep && this._currentFlowStep.policy) {
769
+ this._fetchDocumentation(this._currentFlowStep.policy);
770
+ }
1180
771
  }
1181
- }
1182
-
1183
- _onDeleteFlow({
1184
- detail
1185
- }) {
1186
- const flowId = detail.content._id;
1187
-
1188
- const {
1189
- flows
1190
- } = this._findFlowCollection(flowId);
1191
-
1192
- const flow = flows.find(flow => flow._id === flowId);
1193
-
1194
- this._deleteFlow(flows, flow);
1195
- }
1196
-
1197
- get definedFlows() {
1198
- return this._definition && this._definition.flows ? this._definition.flows : [];
1199
- }
1200
-
1201
- get definedPlans() {
1202
- return this._definition && this._definition.plans ? this._definition.plans : [];
1203
- }
1204
-
1205
- get definedResources() {
1206
- return this._definition && this._definition.resources ? this._definition.resources : [];
1207
- }
1208
-
1209
- get definedProperties() {
1210
- return this._definition && this._definition.properties ? this._definition.properties : [];
1211
- }
1212
-
1213
- async _onDuplicateFlow({
1214
- detail
1215
- }) {
1216
- try {
1217
- await this._askToValidateForms();
1218
- const flowId = detail.content._id;
1219
-
1220
- const {
1221
- plan,
1222
- flows
1223
- } = this._findFlowCollection(flowId);
1224
-
1225
- this._addFlow(flows, this._findFlowById(flowId));
1226
-
1227
- if (plan != null) {
1228
- let planIndex = null;
1229
- this.definedPlans.find((p, i) => {
1230
- if (p.id === plan.id) {
1231
- planIndex = i;
1232
- return true;
1233
- }
1234
-
1235
- return false;
1236
- });
1237
- plan.flows = flows;
1238
- this.definedPlans[planIndex].flows = this._generatePlanFlowsId(plan, true);
1239
-
1240
- this._updateSelectedFlows([this.definedPlans[planIndex].flows[flows.length - 1]._id]);
1241
- } else {
1242
- this._definition.flows = this._generateFlowsId(this._definition.flows);
1243
-
1244
- this._updateSelectedFlows([this._definition.flows[this._definition.flows.length - 1]._id]);
1245
- }
1246
- } catch (err) {
1247
- this._currentAskConfirmation = null;
772
+ _onOpenDocumentationFromForm() {
773
+ localStorage.removeItem('gv-policy-studio:keep-documentation-close');
774
+ this._onOpenDocumentation();
1248
775
  }
1249
- }
1250
-
1251
- _onChangeFlowState({
1252
- detail
1253
- }) {
1254
- const flow = this._findFlowById(detail.content._id);
1255
-
1256
- flow.enabled = detail.enabled;
1257
- flow._dirty = true;
1258
- this.isDirty = true;
1259
- }
1260
-
1261
- async _onAddFlowPlan({
1262
- detail
1263
- }) {
1264
- try {
1265
- await this._askToValidateForms();
1266
-
1267
- this._addFlow(this.definedPlans[detail.planIndex].flows);
1268
-
1269
- this.definedPlans[detail.planIndex].flows = this._generatePlanFlowsId(this.definedPlans[detail.planIndex]);
1270
-
1271
- this._updateSelectedFlows([this.definedPlans[detail.planIndex].flows[this.definedPlans[detail.planIndex].flows.length - 1]._id]);
1272
- } catch (err) {
1273
- this._currentAskConfirmation = null;
776
+ _findFlowCollection(flowId) {
777
+ const plan = this.definedPlans.find((plan) => plan.flows.find((flow) => flow._id === flowId) != null);
778
+ return { plan, flows: plan != null ? plan.flows : this.definedFlows };
1274
779
  }
1275
- }
1276
-
1277
- async _onAddFlow() {
1278
- try {
1279
- await this._askToValidateForms();
1280
-
1281
- this._addFlow(this._definition.flows);
1282
-
1283
- this._definition.flows = this._generateFlowsId(this._definition.flows);
1284
-
1285
- this._updateSelectedFlows([this._definition.flows[this._definition.flows.length - 1]._id]);
1286
- } catch (err) {
1287
- this._currentAskConfirmation = null;
780
+ _findFlowById(flowId) {
781
+ let flow = this.definedFlows.find((flow) => flow._id === flowId);
782
+ if (flow == null) {
783
+ const plansFlows = this.definedPlans.map((plan) => plan.flows).reduce((acc, val) => acc.concat(val), []);
784
+ flow = plansFlows.find((flow) => flow._id === flowId);
785
+ }
786
+ return flow;
1288
787
  }
1289
- }
1290
-
1291
- _addFlow(collection, duplicate = null) {
1292
- const flow = duplicate == null ? this._createFlowFromSchema() : { ...duplicate,
1293
- _id: null,
1294
- // reset the id to avoid issue with AM that persists the ID
1295
- id: null,
1296
- _dirty: true
1297
- };
1298
- collection.push(flow);
1299
- this.isDirty = true;
1300
- return collection;
1301
- }
1302
-
1303
- _createFlowFromSchema() {
1304
- const newFlow = {
1305
- name: '',
1306
- pre: [],
1307
- post: [],
1308
- _dirty: true
1309
- };
1310
- return this._instantiate(this.flowSchema.properties, newFlow);
1311
- }
1312
-
1313
- _instantiate(propertiesDefinition, initiator = {}) {
1314
- const property = { ...initiator
1315
- };
1316
-
1317
- if (propertiesDefinition) {
1318
- for (const key of Object.keys(propertiesDefinition)) {
1319
- const entry = propertiesDefinition[key];
1320
-
1321
- if (entry.type === 'object') {
1322
- property[key] = this._instantiate(entry.properties, initiator = {});
788
+ getSelectedFlow(index = 0) {
789
+ const selectedFlowId = this.selectedFlowsId[index];
790
+ return this._findFlowById(selectedFlowId);
791
+ }
792
+ _onTargetPolicy({ detail }) {
793
+ if (this._currentAskConfirmation == null) {
794
+ this._dragPolicy = detail;
1323
795
  }
1324
-
1325
- if (entry.default !== undefined) {
1326
- property[key] = entry.default;
1327
- } else if (entry.type === 'string') {
1328
- property[key] = '';
796
+ }
797
+ _onChangeFlowStep({ detail }) {
798
+ this._currentFlowStep._values = detail.values;
799
+ }
800
+ _writeFlowStep(values) {
801
+ const { commonDescription, commonCondition, ...configuration } = values;
802
+ if (this._currentFlowStep.step._new ||
803
+ this._currentFlowStep.step.description !== commonDescription ||
804
+ this._currentFlowStep.step.condition !== commonCondition ||
805
+ !deepEqual(this._currentFlowStep.step.configuration, configuration)) {
806
+ const flow = this._findFlowById(this._currentFlowStep.flow._id);
807
+ const position = flow[this._currentFlowStep.group].findIndex((step) => step._id === this._currentFlowStep.step._id);
808
+ flow[this._currentFlowStep.group][position].description = commonDescription;
809
+ flow[this._currentFlowStep.group][position].condition = commonCondition;
810
+ flow[this._currentFlowStep.group][position].configuration = deepClone(configuration);
811
+ delete flow[this._currentFlowStep.group][position]._new;
812
+ flow[this._currentFlowStep.group][position]._dirty = true;
813
+ flow._dirty = true;
814
+ this.isDirty = true;
815
+ this._currentFlowStep.flow = flow;
816
+ this._currentFlowStep.step = flow[this._currentFlowStep.group][position];
1329
817
  }
1330
- }
1331
818
  }
1332
-
1333
- return property;
1334
- }
1335
-
1336
- _deleteFlow(collection, flow) {
1337
- const index = collection.indexOf(flow);
1338
- collection.splice(index, 1);
1339
- const selectedFlows = this.selectedFlowsId.filter(flowId => flowId !== flow._id);
1340
-
1341
- if (selectedFlows.length === 1) {
1342
- this._updateSelectedFlows(selectedFlows);
1343
- } else {
1344
- this._selectFirstFlow(true);
819
+ async _onSubmitFlowStep({ detail }) {
820
+ this._writeFlowStep(detail.values);
821
+ await this.requestUpdate('_definition');
822
+ this.getChildren().forEach((c) => c.requestUpdate());
823
+ }
824
+ _onCancelFlow() {
825
+ this._onDesign();
826
+ }
827
+ _onSubmitFlow({ detail: { values } }) {
828
+ const selectedFlow = this.getSelectedFlow();
829
+ const _values = Object.assign({}, this._createFlowFromSchema(), values);
830
+ const selectedFlowUpdated = Object.assign({}, selectedFlow, _values);
831
+ if (!deepEqual(selectedFlow, selectedFlowUpdated)) {
832
+ Object.assign(selectedFlow, selectedFlowUpdated, { _dirty: true });
833
+ this.isDirty = true;
834
+ this._refresh();
835
+ }
1345
836
  }
1346
-
1347
- this._changeTab('design');
1348
-
1349
- this._refresh();
1350
-
1351
- this.isDirty = true;
1352
- }
1353
-
1354
- _findFlowIndex(list, id) {
1355
- let index = null;
1356
- list.find((f, i) => {
1357
- if (f._id === id) {
1358
- index = i;
1359
- return true;
1360
- }
1361
-
1362
- return false;
1363
- });
1364
- return index;
1365
- }
1366
-
1367
- async _onReorderFlows({
1368
- detail: {
1369
- plan
1370
- }
1371
- }) {
1372
- try {
1373
- await this._askToValidateForms();
1374
- this.isDirty = true;
1375
-
1376
- if (plan != null) {
1377
- const newOrder = this._generatePlanFlowsId(plan, true);
1378
-
1379
- if (this.selectedFlowsId) {
1380
- this._updateSelectedFlows(this.selectedFlowsId.map(flowId => {
1381
- const index = this._findFlowIndex(plan.flows, flowId);
1382
-
1383
- return index != null ? newOrder[index]._id : flowId;
1384
- }));
837
+ _onCancelFlowMode() {
838
+ this._onDesign();
839
+ }
840
+ _onSubmitFlowMode({ detail: { values } }) {
841
+ this._definition['flow-mode'] = values['flow-mode'] || 'DEFAULT';
842
+ this.isDirty = true;
843
+ this._refresh();
844
+ }
845
+ _onChangeTab({ detail }) {
846
+ this._changeTab(detail.value);
847
+ }
848
+ async _changeTabValidator({ from, to }) {
849
+ if (from === 'properties') {
850
+ const component = this.shadowRoot.querySelector('gv-properties');
851
+ if (component.dirty) {
852
+ return component.confirm();
853
+ }
1385
854
  }
1386
-
1387
- plan.flows = newOrder;
1388
- } else {
1389
- const newOrder = this._generateFlowsId(this._definition.flows, true);
1390
-
1391
- if (this.selectedFlowsId) {
1392
- this._updateSelectedFlows(this.selectedFlowsId.map(flowId => {
1393
- const index = this._findFlowIndex(this._definition.flows, flowId);
1394
-
1395
- return index != null ? newOrder[index]._id : flowId;
1396
- }));
855
+ else if (from === 'resources') {
856
+ const component = this.shadowRoot.querySelector('gv-resources');
857
+ if (component.dirty) {
858
+ return component.confirm();
859
+ }
1397
860
  }
1398
-
1399
- this._definition.flows = newOrder;
1400
- }
1401
- } catch (err) {
1402
- this._currentAskConfirmation = false;
861
+ else {
862
+ try {
863
+ return await this._askToValidateForms();
864
+ }
865
+ catch (e) {
866
+ this._currentAskConfirmation = null;
867
+ throw e;
868
+ }
869
+ }
870
+ return Promise.resolve();
1403
871
  }
1404
- }
1405
-
1406
- _onSearchPolicy({
1407
- detail
1408
- }) {
1409
- this._searchPolicyQuery = detail;
1410
- }
1411
-
1412
- _onClearPolicy() {
1413
- this._searchPolicyQuery = null;
1414
- }
1415
-
1416
- _onSearchFlows({
1417
- detail
1418
- }) {
1419
- this._searchFlowQuery = detail;
1420
- }
1421
-
1422
- _onClearFlows() {
1423
- this._searchFlowQuery = null;
1424
- }
1425
-
1426
- async _onResetAll() {
1427
- try {
1428
- await this._closeFlowStepForm();
1429
- this.definition = deepClone(this._initialDefinition);
1430
- } catch (e) {
1431
- this._currentAskConfirmation = null;
1432
- }
1433
- }
1434
-
1435
- _filterNotValidStep(step) {
1436
- return step._new !== true;
1437
- }
1438
-
1439
- _removePrivateProperties(o) {
1440
- const copy = { ...o
1441
- };
1442
- Object.keys(o).filter(key => key.startsWith('_')).forEach(key => {
1443
- delete copy[key];
1444
- });
1445
- return copy;
1446
- }
1447
-
1448
- _submitOrConfirmForms() {
1449
- return [...this.shadowRoot.querySelectorAll('gv-schema-form')].filter(form => {
1450
- const isValid = form.isValid();
1451
-
1452
- if (isValid) {
1453
- form.submit();
1454
- } else {
1455
- form.dirty = true;
1456
- }
1457
-
1458
- return !isValid;
1459
- }).map(form => form.confirm());
1460
- }
1461
-
1462
- getPropertiesElement() {
1463
- return this.shadowRoot.querySelector('gv-properties');
1464
- }
1465
-
1466
- async _checkCurrentFlowStep() {
1467
- if (this._currentFlowStep && this.selectedFlowsId) {
1468
- const closePromises = this.selectedFlowsId.map(flowId => {
1469
- const flow = this._findFlowById(flowId);
1470
-
1471
- const currentStep = [...flow.pre, ...flow.post].find(step => step._id === this._currentFlowStep.step._id);
1472
-
1473
- if (currentStep == null) {
1474
- return this._closeFlowStepForm(true);
872
+ _changeTab(tabId) {
873
+ if (this._currentAskConfirmation == null) {
874
+ this.tabId = tabId;
875
+ dispatchCustomEvent(this, 'change-tab', this.tabId);
1475
876
  }
1476
-
1477
- return null;
1478
- }).filter(p => p !== null);
1479
- return Promise.all(closePromises);
1480
877
  }
1481
-
1482
- return Promise.resolve();
1483
- }
1484
-
1485
- saved() {
1486
- if (this.isDirty) {
1487
- this._initialDefinition = deepClone(this._definitionSaved);
1488
- this._definition = deepClone(this._definitionSaved);
1489
- this._definitionSaved = null;
1490
- this.isDirty = false;
1491
-
1492
- this._checkCurrentFlowStep();
1493
-
1494
- this.definedPlans.forEach(plan => {
1495
- plan.flows.forEach(flow => flow._dirty = false);
1496
- });
1497
- this.definedFlows.forEach(flow => flow._dirty = false);
1498
- this.getChildren().forEach(e => e.requestUpdate());
878
+ _onDragStartFlowStep(flow, { detail }) {
879
+ if (this._currentAskConfirmation == null) {
880
+ this._dropPolicy = detail;
881
+ this._dragPolicy = detail;
882
+ }
1499
883
  }
1500
- }
1501
-
1502
- _buildDefinitionToSave() {
1503
- // Copy definition and remove invalid step
1504
- // Keep private properties like _id and others stuff useful for render
1505
- const flows = this._definition.flows.map(flow => {
1506
- flow.pre = flow.pre.filter(this._filterNotValidStep);
1507
- flow.post = flow.post.filter(this._filterNotValidStep);
1508
- return flow;
1509
- });
1510
-
1511
- let definition = { ...this._definition,
1512
- flows
1513
- };
1514
-
1515
- if (this._definition.plans != null) {
1516
- const plans = this._definition.plans.map(plan => {
1517
- const flows = plan.flows.map(flow => {
1518
- flow.pre = flow.pre.filter(this._filterNotValidStep);
1519
- flow.post = flow.post.filter(this._filterNotValidStep);
1520
- return flow;
884
+ _renderFlowEmptyState(readonlyMode) {
885
+ return html `<div slot="content" class="empty">
886
+ <div>
887
+ Select a flow
888
+ ${readonlyMode !== true
889
+ ? html `or <gv-button @gv-button:click="${this._onAddFlow}" outlined icon="code:plus" large>design new one</gv-button>`
890
+ : ''}
891
+ </div>
892
+ </div>`;
893
+ }
894
+ _renderFlow(index = 0, hasEmptyState = true, readonlyMode) {
895
+ const flow = this.getSelectedFlow(index);
896
+ if (flow) {
897
+ const { plan } = this._findFlowCollection(flow._id);
898
+ const selectedStepId = this._currentFlowStep ? this._currentFlowStep.step._id : null;
899
+ return html ` <gv-flow
900
+ style="height: 100%"
901
+ .id="${flow._id}"
902
+ .flow="${flow}"
903
+ .plan="${plan}"
904
+ .policies="${this.policies}"
905
+ slot="content"
906
+ ?disabled="${this._currentAskConfirmation}"
907
+ .dragPolicy="${this._dragPolicy}"
908
+ .dropPolicy="${this._dropPolicy}"
909
+ .selectedStepId="${selectedStepId}"
910
+ ?readonly="${readonlyMode}"
911
+ ?has-policy-filter="${this._policyFilterOptions != null}"
912
+ flows-title="${this.flowsTitle}"
913
+ @gv-flow:drag-start="${this._onDragStartFlowStep.bind(this, flow)}"
914
+ @gv-flow:edit="${this._onEditFlowStep}"
915
+ @gv-flow:change-state="${this._onChangeFlowStepState}"
916
+ @gv-flow:drop="${this._onDropPolicy}"
917
+ @gv-flow:delete="${this._onDeletePolicy}"
918
+ ></gv-flow>`;
919
+ }
920
+ else if (hasEmptyState) {
921
+ return this._renderFlowEmptyState(readonlyMode);
922
+ }
923
+ return html ``;
924
+ }
925
+ _onFetchResources(event) {
926
+ const { currentTarget, regexTypes } = event.detail;
927
+ const options = this.definedResources
928
+ .filter((resource) => regexTypes == null || new RegExp(regexTypes).test(resource.type))
929
+ .map((resource, index) => {
930
+ const resourceType = this.resourceTypes.find((type) => type.id === resource.type);
931
+ const row = document.createElement('gv-row');
932
+ const picture = resourceType.icon ? resourceType.icon : null;
933
+ row.item = { picture, name: resource.name };
934
+ return {
935
+ element: row,
936
+ value: resource.name,
937
+ id: resource.type,
938
+ };
1521
939
  });
1522
- return { ...plan,
1523
- flows
1524
- };
1525
- });
1526
-
1527
- definition = { ...definition,
1528
- plans
1529
- };
940
+ currentTarget.options = options;
941
+ }
942
+ _renderPolicy(readonlyMode) {
943
+ if (this._flowStepSchema && this.documentation) {
944
+ return html `<gv-resizable-views direction="horizontal" no-overflow>
945
+ <div slot="top">${this._renderFlowStepForm(readonlyMode)}</div>
946
+ <div slot="bottom">
947
+ <gv-documentation
948
+ .text="${this.documentation.content}"
949
+ .image="${this.documentation.image}"
950
+ ?disabled="${this._currentAskConfirmation}"
951
+ @gv-documentation:close="${this._onCloseDocumentation}"
952
+ ></gv-documentation>
953
+ </div>
954
+ </gv-resizable-views>`;
955
+ }
956
+ else if (this.documentation) {
957
+ return html `<gv-documentation
958
+ .text="${this.documentation.content}"
959
+ .image="${this.documentation.image}"
960
+ ?disabled="${this._currentAskConfirmation}"
961
+ @gv-documentation:close="${this._onCloseDocumentation}"
962
+ ></gv-documentation>`;
963
+ }
964
+ else if (this._flowStepSchema) {
965
+ return this._renderFlowStepForm(readonlyMode);
966
+ }
967
+ return html ``;
1530
968
  }
1531
-
1532
- return definition;
1533
- }
1534
-
1535
- _buildDefinitionToSend(definitionToSave) {
1536
- // Copy definition and remove all private properties
1537
- const flows = definitionToSave.flows.map(f => {
1538
- const flow = this._removePrivateProperties(f);
1539
-
1540
- flow.pre = flow.pre.map(this._removePrivateProperties);
1541
- flow.post = flow.post.map(this._removePrivateProperties);
1542
- return flow;
1543
- });
1544
- let definition = { ...this._definition,
1545
- flows
1546
- };
1547
-
1548
- if (this._definition.plans != null) {
1549
- const plans = definitionToSave.plans.map(plan => {
1550
- const flows = plan.flows.map(f => {
1551
- const flow = this._removePrivateProperties(f);
1552
-
1553
- flow.pre = flow.pre.map(this._removePrivateProperties);
1554
- flow.post = flow.post.map(this._removePrivateProperties);
1555
- return flow;
1556
- });
1557
- return { ...plan,
1558
- flows
969
+ _getFlowStepForm() {
970
+ return this.shadowRoot.querySelector(`#${FLOW_STEP_FORM_ID}`);
971
+ }
972
+ _onResetFlowStep() {
973
+ if (this._currentFlowStep) {
974
+ delete this._currentFlowStep._values;
975
+ this._getFlowStepForm().reset();
976
+ }
977
+ }
978
+ _generateFlowsId(list, force = false) {
979
+ return this._generateId('f', list, force, true);
980
+ }
981
+ _generatePlanFlowsId(plan, force = false) {
982
+ return this._generateId(plan.id, plan.flows, force, true);
983
+ }
984
+ _generateFlowStepId(flowId, flowKey, position) {
985
+ return `${flowId}_${flowKey}_${position}`;
986
+ }
987
+ _generateId(prefix, list, force = false, isFlow = false) {
988
+ if (list) {
989
+ return list.map((e, index) => {
990
+ const _id = `${prefix}_${index}`;
991
+ if (isFlow) {
992
+ if (e.pre) {
993
+ e.pre.forEach((step, stepIndex) => (step._id = this._generateFlowStepId(_id, 'pre', stepIndex)));
994
+ }
995
+ if (e.post) {
996
+ e.post.forEach((step, stepIndex) => (step._id = this._generateFlowStepId(_id, 'post', stepIndex)));
997
+ }
998
+ }
999
+ if (force || e._id == null) {
1000
+ return { ...e, _id };
1001
+ }
1002
+ return e;
1003
+ });
1004
+ }
1005
+ return list;
1006
+ }
1007
+ getChildren() {
1008
+ return [
1009
+ ...Array.from(this.shadowRoot.querySelectorAll('gv-flow')),
1010
+ ...Array.from(this.shadowRoot.querySelectorAll('gv-resizable-views')),
1011
+ ];
1012
+ }
1013
+ async getUpdateComplete() {
1014
+ await super.getUpdateComplete();
1015
+ await Promise.all(this.getChildren().map((e) => e.updateComplete));
1016
+ }
1017
+ shouldUpdate(changedProperties) {
1018
+ // Just refresh gv-flow components
1019
+ if (changedProperties.has('_dragPolicy')) {
1020
+ this.shadowRoot.querySelectorAll('gv-flow').forEach((flow) => (flow.dragPolicy = this._dragPolicy));
1021
+ return false;
1022
+ }
1023
+ if (changedProperties.has('_dropPolicy')) {
1024
+ this.shadowRoot.querySelectorAll('gv-flow').forEach((flow) => (flow.dropPolicy = this._dropPolicy));
1025
+ return false;
1026
+ }
1027
+ return super.shouldUpdate(changedProperties);
1028
+ }
1029
+ updated(props) {
1030
+ if (props.has('documentation') && this.documentation != null && this.selectedFlowsId.length > 1) {
1031
+ this._updateSelectedFlows([this.selectedFlowsId[0]]);
1032
+ }
1033
+ }
1034
+ _renderFlowStepForm(readonlyMode) {
1035
+ const values = this._currentFlowStep._values || this._currentFlowStep._initialValues;
1036
+ const groups = [{ items: ['commonDescription', 'commonCondition'] }, { name: i18n('gv-policy-studio.policy-settings'), default: true }];
1037
+ return html `${cache(this._flowStepSchema && this._currentFlowStep
1038
+ ? html `<div class="flow-step__container">
1039
+ <div class="flow-step__form">
1040
+ <gv-schema-form
1041
+ .id="${FLOW_STEP_FORM_ID}"
1042
+ .schema="${this._flowStepSchema}"
1043
+ .icon="design:edit"
1044
+ has-header
1045
+ validate-on-render
1046
+ .values="${values}"
1047
+ .dirty="${this._currentFlowStep._values != null}"
1048
+ ?readonly="${readonlyMode}"
1049
+ scrollable
1050
+ .groups="${groups}"
1051
+ @gv-schema-form:change="${this._onChangeFlowStep}"
1052
+ @gv-schema-form:reset="${this._onResetFlowStep}"
1053
+ @gv-schema-form:fetch-resources="${this._onFetchResources}"
1054
+ @gv-schema-form:submit="${this._onSubmitFlowStep}"
1055
+ >
1056
+ <div slot="title" class="flow-step__form-title">${this._currentFlowStep.step.name}</div>
1057
+ <gv-button
1058
+ slot="header-left"
1059
+ icon="general:close"
1060
+ outlined
1061
+ small
1062
+ @gv-button:click="${this._onCloseFlowStepForm}"
1063
+ title="Close"
1064
+ ></gv-button>
1065
+ <gv-button
1066
+ slot="header-left"
1067
+ icon="home:book"
1068
+ ?disabled="${this.documentation != null}"
1069
+ outlined
1070
+ small
1071
+ @gv-button:click="${this._onOpenDocumentationFromForm}"
1072
+ title="Open documentation"
1073
+ ></gv-button>
1074
+ </gv-schema-form>
1075
+ </div>
1076
+ </div>`
1077
+ : '')}`;
1078
+ }
1079
+ _onCloseDocumentation() {
1080
+ this.documentation = null;
1081
+ if (this._currentFlowStep == null) {
1082
+ this._maximizeTopView();
1083
+ }
1084
+ else {
1085
+ localStorage.setItem('gv-policy-studio:keep-documentation-close', true);
1086
+ }
1087
+ }
1088
+ _onDeleteFlow({ detail }) {
1089
+ const flowId = detail.content._id;
1090
+ const { flows } = this._findFlowCollection(flowId);
1091
+ const flow = flows.find((flow) => flow._id === flowId);
1092
+ this._deleteFlow(flows, flow);
1093
+ }
1094
+ get definedFlows() {
1095
+ return this._definition && this._definition.flows ? this._definition.flows : [];
1096
+ }
1097
+ get definedPlans() {
1098
+ return this._definition && this._definition.plans ? this._definition.plans : [];
1099
+ }
1100
+ get definedResources() {
1101
+ return this._definition && this._definition.resources ? this._definition.resources : [];
1102
+ }
1103
+ get definedProperties() {
1104
+ return this._definition && this._definition.properties ? this._definition.properties : [];
1105
+ }
1106
+ async _onDuplicateFlow({ detail }) {
1107
+ try {
1108
+ await this._askToValidateForms();
1109
+ const flowId = detail.content._id;
1110
+ const { plan, flows } = this._findFlowCollection(flowId);
1111
+ this._addFlow(flows, this._findFlowById(flowId));
1112
+ if (plan != null) {
1113
+ let planIndex = null;
1114
+ this.definedPlans.find((p, i) => {
1115
+ if (p.id === plan.id) {
1116
+ planIndex = i;
1117
+ return true;
1118
+ }
1119
+ return false;
1120
+ });
1121
+ plan.flows = flows;
1122
+ this.definedPlans[planIndex].flows = this._generatePlanFlowsId(plan, true);
1123
+ this._updateSelectedFlows([this.definedPlans[planIndex].flows[flows.length - 1]._id]);
1124
+ }
1125
+ else {
1126
+ this._definition.flows = this._generateFlowsId(this._definition.flows);
1127
+ this._updateSelectedFlows([this._definition.flows[this._definition.flows.length - 1]._id]);
1128
+ }
1129
+ }
1130
+ catch (err) {
1131
+ this._currentAskConfirmation = null;
1132
+ }
1133
+ }
1134
+ _onChangeFlowState({ detail }) {
1135
+ const flow = this._findFlowById(detail.content._id);
1136
+ flow.enabled = detail.enabled;
1137
+ flow._dirty = true;
1138
+ this.isDirty = true;
1139
+ }
1140
+ async _onAddFlowPlan({ detail }) {
1141
+ try {
1142
+ await this._askToValidateForms();
1143
+ this._addFlow(this.definedPlans[detail.planIndex].flows);
1144
+ this.definedPlans[detail.planIndex].flows = this._generatePlanFlowsId(this.definedPlans[detail.planIndex]);
1145
+ this._updateSelectedFlows([this.definedPlans[detail.planIndex].flows[this.definedPlans[detail.planIndex].flows.length - 1]._id]);
1146
+ }
1147
+ catch (err) {
1148
+ this._currentAskConfirmation = null;
1149
+ }
1150
+ }
1151
+ async _onAddFlow() {
1152
+ try {
1153
+ await this._askToValidateForms();
1154
+ this._addFlow(this._definition.flows);
1155
+ this._definition.flows = this._generateFlowsId(this._definition.flows);
1156
+ this._updateSelectedFlows([this._definition.flows[this._definition.flows.length - 1]._id]);
1157
+ }
1158
+ catch (err) {
1159
+ this._currentAskConfirmation = null;
1160
+ }
1161
+ }
1162
+ _addFlow(collection, duplicate = null) {
1163
+ const flow = duplicate == null
1164
+ ? this._createFlowFromSchema()
1165
+ : {
1166
+ ...duplicate,
1167
+ _id: null,
1168
+ // reset the id to avoid issue with AM that persists the ID
1169
+ id: null,
1170
+ _dirty: true,
1171
+ };
1172
+ collection.push(flow);
1173
+ this.isDirty = true;
1174
+ return collection;
1175
+ }
1176
+ _createFlowFromSchema() {
1177
+ const newFlow = {
1178
+ name: '',
1179
+ pre: [],
1180
+ post: [],
1181
+ _dirty: true,
1559
1182
  };
1560
- });
1561
- definition = { ...definition,
1562
- plans
1563
- };
1183
+ return this._instantiate(this.flowSchema.properties, newFlow);
1184
+ }
1185
+ _instantiate(propertiesDefinition, initiator = {}) {
1186
+ const property = { ...initiator };
1187
+ if (propertiesDefinition) {
1188
+ for (const key of Object.keys(propertiesDefinition)) {
1189
+ const entry = propertiesDefinition[key];
1190
+ if (entry.type === 'object') {
1191
+ property[key] = this._instantiate(entry.properties, (initiator = {}));
1192
+ }
1193
+ if (entry.default !== undefined) {
1194
+ property[key] = entry.default;
1195
+ }
1196
+ else if (entry.type === 'string') {
1197
+ property[key] = '';
1198
+ }
1199
+ }
1200
+ }
1201
+ return property;
1202
+ }
1203
+ _deleteFlow(collection, flow) {
1204
+ const index = collection.indexOf(flow);
1205
+ collection.splice(index, 1);
1206
+ const selectedFlows = this.selectedFlowsId.filter((flowId) => flowId !== flow._id);
1207
+ if (selectedFlows.length === 1) {
1208
+ this._updateSelectedFlows(selectedFlows);
1209
+ }
1210
+ else {
1211
+ this._selectFirstFlow(true);
1212
+ }
1213
+ this._changeTab('design');
1214
+ this._refresh();
1215
+ this.isDirty = true;
1216
+ }
1217
+ _findFlowIndex(list, id) {
1218
+ let index = null;
1219
+ list.find((f, i) => {
1220
+ if (f._id === id) {
1221
+ index = i;
1222
+ return true;
1223
+ }
1224
+ return false;
1225
+ });
1226
+ return index;
1227
+ }
1228
+ async _onReorderFlows({ detail: { plan } }) {
1229
+ try {
1230
+ await this._askToValidateForms();
1231
+ this.isDirty = true;
1232
+ if (plan != null) {
1233
+ const newOrder = this._generatePlanFlowsId(plan, true);
1234
+ if (this.selectedFlowsId) {
1235
+ this._updateSelectedFlows(this.selectedFlowsId.map((flowId) => {
1236
+ const index = this._findFlowIndex(plan.flows, flowId);
1237
+ return index != null ? newOrder[index]._id : flowId;
1238
+ }));
1239
+ }
1240
+ plan.flows = newOrder;
1241
+ }
1242
+ else {
1243
+ const newOrder = this._generateFlowsId(this._definition.flows, true);
1244
+ if (this.selectedFlowsId) {
1245
+ this._updateSelectedFlows(this.selectedFlowsId.map((flowId) => {
1246
+ const index = this._findFlowIndex(this._definition.flows, flowId);
1247
+ return index != null ? newOrder[index]._id : flowId;
1248
+ }));
1249
+ }
1250
+ this._definition.flows = newOrder;
1251
+ }
1252
+ }
1253
+ catch (err) {
1254
+ this._currentAskConfirmation = false;
1255
+ }
1564
1256
  }
1565
-
1566
- if (this._definition.properties != null) {
1567
- const properties = this._definition.properties.map(this._removePrivateProperties);
1568
-
1569
- definition = { ...definition,
1570
- properties
1571
- };
1257
+ _onSearchPolicy({ detail }) {
1258
+ this._searchPolicyQuery = detail;
1572
1259
  }
1573
-
1574
- if (this._definition.resources != null) {
1575
- const resources = this._definition.resources.map(this._removePrivateProperties);
1576
-
1577
- definition = { ...definition,
1578
- resources
1579
- };
1260
+ _onClearPolicy() {
1261
+ this._searchPolicyQuery = null;
1580
1262
  }
1581
-
1582
- return definition;
1583
- }
1584
-
1585
- _onSaveAll() {
1586
- if (this.hasProperties) {
1587
- this.getPropertiesElement().submit();
1263
+ _onSearchFlows({ detail }) {
1264
+ this._searchFlowQuery = detail;
1588
1265
  }
1589
-
1590
- Promise.all(this._submitOrConfirmForms()).then(() => {
1591
- this._definitionSaved = this._buildDefinitionToSave();
1592
-
1593
- const definition = this._buildDefinitionToSend(this._definitionSaved);
1594
-
1595
- dispatchCustomEvent(this, 'save', {
1596
- definition,
1597
- services: this.services
1598
- });
1599
- }).catch(err => {
1600
- console.error(`[policy-studio] Error on save`, err);
1601
- });
1602
- }
1603
-
1604
- _onDebug(requestEvent) {
1605
- if (this.hasProperties) {
1606
- this.getPropertiesElement().submit();
1266
+ _onClearFlows() {
1267
+ this._searchFlowQuery = null;
1607
1268
  }
1608
-
1609
- Promise.all(this._submitOrConfirmForms()).then(() => {
1610
- const definition = this._buildDefinitionToSend(this._buildDefinitionToSave());
1611
-
1612
- dispatchCustomEvent(this, 'debug', {
1613
- definition,
1614
- services: this.services,
1615
- request: requestEvent.detail.request
1616
- });
1617
- }).catch(err => {
1618
- console.error(`[policy-studio] Error on debug`, err);
1619
- });
1620
- }
1621
-
1622
- get filteredFlows() {
1623
- if (this._flowFilter.length === 0 || this._flowFilter.includes('api')) {
1624
- return this.definedFlows;
1269
+ async _onResetAll() {
1270
+ try {
1271
+ await this._closeFlowStepForm();
1272
+ this.definition = deepClone(this._initialDefinition);
1273
+ }
1274
+ catch (e) {
1275
+ this._currentAskConfirmation = null;
1276
+ }
1625
1277
  }
1626
-
1627
- return null;
1628
- }
1629
-
1630
- get filteredPlans() {
1631
- if (this._flowFilter.length === 0 || this._flowFilter.includes('plan')) {
1632
- return this.definedPlans;
1278
+ _filterNotValidStep(step) {
1279
+ return step._new !== true;
1633
1280
  }
1634
-
1635
- return null;
1636
- }
1637
-
1638
- _onFilterFlows({
1639
- detail
1640
- }) {
1641
- if (this._flowFilter.includes(detail.id)) {
1642
- this._flowFilter = [];
1643
- } else {
1644
- this._flowFilter = [detail.id];
1645
- }
1646
- }
1647
-
1648
- _getFilteredPolicies() {
1649
- if (this._policyFilter.length > 0) {
1650
- return this.policies.filter(policy => {
1651
- return policy.onRequest && this._policyFilter.includes('onRequest') || policy.onResponse && this._policyFilter.includes('onResponse');
1652
- });
1281
+ _removePrivateProperties(o) {
1282
+ const copy = { ...o };
1283
+ Object.keys(o)
1284
+ .filter((key) => key.startsWith('_'))
1285
+ .forEach((key) => {
1286
+ delete copy[key];
1287
+ });
1288
+ return copy;
1289
+ }
1290
+ _submitOrConfirmForms() {
1291
+ return [...this.shadowRoot.querySelectorAll('gv-schema-form')]
1292
+ .filter((form) => {
1293
+ const isValid = form.isValid();
1294
+ if (isValid) {
1295
+ form.submit();
1296
+ }
1297
+ else {
1298
+ form.dirty = true;
1299
+ }
1300
+ return !isValid;
1301
+ })
1302
+ .map((form) => form.confirm());
1303
+ }
1304
+ getPropertiesElement() {
1305
+ return this.shadowRoot.querySelector('gv-properties');
1306
+ }
1307
+ async _checkCurrentFlowStep() {
1308
+ if (this._currentFlowStep && this.selectedFlowsId) {
1309
+ const closePromises = this.selectedFlowsId
1310
+ .map((flowId) => {
1311
+ const flow = this._findFlowById(flowId);
1312
+ const currentStep = [...flow.pre, ...flow.post].find((step) => step._id === this._currentFlowStep.step._id);
1313
+ if (currentStep == null) {
1314
+ return this._closeFlowStepForm(true);
1315
+ }
1316
+ return null;
1317
+ })
1318
+ .filter((p) => p !== null);
1319
+ return Promise.all(closePromises);
1320
+ }
1321
+ return Promise.resolve();
1322
+ }
1323
+ saved() {
1324
+ if (this.isDirty) {
1325
+ this._initialDefinition = deepClone(this._definitionSaved);
1326
+ this._definition = deepClone(this._definitionSaved);
1327
+ this._definitionSaved = null;
1328
+ this.isDirty = false;
1329
+ this._checkCurrentFlowStep();
1330
+ this.definedPlans.forEach((plan) => {
1331
+ plan.flows.forEach((flow) => (flow._dirty = false));
1332
+ });
1333
+ this.definedFlows.forEach((flow) => (flow._dirty = false));
1334
+ this.getChildren().forEach((e) => e.requestUpdate());
1335
+ }
1653
1336
  }
1654
-
1655
- return this.policies;
1656
- }
1657
-
1658
- _onFilterPolicies({
1659
- detail
1660
- }) {
1661
- if (this._policyFilter.includes(detail.id)) {
1662
- this._policyFilter = [];
1663
- } else {
1664
- this._policyFilter = [detail.id];
1665
- }
1666
- }
1667
-
1668
- _renderDesign(readonlyMode) {
1669
- return html` <div id="design" slot="content" class="design"> <gv-resizable-views no-overflow> <div slot="top">${this._renderFlow(0, true, readonlyMode)}</div> <div slot="bottom"> ${this._renderFlow(1, false, readonlyMode)} ${this._renderPolicy(readonlyMode)} ${this._renderFlowForm(readonlyMode)} </div> </gv-resizable-views> ${readonlyMode !== true ? html`<gv-policy-studio-menu class="right-menu" ?disabled="${this._currentAskConfirmation}" .policies="${this._getFilteredPolicies()}" .selectedIds="${[this._currentPolicyId]}" .query="${this._searchPolicyQuery}" ?has-policy-filter="${this._policyFilterOptions != null}" ?readonly="${readonlyMode}" @gv-policy-studio-menu:target-policy="${this._onTargetPolicy}" @gv-policy-studio-menu:fetch-documentation="${this._onOpenDocumentationFromMenu}" @gv-policy-studio-menu:dragend-policy="${this._onDragEndPolicy}"> <div slot="header" class="search-policies"> ${this._policyFilterOptions != null ? html`<gv-option ?disabled="${this._currentAskConfirmation}" .options="${this._policyFilterOptions}" multiple="multiple" outlined .value="${this._policyFilter}" small @gv-option:select="${this._onFilterPolicies}"></gv-option>` : ''} <gv-input id="search-policy" ?disabled="${this._currentAskConfirmation}" placeholder="Filter policies (Shift + Ctrl + Space)" type="search" small @gv-input:input="${this._onSearchPolicy}" @gv-input:clear="${this._onClearPolicy}"></gv-input> </div> </gv-policy-studio-menu>` : ''} </div>`;
1670
- }
1671
-
1672
- _renderDebug() {
1673
- const response = this.debugResponse ? this.debugResponse.response : undefined;
1674
- const isLoading = this.debugResponse ? this.debugResponse.isLoading : undefined;
1675
- const path = this.debugResponse && this.debugResponse.request ? this.debugResponse.request.path : undefined;
1676
- const method = this.debugResponse && this.debugResponse.request ? this.debugResponse.request.method : undefined;
1677
- return html`<gv-http-client id="debug" slot="content" class="debug" @gv-http-client:send="${this._onDebug}" .response="${response}" .path="${path}" .method="${method}" ?loading="${isLoading}"> </gv-http-client>`;
1678
- }
1679
-
1680
- _renderConfigurationForm(readonlyMode) {
1681
- if (this.configurationSchema) {
1682
- const values = deepClone(this._definition);
1683
- return html` <div id="settings" slot="content" class="api-settings" @dragover="${this._onDesign}"> <gv-schema-form .schema="${this.configurationSchema}" id="api-settings-form" .values="${values}" has-header has-footer scrollable ?readonly="${readonlyMode}" @gv-schema-form:cancel="${this._onCancelFlowMode}" @gv-schema-form:submit="${this._onSubmitFlowMode}"> ${!this.configurationInformation ? '' : html` <div class="api-settings-information" slot="title"> <gv-icon class="api-settings-information__icon" title="Info" shape="code:info"></gv-icon> <blockquote class="api-settings-information__blockquote">${this.configurationInformation}</blockquote> </div> `} </gv-schema-form> </div>`;
1337
+ _buildDefinitionToSave() {
1338
+ // Copy definition and remove invalid step
1339
+ // Keep private properties like _id and others stuff useful for render
1340
+ const flows = this._definition.flows.map((flow) => {
1341
+ flow.pre = flow.pre.filter(this._filterNotValidStep);
1342
+ flow.post = flow.post.filter(this._filterNotValidStep);
1343
+ return flow;
1344
+ });
1345
+ let definition = { ...this._definition, flows };
1346
+ if (this._definition.plans != null) {
1347
+ const plans = this._definition.plans.map((plan) => {
1348
+ const flows = plan.flows.map((flow) => {
1349
+ flow.pre = flow.pre.filter(this._filterNotValidStep);
1350
+ flow.post = flow.post.filter(this._filterNotValidStep);
1351
+ return flow;
1352
+ });
1353
+ return { ...plan, flows };
1354
+ });
1355
+ definition = { ...definition, plans };
1356
+ }
1357
+ return definition;
1358
+ }
1359
+ _buildDefinitionToSend(definitionToSave) {
1360
+ // Copy definition and remove all private properties
1361
+ const flows = definitionToSave.flows.map((f) => {
1362
+ const flow = this._removePrivateProperties(f);
1363
+ flow.pre = flow.pre.map(this._removePrivateProperties);
1364
+ flow.post = flow.post.map(this._removePrivateProperties);
1365
+ return flow;
1366
+ });
1367
+ let definition = { ...this._definition, flows };
1368
+ if (this._definition.plans != null) {
1369
+ const plans = definitionToSave.plans.map((plan) => {
1370
+ const flows = plan.flows.map((f) => {
1371
+ const flow = this._removePrivateProperties(f);
1372
+ flow.pre = flow.pre.map(this._removePrivateProperties);
1373
+ flow.post = flow.post.map(this._removePrivateProperties);
1374
+ return flow;
1375
+ });
1376
+ return { ...plan, flows };
1377
+ });
1378
+ definition = { ...definition, plans };
1379
+ }
1380
+ if (this._definition.properties != null) {
1381
+ const properties = this._definition.properties.map(this._removePrivateProperties);
1382
+ definition = { ...definition, properties };
1383
+ }
1384
+ if (this._definition.resources != null) {
1385
+ const resources = this._definition.resources.map(this._removePrivateProperties);
1386
+ definition = { ...definition, resources };
1387
+ }
1388
+ return definition;
1684
1389
  }
1685
-
1686
- return html``;
1687
- }
1688
-
1689
- _renderFlowForm(readonlyMode) {
1690
- if (this.flowSchema && this._flowStepSchema == null && this.documentation == null && this.selectedFlowsId.length === 1) {
1691
- const flow = this.getSelectedFlow();
1692
-
1693
- if (flow) {
1694
- const values = deepClone(flow);
1695
- return html`<div slot="content" class="flow-settings"> <gv-schema-form .schema="${this.flowSchema}" id="settings-form" .values="${values}" has-header scrollable ?readonly="${readonlyMode}" @gv-schema-form:cancel="${this._onCancelFlow}" @gv-schema-form:submit="${this._onSubmitFlow}"> <div slot="title" class="flow-step__form-title">Flow configuration</div> </gv-schema-form> </div>`;
1696
- }
1390
+ _onSaveAll() {
1391
+ if (this.hasProperties) {
1392
+ this.getPropertiesElement().submit();
1393
+ }
1394
+ Promise.all(this._submitOrConfirmForms())
1395
+ .then(() => {
1396
+ this._definitionSaved = this._buildDefinitionToSave();
1397
+ const definition = this._buildDefinitionToSend(this._definitionSaved);
1398
+ dispatchCustomEvent(this, 'save', { definition, services: this.services });
1399
+ })
1400
+ .catch((err) => {
1401
+ console.error(`[policy-studio] Error on save`, err);
1402
+ });
1697
1403
  }
1698
- }
1699
-
1700
- _onResourcesChange({
1701
- detail
1702
- }) {
1703
- this.definition.resources = detail.resources;
1704
- this.isDirty = true;
1705
- }
1706
-
1707
- _onPropertiesChange({
1708
- detail
1709
- }) {
1710
- this.definition.properties = detail.properties;
1711
- this.isDirty = true;
1712
- }
1713
-
1714
- _onSaveProvider({
1715
- detail
1716
- }) {
1717
- this.services['dynamic-property'] = detail.provider;
1718
- this.isDirty = true;
1719
- }
1720
-
1721
- _onSwitchEncryptedProperty({
1722
- detail
1723
- }) {
1724
- this.isDirty = true;
1725
- }
1726
-
1727
- render() {
1728
- const readonlyMode = this._getReadonlyModeForDesign();
1729
-
1730
- return html`<div class="box"> <gv-policy-studio-menu class="left-menu" .api-name="${this._definition.name}" .flows="${this.filteredFlows}" .plans="${this.filteredPlans}" .selectedIds="${this.selectedFlowsId}" ?disabled="${this._currentAskConfirmation}" ?sortable="${this.sortable && this.readonly !== true}" ?readonly="${this.readonly}" ?readonlyPlans="${this.readonlyPlans}" flows-title="${this.flowsTitle}" .query="${this._searchFlowQuery}" ?can-add="${this.canAdd && !this.readonly}" @gv-policy-studio-menu:reorder-flows="${this._onReorderFlows}" @gv-policy-studio-menu:change-flow-state="${this._onChangeFlowState}" @gv-policy-studio-menu:add-flow="${this._onAddFlow}" @gv-policy-studio-menu:add-flow-plan="${this._onAddFlowPlan}" @gv-policy-studio-menu:delete-flow="${this._onDeleteFlow}" @gv-policy-studio-menu:duplicate-flow="${this._onDuplicateFlow}" @gv-policy-studio-menu:select-flows="${this._onSelectFlows}"> <div slot="header" class="header-actions"> <div class="title">${this._definition.name}</div> ${this._flowFilterOptions != null ? html`<gv-option ?disabled="${this._currentAskConfirmation}" .options="${this._flowFilterOptions}" multiple="multiple" outlined .value="${this._flowFilter}" small @gv-option:select="${this._onFilterFlows}"></gv-option>` : ''} <gv-input ?disabled="${this._currentAskConfirmation}" id="search-flow" placeholder="Filter flows (Ctrl + Space)" type="search" small @gv-input:input="${this._onSearchFlows}" @gv-input:clear="${this._onClearFlows}"></gv-input> </div> ${this.readonly !== true ? html` <div slot="footer" class="footer-actions"> <gv-button class="btn-large" .disabled="${!this.isDirty || this._currentAskConfirmation}" @gv-button:click="${this._onSaveAll}">Save</gv-button> <gv-button link .disabled="${!this.isDirty || this._currentAskConfirmation}" @gv-button:click="${this._onResetAll}">Reset</gv-button> </div>` : ''} </gv-policy-studio-menu> <gv-tabs .value="${this.tabId}" .options="${this._tabs}" .disabled="${this._currentAskConfirmation}" @gv-tabs:change="${this._onChangeTab}" .validator="${this._changeTabValidator.bind(this)}"> ${this._renderDesign(readonlyMode)} ${this._renderConfigurationForm(readonlyMode)} ${this._renderDebug()} <gv-properties id="properties" slot="content" class="properties" .provider="${this.services['dynamic-property']}" @gv-properties:change="${this._onPropertiesChange}" @gv-properties:save-provider="${this._onSaveProvider}" @gv-properties:switch-encrypted="${this._onSwitchEncryptedProperty}" ?readonly="${readonlyMode}" encryptable="true" .properties="${this.definedProperties}" .providers="${this.propertyProviders}" .dynamicPropertySchema="${this.dynamicPropertySchema}"></gv-properties> <gv-resources id="resources" slot="content" class="resources" @gv-resources:change="${this._onResourcesChange}" ?readonly="${readonlyMode}" .resources="${this.definedResources}" .types="${this.resourceTypes}"></gv-resources> </gv-tabs> </div>`;
1731
- }
1732
- /**
1733
- * Determine if the design view should be in readonly mode or not
1734
- * It is in readonly mode if:
1735
- * the readonly attribute is set to true
1736
- * OR
1737
- * the main selected flow belongs to a plan and the readonly-plans attribute is set to true
1738
- * OR
1739
- * the second flow for comparison belongs to a plan and the readonly-plans attribute is set to true
1740
- * @returns {boolean|*|{type: BooleanConstructor}|{attribute: string, type: BooleanConstructor}|{type: *}|{attribute: string, type: *}}
1741
- * @private
1742
- */
1743
-
1744
-
1745
- _getReadonlyModeForDesign() {
1746
- if (this.readonly) {
1747
- return true;
1404
+ _onDebug(requestEvent) {
1405
+ if (this.hasProperties) {
1406
+ this.getPropertiesElement().submit();
1407
+ }
1408
+ Promise.all(this._submitOrConfirmForms())
1409
+ .then(() => {
1410
+ const definition = this._buildDefinitionToSend(this._buildDefinitionToSave());
1411
+ dispatchCustomEvent(this, 'debug', { definition, services: this.services, request: requestEvent.detail.request });
1412
+ })
1413
+ .catch((err) => {
1414
+ console.error(`[policy-studio] Error on debug`, err);
1415
+ });
1748
1416
  }
1749
-
1750
- const flow = this.getSelectedFlow(0);
1751
-
1752
- if (!flow) {
1753
- return false;
1417
+ get filteredFlows() {
1418
+ if (this._flowFilter.length === 0 || this._flowFilter.includes('api')) {
1419
+ return this.definedFlows;
1420
+ }
1421
+ return null;
1754
1422
  }
1755
-
1756
- const {
1757
- plan: flowPlan
1758
- } = this._findFlowCollection(flow._id);
1759
-
1760
- const readonlyMode = flowPlan && this.readonlyPlans;
1761
-
1762
- if (readonlyMode) {
1763
- return true;
1423
+ get filteredPlans() {
1424
+ if (this._flowFilter.length === 0 || this._flowFilter.includes('plan')) {
1425
+ return this.definedPlans;
1426
+ }
1427
+ return null;
1764
1428
  }
1765
-
1766
- const comparedFlow = this.getSelectedFlow(1);
1767
-
1768
- if (!comparedFlow) {
1769
- return false;
1429
+ _onFilterFlows({ detail }) {
1430
+ if (this._flowFilter.includes(detail.id)) {
1431
+ this._flowFilter = [];
1432
+ }
1433
+ else {
1434
+ this._flowFilter = [detail.id];
1435
+ }
1436
+ }
1437
+ _getFilteredPolicies() {
1438
+ if (this._policyFilter.length > 0) {
1439
+ return this.policies.filter((policy) => {
1440
+ return ((policy.onRequest && this._policyFilter.includes('onRequest')) || (policy.onResponse && this._policyFilter.includes('onResponse')));
1441
+ });
1442
+ }
1443
+ return this.policies;
1444
+ }
1445
+ _onFilterPolicies({ detail }) {
1446
+ if (this._policyFilter.includes(detail.id)) {
1447
+ this._policyFilter = [];
1448
+ }
1449
+ else {
1450
+ this._policyFilter = [detail.id];
1451
+ }
1452
+ }
1453
+ _renderDesign(readonlyMode) {
1454
+ return html ` <div id="design" slot="content" class="design">
1455
+ <gv-resizable-views no-overflow>
1456
+ <div slot="top">${this._renderFlow(0, true, readonlyMode)}</div>
1457
+
1458
+ <div slot="bottom">
1459
+ ${this._renderFlow(1, false, readonlyMode)} ${this._renderPolicy(readonlyMode)} ${this._renderFlowForm(readonlyMode)}
1460
+ </div>
1461
+ </gv-resizable-views>
1462
+ ${readonlyMode !== true
1463
+ ? html `<gv-policy-studio-menu
1464
+ class="right-menu"
1465
+ ?disabled="${this._currentAskConfirmation}"
1466
+ .policies="${this._getFilteredPolicies()}"
1467
+ .selectedIds="${[this._currentPolicyId]}"
1468
+ .query="${this._searchPolicyQuery}"
1469
+ ?has-policy-filter="${this._policyFilterOptions != null}"
1470
+ ?readonly="${readonlyMode}"
1471
+ @gv-policy-studio-menu:target-policy="${this._onTargetPolicy}"
1472
+ @gv-policy-studio-menu:fetch-documentation="${this._onOpenDocumentationFromMenu}"
1473
+ @gv-policy-studio-menu:dragend-policy="${this._onDragEndPolicy}"
1474
+ >
1475
+ <div slot="header" class="search-policies">
1476
+ ${this._policyFilterOptions != null
1477
+ ? html `<gv-option
1478
+ ?disabled="${this._currentAskConfirmation}"
1479
+ .options="${this._policyFilterOptions}"
1480
+ multiple
1481
+ outlined
1482
+ .value="${this._policyFilter}"
1483
+ small
1484
+ @gv-option:select="${this._onFilterPolicies}"
1485
+ ></gv-option>`
1486
+ : ''}
1487
+ <gv-input
1488
+ id="search-policy"
1489
+ ?disabled="${this._currentAskConfirmation}"
1490
+ placeholder="Filter policies (Shift + Ctrl + Space)"
1491
+ type="search"
1492
+ small
1493
+ @gv-input:input="${this._onSearchPolicy}"
1494
+ @gv-input:clear="${this._onClearPolicy}"
1495
+ ></gv-input>
1496
+ </div>
1497
+ </gv-policy-studio-menu>`
1498
+ : ''}
1499
+ </div>`;
1500
+ }
1501
+ _renderDebug() {
1502
+ const response = this.debugResponse ? this.debugResponse.response : undefined;
1503
+ const isLoading = this.debugResponse ? this.debugResponse.isLoading : undefined;
1504
+ const path = this.debugResponse && this.debugResponse.request ? this.debugResponse.request.path : undefined;
1505
+ const method = this.debugResponse && this.debugResponse.request ? this.debugResponse.request.method : undefined;
1506
+ return html `<gv-http-client
1507
+ id="debug"
1508
+ slot="content"
1509
+ class="debug"
1510
+ @gv-http-client:send="${this._onDebug}"
1511
+ .response="${response}"
1512
+ .path="${path}"
1513
+ .method="${method}"
1514
+ ?loading="${isLoading}"
1515
+ >
1516
+ </gv-http-client>`;
1517
+ }
1518
+ _renderConfigurationForm(readonlyMode) {
1519
+ if (this.configurationSchema) {
1520
+ const values = deepClone(this._definition);
1521
+ return html ` <div id="settings" slot="content" class="api-settings" @dragover="${this._onDesign}">
1522
+ <gv-schema-form
1523
+ .schema="${this.configurationSchema}"
1524
+ id="api-settings-form"
1525
+ .values="${values}"
1526
+ has-header
1527
+ has-footer
1528
+ scrollable
1529
+ ?readonly="${readonlyMode}"
1530
+ @gv-schema-form:cancel="${this._onCancelFlowMode}"
1531
+ @gv-schema-form:submit="${this._onSubmitFlowMode}"
1532
+ >
1533
+ ${!this.configurationInformation
1534
+ ? ''
1535
+ : html `
1536
+ <div class="api-settings-information" slot="title">
1537
+ <gv-icon class="api-settings-information__icon" title="Info" shape="code:info"></gv-icon>
1538
+ <blockquote class="api-settings-information__blockquote">${this.configurationInformation}</blockquote>
1539
+ </div>
1540
+ `}
1541
+ </gv-schema-form>
1542
+ </div>`;
1543
+ }
1544
+ return html ``;
1545
+ }
1546
+ _renderFlowForm(readonlyMode) {
1547
+ if (this.flowSchema && this._flowStepSchema == null && this.documentation == null && this.selectedFlowsId.length === 1) {
1548
+ const flow = this.getSelectedFlow();
1549
+ if (flow) {
1550
+ const values = deepClone(flow);
1551
+ return html `<div slot="content" class="flow-settings">
1552
+ <gv-schema-form
1553
+ .schema="${this.flowSchema}"
1554
+ id="settings-form"
1555
+ .values="${values}"
1556
+ has-header
1557
+ scrollable
1558
+ ?readonly="${readonlyMode}"
1559
+ @gv-schema-form:cancel="${this._onCancelFlow}"
1560
+ @gv-schema-form:submit="${this._onSubmitFlow}"
1561
+ >
1562
+ <div slot="title" class="flow-step__form-title">Flow configuration</div>
1563
+ </gv-schema-form>
1564
+ </div>`;
1565
+ }
1566
+ }
1567
+ }
1568
+ _onResourcesChange({ detail }) {
1569
+ this.definition.resources = detail.resources;
1570
+ this.isDirty = true;
1571
+ }
1572
+ _onPropertiesChange({ detail }) {
1573
+ this.definition.properties = detail.properties;
1574
+ this.isDirty = true;
1575
+ }
1576
+ _onSaveProvider({ detail }) {
1577
+ this.services['dynamic-property'] = detail.provider;
1578
+ this.isDirty = true;
1579
+ }
1580
+ _onSwitchEncryptedProperty({ detail }) {
1581
+ this.isDirty = true;
1582
+ }
1583
+ render() {
1584
+ const readonlyMode = this._getReadonlyModeForDesign();
1585
+ return html `<div class="box">
1586
+ <gv-policy-studio-menu
1587
+ class="left-menu"
1588
+ .api-name="${this._definition.name}"
1589
+ .flows="${this.filteredFlows}"
1590
+ .plans="${this.filteredPlans}"
1591
+ .selectedIds="${this.selectedFlowsId}"
1592
+ ?disabled="${this._currentAskConfirmation}"
1593
+ ?sortable="${this.sortable && this.readonly !== true}"
1594
+ ?readonly="${this.readonly}"
1595
+ ?readonlyPlans="${this.readonlyPlans}"
1596
+ flows-title="${this.flowsTitle}"
1597
+ .query="${this._searchFlowQuery}"
1598
+ ?can-add="${this.canAdd && !this.readonly}"
1599
+ @gv-policy-studio-menu:reorder-flows="${this._onReorderFlows}"
1600
+ @gv-policy-studio-menu:change-flow-state="${this._onChangeFlowState}"
1601
+ @gv-policy-studio-menu:add-flow="${this._onAddFlow}"
1602
+ @gv-policy-studio-menu:add-flow-plan="${this._onAddFlowPlan}"
1603
+ @gv-policy-studio-menu:delete-flow="${this._onDeleteFlow}"
1604
+ @gv-policy-studio-menu:duplicate-flow="${this._onDuplicateFlow}"
1605
+ @gv-policy-studio-menu:select-flows="${this._onSelectFlows}"
1606
+ >
1607
+ <div slot="header" class="header-actions">
1608
+ <div class="title">${this._definition.name}</div>
1609
+ ${this._flowFilterOptions != null
1610
+ ? html `<gv-option
1611
+ ?disabled="${this._currentAskConfirmation}"
1612
+ .options="${this._flowFilterOptions}"
1613
+ multiple
1614
+ outlined
1615
+ .value="${this._flowFilter}"
1616
+ small
1617
+ @gv-option:select="${this._onFilterFlows}"
1618
+ ></gv-option>`
1619
+ : ''}
1620
+ <gv-input
1621
+ ?disabled="${this._currentAskConfirmation}"
1622
+ id="search-flow"
1623
+ placeholder="Filter flows (Ctrl + Space)"
1624
+ type="search"
1625
+ small
1626
+ @gv-input:input="${this._onSearchFlows}"
1627
+ @gv-input:clear="${this._onClearFlows}"
1628
+ ></gv-input>
1629
+ </div>
1630
+
1631
+ ${this.readonly !== true
1632
+ ? html ` <div slot="footer" class="footer-actions">
1633
+ <gv-button
1634
+ class="btn-large"
1635
+ .disabled="${!this.isDirty || this._currentAskConfirmation}"
1636
+ @gv-button:click="${this._onSaveAll}"
1637
+ >Save</gv-button
1638
+ >
1639
+ <gv-button link .disabled="${!this.isDirty || this._currentAskConfirmation}" @gv-button:click="${this._onResetAll}"
1640
+ >Reset</gv-button
1641
+ >
1642
+ </div>`
1643
+ : ''}
1644
+ </gv-policy-studio-menu>
1645
+
1646
+ <gv-tabs
1647
+ .value="${this.tabId}"
1648
+ .options="${this._tabs}"
1649
+ .disabled="${this._currentAskConfirmation}"
1650
+ @gv-tabs:change="${this._onChangeTab}"
1651
+ .validator="${this._changeTabValidator.bind(this)}"
1652
+ >
1653
+ ${this._renderDesign(readonlyMode)} ${this._renderConfigurationForm(readonlyMode)} ${this._renderDebug()}
1654
+ <gv-properties
1655
+ id="properties"
1656
+ slot="content"
1657
+ class="properties"
1658
+ .provider="${this.services['dynamic-property']}"
1659
+ @gv-properties:change="${this._onPropertiesChange}"
1660
+ @gv-properties:save-provider="${this._onSaveProvider}"
1661
+ @gv-properties:switch-encrypted="${this._onSwitchEncryptedProperty}"
1662
+ ?readonly="${readonlyMode}"
1663
+ encryptable="true"
1664
+ .properties="${this.definedProperties}"
1665
+ .providers="${this.propertyProviders}"
1666
+ .dynamicPropertySchema="${this.dynamicPropertySchema}"
1667
+ ></gv-properties>
1668
+ <gv-resources
1669
+ id="resources"
1670
+ slot="content"
1671
+ class="resources"
1672
+ @gv-resources:change="${this._onResourcesChange}"
1673
+ ?readonly="${readonlyMode}"
1674
+ .resources="${this.definedResources}"
1675
+ .types="${this.resourceTypes}"
1676
+ ></gv-resources>
1677
+ </gv-tabs>
1678
+ </div>`;
1679
+ }
1680
+ /**
1681
+ * Determine if the design view should be in readonly mode or not
1682
+ * It is in readonly mode if:
1683
+ * the readonly attribute is set to true
1684
+ * OR
1685
+ * the main selected flow belongs to a plan and the readonly-plans attribute is set to true
1686
+ * OR
1687
+ * the second flow for comparison belongs to a plan and the readonly-plans attribute is set to true
1688
+ * @returns {boolean|*|{type: BooleanConstructor}|{attribute: string, type: BooleanConstructor}|{type: *}|{attribute: string, type: *}}
1689
+ * @private
1690
+ */
1691
+ _getReadonlyModeForDesign() {
1692
+ if (this.readonly) {
1693
+ return true;
1694
+ }
1695
+ const flow = this.getSelectedFlow(0);
1696
+ if (!flow) {
1697
+ return false;
1698
+ }
1699
+ const { plan: flowPlan } = this._findFlowCollection(flow._id);
1700
+ const readonlyMode = flowPlan && this.readonlyPlans;
1701
+ if (readonlyMode) {
1702
+ return true;
1703
+ }
1704
+ const comparedFlow = this.getSelectedFlow(1);
1705
+ if (!comparedFlow) {
1706
+ return false;
1707
+ }
1708
+ const { plan: comparedFlowPlan } = this._findFlowCollection(comparedFlow._id);
1709
+ return comparedFlowPlan && this.readonlyPlans;
1770
1710
  }
1771
-
1772
- const {
1773
- plan: comparedFlowPlan
1774
- } = this._findFlowCollection(comparedFlow._id);
1775
-
1776
- return comparedFlowPlan && this.readonlyPlans;
1777
- }
1778
-
1779
1711
  }
1780
1712
  window.customElements.define('gv-policy-studio', GvPolicyStudio);
1781
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4vbm9kZV9tb2R1bGVzL0BncmF2aXRlZS91aS1jb21wb25lbnRzL3BvbGljeS1zdHVkaW8vZ3YtcG9saWN5LXN0dWRpby5qcyJdLCJuYW1lcyI6WyJjc3MiLCJodG1sIiwiTGl0RWxlbWVudCIsIm1ldGhvZHMiLCJkaXNwYXRjaEN1c3RvbUV2ZW50IiwiaTE4biIsImVtcHR5IiwiY2FjaGUiLCJkZWVwQ2xvbmUiLCJkZWVwRXF1YWwiLCJLZXlib2FyZEVsZW1lbnQiLCJLRVlTIiwiRkxPV19TVEVQX0ZPUk1fSUQiLCJHdlBvbGljeVN0dWRpbyIsInByb3BlcnRpZXMiLCJwb2xpY2llcyIsInR5cGUiLCJBcnJheSIsInNlcnZpY2VzIiwiT2JqZWN0IiwicmVzb3VyY2VUeXBlcyIsImF0dHJpYnV0ZSIsInByb3BlcnR5UHJvdmlkZXJzIiwiZHluYW1pY1Byb3BlcnR5U2NoZW1hIiwidGFiSWQiLCJTdHJpbmciLCJfdGFiSWQiLCJkZWZpbml0aW9uIiwiX2RlZmluaXRpb24iLCJkb2N1bWVudGF0aW9uIiwiZmxvd1NjaGVtYSIsImNvbmZpZ3VyYXRpb25TY2hlbWEiLCJfY29uZmlndXJhdGlvblNjaGVtYSIsImNvbmZpZ3VyYXRpb25JbmZvcm1hdGlvbiIsImlzRGlydHkiLCJCb29sZWFuIiwicmVmbGVjdCIsIl9kcmFnUG9saWN5IiwiX2Ryb3BQb2xpY3kiLCJzZWxlY3RlZEZsb3dzSWQiLCJfc2VsZWN0ZWRGbG93c0lkIiwiX2N1cnJlbnRQb2xpY3lJZCIsIl9zZWFyY2hQb2xpY3lRdWVyeSIsIl9zZWFyY2hGbG93UXVlcnkiLCJfZmxvd1N0ZXBTY2hlbWEiLCJfY3VycmVudEZsb3dTdGVwIiwiX3BvbGljeUZpbHRlciIsIl9mbG93RmlsdGVyIiwiX2N1cnJlbnRBc2tDb25maXJtYXRpb24iLCJoYXNQcm9wZXJ0aWVzIiwiX2hhc1Byb3BlcnRpZXMiLCJoYXNSZXNvdXJjZXMiLCJoYXNQb2xpY3lGaWx0ZXIiLCJmbG93c1RpdGxlIiwic29ydGFibGUiLCJjYW5BZGQiLCJyZWFkb25seSIsInJlYWRvbmx5UGxhbnMiLCJjYW5EZWJ1ZyIsIl9jYW5EZWJ1ZyIsImRlYnVnUmVzcG9uc2UiLCJoYXNDb25kaXRpb25hbFN0ZXBzIiwic3R5bGVzIiwiY29uc3RydWN0b3IiLCJmbG93cyIsIl90YWJzIiwiaWQiLCJ0aXRsZSIsImljb24iLCJ2YWx1ZSIsInRoZW4iLCJyZXF1ZXN0VXBkYXRlIiwiX2Zsb3dGaWx0ZXJPcHRpb25zIiwiZGVmaW5lZFBsYW5zIiwibGVuZ3RoIiwiX3BvbGljeUZpbHRlck9wdGlvbnMiLCJzcGxpY2UiLCJvbktleWJvYXJkIiwiaXNQcmVzc2VkIiwiU2hpZnQiLCJDdHJsIiwiU3BhY2UiLCJzZWFyY2giLCJzaGFkb3dSb290IiwicXVlcnlTZWxlY3RvciIsImZvY3VzIiwiaW5jbHVkZXMiLCJfZ2VuZXJhdGVGbG93c0lkIiwicmVzb3VyY2VzIiwiX2dlbmVyYXRlSWQiLCJwbGFucyIsIm1hcCIsInBsYW4iLCJfZ2VuZXJhdGVQbGFuRmxvd3NJZCIsIl9pbml0aWFsRGVmaW5pdGlvbiIsIl9zZWxlY3RGaXJzdEZsb3ciLCJpc0FycmF5IiwiZmlsdGVyIiwiX2ZpbmRGbG93QnlJZCIsIl91cGRhdGVTZWxlY3RlZEZsb3dzIiwiZGlzcGF0Y2giLCJjYW5kaWRhdGUiLCJkZWZpbmVkRmxvd3MiLCJfaWQiLCJmaW5kIiwiX2dldEZsb3dFbGVtZW50IiwiZmxvd0lkIiwiX29uRHJhZ0VuZFBvbGljeSIsInF1ZXJ5U2VsZWN0b3JBbGwiLCJmb3JFYWNoIiwiZSIsIm9uRHJhZ0VuZCIsIl9vbkRyb3BQb2xpY3kiLCJkZXRhaWwiLCJfYXNrVG9WYWxpZGF0ZUZvcm1zIiwicG9saWN5IiwidGFyZ2V0RmxvdyIsIm5hbWUiLCJkZXNjcmlwdGlvbiIsImNvbmRpdGlvbiIsImNvbmZpZ3VyYXRpb24iLCJfbmV3IiwiZmxvd1N0ZXAiLCJfZ2VuZXJhdGVGbG93U3RlcElkIiwiZmxvd0tleSIsInBvc2l0aW9uIiwiZW5hYmxlZCIsInNvdXJjZUZsb3ciLCJzb3VyY2VGbG93SWQiLCJzb3VyY2VQb3NpdGlvbiIsInNvdXJjZUZsb3dLZXkiLCJzdGVwIiwiZ3JvdXAiLCJzY2hlbWEiLCJidWlsZFNjaGVtYSIsIl9zZXRDdXJyZW50Rmxvd1N0ZXAiLCJjdXJyZW50Rmxvd0Zvcm0iLCJfZ2V0Rmxvd1N0ZXBGb3JtIiwiZGlydHkiLCJjYW5jZWxFZGl0Iiwic2V0VGltZW91dCIsIl9lZGl0Rmxvd1N0ZXAiLCJmbG93IiwidXBkYXRlQ29tcGxldGUiLCJmbG93RWxlbWVudCIsInNlbGVjdGVkU3RlcElkIiwiX2RpcnR5IiwiZ3ZGbG93IiwicmVtb3ZlQ2FuZGlkYXRlIiwiX29uRGVsZXRlUG9saWN5IiwidGFyZ2V0IiwiZWRpdGluZyIsIl9jbG9zZUZsb3dTdGVwRm9ybSIsIl9vbkRlc2lnbiIsIl9jaGFuZ2VUYWIiLCJfc3BsaXRNYWluVmlld3MiLCJjb21tb25EZXNjcmlwdGlvbiIsImNvbW1vbkNvbmRpdGlvbiIsImpzb25TY2hlbWEiLCJKU09OIiwicGFyc2UiLCJjdXJyZW50Rmxvd1N0ZXAiLCJsb2NhbFN0b3JhZ2UiLCJnZXRJdGVtIiwiX29uT3BlbkRvY3VtZW50YXRpb24iLCJfbWF4aW1pemVUb3BWaWV3IiwiX29uRWRpdEZsb3dTdGVwIiwiX2dldFJlc2l6YWJsZVZpZXdzIiwibWF4aW1pemVUb3AiLCJfbWF4aW1pemVCb3R0b21WaWV3IiwibWF4aW1pemVCb3R0b20iLCJzcGxpdCIsIl9vbkNoYW5nZUZsb3dTdGVwU3RhdGUiLCJfb25DbG9zZUZsb3dTdGVwRm9ybSIsImVyciIsImZvcmNlIiwiUHJvbWlzZSIsImFsbCIsIl9zdWJtaXRPckNvbmZpcm1Gb3JtcyIsImZvcm1zIiwiciIsIl9idWlsZERlZmluaXRpb25Ub1NhdmUiLCJnZXRDaGlsZHJlbiIsIl9jaGVja0N1cnJlbnRGbG93U3RlcCIsIkVycm9yIiwiZmxvd1N0ZXBTY2hlbWEiLCJfaW5pdGlhbFZhbHVlcyIsInNjb3BlIiwiX2VudW0iLCJlbnVtIiwiZmlsdGVyZWQiLCJkZWZhdWx0IiwiX3ZhbHVlcyIsIl9yZWZyZXNoIiwiY2xvc2VTdGVwRm9ybSIsIl9vblNlbGVjdEZsb3dzIiwiX29uQ2xvc2VEb2N1bWVudGF0aW9uIiwiX29uT3BlbkRvY3VtZW50YXRpb25Gcm9tTWVudSIsImdldFNlbGVjdGVkRmxvdyIsIl9mZXRjaERvY3VtZW50YXRpb24iLCJfb25PcGVuRG9jdW1lbnRhdGlvbkZyb21Gb3JtIiwicmVtb3ZlSXRlbSIsIl9maW5kRmxvd0NvbGxlY3Rpb24iLCJwbGFuc0Zsb3dzIiwicmVkdWNlIiwiYWNjIiwidmFsIiwiY29uY2F0IiwiaW5kZXgiLCJzZWxlY3RlZEZsb3dJZCIsIl9vblRhcmdldFBvbGljeSIsIl9vbkNoYW5nZUZsb3dTdGVwIiwidmFsdWVzIiwiX3dyaXRlRmxvd1N0ZXAiLCJmaW5kSW5kZXgiLCJfb25TdWJtaXRGbG93U3RlcCIsImMiLCJfb25DYW5jZWxGbG93IiwiX29uU3VibWl0RmxvdyIsInNlbGVjdGVkRmxvdyIsImFzc2lnbiIsIl9jcmVhdGVGbG93RnJvbVNjaGVtYSIsInNlbGVjdGVkRmxvd1VwZGF0ZWQiLCJfb25DYW5jZWxGbG93TW9kZSIsIl9vblN1Ym1pdEZsb3dNb2RlIiwiX29uQ2hhbmdlVGFiIiwiX2NoYW5nZVRhYlZhbGlkYXRvciIsImZyb20iLCJ0byIsImNvbXBvbmVudCIsImNvbmZpcm0iLCJyZXNvbHZlIiwiX29uRHJhZ1N0YXJ0Rmxvd1N0ZXAiLCJfcmVuZGVyRmxvd0VtcHR5U3RhdGUiLCJyZWFkb25seU1vZGUiLCJfb25BZGRGbG93IiwiX3JlbmRlckZsb3ciLCJoYXNFbXB0eVN0YXRlIiwiYmluZCIsIl9vbkZldGNoUmVzb3VyY2VzIiwiZXZlbnQiLCJjdXJyZW50VGFyZ2V0IiwicmVnZXhUeXBlcyIsIm9wdGlvbnMiLCJkZWZpbmVkUmVzb3VyY2VzIiwicmVzb3VyY2UiLCJSZWdFeHAiLCJ0ZXN0IiwicmVzb3VyY2VUeXBlIiwicm93IiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50IiwicGljdHVyZSIsIml0ZW0iLCJlbGVtZW50IiwiX3JlbmRlclBvbGljeSIsIl9yZW5kZXJGbG93U3RlcEZvcm0iLCJjb250ZW50IiwiaW1hZ2UiLCJfb25SZXNldEZsb3dTdGVwIiwicmVzZXQiLCJsaXN0IiwicHJlZml4IiwiaXNGbG93IiwicHJlIiwic3RlcEluZGV4IiwicG9zdCIsImdldFVwZGF0ZUNvbXBsZXRlIiwic2hvdWxkVXBkYXRlIiwiY2hhbmdlZFByb3BlcnRpZXMiLCJoYXMiLCJkcmFnUG9saWN5IiwiZHJvcFBvbGljeSIsInVwZGF0ZWQiLCJwcm9wcyIsImdyb3VwcyIsIml0ZW1zIiwic2V0SXRlbSIsIl9vbkRlbGV0ZUZsb3ciLCJfZGVsZXRlRmxvdyIsImRlZmluZWRQcm9wZXJ0aWVzIiwiX29uRHVwbGljYXRlRmxvdyIsIl9hZGRGbG93IiwicGxhbkluZGV4IiwicCIsImkiLCJfb25DaGFuZ2VGbG93U3RhdGUiLCJfb25BZGRGbG93UGxhbiIsImNvbGxlY3Rpb24iLCJkdXBsaWNhdGUiLCJwdXNoIiwibmV3RmxvdyIsIl9pbnN0YW50aWF0ZSIsInByb3BlcnRpZXNEZWZpbml0aW9uIiwiaW5pdGlhdG9yIiwicHJvcGVydHkiLCJrZXkiLCJrZXlzIiwiZW50cnkiLCJ1bmRlZmluZWQiLCJpbmRleE9mIiwic2VsZWN0ZWRGbG93cyIsIl9maW5kRmxvd0luZGV4IiwiZiIsIl9vblJlb3JkZXJGbG93cyIsIm5ld09yZGVyIiwiX29uU2VhcmNoUG9saWN5IiwiX29uQ2xlYXJQb2xpY3kiLCJfb25TZWFyY2hGbG93cyIsIl9vbkNsZWFyRmxvd3MiLCJfb25SZXNldEFsbCIsIl9maWx0ZXJOb3RWYWxpZFN0ZXAiLCJfcmVtb3ZlUHJpdmF0ZVByb3BlcnRpZXMiLCJvIiwiY29weSIsInN0YXJ0c1dpdGgiLCJmb3JtIiwiaXNWYWxpZCIsInN1Ym1pdCIsImdldFByb3BlcnRpZXNFbGVtZW50IiwiY2xvc2VQcm9taXNlcyIsImN1cnJlbnRTdGVwIiwic2F2ZWQiLCJfZGVmaW5pdGlvblNhdmVkIiwiX2J1aWxkRGVmaW5pdGlvblRvU2VuZCIsImRlZmluaXRpb25Ub1NhdmUiLCJfb25TYXZlQWxsIiwiY2F0Y2giLCJjb25zb2xlIiwiZXJyb3IiLCJfb25EZWJ1ZyIsInJlcXVlc3RFdmVudCIsInJlcXVlc3QiLCJmaWx0ZXJlZEZsb3dzIiwiZmlsdGVyZWRQbGFucyIsIl9vbkZpbHRlckZsb3dzIiwiX2dldEZpbHRlcmVkUG9saWNpZXMiLCJvblJlcXVlc3QiLCJvblJlc3BvbnNlIiwiX29uRmlsdGVyUG9saWNpZXMiLCJfcmVuZGVyRGVzaWduIiwiX3JlbmRlckZsb3dGb3JtIiwiX3JlbmRlckRlYnVnIiwicmVzcG9uc2UiLCJpc0xvYWRpbmciLCJwYXRoIiwibWV0aG9kIiwiX3JlbmRlckNvbmZpZ3VyYXRpb25Gb3JtIiwiX29uUmVzb3VyY2VzQ2hhbmdlIiwiX29uUHJvcGVydGllc0NoYW5nZSIsIl9vblNhdmVQcm92aWRlciIsInByb3ZpZGVyIiwiX29uU3dpdGNoRW5jcnlwdGVkUHJvcGVydHkiLCJyZW5kZXIiLCJfZ2V0UmVhZG9ubHlNb2RlRm9yRGVzaWduIiwiZmxvd1BsYW4iLCJjb21wYXJlZEZsb3ciLCJjb21wYXJlZEZsb3dQbGFuIiwid2luZG93IiwiY3VzdG9tRWxlbWVudHMiLCJkZWZpbmUiXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVNBLEdBQVQsRUFBY0MsSUFBZCxFQUFvQkMsVUFBcEIsUUFBc0MsS0FBdEM7QUFDQSxTQUFTQyxPQUFULFFBQXdCLGVBQXhCO0FBQ0EsU0FBU0MsbUJBQVQsUUFBb0MsZUFBcEM7QUFDQSxTQUFTQyxJQUFULFFBQXFCLGFBQXJCO0FBQ0EsT0FBTyxvQkFBUDtBQUNBLE9BQU8sa0JBQVA7QUFDQSxPQUFPLHdCQUFQO0FBQ0EsT0FBTywrQkFBUDtBQUNBLE9BQU8saUNBQVA7QUFDQSxPQUFPLDZCQUFQO0FBQ0EsT0FBTyw2QkFBUDtBQUNBLE9BQU8sc0JB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R0FBOUIsQ0FBM0I7O0FBQ0EsVUFBTW1JLFlBQVksR0FBR3lILFFBQVEsSUFBSSxLQUFLMVMsYUFBdEM7O0FBQ0EsUUFBSWlMLFlBQUosRUFBa0I7QUFDaEIsYUFBTyxJQUFQO0FBQ0Q7O0FBRUQsVUFBTTBILFlBQVksR0FBRyxLQUFLOUosZUFBTCxDQUFxQixDQUFyQixDQUFyQjs7QUFDQSxRQUFJLENBQUM4SixZQUFMLEVBQW1CO0FBQ2pCLGFBQU8sS0FBUDtBQUNEOztBQUVELFVBQU07QUFBRXhRLE1BQUFBLElBQUksRUFBRXlRO0FBQVIsUUFBNkIsS0FBSzNKLG1CQUFMLENBQXlCMEosWUFBWSxDQUFDN1AsR0FBdEMsQ0FBbkM7O0FBQ0EsV0FBTzhQLGdCQUFnQixJQUFJLEtBQUs1UyxhQUFoQztBQUNEOztBQXR1RDZEO0FBeXVEaEU2UyxNQUFNLENBQUNDLGNBQVAsQ0FBc0JDLE1BQXRCLENBQTZCLGtCQUE3QixFQUFpRDNWLGNBQWpEIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAoQykgMjAxNSBUaGUgR3Jhdml0ZWUgdGVhbSAoaHR0cDovL2dyYXZpdGVlLmlvKVxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbmltcG9ydCB7IGNzcywgaHRtbCwgTGl0RWxlbWVudCB9IGZyb20gJ2xpdCc7XG5pbXBvcnQgeyBtZXRob2RzIH0gZnJvbSAnLi4vbGliL3N0dWRpbyc7XG5pbXBvcnQgeyBkaXNwYXRjaEN1c3RvbUV2ZW50IH0gZnJvbSAnLi4vbGliL2V2ZW50cyc7XG5pbXBvcnQgeyBpMThuIH0gZnJvbSAnLi4vbGliL2kxOG4nO1xuaW1wb3J0ICcuLi9hdG9tcy9ndi1idXR0b24nO1xuaW1wb3J0ICcuLi9hdG9tcy9ndi1pY29uJztcbmltcG9ydCAnLi4vbW9sZWN1bGVzL2d2LW9wdGlvbic7XG5pbXBvcnQgJy4uL29yZ2FuaXNtcy9ndi1kb2N1bWVudGF0aW9uJztcbmltcG9ydCAnLi4vb3JnYW5pc21zL2d2LXJlc2l6YWJsZS12aWV3cyc7XG5pbXBvcnQgJy4uL29yZ2FuaXNtcy9ndi1zY2hlbWEtZm9ybSc7XG5pbXBvcnQgJy4uL29yZ2FuaXNtcy9ndi1odHRwLWNsaWVudCc7XG5pbXBvcnQgJy4uL29yZ2FuaXNtcy9ndi10YWJzJztcbmltcG9ydCAnLi4vbW9sZWN1bGVzL2d2LXJvdyc7XG5pbXBvcnQgJy4vZ3YtZmxvdyc7XG5pbXBvcnQgJy4vZ3YtZmxvdy1zdGVwJztcbmltcG9ydCAnLi9ndi1wb2xpY3ktc3R1ZGlvLW1lbnUnO1xuaW1wb3J0IHsgZW1wdHkgfSBmcm9tICcuLi9zdHlsZXMvZW1wdHknO1xuaW1wb3J0IHsgY2FjaGUgfSBmcm9tICdsaXQvZGlyZWN0aXZlcy9jYWNoZSc7XG5pbXBvcnQgeyBkZWVwQ2xvbmUsIGRlZXBFcXVhbCB9IGZyb20gJy4uL2xpYi91dGlscyc7XG5pbXBvcnQgeyBLZXlib2FyZEVsZW1lbnQsIEtFWVMgfSBmcm9tICcuLi9taXhpbnMva2V5Ym9hcmQtZWxlbWVudCc7XG5cbmNvbnN0IEZMT1dfU1RFUF9GT1JNX0lEID0gJ2Zsb3ctc3RlcC1mb3JtJztcblxuLyoqXG4gKiAgU3R1ZGlvIFBvbGljeSBjb21wb25lbnRcbiAqXG4gKiDimqDvuI8gVGhpcyBjb21wb25lbnQgaXMgYmFzZWQgb24gYGFzY2lpZG9jdG9yYCwgYGhpZ2hsaWdodC5qc2AgYW5kIGBhc2NpaWRvY3Rvci1oaWdobGlnaHQuanNgLlxuICogVG8gdXNlIHRoaXMgY29tcG9uZW50IGluIHlvdXIgcHJvamVjdCBiZSBzdXJlIHRoZSBkZXBlbmRlbmNpZXMgYXJlIGluc3RhbGxlZCBvclxuICogaW5zdGFsbCB0aGVtIHdpdGg6IGBucG0gaW5zdGFsbCBhc2NpaWRvY3RvciBoaWdobGlnaHQuanMgYXNjaWlkb2N0b3ItaGlnaGxpZ2h0LmpzIC0tc2F2ZWBcbiAqXG4gKiBAZmlyZXMgZ3YtcG9saWN5LXN0dWRpbzpzZWxlY3QtcG9saWN5IC0gU2VsZWN0IHBvbGljeSBldmVudFxuICogQGZpcmVzIGd2LXBvbGljeS1zdHVkaW86c2F2ZSAtIEV2ZW50IHNlbnQgd2hlbiBcIlNhdmVcIiBidXR0b24gaXMgY2xpY2tlZCwgaXQgY29udGFpbnMgdGhlIHdob2xlIGRlZmluaXRpb24gb2YgdGhlIEFQSVxuICogQGZpcmVzIGd2LXBvbGljeS1zdHVkaW86ZGVidWcgLSBFdmVudCBzZW50IHdoZW4gdmFsaWRhdGlvbiBidXR0b24gb2YgdGhlICdUcnkgaXQnIHRhYiBpcyBjbGlja2VkLCBpdCBjb250YWlucyB0aGUgd2hvbGUgZGVmaW5pdGlvbiBvZiB0aGUgQVBJIGFuZCB0aGUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHRyeSBpdCByZXF1ZXN0LlxuICpcbiAqIEBhdHRyIHtBcnJheX0gcG9saWNpZXMgLSBQb2xpY2llcyBhdmFpbGFibGVcbiAqIEBhdHRyIHtBcnJheX0gc2VydmljZXMgLSBTZXJ2aWNlcyBhdmFpbGFibGVcbiAqIEBhdHRyIHtBcnJheX0gcmVzb3VyY2VUeXBlcyAtIFJlc291cmNlcyB0eXBlcyBhdmFpbGFibGVcbiAqIEBhdHRyIHtBcnJheX0gcHJvcGVydHlQcm92aWRlcnMgLSBQcm92aWRlcnMgb2YgcHJvcGVydGllc1xuICogQGF0dHIge0FycmF5fSBkeW5hbWljUHJvcGVydHlTY2hlbWEgLSBTY2hlbWEgZm9yIHRoZSBkeW5hbWljIHByb3BlcnR5IGZvcm1cbiAqIEBhdHRyIHtTdHJpbmd9IHRhYklkIC0gQ3VycmVudCB0YWJJZCB0byBkaXNwbGF5IChkZXNpZ24sIHNldHRpbmdzLCBwcm9wZXJ0aWVzIG9yIHJlc291cmNlcylcbiAqIEBhdHRyIHtPYmplY3R9IGRlZmluaXRpb24gLSBUaGUgZGVmaW5pdGlvbiBvZiBmbG93c1xuICogQGF0dHIge09iamVjdH0gZG9jdW1lbnRhdGlvbiAtIFRoZSBkb2N1bWVudGF0aW9uIHRvIGRpc3BsYXlcbiAqIEBhdHRyIHtPYmplY3R9IGZsb3dTY2hlbWEgLSBUaGUgZmxvdyBmb3JtIGNvbmZpZ3VyYXRpb24gdG8gZGlzcGxheSBpbiBndi1zY2hlbWEtZm9ybSBjb21wb25lbnRcbiAqIEBhdHRyIHtPYmplY3R9IGNvbmZpZ3VyYXRpb25TY2hlbWEgLSBUaGUgZm9ybSBjb25maWd1cmF0aW9uIHRvIGRpc3BsYXkgaW4gZ3Ytc2NoZW1hLWZvcm0gY29tcG9uZW50XG4gKiBAYXR0ciB7T2JqZWN0fSBjb25maWd1cmF0aW9uSW5mb3JtYXRpb24gLSBUaGUgaW5mb3JtYXRpb24gcmVsYXRlZCB0byBhcGkgY29uZmlndXJhdGlvbiB0YWJcbiAqIEBhdHRyIHtCb29sZWFufSBpc0RpcnR5IC0gdHJ1ZSBpZiBjb21wb25lbnQgaXMgZGlydHlcbiAqIEBhdHRyIHtBcnJheX0gc2VsZWN0ZWRGbG93c0lkIC0gVGhlIHNlbGVjdGVkIGZsb3dzIGlkXG4gKiBAYXR0ciB7Qm9vbGVhbn0gc29ydGFibGUgLSB0cnVlIGlmIGZsb3dzIGFyZSBzb3J0YWJsZVxuICogQGF0dHIge0Jvb2xlYW59IHJlYWRvbmx5IC0gdHJ1ZSBpZiByZWFkb25seVxuICogQGF0dHIge0Jvb2xlYW59IHJlYWRvbmx5LXBsYW5zIC0gdHJ1ZSBpZiBwbGFucycgZmxvd3MgY2FuJ3QgYmUgbW9kaWZpZWRcbiAqIEBhdHRyIHtCb29sZWFufSBjYW4tYWRkIC0gdHJ1ZSBpZiB1c2VyIGNhbiBhZGQgZmxvd1xuICogQGF0dHIge1N0cmluZ30gZmxvd3NUaXRsZSAtIGZsb3dzIG1lbnUgdGl0bGVcbiAqIEBhdHRyIHtCb29sZWFufSBoYXMtcG9saWN5LWZpbHRlciAtIHRydWUgaWYgcG9saWNpZXMgaGF2ZSBvblJlcXVlc3Qvb25SZXNwb25zZSBwcm9wZXJ0aWVzXG4gKiBAYXR0ciB7Qm9vbGVhbn0gY2FuLWRlYnVnIC0gdHJ1ZSBpZiBkZWJ1ZyB0YWIgc2hvdWxkIGJlIGRpc3BsYXllZFxuICogQGF0dHIge09iamVjdH0gZGVidWdSZXNwb25zZSAtIHRydWUgaWYgZGVidWcgdGFiIHNob3VsZCBiZSBkaXNwbGF5ZWRcbiAqIEBhdHRyIHtCb29sZWFufSBoYXMtY29uZGl0aW9uYWwtc3RlcHMgLSB0cnVlIGlmIHN0ZXBzIGNhbiBiZSBjb25kaXRpb25lZFxuICovXG5leHBvcnQgY2xhc3MgR3ZQb2xpY3lTdHVkaW8gZXh0ZW5kcyBLZXlib2FyZEVsZW1lbnQoTGl0RWxlbWVudCkge1xuICBzdGF0aWMgZ2V0IHByb3BlcnRpZXMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHBvbGljaWVzOiB7IHR5cGU6IEFycmF5IH0sXG4gICAgICBzZXJ2aWNlczogeyB0eXBlOiBPYmplY3QgfSxcbiAgICAgIHJlc291cmNlVHlwZXM6IHsgdHlwZTogQXJyYXksIGF0dHJpYnV0ZTogJ3Jlc291cmNlLXR5cGVzJyB9LFxuICAgICAgcHJvcGVydHlQcm92aWRlcnM6IHsgdHlwZTogQXJyYXksIGF0dHJpYnV0ZTogJ3Byb3BlcnR5LXByb3ZpZGVycycgfSxcbiAgICAgIGR5bmFtaWNQcm9wZXJ0eVNjaGVtYTogeyB0eXBlOiBPYmplY3QsIGF0dHJpYnV0ZTogJ2R5bmFtaWMtcHJvcGVydHktc2NoZW1hJyB9LFxuICAgICAgdGFiSWQ6IHsgdHlwZTogU3RyaW5nLCBhdHRyaWJ1dGU6ICd0YWItaWQnIH0sXG4gICAgICBfdGFiSWQ6IHsgdHlwZTogU3RyaW5nLCBhdHRyaWJ1dGU6IGZhbHNlIH0sXG4gICAgICBkZWZpbml0aW9uOiB7IHR5cGU6IE9iamVjdCB9LFxuICAgICAgX2RlZmluaXRpb246IHsgdHlwZTogT2JqZWN0LCBhdHRyaWJ1dGU6IGZhbHNlIH0sXG4gICAgICBkb2N1bWVudGF0aW9uOiB7IHR5cGU6IE9iamVjdCB9LFxuICAgICAgZmxvd1NjaGVtYTogeyB0eXBlOiBPYmplY3QsIGF0dHJpYnV0ZTogJ2Zsb3ctc2NoZW1hJyB9LFxuICAgICAgY29uZmlndXJhdGlvblNjaGVtYTogeyB0eXBlOiBPYmplY3QsIGF0dHJpYnV0ZTogJ2NvbmZpZ3VyYXRpb24tc2NoZW1hJyB9LFxuICAgICAgX2NvbmZpZ3VyYXRpb25TY2hlbWE6IHsgdHlwZTogT2JqZWN0LCBhdHRyaWJ1dGU6IGZhbHNlIH0sXG4gICAgICBjb25maWd1cmF0aW9uSW5mb3JtYXRpb246IHsgdHlwZTogU3RyaW5nLCBhdHRyaWJ1dGU6ICdjb25maWd1cmF0aW9uLWluZm9ybWF0aW9uJyB9LFxuICAgICAgaXNEaXJ0eTogeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6ICdkaXJ0eScsIHJlZmxlY3Q6IHRydWUgfSxcbiAgICAgIF9kcmFnUG9saWN5OiB7IHR5cGU6IE9iamVjdCwgYXR0cmlidXRlOiBmYWxzZSB9LFxuICAgICAgX2Ryb3BQb2xpY3k6IHsgdHlwZTogT2JqZWN0LCBhdHRyaWJ1dGU6IGZhbHNlIH0sXG4gICAgICBzZWxlY3RlZEZsb3dzSWQ6IHsgdHlwZTogQXJyYXksIGF0dHJpYnV0ZTogJ3NlbGVjdGVkLWZsb3dzLWlkJyB9LFxuICAgICAgX3NlbGVjdGVkRmxvd3NJZDogeyB0eXBlOiBBcnJheSwgYXR0cmlidXRlOiBmYWxzZSB9LFxuICAgICAgX2N1cnJlbnRQb2xpY3lJZDogeyB0eXBlOiBTdHJpbmcsIGF0dHJpYnV0ZTogZmFsc2UgfSxcbiAgICAgIF9zZWFyY2hQb2xpY3lRdWVyeTogeyB0eXBlOiBTdHJpbmcsIGF0dHJpYnV0ZTogZmFsc2UgfSxcbiAgICAgIF9zZWFyY2hGbG93UXVlcnk6IHsgdHlwZTogU3RyaW5nLCBhdHRyaWJ1dGU6IGZhbHNlIH0sXG4gICAgICBfZmxvd1N0ZXBTY2hlbWE6IHsgdHlwZTogT2JqZWN0LCBhdHRyaWJ1dGU6IGZhbHNlIH0sXG4gICAgICBfY3VycmVudEZsb3dTdGVwOiB7IHR5cGU6IE9iamVjdCwgYXR0cmlidXRlOiBmYWxzZSB9LFxuICAgICAgX3BvbGljeUZpbHRlcjogeyB0eXBlOiBBcnJheSwgYXR0cmlidXRlOiBmYWxzZSB9LFxuICAgICAgX2Zsb3dGaWx0ZXI6IHsgdHlwZTogQXJyYXksIGF0dHJpYnV0ZTogZmFsc2UgfSxcbiAgICAgIF9jdXJyZW50QXNrQ29uZmlybWF0aW9uOiB7IHR5cGU6IEJvb2xlYW4sIGF0dHJpYnV0ZTogZmFsc2UgfSxcbiAgICAgIGhhc1Byb3BlcnRpZXM6IHsgdHlwZTogQm9vbGVhbiwgYXR0cmlidXRlOiAnaGFzLXByb3BlcnRpZXMnIH0sXG4gICAgICBfaGFzUHJvcGVydGllczogeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6IGZhbHNlIH0sXG4gICAgICBoYXNSZXNvdXJjZXM6IHsgdHlwZTogQm9vbGVhbiwgYXR0cmlidXRlOiAnaGFzLXJlc291cmNlcycgfSxcbiAgICAgIGhhc1BvbGljeUZpbHRlcjogeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6ICdoYXMtcG9saWN5LWZpbHRlcicgfSxcbiAgICAgIGZsb3dzVGl0bGU6IHsgdHlwZTogU3RyaW5nLCBhdHRyaWJ1dGU6ICdmbG93cy10aXRsZScgfSxcbiAgICAgIHNvcnRhYmxlOiB7IHR5cGU6IEJvb2xlYW4gfSxcbiAgICAgIGNhbkFkZDogeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6ICdjYW4tYWRkJyB9LFxuICAgICAgcmVhZG9ubHk6IHsgdHlwZTogQm9vbGVhbiB9LFxuICAgICAgcmVhZG9ubHlQbGFuczogeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6ICdyZWFkb25seS1wbGFucycgfSxcbiAgICAgIGNhbkRlYnVnOiB7IHR5cGU6IEJvb2xlYW4sIGF0dHJpYnV0ZTogJ2Nhbi1kZWJ1ZycgfSxcbiAgICAgIF9jYW5EZWJ1ZzogeyB0eXBlOiBCb29sZWFuLCBhdHRyaWJ1dGU6IGZhbHNlIH0sXG4gICAgICBkZWJ1Z1Jlc3BvbnNlOiB7IHR5cGU6IE9iamVjdCwgYXR0cmlidXRlOiAnZGVidWctcmVzcG9uc2UnIH0sXG4gICAgICBoYXNDb25kaXRpb25hbFN0ZXBzOiB7IHR5cGU6IEJvb2xlYW4sIGF0dHJpYnV0ZTogJ2hhcy1jb25kaXRpb25hbC1zdGVwcycgfSxcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIGdldCBzdHlsZXMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIGVtcHR5LFxuICAgICAgbWV0aG9kcyxcbiAgICAgIC8vIGxhbmd1YWdlPUNTU1xuICAgICAgY3NzYFxuICAgICAgICA6aG9zdCB7XG4gICAgICAgICAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgICAgICAgICAtLWhlaWdodDogdmFyKC0tZ3YtcG9saWN5LXN0dWRpby0taCwgY2FsYygxMDB2aCAtIDMycHgpKTtcbiAgICAgICAgICBoZWlnaHQ6IHZhcigtLWhlaWdodCk7XG4gICAgICAgICAgLS1oZWlnaHQtaW4tdGFiczogY2FsYyh2YXIoLS1oZWlnaHQpIC0gMjVweCk7XG4gICAgICAgIH1cblxuICAgICAgICAuYm94IHtcbiAgICAgICAgICBoZWlnaHQ6IHZhcigtLWhlaWdodCk7XG4gICAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgfVxuXG4gICAgICAgIC5kZXNpZ24sXG4gICAgICAgIC5wcm9wZXJ0aWVzIHtcbiAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICB9XG5cbiAgICAgICAgZ3YtcmVzaXphYmxlLXZpZXdzIHtcbiAgICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5lZGl0YWJsZS1uYW1lIHtcbiAgICAgICAgICBwYWRkaW5nOiAwLjVyZW0gMXJlbTtcbiAgICAgICAgICBmb250LXNpemU6IDE2cHg7XG4gICAgICAgIH1cblxuICAgICAgICAuZWRpdGFibGUtbmFtZSBzcGFuIHtcbiAgICAgICAgICBjb2xvcjogI2JmYmZiZjtcbiAgICAgICAgICBmb250LXNpemU6IDEycHg7XG4gICAgICAgIH1cblxuICAgICAgICAuZm9ybV9fY29udHJvbCB7XG4gICAgICAgICAgbWFyZ2luOiAwLjVyZW07XG4gICAgICAgIH1cblxuICAgICAgICBndi1pbnB1dCB7XG4gICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIH1cblxuICAgICAgICAuZmxvdy1uYW1lIHtcbiAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgIH1cblxuICAgICAgICAuZmxvdy1uYW1lLmRpcnR5IHtcbiAgICAgICAgICBmb250LXN0eWxlOiBpdGFsaWM7XG4gICAgICAgICAgb3BhY2l0eTogMC44O1xuICAgICAgICB9XG5cbiAgICAgICAgLmZsb3ctbmFtZSBndi1pY29uIHtcbiAgICAgICAgICAtLWd2LWljb24tLXM6IDI0cHg7XG4gICAgICAgICAgbWFyZ2luLXJpZ2h0OiAwLjJyZW07XG4gICAgICAgIH1cblxuICAgICAgICAuZmxvdy1wYXRoIHtcbiAgICAgICAgICBtYXJnaW4tbGVmdDogMC4ycmVtO1xuICAgICAgICB9XG5cbiAgICAgICAgLnRpdGxlX21ldGhvZHMge1xuICAgICAgICAgIG1hcmdpbi1sZWZ0OiAwLjVyZW07XG4gICAgICAgIH1cblxuICAgICAgICAudHdvLWNvbHMge1xuICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICB9XG5cbiAgICAgICAgLnR3by1jb2xzID4gKiB7XG4gICAgICAgICAgZmxleDogMTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5sZWZ0LW1lbnUge1xuICAgICAgICAgIGJvcmRlci1sZWZ0OiAxcHggc29saWQgI2Q5ZDlkOTtcbiAgICAgICAgICBoZWlnaHQ6IHZhcigtLWhlaWdodC1pbi10YWJzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5yaWdodC1tZW51IHtcbiAgICAgICAgICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjZDlkOWQ5O1xuICAgICAgICAgIGhlaWdodDogdmFyKC0taGVpZ2h0LWluLXRhYnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgLnR3by1jb2xzID4gKjpmaXJzdC1jaGlsZCB7XG4gICAgICAgICAgYm9yZGVyLXJpZ2h0OiAxcHggc29saWQgI2Q5ZDlkOTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5mbG93LXN0ZXBfX2NvbnRhaW5lciB7XG4gICAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gICAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgICAgICAgICBoZWlnaHQ6IDk5JTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5mbG93LXN0ZXBfX2Zvcm0ge1xuICAgICAgICAgIHBhZGRpbmc6IDAgMC41cmVtO1xuICAgICAgICAgIG92ZXJmbG93OiBhdXRvO1xuICAgICAgICB9XG5cbiAgICAgICAgLmZsb3ctc3RlcF9fZm9ybS10aXRsZSB7XG4gICAgICAgICAgdGV4dC10cmFuc2Zvcm06IHVwcGVyY2FzZTtcbiAgICAgICAgICBsZXR0ZXItc3BhY2luZzogMC4ycmVtO1xuICAgICAgICB9XG5cbiAgICAgICAgZ3YtdGFicyB7XG4gICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICAgICAgfVxuXG4gICAgICAgIGd2LXJlc2l6YWJsZS12aWV3cyxcbiAgICAgICAgZ3YtcHJvcGVydGllcyxcbiAgICAgICAgZ3YtcmVzb3VyY2VzIHtcbiAgICAgICAgICBoZWlnaHQ6IHZhcigtLWhlaWdodC1pbi10YWJzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGd2LXByb3BlcnRpZXMsXG4gICAgICAgIGd2LXJlc291cmNlcyB7XG4gICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIH1cblxuICAgICAgICBndi1wcm9wZXJ0aWVzLnByb3BlcnRpZXMge1xuICAgICAgICAgIC0tZ3YtcHJvcGVydGllcy10YWJsZS0tY29sbWc6IDEwcHg7XG4gICAgICAgIH1cblxuICAgICAgICAuYXBpLXNldHRpbmdzIHtcbiAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgICAgYm9yZGVyLWxlZnQ6IDFweCBzb2xpZCAjYmZiZmJmO1xuICAgICAgICAgIGhlaWdodDogdmFyKC0taGVpZ2h0LWluLXRhYnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgLmRlYnVnIHtcbiAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgICAgYm9yZGVyLWxlZnQ6IDFweCBzb2xpZCAjYmZiZmJmO1xuICAgICAgICAgIGhlaWdodDogdmFyKC0taGVpZ2h0LWluLXRhYnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgLmFwaS1zZXR0aW5ncy1pbmZvcm1hdGlvbiB7XG4gICAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICB9XG5cbiAgICAgICAgLmFwaS1zZXR0aW5ncy1pbmZvcm1hdGlvbl9faWNvbiB7XG4gICAgICAgICAgLS1ndi1pY29uLS1jOiB2YXIoLS1ndi10aGVtZS1jb2xvciwgIzVhNzY4NCk7XG4gICAgICAgICAgLS1ndi1pY29uLW9wYWNpdHktLWM6IHZhcigtLWd2LXRoZW1lLWNvbG9yLWluZm8tbGlnaHQsICM2NGI1ZjYpO1xuICAgICAgICB9XG5cbiAgICAgICAgLmFwaS1zZXR0aW5ncy1pbmZvcm1hdGlvbl9fYmxvY2txdW90ZSxcbiAgICAgICAgLmRlYnVnLWluZm9ybWF0aW9uX19ibG9ja3F1b3RlIHtcbiAgICAgICAgICBib3JkZXItbGVmdDogMXB4IHNvbGlkIHZhcigtLWd2LXRoZW1lLWNvbG9yLCAjNWE3Njg0KTtcbiAgICAgICAgICBtYXJnaW46IDE1cHg7XG4gICAgICAgICAgcGFkZGluZy1sZWZ0OiAxNXB4O1xuICAgICAgICAgIGZvbnQtc2l6ZTogMTRweDtcbiAgICAgICAgfVxuXG4gICAgICAgIC5mbG93LXNldHRpbmdzIGd2LXNjaGVtYS1mb3JtIHtcbiAgICAgICAgICBmbGV4OiAxO1xuICAgICAgICAgIHBhZGRpbmc6IDAuNXJlbTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5zZWFyY2gge1xuICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAganVzdGlmeS1jb250ZW50OiBzdHJldGNoO1xuICAgICAgICB9XG5cbiAgICAgICAgZ3YtaW5wdXQge1xuICAgICAgICAgIG1hcmdpbjogMC4ycmVtIDA7XG4gICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIH1cblxuICAgICAgICAuaGVhZGVyLWFjdGlvbnMsXG4gICAgICAgIC5zZWFyY2gtcG9saWNpZXMge1xuICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICAgIG1hcmdpbjogMC41cmVtO1xuICAgICAgICB9XG5cbiAgICAgICAgLnNlYXJjaC1wb2xpY2llcyB7XG4gICAgICAgICAgbWFyZ2luOiAxLjVyZW0gMC41cmVtIDAuNXJlbTtcbiAgICAgICAgfVxuXG4gICAgICAgIC5mb290ZXItYWN0aW9ucyA+IGd2LWJ1dHRvbi5idG4tbGFyZ2UsXG4gICAgICAgIC5mb290ZXItYWN0aW9ucyA+IGd2LW9wdGlvbiB7XG4gICAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIH1cblxuICAgICAgICAuZm9vdGVyLWFjdGlvbnMge1xuICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICAgIHBhZGRpbmc6IDAuNXJlbSAwO1xuICAgICAgICAgIG1hcmdpbjogMC41cmVtIDE1cHg7XG4gICAgICAgICAgYm9yZGVyLXRvcDogMXB4IHNvbGlkICNiZmJmYmY7XG4gICAgICAgIH1cblxuICAgICAgICAuaGVhZGVyLWFjdGlvbnMgLnRpdGxlIHtcbiAgICAgICAgICB0ZXh0LXRyYW5zZm9ybTogdXBwZXJjYXNlO1xuICAgICAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgICAgICAgICBsZXR0ZXItc3BhY2luZzogMC4zcmVtO1xuICAgICAgICAgIGNvbG9yOiAjYmZiZmJmO1xuICAgICAgICAgIGZvbnQtc2l6ZTogMThweDtcbiAgICAgICAgICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICAgICAgICAgIG92ZXJmbG93OiBoaWRkZW47XG4gICAgICAgICAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gICAgICAgICAgd2lkdGg6IDI0MHB4O1xuICAgICAgICAgIG1pbi1oZWlnaHQ6IDI1cHg7XG4gICAgICAgIH1cblxuICAgICAgICAuaGVhZGVyLWFjdGlvbnMgPiAqLFxuICAgICAgICAuc2VhcmNoLXBvbGljaWVzID4gKiB7XG4gICAgICAgICAgbWFyZ2luLWJvdHRvbTogMXJlbTtcbiAgICAgICAgfVxuICAgICAgYCxcbiAgICBdO1xuICB9XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmlzRGlydHkgPSBmYWxzZTtcbiAgICB0aGlzLnBvbGljaWVzID0gW107XG4gICAgdGhpcy5yZXNvdXJjZVR5cGVzID0gW107XG4gICAgdGhpcy50YWJJZCA9ICdkZXNpZ24nO1xuICAgIHRoaXMuc2VsZWN0ZWRGbG93c0lkID0gW107XG4gICAgdGhpcy5mbG93c1RpdGxlID0gJ0Zsb3dzJztcbiAgICB0aGlzLnNvcnRhYmxlID0gZmFsc2U7XG4gICAgdGhpcy5zZXJ2aWNlcyA9IHt9O1xuICAgIHRoaXMuX2RlZmluaXRpb24gPSB7XG4gICAgICBmbG93czogW10sXG4gICAgfTtcbiAgICB0aGlzLl90YWJzID0gW3sgaWQ6ICdkZXNpZ24nLCB0aXRsZTogJ0Rlc2lnbicsIGljb246ICduYXZpZ2F0aW9uOmV4Y2hhbmdlJyB9XTtcbiAgICB0aGlzLl9wb2xpY3lGaWx0ZXIgPSBbXTtcbiAgICB0aGlzLl9mbG93RmlsdGVyID0gW107XG4gIH1cblxuICBzZXQgaGFzUHJvcGVydGllcyh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgaW1wb3J0KCcuLi9vcmdhbmlzbXMvZ3YtcHJvcGVydGllcycpLnRoZW4oKCkgPT4ge1xuICAgICAgICB0aGlzLl90YWJzID0gWy4uLnRoaXMuX3RhYnMsIHsgaWQ6ICdwcm9wZXJ0aWVzJywgdGl0bGU6ICdQcm9wZXJ0aWVzJywgaWNvbjogJ2dlbmVyYWw6c2V0dGluZ3MjMScgfV07XG4gICAgICAgIHRoaXMucmVxdWVzdFVwZGF0ZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuX2hhc1Byb3BlcnRpZXMgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBoYXNQcm9wZXJ0aWVzKCkge1xuICAgIHJldHVybiB0aGlzLl9oYXNQcm9wZXJ0aWVzO1xuICB9XG5cbiAgc2V0IGhhc1Jlc291cmNlcyh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgaW1wb3J0KCcuLi9vcmdhbmlzbXMvZ3YtcmVzb3VyY2VzJykudGhlbigoKSA9PiB7XG4gICAgICAgIHRoaXMuX3RhYnMgPSBbLi4udGhpcy5fdGFicywgeyBpZDogJ3Jlc291cmNlcycsIHRpdGxlOiAnUmVzb3VyY2VzJywgaWNvbjogJ2dlbmVyYWw6c2V0dGluZ3MjNScgfV07XG4gICAgICAgIHRoaXMucmVxdWVzdFVwZGF0ZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgc2V0IGNhbkRlYnVnKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLl90YWJzID0gWy4uLnRoaXMuX3RhYnMsIHsgaWQ6ICdkZWJ1ZycsIHRpdGxlOiAnVHJ5IGl0JywgaWNvbjogJ2NvbnRlbnQ6c2VuZCcgfV07XG4gICAgfVxuICB9XG5cbiAgZ2V0IF9mbG93RmlsdGVyT3B0aW9ucygpIHtcbiAgICBpZiAodGhpcy5kZWZpbmVkUGxhbnMubGVuZ3RoID4gMCkge1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAgeyBpZDogJ2FwaScsIHRpdGxlOiAnQXBpJywgaWNvbjogJ3Nob3BwaW5nOmJveCMzJyB9LFxuICAgICAgICB7IGlkOiAncGxhbicsIHRpdGxlOiAnUGxhbnMnLCBpY29uOiAnc2hvcHBpbmc6c2FsZSMyJyB9LFxuICAgICAgXTtcbiAgICB9XG4gIH1cblxuICBzZXQgaGFzUG9saWN5RmlsdGVyKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLl9wb2xpY3lGaWx0ZXJPcHRpb25zID0gW1xuICAgICAgICB7IGlkOiAnb25SZXF1ZXN0JywgdGl0bGU6ICdSZXF1ZXN0JywgaWNvbjogJ25hdmlnYXRpb246YXJyb3ctZnJvbS1sZWZ0JyB9LFxuICAgICAgICB7IGlkOiAnb25SZXNwb25zZScsIHRpdGxlOiAnUmVzcG9uc2UnLCBpY29uOiAnbmF2aWdhdGlvbjphcnJvdy1mcm9tLXJpZ2h0JyB9LFxuICAgICAgXTtcbiAgICB9XG4gIH1cblxuICBzZXQgY29uZmlndXJhdGlvblNjaGVtYSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5fdGFicy5zcGxpY2UoMSwgMCwgeyBpZDogJ3NldHRpbmdzJywgdGl0bGU6ICdDb25maWd1cmF0aW9uJywgaWNvbjogJ2dlbmVyYWw6c2V0dGluZ3MjMicgfSk7XG4gICAgfVxuXG4gICAgdGhpcy5fY29uZmlndXJhdGlvblNjaGVtYSA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IGNvbmZpZ3VyYXRpb25TY2hlbWEoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbmZpZ3VyYXRpb25TY2hlbWE7XG4gIH1cblxuICBvbktleWJvYXJkKCkge1xuICAgIGlmICh0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID09IG51bGwpIHtcbiAgICAgIGlmICh0aGlzLmlzUHJlc3NlZChLRVlTLlNoaWZ0LCBLRVlTLkN0cmwsIEtFWVMuU3BhY2UpKSB7XG4gICAgICAgIGNvbnN0IHNlYXJjaCA9IHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKCcjc2VhcmNoLXBvbGljeScpO1xuICAgICAgICBpZiAoc2VhcmNoKSB7XG4gICAgICAgICAgc2VhcmNoLmZvY3VzKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1ByZXNzZWQoS0VZUy5DdHJsLCBLRVlTLlNwYWNlKSkge1xuICAgICAgICBjb25zdCBzZWFyY2ggPSB0aGlzLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvcignI3NlYXJjaC1mbG93Jyk7XG4gICAgICAgIGlmIChzZWFyY2gpIHtcbiAgICAgICAgICBzZWFyY2guZm9jdXMoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHNldCB0YWJJZCh0YWJJZCkge1xuICAgIGlmICh0YWJJZCAhPSBudWxsICYmIFsnZGVzaWduJywgJ3NldHRpbmdzJywgJ3Byb3BlcnRpZXMnLCAncmVzb3VyY2VzJywgJ2RlYnVnJ10uaW5jbHVkZXModGFiSWQpKSB7XG4gICAgICB0aGlzLl90YWJJZCA9IHRhYklkO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl90YWJJZCA9ICdkZXNpZ24nO1xuICAgIH1cbiAgfVxuXG4gIGdldCB0YWJJZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fdGFiSWQ7XG4gIH1cblxuICBzZXQgZGVmaW5pdGlvbihkZWZpbml0aW9uKSB7XG4gICAgaWYgKGRlZmluaXRpb24pIHtcbiAgICAgIGNvbnN0IGZsb3dzID0gdGhpcy5fZ2VuZXJhdGVGbG93c0lkKGRlZmluaXRpb24uZmxvd3MpO1xuICAgICAgY29uc3QgcmVzb3VyY2VzID0gdGhpcy5fZ2VuZXJhdGVJZCgncmVzb3VyY2UtJywgZGVmaW5pdGlvbi5yZXNvdXJjZXMpO1xuICAgICAgY29uc3QgcGxhbnMgPVxuICAgICAgICBkZWZpbml0aW9uLnBsYW5zID09IG51bGxcbiAgICAgICAgICA/IFtdXG4gICAgICAgICAgOiBkZWZpbml0aW9uLnBsYW5zLm1hcCgocGxhbikgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4geyAuLi5wbGFuLCBmbG93czogdGhpcy5fZ2VuZXJhdGVQbGFuRmxvd3NJZChwbGFuKSB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICB0aGlzLl9pbml0aWFsRGVmaW5pdGlvbiA9IHsgLi4uZGVmaW5pdGlvbiwgZmxvd3MsIHJlc291cmNlcywgcGxhbnMgfTtcbiAgICAgIHRoaXMuX2RlZmluaXRpb24gPSBkZWVwQ2xvbmUodGhpcy5faW5pdGlhbERlZmluaXRpb24pO1xuICAgICAgdGhpcy5pc0RpcnR5ID0gZmFsc2U7XG4gICAgICB0aGlzLl9zZWxlY3RGaXJzdEZsb3coKTtcbiAgICB9XG4gIH1cblxuICBnZXQgZGVmaW5pdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fZGVmaW5pdGlvbjtcbiAgfVxuXG4gIHNldCBzZWxlY3RlZEZsb3dzSWQoc2VsZWN0ZWRGbG93c0lkKSB7XG4gICAgaWYgKHNlbGVjdGVkRmxvd3NJZCAhPSBudWxsICYmIEFycmF5LmlzQXJyYXkoc2VsZWN0ZWRGbG93c0lkKSkge1xuICAgICAgdGhpcy5fc2VsZWN0ZWRGbG93c0lkID0gc2VsZWN0ZWRGbG93c0lkLmZpbHRlcigoaWQpID0+IHRoaXMuX2ZpbmRGbG93QnlJZChpZCkgIT0gbnVsbCk7XG4gICAgICBpZiAoc2VsZWN0ZWRGbG93c0lkLmxlbmd0aCAhPT0gdGhpcy5fc2VsZWN0ZWRGbG93c0lkLmxlbmd0aCkge1xuICAgICAgICB0aGlzLl9zZWxlY3RGaXJzdEZsb3codHJ1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0IHNlbGVjdGVkRmxvd3NJZCgpIHtcbiAgICByZXR1cm4gdGhpcy5fc2VsZWN0ZWRGbG93c0lkLmZpbHRlcigoaWQpID0+IHRoaXMuX2ZpbmRGbG93QnlJZChpZCkgIT0gbnVsbCk7XG4gIH1cblxuICBfdXBkYXRlU2VsZWN0ZWRGbG93cyhzZWxlY3RlZEZsb3dzSWQpIHtcbiAgICB0aGlzLnNlbGVjdGVkRmxvd3NJZCA9IHNlbGVjdGVkRmxvd3NJZDtcbiAgICBkaXNwYXRjaEN1c3RvbUV2ZW50KHRoaXMsICdzZWxlY3QtZmxvd3MnLCB7IGZsb3dzOiB0aGlzLnNlbGVjdGVkRmxvd3NJZCB9KTtcbiAgfVxuXG4gIF9zZWxlY3RGaXJzdEZsb3coZGlzcGF0Y2ggPSBmYWxzZSkge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkRmxvd3NJZC5sZW5ndGggPT09IDApIHtcbiAgICAgIGxldCBjYW5kaWRhdGUgPSBudWxsO1xuICAgICAgaWYgKHRoaXMuZGVmaW5lZEZsb3dzLmxlbmd0aCA+IDAgJiYgdGhpcy5kZWZpbmVkRmxvd3NbMF0uX2lkICE9IG51bGwpIHtcbiAgICAgICAgY2FuZGlkYXRlID0gdGhpcy5kZWZpbmVkRmxvd3NbMF07XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuZGVmaW5lZFBsYW5zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgcGxhbiA9IHRoaXMuZGVmaW5lZFBsYW5zLmZpbmQoKHBsYW4pID0+IHBsYW4uZmxvd3MgIT0gbnVsbCAmJiBwbGFuLmZsb3dzLmxlbmd0aCA+IDAgJiYgcGxhbi5mbG93c1swXS5faWQgIT0gbnVsbCk7XG4gICAgICAgIGlmIChwbGFuKSB7XG4gICAgICAgICAgY2FuZGlkYXRlID0gcGxhbi5mbG93c1swXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGNhbmRpZGF0ZSAhPSBudWxsKSB7XG4gICAgICAgIGlmIChkaXNwYXRjaCkge1xuICAgICAgICAgIHRoaXMuX3VwZGF0ZVNlbGVjdGVkRmxvd3MoW2NhbmRpZGF0ZS5faWRdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkRmxvd3NJZCA9IFtjYW5kaWRhdGUuX2lkXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIF9nZXRGbG93RWxlbWVudChmbG93SWQpIHtcbiAgICByZXR1cm4gdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3IoYFtpZD1cIiR7Zmxvd0lkfVwiXWApO1xuICB9XG5cbiAgX29uRHJhZ0VuZFBvbGljeSgpIHtcbiAgICB0aGlzLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvckFsbCgnZ3YtZmxvdycpLmZvckVhY2goKGUpID0+IGUub25EcmFnRW5kKCkpO1xuICB9XG5cbiAgYXN5bmMgX29uRHJvcFBvbGljeSh7IGRldGFpbCB9KSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuX2Fza1RvVmFsaWRhdGVGb3JtcygpO1xuXG4gICAgICBjb25zdCBwb2xpY3kgPSBkZXRhaWwucG9saWN5O1xuICAgICAgY29uc3QgdGFyZ2V0RmxvdyA9IHRoaXMuX2ZpbmRGbG93QnlJZChkZXRhaWwuZmxvd0lkKTtcblxuICAgICAgbGV0IG5hbWUgPSBwb2xpY3kubmFtZTtcbiAgICAgIGxldCBkZXNjcmlwdGlvbiA9ICcnO1xuICAgICAgbGV0IGNvbmRpdGlvbiA9ICcnO1xuICAgICAgbGV0IGNvbmZpZ3VyYXRpb24gPSB7fTtcbiAgICAgIGxldCBfaWQ7XG4gICAgICBsZXQgX25ldyA9IGZhbHNlO1xuICAgICAgaWYgKGRldGFpbC5mbG93U3RlcCkge1xuICAgICAgICBfaWQgPSBkZXRhaWwuZmxvd1N0ZXAuX2lkO1xuICAgICAgICBuYW1lID0gZGV0YWlsLmZsb3dTdGVwLm5hbWU7XG4gICAgICAgIGRlc2NyaXB0aW9uID0gZGV0YWlsLmZsb3dTdGVwLmRlc2NyaXB0aW9uIHx8ICcnO1xuICAgICAgICBjb25kaXRpb24gPSBkZXRhaWwuZmxvd1N0ZXAuY29uZGl0aW9uIHx8ICcnO1xuICAgICAgICBjb25maWd1cmF0aW9uID0gZGV0YWlsLmZsb3dTdGVwLmNvbmZpZ3VyYXRpb247XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfaWQgPSB0aGlzLl9nZW5lcmF0ZUZsb3dTdGVwSWQodGFyZ2V0Rmxvdy5faWQsIGRldGFpbC5mbG93S2V5LCBkZXRhaWwucG9zaXRpb24pO1xuICAgICAgICBfbmV3ID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmxvd1N0ZXAgPSB7IF9pZCwgX25ldywgbmFtZSwgcG9saWN5OiBwb2xpY3kuaWQsIGRlc2NyaXB0aW9uLCBjb25kaXRpb24sIGVuYWJsZWQ6IHRydWUsIGNvbmZpZ3VyYXRpb24gfTtcbiAgICAgIGNvbnN0IHNvdXJjZUZsb3cgPSBkZXRhaWwuc291cmNlRmxvd0lkICE9IG51bGwgPyB0aGlzLl9maW5kRmxvd0J5SWQoZGV0YWlsLnNvdXJjZUZsb3dJZCkgOiB0YXJnZXRGbG93O1xuXG4gICAgICBpZiAoZGV0YWlsLnNvdXJjZVBvc2l0aW9uICE9IG51bGwpIHtcbiAgICAgICAgaWYgKGRldGFpbC5zb3VyY2VGbG93S2V5ICYmIGRldGFpbC5zb3VyY2VGbG93S2V5ICE9PSBkZXRhaWwuZmxvd0tleSkge1xuICAgICAgICAgIHNvdXJjZUZsb3dbZGV0YWlsLnNvdXJjZUZsb3dLZXldLnNwbGljZShkZXRhaWwuc291cmNlUG9zaXRpb24sIDEpO1xuICAgICAgICAgIHRhcmdldEZsb3dbZGV0YWlsLmZsb3dLZXldLnNwbGljZShkZXRhaWwucG9zaXRpb24sIDAsIGZsb3dTdGVwKTtcbiAgICAgICAgICBpZiAodGhpcy5fY3VycmVudEZsb3dTdGVwICE9IG51bGwgJiYgdGhpcy5fY3VycmVudEZsb3dTdGVwLnN0ZXAuX2lkID09PSBfaWQpIHtcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRGbG93U3RlcC5ncm91cCA9IGRldGFpbC5mbG93S2V5O1xuICAgICAgICAgICAgLy8gU3BlY2lhbCBjYXNlIGZvciB1cGRhdGUgc2NoZW1hIGFmdGVyIGNoYW5nZSByZXF1ZXN0IHRvIHJlc3BvbnNlIG9yIGludmVyc2VcbiAgICAgICAgICAgIGNvbnN0IHNjaGVtYSA9IHRoaXMuYnVpbGRTY2hlbWEodGhpcy5fY3VycmVudEZsb3dTdGVwLnBvbGljeSk7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLl9zZXRDdXJyZW50Rmxvd1N0ZXAodGhpcy5fY3VycmVudEZsb3dTdGVwLCBzY2hlbWEsIHRydWUpO1xuICAgICAgICAgICAgdGhpcy5fZ2V0Rmxvd0VsZW1lbnQodGFyZ2V0Rmxvdy5faWQpLnJlcXVlc3RVcGRhdGUoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGRldGFpbC5wb3NpdGlvbiA+IGRldGFpbC5zb3VyY2VQb3NpdGlvbikge1xuICAgICAgICAgICAgdGFyZ2V0Rmxvd1tkZXRhaWwuZmxvd0tleV0uc3BsaWNlKGRldGFpbC5wb3NpdGlvbiwgMCwgZmxvd1N0ZXApO1xuICAgICAgICAgICAgc291cmNlRmxvd1tkZXRhaWwuZmxvd0tleV0uc3BsaWNlKGRldGFpbC5zb3VyY2VQb3NpdGlvbiwgMSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNvdXJjZUZsb3dbZGV0YWlsLmZsb3dLZXldLnNwbGljZShkZXRhaWwuc291cmNlUG9zaXRpb24sIDEpO1xuICAgICAgICAgICAgdGFyZ2V0Rmxvd1tkZXRhaWwuZmxvd0tleV0uc3BsaWNlKGRldGFpbC5wb3NpdGlvbiwgMCwgZmxvd1N0ZXApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBGb3JjZSBSZWZyZXNoIHNvdXJjZSBmbG93IGVsZW1lbnQgd2hlbiBtb3ZlIHRvIG90aGVyIGZsb3dcbiAgICAgICAgaWYgKHRhcmdldEZsb3cuX2lkICE9PSBzb3VyY2VGbG93Ll9pZCkge1xuICAgICAgICAgIHRoaXMuX2dldEZsb3dFbGVtZW50KHRhcmdldEZsb3cuX2lkKS5yZXF1ZXN0VXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRhcmdldEZsb3dbZGV0YWlsLmZsb3dLZXldLnNwbGljZShkZXRhaWwucG9zaXRpb24sIDAsIGZsb3dTdGVwKTtcbiAgICAgICAgY29uc3QgY3VycmVudEZsb3dGb3JtID0gdGhpcy5fZ2V0Rmxvd1N0ZXBGb3JtKCk7XG4gICAgICAgIGlmIChjdXJyZW50Rmxvd0Zvcm0gPT0gbnVsbCB8fCBjdXJyZW50Rmxvd0Zvcm0uZGlydHkgIT09IHRydWUpIHtcbiAgICAgICAgICBsZXQgc3RlcCA9IHRhcmdldEZsb3dbZGV0YWlsLmZsb3dLZXldW2RldGFpbC5wb3NpdGlvbl07XG4gICAgICAgICAgaWYgKHN0ZXAgPT0gbnVsbCkge1xuICAgICAgICAgICAgLy8gV2hlbiBjb25maXJtIGxvc2UgY2hhbmdlIGFmdGVyIGRyb3AgcG9saWN5XG4gICAgICAgICAgICBzdGVwID0gdGFyZ2V0Rmxvd1tkZXRhaWwuZmxvd0tleV1bZGV0YWlsLnBvc2l0aW9uIC0gMV07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGRldGFpbC5jYW5jZWxFZGl0ICE9PSB0cnVlKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5fZWRpdEZsb3dTdGVwKHsgc3RlcCwgcG9saWN5LCBmbG93OiB0YXJnZXRGbG93LCBncm91cDogZGV0YWlsLmZsb3dLZXkgfSk7XG4gICAgICAgICAgICAgIHRoaXMudXBkYXRlQ29tcGxldGUudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgZmxvd0VsZW1lbnQgPSB0aGlzLl9nZXRGbG93RWxlbWVudCh0YXJnZXRGbG93Ll9pZCk7XG4gICAgICAgICAgICAgICAgZmxvd0VsZW1lbnQuc2VsZWN0ZWRTdGVwSWQgPSBzdGVwLl9pZDtcbiAgICAgICAgICAgICAgICBmbG93RWxlbWVudC5yZXF1ZXN0VXBkYXRlKCk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0YXJnZXRGbG93Ll9kaXJ0eSA9IHRydWU7XG4gICAgICBzb3VyY2VGbG93Ll9kaXJ0eSA9IHRydWU7XG4gICAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICAgICAgdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3JBbGwoJ2d2LWZsb3cnKS5mb3JFYWNoKChndkZsb3cpID0+IGd2Rmxvdy5yZW1vdmVDYW5kaWRhdGUoKSk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5fZHJhZ1BvbGljeSA9IG51bGw7XG4gICAgICAgIHRoaXMuX2Ryb3BQb2xpY3kgPSBudWxsO1xuICAgICAgfSwgMCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbiA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgX29uRGVsZXRlUG9saWN5KHsgZGV0YWlsIH0pIHtcbiAgICBjb25zdCB0YXJnZXRGbG93ID0gdGhpcy5fZmluZEZsb3dCeUlkKGRldGFpbC5mbG93SWQpO1xuICAgIHRhcmdldEZsb3dbZGV0YWlsLmZsb3dLZXldLnNwbGljZShkZXRhaWwucG9zaXRpb24sIDEpO1xuICAgIHRhcmdldEZsb3cuX2RpcnR5ID0gdHJ1ZTtcbiAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICAgIGlmIChkZXRhaWwudGFyZ2V0LmVkaXRpbmcpIHtcbiAgICAgIHRoaXMuX2Nsb3NlRmxvd1N0ZXBGb3JtKHRydWUpO1xuICAgIH1cbiAgICB0aGlzLl9nZXRGbG93RWxlbWVudChkZXRhaWwuZmxvd0lkKS5yZXF1ZXN0VXBkYXRlKCk7XG4gIH1cblxuICBfb25EZXNpZ24oKSB7XG4gICAgdGhpcy5fY2hhbmdlVGFiKCdkZXNpZ24nKTtcbiAgICB0aGlzLl9zcGxpdE1haW5WaWV3cygpO1xuICB9XG5cbiAgYnVpbGRTY2hlbWEoeyBzY2hlbWEgfSkge1xuICAgIGNvbnN0IGNvbW1vbkRlc2NyaXB0aW9uID0ge1xuICAgICAgdGl0bGU6ICdEZXNjcmlwdGlvbicsXG4gICAgICBkZXNjcmlwdGlvbjogJ0Rlc2NyaXB0aW9uIG9mIGZsb3cgc3RlcCcsXG4gICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICB9O1xuICAgIGNvbnN0IGNvbW1vbkNvbmRpdGlvbiA9IHtcbiAgICAgIHRpdGxlOiAnQ29uZGl0aW9uJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnQ29uZGl0aW9uIHRoZSBleGVjdXRpb24gb2YgdGhlIGZsb3cgc3RlcCAoc3VwcG9ydCBFTCknLFxuICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAneC1zY2hlbWEtZm9ybSc6IHtcbiAgICAgICAgJ2V4cHJlc3Npb24tbGFuZ3VhZ2UnOiB0cnVlLFxuICAgICAgfSxcbiAgICB9O1xuICAgIGlmIChzY2hlbWEpIHtcbiAgICAgIGNvbnN0IGpzb25TY2hlbWEgPSB0eXBlb2Ygc2NoZW1hID09PSAnc3RyaW5nJyA/IEpTT04ucGFyc2Uoc2NoZW1hKSA6IHNjaGVtYTtcbiAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSB7IGNvbW1vbkRlc2NyaXB0aW9uLCAuLi4odGhpcy5oYXNDb25kaXRpb25hbFN0ZXBzID8geyBjb21tb25Db25kaXRpb24gfSA6IHt9KSwgLi4uanNvblNjaGVtYS5wcm9wZXJ0aWVzIH07XG4gICAgICByZXR1cm4geyAuLi5qc29uU2NoZW1hLCBwcm9wZXJ0aWVzIH07XG4gICAgfVxuICAgIHJldHVybiB7IHByb3BlcnRpZXM6IHsgY29tbW9uRGVzY3JpcHRpb24sIC4uLih0aGlzLmhhc0NvbmRpdGlvbmFsU3RlcHMgPyB7IGNvbW1vbkNvbmRpdGlvbiB9IDoge30pIH0gfTtcbiAgfVxuXG4gIGFzeW5jIF9lZGl0Rmxvd1N0ZXAoeyBzdGVwLCBmbG93LCBwb2xpY3ksIGdyb3VwIH0pIHtcbiAgICBpZiAoc3RlcCkge1xuICAgICAgdGhpcy5fY3VycmVudFBvbGljeUlkID0gcG9saWN5LmlkO1xuICAgICAgY29uc3QgY3VycmVudEZsb3dTdGVwID0geyBmbG93LCBzdGVwLCBwb2xpY3ksIGdyb3VwIH07XG4gICAgICBjb25zdCBzY2hlbWEgPSB0aGlzLmJ1aWxkU2NoZW1hKHBvbGljeSk7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCB0aGlzLl9zZXRDdXJyZW50Rmxvd1N0ZXAoY3VycmVudEZsb3dTdGVwLCBzY2hlbWEpO1xuICAgICAgICB0aGlzLl91cGRhdGVTZWxlY3RlZEZsb3dzKFtmbG93Ll9pZF0pO1xuICAgICAgICB0aGlzLl9zcGxpdE1haW5WaWV3cygpO1xuICAgICAgICBpZiAobG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2d2LXBvbGljeS1zdHVkaW86a2VlcC1kb2N1bWVudGF0aW9uLWNsb3NlJykgPT0gbnVsbCkge1xuICAgICAgICAgIHRoaXMuX29uT3BlbkRvY3VtZW50YXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICB0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID0gbnVsbDtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgdGhpcy5fY2xvc2VGbG93U3RlcEZvcm0oKTtcbiAgICAgIHRoaXMuX21heGltaXplVG9wVmlldygpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIF9vbkVkaXRGbG93U3RlcCh7IGRldGFpbDogeyBzdGVwLCBmbG93LCBwb2xpY3ksIGdyb3VwIH0gfSkge1xuICAgIHJldHVybiB0aGlzLl9lZGl0Rmxvd1N0ZXAoeyBzdGVwLCBmbG93LCBwb2xpY3ksIGdyb3VwIH0pO1xuICB9XG5cbiAgX2dldFJlc2l6YWJsZVZpZXdzKCkge1xuICAgIHJldHVybiB0aGlzLnNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvcignZ3YtcmVzaXphYmxlLXZpZXdzJyk7XG4gIH1cblxuICBfbWF4aW1pemVUb3BWaWV3KCkge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkRmxvd3NJZC5sZW5ndGggPD0gMSkge1xuICAgICAgdGhpcy5fZ2V0UmVzaXphYmxlVmlld3MoKS5tYXhpbWl6ZVRvcCgpO1xuICAgIH1cbiAgfVxuXG4gIF9tYXhpbWl6ZUJvdHRvbVZpZXcoKSB7XG4gICAgdGhpcy5fZ2V0UmVzaXphYmxlVmlld3MoKS5tYXhpbWl6ZUJvdHRvbSgpO1xuICB9XG5cbiAgX3NwbGl0TWFpblZpZXdzKCkge1xuICAgIHRoaXMuX2dldFJlc2l6YWJsZVZpZXdzKCkuc3BsaXQoKTtcbiAgfVxuXG4gIF9vbkNoYW5nZUZsb3dTdGVwU3RhdGUoeyBkZXRhaWwgfSkge1xuICAgIGNvbnN0IHRhcmdldEZsb3cgPSB0aGlzLl9maW5kRmxvd0J5SWQoZGV0YWlsLmZsb3dJZCk7XG4gICAgY29uc3Qgc3RlcCA9IHRhcmdldEZsb3dbZGV0YWlsLmZsb3dLZXldW2RldGFpbC5wb3NpdGlvbl07XG4gICAgc3RlcC5lbmFibGVkID0gZGV0YWlsLmVuYWJsZWQ7XG4gICAgdGFyZ2V0Rmxvdy5fZGlydHkgPSB0cnVlO1xuICAgIHRoaXMuaXNEaXJ0eSA9IHRydWU7XG4gIH1cblxuICBhc3luYyBfb25DbG9zZUZsb3dTdGVwRm9ybSgpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5fY2xvc2VGbG93U3RlcEZvcm0oKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb24gPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIF9jbG9zZUZsb3dTdGVwRm9ybShmb3JjZSA9IGZhbHNlKSB7XG4gICAgYXdhaXQgdGhpcy5fc2V0Q3VycmVudEZsb3dTdGVwKG51bGwsIG51bGwsIGZvcmNlKTtcbiAgfVxuXG4gIGFzeW5jIF9hc2tUb1ZhbGlkYXRlRm9ybXMoKSB7XG4gICAgaWYgKHRoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb24gPT0gbnVsbCkge1xuICAgICAgdGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbiA9IHRydWU7XG4gICAgICByZXR1cm4gUHJvbWlzZS5hbGwodGhpcy5fc3VibWl0T3JDb25maXJtRm9ybXMoKSkudGhlbigoZm9ybXMpID0+IHtcbiAgICAgICAgaWYgKGZvcm1zLmZpbHRlcigocikgPT4gciAhPSBudWxsKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGhpcy5fZGVmaW5pdGlvbiA9IHRoaXMuX2J1aWxkRGVmaW5pdGlvblRvU2F2ZSgpO1xuICAgICAgICAgIHRoaXMuZ2V0Q2hpbGRyZW4oKS5mb3JFYWNoKChlKSA9PiBlLnJlcXVlc3RVcGRhdGUoKSk7XG4gICAgICAgICAgLy8gUmVmcmVzaCBpZiBsb3NlIGNoYW5nZXMgbG9zdCBjdXJyZW50IHN0ZXAgc2VsZWN0aW9uXG4gICAgICAgICAgcmV0dXJuIHRoaXMuX2NoZWNrQ3VycmVudEZsb3dTdGVwKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmdldENoaWxkcmVuKCkuZm9yRWFjaCgoZSkgPT4gZS5yZXF1ZXN0VXBkYXRlKCkpO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudXBkYXRlQ29tcGxldGUudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb24gPSBudWxsO1xuICAgICAgICAgICAgICByZXR1cm4gZm9ybXM7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID0gbnVsbDtcbiAgICAgICAgICByZXR1cm4gZm9ybXM7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2FzayBhbHJlYWR5IHdhaXRpbmcnKTtcbiAgfVxuXG4gIGFzeW5jIF9zZXRDdXJyZW50Rmxvd1N0ZXAoY3VycmVudEZsb3dTdGVwLCBmbG93U3RlcFNjaGVtYSwgZm9yY2UgPSBmYWxzZSkge1xuICAgIGlmICghZm9yY2UpIHtcbiAgICAgIGF3YWl0IHRoaXMuX2Fza1RvVmFsaWRhdGVGb3JtcygpO1xuICAgIH1cblxuICAgIGNvbnN0IHNjaGVtYSA9IGRlZXBDbG9uZShmbG93U3RlcFNjaGVtYSk7XG4gICAgaWYgKGN1cnJlbnRGbG93U3RlcCAhPSBudWxsKSB7XG4gICAgICBjb25zdCBjb25maWd1cmF0aW9uID1cbiAgICAgICAgdHlwZW9mIGN1cnJlbnRGbG93U3RlcC5zdGVwLmNvbmZpZ3VyYXRpb24gPT09ICdzdHJpbmcnXG4gICAgICAgICAgPyBKU09OLnBhcnNlKGN1cnJlbnRGbG93U3RlcC5zdGVwLmNvbmZpZ3VyYXRpb24pXG4gICAgICAgICAgOiBjdXJyZW50Rmxvd1N0ZXAuc3RlcC5jb25maWd1cmF0aW9uO1xuICAgICAgY29uc3Qgc3RlcCA9IHsgLi4uY3VycmVudEZsb3dTdGVwLnN0ZXAsIGNvbmZpZ3VyYXRpb24gfTtcblxuICAgICAgY29uc3QgX2luaXRpYWxWYWx1ZXMgPSB7IC4uLnN0ZXAuY29uZmlndXJhdGlvbiwgY29tbW9uRGVzY3JpcHRpb246IHN0ZXAuZGVzY3JpcHRpb24sIGNvbW1vbkNvbmRpdGlvbjogc3RlcC5jb25kaXRpb24gfTtcbiAgICAgIHRoaXMuX2N1cnJlbnRGbG93U3RlcCA9IHsgLi4uY3VycmVudEZsb3dTdGVwLCBzdGVwLCBfaW5pdGlhbFZhbHVlcyB9O1xuXG4gICAgICBpZiAoZmxvd1N0ZXBTY2hlbWEgJiYgZmxvd1N0ZXBTY2hlbWEucHJvcGVydGllcy5zY29wZSkge1xuICAgICAgICBjb25zdCBfZW51bSA9IHNjaGVtYS5wcm9wZXJ0aWVzLnNjb3BlLmVudW07XG4gICAgICAgIGlmIChfZW51bS5maW5kKChzY29wZSkgPT4gWydSRVFVRVNUJywgJ1JFUVVFU1RfQ09OVEVOVCcsICdSRVNQT05TRScsICdSRVNQT05TRV9DT05URU5UJ10uaW5jbHVkZXMoc2NvcGUpKSAhPSBudWxsKSB7XG4gICAgICAgICAgY29uc3QgZmlsdGVyZWQgPSB0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuZ3JvdXAgPT09ICdwcmUnID8gWydSRVFVRVNUJywgJ1JFUVVFU1RfQ09OVEVOVCddIDogWydSRVNQT05TRScsICdSRVNQT05TRV9DT05URU5UJ107XG4gICAgICAgICAgc2NoZW1hLnByb3BlcnRpZXMuc2NvcGUuZW51bSA9IF9lbnVtLmZpbHRlcigoc2NvcGUpID0+IGZpbHRlcmVkLmluY2x1ZGVzKHNjb3BlKSk7XG4gICAgICAgICAgY29uc3Qgc2NvcGUgPSB0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuc3RlcC5jb25maWd1cmF0aW9uLnNjb3BlO1xuICAgICAgICAgIGlmIChzY29wZSA9PSBudWxsIHx8ICFzY2hlbWEucHJvcGVydGllcy5zY29wZS5lbnVtLmluY2x1ZGVzKHNjb3BlKSkge1xuICAgICAgICAgICAgc2NoZW1hLnByb3BlcnRpZXMuc2NvcGUuZGVmYXVsdCA9IHNjaGVtYS5wcm9wZXJ0aWVzLnNjb3BlLmVudW1bMF07XG4gICAgICAgICAgICB0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuc3RlcC5jb25maWd1cmF0aW9uLnNjb3BlID0gc2NoZW1hLnByb3BlcnRpZXMuc2NvcGUuZW51bVswXTtcbiAgICAgICAgICAgIHRoaXMuX2N1cnJlbnRGbG93U3RlcC5faW5pdGlhbFZhbHVlcy5zY29wZSA9IHNjaGVtYS5wcm9wZXJ0aWVzLnNjb3BlLmVudW1bMF07XG4gICAgICAgICAgICBpZiAodGhpcy5fY3VycmVudEZsb3dTdGVwLl92YWx1ZXMpIHtcbiAgICAgICAgICAgICAgdGhpcy5fY3VycmVudEZsb3dTdGVwLl92YWx1ZXMuc2NvcGUgPSBzY2hlbWEucHJvcGVydGllcy5zY29wZS5lbnVtWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9jdXJyZW50Rmxvd1N0ZXAgPSBudWxsO1xuICAgIH1cblxuICAgIHRoaXMuX2Zsb3dTdGVwU2NoZW1hID0gc2NoZW1hO1xuICB9XG5cbiAgX3JlZnJlc2goY2xvc2VTdGVwRm9ybSA9IHRydWUpIHtcbiAgICBpZiAoY2xvc2VTdGVwRm9ybSkge1xuICAgICAgdGhpcy5fY2xvc2VGbG93U3RlcEZvcm0odHJ1ZSk7XG4gICAgfVxuICAgIHRoaXMuX2RlZmluaXRpb24gPSBkZWVwQ2xvbmUodGhpcy5fZGVmaW5pdGlvbik7XG4gIH1cblxuICBhc3luYyBfb25TZWxlY3RGbG93cyh7IGRldGFpbCB9KSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuX2Nsb3NlRmxvd1N0ZXBGb3JtKCk7XG4gICAgICB0aGlzLl9vbkNsb3NlRG9jdW1lbnRhdGlvbigpO1xuICAgICAgdGhpcy5fdXBkYXRlU2VsZWN0ZWRGbG93cyhkZXRhaWwuZmxvd3MpO1xuICAgICAgdGhpcy5fb25EZXNpZ24oKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBhc3luYyBfb25PcGVuRG9jdW1lbnRhdGlvbkZyb21NZW51KHsgZGV0YWlsOiB7IHBvbGljeSB9IH0pIHtcbiAgICB0cnkge1xuICAgICAgaWYgKHRoaXMuZG9jdW1lbnRhdGlvbiA9PSBudWxsIHx8IHRoaXMuZG9jdW1lbnRhdGlvbi5pZCAhPT0gcG9saWN5LmlkKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuX2Nsb3NlRmxvd1N0ZXBGb3JtKCk7XG4gICAgICAgIHRoaXMuX2N1cnJlbnRQb2xpY3lJZCA9IHBvbGljeS5pZDtcbiAgICAgICAgaWYgKHRoaXMuZ2V0U2VsZWN0ZWRGbG93KCkpIHtcbiAgICAgICAgICB0aGlzLl9zcGxpdE1haW5WaWV3cygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuX21heGltaXplQm90dG9tVmlldygpO1xuICAgICAgICB9XG4gICAgICAgIGRpc3BhdGNoQ3VzdG9tRXZlbnQodGhpcywgJ2ZldGNoLWRvY3VtZW50YXRpb24nLCB7IHBvbGljeSB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7fVxuICB9XG5cbiAgX2ZldGNoRG9jdW1lbnRhdGlvbihwb2xpY3kpIHtcbiAgICBpZiAodGhpcy5kb2N1bWVudGF0aW9uID09IG51bGwgfHwgdGhpcy5kb2N1bWVudGF0aW9uLmlkICE9PSBwb2xpY3kuaWQpIHtcbiAgICAgIGRpc3BhdGNoQ3VzdG9tRXZlbnQodGhpcywgJ2ZldGNoLWRvY3VtZW50YXRpb24nLCB7IHBvbGljeSB9KTtcbiAgICB9XG4gIH1cblxuICBfb25PcGVuRG9jdW1lbnRhdGlvbigpIHtcbiAgICBpZiAodGhpcy5fY3VycmVudEZsb3dTdGVwICYmIHRoaXMuX2N1cnJlbnRGbG93U3RlcC5wb2xpY3kpIHtcbiAgICAgIHRoaXMuX2ZldGNoRG9jdW1lbnRhdGlvbih0aGlzLl9jdXJyZW50Rmxvd1N0ZXAucG9saWN5KTtcbiAgICB9XG4gIH1cblxuICBfb25PcGVuRG9jdW1lbnRhdGlvbkZyb21Gb3JtKCkge1xuICAgIGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKCdndi1wb2xpY3ktc3R1ZGlvOmtlZXAtZG9jdW1lbnRhdGlvbi1jbG9zZScpO1xuICAgIHRoaXMuX29uT3BlbkRvY3VtZW50YXRpb24oKTtcbiAgfVxuXG4gIF9maW5kRmxvd0NvbGxlY3Rpb24oZmxvd0lkKSB7XG4gICAgY29uc3QgcGxhbiA9IHRoaXMuZGVmaW5lZFBsYW5zLmZpbmQoKHBsYW4pID0+IHBsYW4uZmxvd3MuZmluZCgoZmxvdykgPT4gZmxvdy5faWQgPT09IGZsb3dJZCkgIT0gbnVsbCk7XG4gICAgcmV0dXJuIHsgcGxhbiwgZmxvd3M6IHBsYW4gIT0gbnVsbCA/IHBsYW4uZmxvd3MgOiB0aGlzLmRlZmluZWRGbG93cyB9O1xuICB9XG5cbiAgX2ZpbmRGbG93QnlJZChmbG93SWQpIHtcbiAgICBsZXQgZmxvdyA9IHRoaXMuZGVmaW5lZEZsb3dzLmZpbmQoKGZsb3cpID0+IGZsb3cuX2lkID09PSBmbG93SWQpO1xuICAgIGlmIChmbG93ID09IG51bGwpIHtcbiAgICAgIGNvbnN0IHBsYW5zRmxvd3MgPSB0aGlzLmRlZmluZWRQbGFucy5tYXAoKHBsYW4pID0+IHBsYW4uZmxvd3MpLnJlZHVjZSgoYWNjLCB2YWwpID0+IGFjYy5jb25jYXQodmFsKSwgW10pO1xuICAgICAgZmxvdyA9IHBsYW5zRmxvd3MuZmluZCgoZmxvdykgPT4gZmxvdy5faWQgPT09IGZsb3dJZCk7XG4gICAgfVxuICAgIHJldHVybiBmbG93O1xuICB9XG5cbiAgZ2V0U2VsZWN0ZWRGbG93KGluZGV4ID0gMCkge1xuICAgIGNvbnN0IHNlbGVjdGVkRmxvd0lkID0gdGhpcy5zZWxlY3RlZEZsb3dzSWRbaW5kZXhdO1xuICAgIHJldHVybiB0aGlzLl9maW5kRmxvd0J5SWQoc2VsZWN0ZWRGbG93SWQpO1xuICB9XG5cbiAgX29uVGFyZ2V0UG9saWN5KHsgZGV0YWlsIH0pIHtcbiAgICBpZiAodGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbiA9PSBudWxsKSB7XG4gICAgICB0aGlzLl9kcmFnUG9saWN5ID0gZGV0YWlsO1xuICAgIH1cbiAgfVxuXG4gIF9vbkNoYW5nZUZsb3dTdGVwKHsgZGV0YWlsIH0pIHtcbiAgICB0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuX3ZhbHVlcyA9IGRldGFpbC52YWx1ZXM7XG4gIH1cblxuICBfd3JpdGVGbG93U3RlcCh2YWx1ZXMpIHtcbiAgICBjb25zdCB7IGNvbW1vbkRlc2NyaXB0aW9uLCBjb21tb25Db25kaXRpb24sIC4uLmNvbmZpZ3VyYXRpb24gfSA9IHZhbHVlcztcbiAgICBpZiAoXG4gICAgICB0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuc3RlcC5fbmV3IHx8XG4gICAgICB0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuc3RlcC5kZXNjcmlwdGlvbiAhPT0gY29tbW9uRGVzY3JpcHRpb24gfHxcbiAgICAgIHRoaXMuX2N1cnJlbnRGbG93U3RlcC5zdGVwLmNvbmRpdGlvbiAhPT0gY29tbW9uQ29uZGl0aW9uIHx8XG4gICAgICAhZGVlcEVxdWFsKHRoaXMuX2N1cnJlbnRGbG93U3RlcC5zdGVwLmNvbmZpZ3VyYXRpb24sIGNvbmZpZ3VyYXRpb24pXG4gICAgKSB7XG4gICAgICBjb25zdCBmbG93ID0gdGhpcy5fZmluZEZsb3dCeUlkKHRoaXMuX2N1cnJlbnRGbG93U3RlcC5mbG93Ll9pZCk7XG4gICAgICBjb25zdCBwb3NpdGlvbiA9IGZsb3dbdGhpcy5fY3VycmVudEZsb3dTdGVwLmdyb3VwXS5maW5kSW5kZXgoKHN0ZXApID0+IHN0ZXAuX2lkID09PSB0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuc3RlcC5faWQpO1xuXG4gICAgICBmbG93W3RoaXMuX2N1cnJlbnRGbG93U3RlcC5ncm91cF1bcG9zaXRpb25dLmRlc2NyaXB0aW9uID0gY29tbW9uRGVzY3JpcHRpb247XG4gICAgICBmbG93W3RoaXMuX2N1cnJlbnRGbG93U3RlcC5ncm91cF1bcG9zaXRpb25dLmNvbmRpdGlvbiA9IGNvbW1vbkNvbmRpdGlvbjtcbiAgICAgIGZsb3dbdGhpcy5fY3VycmVudEZsb3dTdGVwLmdyb3VwXVtwb3NpdGlvbl0uY29uZmlndXJhdGlvbiA9IGRlZXBDbG9uZShjb25maWd1cmF0aW9uKTtcbiAgICAgIGRlbGV0ZSBmbG93W3RoaXMuX2N1cnJlbnRGbG93U3RlcC5ncm91cF1bcG9zaXRpb25dLl9uZXc7XG4gICAgICBmbG93W3RoaXMuX2N1cnJlbnRGbG93U3RlcC5ncm91cF1bcG9zaXRpb25dLl9kaXJ0eSA9IHRydWU7XG4gICAgICBmbG93Ll9kaXJ0eSA9IHRydWU7XG4gICAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICAgICAgdGhpcy5fY3VycmVudEZsb3dTdGVwLmZsb3cgPSBmbG93O1xuICAgICAgdGhpcy5fY3VycmVudEZsb3dTdGVwLnN0ZXAgPSBmbG93W3RoaXMuX2N1cnJlbnRGbG93U3RlcC5ncm91cF1bcG9zaXRpb25dO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIF9vblN1Ym1pdEZsb3dTdGVwKHsgZGV0YWlsIH0pIHtcbiAgICB0aGlzLl93cml0ZUZsb3dTdGVwKGRldGFpbC52YWx1ZXMpO1xuICAgIGF3YWl0IHRoaXMucmVxdWVzdFVwZGF0ZSgnX2RlZmluaXRpb24nKTtcbiAgICB0aGlzLmdldENoaWxkcmVuKCkuZm9yRWFjaCgoYykgPT4gYy5yZXF1ZXN0VXBkYXRlKCkpO1xuICB9XG5cbiAgX29uQ2FuY2VsRmxvdygpIHtcbiAgICB0aGlzLl9vbkRlc2lnbigpO1xuICB9XG5cbiAgX29uU3VibWl0Rmxvdyh7IGRldGFpbDogeyB2YWx1ZXMgfSB9KSB7XG4gICAgY29uc3Qgc2VsZWN0ZWRGbG93ID0gdGhpcy5nZXRTZWxlY3RlZEZsb3coKTtcbiAgICBjb25zdCBfdmFsdWVzID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5fY3JlYXRlRmxvd0Zyb21TY2hlbWEoKSwgdmFsdWVzKTtcbiAgICBjb25zdCBzZWxlY3RlZEZsb3dVcGRhdGVkID0gT2JqZWN0LmFzc2lnbih7fSwgc2VsZWN0ZWRGbG93LCBfdmFsdWVzKTtcbiAgICBpZiAoIWRlZXBFcXVhbChzZWxlY3RlZEZsb3csIHNlbGVjdGVkRmxvd1VwZGF0ZWQpKSB7XG4gICAgICBPYmplY3QuYXNzaWduKHNlbGVjdGVkRmxvdywgc2VsZWN0ZWRGbG93VXBkYXRlZCwgeyBfZGlydHk6IHRydWUgfSk7XG4gICAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICAgICAgdGhpcy5fcmVmcmVzaCgpO1xuICAgIH1cbiAgfVxuXG4gIF9vbkNhbmNlbEZsb3dNb2RlKCkge1xuICAgIHRoaXMuX29uRGVzaWduKCk7XG4gIH1cblxuICBfb25TdWJtaXRGbG93TW9kZSh7IGRldGFpbDogeyB2YWx1ZXMgfSB9KSB7XG4gICAgdGhpcy5fZGVmaW5pdGlvblsnZmxvdy1tb2RlJ10gPSB2YWx1ZXNbJ2Zsb3ctbW9kZSddIHx8ICdERUZBVUxUJztcbiAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICAgIHRoaXMuX3JlZnJlc2goKTtcbiAgfVxuXG4gIF9vbkNoYW5nZVRhYih7IGRldGFpbCB9KSB7XG4gICAgdGhpcy5fY2hhbmdlVGFiKGRldGFpbC52YWx1ZSk7XG4gIH1cblxuICBhc3luYyBfY2hhbmdlVGFiVmFsaWRhdG9yKHsgZnJvbSwgdG8gfSkge1xuICAgIGlmIChmcm9tID09PSAncHJvcGVydGllcycpIHtcbiAgICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKCdndi1wcm9wZXJ0aWVzJyk7XG4gICAgICBpZiAoY29tcG9uZW50LmRpcnR5KSB7XG4gICAgICAgIHJldHVybiBjb21wb25lbnQuY29uZmlybSgpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZnJvbSA9PT0gJ3Jlc291cmNlcycpIHtcbiAgICAgIGNvbnN0IGNvbXBvbmVudCA9IHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKCdndi1yZXNvdXJjZXMnKTtcbiAgICAgIGlmIChjb21wb25lbnQuZGlydHkpIHtcbiAgICAgICAgcmV0dXJuIGNvbXBvbmVudC5jb25maXJtKCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLl9hc2tUb1ZhbGlkYXRlRm9ybXMoKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbiA9IG51bGw7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgfVxuXG4gIF9jaGFuZ2VUYWIodGFiSWQpIHtcbiAgICBpZiAodGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbiA9PSBudWxsKSB7XG4gICAgICB0aGlzLnRhYklkID0gdGFiSWQ7XG4gICAgICBkaXNwYXRjaEN1c3RvbUV2ZW50KHRoaXMsICdjaGFuZ2UtdGFiJywgdGhpcy50YWJJZCk7XG4gICAgfVxuICB9XG5cbiAgX29uRHJhZ1N0YXJ0Rmxvd1N0ZXAoZmxvdywgeyBkZXRhaWwgfSkge1xuICAgIGlmICh0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID09IG51bGwpIHtcbiAgICAgIHRoaXMuX2Ryb3BQb2xpY3kgPSBkZXRhaWw7XG4gICAgICB0aGlzLl9kcmFnUG9saWN5ID0gZGV0YWlsO1xuICAgIH1cbiAgfVxuXG4gIF9yZW5kZXJGbG93RW1wdHlTdGF0ZShyZWFkb25seU1vZGUpIHtcbiAgICByZXR1cm4gaHRtbGA8ZGl2IHNsb3Q9XCJjb250ZW50XCIgY2xhc3M9XCJlbXB0eVwiPlxuICAgICAgPGRpdj5cbiAgICAgICAgU2VsZWN0IGEgZmxvd1xuICAgICAgICAke3JlYWRvbmx5TW9kZSAhPT0gdHJ1ZVxuICAgICAgICAgID8gaHRtbGBvciA8Z3YtYnV0dG9uIEBndi1idXR0b246Y2xpY2s9XCIke3RoaXMuX29uQWRkRmxvd31cIiBvdXRsaW5lZCBpY29uPVwiY29kZTpwbHVzXCIgbGFyZ2U+ZGVzaWduIG5ldyBvbmU8L2d2LWJ1dHRvbj5gXG4gICAgICAgICAgOiAnJ31cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PmA7XG4gIH1cblxuICBfcmVuZGVyRmxvdyhpbmRleCA9IDAsIGhhc0VtcHR5U3RhdGUgPSB0cnVlLCByZWFkb25seU1vZGUpIHtcbiAgICBjb25zdCBmbG93ID0gdGhpcy5nZXRTZWxlY3RlZEZsb3coaW5kZXgpO1xuICAgIGlmIChmbG93KSB7XG4gICAgICBjb25zdCB7IHBsYW4gfSA9IHRoaXMuX2ZpbmRGbG93Q29sbGVjdGlvbihmbG93Ll9pZCk7XG4gICAgICBjb25zdCBzZWxlY3RlZFN0ZXBJZCA9IHRoaXMuX2N1cnJlbnRGbG93U3RlcCA/IHRoaXMuX2N1cnJlbnRGbG93U3RlcC5zdGVwLl9pZCA6IG51bGw7XG4gICAgICByZXR1cm4gaHRtbGAgPGd2LWZsb3dcbiAgICAgICAgc3R5bGU9XCJoZWlnaHQ6IDEwMCVcIlxuICAgICAgICAuaWQ9XCIke2Zsb3cuX2lkfVwiXG4gICAgICAgIC5mbG93PVwiJHtmbG93fVwiXG4gICAgICAgIC5wbGFuPVwiJHtwbGFufVwiXG4gICAgICAgIC5wb2xpY2llcz1cIiR7dGhpcy5wb2xpY2llc31cIlxuICAgICAgICBzbG90PVwiY29udGVudFwiXG4gICAgICAgID9kaXNhYmxlZD1cIiR7dGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbn1cIlxuICAgICAgICAuZHJhZ1BvbGljeT1cIiR7dGhpcy5fZHJhZ1BvbGljeX1cIlxuICAgICAgICAuZHJvcFBvbGljeT1cIiR7dGhpcy5fZHJvcFBvbGljeX1cIlxuICAgICAgICAuc2VsZWN0ZWRTdGVwSWQ9XCIke3NlbGVjdGVkU3RlcElkfVwiXG4gICAgICAgID9yZWFkb25seT1cIiR7cmVhZG9ubHlNb2RlfVwiXG4gICAgICAgID9oYXMtcG9saWN5LWZpbHRlcj1cIiR7dGhpcy5fcG9saWN5RmlsdGVyT3B0aW9ucyAhPSBudWxsfVwiXG4gICAgICAgIGZsb3dzLXRpdGxlPVwiJHt0aGlzLmZsb3dzVGl0bGV9XCJcbiAgICAgICAgQGd2LWZsb3c6ZHJhZy1zdGFydD1cIiR7dGhpcy5fb25EcmFnU3RhcnRGbG93U3RlcC5iaW5kKHRoaXMsIGZsb3cpfVwiXG4gICAgICAgIEBndi1mbG93OmVkaXQ9XCIke3RoaXMuX29uRWRpdEZsb3dTdGVwfVwiXG4gICAgICAgIEBndi1mbG93OmNoYW5nZS1zdGF0ZT1cIiR7dGhpcy5fb25DaGFuZ2VGbG93U3RlcFN0YXRlfVwiXG4gICAgICAgIEBndi1mbG93OmRyb3A9XCIke3RoaXMuX29uRHJvcFBvbGljeX1cIlxuICAgICAgICBAZ3YtZmxvdzpkZWxldGU9XCIke3RoaXMuX29uRGVsZXRlUG9saWN5fVwiXG4gICAgICA+PC9ndi1mbG93PmA7XG4gICAgfSBlbHNlIGlmIChoYXNFbXB0eVN0YXRlKSB7XG4gICAgICByZXR1cm4gdGhpcy5fcmVuZGVyRmxvd0VtcHR5U3RhdGUocmVhZG9ubHlNb2RlKTtcbiAgICB9XG4gICAgcmV0dXJuIGh0bWxgYDtcbiAgfVxuXG4gIF9vbkZldGNoUmVzb3VyY2VzKGV2ZW50KSB7XG4gICAgY29uc3QgeyBjdXJyZW50VGFyZ2V0LCByZWdleFR5cGVzIH0gPSBldmVudC5kZXRhaWw7XG4gICAgY29uc3Qgb3B0aW9ucyA9IHRoaXMuZGVmaW5lZFJlc291cmNlc1xuICAgICAgLmZpbHRlcigocmVzb3VyY2UpID0+IHJlZ2V4VHlwZXMgPT0gbnVsbCB8fCBuZXcgUmVnRXhwKHJlZ2V4VHlwZXMpLnRlc3QocmVzb3VyY2UudHlwZSkpXG4gICAgICAubWFwKChyZXNvdXJjZSwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VUeXBlID0gdGhpcy5yZXNvdXJjZVR5cGVzLmZpbmQoKHR5cGUpID0+IHR5cGUuaWQgPT09IHJlc291cmNlLnR5cGUpO1xuICAgICAgICBjb25zdCByb3cgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdndi1yb3cnKTtcbiAgICAgICAgY29uc3QgcGljdHVyZSA9IHJlc291cmNlVHlwZS5pY29uID8gcmVzb3VyY2VUeXBlLmljb24gOiBudWxsO1xuICAgICAgICByb3cuaXRlbSA9IHsgcGljdHVyZSwgbmFtZTogcmVzb3VyY2UubmFtZSB9O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGVsZW1lbnQ6IHJvdyxcbiAgICAgICAgICB2YWx1ZTogcmVzb3VyY2UubmFtZSxcbiAgICAgICAgICBpZDogcmVzb3VyY2UudHlwZSxcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIGN1cnJlbnRUYXJnZXQub3B0aW9ucyA9IG9wdGlvbnM7XG4gIH1cblxuICBfcmVuZGVyUG9saWN5KHJlYWRvbmx5TW9kZSkge1xuICAgIGlmICh0aGlzLl9mbG93U3RlcFNjaGVtYSAmJiB0aGlzLmRvY3VtZW50YXRpb24pIHtcbiAgICAgIHJldHVybiBodG1sYDxndi1yZXNpemFibGUtdmlld3MgZGlyZWN0aW9uPVwiaG9yaXpvbnRhbFwiIG5vLW92ZXJmbG93PlxuICAgICAgICA8ZGl2IHNsb3Q9XCJ0b3BcIj4ke3RoaXMuX3JlbmRlckZsb3dTdGVwRm9ybShyZWFkb25seU1vZGUpfTwvZGl2PlxuICAgICAgICA8ZGl2IHNsb3Q9XCJib3R0b21cIj5cbiAgICAgICAgICA8Z3YtZG9jdW1lbnRhdGlvblxuICAgICAgICAgICAgLnRleHQ9XCIke3RoaXMuZG9jdW1lbnRhdGlvbi5jb250ZW50fVwiXG4gICAgICAgICAgICAuaW1hZ2U9XCIke3RoaXMuZG9jdW1lbnRhdGlvbi5pbWFnZX1cIlxuICAgICAgICAgICAgP2Rpc2FibGVkPVwiJHt0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9ufVwiXG4gICAgICAgICAgICBAZ3YtZG9jdW1lbnRhdGlvbjpjbG9zZT1cIiR7dGhpcy5fb25DbG9zZURvY3VtZW50YXRpb259XCJcbiAgICAgICAgICA+PC9ndi1kb2N1bWVudGF0aW9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZ3YtcmVzaXphYmxlLXZpZXdzPmA7XG4gICAgfSBlbHNlIGlmICh0aGlzLmRvY3VtZW50YXRpb24pIHtcbiAgICAgIHJldHVybiBodG1sYDxndi1kb2N1bWVudGF0aW9uXG4gICAgICAgIC50ZXh0PVwiJHt0aGlzLmRvY3VtZW50YXRpb24uY29udGVudH1cIlxuICAgICAgICAuaW1hZ2U9XCIke3RoaXMuZG9jdW1lbnRhdGlvbi5pbWFnZX1cIlxuICAgICAgICA/ZGlzYWJsZWQ9XCIke3RoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb259XCJcbiAgICAgICAgQGd2LWRvY3VtZW50YXRpb246Y2xvc2U9XCIke3RoaXMuX29uQ2xvc2VEb2N1bWVudGF0aW9ufVwiXG4gICAgICA+PC9ndi1kb2N1bWVudGF0aW9uPmA7XG4gICAgfSBlbHNlIGlmICh0aGlzLl9mbG93U3RlcFNjaGVtYSkge1xuICAgICAgcmV0dXJuIHRoaXMuX3JlbmRlckZsb3dTdGVwRm9ybShyZWFkb25seU1vZGUpO1xuICAgIH1cbiAgICByZXR1cm4gaHRtbGBgO1xuICB9XG5cbiAgX2dldEZsb3dTdGVwRm9ybSgpIHtcbiAgICByZXR1cm4gdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3IoYCMke0ZMT1dfU1RFUF9GT1JNX0lEfWApO1xuICB9XG5cbiAgX29uUmVzZXRGbG93U3RlcCgpIHtcbiAgICBpZiAodGhpcy5fY3VycmVudEZsb3dTdGVwKSB7XG4gICAgICBkZWxldGUgdGhpcy5fY3VycmVudEZsb3dTdGVwLl92YWx1ZXM7XG4gICAgICB0aGlzLl9nZXRGbG93U3RlcEZvcm0oKS5yZXNldCgpO1xuICAgIH1cbiAgfVxuXG4gIF9nZW5lcmF0ZUZsb3dzSWQobGlzdCwgZm9yY2UgPSBmYWxzZSkge1xuICAgIHJldHVybiB0aGlzLl9nZW5lcmF0ZUlkKCdmJywgbGlzdCwgZm9yY2UsIHRydWUpO1xuICB9XG5cbiAgX2dlbmVyYXRlUGxhbkZsb3dzSWQocGxhbiwgZm9yY2UgPSBmYWxzZSkge1xuICAgIHJldHVybiB0aGlzLl9nZW5lcmF0ZUlkKHBsYW4uaWQsIHBsYW4uZmxvd3MsIGZvcmNlLCB0cnVlKTtcbiAgfVxuXG4gIF9nZW5lcmF0ZUZsb3dTdGVwSWQoZmxvd0lkLCBmbG93S2V5LCBwb3NpdGlvbikge1xuICAgIHJldHVybiBgJHtmbG93SWR9XyR7Zmxvd0tleX1fJHtwb3NpdGlvbn1gO1xuICB9XG5cbiAgX2dlbmVyYXRlSWQocHJlZml4LCBsaXN0LCBmb3JjZSA9IGZhbHNlLCBpc0Zsb3cgPSBmYWxzZSkge1xuICAgIGlmIChsaXN0KSB7XG4gICAgICByZXR1cm4gbGlzdC5tYXAoKGUsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IF9pZCA9IGAke3ByZWZpeH1fJHtpbmRleH1gO1xuICAgICAgICBpZiAoaXNGbG93KSB7XG4gICAgICAgICAgaWYgKGUucHJlKSB7XG4gICAgICAgICAgICBlLnByZS5mb3JFYWNoKChzdGVwLCBzdGVwSW5kZXgpID0+IChzdGVwLl9pZCA9IHRoaXMuX2dlbmVyYXRlRmxvd1N0ZXBJZChfaWQsICdwcmUnLCBzdGVwSW5kZXgpKSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChlLnBvc3QpIHtcbiAgICAgICAgICAgIGUucG9zdC5mb3JFYWNoKChzdGVwLCBzdGVwSW5kZXgpID0+IChzdGVwLl9pZCA9IHRoaXMuX2dlbmVyYXRlRmxvd1N0ZXBJZChfaWQsICdwb3N0Jywgc3RlcEluZGV4KSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoZm9yY2UgfHwgZS5faWQgPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiB7IC4uLmUsIF9pZCB9O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBlO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBsaXN0O1xuICB9XG5cbiAgZ2V0Q2hpbGRyZW4oKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIC4uLkFycmF5LmZyb20odGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3JBbGwoJ2d2LWZsb3cnKSksXG4gICAgICAuLi5BcnJheS5mcm9tKHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yQWxsKCdndi1yZXNpemFibGUtdmlld3MnKSksXG4gICAgXTtcbiAgfVxuXG4gIGFzeW5jIGdldFVwZGF0ZUNvbXBsZXRlKCkge1xuICAgIGF3YWl0IHN1cGVyLmdldFVwZGF0ZUNvbXBsZXRlKCk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwodGhpcy5nZXRDaGlsZHJlbigpLm1hcCgoZSkgPT4gZS51cGRhdGVDb21wbGV0ZSkpO1xuICB9XG5cbiAgc2hvdWxkVXBkYXRlKGNoYW5nZWRQcm9wZXJ0aWVzKSB7XG4gICAgLy8gSnVzdCByZWZyZXNoIGd2LWZsb3cgY29tcG9uZW50c1xuICAgIGlmIChjaGFuZ2VkUHJvcGVydGllcy5oYXMoJ19kcmFnUG9saWN5JykpIHtcbiAgICAgIHRoaXMuc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yQWxsKCdndi1mbG93JykuZm9yRWFjaCgoZmxvdykgPT4gKGZsb3cuZHJhZ1BvbGljeSA9IHRoaXMuX2RyYWdQb2xpY3kpKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZWRQcm9wZXJ0aWVzLmhhcygnX2Ryb3BQb2xpY3knKSkge1xuICAgICAgdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3JBbGwoJ2d2LWZsb3cnKS5mb3JFYWNoKChmbG93KSA9PiAoZmxvdy5kcm9wUG9saWN5ID0gdGhpcy5fZHJvcFBvbGljeSkpO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gc3VwZXIuc2hvdWxkVXBkYXRlKGNoYW5nZWRQcm9wZXJ0aWVzKTtcbiAgfVxuXG4gIHVwZGF0ZWQocHJvcHMpIHtcbiAgICBpZiAocHJvcHMuaGFzKCdkb2N1bWVudGF0aW9uJykgJiYgdGhpcy5kb2N1bWVudGF0aW9uICE9IG51bGwgJiYgdGhpcy5zZWxlY3RlZEZsb3dzSWQubGVuZ3RoID4gMSkge1xuICAgICAgdGhpcy5fdXBkYXRlU2VsZWN0ZWRGbG93cyhbdGhpcy5zZWxlY3RlZEZsb3dzSWRbMF1dKTtcbiAgICB9XG4gIH1cblxuICBfcmVuZGVyRmxvd1N0ZXBGb3JtKHJlYWRvbmx5TW9kZSkge1xuICAgIGNvbnN0IHZhbHVlcyA9IHRoaXMuX2N1cnJlbnRGbG93U3RlcC5fdmFsdWVzIHx8IHRoaXMuX2N1cnJlbnRGbG93U3RlcC5faW5pdGlhbFZhbHVlcztcblxuICAgIGNvbnN0IGdyb3VwcyA9IFt7IGl0ZW1zOiBbJ2NvbW1vbkRlc2NyaXB0aW9uJywgJ2NvbW1vbkNvbmRpdGlvbiddIH0sIHsgbmFtZTogaTE4bignZ3YtcG9saWN5LXN0dWRpby5wb2xpY3ktc2V0dGluZ3MnKSwgZGVmYXVsdDogdHJ1ZSB9XTtcbiAgICByZXR1cm4gaHRtbGAke2NhY2hlKFxuICAgICAgdGhpcy5fZmxvd1N0ZXBTY2hlbWEgJiYgdGhpcy5fY3VycmVudEZsb3dTdGVwXG4gICAgICAgID8gaHRtbGA8ZGl2IGNsYXNzPVwiZmxvdy1zdGVwX19jb250YWluZXJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmbG93LXN0ZXBfX2Zvcm1cIj5cbiAgICAgICAgICAgICAgPGd2LXNjaGVtYS1mb3JtXG4gICAgICAgICAgICAgICAgLmlkPVwiJHtGTE9XX1NURVBfRk9STV9JRH1cIlxuICAgICAgICAgICAgICAgIC5zY2hlbWE9XCIke3RoaXMuX2Zsb3dTdGVwU2NoZW1hfVwiXG4gICAgICAgICAgICAgICAgLmljb249XCJkZXNpZ246ZWRpdFwiXG4gICAgICAgICAgICAgICAgaGFzLWhlYWRlclxuICAgICAgICAgICAgICAgIHZhbGlkYXRlLW9uLXJlbmRlclxuICAgICAgICAgICAgICAgIC52YWx1ZXM9XCIke3ZhbHVlc31cIlxuICAgICAgICAgICAgICAgIC5kaXJ0eT1cIiR7dGhpcy5fY3VycmVudEZsb3dTdGVwLl92YWx1ZXMgIT0gbnVsbH1cIlxuICAgICAgICAgICAgICAgID9yZWFkb25seT1cIiR7cmVhZG9ubHlNb2RlfVwiXG4gICAgICAgICAgICAgICAgc2Nyb2xsYWJsZVxuICAgICAgICAgICAgICAgIC5ncm91cHM9XCIke2dyb3Vwc31cIlxuICAgICAgICAgICAgICAgIEBndi1zY2hlbWEtZm9ybTpjaGFuZ2U9XCIke3RoaXMuX29uQ2hhbmdlRmxvd1N0ZXB9XCJcbiAgICAgICAgICAgICAgICBAZ3Ytc2NoZW1hLWZvcm06cmVzZXQ9XCIke3RoaXMuX29uUmVzZXRGbG93U3RlcH1cIlxuICAgICAgICAgICAgICAgIEBndi1zY2hlbWEtZm9ybTpmZXRjaC1yZXNvdXJjZXM9XCIke3RoaXMuX29uRmV0Y2hSZXNvdXJjZXN9XCJcbiAgICAgICAgICAgICAgICBAZ3Ytc2NoZW1hLWZvcm06c3VibWl0PVwiJHt0aGlzLl9vblN1Ym1pdEZsb3dTdGVwfVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8ZGl2IHNsb3Q9XCJ0aXRsZVwiIGNsYXNzPVwiZmxvdy1zdGVwX19mb3JtLXRpdGxlXCI+JHt0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuc3RlcC5uYW1lfTwvZGl2PlxuICAgICAgICAgICAgICAgIDxndi1idXR0b25cbiAgICAgICAgICAgICAgICAgIHNsb3Q9XCJoZWFkZXItbGVmdFwiXG4gICAgICAgICAgICAgICAgICBpY29uPVwiZ2VuZXJhbDpjbG9zZVwiXG4gICAgICAgICAgICAgICAgICBvdXRsaW5lZFxuICAgICAgICAgICAgICAgICAgc21hbGxcbiAgICAgICAgICAgICAgICAgIEBndi1idXR0b246Y2xpY2s9XCIke3RoaXMuX29uQ2xvc2VGbG93U3RlcEZvcm19XCJcbiAgICAgICAgICAgICAgICAgIHRpdGxlPVwiQ2xvc2VcIlxuICAgICAgICAgICAgICAgID48L2d2LWJ1dHRvbj5cbiAgICAgICAgICAgICAgICA8Z3YtYnV0dG9uXG4gICAgICAgICAgICAgICAgICBzbG90PVwiaGVhZGVyLWxlZnRcIlxuICAgICAgICAgICAgICAgICAgaWNvbj1cImhvbWU6Ym9va1wiXG4gICAgICAgICAgICAgICAgICA/ZGlzYWJsZWQ9XCIke3RoaXMuZG9jdW1lbnRhdGlvbiAhPSBudWxsfVwiXG4gICAgICAgICAgICAgICAgICBvdXRsaW5lZFxuICAgICAgICAgICAgICAgICAgc21hbGxcbiAgICAgICAgICAgICAgICAgIEBndi1idXR0b246Y2xpY2s9XCIke3RoaXMuX29uT3BlbkRvY3VtZW50YXRpb25Gcm9tRm9ybX1cIlxuICAgICAgICAgICAgICAgICAgdGl0bGU9XCJPcGVuIGRvY3VtZW50YXRpb25cIlxuICAgICAgICAgICAgICAgID48L2d2LWJ1dHRvbj5cbiAgICAgICAgICAgICAgPC9ndi1zY2hlbWEtZm9ybT5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PmBcbiAgICAgICAgOiAnJyxcbiAgICApfWA7XG4gIH1cblxuICBfb25DbG9zZURvY3VtZW50YXRpb24oKSB7XG4gICAgdGhpcy5kb2N1bWVudGF0aW9uID0gbnVsbDtcbiAgICBpZiAodGhpcy5fY3VycmVudEZsb3dTdGVwID09IG51bGwpIHtcbiAgICAgIHRoaXMuX21heGltaXplVG9wVmlldygpO1xuICAgIH0gZWxzZSB7XG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnZ3YtcG9saWN5LXN0dWRpbzprZWVwLWRvY3VtZW50YXRpb24tY2xvc2UnLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICBfb25EZWxldGVGbG93KHsgZGV0YWlsIH0pIHtcbiAgICBjb25zdCBmbG93SWQgPSBkZXRhaWwuY29udGVudC5faWQ7XG4gICAgY29uc3QgeyBmbG93cyB9ID0gdGhpcy5fZmluZEZsb3dDb2xsZWN0aW9uKGZsb3dJZCk7XG4gICAgY29uc3QgZmxvdyA9IGZsb3dzLmZpbmQoKGZsb3cpID0+IGZsb3cuX2lkID09PSBmbG93SWQpO1xuICAgIHRoaXMuX2RlbGV0ZUZsb3coZmxvd3MsIGZsb3cpO1xuICB9XG5cbiAgZ2V0IGRlZmluZWRGbG93cygpIHtcbiAgICByZXR1cm4gdGhpcy5fZGVmaW5pdGlvbiAmJiB0aGlzLl9kZWZpbml0aW9uLmZsb3dzID8gdGhpcy5fZGVmaW5pdGlvbi5mbG93cyA6IFtdO1xuICB9XG5cbiAgZ2V0IGRlZmluZWRQbGFucygpIHtcbiAgICByZXR1cm4gdGhpcy5fZGVmaW5pdGlvbiAmJiB0aGlzLl9kZWZpbml0aW9uLnBsYW5zID8gdGhpcy5fZGVmaW5pdGlvbi5wbGFucyA6IFtdO1xuICB9XG5cbiAgZ2V0IGRlZmluZWRSZXNvdXJjZXMoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2RlZmluaXRpb24gJiYgdGhpcy5fZGVmaW5pdGlvbi5yZXNvdXJjZXMgPyB0aGlzLl9kZWZpbml0aW9uLnJlc291cmNlcyA6IFtdO1xuICB9XG5cbiAgZ2V0IGRlZmluZWRQcm9wZXJ0aWVzKCkge1xuICAgIHJldHVybiB0aGlzLl9kZWZpbml0aW9uICYmIHRoaXMuX2RlZmluaXRpb24ucHJvcGVydGllcyA/IHRoaXMuX2RlZmluaXRpb24ucHJvcGVydGllcyA6IFtdO1xuICB9XG5cbiAgYXN5bmMgX29uRHVwbGljYXRlRmxvdyh7IGRldGFpbCB9KSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuX2Fza1RvVmFsaWRhdGVGb3JtcygpO1xuXG4gICAgICBjb25zdCBmbG93SWQgPSBkZXRhaWwuY29udGVudC5faWQ7XG4gICAgICBjb25zdCB7IHBsYW4sIGZsb3dzIH0gPSB0aGlzLl9maW5kRmxvd0NvbGxlY3Rpb24oZmxvd0lkKTtcbiAgICAgIHRoaXMuX2FkZEZsb3coZmxvd3MsIHRoaXMuX2ZpbmRGbG93QnlJZChmbG93SWQpKTtcbiAgICAgIGlmIChwbGFuICE9IG51bGwpIHtcbiAgICAgICAgbGV0IHBsYW5JbmRleCA9IG51bGw7XG4gICAgICAgIHRoaXMuZGVmaW5lZFBsYW5zLmZpbmQoKHAsIGkpID0+IHtcbiAgICAgICAgICBpZiAocC5pZCA9PT0gcGxhbi5pZCkge1xuICAgICAgICAgICAgcGxhbkluZGV4ID0gaTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgICAgICBwbGFuLmZsb3dzID0gZmxvd3M7XG4gICAgICAgIHRoaXMuZGVmaW5lZFBsYW5zW3BsYW5JbmRleF0uZmxvd3MgPSB0aGlzLl9nZW5lcmF0ZVBsYW5GbG93c0lkKHBsYW4sIHRydWUpO1xuICAgICAgICB0aGlzLl91cGRhdGVTZWxlY3RlZEZsb3dzKFt0aGlzLmRlZmluZWRQbGFuc1twbGFuSW5kZXhdLmZsb3dzW2Zsb3dzLmxlbmd0aCAtIDFdLl9pZF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fZGVmaW5pdGlvbi5mbG93cyA9IHRoaXMuX2dlbmVyYXRlRmxvd3NJZCh0aGlzLl9kZWZpbml0aW9uLmZsb3dzKTtcbiAgICAgICAgdGhpcy5fdXBkYXRlU2VsZWN0ZWRGbG93cyhbdGhpcy5fZGVmaW5pdGlvbi5mbG93c1t0aGlzLl9kZWZpbml0aW9uLmZsb3dzLmxlbmd0aCAtIDFdLl9pZF0pO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbiA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgX29uQ2hhbmdlRmxvd1N0YXRlKHsgZGV0YWlsIH0pIHtcbiAgICBjb25zdCBmbG93ID0gdGhpcy5fZmluZEZsb3dCeUlkKGRldGFpbC5jb250ZW50Ll9pZCk7XG4gICAgZmxvdy5lbmFibGVkID0gZGV0YWlsLmVuYWJsZWQ7XG4gICAgZmxvdy5fZGlydHkgPSB0cnVlO1xuICAgIHRoaXMuaXNEaXJ0eSA9IHRydWU7XG4gIH1cblxuICBhc3luYyBfb25BZGRGbG93UGxhbih7IGRldGFpbCB9KSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuX2Fza1RvVmFsaWRhdGVGb3JtcygpO1xuICAgICAgdGhpcy5fYWRkRmxvdyh0aGlzLmRlZmluZWRQbGFuc1tkZXRhaWwucGxhbkluZGV4XS5mbG93cyk7XG4gICAgICB0aGlzLmRlZmluZWRQbGFuc1tkZXRhaWwucGxhbkluZGV4XS5mbG93cyA9IHRoaXMuX2dlbmVyYXRlUGxhbkZsb3dzSWQodGhpcy5kZWZpbmVkUGxhbnNbZGV0YWlsLnBsYW5JbmRleF0pO1xuICAgICAgdGhpcy5fdXBkYXRlU2VsZWN0ZWRGbG93cyhbdGhpcy5kZWZpbmVkUGxhbnNbZGV0YWlsLnBsYW5JbmRleF0uZmxvd3NbdGhpcy5kZWZpbmVkUGxhbnNbZGV0YWlsLnBsYW5JbmRleF0uZmxvd3MubGVuZ3RoIC0gMV0uX2lkXSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBhc3luYyBfb25BZGRGbG93KCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLl9hc2tUb1ZhbGlkYXRlRm9ybXMoKTtcblxuICAgICAgdGhpcy5fYWRkRmxvdyh0aGlzLl9kZWZpbml0aW9uLmZsb3dzKTtcbiAgICAgIHRoaXMuX2RlZmluaXRpb24uZmxvd3MgPSB0aGlzLl9nZW5lcmF0ZUZsb3dzSWQodGhpcy5fZGVmaW5pdGlvbi5mbG93cyk7XG4gICAgICB0aGlzLl91cGRhdGVTZWxlY3RlZEZsb3dzKFt0aGlzLl9kZWZpbml0aW9uLmZsb3dzW3RoaXMuX2RlZmluaXRpb24uZmxvd3MubGVuZ3RoIC0gMV0uX2lkXSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICB0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBfYWRkRmxvdyhjb2xsZWN0aW9uLCBkdXBsaWNhdGUgPSBudWxsKSB7XG4gICAgY29uc3QgZmxvdyA9XG4gICAgICBkdXBsaWNhdGUgPT0gbnVsbFxuICAgICAgICA/IHRoaXMuX2NyZWF0ZUZsb3dGcm9tU2NoZW1hKClcbiAgICAgICAgOiB7XG4gICAgICAgICAgICAuLi5kdXBsaWNhdGUsXG4gICAgICAgICAgICBfaWQ6IG51bGwsXG4gICAgICAgICAgICAvLyByZXNldCB0aGUgaWQgdG8gYXZvaWQgaXNzdWUgd2l0aCBBTSB0aGF0IHBlcnNpc3RzIHRoZSBJRFxuICAgICAgICAgICAgaWQ6IG51bGwsXG4gICAgICAgICAgICBfZGlydHk6IHRydWUsXG4gICAgICAgICAgfTtcblxuICAgIGNvbGxlY3Rpb24ucHVzaChmbG93KTtcbiAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICAgIHJldHVybiBjb2xsZWN0aW9uO1xuICB9XG5cbiAgX2NyZWF0ZUZsb3dGcm9tU2NoZW1hKCkge1xuICAgIGNvbnN0IG5ld0Zsb3cgPSB7XG4gICAgICBuYW1lOiAnJyxcbiAgICAgIHByZTogW10sXG4gICAgICBwb3N0OiBbXSxcbiAgICAgIF9kaXJ0eTogdHJ1ZSxcbiAgICB9O1xuXG4gICAgcmV0dXJuIHRoaXMuX2luc3RhbnRpYXRlKHRoaXMuZmxvd1NjaGVtYS5wcm9wZXJ0aWVzLCBuZXdGbG93KTtcbiAgfVxuXG4gIF9pbnN0YW50aWF0ZShwcm9wZXJ0aWVzRGVmaW5pdGlvbiwgaW5pdGlhdG9yID0ge30pIHtcbiAgICBjb25zdCBwcm9wZXJ0eSA9IHsgLi4uaW5pdGlhdG9yIH07XG5cbiAgICBpZiAocHJvcGVydGllc0RlZmluaXRpb24pIHtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHByb3BlcnRpZXNEZWZpbml0aW9uKSkge1xuICAgICAgICBjb25zdCBlbnRyeSA9IHByb3BlcnRpZXNEZWZpbml0aW9uW2tleV07XG5cbiAgICAgICAgaWYgKGVudHJ5LnR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgcHJvcGVydHlba2V5XSA9IHRoaXMuX2luc3RhbnRpYXRlKGVudHJ5LnByb3BlcnRpZXMsIChpbml0aWF0b3IgPSB7fSkpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlbnRyeS5kZWZhdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBwcm9wZXJ0eVtrZXldID0gZW50cnkuZGVmYXVsdDtcbiAgICAgICAgfSBlbHNlIGlmIChlbnRyeS50eXBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHByb3BlcnR5W2tleV0gPSAnJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwcm9wZXJ0eTtcbiAgfVxuXG4gIF9kZWxldGVGbG93KGNvbGxlY3Rpb24sIGZsb3cpIHtcbiAgICBjb25zdCBpbmRleCA9IGNvbGxlY3Rpb24uaW5kZXhPZihmbG93KTtcbiAgICBjb2xsZWN0aW9uLnNwbGljZShpbmRleCwgMSk7XG4gICAgY29uc3Qgc2VsZWN0ZWRGbG93cyA9IHRoaXMuc2VsZWN0ZWRGbG93c0lkLmZpbHRlcigoZmxvd0lkKSA9PiBmbG93SWQgIT09IGZsb3cuX2lkKTtcbiAgICBpZiAoc2VsZWN0ZWRGbG93cy5sZW5ndGggPT09IDEpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVNlbGVjdGVkRmxvd3Moc2VsZWN0ZWRGbG93cyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3NlbGVjdEZpcnN0Rmxvdyh0cnVlKTtcbiAgICB9XG4gICAgdGhpcy5fY2hhbmdlVGFiKCdkZXNpZ24nKTtcbiAgICB0aGlzLl9yZWZyZXNoKCk7XG4gICAgdGhpcy5pc0RpcnR5ID0gdHJ1ZTtcbiAgfVxuXG4gIF9maW5kRmxvd0luZGV4KGxpc3QsIGlkKSB7XG4gICAgbGV0IGluZGV4ID0gbnVsbDtcbiAgICBsaXN0LmZpbmQoKGYsIGkpID0+IHtcbiAgICAgIGlmIChmLl9pZCA9PT0gaWQpIHtcbiAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9KTtcbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICBhc3luYyBfb25SZW9yZGVyRmxvd3MoeyBkZXRhaWw6IHsgcGxhbiB9IH0pIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5fYXNrVG9WYWxpZGF0ZUZvcm1zKCk7XG4gICAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICAgICAgaWYgKHBsYW4gIT0gbnVsbCkge1xuICAgICAgICBjb25zdCBuZXdPcmRlciA9IHRoaXMuX2dlbmVyYXRlUGxhbkZsb3dzSWQocGxhbiwgdHJ1ZSk7XG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkRmxvd3NJZCkge1xuICAgICAgICAgIHRoaXMuX3VwZGF0ZVNlbGVjdGVkRmxvd3MoXG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkRmxvd3NJZC5tYXAoKGZsb3dJZCkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMuX2ZpbmRGbG93SW5kZXgocGxhbi5mbG93cywgZmxvd0lkKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGluZGV4ICE9IG51bGwgPyBuZXdPcmRlcltpbmRleF0uX2lkIDogZmxvd0lkO1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBwbGFuLmZsb3dzID0gbmV3T3JkZXI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBuZXdPcmRlciA9IHRoaXMuX2dlbmVyYXRlRmxvd3NJZCh0aGlzLl9kZWZpbml0aW9uLmZsb3dzLCB0cnVlKTtcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRGbG93c0lkKSB7XG4gICAgICAgICAgdGhpcy5fdXBkYXRlU2VsZWN0ZWRGbG93cyhcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRGbG93c0lkLm1hcCgoZmxvd0lkKSA9PiB7XG4gICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fZmluZEZsb3dJbmRleCh0aGlzLl9kZWZpbml0aW9uLmZsb3dzLCBmbG93SWQpO1xuICAgICAgICAgICAgICByZXR1cm4gaW5kZXggIT0gbnVsbCA/IG5ld09yZGVyW2luZGV4XS5faWQgOiBmbG93SWQ7XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2RlZmluaXRpb24uZmxvd3MgPSBuZXdPcmRlcjtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb24gPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBfb25TZWFyY2hQb2xpY3koeyBkZXRhaWwgfSkge1xuICAgIHRoaXMuX3NlYXJjaFBvbGljeVF1ZXJ5ID0gZGV0YWlsO1xuICB9XG5cbiAgX29uQ2xlYXJQb2xpY3koKSB7XG4gICAgdGhpcy5fc2VhcmNoUG9saWN5UXVlcnkgPSBudWxsO1xuICB9XG5cbiAgX29uU2VhcmNoRmxvd3MoeyBkZXRhaWwgfSkge1xuICAgIHRoaXMuX3NlYXJjaEZsb3dRdWVyeSA9IGRldGFpbDtcbiAgfVxuXG4gIF9vbkNsZWFyRmxvd3MoKSB7XG4gICAgdGhpcy5fc2VhcmNoRmxvd1F1ZXJ5ID0gbnVsbDtcbiAgfVxuXG4gIGFzeW5jIF9vblJlc2V0QWxsKCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLl9jbG9zZUZsb3dTdGVwRm9ybSgpO1xuICAgICAgdGhpcy5kZWZpbml0aW9uID0gZGVlcENsb25lKHRoaXMuX2luaXRpYWxEZWZpbml0aW9uKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9uID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBfZmlsdGVyTm90VmFsaWRTdGVwKHN0ZXApIHtcbiAgICByZXR1cm4gc3RlcC5fbmV3ICE9PSB0cnVlO1xuICB9XG5cbiAgX3JlbW92ZVByaXZhdGVQcm9wZXJ0aWVzKG8pIHtcbiAgICBjb25zdCBjb3B5ID0geyAuLi5vIH07XG4gICAgT2JqZWN0LmtleXMobylcbiAgICAgIC5maWx0ZXIoKGtleSkgPT4ga2V5LnN0YXJ0c1dpdGgoJ18nKSlcbiAgICAgIC5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgZGVsZXRlIGNvcHlba2V5XTtcbiAgICAgIH0pO1xuICAgIHJldHVybiBjb3B5O1xuICB9XG5cbiAgX3N1Ym1pdE9yQ29uZmlybUZvcm1zKCkge1xuICAgIHJldHVybiBbLi4udGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3JBbGwoJ2d2LXNjaGVtYS1mb3JtJyldXG4gICAgICAuZmlsdGVyKChmb3JtKSA9PiB7XG4gICAgICAgIGNvbnN0IGlzVmFsaWQgPSBmb3JtLmlzVmFsaWQoKTtcbiAgICAgICAgaWYgKGlzVmFsaWQpIHtcbiAgICAgICAgICBmb3JtLnN1Ym1pdCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGZvcm0uZGlydHkgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhaXNWYWxpZDtcbiAgICAgIH0pXG4gICAgICAubWFwKChmb3JtKSA9PiBmb3JtLmNvbmZpcm0oKSk7XG4gIH1cblxuICBnZXRQcm9wZXJ0aWVzRWxlbWVudCgpIHtcbiAgICByZXR1cm4gdGhpcy5zaGFkb3dSb290LnF1ZXJ5U2VsZWN0b3IoJ2d2LXByb3BlcnRpZXMnKTtcbiAgfVxuXG4gIGFzeW5jIF9jaGVja0N1cnJlbnRGbG93U3RlcCgpIHtcbiAgICBpZiAodGhpcy5fY3VycmVudEZsb3dTdGVwICYmIHRoaXMuc2VsZWN0ZWRGbG93c0lkKSB7XG4gICAgICBjb25zdCBjbG9zZVByb21pc2VzID0gdGhpcy5zZWxlY3RlZEZsb3dzSWRcbiAgICAgICAgLm1hcCgoZmxvd0lkKSA9PiB7XG4gICAgICAgICAgY29uc3QgZmxvdyA9IHRoaXMuX2ZpbmRGbG93QnlJZChmbG93SWQpO1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnRTdGVwID0gWy4uLmZsb3cucHJlLCAuLi5mbG93LnBvc3RdLmZpbmQoKHN0ZXApID0+IHN0ZXAuX2lkID09PSB0aGlzLl9jdXJyZW50Rmxvd1N0ZXAuc3RlcC5faWQpO1xuICAgICAgICAgIGlmIChjdXJyZW50U3RlcCA9PSBudWxsKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fY2xvc2VGbG93U3RlcEZvcm0odHJ1ZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9KVxuICAgICAgICAuZmlsdGVyKChwKSA9PiBwICE9PSBudWxsKTtcbiAgICAgIHJldHVybiBQcm9taXNlLmFsbChjbG9zZVByb21pc2VzKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgc2F2ZWQoKSB7XG4gICAgaWYgKHRoaXMuaXNEaXJ0eSkge1xuICAgICAgdGhpcy5faW5pdGlhbERlZmluaXRpb24gPSBkZWVwQ2xvbmUodGhpcy5fZGVmaW5pdGlvblNhdmVkKTtcbiAgICAgIHRoaXMuX2RlZmluaXRpb24gPSBkZWVwQ2xvbmUodGhpcy5fZGVmaW5pdGlvblNhdmVkKTtcbiAgICAgIHRoaXMuX2RlZmluaXRpb25TYXZlZCA9IG51bGw7XG4gICAgICB0aGlzLmlzRGlydHkgPSBmYWxzZTtcbiAgICAgIHRoaXMuX2NoZWNrQ3VycmVudEZsb3dTdGVwKCk7XG4gICAgICB0aGlzLmRlZmluZWRQbGFucy5mb3JFYWNoKChwbGFuKSA9PiB7XG4gICAgICAgIHBsYW4uZmxvd3MuZm9yRWFjaCgoZmxvdykgPT4gKGZsb3cuX2RpcnR5ID0gZmFsc2UpKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5kZWZpbmVkRmxvd3MuZm9yRWFjaCgoZmxvdykgPT4gKGZsb3cuX2RpcnR5ID0gZmFsc2UpKTtcbiAgICAgIHRoaXMuZ2V0Q2hpbGRyZW4oKS5mb3JFYWNoKChlKSA9PiBlLnJlcXVlc3RVcGRhdGUoKSk7XG4gICAgfVxuICB9XG5cbiAgX2J1aWxkRGVmaW5pdGlvblRvU2F2ZSgpIHtcbiAgICAvLyBDb3B5IGRlZmluaXRpb24gYW5kIHJlbW92ZSBpbnZhbGlkIHN0ZXBcbiAgICAvLyBLZWVwIHByaXZhdGUgcHJvcGVydGllcyBsaWtlIF9pZCBhbmQgb3RoZXJzIHN0dWZmIHVzZWZ1bCBmb3IgcmVuZGVyXG4gICAgY29uc3QgZmxvd3MgPSB0aGlzLl9kZWZpbml0aW9uLmZsb3dzLm1hcCgoZmxvdykgPT4ge1xuICAgICAgZmxvdy5wcmUgPSBmbG93LnByZS5maWx0ZXIodGhpcy5fZmlsdGVyTm90VmFsaWRTdGVwKTtcbiAgICAgIGZsb3cucG9zdCA9IGZsb3cucG9zdC5maWx0ZXIodGhpcy5fZmlsdGVyTm90VmFsaWRTdGVwKTtcbiAgICAgIHJldHVybiBmbG93O1xuICAgIH0pO1xuXG4gICAgbGV0IGRlZmluaXRpb24gPSB7IC4uLnRoaXMuX2RlZmluaXRpb24sIGZsb3dzIH07XG5cbiAgICBpZiAodGhpcy5fZGVmaW5pdGlvbi5wbGFucyAhPSBudWxsKSB7XG4gICAgICBjb25zdCBwbGFucyA9IHRoaXMuX2RlZmluaXRpb24ucGxhbnMubWFwKChwbGFuKSA9PiB7XG4gICAgICAgIGNvbnN0IGZsb3dzID0gcGxhbi5mbG93cy5tYXAoKGZsb3cpID0+IHtcbiAgICAgICAgICBmbG93LnByZSA9IGZsb3cucHJlLmZpbHRlcih0aGlzLl9maWx0ZXJOb3RWYWxpZFN0ZXApO1xuICAgICAgICAgIGZsb3cucG9zdCA9IGZsb3cucG9zdC5maWx0ZXIodGhpcy5fZmlsdGVyTm90VmFsaWRTdGVwKTtcbiAgICAgICAgICByZXR1cm4gZmxvdztcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiB7IC4uLnBsYW4sIGZsb3dzIH07XG4gICAgICB9KTtcbiAgICAgIGRlZmluaXRpb24gPSB7IC4uLmRlZmluaXRpb24sIHBsYW5zIH07XG4gICAgfVxuICAgIHJldHVybiBkZWZpbml0aW9uO1xuICB9XG5cbiAgX2J1aWxkRGVmaW5pdGlvblRvU2VuZChkZWZpbml0aW9uVG9TYXZlKSB7XG4gICAgLy8gQ29weSBkZWZpbml0aW9uIGFuZCByZW1vdmUgYWxsIHByaXZhdGUgcHJvcGVydGllc1xuICAgIGNvbnN0IGZsb3dzID0gZGVmaW5pdGlvblRvU2F2ZS5mbG93cy5tYXAoKGYpID0+IHtcbiAgICAgIGNvbnN0IGZsb3cgPSB0aGlzLl9yZW1vdmVQcml2YXRlUHJvcGVydGllcyhmKTtcbiAgICAgIGZsb3cucHJlID0gZmxvdy5wcmUubWFwKHRoaXMuX3JlbW92ZVByaXZhdGVQcm9wZXJ0aWVzKTtcbiAgICAgIGZsb3cucG9zdCA9IGZsb3cucG9zdC5tYXAodGhpcy5fcmVtb3ZlUHJpdmF0ZVByb3BlcnRpZXMpO1xuICAgICAgcmV0dXJuIGZsb3c7XG4gICAgfSk7XG5cbiAgICBsZXQgZGVmaW5pdGlvbiA9IHsgLi4udGhpcy5fZGVmaW5pdGlvbiwgZmxvd3MgfTtcbiAgICBpZiAodGhpcy5fZGVmaW5pdGlvbi5wbGFucyAhPSBudWxsKSB7XG4gICAgICBjb25zdCBwbGFucyA9IGRlZmluaXRpb25Ub1NhdmUucGxhbnMubWFwKChwbGFuKSA9PiB7XG4gICAgICAgIGNvbnN0IGZsb3dzID0gcGxhbi5mbG93cy5tYXAoKGYpID0+IHtcbiAgICAgICAgICBjb25zdCBmbG93ID0gdGhpcy5fcmVtb3ZlUHJpdmF0ZVByb3BlcnRpZXMoZik7XG4gICAgICAgICAgZmxvdy5wcmUgPSBmbG93LnByZS5tYXAodGhpcy5fcmVtb3ZlUHJpdmF0ZVByb3BlcnRpZXMpO1xuICAgICAgICAgIGZsb3cucG9zdCA9IGZsb3cucG9zdC5tYXAodGhpcy5fcmVtb3ZlUHJpdmF0ZVByb3BlcnRpZXMpO1xuICAgICAgICAgIHJldHVybiBmbG93O1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHsgLi4ucGxhbiwgZmxvd3MgfTtcbiAgICAgIH0pO1xuICAgICAgZGVmaW5pdGlvbiA9IHsgLi4uZGVmaW5pdGlvbiwgcGxhbnMgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZGVmaW5pdGlvbi5wcm9wZXJ0aWVzICE9IG51bGwpIHtcbiAgICAgIGNvbnN0IHByb3BlcnRpZXMgPSB0aGlzLl9kZWZpbml0aW9uLnByb3BlcnRpZXMubWFwKHRoaXMuX3JlbW92ZVByaXZhdGVQcm9wZXJ0aWVzKTtcbiAgICAgIGRlZmluaXRpb24gPSB7IC4uLmRlZmluaXRpb24sIHByb3BlcnRpZXMgfTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZGVmaW5pdGlvbi5yZXNvdXJjZXMgIT0gbnVsbCkge1xuICAgICAgY29uc3QgcmVzb3VyY2VzID0gdGhpcy5fZGVmaW5pdGlvbi5yZXNvdXJjZXMubWFwKHRoaXMuX3JlbW92ZVByaXZhdGVQcm9wZXJ0aWVzKTtcbiAgICAgIGRlZmluaXRpb24gPSB7IC4uLmRlZmluaXRpb24sIHJlc291cmNlcyB9O1xuICAgIH1cblxuICAgIHJldHVybiBkZWZpbml0aW9uO1xuICB9XG5cbiAgX29uU2F2ZUFsbCgpIHtcbiAgICBpZiAodGhpcy5oYXNQcm9wZXJ0aWVzKSB7XG4gICAgICB0aGlzLmdldFByb3BlcnRpZXNFbGVtZW50KCkuc3VibWl0KCk7XG4gICAgfVxuXG4gICAgUHJvbWlzZS5hbGwodGhpcy5fc3VibWl0T3JDb25maXJtRm9ybXMoKSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5fZGVmaW5pdGlvblNhdmVkID0gdGhpcy5fYnVpbGREZWZpbml0aW9uVG9TYXZlKCk7XG4gICAgICAgIGNvbnN0IGRlZmluaXRpb24gPSB0aGlzLl9idWlsZERlZmluaXRpb25Ub1NlbmQodGhpcy5fZGVmaW5pdGlvblNhdmVkKTtcbiAgICAgICAgZGlzcGF0Y2hDdXN0b21FdmVudCh0aGlzLCAnc2F2ZScsIHsgZGVmaW5pdGlvbiwgc2VydmljZXM6IHRoaXMuc2VydmljZXMgfSk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgW3BvbGljeS1zdHVkaW9dIEVycm9yIG9uIHNhdmVgLCBlcnIpO1xuICAgICAgfSk7XG4gIH1cblxuICBfb25EZWJ1ZyhyZXF1ZXN0RXZlbnQpIHtcbiAgICBpZiAodGhpcy5oYXNQcm9wZXJ0aWVzKSB7XG4gICAgICB0aGlzLmdldFByb3BlcnRpZXNFbGVtZW50KCkuc3VibWl0KCk7XG4gICAgfVxuXG4gICAgUHJvbWlzZS5hbGwodGhpcy5fc3VibWl0T3JDb25maXJtRm9ybXMoKSlcbiAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgY29uc3QgZGVmaW5pdGlvbiA9IHRoaXMuX2J1aWxkRGVmaW5pdGlvblRvU2VuZCh0aGlzLl9idWlsZERlZmluaXRpb25Ub1NhdmUoKSk7XG4gICAgICAgIGRpc3BhdGNoQ3VzdG9tRXZlbnQodGhpcywgJ2RlYnVnJywgeyBkZWZpbml0aW9uLCBzZXJ2aWNlczogdGhpcy5zZXJ2aWNlcywgcmVxdWVzdDogcmVxdWVzdEV2ZW50LmRldGFpbC5yZXF1ZXN0IH0pO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoZXJyKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYFtwb2xpY3ktc3R1ZGlvXSBFcnJvciBvbiBkZWJ1Z2AsIGVycik7XG4gICAgICB9KTtcbiAgfVxuXG4gIGdldCBmaWx0ZXJlZEZsb3dzKCkge1xuICAgIGlmICh0aGlzLl9mbG93RmlsdGVyLmxlbmd0aCA9PT0gMCB8fCB0aGlzLl9mbG93RmlsdGVyLmluY2x1ZGVzKCdhcGknKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZGVmaW5lZEZsb3dzO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGdldCBmaWx0ZXJlZFBsYW5zKCkge1xuICAgIGlmICh0aGlzLl9mbG93RmlsdGVyLmxlbmd0aCA9PT0gMCB8fCB0aGlzLl9mbG93RmlsdGVyLmluY2x1ZGVzKCdwbGFuJykpIHtcbiAgICAgIHJldHVybiB0aGlzLmRlZmluZWRQbGFucztcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBfb25GaWx0ZXJGbG93cyh7IGRldGFpbCB9KSB7XG4gICAgaWYgKHRoaXMuX2Zsb3dGaWx0ZXIuaW5jbHVkZXMoZGV0YWlsLmlkKSkge1xuICAgICAgdGhpcy5fZmxvd0ZpbHRlciA9IFtdO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9mbG93RmlsdGVyID0gW2RldGFpbC5pZF07XG4gICAgfVxuICB9XG5cbiAgX2dldEZpbHRlcmVkUG9saWNpZXMoKSB7XG4gICAgaWYgKHRoaXMuX3BvbGljeUZpbHRlci5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gdGhpcy5wb2xpY2llcy5maWx0ZXIoKHBvbGljeSkgPT4ge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIChwb2xpY3kub25SZXF1ZXN0ICYmIHRoaXMuX3BvbGljeUZpbHRlci5pbmNsdWRlcygnb25SZXF1ZXN0JykpIHx8IChwb2xpY3kub25SZXNwb25zZSAmJiB0aGlzLl9wb2xpY3lGaWx0ZXIuaW5jbHVkZXMoJ29uUmVzcG9uc2UnKSlcbiAgICAgICAgKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5wb2xpY2llcztcbiAgfVxuXG4gIF9vbkZpbHRlclBvbGljaWVzKHsgZGV0YWlsIH0pIHtcbiAgICBpZiAodGhpcy5fcG9saWN5RmlsdGVyLmluY2x1ZGVzKGRldGFpbC5pZCkpIHtcbiAgICAgIHRoaXMuX3BvbGljeUZpbHRlciA9IFtdO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9wb2xpY3lGaWx0ZXIgPSBbZGV0YWlsLmlkXTtcbiAgICB9XG4gIH1cblxuICBfcmVuZGVyRGVzaWduKHJlYWRvbmx5TW9kZSkge1xuICAgIHJldHVybiBodG1sYCA8ZGl2IGlkPVwiZGVzaWduXCIgc2xvdD1cImNvbnRlbnRcIiBjbGFzcz1cImRlc2lnblwiPlxuICAgICAgPGd2LXJlc2l6YWJsZS12aWV3cyBuby1vdmVyZmxvdz5cbiAgICAgICAgPGRpdiBzbG90PVwidG9wXCI+JHt0aGlzLl9yZW5kZXJGbG93KDAsIHRydWUsIHJlYWRvbmx5TW9kZSl9PC9kaXY+XG5cbiAgICAgICAgPGRpdiBzbG90PVwiYm90dG9tXCI+XG4gICAgICAgICAgJHt0aGlzLl9yZW5kZXJGbG93KDEsIGZhbHNlLCByZWFkb25seU1vZGUpfSAke3RoaXMuX3JlbmRlclBvbGljeShyZWFkb25seU1vZGUpfSAke3RoaXMuX3JlbmRlckZsb3dGb3JtKHJlYWRvbmx5TW9kZSl9XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9ndi1yZXNpemFibGUtdmlld3M+XG4gICAgICAke3JlYWRvbmx5TW9kZSAhPT0gdHJ1ZVxuICAgICAgICA/IGh0bWxgPGd2LXBvbGljeS1zdHVkaW8tbWVudVxuICAgICAgICAgICAgY2xhc3M9XCJyaWdodC1tZW51XCJcbiAgICAgICAgICAgID9kaXNhYmxlZD1cIiR7dGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbn1cIlxuICAgICAgICAgICAgLnBvbGljaWVzPVwiJHt0aGlzLl9nZXRGaWx0ZXJlZFBvbGljaWVzKCl9XCJcbiAgICAgICAgICAgIC5zZWxlY3RlZElkcz1cIiR7W3RoaXMuX2N1cnJlbnRQb2xpY3lJZF19XCJcbiAgICAgICAgICAgIC5xdWVyeT1cIiR7dGhpcy5fc2VhcmNoUG9saWN5UXVlcnl9XCJcbiAgICAgICAgICAgID9oYXMtcG9saWN5LWZpbHRlcj1cIiR7dGhpcy5fcG9saWN5RmlsdGVyT3B0aW9ucyAhPSBudWxsfVwiXG4gICAgICAgICAgICA/cmVhZG9ubHk9XCIke3JlYWRvbmx5TW9kZX1cIlxuICAgICAgICAgICAgQGd2LXBvbGljeS1zdHVkaW8tbWVudTp0YXJnZXQtcG9saWN5PVwiJHt0aGlzLl9vblRhcmdldFBvbGljeX1cIlxuICAgICAgICAgICAgQGd2LXBvbGljeS1zdHVkaW8tbWVudTpmZXRjaC1kb2N1bWVudGF0aW9uPVwiJHt0aGlzLl9vbk9wZW5Eb2N1bWVudGF0aW9uRnJvbU1lbnV9XCJcbiAgICAgICAgICAgIEBndi1wb2xpY3ktc3R1ZGlvLW1lbnU6ZHJhZ2VuZC1wb2xpY3k9XCIke3RoaXMuX29uRHJhZ0VuZFBvbGljeX1cIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxkaXYgc2xvdD1cImhlYWRlclwiIGNsYXNzPVwic2VhcmNoLXBvbGljaWVzXCI+XG4gICAgICAgICAgICAgICR7dGhpcy5fcG9saWN5RmlsdGVyT3B0aW9ucyAhPSBudWxsXG4gICAgICAgICAgICAgICAgPyBodG1sYDxndi1vcHRpb25cbiAgICAgICAgICAgICAgICAgICAgP2Rpc2FibGVkPVwiJHt0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9ufVwiXG4gICAgICAgICAgICAgICAgICAgIC5vcHRpb25zPVwiJHt0aGlzLl9wb2xpY3lGaWx0ZXJPcHRpb25zfVwiXG4gICAgICAgICAgICAgICAgICAgIG11bHRpcGxlXG4gICAgICAgICAgICAgICAgICAgIG91dGxpbmVkXG4gICAgICAgICAgICAgICAgICAgIC52YWx1ZT1cIiR7dGhpcy5fcG9saWN5RmlsdGVyfVwiXG4gICAgICAgICAgICAgICAgICAgIHNtYWxsXG4gICAgICAgICAgICAgICAgICAgIEBndi1vcHRpb246c2VsZWN0PVwiJHt0aGlzLl9vbkZpbHRlclBvbGljaWVzfVwiXG4gICAgICAgICAgICAgICAgICA+PC9ndi1vcHRpb24+YFxuICAgICAgICAgICAgICAgIDogJyd9XG4gICAgICAgICAgICAgIDxndi1pbnB1dFxuICAgICAgICAgICAgICAgIGlkPVwic2VhcmNoLXBvbGljeVwiXG4gICAgICAgICAgICAgICAgP2Rpc2FibGVkPVwiJHt0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9ufVwiXG4gICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJGaWx0ZXIgcG9saWNpZXMgKFNoaWZ0ICsgQ3RybCArIFNwYWNlKVwiXG4gICAgICAgICAgICAgICAgdHlwZT1cInNlYXJjaFwiXG4gICAgICAgICAgICAgICAgc21hbGxcbiAgICAgICAgICAgICAgICBAZ3YtaW5wdXQ6aW5wdXQ9XCIke3RoaXMuX29uU2VhcmNoUG9saWN5fVwiXG4gICAgICAgICAgICAgICAgQGd2LWlucHV0OmNsZWFyPVwiJHt0aGlzLl9vbkNsZWFyUG9saWN5fVwiXG4gICAgICAgICAgICAgID48L2d2LWlucHV0PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9ndi1wb2xpY3ktc3R1ZGlvLW1lbnU+YFxuICAgICAgICA6ICcnfVxuICAgIDwvZGl2PmA7XG4gIH1cblxuICBfcmVuZGVyRGVidWcoKSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLmRlYnVnUmVzcG9uc2UgPyB0aGlzLmRlYnVnUmVzcG9uc2UucmVzcG9uc2UgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgaXNMb2FkaW5nID0gdGhpcy5kZWJ1Z1Jlc3BvbnNlID8gdGhpcy5kZWJ1Z1Jlc3BvbnNlLmlzTG9hZGluZyA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBwYXRoID0gdGhpcy5kZWJ1Z1Jlc3BvbnNlICYmIHRoaXMuZGVidWdSZXNwb25zZS5yZXF1ZXN0ID8gdGhpcy5kZWJ1Z1Jlc3BvbnNlLnJlcXVlc3QucGF0aCA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBtZXRob2QgPSB0aGlzLmRlYnVnUmVzcG9uc2UgJiYgdGhpcy5kZWJ1Z1Jlc3BvbnNlLnJlcXVlc3QgPyB0aGlzLmRlYnVnUmVzcG9uc2UucmVxdWVzdC5tZXRob2QgOiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIGh0bWxgPGd2LWh0dHAtY2xpZW50XG4gICAgICBpZD1cImRlYnVnXCJcbiAgICAgIHNsb3Q9XCJjb250ZW50XCJcbiAgICAgIGNsYXNzPVwiZGVidWdcIlxuICAgICAgQGd2LWh0dHAtY2xpZW50OnNlbmQ9XCIke3RoaXMuX29uRGVidWd9XCJcbiAgICAgIC5yZXNwb25zZT1cIiR7cmVzcG9uc2V9XCJcbiAgICAgIC5wYXRoPVwiJHtwYXRofVwiXG4gICAgICAubWV0aG9kPVwiJHttZXRob2R9XCJcbiAgICAgID9sb2FkaW5nPVwiJHtpc0xvYWRpbmd9XCJcbiAgICA+XG4gICAgPC9ndi1odHRwLWNsaWVudD5gO1xuICB9XG5cbiAgX3JlbmRlckNvbmZpZ3VyYXRpb25Gb3JtKHJlYWRvbmx5TW9kZSkge1xuICAgIGlmICh0aGlzLmNvbmZpZ3VyYXRpb25TY2hlbWEpIHtcbiAgICAgIGNvbnN0IHZhbHVlcyA9IGRlZXBDbG9uZSh0aGlzLl9kZWZpbml0aW9uKTtcbiAgICAgIHJldHVybiBodG1sYCA8ZGl2IGlkPVwic2V0dGluZ3NcIiBzbG90PVwiY29udGVudFwiIGNsYXNzPVwiYXBpLXNldHRpbmdzXCIgQGRyYWdvdmVyPVwiJHt0aGlzLl9vbkRlc2lnbn1cIj5cbiAgICAgICAgPGd2LXNjaGVtYS1mb3JtXG4gICAgICAgICAgLnNjaGVtYT1cIiR7dGhpcy5jb25maWd1cmF0aW9uU2NoZW1hfVwiXG4gICAgICAgICAgaWQ9XCJhcGktc2V0dGluZ3MtZm9ybVwiXG4gICAgICAgICAgLnZhbHVlcz1cIiR7dmFsdWVzfVwiXG4gICAgICAgICAgaGFzLWhlYWRlclxuICAgICAgICAgIGhhcy1mb290ZXJcbiAgICAgICAgICBzY3JvbGxhYmxlXG4gICAgICAgICAgP3JlYWRvbmx5PVwiJHtyZWFkb25seU1vZGV9XCJcbiAgICAgICAgICBAZ3Ytc2NoZW1hLWZvcm06Y2FuY2VsPVwiJHt0aGlzLl9vbkNhbmNlbEZsb3dNb2RlfVwiXG4gICAgICAgICAgQGd2LXNjaGVtYS1mb3JtOnN1Ym1pdD1cIiR7dGhpcy5fb25TdWJtaXRGbG93TW9kZX1cIlxuICAgICAgICA+XG4gICAgICAgICAgJHshdGhpcy5jb25maWd1cmF0aW9uSW5mb3JtYXRpb25cbiAgICAgICAgICAgID8gJydcbiAgICAgICAgICAgIDogaHRtbGBcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYXBpLXNldHRpbmdzLWluZm9ybWF0aW9uXCIgc2xvdD1cInRpdGxlXCI+XG4gICAgICAgICAgICAgICAgICA8Z3YtaWNvbiBjbGFzcz1cImFwaS1zZXR0aW5ncy1pbmZvcm1hdGlvbl9faWNvblwiIHRpdGxlPVwiSW5mb1wiIHNoYXBlPVwiY29kZTppbmZvXCI+PC9ndi1pY29uPlxuICAgICAgICAgICAgICAgICAgPGJsb2NrcXVvdGUgY2xhc3M9XCJhcGktc2V0dGluZ3MtaW5mb3JtYXRpb25fX2Jsb2NrcXVvdGVcIj4ke3RoaXMuY29uZmlndXJhdGlvbkluZm9ybWF0aW9ufTwvYmxvY2txdW90ZT5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgYH1cbiAgICAgICAgPC9ndi1zY2hlbWEtZm9ybT5cbiAgICAgIDwvZGl2PmA7XG4gICAgfVxuICAgIHJldHVybiBodG1sYGA7XG4gIH1cblxuICBfcmVuZGVyRmxvd0Zvcm0ocmVhZG9ubHlNb2RlKSB7XG4gICAgaWYgKHRoaXMuZmxvd1NjaGVtYSAmJiB0aGlzLl9mbG93U3RlcFNjaGVtYSA9PSBudWxsICYmIHRoaXMuZG9jdW1lbnRhdGlvbiA9PSBudWxsICYmIHRoaXMuc2VsZWN0ZWRGbG93c0lkLmxlbmd0aCA9PT0gMSkge1xuICAgICAgY29uc3QgZmxvdyA9IHRoaXMuZ2V0U2VsZWN0ZWRGbG93KCk7XG4gICAgICBpZiAoZmxvdykge1xuICAgICAgICBjb25zdCB2YWx1ZXMgPSBkZWVwQ2xvbmUoZmxvdyk7XG4gICAgICAgIHJldHVybiBodG1sYDxkaXYgc2xvdD1cImNvbnRlbnRcIiBjbGFzcz1cImZsb3ctc2V0dGluZ3NcIj5cbiAgICAgICAgICA8Z3Ytc2NoZW1hLWZvcm1cbiAgICAgICAgICAgIC5zY2hlbWE9XCIke3RoaXMuZmxvd1NjaGVtYX1cIlxuICAgICAgICAgICAgaWQ9XCJzZXR0aW5ncy1mb3JtXCJcbiAgICAgICAgICAgIC52YWx1ZXM9XCIke3ZhbHVlc31cIlxuICAgICAgICAgICAgaGFzLWhlYWRlclxuICAgICAgICAgICAgc2Nyb2xsYWJsZVxuICAgICAgICAgICAgP3JlYWRvbmx5PVwiJHtyZWFkb25seU1vZGV9XCJcbiAgICAgICAgICAgIEBndi1zY2hlbWEtZm9ybTpjYW5jZWw9XCIke3RoaXMuX29uQ2FuY2VsRmxvd31cIlxuICAgICAgICAgICAgQGd2LXNjaGVtYS1mb3JtOnN1Ym1pdD1cIiR7dGhpcy5fb25TdWJtaXRGbG93fVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGRpdiBzbG90PVwidGl0bGVcIiBjbGFzcz1cImZsb3ctc3RlcF9fZm9ybS10aXRsZVwiPkZsb3cgY29uZmlndXJhdGlvbjwvZGl2PlxuICAgICAgICAgIDwvZ3Ytc2NoZW1hLWZvcm0+XG4gICAgICAgIDwvZGl2PmA7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgX29uUmVzb3VyY2VzQ2hhbmdlKHsgZGV0YWlsIH0pIHtcbiAgICB0aGlzLmRlZmluaXRpb24ucmVzb3VyY2VzID0gZGV0YWlsLnJlc291cmNlcztcbiAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICB9XG5cbiAgX29uUHJvcGVydGllc0NoYW5nZSh7IGRldGFpbCB9KSB7XG4gICAgdGhpcy5kZWZpbml0aW9uLnByb3BlcnRpZXMgPSBkZXRhaWwucHJvcGVydGllcztcbiAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICB9XG5cbiAgX29uU2F2ZVByb3ZpZGVyKHsgZGV0YWlsIH0pIHtcbiAgICB0aGlzLnNlcnZpY2VzWydkeW5hbWljLXByb3BlcnR5J10gPSBkZXRhaWwucHJvdmlkZXI7XG4gICAgdGhpcy5pc0RpcnR5ID0gdHJ1ZTtcbiAgfVxuXG4gIF9vblN3aXRjaEVuY3J5cHRlZFByb3BlcnR5KHsgZGV0YWlsIH0pIHtcbiAgICB0aGlzLmlzRGlydHkgPSB0cnVlO1xuICB9XG5cbiAgcmVuZGVyKCkge1xuICAgIGNvbnN0IHJlYWRvbmx5TW9kZSA9IHRoaXMuX2dldFJlYWRvbmx5TW9kZUZvckRlc2lnbigpO1xuXG4gICAgcmV0dXJuIGh0bWxgPGRpdiBjbGFzcz1cImJveFwiPlxuICAgICAgPGd2LXBvbGljeS1zdHVkaW8tbWVudVxuICAgICAgICBjbGFzcz1cImxlZnQtbWVudVwiXG4gICAgICAgIC5hcGktbmFtZT1cIiR7dGhpcy5fZGVmaW5pdGlvbi5uYW1lfVwiXG4gICAgICAgIC5mbG93cz1cIiR7dGhpcy5maWx0ZXJlZEZsb3dzfVwiXG4gICAgICAgIC5wbGFucz1cIiR7dGhpcy5maWx0ZXJlZFBsYW5zfVwiXG4gICAgICAgIC5zZWxlY3RlZElkcz1cIiR7dGhpcy5zZWxlY3RlZEZsb3dzSWR9XCJcbiAgICAgICAgP2Rpc2FibGVkPVwiJHt0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9ufVwiXG4gICAgICAgID9zb3J0YWJsZT1cIiR7dGhpcy5zb3J0YWJsZSAmJiB0aGlzLnJlYWRvbmx5ICE9PSB0cnVlfVwiXG4gICAgICAgID9yZWFkb25seT1cIiR7dGhpcy5yZWFkb25seX1cIlxuICAgICAgICA/cmVhZG9ubHlQbGFucz1cIiR7dGhpcy5yZWFkb25seVBsYW5zfVwiXG4gICAgICAgIGZsb3dzLXRpdGxlPVwiJHt0aGlzLmZsb3dzVGl0bGV9XCJcbiAgICAgICAgLnF1ZXJ5PVwiJHt0aGlzLl9zZWFyY2hGbG93UXVlcnl9XCJcbiAgICAgICAgP2Nhbi1hZGQ9XCIke3RoaXMuY2FuQWRkICYmICF0aGlzLnJlYWRvbmx5fVwiXG4gICAgICAgIEBndi1wb2xpY3ktc3R1ZGlvLW1lbnU6cmVvcmRlci1mbG93cz1cIiR7dGhpcy5fb25SZW9yZGVyRmxvd3N9XCJcbiAgICAgICAgQGd2LXBvbGljeS1zdHVkaW8tbWVudTpjaGFuZ2UtZmxvdy1zdGF0ZT1cIiR7dGhpcy5fb25DaGFuZ2VGbG93U3RhdGV9XCJcbiAgICAgICAgQGd2LXBvbGljeS1zdHVkaW8tbWVudTphZGQtZmxvdz1cIiR7dGhpcy5fb25BZGRGbG93fVwiXG4gICAgICAgIEBndi1wb2xpY3ktc3R1ZGlvLW1lbnU6YWRkLWZsb3ctcGxhbj1cIiR7dGhpcy5fb25BZGRGbG93UGxhbn1cIlxuICAgICAgICBAZ3YtcG9saWN5LXN0dWRpby1tZW51OmRlbGV0ZS1mbG93PVwiJHt0aGlzLl9vbkRlbGV0ZUZsb3d9XCJcbiAgICAgICAgQGd2LXBvbGljeS1zdHVkaW8tbWVudTpkdXBsaWNhdGUtZmxvdz1cIiR7dGhpcy5fb25EdXBsaWNhdGVGbG93fVwiXG4gICAgICAgIEBndi1wb2xpY3ktc3R1ZGlvLW1lbnU6c2VsZWN0LWZsb3dzPVwiJHt0aGlzLl9vblNlbGVjdEZsb3dzfVwiXG4gICAgICA+XG4gICAgICAgIDxkaXYgc2xvdD1cImhlYWRlclwiIGNsYXNzPVwiaGVhZGVyLWFjdGlvbnNcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidGl0bGVcIj4ke3RoaXMuX2RlZmluaXRpb24ubmFtZX08L2Rpdj5cbiAgICAgICAgICAke3RoaXMuX2Zsb3dGaWx0ZXJPcHRpb25zICE9IG51bGxcbiAgICAgICAgICAgID8gaHRtbGA8Z3Ytb3B0aW9uXG4gICAgICAgICAgICAgICAgP2Rpc2FibGVkPVwiJHt0aGlzLl9jdXJyZW50QXNrQ29uZmlybWF0aW9ufVwiXG4gICAgICAgICAgICAgICAgLm9wdGlvbnM9XCIke3RoaXMuX2Zsb3dGaWx0ZXJPcHRpb25zfVwiXG4gICAgICAgICAgICAgICAgbXVsdGlwbGVcbiAgICAgICAgICAgICAgICBvdXRsaW5lZFxuICAgICAgICAgICAgICAgIC52YWx1ZT1cIiR7dGhpcy5fZmxvd0ZpbHRlcn1cIlxuICAgICAgICAgICAgICAgIHNtYWxsXG4gICAgICAgICAgICAgICAgQGd2LW9wdGlvbjpzZWxlY3Q9XCIke3RoaXMuX29uRmlsdGVyRmxvd3N9XCJcbiAgICAgICAgICAgICAgPjwvZ3Ytb3B0aW9uPmBcbiAgICAgICAgICAgIDogJyd9XG4gICAgICAgICAgPGd2LWlucHV0XG4gICAgICAgICAgICA/ZGlzYWJsZWQ9XCIke3RoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb259XCJcbiAgICAgICAgICAgIGlkPVwic2VhcmNoLWZsb3dcIlxuICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJGaWx0ZXIgZmxvd3MgKEN0cmwgKyBTcGFjZSlcIlxuICAgICAgICAgICAgdHlwZT1cInNlYXJjaFwiXG4gICAgICAgICAgICBzbWFsbFxuICAgICAgICAgICAgQGd2LWlucHV0OmlucHV0PVwiJHt0aGlzLl9vblNlYXJjaEZsb3dzfVwiXG4gICAgICAgICAgICBAZ3YtaW5wdXQ6Y2xlYXI9XCIke3RoaXMuX29uQ2xlYXJGbG93c31cIlxuICAgICAgICAgID48L2d2LWlucHV0PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICAke3RoaXMucmVhZG9ubHkgIT09IHRydWVcbiAgICAgICAgICA/IGh0bWxgIDxkaXYgc2xvdD1cImZvb3RlclwiIGNsYXNzPVwiZm9vdGVyLWFjdGlvbnNcIj5cbiAgICAgICAgICAgICAgPGd2LWJ1dHRvblxuICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuLWxhcmdlXCJcbiAgICAgICAgICAgICAgICAuZGlzYWJsZWQ9XCIkeyF0aGlzLmlzRGlydHkgfHwgdGhpcy5fY3VycmVudEFza0NvbmZpcm1hdGlvbn1cIlxuICAgICAgICAgICAgICAgIEBndi1idXR0b246Y2xpY2s9XCIke3RoaXMuX29uU2F2ZUFsbH1cIlxuICAgICAgICAgICAgICAgID5TYXZlPC9ndi1idXR0b25cbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8Z3YtYnV0dG9uIGxpbmsgLmRpc2FibGVkPVwiJHshdGhpcy5pc0RpcnR5IHx8IHRoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb259XCIgQGd2LWJ1dHRvbjpjbGljaz1cIiR7dGhpcy5fb25SZXNldEFsbH1cIlxuICAgICAgICAgICAgICAgID5SZXNldDwvZ3YtYnV0dG9uXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvZGl2PmBcbiAgICAgICAgICA6ICcnfVxuICAgICAgPC9ndi1wb2xpY3ktc3R1ZGlvLW1lbnU+XG5cbiAgICAgIDxndi10YWJzXG4gICAgICAgIC52YWx1ZT1cIiR7dGhpcy50YWJJZH1cIlxuICAgICAgICAub3B0aW9ucz1cIiR7dGhpcy5fdGFic31cIlxuICAgICAgICAuZGlzYWJsZWQ9XCIke3RoaXMuX2N1cnJlbnRBc2tDb25maXJtYXRpb259XCJcbiAgICAgICAgQGd2LXRhYnM6Y2hhbmdlPVwiJHt0aGlzLl9vbkNoYW5nZVRhYn1cIlxuICAgICAgICAudmFsaWRhdG9yPVwiJHt0aGlzLl9jaGFuZ2VUYWJWYWxpZGF0b3IuYmluZCh0aGlzKX1cIlxuICAgICAgPlxuICAgICAgICAke3RoaXMuX3JlbmRlckRlc2lnbihyZWFkb25seU1vZGUpfSAke3RoaXMuX3JlbmRlckNvbmZpZ3VyYXRpb25Gb3JtKHJlYWRvbmx5TW9kZSl9ICR7dGhpcy5fcmVuZGVyRGVidWcoKX1cbiAgICAgICAgPGd2LXByb3BlcnRpZXNcbiAgICAgICAgICBpZD1cInByb3BlcnRpZXNcIlxuICAgICAgICAgIHNsb3Q9XCJjb250ZW50XCJcbiAgICAgICAgICBjbGFzcz1cInByb3BlcnRpZXNcIlxuICAgICAgICAgIC5wcm92aWRlcj1cIiR7dGhpcy5zZXJ2aWNlc1snZHluYW1pYy1wcm9wZXJ0eSddfVwiXG4gICAgICAgICAgQGd2LXByb3BlcnRpZXM6Y2hhbmdlPVwiJHt0aGlzLl9vblByb3BlcnRpZXNDaGFuZ2V9XCJcbiAgICAgICAgICBAZ3YtcHJvcGVydGllczpzYXZlLXByb3ZpZGVyPVwiJHt0aGlzLl9vblNhdmVQcm92aWRlcn1cIlxuICAgICAgICAgIEBndi1wcm9wZXJ0aWVzOnN3aXRjaC1lbmNyeXB0ZWQ9XCIke3RoaXMuX29uU3dpdGNoRW5jcnlwdGVkUHJvcGVydHl9XCJcbiAgICAgICAgICA/cmVhZG9ubHk9XCIke3JlYWRvbmx5TW9kZX1cIlxuICAgICAgICAgIGVuY3J5cHRhYmxlPVwidHJ1ZVwiXG4gICAgICAgICAgLnByb3BlcnRpZXM9XCIke3RoaXMuZGVmaW5lZFByb3BlcnRpZXN9XCJcbiAgICAgICAgICAucHJvdmlkZXJzPVwiJHt0aGlzLnByb3BlcnR5UHJvdmlkZXJzfVwiXG4gICAgICAgICAgLmR5bmFtaWNQcm9wZXJ0eVNjaGVtYT1cIiR7dGhpcy5keW5hbWljUHJvcGVydHlTY2hlbWF9XCJcbiAgICAgICAgPjwvZ3YtcHJvcGVydGllcz5cbiAgICAgICAgPGd2LXJlc291cmNlc1xuICAgICAgICAgIGlkPVwicmVzb3VyY2VzXCJcbiAgICAgICAgICBzbG90PVwiY29udGVudFwiXG4gICAgICAgICAgY2xhc3M9XCJyZXNvdXJjZXNcIlxuICAgICAgICAgIEBndi1yZXNvdXJjZXM6Y2hhbmdlPVwiJHt0aGlzLl9vblJlc291cmNlc0NoYW5nZX1cIlxuICAgICAgICAgID9yZWFkb25seT1cIiR7cmVhZG9ubHlNb2RlfVwiXG4gICAgICAgICAgLnJlc291cmNlcz1cIiR7dGhpcy5kZWZpbmVkUmVzb3VyY2VzfVwiXG4gICAgICAgICAgLnR5cGVzPVwiJHt0aGlzLnJlc291cmNlVHlwZXN9XCJcbiAgICAgICAgPjwvZ3YtcmVzb3VyY2VzPlxuICAgICAgPC9ndi10YWJzPlxuICAgIDwvZGl2PmA7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIGlmIHRoZSBkZXNpZ24gdmlldyBzaG91bGQgYmUgaW4gcmVhZG9ubHkgbW9kZSBvciBub3RcbiAgICogSXQgaXMgaW4gcmVhZG9ubHkgbW9kZSBpZjpcbiAgICogIHRoZSByZWFkb25seSBhdHRyaWJ1dGUgaXMgc2V0IHRvIHRydWVcbiAgICogIE9SXG4gICAqICB0aGUgbWFpbiBzZWxlY3RlZCBmbG93IGJlbG9uZ3MgdG8gYSBwbGFuIGFuZCB0aGUgcmVhZG9ubHktcGxhbnMgYXR0cmlidXRlIGlzIHNldCB0byB0cnVlXG4gICAqICBPUlxuICAgKiAgdGhlIHNlY29uZCBmbG93IGZvciBjb21wYXJpc29uIGJlbG9uZ3MgdG8gYSBwbGFuIGFuZCB0aGUgcmVhZG9ubHktcGxhbnMgYXR0cmlidXRlIGlzIHNldCB0byB0cnVlXG4gICAqIEByZXR1cm5zIHtib29sZWFufCp8e3R5cGU6IEJvb2xlYW5Db25zdHJ1Y3Rvcn18e2F0dHJpYnV0ZTogc3RyaW5nLCB0eXBlOiBCb29sZWFuQ29uc3RydWN0b3J9fHt0eXBlOiAqfXx7YXR0cmlidXRlOiBzdHJpbmcsIHR5cGU6ICp9fVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgX2dldFJlYWRvbmx5TW9kZUZvckRlc2lnbigpIHtcbiAgICBpZiAodGhpcy5yZWFkb25seSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgY29uc3QgZmxvdyA9IHRoaXMuZ2V0U2VsZWN0ZWRGbG93KDApO1xuICAgIGlmICghZmxvdykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IHsgcGxhbjogZmxvd1BsYW4gfSA9IHRoaXMuX2ZpbmRGbG93Q29sbGVjdGlvbihmbG93Ll9pZCk7XG4gICAgY29uc3QgcmVhZG9ubHlNb2RlID0gZmxvd1BsYW4gJiYgdGhpcy5yZWFkb25seVBsYW5zO1xuICAgIGlmIChyZWFkb25seU1vZGUpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbXBhcmVkRmxvdyA9IHRoaXMuZ2V0U2VsZWN0ZWRGbG93KDEpO1xuICAgIGlmICghY29tcGFyZWRGbG93KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgeyBwbGFuOiBjb21wYXJlZEZsb3dQbGFuIH0gPSB0aGlzLl9maW5kRmxvd0NvbGxlY3Rpb24oY29tcGFyZWRGbG93Ll9pZCk7XG4gICAgcmV0dXJuIGNvbXBhcmVkRmxvd1BsYW4gJiYgdGhpcy5yZWFkb25seVBsYW5zO1xuICB9XG59XG5cbndpbmRvdy5jdXN0b21FbGVtZW50cy5kZWZpbmUoJ2d2LXBvbGljeS1zdHVkaW8nLCBHdlBvbGljeVN0dWRpbyk7XG4iXX0=
1713
+ //# sourceMappingURL=gv-policy-studio.js.map